From 7eb9a06ef53e727dc5775121fddebbbada60b907 Mon Sep 17 00:00:00 2001 From: Git User Date: Wed, 3 Apr 2019 04:01:20 -0700 Subject: [PATCH 001/452] Initial empty repository From 623f36a95c2067c95dda82a10c55b4af2d688806 Mon Sep 17 00:00:00 2001 From: Shivendra Kakrania Date: Wed, 1 May 2019 19:45:07 -0700 Subject: [PATCH 002/452] techpack: video: add makefile for video driver This change adds dummy Makefile support to compile video driver project along with base kernel. Change-Id: Ia1fad0785131d3a8852b8d7dcf713b537e9fa4d1 Signed-off-by: Shivendra Kakrania --- Makefile | 3 +++ vid.c | 8 ++++++++ 2 files changed, 11 insertions(+) create mode 100644 Makefile create mode 100644 vid.c diff --git a/Makefile b/Makefile new file mode 100644 index 000000000000..a9a568e77f8e --- /dev/null +++ b/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only +ccflags-y := -Wno-unused-function +obj-y := vid.o diff --git a/vid.c b/vid.c new file mode 100644 index 000000000000..4d2ba3b0a42c --- /dev/null +++ b/vid.c @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +static void _vid_techpack_stub(void) +{ +} From 4ae4cb1749accce97e6069a078b965bd45712624 Mon Sep 17 00:00:00 2001 From: Shivendra Kakrania Date: Mon, 29 Apr 2019 15:20:26 -0700 Subject: [PATCH 003/452] techpack: video: Video driver kernel project initial snapshot This change brings msm vidc driver from base 4.19 kernel project. It is the first source code snapshot from base kernel project. Change-Id: I1d600c4e9459b9013f4b607890c52644f6d94f0c Signed-off-by: Shivendra Kakrania --- Makefile | 13 +- config/konavid.conf | 1 + config/konavidconf.h | 6 + msm/Makefile | 27 + msm/vidc/fixedpoint.h | 68 + msm/vidc/hfi_packetization.c | 894 +++ msm/vidc/hfi_packetization.h | 91 + msm/vidc/hfi_response_handler.c | 1288 +++++ msm/vidc/msm_cvp_external.c | 955 ++++ msm/vidc/msm_cvp_external.h | 168 + msm/vidc/msm_cvp_internal.c | 627 +++ msm/vidc/msm_cvp_internal.h | 25 + msm/vidc/msm_smem.c | 594 ++ msm/vidc/msm_v4l2_private.c | 226 + msm/vidc/msm_v4l2_private.h | 14 + msm/vidc/msm_v4l2_vidc.c | 783 +++ msm/vidc/msm_vdec.c | 1514 +++++ msm/vidc/msm_vdec.h | 26 + msm/vidc/msm_venc.c | 4069 ++++++++++++++ msm/vidc/msm_venc.h | 40 + msm/vidc/msm_vidc.c | 1818 ++++++ msm/vidc/msm_vidc.h | 135 + msm/vidc/msm_vidc_buffer_calculations.c | 1715 ++++++ msm/vidc/msm_vidc_buffer_calculations.h | 40 + msm/vidc/msm_vidc_bus.h | 283 + msm/vidc/msm_vidc_bus_iris1.c | 699 +++ msm/vidc/msm_vidc_bus_iris2.c | 637 +++ msm/vidc/msm_vidc_clocks.c | 1828 ++++++ msm/vidc/msm_vidc_clocks.h | 33 + msm/vidc/msm_vidc_common.c | 6783 +++++++++++++++++++++++ msm/vidc/msm_vidc_common.h | 283 + msm/vidc/msm_vidc_debug.c | 533 ++ msm/vidc/msm_vidc_debug.h | 209 + msm/vidc/msm_vidc_internal.h | 593 ++ msm/vidc/msm_vidc_platform.c | 1024 ++++ msm/vidc/msm_vidc_res_parse.c | 1258 +++++ msm/vidc/msm_vidc_res_parse.h | 30 + msm/vidc/msm_vidc_resources.h | 216 + msm/vidc/venus_hfi.c | 5203 +++++++++++++++++ msm/vidc/venus_hfi.h | 289 + msm/vidc/vidc_hfi.c | 64 + msm/vidc/vidc_hfi.h | 841 +++ msm/vidc/vidc_hfi_api.h | 752 +++ msm/vidc/vidc_hfi_helper.h | 1083 ++++ msm/vidc/vidc_hfi_io.h | 220 + 45 files changed, 37996 insertions(+), 2 deletions(-) create mode 100644 config/konavid.conf create mode 100644 config/konavidconf.h create mode 100644 msm/Makefile create mode 100644 msm/vidc/fixedpoint.h create mode 100644 msm/vidc/hfi_packetization.c create mode 100644 msm/vidc/hfi_packetization.h create mode 100644 msm/vidc/hfi_response_handler.c create mode 100644 msm/vidc/msm_cvp_external.c create mode 100644 msm/vidc/msm_cvp_external.h create mode 100644 msm/vidc/msm_cvp_internal.c create mode 100644 msm/vidc/msm_cvp_internal.h create mode 100644 msm/vidc/msm_smem.c create mode 100644 msm/vidc/msm_v4l2_private.c create mode 100644 msm/vidc/msm_v4l2_private.h create mode 100644 msm/vidc/msm_v4l2_vidc.c create mode 100644 msm/vidc/msm_vdec.c create mode 100644 msm/vidc/msm_vdec.h create mode 100644 msm/vidc/msm_venc.c create mode 100644 msm/vidc/msm_venc.h create mode 100644 msm/vidc/msm_vidc.c create mode 100644 msm/vidc/msm_vidc.h create mode 100644 msm/vidc/msm_vidc_buffer_calculations.c create mode 100644 msm/vidc/msm_vidc_buffer_calculations.h create mode 100644 msm/vidc/msm_vidc_bus.h create mode 100644 msm/vidc/msm_vidc_bus_iris1.c create mode 100644 msm/vidc/msm_vidc_bus_iris2.c create mode 100644 msm/vidc/msm_vidc_clocks.c create mode 100644 msm/vidc/msm_vidc_clocks.h create mode 100644 msm/vidc/msm_vidc_common.c create mode 100644 msm/vidc/msm_vidc_common.h create mode 100644 msm/vidc/msm_vidc_debug.c create mode 100644 msm/vidc/msm_vidc_debug.h create mode 100644 msm/vidc/msm_vidc_internal.h create mode 100644 msm/vidc/msm_vidc_platform.c create mode 100644 msm/vidc/msm_vidc_res_parse.c create mode 100644 msm/vidc/msm_vidc_res_parse.h create mode 100644 msm/vidc/msm_vidc_resources.h create mode 100644 msm/vidc/venus_hfi.c create mode 100644 msm/vidc/venus_hfi.h create mode 100644 msm/vidc/vidc_hfi.c create mode 100644 msm/vidc/vidc_hfi.h create mode 100644 msm/vidc/vidc_hfi_api.h create mode 100644 msm/vidc/vidc_hfi_helper.h create mode 100644 msm/vidc/vidc_hfi_io.h diff --git a/Makefile b/Makefile index a9a568e77f8e..d4981863d8de 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,12 @@ # SPDX-License-Identifier: GPL-2.0-only -ccflags-y := -Wno-unused-function -obj-y := vid.o + +# auto-detect subdirs +ifeq ($(CONFIG_ARCH_KONA), y) +include $(srctree)/techpack/video/config/konavid.conf +endif + +ifeq ($(CONFIG_ARCH_KONA), y) +LINUXINCLUDE += -include $(srctree)/techpack/video/config/konavidconf.h +endif + +obj-y +=msm/ diff --git a/config/konavid.conf b/config/konavid.conf new file mode 100644 index 000000000000..efb4eedfb73e --- /dev/null +++ b/config/konavid.conf @@ -0,0 +1 @@ +export CONFIG_MSM_VIDC_V4L2=y diff --git a/config/konavidconf.h b/config/konavidconf.h new file mode 100644 index 000000000000..da305d52ecd1 --- /dev/null +++ b/config/konavidconf.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#define CONFIG_MSM_VIDC_V4L2 1 diff --git a/msm/Makefile b/msm/Makefile new file mode 100644 index 000000000000..f71400929de6 --- /dev/null +++ b/msm/Makefile @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0-only +ccflags-y += -I$(srctree)/techpack/video/msm/vidc/ \ + -I$(srctree)/drivers/devfreq/ + +msm-vidc-objs := vidc/msm_v4l2_vidc.o \ + vidc/msm_v4l2_private.o \ + vidc/msm_vidc_platform.o \ + vidc/msm_vidc_common.o \ + vidc/msm_vidc.o \ + vidc/msm_vdec.o \ + vidc/msm_venc.o \ + vidc/msm_cvp_internal.o \ + vidc/msm_cvp_external.o \ + vidc/msm_smem.o \ + vidc/msm_vidc_debug.o \ + vidc/msm_vidc_res_parse.o \ + vidc/venus_hfi.o \ + vidc/hfi_response_handler.o \ + vidc/hfi_packetization.o \ + vidc/vidc_hfi.o \ + vidc/msm_vidc_clocks.o \ + vidc/msm_vidc_bus_iris1.o \ + vidc/msm_vidc_bus_iris2.o \ + vidc/msm_vidc_buffer_calculations.o + +obj-$(CONFIG_MSM_VIDC_V4L2) := msm-vidc.o + diff --git a/msm/vidc/fixedpoint.h b/msm/vidc/fixedpoint.h new file mode 100644 index 000000000000..6a28ed839f68 --- /dev/null +++ b/msm/vidc/fixedpoint.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + */ + +#ifdef _FIXP_ARITH_H +#error "This implementation is meant to override fixp-arith.h, don't use both" +#endif + +#ifndef _FIXEDPOINT_H_ +#define _FIXEDPOINT_H_ + +#include +#include + +/* + * Normally would typedef'ed, but checkpatch doesn't like typedef. + * Also should be normally typedef'ed to intmax_t but that doesn't seem to be + * available in the kernel + */ +#define fp_t size_t + +/* (Arbitrarily) make the first 25% of the bits to be the fractional bits */ +#define FP_FRACTIONAL_BITS ((sizeof(fp_t) * 8) / 4) + +#define FP(__i, __f_n, __f_d) \ + ((((fp_t)(__i)) << FP_FRACTIONAL_BITS) + \ + (((__f_n) << FP_FRACTIONAL_BITS) / (__f_d))) + +#define FP_INT(__i) FP(__i, 0, 1) +#define FP_ONE FP_INT(1) +#define FP_ZERO FP_INT(0) + +static inline size_t fp_frac_base(void) +{ + return GENMASK(FP_FRACTIONAL_BITS - 1, 0); +} + +static inline size_t fp_frac(fp_t a) +{ + return a & GENMASK(FP_FRACTIONAL_BITS - 1, 0); +} + +static inline size_t fp_int(fp_t a) +{ + return a >> FP_FRACTIONAL_BITS; +} + +static inline size_t fp_round(fp_t a) +{ + /* is the fractional part >= frac_max / 2? */ + bool round_up = fp_frac(a) >= fp_frac_base() / 2; + + return fp_int(a) + round_up; +} + +static inline fp_t fp_mult(fp_t a, fp_t b) +{ + return (a * b) >> FP_FRACTIONAL_BITS; +} + + +static inline fp_t fp_div(fp_t a, fp_t b) +{ + return (a << FP_FRACTIONAL_BITS) / b; +} + +#endif diff --git a/msm/vidc/hfi_packetization.c b/msm/vidc/hfi_packetization.c new file mode 100644 index 000000000000..aded2b398165 --- /dev/null +++ b/msm/vidc/hfi_packetization.c @@ -0,0 +1,894 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ +#include "hfi_packetization.h" +#include "msm_vidc_debug.h" + +/* Set up look-up tables to convert HAL_* to HFI_*. + * + * The tables below mostly take advantage of the fact that most + * HAL_* types are defined bitwise. So if we index them normally + * when declaring the tables, we end up with huge arrays with wasted + * space. So before indexing them, we apply log2 to use a more + * sensible index. + */ + +enum hal_domain vidc_get_hal_domain(u32 hfi_domain) +{ + enum hal_domain hal_domain = 0; + + switch (hfi_domain) { + case HFI_VIDEO_DOMAIN_VPE: + hal_domain = HAL_VIDEO_DOMAIN_VPE; + break; + case HFI_VIDEO_DOMAIN_ENCODER: + hal_domain = HAL_VIDEO_DOMAIN_ENCODER; + break; + case HFI_VIDEO_DOMAIN_DECODER: + hal_domain = HAL_VIDEO_DOMAIN_DECODER; + break; + case HFI_VIDEO_DOMAIN_CVP: + hal_domain = HAL_VIDEO_DOMAIN_CVP; + break; + default: + dprintk(VIDC_ERR, "%s: invalid domain %x\n", + __func__, hfi_domain); + hal_domain = 0; + break; + } + return hal_domain; +} + +enum hal_video_codec vidc_get_hal_codec(u32 hfi_codec) +{ + enum hal_video_codec hal_codec = 0; + + switch (hfi_codec) { + case HFI_VIDEO_CODEC_H264: + hal_codec = HAL_VIDEO_CODEC_H264; + break; + case HFI_VIDEO_CODEC_MPEG1: + hal_codec = HAL_VIDEO_CODEC_MPEG1; + break; + case HFI_VIDEO_CODEC_MPEG2: + hal_codec = HAL_VIDEO_CODEC_MPEG2; + break; + case HFI_VIDEO_CODEC_VP8: + hal_codec = HAL_VIDEO_CODEC_VP8; + break; + case HFI_VIDEO_CODEC_HEVC: + hal_codec = HAL_VIDEO_CODEC_HEVC; + break; + case HFI_VIDEO_CODEC_VP9: + hal_codec = HAL_VIDEO_CODEC_VP9; + break; + case HFI_VIDEO_CODEC_TME: + hal_codec = HAL_VIDEO_CODEC_TME; + break; + case HFI_VIDEO_CODEC_CVP: + hal_codec = HAL_VIDEO_CODEC_CVP; + break; + default: + dprintk(VIDC_INFO, "%s: invalid codec 0x%x\n", + __func__, hfi_codec); + hal_codec = 0; + break; + } + return hal_codec; +} + + +u32 vidc_get_hfi_domain(enum hal_domain hal_domain) +{ + u32 hfi_domain; + + switch (hal_domain) { + case HAL_VIDEO_DOMAIN_VPE: + hfi_domain = HFI_VIDEO_DOMAIN_VPE; + break; + case HAL_VIDEO_DOMAIN_ENCODER: + hfi_domain = HFI_VIDEO_DOMAIN_ENCODER; + break; + case HAL_VIDEO_DOMAIN_DECODER: + hfi_domain = HFI_VIDEO_DOMAIN_DECODER; + break; + case HAL_VIDEO_DOMAIN_CVP: + hfi_domain = HFI_VIDEO_DOMAIN_CVP; + break; + default: + dprintk(VIDC_ERR, "%s: invalid domain 0x%x\n", + __func__, hal_domain); + hfi_domain = 0; + break; + } + return hfi_domain; +} + +u32 vidc_get_hfi_codec(enum hal_video_codec hal_codec) +{ + u32 hfi_codec = 0; + + switch (hal_codec) { + case HAL_VIDEO_CODEC_H264: + hfi_codec = HFI_VIDEO_CODEC_H264; + break; + case HAL_VIDEO_CODEC_MPEG1: + hfi_codec = HFI_VIDEO_CODEC_MPEG1; + break; + case HAL_VIDEO_CODEC_MPEG2: + hfi_codec = HFI_VIDEO_CODEC_MPEG2; + break; + case HAL_VIDEO_CODEC_VP8: + hfi_codec = HFI_VIDEO_CODEC_VP8; + break; + case HAL_VIDEO_CODEC_HEVC: + hfi_codec = HFI_VIDEO_CODEC_HEVC; + break; + case HAL_VIDEO_CODEC_VP9: + hfi_codec = HFI_VIDEO_CODEC_VP9; + break; + case HAL_VIDEO_CODEC_TME: + hfi_codec = HFI_VIDEO_CODEC_TME; + break; + case HAL_VIDEO_CODEC_CVP: + hfi_codec = HFI_VIDEO_CODEC_CVP; + break; + default: + dprintk(VIDC_INFO, "%s: invalid codec 0x%x\n", + __func__, hal_codec); + hfi_codec = 0; + break; + } + return hfi_codec; +} + +int create_pkt_cmd_sys_init(struct hfi_cmd_sys_init_packet *pkt, + u32 arch_type) +{ + int rc = 0; + + if (!pkt) + return -EINVAL; + + pkt->packet_type = HFI_CMD_SYS_INIT; + pkt->size = sizeof(struct hfi_cmd_sys_init_packet); + pkt->arch_type = arch_type; + return rc; +} + +int create_pkt_cmd_sys_pc_prep(struct hfi_cmd_sys_pc_prep_packet *pkt) +{ + int rc = 0; + + if (!pkt) + return -EINVAL; + + pkt->packet_type = HFI_CMD_SYS_PC_PREP; + pkt->size = sizeof(struct hfi_cmd_sys_pc_prep_packet); + return rc; +} + +int create_pkt_cmd_sys_debug_config( + struct hfi_cmd_sys_set_property_packet *pkt, + u32 mode) +{ + struct hfi_debug_config *hfi; + + if (!pkt) + return -EINVAL; + + pkt->size = sizeof(struct hfi_cmd_sys_set_property_packet) + + sizeof(struct hfi_debug_config) + sizeof(u32); + pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY; + pkt->num_properties = 1; + pkt->rg_property_data[0] = HFI_PROPERTY_SYS_DEBUG_CONFIG; + hfi = (struct hfi_debug_config *) &pkt->rg_property_data[1]; + hfi->debug_config = mode; + hfi->debug_mode = HFI_DEBUG_MODE_QUEUE; + if (msm_vidc_fw_debug_mode + <= (HFI_DEBUG_MODE_QUEUE | HFI_DEBUG_MODE_QDSS)) + hfi->debug_mode = msm_vidc_fw_debug_mode; + return 0; +} + +int create_pkt_cmd_sys_coverage_config( + struct hfi_cmd_sys_set_property_packet *pkt, + u32 mode) +{ + if (!pkt) { + dprintk(VIDC_ERR, "In %s(), No input packet\n", __func__); + return -EINVAL; + } + + pkt->size = sizeof(struct hfi_cmd_sys_set_property_packet) + + sizeof(u32); + pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY; + pkt->num_properties = 1; + pkt->rg_property_data[0] = HFI_PROPERTY_SYS_CONFIG_COVERAGE; + pkt->rg_property_data[1] = mode; + dprintk(VIDC_DBG, "Firmware coverage mode %d\n", + pkt->rg_property_data[1]); + return 0; +} + +int create_pkt_cmd_sys_set_resource( + struct hfi_cmd_sys_set_resource_packet *pkt, + struct vidc_resource_hdr *res_hdr, + void *res_value) +{ + int rc = 0; + u32 i = 0; + + if (!pkt || !res_hdr || !res_value) { + dprintk(VIDC_ERR, + "Invalid paramas pkt %pK res_hdr %pK res_value %pK\n", + pkt, res_hdr, res_value); + return -EINVAL; + } + + pkt->packet_type = HFI_CMD_SYS_SET_RESOURCE; + pkt->size = sizeof(struct hfi_cmd_sys_set_resource_packet); + pkt->resource_handle = hash32_ptr(res_hdr->resource_handle); + + switch (res_hdr->resource_id) { + case VIDC_RESOURCE_SYSCACHE: + { + struct hfi_resource_syscache_info_type *res_sc_info = + (struct hfi_resource_syscache_info_type *) res_value; + struct hfi_resource_subcache_type *res_sc = + (struct hfi_resource_subcache_type *) + &(res_sc_info->rg_subcache_entries[0]); + + struct hfi_resource_syscache_info_type *hfi_sc_info = + (struct hfi_resource_syscache_info_type *) + &pkt->rg_resource_data[0]; + + struct hfi_resource_subcache_type *hfi_sc = + (struct hfi_resource_subcache_type *) + &(hfi_sc_info->rg_subcache_entries[0]); + + pkt->resource_type = HFI_RESOURCE_SYSCACHE; + hfi_sc_info->num_entries = res_sc_info->num_entries; + + pkt->size += (sizeof(struct hfi_resource_subcache_type)) + * hfi_sc_info->num_entries; + + for (i = 0; i < hfi_sc_info->num_entries; i++) { + hfi_sc[i] = res_sc[i]; + dprintk(VIDC_DBG, "entry hfi#%d, sc_id %d, size %d\n", + i, hfi_sc[i].sc_id, hfi_sc[i].size); + } + break; + } + default: + dprintk(VIDC_ERR, + "Invalid resource_id %d\n", res_hdr->resource_id); + rc = -ENOTSUPP; + } + + return rc; +} + +int create_pkt_cmd_sys_release_resource( + struct hfi_cmd_sys_release_resource_packet *pkt, + struct vidc_resource_hdr *res_hdr) +{ + int rc = 0; + + if (!pkt || !res_hdr) { + dprintk(VIDC_ERR, + "Invalid paramas pkt %pK res_hdr %pK\n", + pkt, res_hdr); + return -EINVAL; + } + + pkt->size = sizeof(struct hfi_cmd_sys_release_resource_packet); + pkt->packet_type = HFI_CMD_SYS_RELEASE_RESOURCE; + pkt->resource_handle = hash32_ptr(res_hdr->resource_handle); + + switch (res_hdr->resource_id) { + case VIDC_RESOURCE_SYSCACHE: + pkt->resource_type = HFI_RESOURCE_SYSCACHE; + break; + default: + dprintk(VIDC_ERR, + "Invalid resource_id %d\n", res_hdr->resource_id); + rc = -ENOTSUPP; + } + + dprintk(VIDC_DBG, + "rel_res: pkt_type 0x%x res_type 0x%x prepared\n", + pkt->packet_type, pkt->resource_type); + + return rc; +} + +inline int create_pkt_cmd_sys_session_init( + struct hfi_cmd_sys_session_init_packet *pkt, + struct hal_session *session, + u32 session_domain, u32 session_codec) +{ + int rc = 0; + + if (!pkt) + return -EINVAL; + + pkt->size = sizeof(struct hfi_cmd_sys_session_init_packet); + pkt->packet_type = HFI_CMD_SYS_SESSION_INIT; + pkt->session_id = hash32_ptr(session); + pkt->session_domain = vidc_get_hfi_domain(session_domain); + pkt->session_codec = vidc_get_hfi_codec(session_codec); + if (!pkt->session_codec) + return -EINVAL; + + return rc; +} + + +int create_pkt_cmd_sys_ubwc_config( + struct hfi_cmd_sys_set_property_packet *pkt, + struct msm_vidc_ubwc_config_data *ubwc_config) +{ + int rc = 0; + struct hfi_cmd_sys_set_ubwc_config_packet_type *hfi; + + if (!pkt) + return -EINVAL; + + pkt->size = sizeof(struct hfi_cmd_sys_set_property_packet) + + sizeof(struct hfi_cmd_sys_set_ubwc_config_packet_type) + + sizeof(u32); + + pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY; + pkt->num_properties = 1; + pkt->rg_property_data[0] = HFI_PROPERTY_SYS_UBWC_CONFIG; + hfi = (struct hfi_cmd_sys_set_ubwc_config_packet_type *) + &pkt->rg_property_data[1]; + + hfi->max_channels = ubwc_config->max_channels; + hfi->override_bit_info.max_channel_override = + ubwc_config->override_bit_info.max_channel_override; + + hfi->mal_length = ubwc_config->mal_length; + hfi->override_bit_info.mal_length_override = + ubwc_config->override_bit_info.mal_length_override; + + hfi->highest_bank_bit = ubwc_config->highest_bank_bit; + hfi->override_bit_info.hb_override = + ubwc_config->override_bit_info.hb_override; + + hfi->bank_swzl_level = ubwc_config->bank_swzl_level; + hfi->override_bit_info.bank_swzl_level_override = + ubwc_config->override_bit_info.bank_swzl_level_override; + + hfi->bank_spreading = ubwc_config->bank_spreading; + hfi->override_bit_info.bank_spreading_override = + ubwc_config->override_bit_info.bank_spreading_override; + + return rc; +} + + +int create_pkt_cmd_session_cmd(struct vidc_hal_session_cmd_pkt *pkt, + int pkt_type, struct hal_session *session) +{ + int rc = 0; + + if (!pkt) + return -EINVAL; + + pkt->size = sizeof(struct vidc_hal_session_cmd_pkt); + pkt->packet_type = pkt_type; + pkt->session_id = hash32_ptr(session); + + return rc; +} + +int create_pkt_cmd_sys_power_control( + struct hfi_cmd_sys_set_property_packet *pkt, u32 enable) +{ + struct hfi_enable *hfi; + + if (!pkt) { + dprintk(VIDC_ERR, "No input packet\n"); + return -EINVAL; + } + + pkt->size = sizeof(struct hfi_cmd_sys_set_property_packet) + + sizeof(struct hfi_enable) + sizeof(u32); + pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY; + pkt->num_properties = 1; + pkt->rg_property_data[0] = HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL; + hfi = (struct hfi_enable *) &pkt->rg_property_data[1]; + hfi->enable = enable; + return 0; +} + +static u32 get_hfi_buffer(int hal_buffer) +{ + u32 buffer; + + switch (hal_buffer) { + case HAL_BUFFER_INPUT: + buffer = HFI_BUFFER_INPUT; + break; + case HAL_BUFFER_OUTPUT: + buffer = HFI_BUFFER_OUTPUT; + break; + case HAL_BUFFER_OUTPUT2: + buffer = HFI_BUFFER_OUTPUT2; + break; + case HAL_BUFFER_EXTRADATA_INPUT: + buffer = HFI_BUFFER_EXTRADATA_INPUT; + break; + case HAL_BUFFER_EXTRADATA_OUTPUT: + buffer = HFI_BUFFER_EXTRADATA_OUTPUT; + break; + case HAL_BUFFER_EXTRADATA_OUTPUT2: + buffer = HFI_BUFFER_EXTRADATA_OUTPUT2; + break; + case HAL_BUFFER_INTERNAL_SCRATCH: + buffer = HFI_BUFFER_COMMON_INTERNAL_SCRATCH; + break; + case HAL_BUFFER_INTERNAL_SCRATCH_1: + buffer = HFI_BUFFER_COMMON_INTERNAL_SCRATCH_1; + break; + case HAL_BUFFER_INTERNAL_SCRATCH_2: + buffer = HFI_BUFFER_COMMON_INTERNAL_SCRATCH_2; + break; + case HAL_BUFFER_INTERNAL_PERSIST: + buffer = HFI_BUFFER_INTERNAL_PERSIST; + break; + case HAL_BUFFER_INTERNAL_PERSIST_1: + buffer = HFI_BUFFER_INTERNAL_PERSIST_1; + break; + default: + dprintk(VIDC_ERR, "Invalid buffer: %#x\n", + hal_buffer); + buffer = 0; + break; + } + return buffer; +} + +int create_pkt_cmd_session_set_buffers( + struct hfi_cmd_session_set_buffers_packet *pkt, + struct hal_session *session, + struct vidc_buffer_addr_info *buffer_info) +{ + int rc = 0; + u32 i = 0; + + if (!pkt || !session) + return -EINVAL; + + pkt->packet_type = HFI_CMD_SESSION_SET_BUFFERS; + pkt->session_id = hash32_ptr(session); + pkt->buffer_size = buffer_info->buffer_size; + pkt->min_buffer_size = buffer_info->buffer_size; + pkt->num_buffers = buffer_info->num_buffers; + + if (buffer_info->buffer_type == HAL_BUFFER_OUTPUT || + buffer_info->buffer_type == HAL_BUFFER_OUTPUT2) { + struct hfi_buffer_info *buff; + + pkt->extra_data_size = buffer_info->extradata_size; + + pkt->size = sizeof(struct hfi_cmd_session_set_buffers_packet) - + sizeof(u32) + (buffer_info->num_buffers * + sizeof(struct hfi_buffer_info)); + buff = (struct hfi_buffer_info *) pkt->rg_buffer_info; + for (i = 0; i < pkt->num_buffers; i++) { + buff->buffer_addr = + (u32)buffer_info->align_device_addr; + buff->extra_data_addr = + (u32)buffer_info->extradata_addr; + } + } else { + pkt->extra_data_size = 0; + pkt->size = sizeof(struct hfi_cmd_session_set_buffers_packet) + + ((buffer_info->num_buffers - 1) * sizeof(u32)); + for (i = 0; i < pkt->num_buffers; i++) { + pkt->rg_buffer_info[i] = + (u32)buffer_info->align_device_addr; + } + } + + pkt->buffer_type = get_hfi_buffer(buffer_info->buffer_type); + if (!pkt->buffer_type) + return -EINVAL; + + return rc; +} + +int create_pkt_cmd_session_release_buffers( + struct hfi_cmd_session_release_buffer_packet *pkt, + struct hal_session *session, + struct vidc_buffer_addr_info *buffer_info) +{ + int rc = 0; + u32 i = 0; + + if (!pkt || !session) + return -EINVAL; + + pkt->packet_type = HFI_CMD_SESSION_RELEASE_BUFFERS; + pkt->session_id = hash32_ptr(session); + pkt->buffer_size = buffer_info->buffer_size; + pkt->num_buffers = buffer_info->num_buffers; + + if (buffer_info->buffer_type == HAL_BUFFER_OUTPUT || + buffer_info->buffer_type == HAL_BUFFER_OUTPUT2) { + struct hfi_buffer_info *buff; + + buff = (struct hfi_buffer_info *) pkt->rg_buffer_info; + for (i = 0; i < pkt->num_buffers; i++) { + buff->buffer_addr = + (u32)buffer_info->align_device_addr; + buff->extra_data_addr = + (u32)buffer_info->extradata_addr; + } + pkt->size = sizeof(struct hfi_cmd_session_set_buffers_packet) - + sizeof(u32) + (buffer_info->num_buffers * + sizeof(struct hfi_buffer_info)); + } else { + for (i = 0; i < pkt->num_buffers; i++) { + pkt->rg_buffer_info[i] = + (u32)buffer_info->align_device_addr; + } + pkt->extra_data_size = 0; + pkt->size = sizeof(struct hfi_cmd_session_set_buffers_packet) + + ((buffer_info->num_buffers - 1) * sizeof(u32)); + } + pkt->response_req = buffer_info->response_required; + pkt->buffer_type = get_hfi_buffer(buffer_info->buffer_type); + if (!pkt->buffer_type) + return -EINVAL; + return rc; +} + +int create_pkt_cmd_session_register_buffer( + struct hfi_cmd_session_register_buffers_packet *pkt, + struct hal_session *session, + struct vidc_register_buffer *buffer) +{ + int rc = 0; + u32 i; + struct hfi_buffer_mapping_type *buf; + + if (!pkt || !session) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + pkt->packet_type = HFI_CMD_SESSION_REGISTER_BUFFERS; + pkt->session_id = hash32_ptr(session); + pkt->client_data = buffer->client_data; + pkt->response_req = buffer->response_required; + pkt->num_buffers = 1; + pkt->size = sizeof(struct hfi_cmd_session_register_buffers_packet) - + sizeof(u32) + (pkt->num_buffers * + sizeof(struct hfi_buffer_mapping_type)); + + buf = (struct hfi_buffer_mapping_type *)pkt->buffer; + for (i = 0; i < pkt->num_buffers; i++) { + buf->index = buffer->index; + buf->device_addr = buffer->device_addr; + buf->size = buffer->size; + buf++; + } + + return rc; +} + +int create_pkt_cmd_session_unregister_buffer( + struct hfi_cmd_session_unregister_buffers_packet *pkt, + struct hal_session *session, + struct vidc_unregister_buffer *buffer) +{ + int rc = 0; + u32 i; + struct hfi_buffer_mapping_type *buf; + + if (!pkt || !session) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + pkt->packet_type = HFI_CMD_SESSION_UNREGISTER_BUFFERS; + pkt->session_id = hash32_ptr(session); + pkt->client_data = buffer->client_data; + pkt->response_req = buffer->response_required; + pkt->num_buffers = 1; + pkt->size = sizeof(struct hfi_cmd_session_unregister_buffers_packet) - + sizeof(u32) + (pkt->num_buffers * + sizeof(struct hfi_buffer_mapping_type)); + + buf = (struct hfi_buffer_mapping_type *)pkt->buffer; + for (i = 0; i < pkt->num_buffers; i++) { + buf->index = buffer->index; + buf->device_addr = buffer->device_addr; + buf->size = buffer->size; + buf++; + } + + return rc; +} + +int create_pkt_cmd_session_etb_decoder( + struct hfi_cmd_session_empty_buffer_compressed_packet *pkt, + struct hal_session *session, struct vidc_frame_data *input_frame) +{ + int rc = 0; + + if (!pkt || !session) + return -EINVAL; + + pkt->size = + sizeof(struct hfi_cmd_session_empty_buffer_compressed_packet); + pkt->packet_type = HFI_CMD_SESSION_EMPTY_BUFFER; + pkt->session_id = hash32_ptr(session); + pkt->time_stamp_hi = upper_32_bits(input_frame->timestamp); + pkt->time_stamp_lo = lower_32_bits(input_frame->timestamp); + pkt->flags = input_frame->flags; + pkt->mark_target = input_frame->mark_target; + pkt->mark_data = input_frame->mark_data; + pkt->offset = input_frame->offset; + pkt->alloc_len = input_frame->alloc_len; + pkt->filled_len = input_frame->filled_len; + pkt->input_tag = input_frame->clnt_data; + pkt->packet_buffer = (u32)input_frame->device_addr; + + trace_msm_v4l2_vidc_buffer_event_start("ETB", + input_frame->device_addr, input_frame->timestamp, + input_frame->alloc_len, input_frame->filled_len, + input_frame->offset); + + if (!pkt->packet_buffer) + rc = -EINVAL; + return rc; +} + +int create_pkt_cmd_session_etb_encoder( + struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet *pkt, + struct hal_session *session, struct vidc_frame_data *input_frame) +{ + int rc = 0; + + if (!pkt || !session) + return -EINVAL; + + pkt->size = sizeof(struct + hfi_cmd_session_empty_buffer_uncompressed_plane0_packet); + pkt->packet_type = HFI_CMD_SESSION_EMPTY_BUFFER; + pkt->session_id = hash32_ptr(session); + pkt->view_id = 0; + pkt->time_stamp_hi = upper_32_bits(input_frame->timestamp); + pkt->time_stamp_lo = lower_32_bits(input_frame->timestamp); + pkt->flags = input_frame->flags; + pkt->mark_target = input_frame->mark_target; + pkt->mark_data = input_frame->mark_data; + pkt->offset = input_frame->offset; + pkt->alloc_len = input_frame->alloc_len; + pkt->filled_len = input_frame->filled_len; + pkt->input_tag = input_frame->clnt_data; + pkt->packet_buffer = (u32)input_frame->device_addr; + pkt->extra_data_buffer = (u32)input_frame->extradata_addr; + + trace_msm_v4l2_vidc_buffer_event_start("ETB", + input_frame->device_addr, input_frame->timestamp, + input_frame->alloc_len, input_frame->filled_len, + input_frame->offset); + + if (!pkt->packet_buffer) + rc = -EINVAL; + return rc; +} + +int create_pkt_cmd_session_ftb(struct hfi_cmd_session_fill_buffer_packet *pkt, + struct hal_session *session, + struct vidc_frame_data *output_frame) +{ + int rc = 0; + + if (!pkt || !session || !output_frame) + return -EINVAL; + + pkt->size = sizeof(struct hfi_cmd_session_fill_buffer_packet); + pkt->packet_type = HFI_CMD_SESSION_FILL_BUFFER; + pkt->session_id = hash32_ptr(session); + + if (output_frame->buffer_type == HAL_BUFFER_OUTPUT) + pkt->stream_id = 0; + else if (output_frame->buffer_type == HAL_BUFFER_OUTPUT2) + pkt->stream_id = 1; + + if (!output_frame->device_addr) + return -EINVAL; + + pkt->packet_buffer = (u32)output_frame->device_addr; + pkt->extra_data_buffer = (u32)output_frame->extradata_addr; + pkt->alloc_len = output_frame->alloc_len; + pkt->filled_len = output_frame->filled_len; + pkt->offset = output_frame->offset; + pkt->rgData[0] = output_frame->extradata_size; + + trace_msm_v4l2_vidc_buffer_event_start("FTB", + output_frame->device_addr, output_frame->timestamp, + output_frame->alloc_len, output_frame->filled_len, + output_frame->offset); + + return rc; +} + +int create_pkt_cmd_session_get_buf_req( + struct hfi_cmd_session_get_property_packet *pkt, + struct hal_session *session) +{ + int rc = 0; + + if (!pkt || !session) + return -EINVAL; + + pkt->size = sizeof(struct hfi_cmd_session_get_property_packet); + pkt->packet_type = HFI_CMD_SESSION_GET_PROPERTY; + pkt->session_id = hash32_ptr(session); + pkt->num_properties = 1; + pkt->rg_property_data[0] = HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS; + + return rc; +} + +int create_pkt_cmd_session_flush(struct hfi_cmd_session_flush_packet *pkt, + struct hal_session *session, enum hal_flush flush_mode) +{ + int rc = 0; + + if (!pkt || !session) + return -EINVAL; + + pkt->size = sizeof(struct hfi_cmd_session_flush_packet); + pkt->packet_type = HFI_CMD_SESSION_FLUSH; + pkt->session_id = hash32_ptr(session); + switch (flush_mode) { + case HAL_FLUSH_INPUT: + pkt->flush_type = HFI_FLUSH_INPUT; + break; + case HAL_FLUSH_OUTPUT: + pkt->flush_type = HFI_FLUSH_OUTPUT; + break; + case HAL_FLUSH_ALL: + pkt->flush_type = HFI_FLUSH_ALL; + break; + default: + dprintk(VIDC_ERR, "Invalid flush mode: %#x\n", flush_mode); + return -EINVAL; + } + return rc; +} + +int create_pkt_cmd_session_set_property( + struct hfi_cmd_session_set_property_packet *pkt, + struct hal_session *session, + u32 ptype, void *pdata, u32 size) +{ + if (!pkt || !session) + return -EINVAL; + + pkt->size = sizeof(struct hfi_cmd_session_set_property_packet); + pkt->packet_type = HFI_CMD_SESSION_SET_PROPERTY; + pkt->session_id = hash32_ptr(session); + pkt->num_properties = 1; + pkt->size += size; + pkt->rg_property_data[0] = ptype; + if (size && pdata) + memcpy(&pkt->rg_property_data[1], pdata, size); + + dprintk(VIDC_DBG, "Setting HAL Property = 0x%x\n", ptype); + return 0; +} + +static int get_hfi_ssr_type(enum hal_ssr_trigger_type type) +{ + int rc = HFI_TEST_SSR_HW_WDOG_IRQ; + + switch (type) { + case SSR_ERR_FATAL: + rc = HFI_TEST_SSR_SW_ERR_FATAL; + break; + case SSR_SW_DIV_BY_ZERO: + rc = HFI_TEST_SSR_SW_DIV_BY_ZERO; + break; + case SSR_HW_WDOG_IRQ: + rc = HFI_TEST_SSR_HW_WDOG_IRQ; + break; + default: + dprintk(VIDC_WARN, + "SSR trigger type not recognized, using WDOG.\n"); + } + return rc; +} + +int create_pkt_ssr_cmd(enum hal_ssr_trigger_type type, + struct hfi_cmd_sys_test_ssr_packet *pkt) +{ + if (!pkt) { + dprintk(VIDC_ERR, "Invalid params, device: %pK\n", pkt); + return -EINVAL; + } + pkt->size = sizeof(struct hfi_cmd_sys_test_ssr_packet); + pkt->packet_type = HFI_CMD_SYS_TEST_SSR; + pkt->trigger_type = get_hfi_ssr_type(type); + return 0; +} + +int create_pkt_cmd_sys_image_version( + struct hfi_cmd_sys_get_property_packet *pkt) +{ + if (!pkt) { + dprintk(VIDC_ERR, "%s invalid param :%pK\n", __func__, pkt); + return -EINVAL; + } + pkt->size = sizeof(struct hfi_cmd_sys_get_property_packet); + pkt->packet_type = HFI_CMD_SYS_GET_PROPERTY; + pkt->num_properties = 1; + pkt->rg_property_data[0] = HFI_PROPERTY_SYS_IMAGE_VERSION; + return 0; +} + +int create_pkt_cmd_session_sync_process( + struct hfi_cmd_session_sync_process_packet *pkt, + struct hal_session *session) +{ + if (!pkt || !session) + return -EINVAL; + + *pkt = (struct hfi_cmd_session_sync_process_packet) {0}; + pkt->size = sizeof(*pkt); + pkt->packet_type = HFI_CMD_SESSION_SYNC; + pkt->session_id = hash32_ptr(session); + pkt->sync_id = 0; + + return 0; +} + +static struct hfi_packetization_ops hfi_default = { + .sys_init = create_pkt_cmd_sys_init, + .sys_pc_prep = create_pkt_cmd_sys_pc_prep, + .sys_power_control = create_pkt_cmd_sys_power_control, + .sys_set_resource = create_pkt_cmd_sys_set_resource, + .sys_debug_config = create_pkt_cmd_sys_debug_config, + .sys_coverage_config = create_pkt_cmd_sys_coverage_config, + .sys_release_resource = create_pkt_cmd_sys_release_resource, + .sys_image_version = create_pkt_cmd_sys_image_version, + .sys_ubwc_config = create_pkt_cmd_sys_ubwc_config, + .ssr_cmd = create_pkt_ssr_cmd, + .session_init = create_pkt_cmd_sys_session_init, + .session_cmd = create_pkt_cmd_session_cmd, + .session_set_buffers = create_pkt_cmd_session_set_buffers, + .session_release_buffers = create_pkt_cmd_session_release_buffers, + .session_register_buffer = create_pkt_cmd_session_register_buffer, + .session_unregister_buffer = create_pkt_cmd_session_unregister_buffer, + .session_etb_decoder = create_pkt_cmd_session_etb_decoder, + .session_etb_encoder = create_pkt_cmd_session_etb_encoder, + .session_ftb = create_pkt_cmd_session_ftb, + .session_get_buf_req = create_pkt_cmd_session_get_buf_req, + .session_flush = create_pkt_cmd_session_flush, + .session_set_property = create_pkt_cmd_session_set_property, +}; + +struct hfi_packetization_ops *hfi_get_pkt_ops_handle( + enum hfi_packetization_type type) +{ + dprintk(VIDC_DBG, "%s selected\n", + type == HFI_PACKETIZATION_4XX ? + "4xx packetization" : "Unknown hfi"); + + switch (type) { + case HFI_PACKETIZATION_4XX: + return &hfi_default; + } + + return NULL; +} diff --git a/msm/vidc/hfi_packetization.h b/msm/vidc/hfi_packetization.h new file mode 100644 index 000000000000..d3bb415c27d7 --- /dev/null +++ b/msm/vidc/hfi_packetization.h @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ +#ifndef __HFI_PACKETIZATION_H__ +#define __HFI_PACKETIZATION_H__ + +#include +#include "vidc_hfi_helper.h" +#include "vidc_hfi.h" +#include "vidc_hfi_api.h" + +#define call_hfi_pkt_op(q, op, ...) \ + (((q) && (q)->pkt_ops && (q)->pkt_ops->op) ? \ + ((q)->pkt_ops->op(__VA_ARGS__)) : 0) + +enum hfi_packetization_type { + HFI_PACKETIZATION_4XX, +}; + +struct hfi_packetization_ops { + int (*sys_init)(struct hfi_cmd_sys_init_packet *pkt, u32 arch_type); + int (*sys_pc_prep)(struct hfi_cmd_sys_pc_prep_packet *pkt); + int (*sys_power_control)(struct hfi_cmd_sys_set_property_packet *pkt, + u32 enable); + int (*sys_set_resource)( + struct hfi_cmd_sys_set_resource_packet *pkt, + struct vidc_resource_hdr *resource_hdr, + void *resource_value); + int (*sys_debug_config)(struct hfi_cmd_sys_set_property_packet *pkt, + u32 mode); + int (*sys_coverage_config)(struct hfi_cmd_sys_set_property_packet *pkt, + u32 mode); + int (*sys_release_resource)( + struct hfi_cmd_sys_release_resource_packet *pkt, + struct vidc_resource_hdr *resource_hdr); + int (*sys_image_version)(struct hfi_cmd_sys_get_property_packet *pkt); + int (*sys_ubwc_config)(struct hfi_cmd_sys_set_property_packet *pkt, + struct msm_vidc_ubwc_config_data *ubwc_config); + int (*ssr_cmd)(enum hal_ssr_trigger_type type, + struct hfi_cmd_sys_test_ssr_packet *pkt); + int (*session_init)( + struct hfi_cmd_sys_session_init_packet *pkt, + struct hal_session *session, + u32 session_domain, u32 session_codec); + int (*session_cmd)(struct vidc_hal_session_cmd_pkt *pkt, + int pkt_type, struct hal_session *session); + int (*session_set_buffers)( + struct hfi_cmd_session_set_buffers_packet *pkt, + struct hal_session *session, + struct vidc_buffer_addr_info *buffer_info); + int (*session_release_buffers)( + struct hfi_cmd_session_release_buffer_packet *pkt, + struct hal_session *session, + struct vidc_buffer_addr_info *buffer_info); + int (*session_register_buffer)( + struct hfi_cmd_session_register_buffers_packet *pkt, + struct hal_session *session, + struct vidc_register_buffer *buffer); + int (*session_unregister_buffer)( + struct hfi_cmd_session_unregister_buffers_packet *pkt, + struct hal_session *session, + struct vidc_unregister_buffer *buffer); + int (*session_etb_decoder)( + struct hfi_cmd_session_empty_buffer_compressed_packet *pkt, + struct hal_session *session, + struct vidc_frame_data *input_frame); + int (*session_etb_encoder)( + struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet + *pkt, struct hal_session *session, + struct vidc_frame_data *input_frame); + int (*session_ftb)(struct hfi_cmd_session_fill_buffer_packet *pkt, + struct hal_session *session, + struct vidc_frame_data *output_frame); + int (*session_get_buf_req)( + struct hfi_cmd_session_get_property_packet *pkt, + struct hal_session *session); + int (*session_flush)(struct hfi_cmd_session_flush_packet *pkt, + struct hal_session *session, enum hal_flush flush_mode); + int (*session_set_property)( + struct hfi_cmd_session_set_property_packet *pkt, + struct hal_session *session, + u32 ptype, void *pdata, u32 size); + int (*session_sync_process)( + struct hfi_cmd_session_sync_process_packet *pkt, + struct hal_session *session); +}; + +struct hfi_packetization_ops *hfi_get_pkt_ops_handle( + enum hfi_packetization_type); +#endif diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c new file mode 100644 index 000000000000..ef55a3a3f28a --- /dev/null +++ b/msm/vidc/hfi_response_handler.c @@ -0,0 +1,1288 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "vidc_hfi_helper.h" +#include "vidc_hfi_io.h" +#include "msm_vidc_debug.h" +#include "vidc_hfi.h" + +static enum vidc_status hfi_map_err_status(u32 hfi_err) +{ + enum vidc_status vidc_err; + + switch (hfi_err) { + case HFI_ERR_NONE: + case HFI_ERR_SESSION_SAME_STATE_OPERATION: + vidc_err = VIDC_ERR_NONE; + break; + case HFI_ERR_SYS_FATAL: + vidc_err = VIDC_ERR_HW_FATAL; + break; + case HFI_ERR_SYS_NOC_ERROR: + vidc_err = VIDC_ERR_NOC_ERROR; + break; + case HFI_ERR_SYS_VERSION_MISMATCH: + case HFI_ERR_SYS_INVALID_PARAMETER: + case HFI_ERR_SYS_SESSION_ID_OUT_OF_RANGE: + case HFI_ERR_SESSION_INVALID_PARAMETER: + case HFI_ERR_SESSION_INVALID_SESSION_ID: + case HFI_ERR_SESSION_INVALID_STREAM_ID: + vidc_err = VIDC_ERR_BAD_PARAM; + break; + case HFI_ERR_SYS_INSUFFICIENT_RESOURCES: + case HFI_ERR_SYS_UNSUPPORTED_DOMAIN: + case HFI_ERR_SYS_UNSUPPORTED_CODEC: + case HFI_ERR_SESSION_UNSUPPORTED_PROPERTY: + case HFI_ERR_SESSION_UNSUPPORTED_SETTING: + case HFI_ERR_SESSION_INSUFFICIENT_RESOURCES: + case HFI_ERR_SESSION_UNSUPPORTED_STREAM: + vidc_err = VIDC_ERR_NOT_SUPPORTED; + break; + case HFI_ERR_SYS_MAX_SESSIONS_REACHED: + vidc_err = VIDC_ERR_MAX_CLIENTS; + break; + case HFI_ERR_SYS_SESSION_IN_USE: + vidc_err = VIDC_ERR_CLIENT_PRESENT; + break; + case HFI_ERR_SESSION_FATAL: + vidc_err = VIDC_ERR_CLIENT_FATAL; + break; + case HFI_ERR_SESSION_BAD_POINTER: + vidc_err = VIDC_ERR_BAD_PARAM; + break; + case HFI_ERR_SESSION_INCORRECT_STATE_OPERATION: + vidc_err = VIDC_ERR_BAD_STATE; + break; + case HFI_ERR_SESSION_STREAM_CORRUPT: + case HFI_ERR_SESSION_STREAM_CORRUPT_OUTPUT_STALLED: + vidc_err = VIDC_ERR_BITSTREAM_ERR; + break; + case HFI_ERR_SESSION_SYNC_FRAME_NOT_DETECTED: + vidc_err = VIDC_ERR_IFRAME_EXPECTED; + break; + case HFI_ERR_SESSION_START_CODE_NOT_FOUND: + vidc_err = VIDC_ERR_START_CODE_NOT_FOUND; + break; + case HFI_ERR_SESSION_EMPTY_BUFFER_DONE_OUTPUT_PENDING: + default: + vidc_err = VIDC_ERR_FAIL; + break; + } + return vidc_err; +} + +static int get_hal_pixel_depth(u32 hfi_bit_depth) +{ + switch (hfi_bit_depth) { + case HFI_BITDEPTH_8: return MSM_VIDC_BIT_DEPTH_8; + case HFI_BITDEPTH_9: + case HFI_BITDEPTH_10: return MSM_VIDC_BIT_DEPTH_10; + } + dprintk(VIDC_ERR, "Unsupported bit depth: %d\n", hfi_bit_depth); + return MSM_VIDC_BIT_DEPTH_UNSUPPORTED; +} + +static int hfi_process_sess_evt_seq_changed(u32 device_id, + struct hfi_msg_event_notify_packet *pkt, + struct msm_vidc_cb_info *info) +{ + struct msm_vidc_cb_event event_notify = {0}; + int num_properties_changed; + struct hfi_frame_size *frame_sz; + struct hfi_profile_level *profile_level; + struct hfi_bit_depth *pixel_depth; + struct hfi_pic_struct *pic_struct; + struct hfi_buffer_requirements *buf_req; + struct hfi_index_extradata_input_crop_payload *crop_info; + u32 entropy_mode = 0; + u8 *data_ptr; + int prop_id; + int luma_bit_depth, chroma_bit_depth; + struct hfi_colour_space *colour_info; + + if (sizeof(struct hfi_msg_event_notify_packet) > pkt->size) { + dprintk(VIDC_ERR, + "hal_process_session_init_done: bad_pkt_size\n"); + return -E2BIG; + } + + event_notify.device_id = device_id; + event_notify.session_id = (void *)(uintptr_t)pkt->session_id; + event_notify.status = VIDC_ERR_NONE; + num_properties_changed = pkt->event_data2; + switch (pkt->event_data1) { + case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUFFER_RESOURCES: + event_notify.hal_event_type = + HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES; + break; + case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUFFER_RESOURCES: + event_notify.hal_event_type = + HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES; + break; + default: + break; + } + + if (num_properties_changed) { + data_ptr = (u8 *) &pkt->rg_ext_event_data[0]; + do { + prop_id = (int) *((u32 *)data_ptr); + switch (prop_id) { + case HFI_PROPERTY_PARAM_FRAME_SIZE: + data_ptr = data_ptr + sizeof(u32); + frame_sz = + (struct hfi_frame_size *) data_ptr; + event_notify.width = frame_sz->width; + event_notify.height = frame_sz->height; + dprintk(VIDC_DBG, "height: %d width: %d\n", + frame_sz->height, frame_sz->width); + data_ptr += + sizeof(struct hfi_frame_size); + break; + case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT: + data_ptr = data_ptr + sizeof(u32); + profile_level = + (struct hfi_profile_level *) data_ptr; + event_notify.profile = profile_level->profile; + event_notify.level = profile_level->level; + dprintk(VIDC_DBG, "profile: %d level: %d\n", + profile_level->profile, + profile_level->level); + data_ptr += + sizeof(struct hfi_profile_level); + break; + case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH: + data_ptr = data_ptr + sizeof(u32); + pixel_depth = (struct hfi_bit_depth *) data_ptr; + /* + * Luma and chroma can have different bitdepths. + * Driver should rely on luma and chroma + * bitdepth for determining output bitdepth + * type. + * + * pixel_depth->bitdepth will include luma + * bitdepth info in bits 0..15 and chroma + * bitdept in bits 16..31. + */ + luma_bit_depth = get_hal_pixel_depth( + pixel_depth->bit_depth & + GENMASK(15, 0)); + chroma_bit_depth = get_hal_pixel_depth( + (pixel_depth->bit_depth & + GENMASK(31, 16)) >> 16); + if (luma_bit_depth == MSM_VIDC_BIT_DEPTH_10 || + chroma_bit_depth == + MSM_VIDC_BIT_DEPTH_10) + event_notify.bit_depth = + MSM_VIDC_BIT_DEPTH_10; + else + event_notify.bit_depth = luma_bit_depth; + dprintk(VIDC_DBG, + "bitdepth(%d), luma_bit_depth(%d), chroma_bit_depth(%d)\n", + event_notify.bit_depth, luma_bit_depth, + chroma_bit_depth); + data_ptr += sizeof(struct hfi_bit_depth); + break; + case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT: + data_ptr = data_ptr + sizeof(u32); + pic_struct = (struct hfi_pic_struct *) data_ptr; + event_notify.pic_struct = + pic_struct->progressive_only; + dprintk(VIDC_DBG, + "Progressive only flag: %d\n", + pic_struct->progressive_only); + data_ptr += + sizeof(struct hfi_pic_struct); + break; + case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE: + data_ptr = data_ptr + sizeof(u32); + colour_info = + (struct hfi_colour_space *) data_ptr; + event_notify.colour_space = + colour_info->colour_space; + dprintk(VIDC_DBG, + "Colour space value is: %d\n", + colour_info->colour_space); + data_ptr += + sizeof(struct hfi_colour_space); + break; + case HFI_PROPERTY_CONFIG_VDEC_ENTROPY: + data_ptr = data_ptr + sizeof(u32); + entropy_mode = *(u32 *)data_ptr; + event_notify.entropy_mode = entropy_mode; + dprintk(VIDC_DBG, + "Entropy Mode: 0x%x\n", entropy_mode); + data_ptr += + sizeof(u32); + break; + case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS: + data_ptr = data_ptr + sizeof(u32); + buf_req = + (struct hfi_buffer_requirements *) + data_ptr; + event_notify.capture_buf_count = + buf_req->buffer_count_min; + dprintk(VIDC_DBG, + "Capture Count : 0x%x\n", + event_notify.capture_buf_count); + data_ptr += + sizeof(struct hfi_buffer_requirements); + break; + case HFI_INDEX_EXTRADATA_INPUT_CROP: + data_ptr = data_ptr + sizeof(u32); + crop_info = (struct + hfi_index_extradata_input_crop_payload *) + data_ptr; + event_notify.crop_data.left = crop_info->left; + event_notify.crop_data.top = crop_info->top; + event_notify.crop_data.width = crop_info->width; + event_notify.crop_data.height = + crop_info->height; + dprintk(VIDC_DBG, + "CROP info : Left = %d Top = %d\n", + crop_info->left, + crop_info->top); + dprintk(VIDC_DBG, + "CROP info : Width = %d Height = %d\n", + crop_info->width, + crop_info->height); + data_ptr += + sizeof(struct + hfi_index_extradata_input_crop_payload); + break; + default: + dprintk(VIDC_ERR, + "%s cmd: %#x not supported\n", + __func__, prop_id); + break; + } + num_properties_changed--; + } while (num_properties_changed > 0); + } + + info->response_type = HAL_SESSION_EVENT_CHANGE; + info->response.event = event_notify; + + return 0; +} + +static int hfi_process_evt_release_buffer_ref(u32 device_id, + struct hfi_msg_event_notify_packet *pkt, + struct msm_vidc_cb_info *info) +{ + struct msm_vidc_cb_event event_notify = {0}; + struct hfi_msg_release_buffer_ref_event_packet *data; + + dprintk(VIDC_DBG, + "RECEIVED: EVENT_NOTIFY - release_buffer_reference\n"); + if (sizeof(struct hfi_msg_event_notify_packet) + > pkt->size) { + dprintk(VIDC_ERR, + "hal_process_session_init_done: bad_pkt_size\n"); + return -E2BIG; + } + + data = (struct hfi_msg_release_buffer_ref_event_packet *) + pkt->rg_ext_event_data; + + event_notify.device_id = device_id; + event_notify.session_id = (void *)(uintptr_t)pkt->session_id; + event_notify.status = VIDC_ERR_NONE; + event_notify.hal_event_type = HAL_EVENT_RELEASE_BUFFER_REFERENCE; + event_notify.packet_buffer = data->packet_buffer; + event_notify.extra_data_buffer = data->extra_data_buffer; + + info->response_type = HAL_SESSION_EVENT_CHANGE; + info->response.event = event_notify; + + return 0; +} + +static int hfi_process_sys_error(u32 device_id, + struct hfi_msg_event_notify_packet *pkt, + struct msm_vidc_cb_info *info) +{ + struct msm_vidc_cb_cmd_done cmd_done = {0}; + + cmd_done.device_id = device_id; + cmd_done.status = hfi_map_err_status(pkt->event_data1); + + info->response_type = HAL_SYS_ERROR; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_error(u32 device_id, + struct hfi_msg_event_notify_packet *pkt, + struct msm_vidc_cb_info *info) +{ + struct msm_vidc_cb_cmd_done cmd_done = {0}; + + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->event_data1); + info->response.cmd = cmd_done; + dprintk(VIDC_INFO, "Received: SESSION_ERROR with event id : %#x %#x\n", + pkt->event_data1, pkt->event_data2); + switch (pkt->event_data1) { + /* Ignore below errors */ + case HFI_ERR_SESSION_INVALID_SCALE_FACTOR: + case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED: + dprintk(VIDC_INFO, "Non Fatal: HFI_EVENT_SESSION_ERROR\n"); + info->response_type = HAL_RESPONSE_UNUSED; + break; + default: + dprintk(VIDC_ERR, + "%s: session %x data1 %#x, data2 %#x\n", __func__, + pkt->session_id, pkt->event_data1, pkt->event_data2); + info->response_type = HAL_SESSION_ERROR; + break; + } + + return 0; +} + +static int hfi_process_event_notify(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_event_notify_packet *pkt = _pkt; + dprintk(VIDC_DBG, "Received: EVENT_NOTIFY\n"); + + if (pkt->size < sizeof(struct hfi_msg_event_notify_packet)) { + dprintk(VIDC_ERR, "Invalid Params\n"); + return -E2BIG; + } + + switch (pkt->event_id) { + case HFI_EVENT_SYS_ERROR: + dprintk(VIDC_ERR, "HFI_EVENT_SYS_ERROR: %d, %#x\n", + pkt->event_data1, pkt->event_data2); + return hfi_process_sys_error(device_id, pkt, info); + case HFI_EVENT_SESSION_ERROR: + dprintk(VIDC_INFO, "HFI_EVENT_SESSION_ERROR[%#x]\n", + pkt->session_id); + return hfi_process_session_error(device_id, pkt, info); + + case HFI_EVENT_SESSION_SEQUENCE_CHANGED: + dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED[%#x]\n", + pkt->session_id); + return hfi_process_sess_evt_seq_changed(device_id, pkt, info); + + case HFI_EVENT_RELEASE_BUFFER_REFERENCE: + dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE[%#x]\n", + pkt->session_id); + return hfi_process_evt_release_buffer_ref(device_id, pkt, info); + + case HFI_EVENT_SESSION_PROPERTY_CHANGED: + default: + *info = (struct msm_vidc_cb_info) { + .response_type = HAL_RESPONSE_UNUSED, + }; + + return 0; + } +} + +static int hfi_process_sys_init_done(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_sys_init_done_packet *pkt = _pkt; + struct msm_vidc_cb_cmd_done cmd_done = {0}; + enum vidc_status status = VIDC_ERR_NONE; + + dprintk(VIDC_DBG, "RECEIVED: SYS_INIT_DONE\n"); + if (sizeof(struct hfi_msg_sys_init_done_packet) > pkt->size) { + dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", __func__, + pkt->size); + return -E2BIG; + } + status = hfi_map_err_status(pkt->error_type); + if (status) + dprintk(VIDC_ERR, "%s: status %#x\n", + __func__, status); + + cmd_done.device_id = device_id; + cmd_done.session_id = NULL; + cmd_done.status = (u32)status; + cmd_done.size = sizeof(struct vidc_hal_sys_init_done); + + info->response_type = HAL_SYS_INIT_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_sys_rel_resource_done(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_sys_release_resource_done_packet *pkt = _pkt; + struct msm_vidc_cb_cmd_done cmd_done = {0}; + enum vidc_status status = VIDC_ERR_NONE; + u32 pkt_size; + + dprintk(VIDC_DBG, "RECEIVED: SYS_RELEASE_RESOURCE_DONE\n"); + pkt_size = sizeof(struct hfi_msg_sys_release_resource_done_packet); + if (pkt_size > pkt->size) { + dprintk(VIDC_ERR, + "hal_process_sys_rel_resource_done: bad size: %d\n", + pkt->size); + return -E2BIG; + } + + status = hfi_map_err_status(pkt->error_type); + cmd_done.device_id = device_id; + cmd_done.session_id = NULL; + cmd_done.status = (u32) status; + cmd_done.size = 0; + + info->response_type = HAL_SYS_RELEASE_RESOURCE_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static void hfi_process_sess_get_prop_buf_req( + struct hfi_msg_session_property_info_packet *prop, + struct buffer_requirements *buffreq) +{ + struct hfi_buffer_requirements *hfi_buf_req; + u32 req_bytes; + + if (!prop) { + dprintk(VIDC_ERR, + "hal_process_sess_get_prop_buf_req: bad_prop: %pK\n", + prop); + return; + } + + req_bytes = prop->size - sizeof( + struct hfi_msg_session_property_info_packet); + if (!req_bytes || req_bytes % sizeof(struct hfi_buffer_requirements) || + !prop->rg_property_data[1]) { + dprintk(VIDC_ERR, + "hal_process_sess_get_prop_buf_req: bad_pkt: %d\n", + req_bytes); + return; + } + + hfi_buf_req = (struct hfi_buffer_requirements *) + &prop->rg_property_data[1]; + + if (!hfi_buf_req) { + dprintk(VIDC_ERR, "%s - invalid buffer req pointer\n", + __func__); + return; + } + + while (req_bytes) { + dprintk(VIDC_DBG, "got buffer requirements for: %d\n", + hfi_buf_req->buffer_type); + switch (hfi_buf_req->buffer_type) { + case HFI_BUFFER_INPUT: + memcpy(&buffreq->buffer[0], hfi_buf_req, + sizeof(struct hfi_buffer_requirements)); + buffreq->buffer[0].buffer_type = HAL_BUFFER_INPUT; + break; + case HFI_BUFFER_OUTPUT: + memcpy(&buffreq->buffer[1], hfi_buf_req, + sizeof(struct hfi_buffer_requirements)); + buffreq->buffer[1].buffer_type = HAL_BUFFER_OUTPUT; + break; + case HFI_BUFFER_OUTPUT2: + memcpy(&buffreq->buffer[2], hfi_buf_req, + sizeof(struct hfi_buffer_requirements)); + buffreq->buffer[2].buffer_type = HAL_BUFFER_OUTPUT2; + break; + case HFI_BUFFER_EXTRADATA_INPUT: + memcpy(&buffreq->buffer[3], hfi_buf_req, + sizeof(struct hfi_buffer_requirements)); + buffreq->buffer[3].buffer_type = + HAL_BUFFER_EXTRADATA_INPUT; + break; + case HFI_BUFFER_EXTRADATA_OUTPUT: + memcpy(&buffreq->buffer[4], hfi_buf_req, + sizeof(struct hfi_buffer_requirements)); + buffreq->buffer[4].buffer_type = + HAL_BUFFER_EXTRADATA_OUTPUT; + break; + case HFI_BUFFER_EXTRADATA_OUTPUT2: + memcpy(&buffreq->buffer[5], hfi_buf_req, + sizeof(struct hfi_buffer_requirements)); + buffreq->buffer[5].buffer_type = + HAL_BUFFER_EXTRADATA_OUTPUT2; + break; + case HFI_BUFFER_COMMON_INTERNAL_SCRATCH: + memcpy(&buffreq->buffer[6], hfi_buf_req, + sizeof(struct hfi_buffer_requirements)); + buffreq->buffer[6].buffer_type = + HAL_BUFFER_INTERNAL_SCRATCH; + break; + case HFI_BUFFER_COMMON_INTERNAL_SCRATCH_1: + memcpy(&buffreq->buffer[7], hfi_buf_req, + sizeof(struct hfi_buffer_requirements)); + buffreq->buffer[7].buffer_type = + HAL_BUFFER_INTERNAL_SCRATCH_1; + break; + case HFI_BUFFER_COMMON_INTERNAL_SCRATCH_2: + memcpy(&buffreq->buffer[8], hfi_buf_req, + sizeof(struct hfi_buffer_requirements)); + buffreq->buffer[8].buffer_type = + HAL_BUFFER_INTERNAL_SCRATCH_2; + break; + case HFI_BUFFER_INTERNAL_PERSIST: + memcpy(&buffreq->buffer[9], hfi_buf_req, + sizeof(struct hfi_buffer_requirements)); + buffreq->buffer[9].buffer_type = + HAL_BUFFER_INTERNAL_PERSIST; + break; + case HFI_BUFFER_INTERNAL_PERSIST_1: + memcpy(&buffreq->buffer[10], hfi_buf_req, + sizeof(struct hfi_buffer_requirements)); + buffreq->buffer[10].buffer_type = + HAL_BUFFER_INTERNAL_PERSIST_1; + break; + case HFI_BUFFER_COMMON_INTERNAL_RECON: + memcpy(&buffreq->buffer[11], hfi_buf_req, + sizeof(struct hfi_buffer_requirements)); + buffreq->buffer[11].buffer_type = + HAL_BUFFER_INTERNAL_RECON; + break; + default: + dprintk(VIDC_ERR, + "hal_process_sess_get_prop_buf_req: bad_buffer_type: %d\n", + hfi_buf_req->buffer_type); + break; + } + req_bytes -= sizeof(struct hfi_buffer_requirements); + hfi_buf_req++; + } +} + +static int hfi_process_session_prop_info(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_session_property_info_packet *pkt = _pkt; + struct msm_vidc_cb_cmd_done cmd_done = {0}; + struct buffer_requirements buff_req = { { {0} } }; + + dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO[%#x]\n", + pkt->session_id); + + if (pkt->size < sizeof(struct hfi_msg_session_property_info_packet)) { + dprintk(VIDC_ERR, + "hal_process_session_prop_info: bad_pkt_size\n"); + return -E2BIG; + } else if (!pkt->num_properties) { + dprintk(VIDC_ERR, + "hal_process_session_prop_info: no_properties\n"); + return -EINVAL; + } + + switch (pkt->rg_property_data[0]) { + case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS: + hfi_process_sess_get_prop_buf_req(pkt, &buff_req); + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = VIDC_ERR_NONE; + cmd_done.data.property.buf_req = buff_req; + cmd_done.size = sizeof(buff_req); + + info->response_type = HAL_SESSION_PROPERTY_INFO; + info->response.cmd = cmd_done; + + return 0; + default: + dprintk(VIDC_DBG, + "hal_process_session_prop_info: unknown_prop_id: %x\n", + pkt->rg_property_data[0]); + return -ENOTSUPP; + } +} + +static int hfi_process_session_init_done(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_sys_session_init_done_packet *pkt = _pkt; + struct msm_vidc_cb_cmd_done cmd_done = {0}; + struct vidc_hal_session_init_done session_init_done = { {0} }; + + dprintk(VIDC_DBG, "RECEIVED: SESSION_INIT_DONE[%x]\n", pkt->session_id); + + if (sizeof(struct hfi_msg_sys_session_init_done_packet) > pkt->size) { + dprintk(VIDC_ERR, + "hal_process_session_init_done: bad_pkt_size\n"); + return -E2BIG; + } + + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + cmd_done.data.session_init_done = session_init_done; + cmd_done.size = sizeof(struct vidc_hal_session_init_done); + + info->response_type = HAL_SESSION_INIT_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_load_res_done(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_session_load_resources_done_packet *pkt = _pkt; + struct msm_vidc_cb_cmd_done cmd_done = {0}; + + dprintk(VIDC_DBG, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%#x]\n", + pkt->session_id); + + if (sizeof(struct hfi_msg_session_load_resources_done_packet) != + pkt->size) { + dprintk(VIDC_ERR, + "hal_process_session_load_res_done: bad packet size: %d\n", + pkt->size); + return -E2BIG; + } + + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + cmd_done.size = 0; + + info->response_type = HAL_SESSION_LOAD_RESOURCE_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_flush_done(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_session_flush_done_packet *pkt = _pkt; + struct msm_vidc_cb_cmd_done cmd_done = {0}; + + dprintk(VIDC_DBG, "RECEIVED: SESSION_FLUSH_DONE[%#x]\n", + pkt->session_id); + + if (sizeof(struct hfi_msg_session_flush_done_packet) != pkt->size) { + dprintk(VIDC_ERR, + "hal_process_session_flush_done: bad packet size: %d\n", + pkt->size); + return -E2BIG; + } + + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + cmd_done.size = sizeof(u32); + + switch (pkt->flush_type) { + case HFI_FLUSH_OUTPUT: + cmd_done.data.flush_type = HAL_FLUSH_OUTPUT; + break; + case HFI_FLUSH_INPUT: + cmd_done.data.flush_type = HAL_FLUSH_INPUT; + break; + case HFI_FLUSH_ALL: + cmd_done.data.flush_type = HAL_FLUSH_ALL; + break; + default: + dprintk(VIDC_ERR, + "%s: invalid flush type!", __func__); + return -EINVAL; + } + + info->response_type = HAL_SESSION_FLUSH_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_etb_done(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_session_empty_buffer_done_packet *pkt = _pkt; + struct msm_vidc_cb_data_done data_done = {0}; + struct hfi_picture_type *hfi_picture_type = NULL; + + dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%#x]\n", pkt->session_id); + + if (!pkt || pkt->size < + sizeof(struct hfi_msg_session_empty_buffer_done_packet)) { + dprintk(VIDC_ERR, + "hal_process_session_etb_done: bad_pkt_size\n"); + return -E2BIG; + } + + data_done.device_id = device_id; + data_done.session_id = (void *)(uintptr_t)pkt->session_id; + data_done.status = hfi_map_err_status(pkt->error_type); + data_done.size = sizeof(struct msm_vidc_cb_data_done); + data_done.clnt_data = pkt->input_tag; + data_done.input_done.recon_stats.buffer_index = + pkt->ubwc_cr_stats.frame_index; + memcpy(&data_done.input_done.recon_stats.ubwc_stats_info, + &pkt->ubwc_cr_stats.ubwc_stats_info, + sizeof(data_done.input_done.recon_stats.ubwc_stats_info)); + data_done.input_done.recon_stats.complexity_number = + pkt->ubwc_cr_stats.complexity_number; + data_done.input_done.offset = pkt->offset; + data_done.input_done.filled_len = pkt->filled_len; + data_done.input_done.packet_buffer = pkt->packet_buffer; + data_done.input_done.extra_data_buffer = pkt->extra_data_buffer; + data_done.input_done.status = + hfi_map_err_status(pkt->error_type); + hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[0]; + if (hfi_picture_type->is_sync_frame) { + if (hfi_picture_type->picture_type) + data_done.input_done.flags = + hfi_picture_type->picture_type; + else + dprintk(VIDC_DBG, + "Non-Sync frame sent for H264/HEVC\n"); + } + + trace_msm_v4l2_vidc_buffer_event_end("ETB", + (u32)pkt->packet_buffer, -1, -1, + pkt->filled_len, pkt->offset); + + info->response_type = HAL_SESSION_ETB_DONE; + info->response.data = data_done; + + return 0; +} + +static int hfi_process_session_ftb_done( + u32 device_id, void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct vidc_hal_msg_pkt_hdr *msg_hdr = _pkt; + struct msm_vidc_cb_data_done data_done = {0}; + bool is_decoder = false, is_encoder = false; + + if (!msg_hdr) { + dprintk(VIDC_ERR, "Invalid Params\n"); + return -EINVAL; + } + + is_encoder = msg_hdr->size == sizeof(struct + hfi_msg_session_fill_buffer_done_compressed_packet) + 4; + is_decoder = msg_hdr->size == sizeof(struct + hfi_msg_session_fbd_uncompressed_plane0_packet) + 4; + + if (!(is_encoder ^ is_decoder)) { + dprintk(VIDC_ERR, "Ambiguous packet (%#x) received (size %d)\n", + msg_hdr->packet, msg_hdr->size); + return -EBADHANDLE; + } + + if (is_encoder) { + struct hfi_msg_session_fill_buffer_done_compressed_packet *pkt = + (struct hfi_msg_session_fill_buffer_done_compressed_packet *) + msg_hdr; + dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%#x]\n", + pkt->session_id); + if (sizeof(struct + hfi_msg_session_fill_buffer_done_compressed_packet) + > pkt->size) { + dprintk(VIDC_ERR, + "hal_process_session_ftb_done: bad_pkt_size\n"); + return -E2BIG; + } else if (pkt->error_type != HFI_ERR_NONE) { + dprintk(VIDC_ERR, + "got buffer back with error %x\n", + pkt->error_type); + /* Proceed with the FBD */ + } + + data_done.device_id = device_id; + data_done.session_id = (void *)(uintptr_t)pkt->session_id; + data_done.status = hfi_map_err_status(pkt->error_type); + data_done.size = sizeof(struct msm_vidc_cb_data_done); + data_done.clnt_data = 0; + + data_done.output_done.timestamp_hi = pkt->time_stamp_hi; + data_done.output_done.timestamp_lo = pkt->time_stamp_lo; + data_done.output_done.flags1 = pkt->flags; + data_done.output_done.mark_target = pkt->mark_target; + data_done.output_done.mark_data = pkt->mark_data; + data_done.output_done.stats = pkt->stats; + data_done.output_done.offset1 = pkt->offset; + data_done.output_done.alloc_len1 = pkt->alloc_len; + data_done.output_done.filled_len1 = pkt->filled_len; + data_done.output_done.picture_type = pkt->picture_type; + data_done.output_done.packet_buffer1 = pkt->packet_buffer; + data_done.output_done.extra_data_buffer = + pkt->extra_data_buffer; + data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT; + } else /* if (is_decoder) */ { + struct hfi_msg_session_fbd_uncompressed_plane0_packet *pkt = + (struct hfi_msg_session_fbd_uncompressed_plane0_packet *) + msg_hdr; + + dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%#x]\n", + pkt->session_id); + if (sizeof( + struct hfi_msg_session_fbd_uncompressed_plane0_packet) > + pkt->size) { + dprintk(VIDC_ERR, + "hal_process_session_ftb_done: bad_pkt_size\n"); + return -E2BIG; + } + + data_done.device_id = device_id; + data_done.session_id = (void *)(uintptr_t)pkt->session_id; + data_done.status = hfi_map_err_status(pkt->error_type); + data_done.size = sizeof(struct msm_vidc_cb_data_done); + data_done.clnt_data = 0; + + data_done.output_done.stream_id = pkt->stream_id; + data_done.output_done.view_id = pkt->view_id; + data_done.output_done.timestamp_hi = pkt->time_stamp_hi; + data_done.output_done.timestamp_lo = pkt->time_stamp_lo; + data_done.output_done.flags1 = pkt->flags; + data_done.output_done.mark_target = pkt->mark_target; + data_done.output_done.mark_data = pkt->mark_data; + data_done.output_done.stats = pkt->stats; + data_done.output_done.alloc_len1 = pkt->alloc_len; + data_done.output_done.filled_len1 = pkt->filled_len; + data_done.output_done.offset1 = pkt->offset; + data_done.output_done.frame_width = pkt->frame_width; + data_done.output_done.frame_height = pkt->frame_height; + data_done.output_done.start_x_coord = pkt->start_x_coord; + data_done.output_done.start_y_coord = pkt->start_y_coord; + data_done.output_done.input_tag1 = pkt->input_tag; + data_done.output_done.picture_type = pkt->picture_type; + data_done.output_done.packet_buffer1 = pkt->packet_buffer; + data_done.output_done.extra_data_buffer = + pkt->extra_data_buffer; + + if (!pkt->stream_id) + data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT; + else if (pkt->stream_id == 1) + data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT2; + } + + trace_msm_v4l2_vidc_buffer_event_end("FTB", + (u32)data_done.output_done.packet_buffer1, + (((u64)data_done.output_done.timestamp_hi) << 32) + + ((u64)data_done.output_done.timestamp_lo), + data_done.output_done.alloc_len1, + data_done.output_done.filled_len1, + data_done.output_done.offset1); + + info->response_type = HAL_SESSION_FTB_DONE; + info->response.data = data_done; + + return 0; +} + +static int hfi_process_session_start_done(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_session_start_done_packet *pkt = _pkt; + struct msm_vidc_cb_cmd_done cmd_done = {0}; + + dprintk(VIDC_DBG, "RECEIVED: SESSION_START_DONE[%#x]\n", + pkt->session_id); + + if (!pkt || pkt->size != + sizeof(struct hfi_msg_session_start_done_packet)) { + dprintk(VIDC_ERR, "%s: bad packet/packet size\n", + __func__); + return -E2BIG; + } + + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + cmd_done.size = 0; + + info->response_type = HAL_SESSION_START_DONE; + info->response.cmd = cmd_done; + return 0; +} + +static int hfi_process_session_stop_done(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_session_stop_done_packet *pkt = _pkt; + struct msm_vidc_cb_cmd_done cmd_done = {0}; + + dprintk(VIDC_DBG, "RECEIVED: SESSION_STOP_DONE[%#x]\n", + pkt->session_id); + + if (!pkt || pkt->size != + sizeof(struct hfi_msg_session_stop_done_packet)) { + dprintk(VIDC_ERR, "%s: bad packet/packet size\n", + __func__); + return -E2BIG; + } + + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + cmd_done.size = 0; + + info->response_type = HAL_SESSION_STOP_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_rel_res_done(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_session_release_resources_done_packet *pkt = _pkt; + struct msm_vidc_cb_cmd_done cmd_done = {0}; + + dprintk(VIDC_DBG, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%#x]\n", + pkt->session_id); + + if (!pkt || pkt->size != + sizeof(struct hfi_msg_session_release_resources_done_packet)) { + dprintk(VIDC_ERR, "%s: bad packet/packet size\n", + __func__); + return -E2BIG; + } + + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + cmd_done.size = 0; + + info->response_type = HAL_SESSION_RELEASE_RESOURCE_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_rel_buf_done(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_session_release_buffers_done_packet *pkt = _pkt; + struct msm_vidc_cb_cmd_done cmd_done = {0}; + + if (!pkt || pkt->size < + sizeof(struct hfi_msg_session_release_buffers_done_packet)) { + dprintk(VIDC_ERR, "bad packet/packet size %d\n", + pkt ? pkt->size : 0); + return -E2BIG; + } + dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_BUFFER_DONE[%#x]\n", + pkt->session_id); + + cmd_done.device_id = device_id; + cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done); + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + cmd_done.data.buffer_info = + *(struct hal_buffer_info *)pkt->rg_buffer_info; + cmd_done.size = sizeof(struct hal_buffer_info); + + info->response_type = HAL_SESSION_RELEASE_BUFFER_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_register_buffer_done(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_session_register_buffers_done_packet *pkt = _pkt; + struct msm_vidc_cb_cmd_done cmd_done = {0}; + + if (!pkt || pkt->size < + sizeof(struct hfi_msg_session_register_buffers_done_packet)) { + dprintk(VIDC_ERR, "%s: bad packet/packet size %d\n", + __func__, pkt ? pkt->size : 0); + return -E2BIG; + } + dprintk(VIDC_DBG, "RECEIVED: SESSION_REGISTER_BUFFERS_DONE[%#x]\n", + pkt->session_id); + + cmd_done.device_id = device_id; + cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done); + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + cmd_done.data.regbuf.client_data = pkt->client_data; + + info->response_type = HAL_SESSION_REGISTER_BUFFER_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_unregister_buffer_done(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_session_unregister_buffers_done_packet *pkt = _pkt; + struct msm_vidc_cb_cmd_done cmd_done = {0}; + + if (!pkt || pkt->size < + sizeof(struct hfi_msg_session_unregister_buffers_done_packet)) { + dprintk(VIDC_ERR, "%s: bad packet/packet size %d\n", + __func__, pkt ? pkt->size : 0); + return -E2BIG; + } + dprintk(VIDC_DBG, "RECEIVED: SESSION_UNREGISTER_BUFFERS_DONE[%#x]\n", + pkt->session_id); + + cmd_done.device_id = device_id; + cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done); + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + cmd_done.data.unregbuf.client_data = pkt->client_data; + + info->response_type = HAL_SESSION_UNREGISTER_BUFFER_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_end_done(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_sys_session_end_done_packet *pkt = _pkt; + struct msm_vidc_cb_cmd_done cmd_done = {0}; + + dprintk(VIDC_DBG, "RECEIVED: SESSION_END_DONE[%#x]\n", pkt->session_id); + + if (!pkt || pkt->size != + sizeof(struct hfi_msg_sys_session_end_done_packet)) { + dprintk(VIDC_ERR, "%s: bad packet/packet size\n", __func__); + return -E2BIG; + } + + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + cmd_done.size = 0; + + info->response_type = HAL_SESSION_END_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_abort_done(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_sys_session_abort_done_packet *pkt = _pkt; + struct msm_vidc_cb_cmd_done cmd_done = {0}; + + dprintk(VIDC_DBG, "RECEIVED: SESSION_ABORT_DONE[%#x]\n", + pkt->session_id); + + if (!pkt || pkt->size != + sizeof(struct hfi_msg_sys_session_abort_done_packet)) { + dprintk(VIDC_ERR, "%s: bad packet/packet size: %d\n", + __func__, pkt ? pkt->size : 0); + return -E2BIG; + } + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + cmd_done.size = 0; + + info->response_type = HAL_SESSION_ABORT_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static void hfi_process_sys_get_prop_image_version( + struct hfi_msg_sys_property_info_packet *pkt) +{ + u32 i = 0; + size_t smem_block_size = 0; + u8 *smem_table_ptr; + char version[256]; + const u32 version_string_size = 128; + const u32 smem_image_index_venus = 14 * 128; + u8 *str_image_version; + u32 req_bytes; + + req_bytes = pkt->size - sizeof(*pkt); + if (req_bytes < version_string_size || + !pkt->rg_property_data[1] || + pkt->num_properties > 1) { + dprintk(VIDC_ERR, "%s: bad_pkt: %d\n", __func__, req_bytes); + return; + } + str_image_version = (u8 *)&pkt->rg_property_data[1]; + /* + * The version string returned by firmware includes null + * characters at the start and in between. Replace the null + * characters with space, to print the version info. + */ + for (i = 0; i < version_string_size; i++) { + if (str_image_version[i] != '\0') + version[i] = str_image_version[i]; + else + version[i] = ' '; + } + version[i] = '\0'; + dprintk(VIDC_DBG, "F/W version: %s\n", version); + + smem_table_ptr = qcom_smem_get(QCOM_SMEM_HOST_ANY, + SMEM_IMAGE_VERSION_TABLE, &smem_block_size); + if ((smem_image_index_venus + version_string_size) <= smem_block_size && + smem_table_ptr) + memcpy(smem_table_ptr + smem_image_index_venus, + str_image_version, version_string_size); +} + +static int hfi_process_sys_property_info(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_sys_property_info_packet *pkt = _pkt; + if (!pkt) { + dprintk(VIDC_ERR, "%s: invalid param\n", __func__); + return -EINVAL; + } else if (pkt->size < sizeof(*pkt)) { + dprintk(VIDC_ERR, + "%s: bad_pkt_size\n", __func__); + return -E2BIG; + } else if (!pkt->num_properties) { + dprintk(VIDC_ERR, + "%s: no_properties\n", __func__); + return -EINVAL; + } + + switch (pkt->rg_property_data[0]) { + case HFI_PROPERTY_SYS_IMAGE_VERSION: + hfi_process_sys_get_prop_image_version(pkt); + + *info = (struct msm_vidc_cb_info) { + .response_type = HAL_RESPONSE_UNUSED, + }; + return 0; + default: + dprintk(VIDC_DBG, + "%s: unknown_prop_id: %x\n", + __func__, pkt->rg_property_data[0]); + return -ENOTSUPP; + } + +} + +static int hfi_process_ignore(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + *info = (struct msm_vidc_cb_info) { + .response_type = HAL_RESPONSE_UNUSED, + }; + + return 0; +} + +int hfi_process_msg_packet(u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr, + struct msm_vidc_cb_info *info) +{ + typedef int (*pkt_func_def)(u32, void *, struct msm_vidc_cb_info *info); + pkt_func_def pkt_func = NULL; + + if (!info || !msg_hdr || msg_hdr->size < VIDC_IFACEQ_MIN_PKT_SIZE) { + dprintk(VIDC_ERR, "%s: bad packet/packet size\n", + __func__); + return -EINVAL; + } + + dprintk(VIDC_DBG, "Parse response %#x\n", msg_hdr->packet); + switch (msg_hdr->packet) { + case HFI_MSG_EVENT_NOTIFY: + pkt_func = (pkt_func_def)hfi_process_event_notify; + break; + case HFI_MSG_SYS_INIT_DONE: + pkt_func = (pkt_func_def)hfi_process_sys_init_done; + break; + case HFI_MSG_SYS_SESSION_INIT_DONE: + pkt_func = (pkt_func_def)hfi_process_session_init_done; + break; + case HFI_MSG_SYS_PROPERTY_INFO: + pkt_func = (pkt_func_def)hfi_process_sys_property_info; + break; + case HFI_MSG_SYS_SESSION_END_DONE: + pkt_func = (pkt_func_def)hfi_process_session_end_done; + break; + case HFI_MSG_SESSION_LOAD_RESOURCES_DONE: + pkt_func = (pkt_func_def)hfi_process_session_load_res_done; + break; + case HFI_MSG_SESSION_START_DONE: + pkt_func = (pkt_func_def)hfi_process_session_start_done; + break; + case HFI_MSG_SESSION_STOP_DONE: + pkt_func = (pkt_func_def)hfi_process_session_stop_done; + break; + case HFI_MSG_SESSION_EMPTY_BUFFER_DONE: + pkt_func = (pkt_func_def)hfi_process_session_etb_done; + break; + case HFI_MSG_SESSION_FILL_BUFFER_DONE: + pkt_func = (pkt_func_def)hfi_process_session_ftb_done; + break; + case HFI_MSG_SESSION_FLUSH_DONE: + pkt_func = (pkt_func_def)hfi_process_session_flush_done; + break; + case HFI_MSG_SESSION_PROPERTY_INFO: + pkt_func = (pkt_func_def)hfi_process_session_prop_info; + break; + case HFI_MSG_SESSION_RELEASE_RESOURCES_DONE: + pkt_func = (pkt_func_def)hfi_process_session_rel_res_done; + break; + case HFI_MSG_SYS_RELEASE_RESOURCE: + pkt_func = (pkt_func_def)hfi_process_sys_rel_resource_done; + break; + case HFI_MSG_SESSION_RELEASE_BUFFERS_DONE: + pkt_func = (pkt_func_def)hfi_process_session_rel_buf_done; + break; + case HFI_MSG_SESSION_REGISTER_BUFFERS_DONE: + pkt_func = (pkt_func_def) + hfi_process_session_register_buffer_done; + break; + case HFI_MSG_SESSION_UNREGISTER_BUFFERS_DONE: + pkt_func = (pkt_func_def) + hfi_process_session_unregister_buffer_done; + break; + case HFI_MSG_SYS_SESSION_ABORT_DONE: + pkt_func = (pkt_func_def)hfi_process_session_abort_done; + break; + case HFI_MSG_SESSION_SYNC_DONE: + pkt_func = (pkt_func_def)hfi_process_ignore; + break; + default: + dprintk(VIDC_DBG, "Unable to parse message: %#x\n", + msg_hdr->packet); + break; + } + + return pkt_func ? + pkt_func(device_id, (void *)msg_hdr, info) : -ENOTSUPP; +} diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c new file mode 100644 index 000000000000..717f0bf7efad --- /dev/null +++ b/msm/vidc/msm_cvp_external.c @@ -0,0 +1,955 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include +#include "msm_cvp_external.h" +#include "msm_vidc_common.h" + +static void print_cvp_buffer(u32 tag, const char *str, + struct msm_vidc_inst *inst, struct msm_cvp_buf *cbuf) +{ + struct msm_cvp_external *cvp; + + if (!(tag & msm_vidc_debug) || !inst || !inst->cvp || !cbuf) + return; + + cvp = inst->cvp; + dprintk(tag, + "%s: %x : idx %d fd %d size %d offset %d dbuf %pK kvaddr %pK\n", + str, cvp->session_id, cbuf->index, cbuf->fd, cbuf->size, + cbuf->offset, cbuf->dbuf, cbuf->kvaddr); +} + +static int msm_cvp_fill_planeinfo(struct cvp_kmd_color_plane_info *plane_info, + u32 color_fmt, u32 width, u32 height) +{ + int rc = 0; + u32 y_stride, y_sclines, uv_stride, uv_sclines; + u32 y_meta_stride, y_meta_scalines; + u32 uv_meta_stride, uv_meta_sclines; + + switch (color_fmt) { + case COLOR_FMT_NV12: + case COLOR_FMT_P010: + case COLOR_FMT_NV12_512: + { + y_stride = VENUS_Y_STRIDE(color_fmt, width); + y_sclines = VENUS_Y_SCANLINES(color_fmt, height); + uv_stride = VENUS_UV_STRIDE(color_fmt, width); + uv_sclines = VENUS_UV_SCANLINES(color_fmt, height); + + plane_info->stride[HFI_COLOR_PLANE_METADATA] = 0; + plane_info->stride[HFI_COLOR_PLANE_PICDATA] = y_stride; + plane_info->stride[HFI_COLOR_PLANE_UV_META] = 0; + plane_info->stride[HFI_COLOR_PLANE_UV] = uv_stride; + plane_info->buf_size[HFI_COLOR_PLANE_METADATA] = 0; + plane_info->buf_size[HFI_COLOR_PLANE_PICDATA] = + y_stride * y_sclines; + plane_info->buf_size[HFI_COLOR_PLANE_UV_META] = 0; + plane_info->buf_size[HFI_COLOR_PLANE_UV] = + uv_stride * uv_sclines; + break; + } + case COLOR_FMT_NV12_UBWC: + case COLOR_FMT_NV12_BPP10_UBWC: + { + y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width); + y_meta_scalines = VENUS_Y_META_SCANLINES(color_fmt, height); + uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width); + uv_meta_sclines = VENUS_UV_META_SCANLINES(color_fmt, height); + + y_stride = VENUS_Y_STRIDE(color_fmt, width); + y_sclines = VENUS_Y_SCANLINES(color_fmt, height); + uv_stride = VENUS_UV_STRIDE(color_fmt, width); + uv_sclines = VENUS_UV_SCANLINES(color_fmt, height); + + plane_info->stride[HFI_COLOR_PLANE_METADATA] = y_meta_stride; + plane_info->stride[HFI_COLOR_PLANE_PICDATA] = y_stride; + plane_info->stride[HFI_COLOR_PLANE_UV_META] = uv_meta_stride; + plane_info->stride[HFI_COLOR_PLANE_UV] = uv_stride; + plane_info->buf_size[HFI_COLOR_PLANE_METADATA] = + MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scalines, 4096); + plane_info->buf_size[HFI_COLOR_PLANE_PICDATA] = + MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096); + plane_info->buf_size[HFI_COLOR_PLANE_UV_META] = + MSM_MEDIA_ALIGN(uv_meta_stride * uv_meta_sclines, 4096); + plane_info->buf_size[HFI_COLOR_PLANE_UV] = + MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096); + break; + } + default: + dprintk(VIDC_ERR, "%s: invalid color_fmt %#x\n", + __func__, color_fmt); + rc = -EINVAL; + break; + } + + return rc; +} + +static int msm_cvp_free_buffer(struct msm_vidc_inst *inst, + struct msm_cvp_buf *buffer) +{ + struct msm_cvp_external *cvp; + + if (!inst || !inst->cvp || !buffer) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; + + if (buffer->kvaddr) { + dma_buf_vunmap(buffer->dbuf, buffer->kvaddr); + buffer->kvaddr = NULL; + } + if (buffer->dbuf) { + dma_buf_put(buffer->dbuf); + buffer->dbuf = NULL; + } + return 0; +} + +static int msm_cvp_allocate_buffer(struct msm_vidc_inst *inst, + struct msm_cvp_buf *buffer, bool kernel_map) +{ + int rc = 0; + struct msm_cvp_external *cvp; + int ion_flags = 0; + unsigned long heap_mask = 0; + struct dma_buf *dbuf; + int fd; + + if (!inst || !inst->cvp || !buffer) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; + + heap_mask = ION_HEAP(ION_SYSTEM_HEAP_ID); + if (inst->flags & VIDC_SECURE) { + ion_flags = ION_FLAG_SECURE | ION_FLAG_CP_NON_PIXEL; + heap_mask = ION_HEAP(ION_SECURE_HEAP_ID); + } + + dbuf = ion_alloc(buffer->size, heap_mask, ion_flags); + if (IS_ERR_OR_NULL(dbuf)) { + dprintk(VIDC_ERR, + "%s: failed to allocate, size %d heap_mask %#lx flags %d\n", + __func__, buffer->size, heap_mask, ion_flags); + rc = -ENOMEM; + goto error; + } + buffer->dbuf = dbuf; + + fd = dma_buf_fd(dbuf, O_CLOEXEC); + if (fd < 0) { + dprintk(VIDC_ERR, "%s: failed to get fd\n", __func__); + rc = -ENOMEM; + goto error; + } + buffer->fd = fd; + + if (kernel_map) { + buffer->kvaddr = dma_buf_vmap(dbuf); + if (!buffer->kvaddr) { + dprintk(VIDC_ERR, + "%s: dma_buf_vmap failed\n", __func__); + rc = -EINVAL; + goto error; + } + } else { + buffer->kvaddr = NULL; + } + buffer->index = cvp->buffer_idx++; + buffer->offset = 0; + + return 0; +error: + msm_cvp_free_buffer(inst, buffer); + return rc; +} + +static void msm_cvp_deinit_downscale_buffers(struct msm_vidc_inst *inst) +{ + struct msm_cvp_external *cvp; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return; + } + cvp = inst->cvp; + dprintk(VIDC_DBG, "%s:\n", __func__); + + if (cvp->src_buffer.dbuf) { + print_cvp_buffer(VIDC_DBG, "free: src_buffer", + inst, &cvp->src_buffer); + if (msm_cvp_free_buffer(inst, &cvp->src_buffer)) + print_cvp_buffer(VIDC_ERR, + "free failed: src_buffer", + inst, &cvp->src_buffer); + } + if (cvp->ref_buffer.dbuf) { + print_cvp_buffer(VIDC_DBG, "free: ref_buffer", + inst, &cvp->ref_buffer); + if (msm_cvp_free_buffer(inst, &cvp->ref_buffer)) + print_cvp_buffer(VIDC_ERR, + "free failed: ref_buffer", + inst, &cvp->ref_buffer); + } +} + +static int msm_cvp_init_downscale_buffers(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; + + if (!cvp->downscale) { + dprintk(VIDC_DBG, "%s: downscaling not enabled\n", __func__); + return 0; + } + dprintk(VIDC_DBG, "%s:\n", __func__); + + cvp->src_buffer.size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, + cvp->ds_width, cvp->ds_height); + rc = msm_cvp_allocate_buffer(inst, &cvp->src_buffer, false); + if (rc) { + print_cvp_buffer(VIDC_ERR, + "allocate failed: src_buffer", + inst, &cvp->src_buffer); + goto error; + } + print_cvp_buffer(VIDC_DBG, "alloc: src_buffer", + inst, &cvp->src_buffer); + + cvp->ref_buffer.size = cvp->src_buffer.size; + rc = msm_cvp_allocate_buffer(inst, &cvp->ref_buffer, false); + if (rc) { + print_cvp_buffer(VIDC_ERR, + "allocate failed: ref_buffer", + inst, &cvp->ref_buffer); + goto error; + } + print_cvp_buffer(VIDC_DBG, "alloc: ref_buffer", + inst, &cvp->ref_buffer); + + return rc; + +error: + msm_cvp_deinit_downscale_buffers(inst); + return rc; +} + +static void msm_cvp_deinit_context_buffers(struct msm_vidc_inst *inst) +{ + struct msm_cvp_external *cvp; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return; + } + cvp = inst->cvp; + dprintk(VIDC_DBG, "%s:\n", __func__); + + if (cvp->context_buffer.dbuf) { + print_cvp_buffer(VIDC_DBG, "free: context_buffer", + inst, &cvp->context_buffer); + if (msm_cvp_free_buffer(inst, &cvp->context_buffer)) + print_cvp_buffer(VIDC_ERR, + "free failed: context_buffer", + inst, &cvp->context_buffer); + } + if (cvp->refcontext_buffer.dbuf) { + print_cvp_buffer(VIDC_DBG, "free: refcontext_buffer", + inst, &cvp->refcontext_buffer); + if (msm_cvp_free_buffer(inst, &cvp->refcontext_buffer)) + print_cvp_buffer(VIDC_ERR, + "free failed: refcontext_buffer", + inst, &cvp->refcontext_buffer); + } +} + +static int msm_cvp_init_context_buffers(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; + dprintk(VIDC_DBG, "%s:\n", __func__); + + cvp->context_buffer.size = HFI_DME_FRAME_CONTEXT_BUFFER_SIZE; + rc = msm_cvp_allocate_buffer(inst, &cvp->context_buffer, false); + if (rc) { + print_cvp_buffer(VIDC_ERR, + "allocate failed: context_buffer", + inst, &cvp->context_buffer); + goto error; + } + print_cvp_buffer(VIDC_DBG, "alloc: context_buffer", + inst, &cvp->context_buffer); + + cvp->refcontext_buffer.size = cvp->context_buffer.size; + rc = msm_cvp_allocate_buffer(inst, &cvp->refcontext_buffer, false); + if (rc) { + print_cvp_buffer(VIDC_ERR, + "allocate failed: refcontext_buffer", + inst, &cvp->refcontext_buffer); + goto error; + } + print_cvp_buffer(VIDC_DBG, "alloc: refcontext_buffer", + inst, &cvp->refcontext_buffer); + + return rc; + +error: + msm_cvp_deinit_context_buffers(inst); + return rc; +} + +static void msm_cvp_deinit_internal_buffers(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp; + struct cvp_kmd_arg *arg; + struct msm_cvp_session_release_persist_buffers_packet persist2_packet; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return; + } + + cvp = inst->cvp; + dprintk(VIDC_DBG, "%s:\n", __func__); + + if (cvp->output_buffer.dbuf) { + print_cvp_buffer(VIDC_DBG, "free: output_buffer", + inst, &cvp->output_buffer); + rc = msm_cvp_free_buffer(inst, &cvp->output_buffer); + if (rc) + print_cvp_buffer(VIDC_ERR, + "unregister failed: output_buffer", + inst, &cvp->output_buffer); + } + + if (cvp->persist2_buffer.dbuf) { + print_cvp_buffer(VIDC_DBG, "free: persist2_buffer", + inst, &cvp->persist2_buffer); + memset(&persist2_packet, 0, sizeof(struct + msm_cvp_session_release_persist_buffers_packet)); + persist2_packet.size = sizeof(struct + msm_cvp_session_release_persist_buffers_packet); + persist2_packet.packet_type = + HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS; + persist2_packet.session_id = cvp->session_id; + persist2_packet.cvp_op = CVP_DME; + persist2_packet.persist2_buffer.buffer_addr = + cvp->persist2_buffer.fd; + persist2_packet.persist2_buffer.size = + cvp->persist2_buffer.size; + + arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL); + if (arg) { + memset(arg, 0, sizeof(struct cvp_kmd_arg)); + arg->type = CVP_KMD_HFI_PERSIST_CMD; + memcpy(&(arg->data.pbuf_cmd), &persist2_packet, + sizeof(struct + msm_cvp_session_release_persist_buffers_packet)); + rc = msm_cvp_private(cvp->priv, + CVP_KMD_HFI_PERSIST_CMD, arg); + if (rc) + print_cvp_buffer(VIDC_ERR, + "release failed: persist2_buffer", + inst, &cvp->persist2_buffer); + kfree(arg); + } + + rc = msm_cvp_free_buffer(inst, &cvp->persist2_buffer); + if (rc) + print_cvp_buffer(VIDC_ERR, + "free failed: persist2_buffer", + inst, &cvp->persist2_buffer); + } +} + +static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp; + struct cvp_kmd_arg *arg; + struct msm_cvp_session_set_persist_buffers_packet persist2_packet; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL); + if (!arg) + return -ENOMEM; + + cvp = inst->cvp; + dprintk(VIDC_DBG, "%s:\n", __func__); + + cvp->persist2_buffer.size = HFI_DME_INTERNAL_PERSIST_2_BUFFER_SIZE; + rc = msm_cvp_allocate_buffer(inst, &cvp->persist2_buffer, false); + if (rc) { + print_cvp_buffer(VIDC_ERR, + "allocate failed: persist2_buffer", + inst, &cvp->persist2_buffer); + goto error; + } + print_cvp_buffer(VIDC_DBG, "alloc: persist2_buffer", + inst, &cvp->persist2_buffer); + + /* set buffer */ + memset(&persist2_packet, 0, + sizeof(struct msm_cvp_session_set_persist_buffers_packet)); + persist2_packet.size = + sizeof(struct msm_cvp_session_set_persist_buffers_packet); + persist2_packet.packet_type = HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS; + persist2_packet.session_id = cvp->session_id; + persist2_packet.cvp_op = CVP_DME; + persist2_packet.persist2_buffer.buffer_addr = cvp->persist2_buffer.fd; + persist2_packet.persist2_buffer.size = cvp->persist2_buffer.size; + + memset(arg, 0, sizeof(struct cvp_kmd_arg)); + arg->type = CVP_KMD_HFI_PERSIST_CMD; + if (sizeof(struct cvp_kmd_persist_buf) < + sizeof(struct msm_cvp_session_set_persist_buffers_packet)) { + dprintk(VIDC_ERR, "%s: insufficient size\n", __func__); + goto error; + } + memcpy(&(arg->data.pbuf_cmd), &persist2_packet, + sizeof(struct msm_cvp_session_set_persist_buffers_packet)); + rc = msm_cvp_private(cvp->priv, CVP_KMD_HFI_PERSIST_CMD, arg); + if (rc) { + print_cvp_buffer(VIDC_ERR, + "set failed: persist2_buffer", + inst, &cvp->persist2_buffer); + goto error; + } + + /* allocate one output buffer for internal use */ + cvp->output_buffer.size = HFI_DME_OUTPUT_BUFFER_SIZE; + rc = msm_cvp_allocate_buffer(inst, &cvp->output_buffer, true); + if (rc) { + print_cvp_buffer(VIDC_ERR, + "allocate failed: output_buffer", + inst, &cvp->output_buffer); + goto error; + } + print_cvp_buffer(VIDC_DBG, "alloc: output_buffer", + inst, &cvp->output_buffer); + + kfree(arg); + return rc; + +error: + msm_cvp_deinit_internal_buffers(inst); + kfree(arg); + return rc; +} + +static int msm_cvp_prepare_extradata(struct msm_vidc_inst *inst, + struct vb2_buffer *vb) +{ + int rc = 0; + struct msm_cvp_external *cvp; + struct dma_buf *dbuf = NULL; + char *kvaddr = NULL; + struct msm_vidc_extradata_header *e_hdr; + bool input_extradata, found_end; + + if (!inst || !inst->cvp || !vb) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + if (vb->num_planes <= 1) { + dprintk(VIDC_ERR, "%s: extradata plane not enabled\n", + __func__); + return -EINVAL; + } + cvp = inst->cvp; + + dbuf = dma_buf_get(vb->planes[1].m.fd); + if (!dbuf) { + dprintk(VIDC_ERR, "%s: dma_buf_get(%d) failed\n", + __func__, vb->planes[1].m.fd); + return -EINVAL; + } + if (dbuf->size < vb->planes[1].length) { + dprintk(VIDC_ERR, "%s: invalid size %d vs %d\n", __func__, + dbuf->size, vb->planes[1].length); + rc = -EINVAL; + goto error; + } + rc = dma_buf_begin_cpu_access(dbuf, DMA_BIDIRECTIONAL); + if (rc) { + dprintk(VIDC_ERR, "%s: begin_cpu_access failed\n", __func__); + goto error; + } + kvaddr = dma_buf_vmap(dbuf); + if (!kvaddr) { + dprintk(VIDC_ERR, "%s: dma_buf_vmap(%d) failed\n", + __func__, vb->planes[1].m.fd); + rc = -EINVAL; + goto error; + } + e_hdr = (struct msm_vidc_extradata_header *)((char *)kvaddr + + vb->planes[1].data_offset); + + input_extradata = + !!((inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_ROI) || + (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_HDR10PLUS)); + found_end = false; + while ((char *)e_hdr < (char *)(kvaddr + dbuf->size)) { + if (!input_extradata) { + found_end = true; + break; + } + if (e_hdr->type == MSM_VIDC_EXTRADATA_NONE) { + found_end = true; + break; + } + e_hdr += e_hdr->size; + } + if (!found_end) { + dprintk(VIDC_ERR, "%s: extradata_none not found\n", __func__); + e_hdr = (struct msm_vidc_extradata_header *)((char *)kvaddr + + vb->planes[1].data_offset); + } + /* check if sufficient space available */ + if (((char *)e_hdr + sizeof(struct msm_vidc_extradata_header) + + sizeof(struct msm_vidc_enc_cvp_metadata_payload) + + sizeof(struct msm_vidc_extradata_header)) > + (kvaddr + dbuf->size)) { + dprintk(VIDC_ERR, + "%s: couldn't append extradata, (e_hdr[%pK] - kvaddr[%pK]) %#x, size %d\n", + __func__, e_hdr, kvaddr, (char *)e_hdr - (char *)kvaddr, + dbuf->size); + goto error; + } + /* copy payload */ + e_hdr->version = 0x00000001; + e_hdr->port_index = 1; + e_hdr->type = MSM_VIDC_EXTRADATA_CVP_METADATA; + e_hdr->data_size = sizeof(struct msm_vidc_enc_cvp_metadata_payload); + e_hdr->size = sizeof(struct msm_vidc_extradata_header) + + e_hdr->data_size; + dma_buf_begin_cpu_access(cvp->output_buffer.dbuf, DMA_BIDIRECTIONAL); + memcpy(e_hdr->data, cvp->output_buffer.kvaddr, + sizeof(struct msm_vidc_enc_cvp_metadata_payload)); + dma_buf_end_cpu_access(cvp->output_buffer.dbuf, DMA_BIDIRECTIONAL); + /* fill extradata none */ + e_hdr = (struct msm_vidc_extradata_header *) + ((char *)e_hdr + e_hdr->size); + e_hdr->version = 0x00000001; + e_hdr->port_index = 1; + e_hdr->type = MSM_VIDC_EXTRADATA_NONE; + e_hdr->data_size = 0; + e_hdr->size = sizeof(struct msm_vidc_extradata_header) + + e_hdr->data_size; + + dma_buf_vunmap(dbuf, kvaddr); + dma_buf_end_cpu_access(dbuf, DMA_BIDIRECTIONAL); + dma_buf_put(dbuf); + + return rc; + +error: + if (kvaddr) { + dma_buf_vunmap(dbuf, kvaddr); + dma_buf_end_cpu_access(dbuf, DMA_BIDIRECTIONAL); + } + if (dbuf) + dma_buf_put(dbuf); + + return rc; +} + +static int msm_cvp_reference_management(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp; + struct msm_cvp_buf temp; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; + + /* swap context buffers */ + memcpy(&temp, &cvp->refcontext_buffer, sizeof(struct msm_cvp_buf)); + memcpy(&cvp->refcontext_buffer, &cvp->context_buffer, + sizeof(struct msm_cvp_buf)); + memcpy(&cvp->context_buffer, &temp, sizeof(struct msm_cvp_buf)); + + /* swap downscale buffers */ + if (cvp->downscale) { + memcpy(&temp, &cvp->ref_buffer, sizeof(struct msm_cvp_buf)); + memcpy(&cvp->ref_buffer, &cvp->src_buffer, + sizeof(struct msm_cvp_buf)); + memcpy(&cvp->src_buffer, &temp, sizeof(struct msm_cvp_buf)); + } + + return rc; +} + +static int msm_cvp_frame_process(struct msm_vidc_inst *inst, + struct vb2_buffer *vb) +{ + int rc = 0; + struct msm_cvp_external *cvp; + struct cvp_kmd_arg *arg; + struct msm_cvp_dme_frame_packet *frame; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL); + if (!arg) + return -ENOMEM; + + cvp = inst->cvp; + cvp->fullres_buffer.index = vb->index; + cvp->fullres_buffer.fd = vb->planes[0].m.fd; + cvp->fullres_buffer.size = vb->planes[0].length; + cvp->fullres_buffer.offset = vb->planes[0].data_offset; + + arg->type = CVP_KMD_SEND_CMD_PKT; + frame = (struct msm_cvp_dme_frame_packet *)&arg->data.hfi_pkt.pkt_data; + + frame->size = sizeof(struct msm_cvp_dme_frame_packet); + frame->packet_type = HFI_CMD_SESSION_CVP_DME_FRAME; + frame->session_id = cvp->session_id; + if (!cvp->framecount) + frame->skip_mv_calc = 1; + else + frame->skip_mv_calc = 0; + frame->min_fpx_threshold = 2; + frame->enable_descriptor_lpf = 1; + frame->enable_ncc_subpel = 1; + frame->descmatch_threshold = 52; + frame->ncc_robustness_threshold = 0; + + frame->fullres_srcbuffer.buffer_addr = cvp->fullres_buffer.fd; + frame->fullres_srcbuffer.size = cvp->fullres_buffer.size; + frame->videospatialtemporal_statsbuffer.buffer_addr = + cvp->output_buffer.fd; + frame->videospatialtemporal_statsbuffer.size = + cvp->output_buffer.size; + + frame->src_buffer.buffer_addr = cvp->fullres_buffer.fd; + frame->src_buffer.size = cvp->fullres_buffer.size; + if (cvp->downscale) { + frame->src_buffer.buffer_addr = cvp->src_buffer.fd; + frame->src_buffer.size = cvp->src_buffer.size; + frame->ref_buffer.buffer_addr = cvp->ref_buffer.fd; + frame->ref_buffer.size = cvp->ref_buffer.size; + } + frame->srcframe_contextbuffer.buffer_addr = cvp->context_buffer.fd; + frame->srcframe_contextbuffer.size = cvp->context_buffer.size; + frame->refframe_contextbuffer.buffer_addr = cvp->refcontext_buffer.fd; + frame->refframe_contextbuffer.size = cvp->refcontext_buffer.size; + + print_cvp_buffer(VIDC_DBG, "input frame", inst, &cvp->fullres_buffer); + rc = msm_cvp_private(cvp->priv, CVP_KMD_SEND_CMD_PKT, arg); + if (rc) { + print_cvp_buffer(VIDC_ERR, "send failed: input frame", + inst, &cvp->fullres_buffer); + goto error; + } + /* wait for frame done */ + arg->type = CVP_KMD_RECEIVE_MSG_PKT; + rc = msm_cvp_private(cvp->priv, CVP_KMD_RECEIVE_MSG_PKT, arg); + if (rc) { + print_cvp_buffer(VIDC_ERR, "wait failed: input frame", + inst, &cvp->fullres_buffer); + goto error; + } + cvp->framecount++; + +error: + kfree(arg); + return rc; +} + +int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst, struct vb2_buffer *vb) +{ + int rc = 0; + struct msm_cvp_external *cvp; + + if (!inst || !inst->cvp || !vb) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + if (inst->state != MSM_VIDC_START_DONE) { + dprintk(VIDC_ERR, "%s: invalid inst state %d\n", + __func__, inst->state); + return -EINVAL; + } + cvp = inst->cvp; + + rc = msm_cvp_frame_process(inst, vb); + if (rc) { + dprintk(VIDC_ERR, "%s: cvp process failed\n", __func__); + return rc; + } + + rc = msm_cvp_prepare_extradata(inst, vb); + if (rc) { + dprintk(VIDC_ERR, "%s: prepare extradata failed\n", __func__); + return rc; + } + + rc = msm_cvp_reference_management(inst); + if (rc) { + dprintk(VIDC_ERR, "%s: ref management failed\n", __func__); + return rc; + } + + return rc; +} + +static int msm_vidc_cvp_deinit(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; + + dprintk(VIDC_DBG, "%s: cvp session %#x\n", __func__, cvp->session_id); + msm_cvp_deinit_internal_buffers(inst); + msm_cvp_deinit_context_buffers(inst); + msm_cvp_deinit_downscale_buffers(inst); + + return rc; +} + +static int msm_vidc_cvp_close(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; + + dprintk(VIDC_DBG, "%s: cvp session %#x\n", __func__, cvp->session_id); + rc = msm_cvp_close(cvp->priv); + if (rc) + dprintk(VIDC_ERR, + "%s: cvp close failed with error %d\n", __func__, rc); + cvp->priv = NULL; + + kfree(inst->cvp); + inst->cvp = NULL; + + return rc; +} + +int msm_vidc_cvp_unprepare_preprocess(struct msm_vidc_inst *inst) +{ + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + if (!inst->cvp) { + dprintk(VIDC_DBG, "%s: cvp not enabled or closed\n", __func__); + return 0; + } + + msm_vidc_cvp_deinit(inst); + msm_vidc_cvp_close(inst); + + return 0; +} + +static int msm_vidc_cvp_init(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp; + struct v4l2_format *f; + struct cvp_kmd_arg *arg; + struct msm_cvp_dme_basic_config_packet *dmecfg; + u32 color_fmt; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL); + if (!arg) + return -ENOMEM; + + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + cvp = inst->cvp; + + cvp->framecount = 0; + cvp->width = f->fmt.pix_mp.width; + cvp->height = f->fmt.pix_mp.height; + color_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat); + + /* enable downscale always */ + cvp->downscale = true; + if (cvp->width * cvp->height < 640 * 480) { + cvp->ds_width = cvp->width; + cvp->ds_height = cvp->height; + } else if (cvp->width * cvp->height < 1920 * 1080) { + if (cvp->ds_width >= cvp->ds_height) { + cvp->ds_width = 480; + cvp->ds_height = 270; + } else { + cvp->ds_width = 270; + cvp->ds_height = 480; + } + } else { + cvp->ds_width = cvp->width / 4; + cvp->ds_height = cvp->height / 4; + } + dprintk(VIDC_DBG, + "%s: pixelformat %#x, wxh %dx%d downscale %d ds_wxh %dx%d\n", + __func__, f->fmt.pix_mp.pixelformat, + cvp->width, cvp->height, cvp->downscale, + cvp->ds_width, cvp->ds_height); + + memset(arg, 0, sizeof(struct cvp_kmd_arg)); + arg->type = CVP_KMD_SEND_CMD_PKT; + dmecfg = (struct msm_cvp_dme_basic_config_packet *) + &arg->data.hfi_pkt.pkt_data; + dmecfg->size = sizeof(struct msm_cvp_dme_basic_config_packet); + dmecfg->packet_type = HFI_CMD_SESSION_CVP_DME_BASIC_CONFIG; + dmecfg->session_id = cvp->session_id; + /* source buffer format should be NV12_UBWC always */ + dmecfg->srcbuffer_format = HFI_COLOR_FORMAT_NV12_UBWC; + dmecfg->src_width = cvp->ds_width; + dmecfg->src_height = cvp->ds_height; + rc = msm_cvp_fill_planeinfo(&dmecfg->srcbuffer_planeinfo, + COLOR_FMT_NV12_UBWC, dmecfg->src_width, dmecfg->src_height); + if (rc) + goto error; + dmecfg->fullresbuffer_format = msm_comm_get_hfi_uncompressed( + f->fmt.pix_mp.pixelformat); + dmecfg->fullres_width = cvp->width; + dmecfg->fullres_height = cvp->height; + rc = msm_cvp_fill_planeinfo(&dmecfg->fullresbuffer_planeinfo, + color_fmt, dmecfg->fullres_width, dmecfg->fullres_height); + if (rc) + goto error; + dmecfg->ds_enable = cvp->downscale; + dmecfg->enable_lrme_robustness = 1; + dmecfg->enable_inlier_tracking = 1; + rc = msm_cvp_private(cvp->priv, CVP_KMD_SEND_CMD_PKT, arg); + if (rc) { + dprintk(VIDC_ERR, "%s: cvp configuration failed\n", __func__); + goto error; + } + + rc = msm_cvp_init_downscale_buffers(inst); + if (rc) + goto error; + rc = msm_cvp_init_internal_buffers(inst); + if (rc) + goto error; + rc = msm_cvp_init_context_buffers(inst); + if (rc) + goto error; + + kfree(arg); + return rc; + +error: + msm_vidc_cvp_deinit(inst); + kfree(arg); + return rc; +} + +static int msm_vidc_cvp_open(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp; + struct cvp_kmd_arg *arg; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL); + if (!arg) + return -ENOMEM; + + inst->cvp = kzalloc(sizeof(struct msm_cvp_external), GFP_KERNEL); + if (!inst->cvp) { + dprintk(VIDC_ERR, "%s: failed to allocate\n", __func__); + rc = -ENOMEM; + goto error; + } + cvp = inst->cvp; + + dprintk(VIDC_DBG, "%s: opening cvp\n", __func__); + cvp->priv = msm_cvp_open(0, MSM_VIDC_CVP); + if (!cvp->priv) { + dprintk(VIDC_ERR, "%s: failed to open cvp session\n", __func__); + rc = -EINVAL; + goto error; + } + + memset(arg, 0, sizeof(struct cvp_kmd_arg)); + arg->type = CVP_KMD_GET_SESSION_INFO; + rc = msm_cvp_private(cvp->priv, CVP_KMD_GET_SESSION_INFO, arg); + if (rc) { + dprintk(VIDC_ERR, "%s: get_session_info failed\n", __func__); + goto error; + } + cvp->session_id = arg->data.session.session_id; + dprintk(VIDC_DBG, "%s: cvp session id %#x\n", + __func__, cvp->session_id); + + kfree(arg); + return 0; + +error: + msm_vidc_cvp_close(inst); + kfree(inst->cvp); + inst->cvp = NULL; + kfree(arg); + return rc; +} + +int msm_vidc_cvp_prepare_preprocess(struct msm_vidc_inst *inst) +{ + int rc; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + rc = msm_vidc_cvp_open(inst); + if (rc) + return rc; + + rc = msm_vidc_cvp_init(inst); + if (rc) + return rc; + + return 0; +} diff --git a/msm/vidc/msm_cvp_external.h b/msm/vidc/msm_cvp_external.h new file mode 100644 index 000000000000..ed98428f78c3 --- /dev/null +++ b/msm/vidc/msm_cvp_external.h @@ -0,0 +1,168 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#ifndef _MSM_CVP_EXTERNAL_H_ +#define _MSM_CVP_EXTERNAL_H_ + +#include +#include +#include +#include "msm_vidc_internal.h" +#include "msm_vidc_debug.h" + +#define CVP_DME (24) + +#define HFI_COMMON_BASE (0) +#define HFI_VIDEO_DOMAIN_CVP (HFI_COMMON_BASE + 0x8) +#define HFI_DOMAIN_BASE_COMMON (HFI_COMMON_BASE + 0) +#define HFI_DOMAIN_BASE_CVP (HFI_COMMON_BASE + 0x04000000) +#define HFI_ARCH_COMMON_OFFSET (0) +#define HFI_CMD_START_OFFSET (0x00010000) +#define HFI_CMD_SESSION_CVP_START \ + (HFI_DOMAIN_BASE_CVP + HFI_ARCH_COMMON_OFFSET + \ + HFI_CMD_START_OFFSET + 0x1000) + +#define HFI_CMD_SESSION_CVP_DME_FRAME \ + (HFI_CMD_SESSION_CVP_START + 0x03A) +#define HFI_CMD_SESSION_CVP_DME_BASIC_CONFIG \ + (HFI_CMD_SESSION_CVP_START + 0x03B) +#define HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS \ + (HFI_CMD_SESSION_CVP_START + 0x04D) +#define HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS \ + (HFI_CMD_SESSION_CVP_START + 0x050) + +#define HFI_DME_OUTPUT_BUFFER_SIZE (256 * 4) +#define HFI_DME_INTERNAL_PERSIST_2_BUFFER_SIZE (512 * 1024) +#define HFI_DME_FRAME_CONTEXT_BUFFER_SIZE (64 * 1024) + +enum HFI_COLOR_PLANE_TYPE { + HFI_COLOR_PLANE_METADATA, + HFI_COLOR_PLANE_PICDATA, + HFI_COLOR_PLANE_UV_META, + HFI_COLOR_PLANE_UV, + HFI_MAX_COLOR_PLANES +}; + +static inline bool is_vidc_cvp_enabled(struct msm_vidc_inst *inst) +{ + return !!inst->cvp; +} + +static inline bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst) +{ + return false; +} + +struct msm_cvp_buffer_type { + u32 buffer_addr; + u32 size; +}; + +struct msm_cvp_session_release_persist_buffers_packet { + u32 size; + u32 packet_type; + u32 session_id; + struct cvp_kmd_client_data client_data; + u32 cvp_op; + struct msm_cvp_buffer_type persist1_buffer; + struct msm_cvp_buffer_type persist2_buffer; +}; + +struct msm_cvp_session_set_persist_buffers_packet { + u32 size; + u32 packet_type; + u32 session_id; + struct cvp_kmd_client_data client_data; + u32 cvp_op; + struct msm_cvp_buffer_type persist1_buffer; + struct msm_cvp_buffer_type persist2_buffer; +}; + +struct msm_cvp_dme_frame_packet { + u32 size; + u32 packet_type; + u32 session_id; + struct cvp_kmd_client_data client_data; + u32 skip_mv_calc; + u32 min_fpx_threshold; + u32 enable_descriptor_lpf; + u32 enable_ncc_subpel; + u32 descmatch_threshold; + int ncc_robustness_threshold; + struct msm_cvp_buffer_type fullres_srcbuffer; + struct msm_cvp_buffer_type src_buffer; + struct msm_cvp_buffer_type srcframe_contextbuffer; + struct msm_cvp_buffer_type prsp_buffer; + struct msm_cvp_buffer_type grid_buffer; + struct msm_cvp_buffer_type ref_buffer; + struct msm_cvp_buffer_type refframe_contextbuffer; + struct msm_cvp_buffer_type videospatialtemporal_statsbuffer; +}; + +struct msm_cvp_dme_basic_config_packet { + u32 size; + u32 packet_type; + u32 session_id; + struct cvp_kmd_client_data client_data; + u32 srcbuffer_format; + struct cvp_kmd_color_plane_info srcbuffer_planeinfo; + u32 src_width; + u32 src_height; + u32 fullres_width; + u32 fullres_height; + u32 fullresbuffer_format; + struct cvp_kmd_color_plane_info fullresbuffer_planeinfo; + u32 ds_enable; + u32 enable_lrme_robustness; + u32 enable_inlier_tracking; + u32 override_defaults; + s32 inlier_step; + s32 outlier_step; + s32 follow_globalmotion_step; + s32 nomv_conveyedinfo_step; + s32 invalid_transform_step; + s32 valid_transform_min_confidence_for_updates; + u32 min_inlier_weight_threshold; + u32 ncc_threshold; + u32 min_allowed_tar_var; + u32 meaningful_ncc_diff; + u32 robustness_distmap[8]; + u32 ransac_threshold; +}; + +struct msm_cvp_buf { + u32 index; + int fd; + u32 size; + u32 offset; + struct dma_buf *dbuf; + void *kvaddr; +}; + +struct msm_cvp_external { + void *priv; + u32 session_id; + u32 width; + u32 height; + u32 ds_width; + u32 ds_height; + bool downscale; + u32 framecount; + u32 buffer_idx; + struct msm_cvp_buf fullres_buffer; + struct msm_cvp_buf src_buffer; + struct msm_cvp_buf ref_buffer; + struct msm_cvp_buf output_buffer; + struct msm_cvp_buf context_buffer; + struct msm_cvp_buf refcontext_buffer; + struct msm_cvp_buf persist2_buffer; +}; + +int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst, + struct vb2_buffer *vb); +int msm_vidc_cvp_prepare_preprocess(struct msm_vidc_inst *inst); +int msm_vidc_cvp_unprepare_preprocess(struct msm_vidc_inst *inst); + +#endif diff --git a/msm/vidc/msm_cvp_internal.c b/msm/vidc/msm_cvp_internal.c new file mode 100644 index 000000000000..60eda88e254e --- /dev/null +++ b/msm/vidc/msm_cvp_internal.c @@ -0,0 +1,627 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + */ + +#include "msm_cvp_internal.h" + +#define MSM_VIDC_NOMINAL_CYCLES (444 * 1000 * 1000) +#define MSM_VIDC_UHD60E_VPSS_CYCLES (111 * 1000 * 1000) +#define MSM_VIDC_UHD60E_ISE_CYCLES (175 * 1000 * 1000) +#define MAX_CVP_VPSS_CYCLES (MSM_VIDC_NOMINAL_CYCLES - \ + MSM_VIDC_UHD60E_VPSS_CYCLES) +#define MAX_CVP_ISE_CYCLES (MSM_VIDC_NOMINAL_CYCLES - \ + MSM_VIDC_UHD60E_ISE_CYCLES) + +static void print_client_buffer(u32 tag, const char *str, + struct msm_vidc_inst *inst, struct msm_cvp_buffer *cbuf) +{ + if (!(tag & msm_vidc_debug) || !inst || !cbuf) + return; + + dprintk(tag, + "%s: %x : idx %2d fd %d off %d size %d type %d flags 0x%x\n", + str, hash32_ptr(inst->session), cbuf->index, cbuf->fd, + cbuf->offset, cbuf->size, cbuf->type, cbuf->flags); +} + +static void print_cvp_buffer(u32 tag, const char *str, + struct msm_vidc_inst *inst, struct msm_vidc_cvp_buffer *cbuf) +{ + if (!(tag & msm_vidc_debug) || !inst || !cbuf) + return; + + dprintk(tag, + "%s: %x : idx %2d fd %d off %d daddr %x size %d type %d flags 0x%x\n", + str, hash32_ptr(inst->session), cbuf->buf.index, cbuf->buf.fd, + cbuf->buf.offset, cbuf->smem.device_addr, cbuf->buf.size, + cbuf->buf.type, cbuf->buf.flags); +} + +static enum hal_buffer get_hal_buftype(const char *str, unsigned int type) +{ + enum hal_buffer buftype = HAL_BUFFER_NONE; + + if (type == MSM_CVP_BUFTYPE_INPUT) + buftype = HAL_BUFFER_INPUT; + else if (type == MSM_CVP_BUFTYPE_OUTPUT) + buftype = HAL_BUFFER_OUTPUT; + else if (type == MSM_CVP_BUFTYPE_INTERNAL_1) + buftype = HAL_BUFFER_INTERNAL_SCRATCH_1; + else if (type == MSM_CVP_BUFTYPE_INTERNAL_2) + buftype = HAL_BUFFER_INTERNAL_SCRATCH_1; + else + dprintk(VIDC_ERR, "%s: unknown buffer type %#x\n", + str, type); + + return buftype; +} + +void handle_session_register_buffer_done(enum hal_command_response cmd, + void *resp) +{ + struct msm_vidc_cb_cmd_done *response = resp; + struct msm_vidc_inst *inst; + struct msm_vidc_cvp_buffer *cbuf; + struct v4l2_event event = {0}; + u32 *data; + bool found; + + if (!response) { + dprintk(VIDC_ERR, "%s: invalid response\n", __func__); + return; + } + inst = get_inst(get_vidc_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid session %pK\n", __func__, + response->session_id); + return; + } + + mutex_lock(&inst->cvpbufs.lock); + found = false; + list_for_each_entry(cbuf, &inst->cvpbufs.list, list) { + if (response->data.regbuf.client_data == + cbuf->smem.device_addr) { + found = true; + break; + } + } + mutex_unlock(&inst->cvpbufs.lock); + if (!found) { + dprintk(VIDC_ERR, "%s: client_data %x not found\n", + __func__, response->data.regbuf.client_data); + goto exit; + } + print_cvp_buffer(VIDC_DBG, "register_done", inst, cbuf); + + event.type = V4L2_EVENT_MSM_VIDC_REGISTER_BUFFER_DONE; + data = (u32 *)event.u.data; + data[0] = cbuf->buf.index; + data[1] = cbuf->buf.type; + data[2] = cbuf->buf.fd; + data[3] = cbuf->buf.offset; + v4l2_event_queue_fh(&inst->event_handler, &event); + +exit: + put_inst(inst); +} + +void handle_session_unregister_buffer_done(enum hal_command_response cmd, + void *resp) +{ + int rc; + struct msm_vidc_cb_cmd_done *response = resp; + struct msm_vidc_inst *inst; + struct msm_vidc_cvp_buffer *cbuf, *dummy; + struct v4l2_event event = {0}; + u32 *data; + bool found; + + if (!response) { + dprintk(VIDC_ERR, "%s: invalid response\n", __func__); + return; + } + inst = get_inst(get_vidc_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid session %pK\n", __func__, + response->session_id); + return; + } + + mutex_lock(&inst->cvpbufs.lock); + found = false; + list_for_each_entry_safe(cbuf, dummy, &inst->cvpbufs.list, list) { + if (response->data.unregbuf.client_data == + cbuf->smem.device_addr) { + found = true; + break; + } + } + mutex_unlock(&inst->cvpbufs.lock); + if (!found) { + dprintk(VIDC_ERR, "%s: client_data %x not found\n", + __func__, response->data.unregbuf.client_data); + goto exit; + } + print_cvp_buffer(VIDC_DBG, "unregister_done", inst, cbuf); + + rc = inst->smem_ops->smem_unmap_dma_buf(inst, &cbuf->smem); + if (rc) { + print_cvp_buffer(VIDC_ERR, "unmap fail", inst, cbuf); + goto exit; + } + + event.type = V4L2_EVENT_MSM_VIDC_UNREGISTER_BUFFER_DONE; + data = (u32 *)event.u.data; + data[0] = cbuf->buf.index; + data[1] = cbuf->buf.type; + data[2] = cbuf->buf.fd; + data[3] = cbuf->buf.offset; + v4l2_event_queue_fh(&inst->event_handler, &event); + + mutex_lock(&inst->cvpbufs.lock); + list_del(&cbuf->list); + mutex_unlock(&inst->cvpbufs.lock); + kfree(cbuf); + cbuf = NULL; +exit: + put_inst(inst); +} + +static void print_cvp_cycles(struct msm_vidc_inst *inst) +{ + struct msm_vidc_core *core; + struct msm_vidc_inst *temp; + + if (!inst || !inst->core) + return; + core = inst->core; + + mutex_lock(&core->lock); + list_for_each_entry(temp, &core->instances, list) { + if (temp->session_type == MSM_VIDC_CVP) { + dprintk(VIDC_ERR, "session %#x, vpss %d ise %d\n", + hash32_ptr(temp->session), + temp->clk_data.vpss_cycles, + temp->clk_data.ise_cycles); + } + } + mutex_unlock(&core->lock); +} + +static bool msm_cvp_check_session_supported(struct msm_vidc_inst *inst, + u32 vpss_cycles, u32 ise_cycles) +{ + struct msm_vidc_core *core; + struct msm_vidc_inst *temp; + u32 total_vpss_cycles = 0; + u32 total_ise_cycles = 0; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return false; + } + core = inst->core; + + mutex_lock(&core->lock); + list_for_each_entry(temp, &core->instances, list) { + if (temp->session_type == MSM_VIDC_CVP) { + total_vpss_cycles += inst->clk_data.vpss_cycles; + total_ise_cycles += inst->clk_data.ise_cycles; + } + } + mutex_unlock(&core->lock); + + if ((total_vpss_cycles > MAX_CVP_VPSS_CYCLES) || + (total_ise_cycles > MAX_CVP_ISE_CYCLES)) + return false; + + return true; +} + +static int msm_cvp_scale_clocks_and_bus(struct msm_vidc_inst *inst) +{ + int rc = 0; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + rc = msm_vidc_set_clocks(inst->core); + if (rc) { + dprintk(VIDC_ERR, + "%s: failed set_clocks for inst %pK (%#x)\n", + __func__, inst, hash32_ptr(inst->session)); + goto exit; + } + + rc = msm_comm_vote_bus(inst->core); + if (rc) { + dprintk(VIDC_ERR, + "%s: failed vote_bus for inst %pK (%#x)\n", + __func__, inst, hash32_ptr(inst->session)); + goto exit; + } + +exit: + return rc; +} + +static int msm_cvp_get_session_info(struct msm_vidc_inst *inst, + struct msm_cvp_session_info *session) +{ + int rc = 0; + + if (!inst || !inst->core || !session) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + session->session_id = hash32_ptr(inst->session); + dprintk(VIDC_DBG, "%s: id 0x%x\n", __func__, session->session_id); + + return rc; +} + +static int msm_cvp_request_power(struct msm_vidc_inst *inst, + struct msm_cvp_request_power *power) +{ + int rc = 0; + + if (!inst || !power) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + dprintk(VIDC_DBG, + "%s: clock_cycles_a %d, clock_cycles_b %d, ddr_bw %d sys_cache_bw %d\n", + __func__, power->clock_cycles_a, power->clock_cycles_b, + power->ddr_bw, power->sys_cache_bw); + + rc = msm_cvp_check_session_supported(inst, power->clock_cycles_a, + power->clock_cycles_b); + if (!rc) { + dprintk(VIDC_ERR, + "%s: session %#x rejected, cycles: vpss %d, ise %d\n", + __func__, hash32_ptr(inst->session), + power->clock_cycles_a, power->clock_cycles_b); + print_cvp_cycles(inst); + msm_comm_kill_session(inst); + return -EOVERFLOW; + } + + inst->clk_data.min_freq = max(power->clock_cycles_a, + power->clock_cycles_b); + /* convert client provided bps into kbps as expected by driver */ + inst->clk_data.ddr_bw = power->ddr_bw / 1000; + inst->clk_data.sys_cache_bw = power->sys_cache_bw / 1000; + rc = msm_cvp_scale_clocks_and_bus(inst); + if (rc) { + dprintk(VIDC_ERR, + "%s: failed to scale clocks and bus for inst %pK (%#x)\n", + __func__, inst, hash32_ptr(inst->session)); + goto exit; + } + + if (!inst->clk_data.min_freq && !inst->clk_data.ddr_bw && + !inst->clk_data.sys_cache_bw) { + rc = msm_cvp_inst_pause(inst); + if (rc) { + dprintk(VIDC_ERR, + "%s: failed to pause inst %pK (%#x)\n", + __func__, inst, hash32_ptr(inst->session)); + goto exit; + } + } else { + rc = msm_cvp_inst_resume(inst); + if (rc) { + dprintk(VIDC_ERR, + "%s: failed to resume inst %pK (%#x)\n", + __func__, inst, hash32_ptr(inst->session)); + goto exit; + } + } + +exit: + return rc; +} + +static int msm_cvp_register_buffer(struct msm_vidc_inst *inst, + struct msm_cvp_buffer *buf) +{ + int rc = 0; + bool found; + struct hfi_device *hdev; + struct msm_vidc_cvp_buffer *cbuf; + struct vidc_register_buffer vbuf; + + if (!inst || !inst->core || !buf) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + print_client_buffer(VIDC_DBG, "register", inst, buf); + + mutex_lock(&inst->cvpbufs.lock); + found = false; + list_for_each_entry(cbuf, &inst->cvpbufs.list, list) { + if (cbuf->buf.index == buf->index && + cbuf->buf.fd == buf->fd && + cbuf->buf.offset == buf->offset) { + found = true; + break; + } + } + mutex_unlock(&inst->cvpbufs.lock); + if (found) { + print_client_buffer(VIDC_ERR, "duplicate", inst, buf); + return -EINVAL; + } + + cbuf = kzalloc(sizeof(struct msm_vidc_cvp_buffer), GFP_KERNEL); + if (!cbuf) { + dprintk(VIDC_ERR, "%s: cbuf alloc failed\n", __func__); + return -ENOMEM; + } + mutex_lock(&inst->cvpbufs.lock); + list_add_tail(&cbuf->list, &inst->cvpbufs.list); + mutex_unlock(&inst->cvpbufs.lock); + + memcpy(&cbuf->buf, buf, sizeof(struct msm_cvp_buffer)); + cbuf->smem.buffer_type = get_hal_buftype(__func__, buf->type); + cbuf->smem.fd = buf->fd; + cbuf->smem.offset = buf->offset; + cbuf->smem.size = buf->size; + rc = inst->smem_ops->smem_map_dma_buf(inst, &cbuf->smem); + if (rc) { + print_client_buffer(VIDC_ERR, "map failed", inst, buf); + goto exit; + } + + memset(&vbuf, 0, sizeof(struct vidc_register_buffer)); + vbuf.index = buf->index; + vbuf.type = get_hal_buftype(__func__, buf->type); + vbuf.size = buf->size; + vbuf.device_addr = cbuf->smem.device_addr; + vbuf.client_data = cbuf->smem.device_addr; + vbuf.response_required = true; + rc = call_hfi_op(hdev, session_register_buffer, + (void *)inst->session, &vbuf); + if (rc) { + print_cvp_buffer(VIDC_ERR, "register failed", inst, cbuf); + goto exit; + } + return rc; + +exit: + if (cbuf->smem.device_addr) + inst->smem_ops->smem_unmap_dma_buf(inst, &cbuf->smem); + mutex_lock(&inst->cvpbufs.lock); + list_del(&cbuf->list); + mutex_unlock(&inst->cvpbufs.lock); + kfree(cbuf); + cbuf = NULL; + + return rc; +} + +static int msm_cvp_unregister_buffer(struct msm_vidc_inst *inst, + struct msm_cvp_buffer *buf) +{ + int rc = 0; + bool found; + struct hfi_device *hdev; + struct msm_vidc_cvp_buffer *cbuf; + struct vidc_unregister_buffer vbuf; + + if (!inst || !inst->core || !buf) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + print_client_buffer(VIDC_DBG, "unregister", inst, buf); + + mutex_lock(&inst->cvpbufs.lock); + found = false; + list_for_each_entry(cbuf, &inst->cvpbufs.list, list) { + if (cbuf->buf.index == buf->index && + cbuf->buf.fd == buf->fd && + cbuf->buf.offset == buf->offset) { + found = true; + break; + } + } + mutex_unlock(&inst->cvpbufs.lock); + if (!found) { + print_client_buffer(VIDC_ERR, "invalid", inst, buf); + return -EINVAL; + } + + memset(&vbuf, 0, sizeof(struct vidc_unregister_buffer)); + vbuf.index = cbuf->buf.index; + vbuf.type = get_hal_buftype(__func__, cbuf->buf.type); + vbuf.size = cbuf->buf.size; + vbuf.device_addr = cbuf->smem.device_addr; + vbuf.client_data = cbuf->smem.device_addr; + vbuf.response_required = true; + rc = call_hfi_op(hdev, session_unregister_buffer, + (void *)inst->session, &vbuf); + if (rc) + print_cvp_buffer(VIDC_ERR, "unregister failed", inst, cbuf); + + return rc; +} + +int msm_vidc_cvp(struct msm_vidc_inst *inst, struct msm_vidc_arg *arg) +{ + int rc = 0; + + if (!inst || !arg) { + dprintk(VIDC_ERR, "%s: invalid args\n", __func__); + return -EINVAL; + } + + switch (arg->type) { + case MSM_CVP_GET_SESSION_INFO: + { + struct msm_cvp_session_info *session = + (struct msm_cvp_session_info *)&arg->data.session; + + rc = msm_cvp_get_session_info(inst, session); + break; + } + case MSM_CVP_REQUEST_POWER: + { + struct msm_cvp_request_power *power = + (struct msm_cvp_request_power *)&arg->data.req_power; + + rc = msm_cvp_request_power(inst, power); + break; + } + case MSM_CVP_REGISTER_BUFFER: + { + struct msm_cvp_buffer *buf = + (struct msm_cvp_buffer *)&arg->data.regbuf; + + rc = msm_cvp_register_buffer(inst, buf); + break; + } + case MSM_CVP_UNREGISTER_BUFFER: + { + struct msm_cvp_buffer *buf = + (struct msm_cvp_buffer *)&arg->data.unregbuf; + + rc = msm_cvp_unregister_buffer(inst, buf); + break; + } + default: + dprintk(VIDC_ERR, "%s: unknown arg type 0x%x\n", + __func__, arg->type); + rc = -ENOTSUPP; + break; + } + + return rc; +} + +static struct msm_vidc_ctrl msm_cvp_ctrls[] = { + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE, + .name = "Secure mode", + .type = V4L2_CTRL_TYPE_BUTTON, + .minimum = 0, + .maximum = 1, + .default_value = 0, + .step = 1, + .menu_skip_mask = 0, + .qmenu = NULL, + }, +}; + +int msm_cvp_ctrl_init(struct msm_vidc_inst *inst, + const struct v4l2_ctrl_ops *ctrl_ops) +{ + return msm_comm_ctrl_init(inst, msm_cvp_ctrls, + ARRAY_SIZE(msm_cvp_ctrls), ctrl_ops); +} + +int msm_cvp_inst_pause(struct msm_vidc_inst *inst) +{ + int rc; + struct hfi_device *hdev; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + rc = call_hfi_op(hdev, session_pause, (void *)inst->session); + if (rc) + dprintk(VIDC_ERR, "%s: failed to pause inst %pK (%#x)\n", + __func__, inst, hash32_ptr(inst->session)); + + return rc; +} + +int msm_cvp_inst_resume(struct msm_vidc_inst *inst) +{ + int rc; + struct hfi_device *hdev; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + rc = call_hfi_op(hdev, session_resume, (void *)inst->session); + if (rc) + dprintk(VIDC_ERR, "%s: failed to resume inst %pK (%#x)\n", + __func__, inst, hash32_ptr(inst->session)); + + return rc; +} + +int msm_cvp_inst_deinit(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_vidc_cvp_buffer *cbuf, *temp; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + dprintk(VIDC_DBG, "%s: inst %pK (%#x)\n", __func__, + inst, hash32_ptr(inst->session)); + + rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE); + if (rc) + dprintk(VIDC_ERR, "%s: close failed\n", __func__); + + mutex_lock(&inst->cvpbufs.lock); + list_for_each_entry_safe(cbuf, temp, &inst->cvpbufs.list, list) { + print_cvp_buffer(VIDC_ERR, "unregistered", inst, cbuf); + rc = inst->smem_ops->smem_unmap_dma_buf(inst, &cbuf->smem); + if (rc) + dprintk(VIDC_ERR, "%s: unmap failed\n", __func__); + list_del(&cbuf->list); + kfree(cbuf); + } + mutex_unlock(&inst->cvpbufs.lock); + + inst->clk_data.min_freq = 0; + inst->clk_data.ddr_bw = 0; + inst->clk_data.sys_cache_bw = 0; + rc = msm_cvp_scale_clocks_and_bus(inst); + if (rc) + dprintk(VIDC_ERR, "%s: failed to scale_clocks_and_bus\n", + __func__); + + return rc; +} + +int msm_cvp_inst_init(struct msm_vidc_inst *inst) +{ + int rc = 0; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + dprintk(VIDC_DBG, "%s: inst %pK (%#x)\n", __func__, + inst, hash32_ptr(inst->session)); + + /* set default frequency */ + inst->clk_data.core_id = VIDC_CORE_ID_2; + inst->clk_data.min_freq = 1000; + inst->clk_data.ddr_bw = 1000; + inst->clk_data.sys_cache_bw = 1000; + + return rc; +} diff --git a/msm/vidc/msm_cvp_internal.h b/msm/vidc/msm_cvp_internal.h new file mode 100644 index 000000000000..1a6f4ce63476 --- /dev/null +++ b/msm/vidc/msm_cvp_internal.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + */ + +#ifndef _MSM_CVP_INTERNAL_H_ +#define _MSM_CVP_INTERNAL_H_ + +#include "msm_vidc_internal.h" +#include "msm_vidc_common.h" +#include "msm_vidc_clocks.h" +#include "msm_vidc_debug.h" + +void handle_session_register_buffer_done(enum hal_command_response cmd, + void *resp); +void handle_session_unregister_buffer_done(enum hal_command_response cmd, + void *resp); +int msm_vidc_cvp(struct msm_vidc_inst *inst, struct msm_vidc_arg *arg); +int msm_cvp_inst_init(struct msm_vidc_inst *inst); +int msm_cvp_inst_deinit(struct msm_vidc_inst *inst); +int msm_cvp_inst_pause(struct msm_vidc_inst *inst); +int msm_cvp_inst_resume(struct msm_vidc_inst *inst); +int msm_cvp_ctrl_init(struct msm_vidc_inst *inst, + const struct v4l2_ctrl_ops *ctrl_ops); +#endif diff --git a/msm/vidc/msm_smem.c b/msm/vidc/msm_smem.c new file mode 100644 index 000000000000..f9336347f99d --- /dev/null +++ b/msm/vidc/msm_smem.c @@ -0,0 +1,594 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm_vidc.h" +#include "msm_vidc_debug.h" +#include "msm_vidc_resources.h" + + +static int msm_dma_get_device_address(struct dma_buf *dbuf, unsigned long align, + dma_addr_t *iova, unsigned long *buffer_size, + unsigned long flags, enum hal_buffer buffer_type, + unsigned long session_type, struct msm_vidc_platform_resources *res, + struct dma_mapping_info *mapping_info) +{ + int rc = 0; + struct dma_buf_attachment *attach; + struct sg_table *table = NULL; + struct context_bank_info *cb = NULL; + + if (!dbuf || !iova || !buffer_size || !mapping_info) { + dprintk(VIDC_ERR, "Invalid params: %pK, %pK, %pK, %pK\n", + dbuf, iova, buffer_size, mapping_info); + return -EINVAL; + } + + if (is_iommu_present(res)) { + cb = msm_smem_get_context_bank( + session_type, (flags & SMEM_SECURE), + res, buffer_type); + if (!cb) { + dprintk(VIDC_ERR, + "%s: Failed to get context bank device\n", + __func__); + rc = -EIO; + goto mem_map_failed; + } + + /* Check if the dmabuf size matches expected size */ + if (dbuf->size < *buffer_size) { + rc = -EINVAL; + dprintk(VIDC_ERR, + "Size mismatch: Dmabuf size: %zu Expected Size: %lu", + dbuf->size, *buffer_size); + msm_vidc_res_handle_fatal_hw_error(res, + true); + goto mem_buf_size_mismatch; + } + + /* Prepare a dma buf for dma on the given device */ + attach = dma_buf_attach(dbuf, cb->dev); + if (IS_ERR_OR_NULL(attach)) { + rc = PTR_ERR(attach) ? PTR_ERR(attach) : -ENOMEM; + dprintk(VIDC_ERR, "Failed to attach dmabuf\n"); + goto mem_buf_attach_failed; + } + + /* + * Get the scatterlist for the given attachment + * Mapping of sg is taken care by map attachment + */ + attach->dma_map_attrs = DMA_ATTR_DELAYED_UNMAP; + /* + * We do not need dma_map function to perform cache operations + * on the whole buffer size and hence pass skip sync flag. + * We do the required cache operations separately for the + * required buffer size + */ + attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC; + if (res->sys_cache_present) + attach->dma_map_attrs |= + DMA_ATTR_IOMMU_USE_UPSTREAM_HINT; + + table = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); + if (IS_ERR_OR_NULL(table)) { + rc = PTR_ERR(table) ? PTR_ERR(table) : -ENOMEM; + dprintk(VIDC_ERR, "Failed to map table\n"); + goto mem_map_table_failed; + } + + /* debug trace's need to be updated later */ + trace_msm_smem_buffer_iommu_op_start("MAP", 0, 0, + align, *iova, *buffer_size); + + if (table->sgl) { + *iova = table->sgl->dma_address; + *buffer_size = table->sgl->dma_length; + } else { + dprintk(VIDC_ERR, "sgl is NULL\n"); + rc = -ENOMEM; + goto mem_map_sg_failed; + } + + mapping_info->dev = cb->dev; + mapping_info->domain = cb->domain; + mapping_info->table = table; + mapping_info->attach = attach; + mapping_info->buf = dbuf; + mapping_info->cb_info = (void *)cb; + + trace_msm_smem_buffer_iommu_op_end("MAP", 0, 0, + align, *iova, *buffer_size); + } else { + dprintk(VIDC_DBG, "iommu not present, use phys mem addr\n"); + } + + return 0; +mem_map_sg_failed: + dma_buf_unmap_attachment(attach, table, DMA_BIDIRECTIONAL); +mem_map_table_failed: + dma_buf_detach(dbuf, attach); +mem_buf_size_mismatch: +mem_buf_attach_failed: +mem_map_failed: + return rc; +} + +static int msm_dma_put_device_address(u32 flags, + struct dma_mapping_info *mapping_info, + enum hal_buffer buffer_type) +{ + int rc = 0; + + if (!mapping_info) { + dprintk(VIDC_WARN, "Invalid mapping_info\n"); + return -EINVAL; + } + + if (!mapping_info->dev || !mapping_info->table || + !mapping_info->buf || !mapping_info->attach || + !mapping_info->cb_info) { + dprintk(VIDC_WARN, "Invalid params\n"); + return -EINVAL; + } + + trace_msm_smem_buffer_iommu_op_start("UNMAP", 0, 0, 0, 0, 0); + dma_buf_unmap_attachment(mapping_info->attach, + mapping_info->table, DMA_BIDIRECTIONAL); + dma_buf_detach(mapping_info->buf, mapping_info->attach); + trace_msm_smem_buffer_iommu_op_end("UNMAP", 0, 0, 0, 0, 0); + + mapping_info->dev = NULL; + mapping_info->domain = NULL; + mapping_info->table = NULL; + mapping_info->attach = NULL; + mapping_info->buf = NULL; + mapping_info->cb_info = NULL; + + + return rc; +} + +struct dma_buf *msm_smem_get_dma_buf(int fd) +{ + struct dma_buf *dma_buf; + + dma_buf = dma_buf_get(fd); + if (IS_ERR_OR_NULL(dma_buf)) { + dprintk(VIDC_ERR, "Failed to get dma_buf for %d, error %ld\n", + fd, PTR_ERR(dma_buf)); + dma_buf = NULL; + } + + return dma_buf; +} + +void msm_smem_put_dma_buf(void *dma_buf) +{ + if (!dma_buf) { + dprintk(VIDC_ERR, "%s: NULL dma_buf\n", __func__); + return; + } + + dma_buf_put((struct dma_buf *)dma_buf); +} + +int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) +{ + int rc = 0; + + dma_addr_t iova = 0; + u32 temp = 0; + unsigned long buffer_size = 0; + unsigned long align = SZ_4K; + struct dma_buf *dbuf; + unsigned long ion_flags = 0; + + if (!inst || !smem) { + dprintk(VIDC_ERR, "%s: Invalid params: %pK %pK\n", + __func__, inst, smem); + rc = -EINVAL; + goto exit; + } + + if (smem->refcount) { + smem->refcount++; + goto exit; + } + + dbuf = msm_smem_get_dma_buf(smem->fd); + if (!dbuf) { + rc = -EINVAL; + goto exit; + } + + smem->dma_buf = dbuf; + + rc = dma_buf_get_flags(dbuf, &ion_flags); + if (rc) { + dprintk(VIDC_ERR, "Failed to get dma buf flags: %d\n", rc); + goto exit; + } + if (ion_flags & ION_FLAG_CACHED) + smem->flags |= SMEM_CACHED; + + if (ion_flags & ION_FLAG_SECURE) + smem->flags |= SMEM_SECURE; + + buffer_size = smem->size; + + rc = msm_dma_get_device_address(dbuf, align, &iova, &buffer_size, + smem->flags, smem->buffer_type, inst->session_type, + &(inst->core->resources), &smem->mapping_info); + if (rc) { + dprintk(VIDC_ERR, "Failed to get device address: %d\n", rc); + goto exit; + } + temp = (u32)iova; + if ((dma_addr_t)temp != iova) { + dprintk(VIDC_ERR, "iova(%pa) truncated to %#x", &iova, temp); + rc = -EINVAL; + goto exit; + } + + smem->device_addr = (u32)iova + smem->offset; + + smem->refcount++; +exit: + return rc; +} + +int msm_smem_unmap_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) +{ + int rc = 0; + + if (!inst || !smem) { + dprintk(VIDC_ERR, "%s: Invalid params: %pK %pK\n", + __func__, inst, smem); + rc = -EINVAL; + goto exit; + } + + if (smem->refcount) { + smem->refcount--; + } else { + dprintk(VIDC_WARN, + "unmap called while refcount is zero already\n"); + return -EINVAL; + } + + if (smem->refcount) + goto exit; + + rc = msm_dma_put_device_address(smem->flags, &smem->mapping_info, + smem->buffer_type); + if (rc) { + dprintk(VIDC_ERR, "Failed to put device address: %d\n", rc); + goto exit; + } + + msm_smem_put_dma_buf(smem->dma_buf); + + smem->device_addr = 0x0; + smem->dma_buf = NULL; + +exit: + return rc; +} + +static int get_secure_flag_for_buffer_type( + u32 session_type, enum hal_buffer buffer_type) +{ + switch (buffer_type) { + case HAL_BUFFER_INPUT: + if (session_type == MSM_VIDC_ENCODER) + return ION_FLAG_CP_PIXEL; + else + return ION_FLAG_CP_BITSTREAM; + case HAL_BUFFER_OUTPUT: + case HAL_BUFFER_OUTPUT2: + if (session_type == MSM_VIDC_ENCODER) + return ION_FLAG_CP_BITSTREAM; + else + return ION_FLAG_CP_PIXEL; + case HAL_BUFFER_INTERNAL_SCRATCH: + return ION_FLAG_CP_BITSTREAM; + case HAL_BUFFER_INTERNAL_SCRATCH_1: + return ION_FLAG_CP_NON_PIXEL; + case HAL_BUFFER_INTERNAL_SCRATCH_2: + return ION_FLAG_CP_PIXEL; + case HAL_BUFFER_INTERNAL_PERSIST: + if (session_type == MSM_VIDC_ENCODER) + return ION_FLAG_CP_NON_PIXEL; + else + return ION_FLAG_CP_BITSTREAM; + case HAL_BUFFER_INTERNAL_PERSIST_1: + return ION_FLAG_CP_NON_PIXEL; + default: + WARN(1, "No matching secure flag for buffer type : %x\n", + buffer_type); + return -EINVAL; + } +} + +static int alloc_dma_mem(size_t size, u32 align, u32 flags, + enum hal_buffer buffer_type, int map_kernel, + struct msm_vidc_platform_resources *res, u32 session_type, + struct msm_smem *mem) +{ + dma_addr_t iova = 0; + unsigned long buffer_size = 0; + unsigned long heap_mask = 0; + int rc = 0; + int ion_flags = 0; + struct dma_buf *dbuf = NULL; + + if (!res) { + dprintk(VIDC_ERR, "%s: NULL res\n", __func__); + return -EINVAL; + } + + align = ALIGN(align, SZ_4K); + size = ALIGN(size, SZ_4K); + + if (is_iommu_present(res)) { + if (flags & SMEM_ADSP) { + dprintk(VIDC_DBG, "Allocating from ADSP heap\n"); + heap_mask = ION_HEAP(ION_ADSP_HEAP_ID); + } else { + heap_mask = ION_HEAP(ION_SYSTEM_HEAP_ID); + } + } else { + dprintk(VIDC_DBG, + "allocate shared memory from adsp heap size %zx align %d\n", + size, align); + heap_mask = ION_HEAP(ION_ADSP_HEAP_ID); + } + + if (flags & SMEM_CACHED) + ion_flags |= ION_FLAG_CACHED; + + if ((flags & SMEM_SECURE) || + (buffer_type == HAL_BUFFER_INTERNAL_PERSIST && + session_type == MSM_VIDC_ENCODER)) { + int secure_flag = + get_secure_flag_for_buffer_type( + session_type, buffer_type); + if (secure_flag < 0) { + rc = secure_flag; + goto fail_shared_mem_alloc; + } + + ion_flags |= ION_FLAG_SECURE | secure_flag; + heap_mask = ION_HEAP(ION_SECURE_HEAP_ID); + + if (res->slave_side_cp) { + heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID); + size = ALIGN(size, SZ_1M); + align = ALIGN(size, SZ_1M); + } + flags |= SMEM_SECURE; + } + + trace_msm_smem_buffer_dma_op_start("ALLOC", (u32)buffer_type, + heap_mask, size, align, flags, map_kernel); + dbuf = ion_alloc(size, heap_mask, ion_flags); + if (IS_ERR_OR_NULL(dbuf)) { + dprintk(VIDC_ERR, + "Failed to allocate shared memory = %zx, %#x\n", + size, flags); + rc = -ENOMEM; + goto fail_shared_mem_alloc; + } + trace_msm_smem_buffer_dma_op_end("ALLOC", (u32)buffer_type, + heap_mask, size, align, flags, map_kernel); + + mem->flags = flags; + mem->buffer_type = buffer_type; + mem->offset = 0; + mem->size = size; + mem->dma_buf = dbuf; + mem->kvaddr = NULL; + + rc = msm_dma_get_device_address(dbuf, align, &iova, + &buffer_size, flags, buffer_type, + session_type, res, &mem->mapping_info); + if (rc) { + dprintk(VIDC_ERR, "Failed to get device address: %d\n", + rc); + goto fail_device_address; + } + mem->device_addr = (u32)iova; + if ((dma_addr_t)mem->device_addr != iova) { + dprintk(VIDC_ERR, "iova(%pa) truncated to %#x", + &iova, mem->device_addr); + goto fail_device_address; + } + + if (map_kernel) { + dma_buf_begin_cpu_access(dbuf, DMA_BIDIRECTIONAL); + mem->kvaddr = dma_buf_vmap(dbuf); + if (!mem->kvaddr) { + dprintk(VIDC_ERR, + "Failed to map shared mem in kernel\n"); + rc = -EIO; + goto fail_map; + } + } + + dprintk(VIDC_DBG, + "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, buffer_type = %#x, flags = %#lx\n", + __func__, mem->dma_buf, mem->device_addr, mem->size, + mem->kvaddr, mem->buffer_type, mem->flags); + return rc; + +fail_map: + if (map_kernel) + dma_buf_end_cpu_access(dbuf, DMA_BIDIRECTIONAL); +fail_device_address: + dma_buf_put(dbuf); +fail_shared_mem_alloc: + return rc; +} + +static int free_dma_mem(struct msm_smem *mem) +{ + dprintk(VIDC_DBG, + "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, buffer_type = %#x\n", + __func__, mem->dma_buf, mem->device_addr, mem->size, + mem->kvaddr, mem->buffer_type); + + if (mem->device_addr) { + msm_dma_put_device_address(mem->flags, + &mem->mapping_info, mem->buffer_type); + mem->device_addr = 0x0; + } + + if (mem->kvaddr) { + dma_buf_vunmap(mem->dma_buf, mem->kvaddr); + mem->kvaddr = NULL; + dma_buf_end_cpu_access(mem->dma_buf, DMA_BIDIRECTIONAL); + } + + if (mem->dma_buf) { + trace_msm_smem_buffer_dma_op_start("FREE", + (u32)mem->buffer_type, -1, mem->size, -1, + mem->flags, -1); + dma_buf_put(mem->dma_buf); + mem->dma_buf = NULL; + trace_msm_smem_buffer_dma_op_end("FREE", (u32)mem->buffer_type, + -1, mem->size, -1, mem->flags, -1); + } + + return 0; +} + +int msm_smem_alloc(size_t size, u32 align, u32 flags, + enum hal_buffer buffer_type, int map_kernel, + void *res, u32 session_type, struct msm_smem *smem) +{ + int rc = 0; + + if (!smem || !size) { + dprintk(VIDC_ERR, "%s: NULL smem or %d size\n", + __func__, (u32)size); + return -EINVAL; + } + + rc = alloc_dma_mem(size, align, flags, buffer_type, map_kernel, + (struct msm_vidc_platform_resources *)res, + session_type, smem); + + return rc; +} + +int msm_smem_free(struct msm_smem *smem) +{ + int rc = 0; + + if (!smem) { + dprintk(VIDC_ERR, "NULL smem passed\n"); + return -EINVAL; + } + rc = free_dma_mem(smem); + + return rc; +}; + +int msm_smem_cache_operations(struct dma_buf *dbuf, + enum smem_cache_ops cache_op, unsigned long offset, unsigned long size) +{ + int rc = 0; + unsigned long flags = 0; + + if (!dbuf) { + dprintk(VIDC_ERR, "%s: Invalid params\n", __func__); + return -EINVAL; + } + + /* Return if buffer doesn't support caching */ + rc = dma_buf_get_flags(dbuf, &flags); + if (rc) { + dprintk(VIDC_ERR, "%s: dma_buf_get_flags failed, err %d\n", + __func__, rc); + return rc; + } else if (!(flags & ION_FLAG_CACHED)) { + return rc; + } + + switch (cache_op) { + case SMEM_CACHE_CLEAN: + case SMEM_CACHE_CLEAN_INVALIDATE: + rc = dma_buf_begin_cpu_access_partial(dbuf, DMA_TO_DEVICE, + offset, size); + if (rc) + break; + rc = dma_buf_end_cpu_access_partial(dbuf, DMA_TO_DEVICE, + offset, size); + break; + case SMEM_CACHE_INVALIDATE: + rc = dma_buf_begin_cpu_access_partial(dbuf, DMA_TO_DEVICE, + offset, size); + if (rc) + break; + rc = dma_buf_end_cpu_access_partial(dbuf, DMA_FROM_DEVICE, + offset, size); + break; + default: + dprintk(VIDC_ERR, "%s: cache (%d) operation not supported\n", + __func__, cache_op); + rc = -EINVAL; + break; + } + + return rc; +} + +struct context_bank_info *msm_smem_get_context_bank(u32 session_type, + bool is_secure, struct msm_vidc_platform_resources *res, + enum hal_buffer buffer_type) +{ + struct context_bank_info *cb = NULL, *match = NULL; + + /* + * HAL_BUFFER_INPUT is directly mapped to bitstream CB in DT + * as the buffer type structure was initially designed + * just for decoder. For Encoder, input should be mapped to + * yuvpixel CB. Persist is mapped to nonpixel CB. + * So swap the buffer types just in this local scope. + */ + if (is_secure && session_type == MSM_VIDC_ENCODER) { + if (buffer_type == HAL_BUFFER_INPUT) + buffer_type = HAL_BUFFER_OUTPUT; + else if (buffer_type == HAL_BUFFER_OUTPUT) + buffer_type = HAL_BUFFER_INPUT; + else if (buffer_type == HAL_BUFFER_INTERNAL_PERSIST) + buffer_type = HAL_BUFFER_INTERNAL_PERSIST_1; + } + + list_for_each_entry(cb, &res->context_banks, list) { + if (cb->is_secure == is_secure && + cb->buffer_type & buffer_type) { + match = cb; + break; + } + } + if (!match) + dprintk(VIDC_ERR, + "%s: cb not found for buffer_type %x, is_secure %d\n", + __func__, buffer_type, is_secure); + + return match; +} + diff --git a/msm/vidc/msm_v4l2_private.c b/msm/vidc/msm_v4l2_private.c new file mode 100644 index 000000000000..6200054e0dbd --- /dev/null +++ b/msm/vidc/msm_v4l2_private.c @@ -0,0 +1,226 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include "msm_v4l2_private.h" + +static int convert_from_user(struct msm_vidc_arg *kp, unsigned long arg) +{ + int rc = 0; + int i; + struct msm_vidc_arg __user *up = compat_ptr(arg); + + if (!kp || !up) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (get_user(kp->type, &up->type)) + return -EFAULT; + + switch (kp->type) { + case MSM_CVP_GET_SESSION_INFO: + { + struct msm_cvp_session_info *k, *u; + + k = &kp->data.session; + u = &up->data.session; + if (get_user(k->session_id, &u->session_id)) + return -EFAULT; + for (i = 0; i < 10; i++) + if (get_user(k->reserved[i], &u->reserved[i])) + return -EFAULT; + break; + } + case MSM_CVP_REQUEST_POWER: + { + struct msm_cvp_request_power *k, *u; + + k = &kp->data.req_power; + u = &up->data.req_power; + if (get_user(k->clock_cycles_a, &u->clock_cycles_a) || + get_user(k->clock_cycles_b, &u->clock_cycles_b) || + get_user(k->ddr_bw, &u->ddr_bw) || + get_user(k->sys_cache_bw, &u->sys_cache_bw)) + return -EFAULT; + for (i = 0; i < 8; i++) + if (get_user(k->reserved[i], &u->reserved[i])) + return -EFAULT; + break; + } + case MSM_CVP_REGISTER_BUFFER: + { + struct msm_cvp_buffer *k, *u; + + k = &kp->data.regbuf; + u = &up->data.regbuf; + if (get_user(k->type, &u->type) || + get_user(k->index, &u->index) || + get_user(k->fd, &u->fd) || + get_user(k->size, &u->size) || + get_user(k->offset, &u->offset) || + get_user(k->pixelformat, &u->pixelformat) || + get_user(k->flags, &u->flags)) + return -EFAULT; + for (i = 0; i < 5; i++) + if (get_user(k->reserved[i], &u->reserved[i])) + return -EFAULT; + break; + } + case MSM_CVP_UNREGISTER_BUFFER: + { + struct msm_cvp_buffer *k, *u; + + k = &kp->data.unregbuf; + u = &up->data.unregbuf; + if (get_user(k->type, &u->type) || + get_user(k->index, &u->index) || + get_user(k->fd, &u->fd) || + get_user(k->size, &u->size) || + get_user(k->offset, &u->offset) || + get_user(k->pixelformat, &u->pixelformat) || + get_user(k->flags, &u->flags)) + return -EFAULT; + for (i = 0; i < 5; i++) + if (get_user(k->reserved[i], &u->reserved[i])) + return -EFAULT; + break; + } + default: + dprintk(VIDC_ERR, "%s: unknown cmd type 0x%x\n", + __func__, kp->type); + rc = -EINVAL; + break; + } + + return rc; +} + +static int convert_to_user(struct msm_vidc_arg *kp, unsigned long arg) +{ + int rc = 0; + int i; + struct msm_vidc_arg __user *up = compat_ptr(arg); + + if (!kp || !up) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (put_user(kp->type, &up->type)) + return -EFAULT; + + switch (kp->type) { + case MSM_CVP_GET_SESSION_INFO: + { + struct msm_cvp_session_info *k, *u; + + k = &kp->data.session; + u = &up->data.session; + if (put_user(k->session_id, &u->session_id)) + return -EFAULT; + for (i = 0; i < 10; i++) + if (put_user(k->reserved[i], &u->reserved[i])) + return -EFAULT; + break; + } + case MSM_CVP_REQUEST_POWER: + { + struct msm_cvp_request_power *k, *u; + + k = &kp->data.req_power; + u = &up->data.req_power; + if (put_user(k->clock_cycles_a, &u->clock_cycles_a) || + put_user(k->clock_cycles_b, &u->clock_cycles_b) || + put_user(k->ddr_bw, &u->ddr_bw) || + put_user(k->sys_cache_bw, &u->sys_cache_bw)) + return -EFAULT; + for (i = 0; i < 8; i++) + if (put_user(k->reserved[i], &u->reserved[i])) + return -EFAULT; + break; + } + case MSM_CVP_REGISTER_BUFFER: + { + struct msm_cvp_buffer *k, *u; + + k = &kp->data.regbuf; + u = &up->data.regbuf; + if (put_user(k->type, &u->type) || + put_user(k->index, &u->index) || + put_user(k->fd, &u->fd) || + put_user(k->size, &u->size) || + put_user(k->offset, &u->offset) || + put_user(k->pixelformat, &u->pixelformat) || + put_user(k->flags, &u->flags)) + return -EFAULT; + for (i = 0; i < 5; i++) + if (put_user(k->reserved[i], &u->reserved[i])) + return -EFAULT; + break; + } + case MSM_CVP_UNREGISTER_BUFFER: + { + struct msm_cvp_buffer *k, *u; + + k = &kp->data.unregbuf; + u = &up->data.unregbuf; + if (put_user(k->type, &u->type) || + put_user(k->index, &u->index) || + put_user(k->fd, &u->fd) || + put_user(k->size, &u->size) || + put_user(k->offset, &u->offset) || + put_user(k->pixelformat, &u->pixelformat) || + put_user(k->flags, &u->flags)) + return -EFAULT; + for (i = 0; i < 5; i++) + if (put_user(k->reserved[i], &u->reserved[i])) + return -EFAULT; + break; + } + default: + dprintk(VIDC_ERR, "%s: unknown cmd type 0x%x\n", + __func__, kp->type); + rc = -EINVAL; + break; + } + + return rc; +} + +long msm_v4l2_private(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int rc; + struct msm_vidc_inst *inst; + struct msm_vidc_arg karg; + + if (!filp || !filp->private_data) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + inst = container_of(filp->private_data, struct msm_vidc_inst, + event_handler); + memset(&karg, 0, sizeof(struct msm_vidc_arg)); + + /* + * the arg points to user space memory and needs + * to be converted to kernel space before using it. + * Check do_video_ioctl() for more details. + */ + if (convert_from_user(&karg, arg)) + return -EFAULT; + + rc = msm_vidc_private((void *)inst, cmd, &karg); + if (rc) { + dprintk(VIDC_ERR, "%s: failed cmd type %x\n", + __func__, karg.type); + return -EINVAL; + } + + if (convert_to_user(&karg, arg)) + return -EFAULT; + + return rc; +} diff --git a/msm/vidc/msm_v4l2_private.h b/msm/vidc/msm_v4l2_private.h new file mode 100644 index 000000000000..5f1602aca410 --- /dev/null +++ b/msm/vidc/msm_v4l2_private.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _MSM_V4L2_PRIVATE_H_ +#define _MSM_V4L2_PRIVATE_H_ + +#include +#include "msm_vidc_debug.h" + +long msm_v4l2_private(struct file *file, unsigned int cmd, unsigned long arg); + +#endif diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c new file mode 100644 index 000000000000..1eb74547a8d3 --- /dev/null +++ b/msm/vidc/msm_v4l2_vidc.c @@ -0,0 +1,783 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm_vidc.h" +#include "msm_vidc_common.h" +#include "msm_vidc_debug.h" +#include "msm_vidc_internal.h" +#include "msm_vidc_res_parse.h" +#include "msm_vidc_resources.h" +#include "vidc_hfi_api.h" +#include "msm_v4l2_private.h" +#include "msm_vidc_clocks.h" + +#define BASE_DEVICE_NUMBER 32 + +struct msm_vidc_drv *vidc_driver; + + +static inline struct msm_vidc_inst *get_vidc_inst(struct file *filp, void *fh) +{ + if (!filp->private_data) + return NULL; + return container_of(filp->private_data, + struct msm_vidc_inst, event_handler); +} + +static int msm_v4l2_open(struct file *filp) +{ + struct video_device *vdev = video_devdata(filp); + struct msm_video_device *vid_dev = + container_of(vdev, struct msm_video_device, vdev); + struct msm_vidc_core *core = video_drvdata(filp); + struct msm_vidc_inst *vidc_inst; + + trace_msm_v4l2_vidc_open_start("msm v4l2_open start"); + vidc_inst = msm_vidc_open(core->id, vid_dev->type); + if (!vidc_inst) { + dprintk(VIDC_ERR, + "Failed to create video instance, core: %d, type = %d\n", + core->id, vid_dev->type); + return -ENOMEM; + } + clear_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags); + filp->private_data = &(vidc_inst->event_handler); + trace_msm_v4l2_vidc_open_end("msm v4l2_open end"); + return 0; +} + +static int msm_v4l2_close(struct file *filp) +{ + int rc = 0; + struct msm_vidc_inst *vidc_inst; + + trace_msm_v4l2_vidc_close_start("msm v4l2_close start"); + vidc_inst = get_vidc_inst(filp, NULL); + + rc = msm_vidc_close(vidc_inst); + filp->private_data = NULL; + trace_msm_v4l2_vidc_close_end("msm v4l2_close end"); + return rc; +} + +static int msm_v4l2_querycap(struct file *filp, void *fh, + struct v4l2_capability *cap) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(filp, fh); + + return msm_vidc_querycap((void *)vidc_inst, cap); +} + +int msm_v4l2_enum_fmt(struct file *file, void *fh, + struct v4l2_fmtdesc *f) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_enum_fmt((void *)vidc_inst, f); +} + +int msm_v4l2_s_fmt(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_s_fmt((void *)vidc_inst, f); +} + +int msm_v4l2_g_fmt(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_g_fmt((void *)vidc_inst, f); +} + +int msm_v4l2_s_ctrl(struct file *file, void *fh, + struct v4l2_control *a) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_s_ctrl((void *)vidc_inst, a); +} + +int msm_v4l2_g_ctrl(struct file *file, void *fh, + struct v4l2_control *a) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_g_ctrl((void *)vidc_inst, a); +} + +int msm_v4l2_reqbufs(struct file *file, void *fh, + struct v4l2_requestbuffers *b) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_reqbufs((void *)vidc_inst, b); +} + +int msm_v4l2_qbuf(struct file *file, void *fh, + struct v4l2_buffer *b) +{ + return msm_vidc_qbuf(get_vidc_inst(file, fh), b); +} + +int msm_v4l2_dqbuf(struct file *file, void *fh, + struct v4l2_buffer *b) +{ + return msm_vidc_dqbuf(get_vidc_inst(file, fh), b); +} + +int msm_v4l2_streamon(struct file *file, void *fh, + enum v4l2_buf_type i) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_streamon((void *)vidc_inst, i); +} + +int msm_v4l2_streamoff(struct file *file, void *fh, + enum v4l2_buf_type i) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_streamoff((void *)vidc_inst, i); +} + +static int msm_v4l2_subscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + struct msm_vidc_inst *vidc_inst = container_of(fh, + struct msm_vidc_inst, event_handler); + + return msm_vidc_subscribe_event((void *)vidc_inst, sub); +} + +static int msm_v4l2_unsubscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + struct msm_vidc_inst *vidc_inst = container_of(fh, + struct msm_vidc_inst, event_handler); + + return msm_vidc_unsubscribe_event((void *)vidc_inst, sub); +} + +static int msm_v4l2_decoder_cmd(struct file *file, void *fh, + struct v4l2_decoder_cmd *dec) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_comm_cmd((void *)vidc_inst, (union msm_v4l2_cmd *)dec); +} + +static int msm_v4l2_encoder_cmd(struct file *file, void *fh, + struct v4l2_encoder_cmd *enc) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_comm_cmd((void *)vidc_inst, (union msm_v4l2_cmd *)enc); +} + +static int msm_v4l2_enum_framesizes(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_enum_framesizes((void *)vidc_inst, fsize); +} + +static int msm_v4l2_queryctrl(struct file *file, void *fh, + struct v4l2_queryctrl *ctrl) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_query_ctrl((void *)vidc_inst, ctrl); +} + +static long msm_v4l2_default(struct file *file, void *fh, + bool valid_prio, unsigned int cmd, void *arg) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_private((void *)vidc_inst, cmd, arg); +} + + +const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = { + .vidioc_querycap = msm_v4l2_querycap, + .vidioc_enum_fmt_vid_cap_mplane = msm_v4l2_enum_fmt, + .vidioc_enum_fmt_vid_out_mplane = msm_v4l2_enum_fmt, + .vidioc_s_fmt_vid_cap_mplane = msm_v4l2_s_fmt, + .vidioc_s_fmt_vid_out_mplane = msm_v4l2_s_fmt, + .vidioc_g_fmt_vid_cap_mplane = msm_v4l2_g_fmt, + .vidioc_g_fmt_vid_out_mplane = msm_v4l2_g_fmt, + .vidioc_reqbufs = msm_v4l2_reqbufs, + .vidioc_qbuf = msm_v4l2_qbuf, + .vidioc_dqbuf = msm_v4l2_dqbuf, + .vidioc_streamon = msm_v4l2_streamon, + .vidioc_streamoff = msm_v4l2_streamoff, + .vidioc_s_ctrl = msm_v4l2_s_ctrl, + .vidioc_g_ctrl = msm_v4l2_g_ctrl, + .vidioc_queryctrl = msm_v4l2_queryctrl, + .vidioc_subscribe_event = msm_v4l2_subscribe_event, + .vidioc_unsubscribe_event = msm_v4l2_unsubscribe_event, + .vidioc_decoder_cmd = msm_v4l2_decoder_cmd, + .vidioc_encoder_cmd = msm_v4l2_encoder_cmd, + .vidioc_enum_framesizes = msm_v4l2_enum_framesizes, + .vidioc_default = msm_v4l2_default, +}; + +static const struct v4l2_ioctl_ops msm_v4l2_enc_ioctl_ops = { 0 }; + +static unsigned int msm_v4l2_poll(struct file *filp, + struct poll_table_struct *pt) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(filp, NULL); + + return msm_vidc_poll((void *)vidc_inst, filp, pt); +} + +static const struct v4l2_file_operations msm_v4l2_vidc_fops = { + .owner = THIS_MODULE, + .open = msm_v4l2_open, + .release = msm_v4l2_close, + .unlocked_ioctl = video_ioctl2, + .compat_ioctl32 = msm_v4l2_private, + .poll = msm_v4l2_poll, +}; + +void msm_vidc_release_video_device(struct video_device *pvdev) +{ +} + +static int read_platform_resources(struct msm_vidc_core *core, + struct platform_device *pdev) +{ + int rc = 0; + + if (!core || !pdev) { + dprintk(VIDC_ERR, "%s: Invalid params %pK %pK\n", + __func__, core, pdev); + return -EINVAL; + } + + core->hfi_type = VIDC_HFI_VENUS; + core->resources.pdev = pdev; + if (pdev->dev.of_node) { + /* Target supports DT, parse from it */ + rc = read_platform_resources_from_drv_data(core); + rc = read_platform_resources_from_dt(&core->resources); + } else { + dprintk(VIDC_ERR, "pdev node is NULL\n"); + rc = -EINVAL; + } + return rc; +} + +static int msm_vidc_initialize_core(struct platform_device *pdev, + struct msm_vidc_core *core) +{ + int i = 0; + int rc = 0; + + if (!core) + return -EINVAL; + rc = read_platform_resources(core, pdev); + if (rc) { + dprintk(VIDC_ERR, "Failed to get platform resources\n"); + return rc; + } + + INIT_LIST_HEAD(&core->instances); + mutex_init(&core->lock); + + core->state = VIDC_CORE_UNINIT; + for (i = SYS_MSG_INDEX(SYS_MSG_START); + i <= SYS_MSG_INDEX(SYS_MSG_END); i++) { + init_completion(&core->completions[i]); + } + + INIT_DELAYED_WORK(&core->fw_unload_work, msm_vidc_fw_unload_handler); + INIT_WORK(&core->ssr_work, msm_vidc_ssr_handler); + + msm_vidc_init_core_clk_ops(core); + return rc; +} + +static ssize_t link_name_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct msm_vidc_core *core = dev_get_drvdata(dev); + + if (core) + if (dev == &core->vdev[MSM_VIDC_DECODER].vdev.dev) + return snprintf(buf, PAGE_SIZE, "venus_dec"); + else if (dev == &core->vdev[MSM_VIDC_ENCODER].vdev.dev) + return snprintf(buf, PAGE_SIZE, "venus_enc"); + else if (dev == &core->vdev[MSM_VIDC_CVP].vdev.dev) + return snprintf(buf, PAGE_SIZE, "venus_cvp"); + else + return 0; + else + return 0; +} + +static DEVICE_ATTR_RO(link_name); + +static ssize_t pwr_collapse_delay_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long val = 0; + int rc = 0; + struct msm_vidc_core *core = NULL; + + rc = kstrtoul(buf, 0, &val); + if (rc) + return rc; + else if (!val) + return -EINVAL; + + core = get_vidc_core(MSM_VIDC_CORE_VENUS); + if (!core) + return -EINVAL; + core->resources.msm_vidc_pwr_collapse_delay = val; + return count; +} + +static ssize_t pwr_collapse_delay_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct msm_vidc_core *core = NULL; + + core = get_vidc_core(MSM_VIDC_CORE_VENUS); + if (!core) + return -EINVAL; + + return snprintf(buf, PAGE_SIZE, "%u\n", + core->resources.msm_vidc_pwr_collapse_delay); +} + +static DEVICE_ATTR_RW(pwr_collapse_delay); + +static ssize_t thermal_level_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", vidc_driver->thermal_level); +} + +static ssize_t thermal_level_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int rc = 0, val = 0; + + rc = kstrtoint(buf, 0, &val); + if (rc || val < 0) { + dprintk(VIDC_WARN, + "Invalid thermal level value: %s\n", buf); + return -EINVAL; + } + dprintk(VIDC_DBG, "Thermal level old %d new %d\n", + vidc_driver->thermal_level, val); + + if (val == vidc_driver->thermal_level) + return count; + vidc_driver->thermal_level = val; + + msm_comm_handle_thermal_event(); + return count; +} + +static DEVICE_ATTR_RW(thermal_level); + +static ssize_t sku_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%d", + vidc_driver->sku_version); +} + +static DEVICE_ATTR_RO(sku_version); + +static struct attribute *msm_vidc_core_attrs[] = { + &dev_attr_pwr_collapse_delay.attr, + &dev_attr_thermal_level.attr, + &dev_attr_sku_version.attr, + NULL +}; + +static struct attribute_group msm_vidc_core_attr_group = { + .attrs = msm_vidc_core_attrs, +}; + +static const struct of_device_id msm_vidc_dt_match[] = { + {.compatible = "qcom,msm-vidc"}, + {.compatible = "qcom,msm-vidc,context-bank"}, + {.compatible = "qcom,msm-vidc,bus"}, + {.compatible = "qcom,msm-vidc,mem-cdsp"}, + {} +}; + +static int msm_vidc_register_video_device(enum session_type sess_type, + int nr, struct msm_vidc_core *core, struct device *dev) +{ + int rc = 0; + + core->vdev[sess_type].vdev.release = + msm_vidc_release_video_device; + core->vdev[sess_type].vdev.fops = &msm_v4l2_vidc_fops; + core->vdev[sess_type].vdev.ioctl_ops = &msm_v4l2_ioctl_ops; + core->vdev[sess_type].vdev.vfl_dir = VFL_DIR_M2M; + core->vdev[sess_type].type = sess_type; + core->vdev[sess_type].vdev.v4l2_dev = &core->v4l2_dev; + rc = video_register_device(&core->vdev[sess_type].vdev, + VFL_TYPE_GRABBER, nr); + if (rc) { + dprintk(VIDC_ERR, "Failed to register the video device\n"); + return rc; + } + video_set_drvdata(&core->vdev[sess_type].vdev, core); + dev = &core->vdev[sess_type].vdev.dev; + rc = device_create_file(dev, &dev_attr_link_name); + if (rc) { + dprintk(VIDC_ERR, "Failed to create video device file\n"); + video_unregister_device(&core->vdev[sess_type].vdev); + return rc; + } + return 0; +} +static int msm_vidc_probe_vidc_device(struct platform_device *pdev) +{ + int rc = 0; + struct msm_vidc_core *core; + struct device *dev = NULL; + int nr = BASE_DEVICE_NUMBER; + + if (!vidc_driver) { + dprintk(VIDC_ERR, "Invalid vidc driver\n"); + return -EINVAL; + } + + core = kzalloc(sizeof(*core), GFP_KERNEL); + if (!core) + return -ENOMEM; + + core->platform_data = vidc_get_drv_data(&pdev->dev); + dev_set_drvdata(&pdev->dev, core); + rc = msm_vidc_initialize_core(pdev, core); + if (rc) { + dprintk(VIDC_ERR, "Failed to init core\n"); + goto err_core_init; + } + rc = sysfs_create_group(&pdev->dev.kobj, &msm_vidc_core_attr_group); + if (rc) { + dprintk(VIDC_ERR, + "Failed to create attributes\n"); + goto err_core_init; + } + + core->id = MSM_VIDC_CORE_VENUS; + + rc = v4l2_device_register(&pdev->dev, &core->v4l2_dev); + if (rc) { + dprintk(VIDC_ERR, "Failed to register v4l2 device\n"); + goto err_v4l2_register; + } + + /* setup the decoder device */ + rc = msm_vidc_register_video_device(MSM_VIDC_DECODER, + nr, core, dev); + if (rc) { + dprintk(VIDC_ERR, "Failed to register video decoder\n"); + goto err_dec; + } + + /* setup the encoder device */ + rc = msm_vidc_register_video_device(MSM_VIDC_ENCODER, + nr + 1, core, dev); + if (rc) { + dprintk(VIDC_ERR, "Failed to register video encoder\n"); + goto err_enc; + } + + /* setup the cvp device */ + if (core->resources.domain_cvp) { + rc = msm_vidc_register_video_device(MSM_VIDC_CVP, + nr + 2, core, dev); + if (rc) { + dprintk(VIDC_ERR, "Failed to register video CVP\n"); + goto err_cvp; + } + } + + /* finish setting up the 'core' */ + mutex_lock(&vidc_driver->lock); + if (vidc_driver->num_cores + 1 > MSM_VIDC_CORES_MAX) { + mutex_unlock(&vidc_driver->lock); + dprintk(VIDC_ERR, "Maximum cores already exist, core_no = %d\n", + vidc_driver->num_cores); + goto err_cores_exceeded; + } + vidc_driver->num_cores++; + mutex_unlock(&vidc_driver->lock); + + core->device = vidc_hfi_initialize(core->hfi_type, core->id, + &core->resources, &handle_cmd_response); + if (IS_ERR_OR_NULL(core->device)) { + mutex_lock(&vidc_driver->lock); + vidc_driver->num_cores--; + mutex_unlock(&vidc_driver->lock); + + rc = PTR_ERR(core->device) ? + PTR_ERR(core->device) : -EBADHANDLE; + if (rc != -EPROBE_DEFER) + dprintk(VIDC_ERR, "Failed to create HFI device\n"); + else + dprintk(VIDC_DBG, "msm_vidc: request probe defer\n"); + goto err_cores_exceeded; + } + + mutex_lock(&vidc_driver->lock); + list_add_tail(&core->list, &vidc_driver->cores); + mutex_unlock(&vidc_driver->lock); + + core->debugfs_root = msm_vidc_debugfs_init_core( + core, vidc_driver->debugfs_root); + + vidc_driver->sku_version = core->resources.sku_version; + + dprintk(VIDC_DBG, "populating sub devices\n"); + /* + * Trigger probe for each sub-device i.e. qcom,msm-vidc,context-bank. + * When msm_vidc_probe is called for each sub-device, parse the + * context-bank details and store it in core->resources.context_banks + * list. + */ + rc = of_platform_populate(pdev->dev.of_node, msm_vidc_dt_match, NULL, + &pdev->dev); + if (rc) { + dprintk(VIDC_ERR, "Failed to trigger probe for sub-devices\n"); + goto err_fail_sub_device_probe; + } + + return rc; + +err_fail_sub_device_probe: + vidc_hfi_deinitialize(core->hfi_type, core->device); +err_cores_exceeded: + if (core->resources.domain_cvp) { + device_remove_file(&core->vdev[MSM_VIDC_CVP].vdev.dev, + &dev_attr_link_name); + video_unregister_device(&core->vdev[MSM_VIDC_CVP].vdev); + } +err_cvp: + device_remove_file(&core->vdev[MSM_VIDC_ENCODER].vdev.dev, + &dev_attr_link_name); + video_unregister_device(&core->vdev[MSM_VIDC_ENCODER].vdev); +err_enc: + device_remove_file(&core->vdev[MSM_VIDC_DECODER].vdev.dev, + &dev_attr_link_name); + video_unregister_device(&core->vdev[MSM_VIDC_DECODER].vdev); +err_dec: + v4l2_device_unregister(&core->v4l2_dev); +err_v4l2_register: + sysfs_remove_group(&pdev->dev.kobj, &msm_vidc_core_attr_group); +err_core_init: + dev_set_drvdata(&pdev->dev, NULL); + kfree(core); + return rc; +} + +static int msm_vidc_probe_mem_cdsp(struct platform_device *pdev) +{ + return read_mem_cdsp_resources_from_dt(pdev); +} + +static int msm_vidc_probe_context_bank(struct platform_device *pdev) +{ + return read_context_bank_resources_from_dt(pdev); +} + +static int msm_vidc_probe_bus(struct platform_device *pdev) +{ + return read_bus_resources_from_dt(pdev); +} + +static int msm_vidc_probe(struct platform_device *pdev) +{ + /* + * Sub devices probe will be triggered by of_platform_populate() towards + * the end of the probe function after msm-vidc device probe is + * completed. Return immediately after completing sub-device probe. + */ + if (of_device_is_compatible(pdev->dev.of_node, "qcom,msm-vidc")) { + return msm_vidc_probe_vidc_device(pdev); + } else if (of_device_is_compatible(pdev->dev.of_node, + "qcom,msm-vidc,bus")) { + return msm_vidc_probe_bus(pdev); + } else if (of_device_is_compatible(pdev->dev.of_node, + "qcom,msm-vidc,context-bank")) { + return msm_vidc_probe_context_bank(pdev); + } else if (of_device_is_compatible(pdev->dev.of_node, + "qcom,msm-vidc,mem-cdsp")) { + return msm_vidc_probe_mem_cdsp(pdev); + } + + /* How did we end up here? */ + MSM_VIDC_ERROR(1); + return -EINVAL; +} + +static int msm_vidc_remove(struct platform_device *pdev) +{ + int rc = 0; + struct msm_vidc_core *core; + + if (!pdev) { + dprintk(VIDC_ERR, "%s invalid input %pK", __func__, pdev); + return -EINVAL; + } + + core = dev_get_drvdata(&pdev->dev); + if (!core) { + dprintk(VIDC_ERR, "%s invalid core", __func__); + return -EINVAL; + } + + vidc_hfi_deinitialize(core->hfi_type, core->device); + if (core->resources.domain_cvp) { + device_remove_file(&core->vdev[MSM_VIDC_CVP].vdev.dev, + &dev_attr_link_name); + video_unregister_device(&core->vdev[MSM_VIDC_CVP].vdev); + } + device_remove_file(&core->vdev[MSM_VIDC_ENCODER].vdev.dev, + &dev_attr_link_name); + video_unregister_device(&core->vdev[MSM_VIDC_ENCODER].vdev); + device_remove_file(&core->vdev[MSM_VIDC_DECODER].vdev.dev, + &dev_attr_link_name); + video_unregister_device(&core->vdev[MSM_VIDC_DECODER].vdev); + v4l2_device_unregister(&core->v4l2_dev); + + msm_vidc_free_platform_resources(&core->resources); + sysfs_remove_group(&pdev->dev.kobj, &msm_vidc_core_attr_group); + dev_set_drvdata(&pdev->dev, NULL); + mutex_destroy(&core->lock); + kfree(core); + return rc; +} + +static int msm_vidc_pm_suspend(struct device *dev) +{ + int rc = 0; + struct msm_vidc_core *core; + + /* + * Bail out if + * - driver possibly not probed yet + * - not the main device. We don't support power management on + * subdevices (e.g. context banks) + */ + if (!dev || !dev->driver || + !of_device_is_compatible(dev->of_node, "qcom,msm-vidc")) + return 0; + + core = dev_get_drvdata(dev); + if (!core) { + dprintk(VIDC_ERR, "%s invalid core\n", __func__); + return -EINVAL; + } + + rc = msm_vidc_suspend(core->id); + if (rc == -ENOTSUPP) + rc = 0; + else if (rc) + dprintk(VIDC_WARN, "Failed to suspend: %d\n", rc); + + + return rc; +} + +static int msm_vidc_pm_resume(struct device *dev) +{ + dprintk(VIDC_INFO, "%s\n", __func__); + return 0; +} + +static const struct dev_pm_ops msm_vidc_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(msm_vidc_pm_suspend, msm_vidc_pm_resume) +}; + +MODULE_DEVICE_TABLE(of, msm_vidc_dt_match); + +static struct platform_driver msm_vidc_driver = { + .probe = msm_vidc_probe, + .remove = msm_vidc_remove, + .driver = { + .name = "msm_vidc_v4l2", + .of_match_table = msm_vidc_dt_match, + .pm = &msm_vidc_pm_ops, + }, +}; + +static int __init msm_vidc_init(void) +{ + int rc = 0; + + vidc_driver = kzalloc(sizeof(*vidc_driver), + GFP_KERNEL); + if (!vidc_driver) { + dprintk(VIDC_ERR, + "Failed to allocate memroy for msm_vidc_drv\n"); + return -ENOMEM; + } + + INIT_LIST_HEAD(&vidc_driver->cores); + mutex_init(&vidc_driver->lock); + vidc_driver->debugfs_root = msm_vidc_debugfs_init_drv(); + if (!vidc_driver->debugfs_root) + dprintk(VIDC_ERR, + "Failed to create debugfs for msm_vidc\n"); + + rc = platform_driver_register(&msm_vidc_driver); + if (rc) { + dprintk(VIDC_ERR, + "Failed to register platform driver\n"); + debugfs_remove_recursive(vidc_driver->debugfs_root); + kfree(vidc_driver); + vidc_driver = NULL; + } + + return rc; +} + +static void __exit msm_vidc_exit(void) +{ + platform_driver_unregister(&msm_vidc_driver); + debugfs_remove_recursive(vidc_driver->debugfs_root); + mutex_destroy(&vidc_driver->lock); + kfree(vidc_driver); + vidc_driver = NULL; +} + +module_init(msm_vidc_init); +module_exit(msm_vidc_exit); + +MODULE_LICENSE("GPL v2"); diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c new file mode 100644 index 000000000000..45a4774ba6a7 --- /dev/null +++ b/msm/vidc/msm_vdec.c @@ -0,0 +1,1514 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include "msm_vdec.h" +#include "msm_vidc_internal.h" +#include "msm_vidc_common.h" +#include "vidc_hfi.h" +#include "vidc_hfi_helper.h" +#include "vidc_hfi_api.h" +#include "msm_vidc_debug.h" +#include "msm_vidc_clocks.h" +#include "msm_vidc_buffer_calculations.h" + +#define MIN_NUM_DEC_OUTPUT_BUFFERS 4 +#define MIN_NUM_DEC_CAPTURE_BUFFERS 4 +/* Y=16(0-9bits), Cb(10-19bits)=Cr(20-29bits)=128, black by default */ +#define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8020010 +#define MAX_VP9D_INST_COUNT 6 + +static const char *const vp8_profile_level[] = { + "Unused", + "0.0", + "1.0", + "2.0", + "3.0", + NULL +}; + +static const char *const vp9_level[] = { + "Unused", + "1.0", + "1.1", + "2.0", + "2.1", + "3.0", + "3.1", + "4.0", + "4.1", + "5.0", + "5.1", + "6.0", + "6.1", + NULL +}; + +static const char *const mpeg2_profile[] = { + "Simple", + "Main", + "High", + NULL +}; + +static const char *const mpeg2_level[] = { + "0", + "1", + "2", + "3", + NULL +}; + +static struct msm_vidc_ctrl msm_vdec_ctrls[] = { + { + .id = V4L2_CID_MPEG_VIDEO_UNKNOWN, + .name = "Invalid control", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 0, + .default_value = 0, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER, + .name = "Decode Order", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE, + .name = "Picture Type Decoding", + .type = V4L2_CTRL_TYPE_BITMASK, + .minimum = 0, + .maximum = (V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_I | + V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_P | + V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_B), + .default_value = (V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_I | + V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_P | + V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_B), + .step = 0, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE, + .name = "Sync Frame Decode", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE, + .name = "Secure mode", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA, + .name = "Extradata Type", + .type = V4L2_CTRL_TYPE_BITMASK, + .minimum = EXTRADATA_NONE, + .maximum = EXTRADATA_DEFAULT | EXTRADATA_ADVANCED, + .default_value = EXTRADATA_DEFAULT, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE, + .name = "Video decoder multi stream", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = + V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY, + .maximum = + V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY, + .default_value = + V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE, + .name = "H264 Profile", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, + .maximum = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH, + .default_value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | + (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | + (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | + (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) | + (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH) + ), + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_LEVEL, + .name = "H264 Level", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + .maximum = V4L2_MPEG_VIDEO_H264_LEVEL_6_2, + .default_value = V4L2_MPEG_VIDEO_H264_LEVEL_5_0, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_1B) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_1_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_1_2) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_1_3) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_2_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_2_2) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_2) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_5_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_5_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_5_2) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_6_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_6_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_6_2) + ), + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, + .name = "HEVC Profile", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, + .maximum = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10, + .default_value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) | + (1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE) | + (1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10) + ), + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, + .name = "HEVC Level", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + .maximum = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2, + .default_value = V4L2_MPEG_VIDEO_HEVC_LEVEL_5, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_1) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_2) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_3) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_4) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_5) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_6) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2) + ), + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_TIER, + .name = "HEVC Tier", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN, + .maximum = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH, + .default_value = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_HEVC_TIER_MAIN) | + (1 << V4L2_MPEG_VIDEO_HEVC_TIER_HIGH) + ), + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_VP8_PROFILE, + .name = "VP8 Profile", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_VP8_PROFILE_0, + .maximum = V4L2_MPEG_VIDEO_VP8_PROFILE_0, + .default_value = V4L2_MPEG_VIDEO_VP8_PROFILE_0, + .menu_skip_mask = ~(1 << V4L2_MPEG_VIDEO_VP8_PROFILE_0), + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL, + .name = "VP8 Profile Level", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED, + .maximum = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3, + .default_value = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_2) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3) + ), + .qmenu = vp8_profile_level, + }, + { + .id = V4L2_CID_MPEG_VIDEO_VP9_PROFILE, + .name = "VP9 Profile", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_VP9_PROFILE_0, + .maximum = V4L2_MPEG_VIDEO_VP9_PROFILE_2, + .default_value = V4L2_MPEG_VIDEO_VP9_PROFILE_0, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_VP9_PROFILE_0) | + (1 << V4L2_MPEG_VIDEO_VP9_PROFILE_1) | + (1 << V4L2_MPEG_VIDEO_VP9_PROFILE_2) + ), + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL, + .name = "VP9 Level", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_UNUSED, + .maximum = V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_61, + .default_value = V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_61, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_UNUSED) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_1) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_11) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_2) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_21) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_3) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_31) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_4) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_41) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_5) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_51) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_61) + ), + .qmenu = vp9_level, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE, + .name = "MPEG2 Profile", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_SIMPLE, + .maximum = V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_MAIN, + .default_value = V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_MAIN, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_SIMPLE) | + (1 << V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_MAIN) + ), + .qmenu = mpeg2_profile, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL, + .name = "MPEG2 Level", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_0, + .maximum = V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_2, + .default_value = V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_2, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_0) | + (1 << V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_1) | + (1 << V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_2) + ), + .qmenu = mpeg2_level, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_8BIT, + .name = "Picture concealed color 8bit", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0x0, + .maximum = 0xff3fcff, + .default_value = DEFAULT_VIDEO_CONCEAL_COLOR_BLACK, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_10BIT, + .name = "Picture concealed color 10bit", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0x0, + .maximum = 0x3fffffff, + .default_value = DEFAULT_VIDEO_CONCEAL_COLOR_BLACK, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT, + .name = "Buffer size limit", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = INT_MAX, + .default_value = 0, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, + .name = "CAPTURE Count", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_NUM_OUTPUT_BUFFERS, + .maximum = MAX_NUM_OUTPUT_BUFFERS, + .default_value = MIN_NUM_OUTPUT_BUFFERS, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, + .name = "OUTPUT Count", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_NUM_INPUT_BUFFERS, + .maximum = MAX_NUM_INPUT_BUFFERS, + .default_value = MIN_NUM_INPUT_BUFFERS, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE, + .name = "Frame Rate", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = (MINIMUM_FPS << 16), + .maximum = (MAXIMUM_FPS << 16), + .default_value = (DEFAULT_FPS << 16), + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY, + .name = "Session Priority", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE, + .name = "Set Decoder Operating rate", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = (MINIMUM_FPS << 16), + .maximum = INT_MAX, + .default_value = (DEFAULT_FPS << 16), + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE, + .name = "Low Latency Mode", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, +}; + +#define NUM_CTRLS ARRAY_SIZE(msm_vdec_ctrls) + + +struct msm_vidc_format_desc vdec_output_formats[] = { + { + .name = "YCbCr Semiplanar 4:2:0", + .description = "Y/CbCr 4:2:0", + .fourcc = V4L2_PIX_FMT_NV12, + }, + { + .name = "YCbCr Semiplanar 4:2:0 10bit", + .description = "Y/CbCr 4:2:0 10bit", + .fourcc = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS, + }, + { + .name = "UBWC YCbCr Semiplanar 4:2:0", + .description = "UBWC Y/CbCr 4:2:0", + .fourcc = V4L2_PIX_FMT_NV12_UBWC, + }, + { + .name = "UBWC YCbCr Semiplanar 4:2:0 10bit", + .description = "UBWC Y/CbCr 4:2:0 10bit", + .fourcc = V4L2_PIX_FMT_NV12_TP10_UBWC, + }, +}; + +struct msm_vidc_format_desc vdec_input_formats[] = { + { + .name = "Mpeg2", + .description = "Mpeg2 compressed format", + .fourcc = V4L2_PIX_FMT_MPEG2, + }, + { + .name = "H264", + .description = "H264 compressed format", + .fourcc = V4L2_PIX_FMT_H264, + }, + { + .name = "HEVC", + .description = "HEVC compressed format", + .fourcc = V4L2_PIX_FMT_HEVC, + }, + { + .name = "VP8", + .description = "VP8 compressed format", + .fourcc = V4L2_PIX_FMT_VP8, + }, + { + .name = "VP9", + .description = "VP9 compressed format", + .fourcc = V4L2_PIX_FMT_VP9, + }, +}; + +struct msm_vidc_format_constraint dec_pix_format_constraints[] = { + { + .fourcc = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS, + .num_planes = 2, + .y_max_stride = 8192, + .y_buffer_alignment = 256, + .uv_max_stride = 8192, + .uv_buffer_alignment = 256, + }, + { + .fourcc = V4L2_PIX_FMT_NV12, + .num_planes = 2, + .y_max_stride = 8192, + .y_buffer_alignment = 512, + .uv_max_stride = 8192, + .uv_buffer_alignment = 256, + }, + { + .fourcc = V4L2_PIX_FMT_NV21, + .num_planes = 2, + .y_max_stride = 8192, + .y_buffer_alignment = 512, + .uv_max_stride = 8192, + .uv_buffer_alignment = 256, + }, +}; + +static bool msm_vidc_check_for_vp9d_overload(struct msm_vidc_core *core) +{ + u32 vp9d_instance_count = 0; + struct msm_vidc_inst *inst = NULL; + + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) { + if (inst->session_type == MSM_VIDC_DECODER && + get_v4l2_codec(inst) == V4L2_PIX_FMT_VP9) + vp9d_instance_count++; + } + mutex_unlock(&core->lock); + + if (vp9d_instance_count > MAX_VP9D_INST_COUNT) + return true; + return false; +} + +int msm_vdec_update_stream_output_mode(struct msm_vidc_inst *inst) +{ + struct v4l2_format *f; + u32 format; + u32 stream_output_mode; + u32 fourcc; + + if (!inst) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + format = f->fmt.pix_mp.pixelformat; + stream_output_mode = HAL_VIDEO_DECODER_PRIMARY; + if ((format == V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS) || + (format == V4L2_PIX_FMT_NV12)) { + stream_output_mode = HAL_VIDEO_DECODER_SECONDARY; + } + + msm_comm_set_stream_output_mode(inst, + stream_output_mode); + + fourcc = V4L2_PIX_FMT_NV12_UBWC; + if (inst->bit_depth == MSM_VIDC_BIT_DEPTH_10) + fourcc = V4L2_PIX_FMT_NV12_TP10_UBWC; + + inst->clk_data.dpb_fourcc = fourcc; + + return 0; +} + +int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) +{ + struct msm_vidc_format *fmt = NULL; + struct msm_vidc_format_desc *fmt_desc = NULL; + struct v4l2_pix_format_mplane *mplane = NULL; + int rc = 0; + u32 color_format; + + if (!inst || !f) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + /* + * First update inst format with new width/height/format + * Recalculate sizes/strides etc + * Perform necessary checks to continue with session + * Copy recalculated info into user format + */ + if (f->type == OUTPUT_MPLANE) { + fmt = &inst->fmts[OUTPUT_PORT]; + fmt_desc = msm_comm_get_pixel_fmt_fourcc(vdec_output_formats, + ARRAY_SIZE(vdec_output_formats), + f->fmt.pix_mp.pixelformat); + if (!fmt_desc) { + dprintk(VIDC_ERR, "Invalid fmt set : %x\n", + f->fmt.pix_mp.pixelformat); + return -EINVAL; + } + strlcpy(fmt->name, fmt_desc->name, sizeof(fmt->name)); + strlcpy(fmt->description, fmt_desc->description, + sizeof(fmt->description)); + + inst->clk_data.opb_fourcc = f->fmt.pix_mp.pixelformat; + + fmt->v4l2_fmt.type = f->type; + mplane = &fmt->v4l2_fmt.fmt.pix_mp; + mplane->width = f->fmt.pix_mp.width; + mplane->height = f->fmt.pix_mp.height; + mplane->pixelformat = f->fmt.pix_mp.pixelformat; + mplane->plane_fmt[0].sizeimage = + msm_vidc_calculate_dec_output_frame_size(inst); + + if (mplane->num_planes > 1) + mplane->plane_fmt[1].sizeimage = + msm_vidc_calculate_dec_output_extra_size(inst); + color_format = msm_comm_convert_color_fmt( + f->fmt.pix_mp.pixelformat); + mplane->plane_fmt[0].bytesperline = + VENUS_Y_STRIDE(color_format, f->fmt.pix_mp.width); + mplane->plane_fmt[0].reserved[0] = + VENUS_Y_SCANLINES(color_format, f->fmt.pix_mp.height); + inst->bit_depth = MSM_VIDC_BIT_DEPTH_8; + if ((f->fmt.pix_mp.pixelformat == + V4L2_PIX_FMT_NV12_TP10_UBWC) || + (f->fmt.pix_mp.pixelformat == + V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS)) { + inst->bit_depth = MSM_VIDC_BIT_DEPTH_10; + } + + rc = msm_vidc_check_session_supported(inst); + if (rc) { + dprintk(VIDC_ERR, + "%s: session not supported\n", __func__); + goto err_invalid_fmt; + } + + rc = msm_vdec_update_stream_output_mode(inst); + if (rc) { + dprintk(VIDC_ERR, + "%s: failed to update output stream mode\n", + __func__); + goto err_invalid_fmt; + } + + memcpy(f, &fmt->v4l2_fmt, sizeof(struct v4l2_format)); + } else if (f->type == INPUT_MPLANE) { + fmt = &inst->fmts[INPUT_PORT]; + fmt_desc = msm_comm_get_pixel_fmt_fourcc(vdec_input_formats, + ARRAY_SIZE(vdec_input_formats), + f->fmt.pix_mp.pixelformat); + if (!fmt_desc) { + dprintk(VIDC_ERR, "Invalid fmt set : %x\n", + f->fmt.pix_mp.pixelformat); + return -EINVAL; + } + strlcpy(fmt->name, fmt_desc->name, sizeof(fmt->name)); + strlcpy(fmt->description, fmt_desc->description, + sizeof(fmt->description)); + + if (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_VP9) { + if (msm_vidc_check_for_vp9d_overload(inst->core)) { + dprintk(VIDC_ERR, "VP9 Decode overload\n"); + rc = -ENOTSUPP; + goto err_invalid_fmt; + } + } + + fmt->v4l2_fmt.type = f->type; + mplane = &fmt->v4l2_fmt.fmt.pix_mp; + mplane->width = f->fmt.pix_mp.width; + mplane->height = f->fmt.pix_mp.height; + mplane->pixelformat = f->fmt.pix_mp.pixelformat; + rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE); + if (rc) { + dprintk(VIDC_ERR, "Failed to open instance\n"); + goto err_invalid_fmt; + } + + mplane->plane_fmt[0].sizeimage = + msm_vidc_calculate_dec_input_frame_size(inst); + + rc = msm_vidc_check_session_supported(inst); + if (rc) { + dprintk(VIDC_ERR, + "%s: session not supported\n", __func__); + goto err_invalid_fmt; + } + + memcpy(f, &fmt->v4l2_fmt, sizeof(struct v4l2_format)); + } + +err_invalid_fmt: + return rc; +} + +int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) +{ + struct v4l2_format *fmt; + + if (f->type == OUTPUT_MPLANE) { + fmt = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + fmt->fmt.pix_mp.plane_fmt[0].sizeimage = + msm_vidc_calculate_dec_output_frame_size(inst); + if (fmt->fmt.pix_mp.num_planes > 1) + fmt->fmt.pix_mp.plane_fmt[1].sizeimage = + msm_vidc_calculate_dec_output_extra_size(inst); + memcpy(f, fmt, sizeof(struct v4l2_format)); + } else if (f->type == INPUT_MPLANE) { + fmt = &inst->fmts[INPUT_PORT].v4l2_fmt; + if (inst->in_reconfig) { + fmt->fmt.pix_mp.width = inst->reconfig_width; + fmt->fmt.pix_mp.height = inst->reconfig_height; + } + fmt->fmt.pix_mp.plane_fmt[0].sizeimage = + msm_vidc_calculate_dec_input_frame_size(inst); + memcpy(f, fmt, sizeof(struct v4l2_format)); + } else { + dprintk(VIDC_ERR, "%s - Unsupported buf type: %d\n", + __func__, f->type); + return -EINVAL; + } + + return 0; +} + +int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) +{ + const struct msm_vidc_format_desc *fmt_desc = NULL; + int rc = 0; + + if (!inst || !f) { + dprintk(VIDC_ERR, + "Invalid input, inst = %pK, f = %pK\n", inst, f); + return -EINVAL; + } + if (f->type == OUTPUT_MPLANE) { + fmt_desc = msm_comm_get_pixel_fmt_index(vdec_output_formats, + ARRAY_SIZE(vdec_output_formats), f->index); + } else if (f->type == INPUT_MPLANE) { + fmt_desc = msm_comm_get_pixel_fmt_index(vdec_input_formats, + ARRAY_SIZE(vdec_input_formats), f->index); + f->flags = V4L2_FMT_FLAG_COMPRESSED; + } + + memset(f->reserved, 0, sizeof(f->reserved)); + if (fmt_desc) { + strlcpy(f->description, fmt_desc->description, + sizeof(f->description)); + f->pixelformat = fmt_desc->fourcc; + } else { + dprintk(VIDC_DBG, "No more formats found\n"); + rc = -EINVAL; + } + return rc; +} + +int msm_vdec_inst_init(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_vidc_core *core; + struct msm_vidc_format_desc *fmt_desc = NULL; + struct v4l2_format *f = NULL; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "Invalid input = %pK\n", inst); + return -EINVAL; + } + core = inst->core; + + inst->prop.extradata_ctrls = EXTRADATA_DEFAULT; + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + f->fmt.pix_mp.height = DEFAULT_HEIGHT; + f->fmt.pix_mp.width = DEFAULT_WIDTH; + f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12_UBWC; + f->fmt.pix_mp.num_planes = 2; + f->fmt.pix_mp.plane_fmt[0].sizeimage = + msm_vidc_calculate_dec_output_frame_size(inst); + f->fmt.pix_mp.plane_fmt[1].sizeimage = + msm_vidc_calculate_dec_output_extra_size(inst); + fmt_desc = msm_comm_get_pixel_fmt_fourcc(vdec_output_formats, + ARRAY_SIZE(vdec_output_formats), f->fmt.pix_mp.pixelformat); + if (!fmt_desc) { + dprintk(VIDC_ERR, "Invalid fmt set : %x\n", + f->fmt.pix_mp.pixelformat); + return -EINVAL; + } + strlcpy(inst->fmts[OUTPUT_PORT].name, fmt_desc->name, + sizeof(inst->fmts[OUTPUT_PORT].name)); + strlcpy(inst->fmts[OUTPUT_PORT].description, fmt_desc->description, + sizeof(inst->fmts[OUTPUT_PORT].description)); + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + f->fmt.pix_mp.height = DEFAULT_HEIGHT; + f->fmt.pix_mp.width = DEFAULT_WIDTH; + f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; + f->fmt.pix_mp.num_planes = 1; + f->fmt.pix_mp.plane_fmt[0].sizeimage = + msm_vidc_calculate_dec_input_frame_size(inst); + fmt_desc = msm_comm_get_pixel_fmt_fourcc(vdec_input_formats, + ARRAY_SIZE(vdec_input_formats), f->fmt.pix_mp.pixelformat); + if (!fmt_desc) { + dprintk(VIDC_ERR, "Invalid fmt set : %x\n", + f->fmt.pix_mp.pixelformat); + return -EINVAL; + } + strlcpy(inst->fmts[INPUT_PORT].name, fmt_desc->name, + sizeof(inst->fmts[INPUT_PORT].name)); + strlcpy(inst->fmts[INPUT_PORT].description, fmt_desc->description, + sizeof(inst->fmts[INPUT_PORT].description)); + inst->buffer_mode_set[INPUT_PORT] = HAL_BUFFER_MODE_STATIC; + inst->buffer_mode_set[OUTPUT_PORT] = HAL_BUFFER_MODE_DYNAMIC; + inst->stream_output_mode = HAL_VIDEO_DECODER_PRIMARY; + + + inst->clk_data.frame_rate = (DEFAULT_FPS << 16); + inst->clk_data.operating_rate = (DEFAULT_FPS << 16); + if (core->resources.decode_batching) + inst->batch.size = MAX_DEC_BATCH_SIZE; + + inst->buff_req.buffer[1].buffer_type = HAL_BUFFER_INPUT; + inst->buff_req.buffer[1].buffer_count_min_host = + inst->buff_req.buffer[1].buffer_count_actual = + MIN_NUM_DEC_OUTPUT_BUFFERS; + inst->buff_req.buffer[2].buffer_type = HAL_BUFFER_OUTPUT; + inst->buff_req.buffer[2].buffer_count_min_host = + inst->buff_req.buffer[2].buffer_count_actual = + MIN_NUM_DEC_CAPTURE_BUFFERS; + inst->buff_req.buffer[3].buffer_type = HAL_BUFFER_OUTPUT2; + inst->buff_req.buffer[3].buffer_count_min_host = + inst->buff_req.buffer[3].buffer_count_actual = + MIN_NUM_DEC_CAPTURE_BUFFERS; + inst->buff_req.buffer[4].buffer_type = HAL_BUFFER_EXTRADATA_INPUT; + inst->buff_req.buffer[5].buffer_type = HAL_BUFFER_EXTRADATA_OUTPUT; + inst->buff_req.buffer[6].buffer_type = HAL_BUFFER_EXTRADATA_OUTPUT2; + inst->buff_req.buffer[7].buffer_type = HAL_BUFFER_INTERNAL_SCRATCH; + inst->buff_req.buffer[8].buffer_type = HAL_BUFFER_INTERNAL_SCRATCH_1; + inst->buff_req.buffer[9].buffer_type = HAL_BUFFER_INTERNAL_SCRATCH_2; + inst->buff_req.buffer[10].buffer_type = HAL_BUFFER_INTERNAL_PERSIST; + inst->buff_req.buffer[11].buffer_type = HAL_BUFFER_INTERNAL_PERSIST_1; + inst->buff_req.buffer[12].buffer_type = HAL_BUFFER_INTERNAL_CMD_QUEUE; + inst->buff_req.buffer[13].buffer_type = HAL_BUFFER_INTERNAL_RECON; + msm_vidc_init_buffer_size_calculators(inst); + + return rc; +} + +int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) +{ + int rc = 0; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + dprintk(VIDC_DBG, + "%s: %x : control name = %s, id = 0x%x value = %d\n", + __func__, hash32_ptr(inst->session), ctrl->name, + ctrl->id, ctrl->val); + + switch (ctrl->id) { + case V4L2_CID_MPEG_VIDEO_H264_PROFILE: + case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: + case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: + case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: + case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE: + inst->profile = msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val); + break; + case V4L2_CID_MPEG_VIDEO_H264_LEVEL: + case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: + case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL: + case V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL: + case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL: + inst->level = msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val); + break; + case V4L2_CID_MPEG_VIDEO_HEVC_TIER: + inst->level |= + (msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val) << 28); + break; + case V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER: + case V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE: + case V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_8BIT: + case V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_10BIT: + break; + case V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE: + inst->flags &= ~VIDC_THUMBNAIL; + if (ctrl->val) + inst->flags |= VIDC_THUMBNAIL; + + msm_dcvs_try_enable(inst); + rc = msm_vidc_set_buffer_count_for_thumbnail(inst); + if (rc) { + dprintk(VIDC_ERR, "Failed to set buffer count\n"); + return rc; + } + break; + case V4L2_CID_MPEG_VIDC_VIDEO_SECURE: + inst->flags &= ~VIDC_SECURE; + if (ctrl->val) + inst->flags |= VIDC_SECURE; + if (msm_comm_check_for_inst_overload(inst->core)) { + dprintk(VIDC_ERR, + "%s: Instance count reached Max limit, rejecting session", + __func__); + return -ENOTSUPP; + } + break; + case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE: + inst->clk_data.frame_rate = ctrl->val; + break; + case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA: + if (ctrl->val == EXTRADATA_NONE) + inst->prop.extradata_ctrls = 0; + else + inst->prop.extradata_ctrls |= ctrl->val; + /* + * nothing to do here as inst->bufq[OUTPUT_PORT].num_planes + * and inst->bufq[OUTPUT_PORT].plane_sizes[1] are already + * initialized to proper values + */ + break; + case V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT: + inst->buffer_size_limit = ctrl->val; + break; + case V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY: + inst->flags &= ~VIDC_REALTIME; + if (ctrl->val) + inst->flags |= VIDC_REALTIME; + break; + case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: + inst->clk_data.operating_rate = ctrl->val; + break; + case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE: + inst->clk_data.low_latency_mode = !!ctrl->val; + break; + default: + dprintk(VIDC_ERR, + "Unknown control %#x\n", ctrl->id); + break; + } + + return rc; +} + +int msm_vdec_set_frame_size(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_frame_size frame_size; + struct v4l2_format *f; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + frame_size.buffer_type = HFI_BUFFER_INPUT; + frame_size.width = f->fmt.pix_mp.width; + frame_size.height = f->fmt.pix_mp.height; + dprintk(VIDC_DBG, "%s: input wxh %dx%d\n", __func__, + frame_size.width, frame_size.height); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_FRAME_SIZE, &frame_size, sizeof(frame_size)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_vdec_set_color_format(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct msm_vidc_format_constraint *fmt_constraint; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + rc = msm_comm_set_color_format(inst, + msm_comm_get_hal_output_buffer(inst), + inst->clk_data.opb_fourcc); + if (rc) { + dprintk(VIDC_ERR, + "%s: set color format (%#x) failed\n", + __func__, inst->clk_data.opb_fourcc); + return rc; + } + fmt_constraint = msm_comm_get_pixel_fmt_constraints( + dec_pix_format_constraints, + ARRAY_SIZE(dec_pix_format_constraints), + inst->clk_data.opb_fourcc); + if (fmt_constraint) { + rc = msm_comm_set_color_format_constraints(inst, + msm_comm_get_hal_output_buffer(inst), + fmt_constraint); + if (rc) { + dprintk(VIDC_ERR, + "%s: Set constraints for color format %#x failed\n", + __func__, inst->clk_data.opb_fourcc); + return rc; + } + } + + return rc; +} + +int msm_vdec_set_input_buffer_counts(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct msm_vidc_format *fmt; + enum hal_buffer buffer_type; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + buffer_type = HAL_BUFFER_INPUT; + fmt = &inst->fmts[INPUT_PORT]; + rc = msm_comm_set_buffer_count(inst, + fmt->count_min, + fmt->count_actual, + buffer_type); + if (rc) { + dprintk(VIDC_ERR, "%s: failed to set bufreqs(%#x)\n", + __func__, buffer_type); + return -EINVAL; + } + + return rc; +} + +int msm_vdec_set_output_buffer_counts(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct msm_vidc_format *fmt; + enum hal_buffer buffer_type; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + buffer_type = msm_comm_get_hal_output_buffer(inst); + /* Correct buffer counts is always stored in HAL_BUFFER_OUTPUT */ + fmt = &inst->fmts[OUTPUT_PORT]; + if (buffer_type == HAL_BUFFER_OUTPUT2) { + /* + * For split mode set DPB count as well + * For DPB actual count is same as min output count + */ + rc = msm_comm_set_buffer_count(inst, + fmt->count_min, + fmt->count_min, + HAL_BUFFER_OUTPUT); + if (rc) { + dprintk(VIDC_ERR, + "%s: failed to set buffer count(%#x)\n", + __func__, buffer_type); + return -EINVAL; + } + } + rc = msm_comm_set_buffer_count(inst, + fmt->count_min, + fmt->count_actual, + buffer_type); + if (rc) { + dprintk(VIDC_ERR, "%s: failed to set bufreqs(%#x)\n", + __func__, buffer_type); + return -EINVAL; + } + + return rc; +} + +int msm_vdec_set_profile_level(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_profile_level profile_level; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + profile_level.profile = inst->profile; + profile_level.level = inst->level; + + dprintk(VIDC_DBG, "%s: %#x %#x\n", __func__, + profile_level.profile, profile_level.level); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT, &profile_level, + sizeof(profile_level)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_vdec_set_output_order(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + u32 output_order; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER); + dprintk(VIDC_DBG, "%s: %d\n", __func__, ctrl->val); + if (ctrl->val == V4L2_MPEG_MSM_VIDC_ENABLE) + output_order = HFI_OUTPUT_ORDER_DECODE; + else + output_order = HFI_OUTPUT_ORDER_DISPLAY; + + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VDEC_OUTPUT_ORDER, &output_order, + sizeof(u32)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_vdec_set_picture_type(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_enable_picture enable_picture; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE); + enable_picture.picture_type = ctrl->val; + + dprintk(VIDC_DBG, "%s: %#x\n", __func__, enable_picture.picture_type); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VDEC_PICTURE_TYPE_DECODE, &enable_picture, + sizeof(enable_picture)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_vdec_set_sync_frame_mode(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_enable hfi_property; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE); + hfi_property.enable = (bool)ctrl->val; + + dprintk(VIDC_DBG, "%s: %#x\n", __func__, hfi_property.enable); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VDEC_THUMBNAIL_MODE, &hfi_property, + sizeof(hfi_property)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_vdec_set_secure_mode(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + u32 codec; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_SECURE); + + codec = get_v4l2_codec(inst); + if (ctrl->val) { + if (!(codec == V4L2_PIX_FMT_HEVC || + codec == V4L2_PIX_FMT_H264 || + codec == V4L2_PIX_FMT_VP9 || + codec == V4L2_PIX_FMT_MPEG2)) { + dprintk(VIDC_ERR, + "%s: Secure allowed for HEVC/H264/VP9/MPEG2\n", + __func__); + return -EINVAL; + } + } + + dprintk(VIDC_DBG, "%s: %#x\n", __func__, ctrl->val); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_SECURE_SESSION, &ctrl->val, sizeof(u32)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_vdec_set_output_stream_mode(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_multi_stream multi_stream; + struct hfi_frame_size frame_sz; + struct v4l2_format *f; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + if (is_primary_output_mode(inst)) { + multi_stream.buffer_type = HFI_BUFFER_OUTPUT; + multi_stream.enable = true; + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, &multi_stream, + sizeof(multi_stream)); + if (rc) { + dprintk(VIDC_ERR, + "%s: set prop multistream primary failed : %d\n", + __func__, rc); + return rc; + } + multi_stream.buffer_type = HFI_BUFFER_OUTPUT2; + multi_stream.enable = false; + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, &multi_stream, + sizeof(multi_stream)); + if (rc) { + dprintk(VIDC_ERR, + "%s: set prop multistream primary2 failed : %d\n", + __func__, rc); + return rc; + } + } else { + rc = msm_comm_set_color_format(inst, + HAL_BUFFER_OUTPUT, inst->clk_data.dpb_fourcc); + if (rc) + return rc; + + multi_stream.buffer_type = HFI_BUFFER_OUTPUT2; + multi_stream.enable = true; + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, &multi_stream, + sizeof(multi_stream)); + if (rc) { + dprintk(VIDC_ERR, + "%s: set prop multistream secondary failed : %d\n", + __func__, rc); + return rc; + } + multi_stream.buffer_type = HFI_BUFFER_OUTPUT; + multi_stream.enable = false; + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, &multi_stream, + sizeof(multi_stream)); + if (rc) { + dprintk(VIDC_ERR, + "%s: set prop multistream secondary2 failed : %d\n", + __func__, rc); + return rc; + } + frame_sz.buffer_type = HFI_BUFFER_OUTPUT2; + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + frame_sz.width = f->fmt.pix_mp.width; + frame_sz.height = f->fmt.pix_mp.height; + dprintk(VIDC_DBG, + "frame_size: hal buffer type %d, width %d, height %d\n", + frame_sz.buffer_type, frame_sz.width, frame_sz.height); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_FRAME_SIZE, &frame_sz, + sizeof(frame_sz)); + if (rc) { + dprintk(VIDC_ERR, + "%s: set prop frame_size failed\n", + __func__); + return rc; + } + } + + return rc; +} + +int msm_vdec_set_priority(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_enable hfi_property; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY); + hfi_property.enable = (bool)ctrl->val; + + dprintk(VIDC_DBG, "%s: %#x\n", __func__, hfi_property.enable); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_REALTIME, &hfi_property, + sizeof(hfi_property)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_vdec_set_operating_rate(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_operating_rate operating_rate; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + if (is_decode_session(inst)) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE); + operating_rate.operating_rate = ctrl->val; + + dprintk(VIDC_DBG, "%s: %#x\n", __func__, + operating_rate.operating_rate); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_OPERATING_RATE, &operating_rate, + sizeof(operating_rate)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_vdec_set_conceal_color(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl_8b; + struct v4l2_ctrl *ctrl_10b; + struct hfi_conceal_color conceal_color; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + ctrl_8b = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_8BIT); + ctrl_10b = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_10BIT); + conceal_color.conceal_color_8bit = ctrl_8b->val; + conceal_color.conceal_color_10bit = ctrl_10b->val; + + dprintk(VIDC_DBG, "%s: %#x %#x\n", __func__, + conceal_color.conceal_color_8bit, + conceal_color.conceal_color_10bit); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR, &conceal_color, + sizeof(conceal_color)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + + +int msm_vdec_set_extradata(struct msm_vidc_inst *inst) +{ + uint32_t display_info = HFI_PROPERTY_PARAM_VUI_DISPLAY_INFO_EXTRADATA; + u32 value = 0x0; + u32 codec; + + codec = get_v4l2_codec(inst); + switch (codec) { + case V4L2_PIX_FMT_H264: + case V4L2_PIX_FMT_HEVC: + display_info = HFI_PROPERTY_PARAM_VUI_DISPLAY_INFO_EXTRADATA; + break; + case V4L2_PIX_FMT_VP8: + case V4L2_PIX_FMT_VP9: + display_info = + HFI_PROPERTY_PARAM_VDEC_VPX_COLORSPACE_EXTRADATA; + break; + case V4L2_PIX_FMT_MPEG2: + display_info = HFI_PROPERTY_PARAM_VDEC_MPEG2_SEQDISP_EXTRADATA; + break; + } + + /* Enable Default Extradata */ + msm_comm_set_index_extradata(inst, + MSM_VIDC_EXTRADATA_OUTPUT_CROP, 0x1); + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VDEC_INTERLACE_VIDEO_EXTRADATA, 0x1); + msm_comm_set_extradata(inst, display_info, 0x1); + + if (codec == V4L2_PIX_FMT_VP9 || codec == V4L2_PIX_FMT_HEVC) { + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_HDR10_HIST_EXTRADATA, 0x1); + } + + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VDEC_NUM_CONCEALED_MB, 0x1); + if (codec == V4L2_PIX_FMT_HEVC) { + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VDEC_MASTER_DISP_COL_SEI_EXTRADATA, + 0x1); + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VDEC_CLL_SEI_EXTRADATA, 0x1); + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VDEC_STREAM_USERDATA_EXTRADATA, + 0x1); + } + + /* Enable / Disable Advanced Extradata */ + if (inst->prop.extradata_ctrls & EXTRADATA_ADVANCED) + value = 0x1; + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VDEC_STREAM_USERDATA_EXTRADATA, value); + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VDEC_TIMESTAMP_EXTRADATA, value); + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_S3D_FRAME_PACKING_EXTRADATA, value); + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VDEC_FRAME_RATE_EXTRADATA, value); + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VDEC_PANSCAN_WNDW_EXTRADATA, value); + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VDEC_RECOVERY_POINT_SEI_EXTRADATA, value); + msm_comm_set_index_extradata(inst, + MSM_VIDC_EXTRADATA_ASPECT_RATIO, value); + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VDEC_FRAME_QP_EXTRADATA, value); + + return 0; +} + +int msm_vdec_set_properties(struct msm_vidc_inst *inst) +{ + int rc = 0; + + if (!in_port_reconfig(inst)) { + /* do not allow these settings in port reconfiration */ + rc = msm_vdec_set_frame_size(inst); + if (rc) + goto exit; + rc = msm_vdec_set_input_buffer_counts(inst); + if (rc) + goto exit; + rc = msm_vdec_set_profile_level(inst); + if (rc) + goto exit; + rc = msm_vdec_set_output_order(inst); + if (rc) + goto exit; + rc = msm_vdec_set_picture_type(inst); + if (rc) + goto exit; + rc = msm_vdec_set_sync_frame_mode(inst); + if (rc) + goto exit; + rc = msm_vdec_set_secure_mode(inst); + if (rc) + goto exit; + rc = msm_vdec_set_extradata(inst); + if (rc) + goto exit; + rc = msm_vdec_set_priority(inst); + if (rc) + goto exit; + rc = msm_vdec_set_conceal_color(inst); + if (rc) + goto exit; + } + + rc = msm_vdec_set_color_format(inst); + if (rc) + goto exit; + rc = msm_vdec_set_output_stream_mode(inst); + if (rc) + goto exit; + rc = msm_vdec_set_output_buffer_counts(inst); + if (rc) + goto exit; + rc = msm_vdec_set_operating_rate(inst); + if (rc) + goto exit; + +exit: + if (rc) + dprintk(VIDC_ERR, "%s: failed with %d\n", __func__, rc); + else + dprintk(VIDC_DBG, "%s: set properties successful\n", __func__); + + return rc; +} + +int msm_vdec_ctrl_init(struct msm_vidc_inst *inst, + const struct v4l2_ctrl_ops *ctrl_ops) +{ + return msm_comm_ctrl_init(inst, msm_vdec_ctrls, + ARRAY_SIZE(msm_vdec_ctrls), ctrl_ops); +} diff --git a/msm/vidc/msm_vdec.h b/msm/vidc/msm_vdec.h new file mode 100644 index 000000000000..d2e8b28033ed --- /dev/null +++ b/msm/vidc/msm_vdec.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ +#ifndef _MSM_VDEC_H_ +#define _MSM_VDEC_H_ + +#include "msm_vidc.h" +#include "msm_vidc_internal.h" +#define MSM_VDEC_DVC_NAME "msm_vidc_vdec" + +int msm_vdec_inst_init(struct msm_vidc_inst *inst); +int msm_vdec_ctrl_init(struct msm_vidc_inst *inst, + const struct v4l2_ctrl_ops *ctrl_ops); +int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, + struct v4l2_fmtdesc *f); +int msm_vdec_s_fmt(struct msm_vidc_inst *inst, + struct v4l2_format *f); +int msm_vdec_g_fmt(struct msm_vidc_inst *inst, + struct v4l2_format *f); +int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, + struct v4l2_ctrl *ctrl); +int msm_vdec_g_ctrl(struct msm_vidc_inst *inst, + struct v4l2_ctrl *ctrl); +int msm_vdec_set_properties(struct msm_vidc_inst *inst); +#endif diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c new file mode 100644 index 000000000000..8d1256cdf1ce --- /dev/null +++ b/msm/vidc/msm_venc.c @@ -0,0 +1,4069 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ +#include +#include "msm_venc.h" +#include "msm_vidc_internal.h" +#include "msm_vidc_common.h" +#include "vidc_hfi.h" +#include "vidc_hfi_helper.h" +#include "vidc_hfi_api.h" +#include "msm_vidc_debug.h" +#include "msm_vidc_clocks.h" +#include "msm_vidc_buffer_calculations.h" + +#define MIN_BIT_RATE 32000 +#define MAX_BIT_RATE 1200000000 +#define DEFAULT_BIT_RATE 64000 +#define MIN_BIT_RATE_RATIO 0 +#define MAX_BIT_RATE_RATIO 100 +#define MAX_HIER_CODING_LAYER 6 +#define BIT_RATE_STEP 1 +#define MAX_BASE_LAYER_PRIORITY_ID 63 +#define MAX_SLICE_BYTE_SIZE ((MAX_BIT_RATE)>>3) +#define MIN_SLICE_BYTE_SIZE 512 +#define MAX_SLICE_MB_SIZE (((4096 + 15) >> 4) * ((2304 + 15) >> 4)) +#define QP_ENABLE_I 0x1 +#define QP_ENABLE_P 0x2 +#define QP_ENABLE_B 0x4 +#define MIN_QP 0 +#define MAX_QP 0x7F +#define MAX_QP_PACKED 0x7F7F7F +#define DEFAULT_QP 0xA +#define DEFAULT_QP_PACKED 0xA0A0A +#define MAX_INTRA_REFRESH_MBS ((7680 * 4320) >> 8) +#define MAX_LTR_FRAME_COUNT 10 +#define MAX_NUM_B_FRAMES 1 +#define MIN_CBRPLUS_W 640 +#define MIN_CBRPLUS_H 480 +#define MAX_CBR_W 1280 +#define MAX_CBR_H 720 + +#define L_MODE V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY +#define MIN_NUM_ENC_OUTPUT_BUFFERS 4 +#define MIN_NUM_ENC_CAPTURE_BUFFERS 5 + +static const char *const mpeg_video_rate_control[] = { + "VBR CFR", + "CBR CFR", + "MBR CFR", + "CBR VFR", + "MBR VFR", + "CQ", + NULL +}; + +static const char *const vp8_profile_level[] = { + "Unused", + "0.0", + "1.0", + "2.0", + "3.0", + NULL +}; + +static const char *const mpeg_video_stream_format[] = { + "NAL Format Start Codes", + "NAL Format One NAL Per Buffer", + "NAL Format One Byte Length", + "NAL Format Two Byte Length", + "NAL Format Four Byte Length", + NULL +}; + +static struct msm_vidc_ctrl msm_venc_ctrls[] = { + { + .id = V4L2_CID_MPEG_VIDEO_UNKNOWN, + .name = "Invalid control", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 0, + .default_value = 0, + .step = 1, + .menu_skip_mask = 0, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE, + .name = "Intra Period for P frames", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = INT_MAX, + .default_value = 2*DEFAULT_FPS-1, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP, + .name = "HEVC I Frame Quantization", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_QP, + .maximum = MAX_QP, + .default_value = DEFAULT_QP, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP, + .name = "HEVC P Frame Quantization", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_QP, + .maximum = MAX_QP, + .default_value = DEFAULT_QP, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP, + .name = "HEVC B Frame Quantization", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_QP, + .maximum = MAX_QP, + .default_value = DEFAULT_QP, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, + .name = "HEVC Quantization Range Minimum", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_QP, + .maximum = MAX_QP_PACKED, + .default_value = DEFAULT_QP_PACKED, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP, + .name = "HEVC Quantization Range Maximum", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_QP, + .maximum = MAX_QP_PACKED, + .default_value = DEFAULT_QP_PACKED, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_B_FRAMES, + .name = "Intra Period for B frames", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = MAX_NUM_B_FRAMES, + .default_value = 0, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, + .name = "CAPTURE Count", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_NUM_OUTPUT_BUFFERS, + .maximum = MAX_NUM_OUTPUT_BUFFERS, + .default_value = MIN_NUM_OUTPUT_BUFFERS, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, + .name = "OUTPUT Count", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_NUM_INPUT_BUFFERS, + .maximum = MAX_NUM_INPUT_BUFFERS, + .default_value = MIN_NUM_INPUT_BUFFERS, + .step = 1, + .qmenu = NULL, + }, + + { + .id = V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, + .name = "Request I Frame", + .type = V4L2_CTRL_TYPE_BUTTON, + .minimum = 0, + .maximum = 0, + .default_value = 0, + .step = 0, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE, + .name = "Video Bitrate Control", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, + .maximum = V4L2_MPEG_VIDEO_BITRATE_MODE_CQ, + .default_value = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) | + (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) | + (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_MBR) | + (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR) | + (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR) | + (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) + ), + .qmenu = mpeg_video_rate_control, + }, + { + .id = V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY, + .name = "Compression quality", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_FRAME_QUALITY, + .maximum = MAX_FRAME_QUALITY, + .default_value = DEFAULT_FRAME_QUALITY, + .step = FRAME_QUALITY_STEP, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE, + .name = "Image grid size", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 512, + .default_value = 0, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE, + .name = "Frame Rate", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = (MINIMUM_FPS << 16), + .maximum = (MAXIMUM_FPS << 16), + .default_value = (DEFAULT_FPS << 16), + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_BITRATE, + .name = "Bit Rate", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_BIT_RATE, + .maximum = MAX_BIT_RATE, + .default_value = DEFAULT_BIT_RATE, + .step = BIT_RATE_STEP, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, + .name = "Entropy Mode", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC, + .maximum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC, + .default_value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) | + (1 << V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC) + ), + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE, + .name = "H264 Profile", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, + .maximum = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH, + .default_value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | + (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | + (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | + (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) | + (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH) + ), + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_LEVEL, + .name = "H264 Level", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + .maximum = V4L2_MPEG_VIDEO_H264_LEVEL_6_2, + .default_value = V4L2_MPEG_VIDEO_H264_LEVEL_6_2, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_1B) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_1_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_1_2) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_1_3) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_2_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_2_2) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_2) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_5_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_5_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_5_2) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_6_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_6_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_6_2) + ), + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_VP8_PROFILE, + .name = "VP8 Profile", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_VP8_PROFILE_0, + .maximum = V4L2_MPEG_VIDEO_VP8_PROFILE_0, + .default_value = V4L2_MPEG_VIDEO_VP8_PROFILE_0, + .menu_skip_mask = ~(1 << V4L2_MPEG_VIDEO_VP8_PROFILE_0), + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL, + .name = "VP8 Profile Level", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED, + .maximum = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3, + .default_value = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_2) | + (1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3) + ), + .qmenu = vp8_profile_level, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, + .name = "HEVC Profile", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, + .maximum = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10, + .default_value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) | + (1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE) | + (1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10) + ), + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, + .name = "HEVC Level", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + .maximum = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2, + .default_value = + V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_1) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_2) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_3) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_4) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_5) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_6) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1) | + (1 << V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2) + ), + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_TIER, + .name = "HEVC Tier", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN, + .maximum = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH, + .default_value = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_HEVC_TIER_MAIN) | + (1 << V4L2_MPEG_VIDEO_HEVC_TIER_HIGH) + ), + .qmenu = NULL, + }, + { + .id = V4L2_CID_ROTATE, + .name = "Rotation", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 270, + .default_value = 0, + .step = 90, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE, + .name = "Slice Mode", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE, + .maximum = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES, + .default_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) | + (1 << V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) | + (1 << V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) + ), + }, + { + .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES, + .name = "Slice Byte Size", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_SLICE_BYTE_SIZE, + .maximum = MAX_SLICE_BYTE_SIZE, + .default_value = MIN_SLICE_BYTE_SIZE, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB, + .name = "Slice MB Size", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 1, + .maximum = MAX_SLICE_MB_SIZE, + .default_value = 1, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM, + .name = "Random Intra Refresh MBs", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = MAX_INTRA_REFRESH_MBS, + .default_value = 0, + .step = 1, + .menu_skip_mask = 0, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB, + .name = "Cyclic Intra Refresh MBs", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = MAX_INTRA_REFRESH_MBS, + .default_value = 0, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA, + .name = "H.264 Loop Filter Alpha Offset", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = -6, + .maximum = 6, + .default_value = 0, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, + .name = "H.264 Loop Filter Beta Offset", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = -6, + .maximum = 6, + .default_value = 0, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE, + .name = "H.264 Loop Filter Mode", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED, + .maximum = L_MODE, + .default_value = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED) | + (1 << V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED) | + (1 << L_MODE) + ), + }, + { + .id = V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR, + .name = "Prepend SPS/PPS to IDR", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE, + .name = "Secure mode", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA, + .name = "Extradata Type", + .type = V4L2_CTRL_TYPE_BITMASK, + .minimum = EXTRADATA_NONE, + .maximum = EXTRADATA_ADVANCED | EXTRADATA_ENC_INPUT_ROI | + EXTRADATA_ENC_INPUT_HDR10PLUS | + EXTRADATA_ENC_INPUT_CVP, + .default_value = EXTRADATA_NONE, + .menu_skip_mask = 0, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_VUI_TIMING_INFO, + .name = "H264 VUI Timing Info", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_AU_DELIMITER, + .name = "AU Delimiter", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .step = 1, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME, + .name = "H264 Use LTR", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = (MAX_LTR_FRAME_COUNT - 1), + .default_value = 0, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT, + .name = "Ltr Count", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = MAX_LTR_FRAME_COUNT, + .default_value = 0, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME, + .name = "H264 Mark LTR", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = (MAX_LTR_FRAME_COUNT - 1), + .default_value = 0, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER, + .name = "Set Hier layers", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = MAX_HIER_CODING_LAYER, + .default_value = 0, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER, + .name = "Set Hier max layers", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = V4L2_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER_0, + .maximum = V4L2_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER_6, + .default_value = + V4L2_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER_0, + .step = 1, + .menu_skip_mask = 0, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE, + .name = "Set Hier coding type", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P, + .maximum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P, + .default_value = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P) + ), + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP, + .name = "Set layer0 QP", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 51, + .default_value = 51, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP, + .name = "Set layer1 QP", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 51, + .default_value = 51, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP, + .name = "Set layer2 QP", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 51, + .default_value = 51, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP, + .name = "Set layer3 QP", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 51, + .default_value = 51, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP, + .name = "Set layer4 QP", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 51, + .default_value = 51, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP, + .name = "Set layer5 QP", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 51, + .default_value = 51, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR, + .name = "Set layer0 BR", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_BIT_RATE_RATIO, + .maximum = MAX_BIT_RATE_RATIO, + .default_value = MIN_BIT_RATE_RATIO, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR, + .name = "Set layer1 BR", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_BIT_RATE_RATIO, + .maximum = MAX_BIT_RATE_RATIO, + .default_value = MIN_BIT_RATE_RATIO, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR, + .name = "Set layer2 BR", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_BIT_RATE_RATIO, + .maximum = MAX_BIT_RATE_RATIO, + .default_value = MIN_BIT_RATE_RATIO, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR, + .name = "Set layer3 BR", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_BIT_RATE_RATIO, + .maximum = MAX_BIT_RATE_RATIO, + .default_value = MIN_BIT_RATE_RATIO, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR, + .name = "Set layer4 BR", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_BIT_RATE_RATIO, + .maximum = MAX_BIT_RATE_RATIO, + .default_value = MIN_BIT_RATE_RATIO, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR, + .name = "Set layer5 BR", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_BIT_RATE_RATIO, + .maximum = MAX_BIT_RATE_RATIO, + .default_value = MIN_BIT_RATE_RATIO, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE, + .name = "VP8 Error Resilience mode", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID, + .name = "Set Base Layer Priority ID for Hier-P", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = MAX_BASE_LAYER_PRIORITY_ID, + .default_value = 0, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH, + .name = "SAR Width", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 7680, + .default_value = 0, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT, + .name = "SAR Height", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 7680, + .default_value = 0, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY, + .name = "Session Priority", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE, + .name = "Set Encoder Operating rate", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = (MINIMUM_FPS << 16), + .maximum = INT_MAX, + .default_value = (DEFAULT_FPS << 16), + .step = 1, + .menu_skip_mask = 0, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC, + .name = "Set VPE Color space conversion coefficients", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE, + .name = "Low Latency Mode", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_BLUR_DIMENSIONS, + .name = "Set Blur width/height", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 0xFFFFFFFF, + .default_value = 0, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM, + .name = "Transform 8x8", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_ENABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE, + .name = "Set Color space", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MSM_VIDC_RESERVED_1, + .maximum = MSM_VIDC_BT2020, + .default_value = MSM_VIDC_RESERVED_1, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE, + .name = "Set Color space range", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS, + .name = "Set Color space transfer characterstics", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MSM_VIDC_TRANSFER_BT709_5, + .maximum = MSM_VIDC_TRANSFER_HLG, + .default_value = MSM_VIDC_TRANSFER_601_6_625, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS, + .name = "Set Color space matrix coefficients", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MSM_VIDC_MATRIX_BT_709_5, + .maximum = MSM_VIDC_MATRIX_BT_2020_CONST, + .default_value = MSM_VIDC_MATRIX_601_6_625, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, + .name = "Frame Rate based Rate Control", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = 0, + .maximum = 1, + .default_value = 0, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VENC_RC_TIMESTAMP_DISABLE, + .name = "RC Timestamp disable", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_CUSTOM_MATRIX, + .name = "Enable/Disable CSC Custom Matrix", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_HFLIP, + .name = "Enable/Disable Horizontal Flip", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_VFLIP, + .name = "Enable/Disable Vertical Flip", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VENC_HDR_INFO, + .name = "HDR PQ information", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = INT_MIN, + .maximum = INT_MAX, + .default_value = 0, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD, + .name = "NAL Format", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_MPEG_VIDEO_HEVC_SIZE_0, + .maximum = V4L2_MPEG_VIDEO_HEVC_SIZE_4, + .default_value = V4L2_MPEG_VIDEO_HEVC_SIZE_0, + .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_HEVC_SIZE_0) | + (1 << V4L2_MPEG_VIDEO_HEVC_SIZE_4) + ), + .qmenu = mpeg_video_stream_format, + }, + { + .id = V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE, + .name = "CVP Disable", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER, + .name = "Enable/Disable Native Recorder", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS, + .name = "Enable/Disable bitrate savings", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_ENABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDEO_VBV_DELAY, + .name = "Set Vbv Delay", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 1000, + .default_value = 0, + .step = 500, + }, +}; + +#define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls) + +static struct msm_vidc_format_desc venc_input_formats[] = { + { + .name = "YCbCr Semiplanar 4:2:0", + .description = "Y/CbCr 4:2:0", + .fourcc = V4L2_PIX_FMT_NV12, + }, + { + .name = "UBWC YCbCr Semiplanar 4:2:0", + .description = "UBWC Y/CbCr 4:2:0", + .fourcc = V4L2_PIX_FMT_NV12_UBWC, + }, + { + .name = "YCrCb Semiplanar 4:2:0", + .description = "Y/CrCb 4:2:0", + .fourcc = V4L2_PIX_FMT_NV21, + }, + { + .name = "TP10 UBWC 4:2:0", + .description = "TP10 UBWC 4:2:0", + .fourcc = V4L2_PIX_FMT_NV12_TP10_UBWC, + }, + { + .name = "YCbCr Semiplanar 4:2:0 10bit", + .description = "Y/CbCr 4:2:0 10bit", + .fourcc = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS, + }, + { + .name = "YCbCr Semiplanar 4:2:0 512 aligned", + .description = "Y/CbCr 4:2:0 512 aligned", + .fourcc = V4L2_PIX_FMT_NV12_512, + }, +}; + +static struct msm_vidc_format_desc venc_output_formats[] = { + { + .name = "H264", + .description = "H264 compressed format", + .fourcc = V4L2_PIX_FMT_H264, + }, + { + .name = "VP8", + .description = "VP8 compressed format", + .fourcc = V4L2_PIX_FMT_VP8, + }, + { + .name = "HEVC", + .description = "HEVC compressed format", + .fourcc = V4L2_PIX_FMT_HEVC, + }, + { + .name = "TME", + .description = "TME MBI format", + .fourcc = V4L2_PIX_FMT_TME, + }, +}; + +struct msm_vidc_format_constraint enc_pix_format_constraints[] = { + { + .fourcc = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS, + .num_planes = 2, + .y_max_stride = 8192, + .y_buffer_alignment = 256, + .uv_max_stride = 8192, + .uv_buffer_alignment = 256, + }, + { + .fourcc = V4L2_PIX_FMT_NV12_512, + .num_planes = 2, + .y_max_stride = 8192, + .y_buffer_alignment = 512, + .uv_max_stride = 8192, + .uv_buffer_alignment = 256, + }, + { + .fourcc = V4L2_PIX_FMT_NV12, + .num_planes = 2, + .y_max_stride = 8192, + .y_buffer_alignment = 512, + .uv_max_stride = 8192, + .uv_buffer_alignment = 256, + }, + { + .fourcc = V4L2_PIX_FMT_NV21, + .num_planes = 2, + .y_max_stride = 8192, + .y_buffer_alignment = 512, + .uv_max_stride = 8192, + .uv_buffer_alignment = 256, + }, +}; + + +static int msm_venc_set_csc(struct msm_vidc_inst *inst, + u32 color_primaries, u32 custom_matrix); + +int msm_venc_inst_init(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_vidc_format_desc *fmt_desc = NULL; + struct v4l2_format *f = NULL; + + if (!inst) { + dprintk(VIDC_ERR, "Invalid input = %pK\n", inst); + return -EINVAL; + } + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + f->fmt.pix_mp.height = DEFAULT_HEIGHT; + f->fmt.pix_mp.width = DEFAULT_WIDTH; + f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; + f->fmt.pix_mp.num_planes = 1; + f->fmt.pix_mp.plane_fmt[0].sizeimage = + msm_vidc_calculate_enc_output_frame_size(inst); + fmt_desc = msm_comm_get_pixel_fmt_fourcc(venc_output_formats, + ARRAY_SIZE(venc_output_formats), f->fmt.pix_mp.pixelformat); + if (!fmt_desc) { + dprintk(VIDC_ERR, "Invalid fmt set : %x\n", + f->fmt.pix_mp.pixelformat); + return -EINVAL; + } + strlcpy(inst->fmts[OUTPUT_PORT].name, fmt_desc->name, + sizeof(inst->fmts[OUTPUT_PORT].name)); + strlcpy(inst->fmts[OUTPUT_PORT].description, fmt_desc->description, + sizeof(inst->fmts[OUTPUT_PORT].description)); + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + f->fmt.pix_mp.height = DEFAULT_HEIGHT; + f->fmt.pix_mp.width = DEFAULT_WIDTH; + f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12_UBWC; + f->fmt.pix_mp.num_planes = 2; + f->fmt.pix_mp.plane_fmt[0].sizeimage = + msm_vidc_calculate_enc_input_frame_size(inst); + f->fmt.pix_mp.plane_fmt[1].sizeimage = + msm_vidc_calculate_enc_input_extra_size(inst); + fmt_desc = msm_comm_get_pixel_fmt_fourcc(venc_input_formats, + ARRAY_SIZE(venc_input_formats), f->fmt.pix_mp.pixelformat); + if (!fmt_desc) { + dprintk(VIDC_ERR, "Invalid fmt set : %x\n", + f->fmt.pix_mp.pixelformat); + return -EINVAL; + } + strlcpy(inst->fmts[INPUT_PORT].name, fmt_desc->name, + sizeof(inst->fmts[INPUT_PORT].name)); + strlcpy(inst->fmts[INPUT_PORT].description, fmt_desc->description, + sizeof(inst->fmts[INPUT_PORT].description)); + inst->prop.bframe_changed = false; + inst->prop.extradata_ctrls = EXTRADATA_DEFAULT; + inst->buffer_mode_set[INPUT_PORT] = HAL_BUFFER_MODE_DYNAMIC; + inst->buffer_mode_set[OUTPUT_PORT] = HAL_BUFFER_MODE_STATIC; + inst->clk_data.frame_rate = (DEFAULT_FPS << 16); + + inst->clk_data.operating_rate = (DEFAULT_FPS << 16); + + inst->buff_req.buffer[1].buffer_type = HAL_BUFFER_INPUT; + inst->buff_req.buffer[1].buffer_count_min_host = + inst->buff_req.buffer[1].buffer_count_actual = + MIN_NUM_ENC_OUTPUT_BUFFERS; + inst->buff_req.buffer[2].buffer_type = HAL_BUFFER_OUTPUT; + inst->buff_req.buffer[2].buffer_count_min_host = + inst->buff_req.buffer[2].buffer_count_actual = + MIN_NUM_ENC_CAPTURE_BUFFERS; + inst->buff_req.buffer[3].buffer_type = HAL_BUFFER_OUTPUT2; + inst->buff_req.buffer[3].buffer_count_min_host = + inst->buff_req.buffer[3].buffer_count_actual = + MIN_NUM_ENC_CAPTURE_BUFFERS; + inst->buff_req.buffer[4].buffer_type = HAL_BUFFER_EXTRADATA_INPUT; + inst->buff_req.buffer[5].buffer_type = HAL_BUFFER_EXTRADATA_OUTPUT; + inst->buff_req.buffer[6].buffer_type = HAL_BUFFER_EXTRADATA_OUTPUT2; + inst->buff_req.buffer[7].buffer_type = HAL_BUFFER_INTERNAL_SCRATCH; + inst->buff_req.buffer[8].buffer_type = HAL_BUFFER_INTERNAL_SCRATCH_1; + inst->buff_req.buffer[9].buffer_type = HAL_BUFFER_INTERNAL_SCRATCH_2; + inst->buff_req.buffer[10].buffer_type = HAL_BUFFER_INTERNAL_PERSIST; + inst->buff_req.buffer[11].buffer_type = HAL_BUFFER_INTERNAL_PERSIST_1; + inst->buff_req.buffer[12].buffer_type = HAL_BUFFER_INTERNAL_CMD_QUEUE; + inst->buff_req.buffer[13].buffer_type = HAL_BUFFER_INTERNAL_RECON; + msm_vidc_init_buffer_size_calculators(inst); + + return rc; +} + +int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) +{ + const struct msm_vidc_format_desc *fmt_desc = NULL; + int rc = 0; + + if (!inst || !f) { + dprintk(VIDC_ERR, + "Invalid input, inst = %pK, f = %pK\n", inst, f); + return -EINVAL; + } + if (f->type == OUTPUT_MPLANE) { + fmt_desc = msm_comm_get_pixel_fmt_index(venc_output_formats, + ARRAY_SIZE(venc_output_formats), f->index); + } else if (f->type == INPUT_MPLANE) { + fmt_desc = msm_comm_get_pixel_fmt_index(venc_input_formats, + ARRAY_SIZE(venc_input_formats), f->index); + f->flags = V4L2_FMT_FLAG_COMPRESSED; + } + + memset(f->reserved, 0, sizeof(f->reserved)); + if (fmt_desc) { + strlcpy(f->description, fmt_desc->description, + sizeof(f->description)); + f->pixelformat = fmt_desc->fourcc; + } else { + dprintk(VIDC_DBG, "No more formats found\n"); + rc = -EINVAL; + } + return rc; +} + +static int msm_venc_set_csc(struct msm_vidc_inst *inst, + u32 color_primaries, u32 custom_matrix) +{ + int rc = 0; + int count = 0; + struct hfi_vpe_color_space_conversion vpe_csc; + struct msm_vidc_platform_resources *resources; + u32 *bias_coeff = NULL; + u32 *csc_limit = NULL; + u32 *csc_matrix = NULL; + struct hfi_device *hdev; + + hdev = inst->core->device; + resources = &(inst->core->resources); + bias_coeff = + resources->csc_coeff_data->vpe_csc_custom_bias_coeff; + csc_limit = + resources->csc_coeff_data->vpe_csc_custom_limit_coeff; + csc_matrix = + resources->csc_coeff_data->vpe_csc_custom_matrix_coeff; + + vpe_csc.input_color_primaries = color_primaries; + /* Custom bias, matrix & limit */ + vpe_csc.custom_matrix_enabled = custom_matrix; + + if (vpe_csc.custom_matrix_enabled && bias_coeff != NULL + && csc_limit != NULL && csc_matrix != NULL) { + while (count < HAL_MAX_MATRIX_COEFFS) { + if (count < HAL_MAX_BIAS_COEFFS) + vpe_csc.csc_bias[count] = + bias_coeff[count]; + if (count < HAL_MAX_LIMIT_COEFFS) + vpe_csc.csc_limit[count] = + csc_limit[count]; + vpe_csc.csc_matrix[count] = + csc_matrix[count]; + count = count + 1; + } + } + + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VPE_COLOR_SPACE_CONVERSION, + &vpe_csc, sizeof(vpe_csc)); + if (rc) + dprintk(VIDC_ERR, + "%s: set property failed\n", __func__); + return rc; +} + +int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) +{ + int rc = 0; + struct msm_vidc_format *fmt = NULL; + struct msm_vidc_format_desc *fmt_desc = NULL; + struct v4l2_pix_format_mplane *mplane = NULL; + u32 color_format; + + if (!inst || !f) { + dprintk(VIDC_ERR, + "Invalid input, inst = %pK, format = %pK\n", inst, f); + return -EINVAL; + } + + /* + * First update inst format with new width/height/format + * Recalculate sizes/strides etc + * Perform necessary checks to continue with session + * Copy recalculated info into user format + */ + if (f->type == OUTPUT_MPLANE) { + fmt = &inst->fmts[OUTPUT_PORT]; + fmt_desc = msm_comm_get_pixel_fmt_fourcc(venc_output_formats, + ARRAY_SIZE(venc_output_formats), + f->fmt.pix_mp.pixelformat); + if (!fmt_desc) { + dprintk(VIDC_ERR, "Invalid fmt set : %x\n", + f->fmt.pix_mp.pixelformat); + return -EINVAL; + } + strlcpy(fmt->name, fmt_desc->name, sizeof(fmt->name)); + strlcpy(fmt->description, fmt_desc->description, + sizeof(fmt->description)); + + fmt->v4l2_fmt.type = f->type; + mplane = &fmt->v4l2_fmt.fmt.pix_mp; + mplane->width = f->fmt.pix_mp.width; + mplane->height = f->fmt.pix_mp.height; + mplane->pixelformat = f->fmt.pix_mp.pixelformat; + rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE); + if (rc) { + dprintk(VIDC_ERR, "Failed to open instance\n"); + goto exit; + } + + mplane->plane_fmt[0].sizeimage = + msm_vidc_calculate_enc_output_frame_size(inst); + if (mplane->num_planes > 1) + mplane->plane_fmt[1].sizeimage = + msm_vidc_calculate_enc_output_extra_size(inst); + + rc = msm_vidc_check_session_supported(inst); + if (rc) { + dprintk(VIDC_ERR, + "%s: session not supported\n", __func__); + goto exit; + } + + memcpy(f, &fmt->v4l2_fmt, sizeof(struct v4l2_format)); + } else if (f->type == INPUT_MPLANE) { + fmt = &inst->fmts[INPUT_PORT]; + fmt_desc = msm_comm_get_pixel_fmt_fourcc(venc_input_formats, + ARRAY_SIZE(venc_input_formats), + f->fmt.pix_mp.pixelformat); + if (!fmt_desc) { + dprintk(VIDC_ERR, "Invalid fmt set : %x\n", + f->fmt.pix_mp.pixelformat); + return -EINVAL; + } + strlcpy(fmt->name, fmt_desc->name, sizeof(fmt->name)); + strlcpy(fmt->description, fmt_desc->description, + sizeof(fmt->description)); + + inst->clk_data.opb_fourcc = f->fmt.pix_mp.pixelformat; + + fmt->v4l2_fmt.type = f->type; + mplane = &fmt->v4l2_fmt.fmt.pix_mp; + mplane->width = f->fmt.pix_mp.width; + mplane->height = f->fmt.pix_mp.height; + mplane->pixelformat = f->fmt.pix_mp.pixelformat; + mplane->plane_fmt[0].sizeimage = + msm_vidc_calculate_enc_input_frame_size(inst); + if (mplane->num_planes > 1) + mplane->plane_fmt[1].sizeimage = + msm_vidc_calculate_enc_input_extra_size(inst); + color_format = msm_comm_convert_color_fmt( + f->fmt.pix_mp.pixelformat); + mplane->plane_fmt[0].bytesperline = + VENUS_Y_STRIDE(color_format, f->fmt.pix_mp.width); + mplane->plane_fmt[0].reserved[0] = + VENUS_Y_SCANLINES(color_format, f->fmt.pix_mp.height); + inst->bit_depth = MSM_VIDC_BIT_DEPTH_8; + if ((f->fmt.pix_mp.pixelformat == + V4L2_PIX_FMT_NV12_TP10_UBWC) || + (f->fmt.pix_mp.pixelformat == + V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS)) { + inst->bit_depth = MSM_VIDC_BIT_DEPTH_10; + } + + rc = msm_vidc_check_session_supported(inst); + if (rc) { + dprintk(VIDC_ERR, + "%s: session not supported\n", __func__); + goto exit; + } + + memcpy(f, &fmt->v4l2_fmt, sizeof(struct v4l2_format)); + } else { + dprintk(VIDC_ERR, "%s - Unsupported buf type: %d\n", + __func__, f->type); + rc = -EINVAL; + goto exit; + } +exit: + return rc; +} + +int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) +{ + struct v4l2_format *fmt; + + if (f->type == OUTPUT_MPLANE) { + fmt = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + fmt->fmt.pix_mp.plane_fmt[0].sizeimage = + msm_vidc_calculate_enc_output_frame_size(inst); + if (fmt->fmt.pix_mp.num_planes > 1) + fmt->fmt.pix_mp.plane_fmt[1].sizeimage = + msm_vidc_calculate_enc_output_extra_size(inst); + memcpy(f, fmt, sizeof(struct v4l2_format)); + } else if (f->type == INPUT_MPLANE) { + fmt = &inst->fmts[INPUT_PORT].v4l2_fmt; + fmt->fmt.pix_mp.plane_fmt[0].sizeimage = + msm_vidc_calculate_enc_input_frame_size(inst); + if (fmt->fmt.pix_mp.num_planes > 1) { + fmt->fmt.pix_mp.plane_fmt[1].sizeimage = + msm_vidc_calculate_enc_input_extra_size(inst); + } + memcpy(f, fmt, sizeof(struct v4l2_format)); + } else { + dprintk(VIDC_ERR, "%s - Unsupported buf type: %d\n", + __func__, f->type); + return -EINVAL; + } + + return 0; +} + +int msm_venc_ctrl_init(struct msm_vidc_inst *inst, + const struct v4l2_ctrl_ops *ctrl_ops) +{ + return msm_comm_ctrl_init(inst, msm_venc_ctrls, + ARRAY_SIZE(msm_venc_ctrls), ctrl_ops); +} + +static int msm_venc_resolve_rc_enable(struct msm_vidc_inst *inst, + struct v4l2_ctrl *ctrl) +{ + struct v4l2_ctrl *rc_mode; + u32 codec; + + if (!ctrl->val) { + dprintk(VIDC_DBG, + "RC is not enabled. Setting RC OFF\n"); + inst->rc_type = RATE_CONTROL_OFF; + } else { + rc_mode = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE_MODE); + inst->rc_type = rc_mode->val; + } + + codec = get_v4l2_codec(inst); + if (msm_vidc_lossless_encode + && (codec == V4L2_PIX_FMT_HEVC || + codec == V4L2_PIX_FMT_H264)) { + dprintk(VIDC_DBG, + "Reset RC mode to RC_LOSSLESS for HEVC lossless encoding\n"); + inst->rc_type = RATE_CONTROL_LOSSLESS; + } + return 0; +} + +static int msm_venc_resolve_rate_control(struct msm_vidc_inst *inst, + struct v4l2_ctrl *ctrl) +{ + struct v4l2_ctrl *rc_enable; + + if (inst->rc_type == RATE_CONTROL_LOSSLESS) { + dprintk(VIDC_DBG, + "Skip RC mode when enabling lossless encoding\n"); + return 0; + } + + rc_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE); + if (!rc_enable->val) { + dprintk(VIDC_ERR, + "RC is not enabled.\n"); + return -EINVAL; + } + + if ((ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) && + get_v4l2_codec(inst) != V4L2_PIX_FMT_HEVC) { + dprintk(VIDC_ERR, "CQ supported only for HEVC\n"); + return -EINVAL; + } + inst->rc_type = ctrl->val; + return 0; +} + +int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) +{ + int rc = 0; + struct msm_vidc_mastering_display_colour_sei_payload *mdisp_sei = NULL; + struct msm_vidc_content_light_level_sei_payload *cll_sei = NULL; + u32 i_qp_min, i_qp_max, p_qp_min, p_qp_max, b_qp_min, b_qp_max; + struct v4l2_format *f; + u32 codec; + + if (!inst || !inst->core || !inst->core->device || !ctrl) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + mdisp_sei = &(inst->hdr10_sei_params.disp_color_sei); + cll_sei = &(inst->hdr10_sei_params.cll_sei); + codec = get_v4l2_codec(inst); + + dprintk(VIDC_DBG, + "%s: %x : name %s, id 0x%x value %d\n", + __func__, hash32_ptr(inst->session), ctrl->name, + ctrl->id, ctrl->val); + + switch (ctrl->id) { + case V4L2_CID_MPEG_VIDEO_GOP_SIZE: + if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_set_intra_period(inst); + if (rc) + dprintk(VIDC_ERR, + "%s: set intra period failed.\n", + __func__); + } + break; + case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: + if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_set_request_keyframe(inst); + if (rc) + dprintk(VIDC_ERR, + "%s: set bitrate failed\n", __func__); + } + break; + case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: + { + rc = msm_venc_resolve_rate_control(inst, ctrl); + if (rc) + dprintk(VIDC_ERR, + "%s: set bitrate mode failed\n", __func__); + break; + } + case V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY: + inst->frame_quality = ctrl->val; + break; + case V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE: + inst->grid_enable = ctrl->val; + break; + case V4L2_CID_MPEG_VIDEO_BITRATE: + inst->clk_data.bitrate = ctrl->val; + if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_set_bitrate(inst); + if (rc) + dprintk(VIDC_ERR, + "%s: set bitrate failed\n", __func__); + } + break; + case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE: + inst->clk_data.frame_rate = ctrl->val; + if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_set_frame_rate(inst); + if (rc) + dprintk(VIDC_ERR, + "%s: set frame rate failed\n", + __func__); + } + break; + case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: + case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: + case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: + if (codec != V4L2_PIX_FMT_HEVC && codec != V4L2_PIX_FMT_H264) { + dprintk(VIDC_ERR, + "Slice mode not supported for encoder %#x\n", + codec); + rc = -ENOTSUPP; + } + break; + case V4L2_CID_MPEG_VIDC_VIDEO_SECURE: + inst->flags &= ~VIDC_SECURE; + if (ctrl->val) + inst->flags |= VIDC_SECURE; + break; + case V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME: + if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_set_ltr_useframe(inst); + if (rc) + dprintk(VIDC_ERR, + "%s: ltr useframe failed\n", + __func__); + } + break; + case V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME: + if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_set_ltr_markframe(inst); + if (rc) + dprintk(VIDC_ERR, + "%s: ltr markframe failed\n", + __func__); + } + break; + case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: + inst->clk_data.operating_rate = ctrl->val; + if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_set_operating_rate(inst); + if (rc) + dprintk(VIDC_ERR, + "%s: set operating rate failed\n", + __func__); + } + break; + case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE: + inst->clk_data.low_latency_mode = !!ctrl->val; + break; + case V4L2_CID_MPEG_VIDC_VENC_HDR_INFO: { + u32 info_type = ((u32)ctrl->val >> 28) & 0xF; + u32 val = (ctrl->val & 0xFFFFFFF); + + dprintk(VIDC_DBG, "Ctrl:%d, HDR Info with value %u (%#X)", + info_type, val, ctrl->val); + switch (info_type) { + case MSM_VIDC_RGB_PRIMARY_00: + mdisp_sei->nDisplayPrimariesX[0] = val; + break; + case MSM_VIDC_RGB_PRIMARY_01: + mdisp_sei->nDisplayPrimariesY[0] = val; + break; + case MSM_VIDC_RGB_PRIMARY_10: + mdisp_sei->nDisplayPrimariesX[1] = val; + break; + case MSM_VIDC_RGB_PRIMARY_11: + mdisp_sei->nDisplayPrimariesY[1] = val; + break; + case MSM_VIDC_RGB_PRIMARY_20: + mdisp_sei->nDisplayPrimariesX[2] = val; + break; + case MSM_VIDC_RGB_PRIMARY_21: + mdisp_sei->nDisplayPrimariesY[2] = val; + break; + case MSM_VIDC_WHITEPOINT_X: + mdisp_sei->nWhitePointX = val; + break; + case MSM_VIDC_WHITEPOINT_Y: + mdisp_sei->nWhitePointY = val; + break; + case MSM_VIDC_MAX_DISP_LUM: + mdisp_sei->nMaxDisplayMasteringLuminance = val; + break; + case MSM_VIDC_MIN_DISP_LUM: + mdisp_sei->nMinDisplayMasteringLuminance = val; + break; + case MSM_VIDC_RGB_MAX_CLL: + cll_sei->nMaxContentLight = val; + break; + case MSM_VIDC_RGB_MAX_FLL: + cll_sei->nMaxPicAverageLight = val; + break; + default: + dprintk(VIDC_ERR, + "Unknown Ctrl:%d, not part of HDR Info with value %u", + info_type, val); + } + } + break; + case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA: + if (ctrl->val == EXTRADATA_NONE) + inst->prop.extradata_ctrls = 0; + else + inst->prop.extradata_ctrls |= ctrl->val; + + if ((inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_ROI) || + (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_HDR10PLUS)) { + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + f->fmt.pix_mp.plane_fmt[1].sizeimage = + msm_vidc_calculate_enc_input_extra_size(inst); + } + + if (inst->prop.extradata_ctrls & EXTRADATA_ADVANCED) { + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + f->fmt.pix_mp.num_planes = 2; + f->fmt.pix_mp.plane_fmt[1].sizeimage = + msm_vidc_calculate_enc_output_extra_size(inst); + } + + break; + case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: + rc = msm_venc_resolve_rc_enable(inst, ctrl); + if (rc) + dprintk(VIDC_ERR, + "%s: set rc enable failed.\n", __func__); + break; + case V4L2_CID_MPEG_VIDEO_H264_PROFILE: + case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: + case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: + inst->profile = msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val); + break; + case V4L2_CID_MPEG_VIDEO_H264_LEVEL: + case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: + case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL: + inst->level = msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val); + break; + case V4L2_CID_MPEG_VIDEO_HEVC_TIER: + inst->level |= + (msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val) << 28); + break; + case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP: + case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP: + i_qp_min = inst->capability.cap[CAP_I_FRAME_QP].min; + i_qp_max = inst->capability.cap[CAP_I_FRAME_QP].max; + p_qp_min = inst->capability.cap[CAP_P_FRAME_QP].min; + p_qp_max = inst->capability.cap[CAP_P_FRAME_QP].max; + b_qp_min = inst->capability.cap[CAP_B_FRAME_QP].min; + b_qp_max = inst->capability.cap[CAP_B_FRAME_QP].max; + if ((ctrl->val & 0xff) < i_qp_min || + ((ctrl->val >> 8) & 0xff) < p_qp_min || + ((ctrl->val >> 16) & 0xff) < b_qp_min || + (ctrl->val & 0xff) > i_qp_max || + ((ctrl->val >> 8) & 0xff) > p_qp_max || + ((ctrl->val >> 16) & 0xff) > b_qp_max) { + dprintk(VIDC_ERR, "Invalid QP %#x\n", ctrl->val); + return -EINVAL; + } + if (ctrl->id == V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP) + inst->client_set_ctrls |= CLIENT_SET_MIN_QP; + else + inst->client_set_ctrls |= CLIENT_SET_MAX_QP; + break; + case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP: + i_qp_min = inst->capability.cap[CAP_I_FRAME_QP].min; + i_qp_max = inst->capability.cap[CAP_I_FRAME_QP].max; + if (ctrl->val < i_qp_min || ctrl->val > i_qp_max) { + dprintk(VIDC_ERR, "Invalid I QP %#x\n", ctrl->val); + return -EINVAL; + } + inst->client_set_ctrls |= CLIENT_SET_I_QP; + if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_set_dyn_qp(inst, ctrl); + if (rc) + dprintk(VIDC_ERR, + "%s: setting dyn frame QP failed\n", + __func__); + } + break; + case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP: + p_qp_min = inst->capability.cap[CAP_P_FRAME_QP].min; + p_qp_max = inst->capability.cap[CAP_P_FRAME_QP].max; + if (ctrl->val < p_qp_min || ctrl->val > p_qp_max) { + dprintk(VIDC_ERR, "Invalid P QP %#x\n", ctrl->val); + return -EINVAL; + } + inst->client_set_ctrls |= CLIENT_SET_P_QP; + break; + case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP: + b_qp_min = inst->capability.cap[CAP_B_FRAME_QP].min; + b_qp_max = inst->capability.cap[CAP_B_FRAME_QP].max; + if (ctrl->val < b_qp_min || ctrl->val > b_qp_max) { + dprintk(VIDC_ERR, "Invalid B QP %#x\n", ctrl->val); + return -EINVAL; + } + inst->client_set_ctrls |= CLIENT_SET_B_QP; + break; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER: + if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_set_hp_layer(inst); + if (rc) + dprintk(VIDC_ERR, + "%s: set dyn hp layer failed.\n", + __func__); + } + break; + case V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID: + if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_set_base_layer_priority_id(inst); + if (rc) + dprintk(VIDC_ERR, + "%s: set baselayer id failed.\n", + __func__); + } + break; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR: + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR: + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR: + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR: + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR: + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR: + if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_set_layer_bitrate(inst); + if (rc) + dprintk(VIDC_ERR, + "%s: set layer bitrate failed\n", + __func__); + } + break; + case V4L2_CID_MPEG_VIDEO_B_FRAMES: + if (inst->state == MSM_VIDC_START_DONE) { + dprintk(VIDC_ERR, + "%s: Dynamic setting of Bframe is not supported\n", + __func__); + return -EINVAL; + } + break; + case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER: + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: + case V4L2_CID_ROTATE: + case V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT: + case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: + case V4L2_CID_HFLIP: + case V4L2_CID_VFLIP: + case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: + case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: + case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: + case V4L2_CID_MPEG_VIDC_VIDEO_AU_DELIMITER: + case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR: + case V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE: + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP: + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP: + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP: + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP: + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP: + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP: + case V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE: + case V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE: + case V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS: + case V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS: + case V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC: + case V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_CUSTOM_MATRIX: + case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: + case V4L2_CID_MPEG_VIDC_VIDEO_VUI_TIMING_INFO: + case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: + case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH: + case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT: + case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_DIMENSIONS: + case V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY: + case V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM: + case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: + case V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE: + case V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER: + case V4L2_CID_MPEG_VIDC_VENC_RC_TIMESTAMP_DISABLE: + case V4L2_CID_MPEG_VIDEO_VBV_DELAY: + dprintk(VIDC_DBG, "Control set: ID : %x Val : %d\n", + ctrl->id, ctrl->val); + break; + default: + dprintk(VIDC_ERR, "Unsupported index: %x\n", ctrl->id); + rc = -ENOTSUPP; + break; + } + + return rc; +} + +int msm_venc_set_frame_size(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_frame_size frame_sz; + struct v4l2_format *f; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + frame_sz.buffer_type = HFI_BUFFER_INPUT; + frame_sz.width = f->fmt.pix_mp.width; + frame_sz.height = f->fmt.pix_mp.height; + dprintk(VIDC_DBG, "%s: input %d %d\n", __func__, + frame_sz.width, frame_sz.height); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_FRAME_SIZE, &frame_sz, sizeof(frame_sz)); + if (rc) { + dprintk(VIDC_ERR, "%s: failed to set input frame size %d %d\n", + __func__, frame_sz.width, frame_sz.height); + return rc; + } + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + frame_sz.buffer_type = HFI_BUFFER_OUTPUT; + frame_sz.width = f->fmt.pix_mp.width; + frame_sz.height = f->fmt.pix_mp.height; + dprintk(VIDC_DBG, "%s: output %d %d\n", __func__, + frame_sz.width, frame_sz.height); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_FRAME_SIZE, &frame_sz, sizeof(frame_sz)); + if (rc) { + dprintk(VIDC_ERR, + "%s: failed to set output frame size %d %d\n", + __func__, frame_sz.width, frame_sz.height); + return rc; + } + + return rc; +} + +int msm_venc_set_frame_rate(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_frame_rate frame_rate; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + frame_rate.buffer_type = HFI_BUFFER_OUTPUT; + frame_rate.frame_rate = inst->clk_data.frame_rate; + + dprintk(VIDC_DBG, "%s: %#x\n", __func__, frame_rate.frame_rate); + + rc = call_hfi_op(hdev, session_set_property, + inst->session, HFI_PROPERTY_CONFIG_FRAME_RATE, + &frame_rate, sizeof(frame_rate)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_color_format(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_vidc_format_constraint *fmt_constraints; + struct v4l2_format *f; + + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + rc = msm_comm_set_color_format(inst, HAL_BUFFER_INPUT, + f->fmt.pix_mp.pixelformat); + if (rc) + return rc; + + fmt_constraints = msm_comm_get_pixel_fmt_constraints( + enc_pix_format_constraints, + ARRAY_SIZE(enc_pix_format_constraints), + f->fmt.pix_mp.pixelformat); + if (fmt_constraints) { + rc = msm_comm_set_color_format_constraints(inst, + HAL_BUFFER_INPUT, + fmt_constraints); + if (rc) { + dprintk(VIDC_ERR, "Set constraints for %d failed\n", + f->fmt.pix_mp.pixelformat); + return rc; + } + } + + return rc; +} + +int msm_venc_set_buffer_counts(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_vidc_format *fmt; + enum hal_buffer buffer_type; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + buffer_type = HAL_BUFFER_INPUT; + fmt = &inst->fmts[INPUT_PORT]; + rc = msm_comm_set_buffer_count(inst, + fmt->count_min, + fmt->count_actual, + buffer_type); + if (rc) { + dprintk(VIDC_ERR, "%s: failed to set bufcounts(%#x)\n", + __func__, buffer_type); + return -EINVAL; + } + + buffer_type = HAL_BUFFER_OUTPUT; + fmt = &inst->fmts[OUTPUT_PORT]; + rc = msm_comm_set_buffer_count(inst, + fmt->count_min, + fmt->count_actual, + buffer_type); + if (rc) { + dprintk(VIDC_ERR, "%s: failed to set buf counts(%#x)\n", + __func__, buffer_type); + return -EINVAL; + } + + return rc; +} + +int msm_venc_set_secure_mode(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_enable enable; + u32 codec; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_SECURE); + enable.enable = !!ctrl->val; + + if (enable.enable) { + codec = get_v4l2_codec(inst); + if (!(codec == V4L2_PIX_FMT_H264 || + codec == V4L2_PIX_FMT_HEVC)) { + dprintk(VIDC_ERR, + "%s: Secure mode only allowed for HEVC/H264\n", + __func__); + return -EINVAL; + } + } + + dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_SECURE_SESSION, &enable, sizeof(enable)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_priority(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_enable enable; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY); + enable.enable = !!ctrl->val; + + dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_REALTIME, &enable, sizeof(enable)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_operating_rate(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_operating_rate op_rate; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE); + op_rate.operating_rate = ctrl->val; + + dprintk(VIDC_DBG, "%s: %d\n", __func__, op_rate.operating_rate >> 16); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_OPERATING_RATE, &op_rate, sizeof(op_rate)); + if (rc) { + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + return rc; + } + + return rc; +} + +int msm_venc_set_profile_level(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_profile_level profile_level; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + if (!inst->profile) { + dprintk(VIDC_ERR, + "%s: skip as client did not set profile\n", + __func__); + return -EINVAL; + } + profile_level.profile = inst->profile; + profile_level.level = inst->level; + + dprintk(VIDC_DBG, "%s: %#x %#x\n", __func__, + profile_level.profile, profile_level.level); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT, &profile_level, + sizeof(profile_level)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_idr_period(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_idr_period idr_period; + u32 codec; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + codec = get_v4l2_codec(inst); + if (codec != V4L2_PIX_FMT_H264 && codec != V4L2_PIX_FMT_HEVC) + return 0; + + idr_period.idr_period = 1; + + dprintk(VIDC_DBG, "%s: %d\n", __func__, idr_period.idr_period); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD, &idr_period, + sizeof(idr_period)); + if (rc) { + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + return rc; + } + + return rc; +} + +void msm_venc_decide_bframe(struct msm_vidc_inst *inst) +{ + u32 width; + u32 height; + u32 num_mbs_per_frame, num_mbs_per_sec; + struct v4l2_ctrl *ctrl; + struct v4l2_ctrl *bframe_ctrl; + struct msm_vidc_platform_resources *res; + struct v4l2_format *f; + + res = &inst->core->resources; + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + width = f->fmt.pix_mp.width; + height = f->fmt.pix_mp.height; + bframe_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); + num_mbs_per_frame = NUM_MBS_PER_FRAME(width, height); + if (num_mbs_per_frame > res->max_bframe_mbs_per_frame) + goto disable_bframe; + + num_mbs_per_sec = num_mbs_per_frame * + (inst->clk_data.frame_rate >> 16); + if (num_mbs_per_sec > res->max_bframe_mbs_per_sec) + goto disable_bframe; + + ctrl = get_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); + if (ctrl->val > 1) + goto disable_bframe; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); + if (ctrl->val) + goto disable_bframe; + + if (inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) + goto disable_bframe; + + if (get_v4l2_codec(inst) == V4L2_PIX_FMT_H264) { + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_PROFILE); + if ((ctrl->val != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) && + (ctrl->val != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) + goto disable_bframe; + } else if (get_v4l2_codec(inst) != V4L2_PIX_FMT_HEVC) + goto disable_bframe; + + if (inst->clk_data.low_latency_mode) + goto disable_bframe; + + if (!bframe_ctrl->val) { + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER); + if (ctrl->val) { + /* + * Native recorder is enabled and bframe is not enabled + * Hence, forcefully enable bframe + */ + inst->prop.bframe_changed = true; + bframe_ctrl->val = MAX_NUM_B_FRAMES; + dprintk(VIDC_DBG, "Bframe is forcefully enabled\n"); + } else { + /* + * Native recorder is not enabled + * B-Frame is not enabled by client + */ + goto disable_bframe; + } + } + dprintk(VIDC_DBG, "Bframe can be enabled!\n"); + + return; +disable_bframe: + if (bframe_ctrl->val) { + /* + * Client wanted to enable bframe but, + * conditions to enable are not met + * Hence, forcefully disable bframe + */ + inst->prop.bframe_changed = true; + bframe_ctrl->val = 0; + dprintk(VIDC_DBG, "Bframe is forcefully disabled!\n"); + } else { + dprintk(VIDC_DBG, "Bframe is disabled\n"); + } +} + +int msm_venc_set_adaptive_bframes(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_enable enable; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + enable.enable = true; + + dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_ADAPTIVE_B, &enable, sizeof(enable)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +void msm_venc_adjust_gop_size(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *hier_ctrl; + struct v4l2_ctrl *bframe_ctrl; + struct v4l2_ctrl *gop_size_ctrl; + + gop_size_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_GOP_SIZE); + if (inst->prop.bframe_changed) { + /* + * BFrame size was explicitly change + * Hence, adjust GOP size accordingly + */ + bframe_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); + if (!bframe_ctrl->val) + /* Forcefully disabled */ + gop_size_ctrl->val = gop_size_ctrl->val * + (1 + MAX_NUM_B_FRAMES); + else + /* Forcefully enabled */ + gop_size_ctrl->val = gop_size_ctrl->val / + (1 + MAX_NUM_B_FRAMES); + } + + /* + * Layer encoding needs GOP size to be multiple of subgop size + * And subgop size is 2 ^ number of enhancement layers + */ + hier_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); + if (hier_ctrl->val > 1) { + u32 min_gop_size; + u32 num_subgops; + + min_gop_size = (1 << (hier_ctrl->val - 1)); + num_subgops = (gop_size_ctrl->val + (min_gop_size >> 1)) / + min_gop_size; + if (num_subgops) + gop_size_ctrl->val = num_subgops * min_gop_size; + else + gop_size_ctrl->val = min_gop_size; + } +} + +int msm_venc_set_intra_period(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_intra_period intra_period; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + msm_venc_adjust_gop_size(inst); + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_GOP_SIZE); + intra_period.pframes = ctrl->val; + + /* + * At this point we have already made decision on bframe + * Control value gives updated bframe value. + */ + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); + intra_period.bframes = ctrl->val; + + dprintk(VIDC_DBG, "%s: %d %d\n", __func__, intra_period.pframes, + intra_period.bframes); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD, &intra_period, + sizeof(intra_period)); + if (rc) { + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + return rc; + } + + if (intra_period.bframes) { + /* Enable adaptive bframes as nbframes!= 0 */ + rc = msm_venc_set_adaptive_bframes(inst); + if (rc) { + dprintk(VIDC_ERR, "%s: set property failed\n", + __func__); + return rc; + } + } + return rc; +} + +int msm_venc_set_request_keyframe(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + dprintk(VIDC_DBG, "%s\n", __func__); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME, NULL, 0); + if (rc) { + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + return rc; + } + + return rc; +} + +int msm_venc_set_rate_control(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + u32 hfi_rc, codec; + u32 height, width, mbpf; + struct v4l2_format *f; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + hdev = inst->core->device; + inst->clk_data.is_cbr_plus = false; + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + codec = get_v4l2_codec(inst); + height = f->fmt.pix_mp.height; + width = f->fmt.pix_mp.width; + mbpf = NUM_MBS_PER_FRAME(height, width); + + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR) + inst->rc_type = V4L2_MPEG_VIDEO_BITRATE_MODE_MBR; + else if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR && + inst->clk_data.low_latency_mode) + inst->rc_type = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR; + + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR || + inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR) + inst->clk_data.low_latency_mode = true; + + switch (inst->rc_type) { + case RATE_CONTROL_OFF: + case RATE_CONTROL_LOSSLESS: + hfi_rc = HFI_RATE_CONTROL_OFF; + break; + case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR: + hfi_rc = HFI_RATE_CONTROL_CBR_CFR; + break; + case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR: + hfi_rc = HFI_RATE_CONTROL_VBR_CFR; + break; + case V4L2_MPEG_VIDEO_BITRATE_MODE_MBR: + hfi_rc = HFI_RATE_CONTROL_MBR_CFR; + break; + case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR: + hfi_rc = HFI_RATE_CONTROL_CBR_VFR; + break; + case V4L2_MPEG_VIDEO_BITRATE_MODE_CQ: + hfi_rc = HFI_RATE_CONTROL_CQ; + break; + default: + hfi_rc = HFI_RATE_CONTROL_OFF; + dprintk(VIDC_ERR, + "Invalid Rate control setting: %d Default RCOFF\n", + inst->rc_type); + break; + } + dprintk(VIDC_DBG, "%s: %d\n", __func__, inst->rc_type); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_RATE_CONTROL, &hfi_rc, + sizeof(u32)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + + + +int msm_venc_set_vbv_delay(struct msm_vidc_inst *inst) +{ + + int rc = 0; + bool is_greater_or_equal_vga = false; + bool is_less_or_equal_720p = false; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + u32 codec; + u32 height, width, fps, mbpf, mbps; + u32 buf_size = 0; + u32 max_fps = 15; + struct hfi_vbv_hrd_buf_size hrd_buf_size; + struct v4l2_format *f; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + hdev = inst->core->device; + inst->clk_data.is_cbr_plus = false; + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + codec = get_v4l2_codec(inst); + height = f->fmt.pix_mp.height; + width = f->fmt.pix_mp.width; + mbpf = NUM_MBS_PER_FRAME(height, width); + fps = inst->clk_data.frame_rate; + mbpf = NUM_MBS_PER_FRAME(height, width); + mbps = NUM_MBS_PER_SEC(height, width, fps); + + if (!(inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR ^ + inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR)) + return 0; + + if (codec == V4L2_PIX_FMT_VP8) + return 0; + + if (((width >= MIN_CBRPLUS_W && height >= MIN_CBRPLUS_H) || + (width >= MIN_CBRPLUS_H && height >= MIN_CBRPLUS_W) || + mbpf >= NUM_MBS_PER_FRAME(MIN_CBRPLUS_H, MIN_CBRPLUS_W)) && + mbps > NUM_MBS_PER_SEC(MIN_CBRPLUS_H, MIN_CBRPLUS_W, max_fps)) + is_greater_or_equal_vga = true; + + if ((width <= MAX_CBR_W && height <= MAX_CBR_H) || + (width <= MAX_CBR_H && height <= MAX_CBR_W) || + mbpf <= NUM_MBS_PER_FRAME(MAX_CBR_H, MAX_CBR_W)) + is_less_or_equal_720p = true; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_VBV_DELAY); + + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR && + is_greater_or_equal_vga && is_less_or_equal_720p) + buf_size = ctrl->val; + + if ((is_greater_or_equal_vga) && (buf_size != 500)) { + inst->clk_data.is_cbr_plus = true; + hrd_buf_size.vbv_hrd_buf_size = 1000; + } else { + inst->clk_data.is_cbr_plus = false; + hrd_buf_size.vbv_hrd_buf_size = 500; + } + + dprintk(VIDC_DBG, "Set hrd_buf_size %d", + hrd_buf_size.vbv_hrd_buf_size); + rc = call_hfi_op(hdev, session_set_property, + (void *)inst->session, + HFI_PROPERTY_CONFIG_VENC_VBV_HRD_BUF_SIZE, + (void *)&hrd_buf_size, sizeof(hrd_buf_size)); + if (rc) { + dprintk(VIDC_ERR, "%s: set HRD_BUF_SIZE %u failed\n", + __func__, + hrd_buf_size.vbv_hrd_buf_size); + inst->clk_data.is_cbr_plus = false; + } + return rc; +} + + +int msm_venc_set_input_timestamp_rc(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_enable enable; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_RC_TIMESTAMP_DISABLE); + /* + * HFI values: + * 0 - time delta is calculated based on buffer timestamp + * 1 - ignores buffer timestamp and fw derives time delta based + * on input frame rate. + */ + enable.enable = !!ctrl->val; + + dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_DISABLE_RC_TIMESTAMP, &enable, + sizeof(enable)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_bitrate(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_bitrate bitrate; + struct hfi_enable enable; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + if (inst->layer_bitrate) { + dprintk(VIDC_DBG, "%s: Layer bitrate is enabled\n", __func__); + return 0; + } + + enable.enable = 0; + dprintk(VIDC_DBG, "%s: bitrate type: %d\n", + __func__, enable.enable); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_BITRATE_TYPE, &enable, + sizeof(enable)); + if (rc) { + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + return rc; + } + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE); + bitrate.bit_rate = ctrl->val; + bitrate.layer_id = MSM_VIDC_ALL_LAYER_ID; + dprintk(VIDC_DBG, "%s: %d\n", __func__, bitrate.bit_rate); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE, &bitrate, + sizeof(bitrate)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst) +{ + int rc = 0, i = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *bitrate = NULL; + struct v4l2_ctrl *layer = NULL; + struct v4l2_ctrl *max_layer = NULL; + struct v4l2_ctrl *layer_br_ratios[MAX_HIER_CODING_LAYER] = {NULL}; + struct hfi_bitrate layer_br; + struct hfi_enable enable; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + max_layer = get_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); + layer = get_ctrl(inst, + V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); + + if (!max_layer->val || !layer->val) { + dprintk(VIDC_DBG, + "%s: Hierp layer not set. Ignore layer bitrate\n", + __func__); + goto error; + } + + if (max_layer->val < layer->val) { + dprintk(VIDC_DBG, + "%s: Hierp layer greater than max isn't allowed\n", + __func__); + goto error; + } + + layer_br_ratios[0] = get_ctrl(inst, + V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR); + layer_br_ratios[1] = get_ctrl(inst, + V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR); + layer_br_ratios[2] = get_ctrl(inst, + V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR); + layer_br_ratios[3] = get_ctrl(inst, + V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR); + layer_br_ratios[4] = get_ctrl(inst, + V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR); + layer_br_ratios[5] = get_ctrl(inst, + V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR); + + /* Set layer bitrates only when highest layer br ratio is 100. */ + if (layer_br_ratios[layer->val-1]->val != MAX_BIT_RATE_RATIO || + layer_br_ratios[0]->val == 0) { + dprintk(VIDC_DBG, + "%s: Improper layer bitrate ratio\n", + __func__); + goto error; + } + + for (i = layer->val - 1; i > 0; --i) { + if (layer_br_ratios[i]->val == 0) { + dprintk(VIDC_DBG, + "%s: Layer ratio must be non-zero\n", + __func__); + goto error; + } + layer_br_ratios[i]->val -= layer_br_ratios[i-1]->val; + } + + enable.enable = 1; + dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_BITRATE_TYPE, &enable, + sizeof(enable)); + if (rc) { + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + goto error; + } + + bitrate = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE); + for (i = 0; i < layer->val; ++i) { + layer_br.bit_rate = + bitrate->val * layer_br_ratios[i]->val / 100; + layer_br.layer_id = i; + dprintk(VIDC_DBG, + "%s: Bitrate for Layer[%u]: [%u]\n", + __func__, layer_br.layer_id, layer_br.bit_rate); + + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE, &layer_br, + sizeof(layer_br)); + if (rc) { + dprintk(VIDC_ERR, + "%s: set property failed for layer: %u\n", + __func__, layer_br.layer_id); + goto error; + } + } + + inst->layer_bitrate = true; + return rc; + +error: + inst->layer_bitrate = false; + return rc; +} + +int msm_venc_set_frame_qp(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *i_qp = NULL; + struct v4l2_ctrl *p_qp = NULL; + struct v4l2_ctrl *b_qp = NULL; + struct v4l2_ctrl *rc_enable = NULL; + struct hfi_quantization qp; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + qp.layer_id = MSM_VIDC_ALL_LAYER_ID; + qp.enable = 0; + qp.enable = QP_ENABLE_I | QP_ENABLE_P | QP_ENABLE_B; + + i_qp = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP); + p_qp = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP); + b_qp = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP); + rc_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE); + + /* + * When RC is ON: + * Enable QP types which have been set by client. + * When RC is OFF: + * I_QP value must be set by client. + * If other QP value is invalid, then, assign I_QP value to it. + */ + if (rc_enable->val) { + if (!(inst->client_set_ctrls & CLIENT_SET_I_QP)) + qp.enable &= ~QP_ENABLE_I; + if (!(inst->client_set_ctrls & CLIENT_SET_P_QP)) + qp.enable &= ~QP_ENABLE_P; + if (!(inst->client_set_ctrls & CLIENT_SET_B_QP)) + qp.enable &= ~QP_ENABLE_B; + + if (!qp.enable) + return 0; + } else { + if (!(inst->client_set_ctrls & CLIENT_SET_I_QP)) { + dprintk(VIDC_WARN, + "%s: Client value is not valid\n", __func__); + return -EINVAL; + } + if (!(inst->client_set_ctrls & CLIENT_SET_P_QP)) + p_qp->val = i_qp->val; + if (!(inst->client_set_ctrls & CLIENT_SET_B_QP)) + b_qp->val = i_qp->val; + } + + /* B frame QP is not supported for VP8. */ + if (get_v4l2_codec(inst) == V4L2_PIX_FMT_VP8) + qp.enable &= ~QP_ENABLE_B; + + qp.qp_packed = i_qp->val | p_qp->val << 8 | b_qp->val << 16; + + dprintk(VIDC_DBG, "%s: layers %#x frames %#x qp_packed %#x\n", + __func__, qp.layer_id, qp.enable, qp.qp_packed); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_VENC_FRAME_QP, &qp, sizeof(qp)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_qp_range(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_quantization_range qp_range; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + if (!(inst->client_set_ctrls & CLIENT_SET_MIN_QP) && + !(inst->client_set_ctrls & CLIENT_SET_MAX_QP)) { + dprintk(VIDC_DBG, + "%s: Client didn't set QP range.\n", __func__); + return 0; + } + + qp_range.min_qp.layer_id = MSM_VIDC_ALL_LAYER_ID; + qp_range.max_qp.layer_id = MSM_VIDC_ALL_LAYER_ID; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP); + qp_range.min_qp.qp_packed = ctrl->val; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP); + qp_range.max_qp.qp_packed = ctrl->val; + + dprintk(VIDC_DBG, + "%s: layers %#x qp_min %#x qp_max %#x\n", + __func__, qp_range.min_qp.layer_id, + qp_range.min_qp.qp_packed, qp_range.max_qp.qp_packed); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE, &qp_range, + sizeof(qp_range)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_frame_quality(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_heic_frame_quality frame_quality; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + if (inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY); + frame_quality.frame_quality = ctrl->val; + + dprintk(VIDC_DBG, "%s: %d\n", __func__, frame_quality.frame_quality); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_HEIC_FRAME_QUALITY, &frame_quality, + sizeof(frame_quality)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_grid(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_heic_grid_enable grid_enable; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + if (inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE); + + /* Need a change in HFI if we want to pass size */ + if (!ctrl->val) + grid_enable.grid_enable = false; + else + grid_enable.grid_enable = true; + + dprintk(VIDC_DBG, "%s: %d\n", __func__, grid_enable.grid_enable); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_HEIC_GRID_ENABLE, &grid_enable, + sizeof(grid_enable)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_entropy_mode(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_h264_entropy_control entropy; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + if (get_v4l2_codec(inst) != V4L2_PIX_FMT_H264) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE); + entropy.entropy_mode = msm_comm_v4l2_to_hfi( + V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, + ctrl->val); + entropy.cabac_model = HFI_H264_CABAC_MODEL_2; + + dprintk(VIDC_DBG, "%s: %d\n", __func__, entropy.entropy_mode); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL, &entropy, + sizeof(entropy)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct v4l2_ctrl *ctrl_t; + struct hfi_multi_slice_control multi_slice_control; + struct v4l2_format *f; + int temp = 0; + u32 mb_per_frame, fps, mbps, bitrate, max_slices; + u32 slice_val, slice_mode, max_avg_slicesize; + u32 rc_mode, output_width, output_height; + struct v4l2_ctrl *rc_enable; + u32 codec; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + codec = get_v4l2_codec(inst); + if (codec != V4L2_PIX_FMT_HEVC && codec != V4L2_PIX_FMT_H264) + return 0; + + slice_mode = HFI_MULTI_SLICE_OFF; + slice_val = 0; + + bitrate = inst->clk_data.bitrate; + fps = inst->clk_data.frame_rate; + rc_mode = inst->rc_type; + rc_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE); + if (fps > 60 || + (rc_enable->val && + rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR && + rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)) { + goto set_and_exit; + } + + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + output_width = f->fmt.pix_mp.width; + output_height = f->fmt.pix_mp.height; + if (output_height < 128 || + (codec != V4L2_PIX_FMT_HEVC && output_width < 384) || + (codec != V4L2_PIX_FMT_H264 && output_width < 192)) { + goto set_and_exit; + } + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); + if (ctrl->val == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) { + temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB; + slice_mode = HFI_MULTI_SLICE_BY_MB_COUNT; + } else if (ctrl->val == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) { + temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES; + slice_mode = HFI_MULTI_SLICE_BY_BYTE_COUNT; + } else { + goto set_and_exit; + } + + ctrl_t = get_ctrl(inst, temp); + slice_val = ctrl_t->val; + + /* Update Slice Config */ + mb_per_frame = NUM_MBS_PER_FRAME(output_height, output_width); + mbps = NUM_MBS_PER_SEC(output_height, output_width, fps); + + if (slice_mode == HFI_MULTI_SLICE_BY_MB_COUNT) { + if (output_width <= 4096 || output_height <= 4096 || + mb_per_frame <= NUM_MBS_PER_FRAME(4096, 2160) || + mbps <= NUM_MBS_PER_SEC(4096, 2160, 60)) { + max_slices = inst->capability.cap[CAP_SLICE_MB].max ? + inst->capability.cap[CAP_SLICE_MB].max : 1; + slice_val = max(slice_val, mb_per_frame / max_slices); + } + } else { + if (output_width <= 1920 || output_height <= 1920 || + mb_per_frame <= NUM_MBS_PER_FRAME(1088, 1920) || + mbps <= NUM_MBS_PER_SEC(1088, 1920, 60)) { + max_slices = inst->capability.cap[CAP_SLICE_BYTE].max ? + inst->capability.cap[CAP_SLICE_BYTE].max : 1; + max_avg_slicesize = ((bitrate / fps) / 8) / max_slices; + slice_val = max(slice_val, max_avg_slicesize); + } + } + + if (slice_mode == HFI_MULTI_SLICE_OFF) { + ctrl->val = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; + ctrl_t->val = 0; + } + +set_and_exit: + multi_slice_control.multi_slice = slice_mode; + multi_slice_control.slice_size = slice_val; + + hdev = inst->core->device; + dprintk(VIDC_DBG, "%s: %d %d\n", __func__, + multi_slice_control.multi_slice, + multi_slice_control.slice_size); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_CONTROL, + &multi_slice_control, sizeof(multi_slice_control)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl = NULL; + struct v4l2_ctrl *rc_mode = NULL; + struct hfi_intra_refresh intra_refresh; + struct v4l2_format *f; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + rc_mode = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE_MODE); + if (!(rc_mode->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR || + rc_mode->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)) + return 0; + + /* Firmware supports only random mode */ + intra_refresh.mode = HFI_INTRA_REFRESH_RANDOM; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM); + intra_refresh.mbs = 0; + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + if (ctrl->val) { + u32 num_mbs_per_frame = 0; + u32 width = f->fmt.pix_mp.width; + u32 height = f->fmt.pix_mp.height; + + num_mbs_per_frame = NUM_MBS_PER_FRAME(height, width); + intra_refresh.mbs = num_mbs_per_frame / ctrl->val; + if (num_mbs_per_frame % ctrl->val) { + intra_refresh.mbs++; + } + } else { + ctrl = get_ctrl(inst, + V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB); + intra_refresh.mbs = ctrl->val; + } + if (!intra_refresh.mbs) { + intra_refresh.mode = HFI_INTRA_REFRESH_NONE; + intra_refresh.mbs = 0; + } + + dprintk(VIDC_DBG, "%s: %d %d\n", __func__, + intra_refresh.mode, intra_refresh.mbs); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH, &intra_refresh, + sizeof(intra_refresh)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_bitrate_savings_mode(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl = NULL; + struct hfi_enable enable; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS); + enable.enable = !!ctrl->val; + if (!ctrl->val && inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { + dprintk(VIDC_DBG, + "Can't disable bitrate savings for non-VBR_CFR\n"); + enable.enable = 1; + } + + dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_BITRATE_SAVINGS, &enable, + sizeof(enable)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_loop_filter_mode(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct v4l2_ctrl *ctrl_a; + struct v4l2_ctrl *ctrl_b; + struct hfi_h264_db_control h264_db_control; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + if (get_v4l2_codec(inst) != V4L2_PIX_FMT_H264) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE); + ctrl_a = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA); + ctrl_b = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA); + h264_db_control.mode = msm_comm_v4l2_to_hfi( + V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE, + ctrl->val); + h264_db_control.slice_alpha_offset = ctrl_a->val; + h264_db_control.slice_beta_offset = ctrl_b->val; + + dprintk(VIDC_DBG, "%s: %d %d %d\n", __func__, + h264_db_control.mode, h264_db_control.slice_alpha_offset, + h264_db_control.slice_beta_offset); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL, &h264_db_control, + sizeof(h264_db_control)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_sequence_header_mode(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_enable enable; + u32 codec; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + codec = get_v4l2_codec(inst); + if (!(codec == V4L2_PIX_FMT_H264 || codec == V4L2_PIX_FMT_HEVC)) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR); + if (ctrl->val) + enable.enable = true; + else + enable.enable = false; + + dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER, &enable, + sizeof(enable)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_au_delimiter_mode(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_enable enable; + u32 codec; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + codec = get_v4l2_codec(inst); + if (!(codec == V4L2_PIX_FMT_H264 || codec == V4L2_PIX_FMT_HEVC)) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_AU_DELIMITER); + enable.enable = !!ctrl->val; + + dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_GENERATE_AUDNAL, &enable, + sizeof(enable)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_enable_hybrid_hp(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *ctrl = NULL; + struct v4l2_ctrl *layer = NULL; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (get_v4l2_codec(inst) != V4L2_PIX_FMT_H264) + return 0; + + if (inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); + if (ctrl->val) + return 0; + + ctrl = get_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); + layer = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); + if (ctrl->val != layer->val) + return 0; + + /* + * Hybrid HP is enabled only for H264 when + * LTR and B-frame are both disabled, + * Layer encoding has higher priority over B-frame + * Hence, no need to check for B-frame + * Rate control type is VBR and + * Max layer equals layer count. + */ + + inst->hybrid_hp = true; + + return 0; +} + +int msm_venc_set_base_layer_priority_id(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl = NULL; + struct v4l2_ctrl *max_layer = NULL; + u32 baselayerid; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + max_layer = get_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); + if (max_layer->val <= 0) { + dprintk(VIDC_DBG, "%s: Layer id can only be set with Hierp\n", + __func__); + return 0; + } + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID); + baselayerid = ctrl->val; + + dprintk(VIDC_DBG, "%s: %d\n", __func__, baselayerid); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_VENC_BASELAYER_PRIORITYID, &baselayerid, + sizeof(baselayerid)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_hp_max_layer(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + u32 hp_layer = 0; + u32 codec; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + codec = get_v4l2_codec(inst); + if (codec != V4L2_PIX_FMT_H264 && codec != V4L2_PIX_FMT_HEVC) + return 0; + + ctrl = get_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); + + rc = msm_venc_enable_hybrid_hp(inst); + if (rc) { + dprintk(VIDC_ERR, "%s: get hybrid hp decision failed\n", + __func__); + return rc; + } + + /* + * We send enhancement layer count to FW, + * hence, input 0/1 indicates absence of layer encoding. + */ + if (ctrl->val) + hp_layer = ctrl->val - 1; + + if (inst->hybrid_hp) { + dprintk(VIDC_DBG, "%s: Hybrid hierp layer: %d\n", + __func__, hp_layer); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_HIER_P_HYBRID_MODE, + &hp_layer, sizeof(hp_layer)); + } else { + dprintk(VIDC_DBG, "%s: Hierp max layer: %d\n", + __func__, hp_layer); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER, + &hp_layer, sizeof(hp_layer)); + } + if (rc) + dprintk(VIDC_ERR, + "%s: set property failed\n", __func__); + return rc; +} + +int msm_venc_set_hp_layer(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl = NULL; + struct v4l2_ctrl *max_layer = NULL; + u32 hp_layer = 0; + u32 codec; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + codec = get_v4l2_codec(inst); + if (codec != V4L2_PIX_FMT_H264 && codec != V4L2_PIX_FMT_HEVC) + return 0; + + if (inst->hybrid_hp) { + dprintk(VIDC_WARN, + "%s: Setting layer isn't allowed with hybrid hp\n", + __func__); + return 0; + } + + max_layer = get_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); + ctrl = get_ctrl(inst, + V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); + + if (max_layer->val < ctrl->val) { + dprintk(VIDC_WARN, + "%s: HP layer count greater than max isn't allowed\n", + __func__); + return 0; + } + + /* + * We send enhancement layer count to FW, + * hence, input 0/1 indicates absence of layer encoding. + */ + if (ctrl->val) + hp_layer = ctrl->val - 1; + + dprintk(VIDC_DBG, "%s: Hierp enhancement layer: %d\n", + __func__, hp_layer); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER, + &hp_layer, sizeof(hp_layer)); + if (rc) + dprintk(VIDC_ERR, + "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_vpx_error_resilience(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_enable enable; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + if (get_v4l2_codec(inst) != V4L2_PIX_FMT_VP8) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE); + enable.enable = !!ctrl->val; + + dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_VPX_ERROR_RESILIENCE_MODE, &enable, + sizeof(enable)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_video_signal_info(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl_cs; + struct v4l2_ctrl *ctrl_fr; + struct v4l2_ctrl *ctrl_tr; + struct v4l2_ctrl *ctrl_mc; + struct hfi_video_signal_metadata signal_info; + u32 codec; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + codec = get_v4l2_codec(inst); + if (!(codec == V4L2_PIX_FMT_H264 || codec == V4L2_PIX_FMT_HEVC)) + return 0; + + ctrl_cs = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE); + ctrl_fr = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE); + ctrl_tr = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS); + ctrl_mc = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS); + if (ctrl_cs->val == MSM_VIDC_RESERVED_1) + return 0; + + signal_info.enable = true; + signal_info.video_format = MSM_VIDC_NTSC; + signal_info.video_full_range = ctrl_fr->val; + signal_info.color_description = 1; + signal_info.color_primaries = ctrl_cs->val; + signal_info.transfer_characteristics = ctrl_tr->val; + signal_info.matrix_coeffs = ctrl_mc->val; + + dprintk(VIDC_DBG, "%s: %d %d %d %d\n", __func__, + signal_info.color_primaries, signal_info.video_full_range, + signal_info.transfer_characteristics, + signal_info.matrix_coeffs); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_VIDEO_SIGNAL_INFO, &signal_info, + sizeof(signal_info)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_rotation(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct v4l2_ctrl *rotation = NULL; + struct v4l2_ctrl *hflip = NULL; + struct v4l2_ctrl *vflip = NULL; + struct hfi_device *hdev; + struct hfi_vpe_rotation_type vpe_rotation; + + hdev = inst->core->device; + + rotation = get_ctrl(inst, V4L2_CID_ROTATE); + + vpe_rotation.rotation = HFI_ROTATE_NONE; + if (rotation->val == 90) + vpe_rotation.rotation = HFI_ROTATE_90; + else if (rotation->val == 180) + vpe_rotation.rotation = HFI_ROTATE_180; + else if (rotation->val == 270) + vpe_rotation.rotation = HFI_ROTATE_270; + + hflip = get_ctrl(inst, V4L2_CID_HFLIP); + vflip = get_ctrl(inst, V4L2_CID_VFLIP); + + vpe_rotation.flip = HFI_FLIP_NONE; + if ((hflip->val == V4L2_MPEG_MSM_VIDC_ENABLE) && + (vflip->val == V4L2_MPEG_MSM_VIDC_ENABLE)) + vpe_rotation.flip = HFI_FLIP_HORIZONTAL | HFI_FLIP_VERTICAL; + else if (hflip->val == V4L2_MPEG_MSM_VIDC_ENABLE) + vpe_rotation.flip = HFI_FLIP_HORIZONTAL; + else if (vflip->val == V4L2_MPEG_MSM_VIDC_ENABLE) + vpe_rotation.flip = HFI_FLIP_VERTICAL; + + dprintk(VIDC_DBG, "Set rotation = %d, flip = %d\n", + vpe_rotation.rotation, vpe_rotation.flip); + rc = call_hfi_op(hdev, session_set_property, + (void *)inst->session, + HFI_PROPERTY_PARAM_VPE_ROTATION, + &vpe_rotation, sizeof(vpe_rotation)); + if (rc) { + dprintk(VIDC_ERR, "Set rotation/flip failed\n"); + return rc; + } + + return rc; +} + +int msm_venc_set_video_csc(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct v4l2_ctrl *ctrl_cs; + struct v4l2_ctrl *ctrl_cm; + u32 color_primaries, custom_matrix; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + if (get_v4l2_codec(inst) != V4L2_PIX_FMT_H264) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC); + if (ctrl->val == V4L2_MPEG_MSM_VIDC_DISABLE) + return 0; + + ctrl_cs = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE); + ctrl_cm = get_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_CUSTOM_MATRIX); + + color_primaries = ctrl_cs->val; + custom_matrix = ctrl_cm->val; + rc = msm_venc_set_csc(inst, color_primaries, custom_matrix); + if (rc) + dprintk(VIDC_ERR, "%s: msm_venc_set_csc failed\n", __func__); + + return rc; +} + +int msm_venc_set_8x8_transform(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl = NULL; + struct hfi_enable enable; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + if (get_v4l2_codec(inst) != V4L2_PIX_FMT_H264) { + dprintk(VIDC_DBG, "%s: skip as codec is not H264\n", + __func__); + return 0; + } + + if (inst->profile != HFI_H264_PROFILE_HIGH && + inst->profile != HFI_H264_PROFILE_CONSTRAINED_HIGH) { + dprintk(VIDC_DBG, "%s: skip due to %#x\n", + __func__, inst->profile); + return 0; + } + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM); + enable.enable = !!ctrl->val; + + dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_H264_8X8_TRANSFORM, &enable, + sizeof(enable)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_vui_timing_info(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_vui_timing_info timing_info; + bool cfr; + u32 codec; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + codec = get_v4l2_codec(inst); + if (codec != V4L2_PIX_FMT_H264 && codec != V4L2_PIX_FMT_HEVC) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_VUI_TIMING_INFO); + if (ctrl->val == V4L2_MPEG_MSM_VIDC_DISABLE) + return 0; + + switch (inst->rc_type) { + case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR: + case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR: + case V4L2_MPEG_VIDEO_BITRATE_MODE_MBR: + cfr = true; + break; + default: + cfr = false; + break; + } + + timing_info.enable = 1; + timing_info.fixed_frame_rate = cfr; + timing_info.time_scale = NSEC_PER_SEC; + + dprintk(VIDC_DBG, "%s: %d %d\n", __func__, timing_info.enable, + timing_info.fixed_frame_rate); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_VUI_TIMING_INFO, &timing_info, + sizeof(timing_info)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_nal_stream_format(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_nal_stream_format_select stream_format; + u32 codec; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + codec = get_v4l2_codec(inst); + if (codec != V4L2_PIX_FMT_H264 && codec != V4L2_PIX_FMT_HEVC) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD); + stream_format.nal_stream_format_select = BIT(ctrl->val); + switch (ctrl->val) { + case V4L2_MPEG_VIDEO_HEVC_SIZE_0: + stream_format.nal_stream_format_select = + HFI_NAL_FORMAT_STARTCODES; + break; + case V4L2_MPEG_VIDEO_HEVC_SIZE_4: + stream_format.nal_stream_format_select = + HFI_NAL_FORMAT_FOUR_BYTE_LENGTH; + break; + default: + dprintk(VIDC_ERR, + "%s: Invalid stream format setting. Setting default\n", + __func__); + stream_format.nal_stream_format_select = + HFI_NAL_FORMAT_STARTCODES; + break; + } + + dprintk(VIDC_DBG, "%s: %#x\n", __func__, + stream_format.nal_stream_format_select); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT, &stream_format, + sizeof(stream_format)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_ltr_mode ltr; + u32 codec; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + codec = get_v4l2_codec(inst); + if (!(codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264)) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); + if (!ctrl->val) + return 0; + if (ctrl->val > inst->capability.cap[CAP_LTR_COUNT].max) { + dprintk(VIDC_ERR, "%s: invalid ltr count %d, max %d\n", + __func__, ctrl->val, + inst->capability.cap[CAP_LTR_COUNT].max); + return -EINVAL; + } + ltr.ltr_count = ctrl->val; + ltr.ltr_mode = HFI_LTR_MODE_MANUAL; + ltr.trust_mode = 1; + dprintk(VIDC_DBG, "%s: %d %d\n", __func__, + ltr.ltr_mode, ltr.ltr_count); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_LTRMODE, <r, sizeof(ltr)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_ltr_useframe(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_ltr_use use_ltr; + u32 codec; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + codec = get_v4l2_codec(inst); + if (!(codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264)) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME); + use_ltr.ref_ltr = ctrl->val; + use_ltr.use_constrnt = false; + use_ltr.frames = 0; + dprintk(VIDC_DBG, "%s: %d\n", __func__, use_ltr.ref_ltr); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_VENC_USELTRFRAME, &use_ltr, + sizeof(use_ltr)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_ltr_markframe(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_ltr_mark mark_ltr; + u32 codec; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + codec = get_v4l2_codec(inst); + if (!(codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264)) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME); + mark_ltr.mark_frame = ctrl->val; + + dprintk(VIDC_DBG, "%s: %d\n", __func__, mark_ltr.mark_frame); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME, &mark_ltr, + sizeof(mark_ltr)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_dyn_qp(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_quantization qp; + struct v4l2_ctrl *rc_enable; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + rc_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE); + if (rc_enable->val) { + dprintk(VIDC_ERR, "%s: Dyn qp is set only when RC is OFF\n", + __func__); + return -EINVAL; + } + + qp.qp_packed = ctrl->val | ctrl->val << 8 | ctrl->val << 16; + qp.enable = QP_ENABLE_I | QP_ENABLE_P | QP_ENABLE_B; + qp.layer_id = MSM_VIDC_ALL_LAYER_ID; + + /* B frame QP is not supported for VP8. */ + if (get_v4l2_codec(inst) == V4L2_PIX_FMT_VP8) + qp.enable &= ~QP_ENABLE_B; + + dprintk(VIDC_DBG, "%s: %#x\n", __func__, + ctrl->val); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_VENC_FRAME_QP, &qp, sizeof(qp)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_aspect_ratio(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_aspect_ratio sar; + u32 codec; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + codec = get_v4l2_codec(inst); + if (!(codec == V4L2_PIX_FMT_H264 || codec == V4L2_PIX_FMT_HEVC)) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH); + if (!ctrl->val) + return 0; + sar.aspect_width = ctrl->val; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT); + if (!ctrl->val) + return 0; + sar.aspect_height = ctrl->val; + + dprintk(VIDC_DBG, "%s: %d %d\n", __func__, + sar.aspect_width, sar.aspect_height); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_ASPECT_RATIO, &sar, sizeof(sar)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_frame_size frame_sz; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_BLUR_DIMENSIONS); + + frame_sz.buffer_type = HFI_BUFFER_INPUT; + frame_sz.height = ctrl->val & 0xFFFF; + frame_sz.width = (ctrl->val & 0xFFFF0000) >> 16; + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_VENC_BLUR_FRAME_SIZE, &frame_sz, + sizeof(frame_sz)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_hdr_info(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct v4l2_ctrl *profile = NULL; + struct hfi_device *hdev; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + if (get_v4l2_codec(inst) != V4L2_PIX_FMT_HEVC) + return 0; + + profile = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_PROFILE); + if (profile->val != V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10) + return 0; + + /* No conversion to HFI needed as both structures are same */ + dprintk(VIDC_DBG, "%s: setting hdr info\n", __func__); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_HDR10_PQ_SEI, &inst->hdr10_sei_params, + sizeof(inst->hdr10_sei_params)); + if (rc) + dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + + return rc; +} + +int msm_venc_set_extradata(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct v4l2_ctrl *cvp_ctrl; + u32 value = 0x0; + u32 codec; + + codec = get_v4l2_codec(inst); + if (inst->prop.extradata_ctrls == EXTRADATA_NONE) { + // Disable all Extradata + msm_comm_set_index_extradata(inst, + MSM_VIDC_EXTRADATA_ASPECT_RATIO, 0x0); + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VENC_LTR_INFO, 0x0); + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VENC_ROI_QP_EXTRADATA, 0x0); + if (codec == V4L2_PIX_FMT_HEVC) { + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VENC_HDR10PLUS_METADATA_EXTRADATA, + 0x0); + } + } + + if (inst->prop.extradata_ctrls & EXTRADATA_ADVANCED) + // Enable Advanced Extradata - LTR Info + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VENC_LTR_INFO, 0x1); + + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_ROI) + // Enable ROIQP Extradata + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VENC_ROI_QP_EXTRADATA, 0x1); + + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_HDR10PLUS) { + // Enable HDR10+ Extradata + if (codec == V4L2_PIX_FMT_HEVC) { + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VENC_HDR10PLUS_METADATA_EXTRADATA, + 0x1); + } + } + + cvp_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE); + if (cvp_ctrl->val == V4L2_MPEG_MSM_VIDC_ENABLE) { + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) { + dprintk(VIDC_ERR, + "%s: invalid params\n", __func__); + return -EINVAL; + } + } else { + /* + * For now, enable CVP metadata only if client provides it. + * Once the kernel-mode CVP metadata implementation + * is completed, this condition should be removed. + */ + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) + value = 0x1; + + } + rc = msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VENC_CVP_METADATA_EXTRADATA, value); + + return rc; +} + +int msm_venc_set_lossless(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_enable enable; + + hdev = inst->core->device; + + if (inst->rc_type != RATE_CONTROL_LOSSLESS) + return 0; + + dprintk(VIDC_DBG, "%s: enable lossless encoding\n", __func__); + enable.enable = 1; + rc = call_hfi_op(hdev, session_set_property, + inst->session, + HFI_PROPERTY_PARAM_VENC_LOSSLESS_ENCODING, + &enable, sizeof(enable)); + + if (rc) + dprintk(VIDC_ERR, "Failed to set lossless mode\n"); + + return rc; +} + +int msm_venc_set_properties(struct msm_vidc_inst *inst) +{ + int rc = 0; + + rc = msm_venc_set_frame_size(inst); + if (rc) + goto exit; + rc = msm_venc_set_frame_rate(inst); + if (rc) + goto exit; + rc = msm_venc_set_secure_mode(inst); + if (rc) + goto exit; + rc = msm_venc_set_priority(inst); + if (rc) + goto exit; + rc = msm_venc_set_color_format(inst); + if (rc) + goto exit; + rc = msm_venc_set_sequence_header_mode(inst); + if (rc) + goto exit; + rc = msm_venc_set_profile_level(inst); + if (rc) + goto exit; + rc = msm_venc_set_8x8_transform(inst); + if (rc) + goto exit; + rc = msm_venc_set_bitrate(inst); + if (rc) + goto exit; + rc = msm_venc_set_entropy_mode(inst); + if (rc) + goto exit; + rc = msm_venc_set_rate_control(inst); + if (rc) + goto exit; + rc = msm_venc_set_bitrate_savings_mode(inst); + if (rc) + goto exit; + rc = msm_venc_set_input_timestamp_rc(inst); + if (rc) + goto exit; + rc = msm_venc_set_frame_qp(inst); + if (rc) + goto exit; + rc = msm_venc_set_qp_range(inst); + if (rc) + goto exit; + rc = msm_venc_set_frame_quality(inst); + if (rc) + goto exit; + rc = msm_venc_set_grid(inst); + if (rc) + goto exit; + rc = msm_venc_set_au_delimiter_mode(inst); + if (rc) + goto exit; + rc = msm_venc_set_vui_timing_info(inst); + if (rc) + goto exit; + rc = msm_venc_set_hdr_info(inst); + if (rc) + goto exit; + rc = msm_venc_set_vpx_error_resilience(inst); + if (rc) + goto exit; + rc = msm_venc_set_nal_stream_format(inst); + if (rc) + goto exit; + rc = msm_venc_set_slice_control_mode(inst); + if (rc) + goto exit; + rc = msm_venc_set_loop_filter_mode(inst); + if (rc) + goto exit; + rc = msm_venc_set_intra_refresh_mode(inst); + if (rc) + goto exit; + rc = msm_venc_set_ltr_mode(inst); + if (rc) + goto exit; + rc = msm_venc_set_hp_max_layer(inst); + if (rc) + goto exit; + rc = msm_venc_set_hp_layer(inst); + if (rc) + goto exit; + rc = msm_venc_set_base_layer_priority_id(inst); + if (rc) + goto exit; + msm_venc_decide_bframe(inst); + rc = msm_venc_set_idr_period(inst); + if (rc) + goto exit; + rc = msm_venc_set_intra_period(inst); + if (rc) + goto exit; + rc = msm_venc_set_aspect_ratio(inst); + if (rc) + goto exit; + rc = msm_venc_set_video_signal_info(inst); + if (rc) + goto exit; + /* + * Layer bitrate is preferred over cumulative bitrate. + * Cumulative bitrate is set only when we fall back. + */ + rc = msm_venc_set_layer_bitrate(inst); + if (rc) + goto exit; + rc = msm_venc_set_bitrate(inst); + if (rc) + goto exit; + rc = msm_venc_set_video_csc(inst); + if (rc) + goto exit; + rc = msm_venc_set_blur_resolution(inst); + if (rc) + goto exit; + rc = msm_venc_set_extradata(inst); + if (rc) + goto exit; + rc = msm_venc_set_operating_rate(inst); + if (rc) + goto exit; + rc = msm_venc_set_buffer_counts(inst); + if (rc) + goto exit; + rc = msm_venc_set_rotation(inst); + if (rc) + goto exit; + rc = msm_venc_set_lossless(inst); + if (rc) + goto exit; + +exit: + if (rc) + dprintk(VIDC_ERR, "%s: failed with %d\n", __func__, rc); + else + dprintk(VIDC_DBG, "%s: set properties successful\n", __func__); + + return rc; +} diff --git a/msm/vidc/msm_venc.h b/msm/vidc/msm_venc.h new file mode 100644 index 000000000000..4894e4013d43 --- /dev/null +++ b/msm/vidc/msm_venc.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ +#ifndef _MSM_VENC_H_ +#define _MSM_VENC_H_ + +#include "msm_vidc.h" +#include "msm_vidc_internal.h" +#define MSM_VENC_DVC_NAME "msm_vidc_venc" + +int msm_venc_inst_init(struct msm_vidc_inst *inst); +int msm_venc_ctrl_init(struct msm_vidc_inst *inst, + const struct v4l2_ctrl_ops *ctrl_ops); +int msm_venc_enum_fmt(struct msm_vidc_inst *inst, + struct v4l2_fmtdesc *f); +int msm_venc_s_fmt(struct msm_vidc_inst *inst, + struct v4l2_format *f); +int msm_venc_g_fmt(struct msm_vidc_inst *inst, + struct v4l2_format *f); +int msm_venc_s_ctrl(struct msm_vidc_inst *inst, + struct v4l2_ctrl *ctrl); +int msm_venc_set_properties(struct msm_vidc_inst *inst); +int msm_venc_set_extradata(struct msm_vidc_inst *inst); +int msm_venc_set_frame_rate(struct msm_vidc_inst *inst); +int msm_venc_set_bitrate(struct msm_vidc_inst *inst); +int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst); +int msm_venc_set_operating_rate(struct msm_vidc_inst *inst); +int msm_venc_set_idr_period(struct msm_vidc_inst *inst); +int msm_venc_set_intra_period(struct msm_vidc_inst *inst); +int msm_venc_set_ltr_useframe(struct msm_vidc_inst *inst); +int msm_venc_set_ltr_markframe(struct msm_vidc_inst *inst); +int msm_venc_set_dyn_qp(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl); +int msm_venc_set_request_keyframe(struct msm_vidc_inst *inst); +int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst); +int msm_venc_set_hp_max_layer(struct msm_vidc_inst *inst); +int msm_venc_set_hp_layer(struct msm_vidc_inst *inst); +int msm_venc_set_base_layer_priority_id(struct msm_vidc_inst *inst); +int msm_venc_set_lossless(struct msm_vidc_inst *inst); +#endif diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c new file mode 100644 index 000000000000..15954723facb --- /dev/null +++ b/msm/vidc/msm_vidc.c @@ -0,0 +1,1818 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include "msm_vidc.h" +#include "msm_vidc_internal.h" +#include "msm_vidc_debug.h" +#include "msm_vdec.h" +#include "msm_venc.h" +#include "msm_cvp_internal.h" +#include "msm_cvp_external.h" +#include "msm_vidc_common.h" +#include +#include "vidc_hfi.h" +#include "vidc_hfi_helper.h" +#include "vidc_hfi_api.h" +#include "msm_vidc_clocks.h" +#include + +#define MAX_EVENTS 30 + +static int try_get_ctrl_for_instance(struct msm_vidc_inst *inst, + struct v4l2_ctrl *ctrl); + +static int get_poll_flags(void *instance) +{ + struct msm_vidc_inst *inst = instance; + struct vb2_queue *outq = &inst->bufq[INPUT_PORT].vb2_bufq; + struct vb2_queue *capq = &inst->bufq[OUTPUT_PORT].vb2_bufq; + struct vb2_buffer *out_vb = NULL; + struct vb2_buffer *cap_vb = NULL; + unsigned long flags = 0; + int rc = 0; + + if (v4l2_event_pending(&inst->event_handler)) + rc |= POLLPRI; + + spin_lock_irqsave(&capq->done_lock, flags); + if (!list_empty(&capq->done_list)) + cap_vb = list_first_entry(&capq->done_list, struct vb2_buffer, + done_entry); + if (cap_vb && (cap_vb->state == VB2_BUF_STATE_DONE + || cap_vb->state == VB2_BUF_STATE_ERROR)) + rc |= POLLIN | POLLRDNORM; + spin_unlock_irqrestore(&capq->done_lock, flags); + + spin_lock_irqsave(&outq->done_lock, flags); + if (!list_empty(&outq->done_list)) + out_vb = list_first_entry(&outq->done_list, struct vb2_buffer, + done_entry); + if (out_vb && (out_vb->state == VB2_BUF_STATE_DONE + || out_vb->state == VB2_BUF_STATE_ERROR)) + rc |= POLLOUT | POLLWRNORM; + spin_unlock_irqrestore(&outq->done_lock, flags); + + return rc; +} + +int msm_vidc_poll(void *instance, struct file *filp, + struct poll_table_struct *wait) +{ + struct msm_vidc_inst *inst = instance; + struct vb2_queue *outq = NULL; + struct vb2_queue *capq = NULL; + + if (!inst) + return -EINVAL; + + outq = &inst->bufq[INPUT_PORT].vb2_bufq; + capq = &inst->bufq[OUTPUT_PORT].vb2_bufq; + + poll_wait(filp, &inst->event_handler.wait, wait); + poll_wait(filp, &capq->done_wq, wait); + poll_wait(filp, &outq->done_wq, wait); + return get_poll_flags(inst); +} +EXPORT_SYMBOL(msm_vidc_poll); + +int msm_vidc_querycap(void *instance, struct v4l2_capability *cap) +{ + struct msm_vidc_inst *inst = instance; + + if (!inst || !cap) + return -EINVAL; + + strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver)); + cap->bus_info[0] = 0; + cap->version = MSM_VIDC_VERSION; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | + V4L2_CAP_VIDEO_OUTPUT_MPLANE | + V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + + memset(cap->reserved, 0, sizeof(cap->reserved)); + + if (inst->session_type == MSM_VIDC_DECODER) + strlcpy(cap->card, MSM_VDEC_DVC_NAME, sizeof(cap->card)); + else if (inst->session_type == MSM_VIDC_ENCODER) + strlcpy(cap->card, MSM_VENC_DVC_NAME, sizeof(cap->card)); + else + return -EINVAL; + + return 0; +} +EXPORT_SYMBOL(msm_vidc_querycap); + +int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f) +{ + struct msm_vidc_inst *inst = instance; + + if (!inst || !f) + return -EINVAL; + + if (inst->session_type == MSM_VIDC_DECODER) + return msm_vdec_enum_fmt(instance, f); + else if (inst->session_type == MSM_VIDC_ENCODER) + return msm_venc_enum_fmt(instance, f); + return -EINVAL; +} +EXPORT_SYMBOL(msm_vidc_enum_fmt); + +int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *q_ctrl) +{ + int rc = 0; + struct msm_vidc_inst *inst = instance; + struct v4l2_ctrl *ctrl; + + if (!inst || !q_ctrl) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + ctrl = v4l2_ctrl_find(&inst->ctrl_handler, q_ctrl->id); + if (!ctrl) { + dprintk(VIDC_ERR, "%s: get_ctrl failed for id %d\n", + __func__, q_ctrl->id); + return -EINVAL; + } + q_ctrl->minimum = ctrl->minimum; + q_ctrl->maximum = ctrl->maximum; + /* remove tier info for HEVC level */ + if (q_ctrl->id == V4L2_CID_MPEG_VIDEO_HEVC_LEVEL) { + q_ctrl->minimum &= ~(0xF << 28); + q_ctrl->maximum &= ~(0xF << 28); + } + if (ctrl->type == V4L2_CTRL_TYPE_MENU) + q_ctrl->flags = ~(ctrl->menu_skip_mask); + else + q_ctrl->flags = 0; + + dprintk(VIDC_DBG, "query ctrl: %s: min %d, max %d, flags %#x\n", + ctrl->name, q_ctrl->minimum, q_ctrl->maximum, q_ctrl->flags); + return rc; +} +EXPORT_SYMBOL(msm_vidc_query_ctrl); + +int msm_vidc_s_fmt(void *instance, struct v4l2_format *f) +{ + int rc = 0; + struct msm_vidc_inst *inst = instance; + + if (!inst || !f) + return -EINVAL; + + if (inst->session_type == MSM_VIDC_DECODER) + rc = msm_vdec_s_fmt(instance, f); + if (inst->session_type == MSM_VIDC_ENCODER) + rc = msm_venc_s_fmt(instance, f); + + dprintk(VIDC_DBG, + "s_fmt: %x : type %d wxh %dx%d pixelfmt %#x num_planes %d size[0] %d size[1] %d in_reconfig %d\n", + hash32_ptr(inst->session), f->type, + f->fmt.pix_mp.width, f->fmt.pix_mp.height, + f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.num_planes, + f->fmt.pix_mp.plane_fmt[0].sizeimage, + f->fmt.pix_mp.plane_fmt[1].sizeimage, inst->in_reconfig); + return rc; +} +EXPORT_SYMBOL(msm_vidc_s_fmt); + +int msm_vidc_g_fmt(void *instance, struct v4l2_format *f) +{ + int rc = 0; + struct msm_vidc_inst *inst = instance; + + if (!inst || !f) + return -EINVAL; + + if (inst->session_type == MSM_VIDC_DECODER) + rc = msm_vdec_g_fmt(instance, f); + if (inst->session_type == MSM_VIDC_ENCODER) + rc = msm_venc_g_fmt(instance, f); + + dprintk(VIDC_DBG, + "g_fmt: %x : type %d wxh %dx%d pixelfmt %#x num_planes %d size[0] %d size[1] %d in_reconfig %d\n", + hash32_ptr(inst->session), f->type, + f->fmt.pix_mp.width, f->fmt.pix_mp.height, + f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.num_planes, + f->fmt.pix_mp.plane_fmt[0].sizeimage, + f->fmt.pix_mp.plane_fmt[1].sizeimage, inst->in_reconfig); + return rc; +} +EXPORT_SYMBOL(msm_vidc_g_fmt); + +int msm_vidc_s_ctrl(void *instance, struct v4l2_control *control) +{ + struct msm_vidc_inst *inst = instance; + + if (!inst || !control) + return -EINVAL; + + return msm_comm_s_ctrl(instance, control); +} +EXPORT_SYMBOL(msm_vidc_s_ctrl); + +int msm_vidc_g_ctrl(void *instance, struct v4l2_control *control) +{ + struct msm_vidc_inst *inst = instance; + struct v4l2_ctrl *ctrl = NULL; + int rc = 0; + + if (!inst || !control) + return -EINVAL; + + ctrl = v4l2_ctrl_find(&inst->ctrl_handler, control->id); + if (ctrl) { + rc = try_get_ctrl_for_instance(inst, ctrl); + if (!rc) + control->value = ctrl->val; + } + + return rc; +} +EXPORT_SYMBOL(msm_vidc_g_ctrl); + +int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b) +{ + struct msm_vidc_inst *inst = instance; + struct buf_queue *q = NULL; + int rc = 0; + + if (!inst || !b) + return -EINVAL; + q = msm_comm_get_vb2q(inst, b->type); + if (!q) { + dprintk(VIDC_ERR, + "Failed to find buffer queue for type = %d\n", + b->type); + return -EINVAL; + } + + mutex_lock(&q->lock); + rc = vb2_reqbufs(&q->vb2_bufq, b); + mutex_unlock(&q->lock); + + if (rc) + dprintk(VIDC_ERR, "Failed to get reqbufs, %d\n", rc); + return rc; +} +EXPORT_SYMBOL(msm_vidc_reqbufs); + +static bool valid_v4l2_buffer(struct v4l2_buffer *b, + struct msm_vidc_inst *inst) +{ + struct v4l2_format *f; + enum vidc_ports port = + !V4L2_TYPE_IS_MULTIPLANAR(b->type) ? MAX_PORT_NUM : + b->type == OUTPUT_MPLANE ? OUTPUT_PORT : + b->type == INPUT_MPLANE ? INPUT_PORT : + MAX_PORT_NUM; + + f = &inst->fmts[port].v4l2_fmt; + return port != MAX_PORT_NUM && + f->fmt.pix_mp.num_planes == b->length; +} + +int msm_vidc_release_buffer(void *instance, int type, unsigned int index) +{ + int rc = 0; + struct msm_vidc_inst *inst = instance; + struct msm_vidc_buffer *mbuf, *dummy; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid inst\n", __func__); + return -EINVAL; + } + + if (!inst->in_reconfig && + inst->state > MSM_VIDC_LOAD_RESOURCES && + inst->state < MSM_VIDC_RELEASE_RESOURCES_DONE) { + rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); + if (rc) { + dprintk(VIDC_ERR, + "%s: Failed to move inst: %pK to rel res done\n", + __func__, inst); + } + } + + mutex_lock(&inst->registeredbufs.lock); + list_for_each_entry_safe(mbuf, dummy, &inst->registeredbufs.list, + list) { + struct vb2_buffer *vb2 = &mbuf->vvb.vb2_buf; + + if (vb2->type != type || vb2->index != index) + continue; + + if (mbuf->flags & MSM_VIDC_FLAG_RBR_PENDING) { + print_vidc_buffer(VIDC_DBG, + "skip rel buf (rbr pending)", inst, mbuf); + continue; + } + + print_vidc_buffer(VIDC_DBG, "release buf", inst, mbuf); + msm_comm_unmap_vidc_buffer(inst, mbuf); + list_del(&mbuf->list); + kref_put_mbuf(mbuf); + } + mutex_unlock(&inst->registeredbufs.lock); + + return rc; +} +EXPORT_SYMBOL(msm_vidc_release_buffer); + +static int msm_vidc_preprocess(struct msm_vidc_inst *inst, + struct vb2_buffer *vb) +{ + int rc = 0; + struct buf_queue *q; + + if (!inst || !vb) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (!is_encode_session(inst) || vb->type != + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + return 0; + + if (!is_vidc_cvp_enabled(inst)) + return 0; + + q = msm_comm_get_vb2q(inst, vb->type); + if (!q) { + dprintk(VIDC_ERR, "%s: queue not found for type %d\n", + __func__, vb->type); + return -EINVAL; + } + if (!q->vb2_bufq.streaming) { + dprintk(VIDC_ERR, + "%s: enable input port streaming before queuing input buffers\n", + __func__); + return -EINVAL; + } + rc = msm_vidc_cvp_preprocess(inst, vb); + if (rc) { + dprintk(VIDC_ERR, "%s: cvp preprocess failed\n", + __func__); + return rc; + } + + return rc; +} + +int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) +{ + struct msm_vidc_inst *inst = instance; + int rc = 0; + unsigned int i = 0; + struct buf_queue *q = NULL; + u32 cr = 0; + + if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) { + dprintk(VIDC_ERR, "%s: invalid params, inst %pK\n", + __func__, inst); + return -EINVAL; + } + + for (i = 0; i < b->length; i++) { + b->m.planes[i].m.fd = b->m.planes[i].reserved[0]; + b->m.planes[i].data_offset = b->m.planes[i].reserved[1]; + } + + /* Compression ratio is valid only for Encoder YUV buffers. */ + if (inst->session_type == MSM_VIDC_ENCODER && + b->type == INPUT_MPLANE) { + cr = b->m.planes[0].reserved[2]; + msm_comm_update_input_cr(inst, b->index, cr); + } + + if (inst->session_type == MSM_VIDC_DECODER && + b->type == INPUT_MPLANE) { + msm_comm_store_mark_data(&inst->etb_data, b->index, + b->m.planes[0].reserved[3], b->m.planes[0].reserved[4]); + } + + q = msm_comm_get_vb2q(inst, b->type); + if (!q) { + dprintk(VIDC_ERR, + "Failed to find buffer queue for type = %d\n", b->type); + return -EINVAL; + } + + mutex_lock(&q->lock); + rc = vb2_qbuf(&q->vb2_bufq, b); + mutex_unlock(&q->lock); + if (rc) + dprintk(VIDC_ERR, "Failed to qbuf, %d\n", rc); + + return rc; +} +EXPORT_SYMBOL(msm_vidc_qbuf); + +int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) +{ + struct msm_vidc_inst *inst = instance; + int rc = 0; + unsigned int i = 0; + struct buf_queue *q = NULL; + + if (!inst || !b || !valid_v4l2_buffer(b, inst)) { + dprintk(VIDC_ERR, "%s: invalid params, inst %pK\n", + __func__, inst); + return -EINVAL; + } + + q = msm_comm_get_vb2q(inst, b->type); + if (!q) { + dprintk(VIDC_ERR, + "Failed to find buffer queue for type = %d\n", b->type); + return -EINVAL; + } + + mutex_lock(&q->lock); + rc = vb2_dqbuf(&q->vb2_bufq, b, true); + mutex_unlock(&q->lock); + if (rc == -EAGAIN) { + return rc; + } else if (rc) { + dprintk(VIDC_ERR, "Failed to dqbuf, %d\n", rc); + return rc; + } + + for (i = 0; i < b->length; i++) { + b->m.planes[i].reserved[0] = b->m.planes[i].m.fd; + b->m.planes[i].reserved[1] = b->m.planes[i].data_offset; + } + + if (inst->session_type == MSM_VIDC_DECODER && + b->type == OUTPUT_MPLANE) { + msm_comm_fetch_mark_data(&inst->fbd_data, b->index, + &b->m.planes[0].reserved[3], + &b->m.planes[0].reserved[4]); + } + + return rc; +} +EXPORT_SYMBOL(msm_vidc_dqbuf); + +int msm_vidc_streamon(void *instance, enum v4l2_buf_type i) +{ + struct msm_vidc_inst *inst = instance; + int rc = 0; + struct buf_queue *q; + + if (!inst) + return -EINVAL; + + q = msm_comm_get_vb2q(inst, i); + if (!q) { + dprintk(VIDC_ERR, + "Failed to find buffer queue for type = %d\n", i); + return -EINVAL; + } + dprintk(VIDC_DBG, "Calling streamon\n"); + mutex_lock(&q->lock); + rc = vb2_streamon(&q->vb2_bufq, i); + mutex_unlock(&q->lock); + if (rc) { + dprintk(VIDC_ERR, "streamon failed on port: %d\n", i); + msm_comm_kill_session(inst); + } + return rc; +} +EXPORT_SYMBOL(msm_vidc_streamon); + +int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i) +{ + struct msm_vidc_inst *inst = instance; + int rc = 0; + struct buf_queue *q; + + if (!inst) + return -EINVAL; + + q = msm_comm_get_vb2q(inst, i); + if (!q) { + dprintk(VIDC_ERR, + "Failed to find buffer queue for type = %d\n", i); + return -EINVAL; + } + + if (!inst->in_reconfig) { + dprintk(VIDC_DBG, "%s: inst %pK release resources\n", + __func__, inst); + rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); + if (rc) + dprintk(VIDC_ERR, + "%s: inst %pK move to rel res done failed\n", + __func__, inst); + } + + dprintk(VIDC_DBG, "Calling streamoff\n"); + mutex_lock(&q->lock); + rc = vb2_streamoff(&q->vb2_bufq, i); + mutex_unlock(&q->lock); + if (rc) + dprintk(VIDC_ERR, "streamoff failed on port: %d\n", i); + return rc; +} +EXPORT_SYMBOL(msm_vidc_streamoff); + +int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize) +{ + struct msm_vidc_inst *inst = instance; + struct msm_vidc_capability *capability = NULL; + + if (!inst || !fsize) { + dprintk(VIDC_ERR, "%s: invalid parameter: %pK %pK\n", + __func__, inst, fsize); + return -EINVAL; + } + if (!inst->core) + return -EINVAL; + + capability = &inst->capability; + fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; + fsize->stepwise.min_width = capability->cap[CAP_FRAME_WIDTH].min; + fsize->stepwise.max_width = capability->cap[CAP_FRAME_WIDTH].max; + fsize->stepwise.step_width = + capability->cap[CAP_FRAME_WIDTH].step_size; + fsize->stepwise.min_height = capability->cap[CAP_FRAME_HEIGHT].min; + fsize->stepwise.max_height = capability->cap[CAP_FRAME_HEIGHT].max; + fsize->stepwise.step_height = + capability->cap[CAP_FRAME_HEIGHT].step_size; + return 0; +} +EXPORT_SYMBOL(msm_vidc_enum_framesizes); + +static void *vidc_get_userptr(struct device *dev, unsigned long vaddr, + unsigned long size, enum dma_data_direction dma_dir) +{ + return (void *)0xdeadbeef; +} + +static void vidc_put_userptr(void *buf_priv) +{ +} + +static const struct vb2_mem_ops msm_vidc_vb2_mem_ops = { + .get_userptr = vidc_get_userptr, + .put_userptr = vidc_put_userptr, +}; + +static void msm_vidc_cleanup_buffer(struct vb2_buffer *vb) +{ + int rc = 0; + struct buf_queue *q = NULL; + struct msm_vidc_inst *inst = NULL; + + if (!vb) { + dprintk(VIDC_ERR, "%s : Invalid vb pointer %pK", + __func__, vb); + return; + } + + inst = vb2_get_drv_priv(vb->vb2_queue); + if (!inst) { + dprintk(VIDC_ERR, "%s : Invalid inst pointer", + __func__); + return; + } + + q = msm_comm_get_vb2q(inst, vb->type); + if (!q) { + dprintk(VIDC_ERR, + "%s : Failed to find buffer queue for type = %d\n", + __func__, vb->type); + return; + } + + if (q->vb2_bufq.streaming) { + dprintk(VIDC_DBG, "%d PORT is streaming\n", + vb->type); + return; + } + + rc = msm_vidc_release_buffer(inst, vb->type, vb->index); + if (rc) + dprintk(VIDC_ERR, "%s : Failed to release buffers : %d\n", + __func__, rc); +} + +static int msm_vidc_queue_setup(struct vb2_queue *q, + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], struct device *alloc_devs[]) +{ + struct msm_vidc_inst *inst; + int rc = 0; + unsigned int i = 0; + struct msm_vidc_format *fmt; + struct v4l2_format *f; + + if (!q || !num_buffers || !num_planes + || !sizes || !q->drv_priv) { + dprintk(VIDC_ERR, "Invalid input, q = %pK, %pK, %pK\n", + q, num_buffers, num_planes); + return -EINVAL; + } + inst = q->drv_priv; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + switch (q->type) { + case INPUT_MPLANE: { + fmt = &inst->fmts[INPUT_PORT]; + if (*num_buffers < fmt->count_min_host) { + dprintk(VIDC_DBG, + "Client passed num buffers %d less than the min_host count %d\n", + *num_buffers, fmt->count_min_host); + } + f = &fmt->v4l2_fmt; + *num_planes = f->fmt.pix_mp.num_planes; + if (*num_buffers < MIN_NUM_INPUT_BUFFERS || + *num_buffers > MAX_NUM_INPUT_BUFFERS) + fmt->count_actual = *num_buffers = + MIN_NUM_INPUT_BUFFERS; + for (i = 0; i < *num_planes; i++) + sizes[i] = f->fmt.pix_mp.plane_fmt[i].sizeimage; + + fmt->count_actual = *num_buffers; + } + break; + case OUTPUT_MPLANE: { + fmt = &inst->fmts[OUTPUT_PORT]; + if (inst->session_type != MSM_VIDC_DECODER && + inst->state > MSM_VIDC_LOAD_RESOURCES_DONE) { + if (*num_buffers < fmt->count_min_host) { + dprintk(VIDC_DBG, + "Client passed num buffers %d less than the min_host count %d\n", + *num_buffers, + fmt->count_min_host); + } + } + f = &fmt->v4l2_fmt; + *num_planes = f->fmt.pix_mp.num_planes; + if (*num_buffers < MIN_NUM_OUTPUT_BUFFERS || + *num_buffers > MAX_NUM_OUTPUT_BUFFERS) + fmt->count_actual = *num_buffers = + MIN_NUM_OUTPUT_BUFFERS; + + for (i = 0; i < *num_planes; i++) + sizes[i] = f->fmt.pix_mp.plane_fmt[i].sizeimage; + + fmt->count_actual = *num_buffers; + } + break; + default: + dprintk(VIDC_ERR, "Invalid q type = %d\n", q->type); + rc = -EINVAL; + break; + } + + dprintk(VIDC_DBG, + "queue_setup: %x : type %d num_buffers %d num_planes %d sizes[0] %d sizes[1] %d\n", + hash32_ptr(inst->session), q->type, *num_buffers, + *num_planes, sizes[0], sizes[1]); + return rc; +} + +static inline int msm_vidc_verify_buffer_counts(struct msm_vidc_inst *inst) +{ + int rc = 0, i = 0; + + /* For decoder No need to sanity till LOAD_RESOURCES */ + if (inst->session_type == MSM_VIDC_DECODER && + (inst->state < MSM_VIDC_LOAD_RESOURCES_DONE || + inst->state >= MSM_VIDC_RELEASE_RESOURCES_DONE)) { + dprintk(VIDC_DBG, + "No need to verify buffer counts : %pK\n", inst); + return 0; + } + + for (i = 0; i < HAL_BUFFER_MAX; i++) { + struct hal_buffer_requirements *req = &inst->buff_req.buffer[i]; + + if (req && (req->buffer_type == HAL_BUFFER_OUTPUT)) { + dprintk(VIDC_DBG, "Verifying Buffer : %d\n", + req->buffer_type); + if (req->buffer_count_actual < + req->buffer_count_min_host || + req->buffer_count_min_host < + req->buffer_count_min) { + + dprintk(VIDC_ERR, + "Invalid data : Counts mismatch\n"); + dprintk(VIDC_ERR, + "Min Count = %d ", + req->buffer_count_min); + dprintk(VIDC_ERR, + "Min Host Count = %d ", + req->buffer_count_min_host); + dprintk(VIDC_ERR, + "Min Actual Count = %d\n", + req->buffer_count_actual); + rc = -EINVAL; + break; + } + } + } + return rc; +} + +static int msm_vidc_set_properties(struct msm_vidc_inst *inst) +{ + int rc = 0; + + if (is_decode_session(inst)) + rc = msm_vdec_set_properties(inst); + else if (is_encode_session(inst)) + rc = msm_venc_set_properties(inst); + + return rc; +} + +static int msm_vidc_prepare_preprocess(struct msm_vidc_inst *inst) +{ + int rc = 0; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (!is_vidc_cvp_allowed(inst)) { + dprintk(VIDC_DBG, "%s: cvp not allowed\n", __func__); + return 0; + } + + rc = msm_vidc_cvp_prepare_preprocess(inst); + if (rc) { + dprintk(VIDC_WARN, "%s: no cvp preprocessing\n", __func__); + msm_vidc_cvp_unprepare_preprocess(inst); + goto exit; + } + dprintk(VIDC_DBG, "%s: cvp enabled\n", __func__); + +exit: + return rc; +} + +static inline int start_streaming(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_buffer_size_minimum b; + struct v4l2_format *f; + + dprintk(VIDC_DBG, "%s: %x : inst %pK\n", __func__, + hash32_ptr(inst->session), inst); + hdev = inst->core->device; + + rc = msm_vidc_set_properties(inst); + if (rc) { + dprintk(VIDC_ERR, "%s: %x: set props failed\n", + __func__, hash32_ptr(inst->session)); + goto fail_start; + } + + b.buffer_type = HFI_BUFFER_OUTPUT; + if (inst->session_type == MSM_VIDC_DECODER && + is_secondary_output_mode(inst)) + b.buffer_type = HFI_BUFFER_OUTPUT2; + + /* HEIC HW/FWK tiling encode is supported only for CQ RC mode */ + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) { + if (!heic_encode_session_supported(inst)) { + dprintk(VIDC_ERR, + "HEIC Encode session not supported\n"); + return -ENOTSUPP; + } + } + + /* Check if current session is under HW capability */ + rc = msm_vidc_check_session_supported(inst); + if (rc) { + dprintk(VIDC_ERR, + "This session is not supported %pK\n", inst); + goto fail_start; + } + + rc = msm_vidc_check_scaling_supported(inst); + if (rc) { + dprintk(VIDC_ERR, + "This session scaling is not supported %pK\n", inst); + goto fail_start; + } + + /* Decide work mode for current session */ + rc = call_core_op(inst->core, decide_work_mode, inst); + if (rc) { + dprintk(VIDC_ERR, + "Failed to decide work mode for session %pK\n", inst); + goto fail_start; + } + + /* Decide work route for current session */ + rc = call_core_op(inst->core, decide_work_route, inst); + if (rc) { + dprintk(VIDC_ERR, + "Failed to decide work route for session %pK\n", inst); + goto fail_start; + } + + /* Assign Core and LP mode for current session */ + rc = call_core_op(inst->core, decide_core_and_power_mode, inst); + if (rc) { + dprintk(VIDC_ERR, + "This session can't be submitted to HW %pK\n", inst); + goto fail_start; + } + + rc = msm_comm_try_get_bufreqs(inst); + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + b.buffer_size = f->fmt.pix_mp.plane_fmt[0].sizeimage; + rc = call_hfi_op(hdev, session_set_property, + inst->session, HFI_PROPERTY_PARAM_BUFFER_SIZE_MINIMUM, + &b, sizeof(b)); + + /* Verify if buffer counts are correct */ + rc = msm_vidc_verify_buffer_counts(inst); + if (rc) { + dprintk(VIDC_ERR, + "This session has mis-match buffer counts%pK\n", inst); + goto fail_start; + } + + rc = msm_comm_set_scratch_buffers(inst); + if (rc) { + dprintk(VIDC_ERR, + "Failed to set scratch buffers: %d\n", rc); + goto fail_start; + } + rc = msm_comm_set_persist_buffers(inst); + if (rc) { + dprintk(VIDC_ERR, + "Failed to set persist buffers: %d\n", rc); + goto fail_start; + } + + rc = msm_comm_set_recon_buffers(inst); + if (rc) { + dprintk(VIDC_ERR, + "Failed to set recon buffers: %d\n", rc); + goto fail_start; + } + + if (msm_comm_get_stream_output_mode(inst) == + HAL_VIDEO_DECODER_SECONDARY) { + rc = msm_comm_set_dpb_only_buffers(inst); + if (rc) { + dprintk(VIDC_ERR, + "Failed to set output buffers: %d\n", rc); + goto fail_start; + } + } + + inst->batch.enable = is_batching_allowed(inst); + dprintk(VIDC_DBG, "%s: batching %s for inst %pK (%#x)\n", + __func__, inst->batch.enable ? "enabled" : "disabled", + inst, hash32_ptr(inst->session)); + + /* + * For seq_changed_insufficient, driver should set session_continue + * to firmware after the following sequence + * - driver raises insufficient event to v4l2 client + * - all output buffers have been flushed and freed + * - v4l2 client queries buffer requirements and splits/combines OPB-DPB + * - v4l2 client sets new set of buffers to firmware + * - v4l2 client issues CONTINUE to firmware to resume decoding of + * submitted ETBs. + */ + rc = msm_comm_session_continue(inst); + if (rc) + goto fail_start; + + msm_comm_scale_clocks_and_bus(inst); + + rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE); + if (rc) { + dprintk(VIDC_ERR, + "Failed to move inst: %pK to start done state\n", inst); + goto fail_start; + } + + msm_clock_data_reset(inst); + + if (msm_comm_get_stream_output_mode(inst) == + HAL_VIDEO_DECODER_SECONDARY) { + rc = msm_comm_queue_dpb_only_buffers(inst); + if (rc) { + dprintk(VIDC_ERR, + "Failed to queue output buffers: %d\n", rc); + goto fail_start; + } + } + +fail_start: + if (rc) + dprintk(VIDC_ERR, "%s: inst %pK session %x failed to start\n", + __func__, inst, hash32_ptr(inst->session)); + return rc; +} + +static int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct msm_vidc_inst *inst; + int rc = 0; + struct hfi_device *hdev; + + if (!q || !q->drv_priv) { + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); + return -EINVAL; + } + inst = q->drv_priv; + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + dprintk(VIDC_DBG, "Streamon called on: %d capability for inst: %pK\n", + q->type, inst); + switch (q->type) { + case INPUT_MPLANE: + if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming) + rc = start_streaming(inst); + break; + case OUTPUT_MPLANE: + if (inst->bufq[INPUT_PORT].vb2_bufq.streaming) + rc = start_streaming(inst); + break; + default: + dprintk(VIDC_ERR, "Queue type is not supported: %d\n", q->type); + rc = -EINVAL; + goto stream_start_failed; + } + if (rc) { + dprintk(VIDC_ERR, + "Streamon failed on: %d capability for inst: %pK\n", + q->type, inst); + goto stream_start_failed; + } + + if (is_encode_session(inst) && q->type == + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + rc = msm_vidc_prepare_preprocess(inst); + if (rc) { + dprintk(VIDC_WARN, "%s: no preprocessing\n", __func__); + /* ignore error */ + rc = 0; + } + } + + rc = msm_comm_qbufs(inst); + if (rc) { + dprintk(VIDC_ERR, + "Failed to commit buffers queued before STREAM_ON to hardware: %d\n", + rc); + goto stream_start_failed; + } + + rc = msm_vidc_send_pending_eos_buffers(inst); + if (rc) { + dprintk(VIDC_ERR, + "Failed : Send pending EOS buffs for Inst = %pK, %d\n", + inst, rc); + goto stream_start_failed; + } + +stream_start_failed: + if (rc) { + struct msm_vidc_buffer *temp, *next; + struct vb2_buffer *vb; + + mutex_lock(&inst->registeredbufs.lock); + list_for_each_entry_safe(temp, next, &inst->registeredbufs.list, + list) { + if (temp->vvb.vb2_buf.type != q->type) + continue; + /* + * queued_list lock is already acquired before + * vb2_stream so no need to acquire it again. + */ + list_for_each_entry(vb, &q->queued_list, queued_entry) { + if (msm_comm_compare_vb2_planes(inst, temp, + vb)) { + print_vb2_buffer(VIDC_ERR, "return vb", + inst, vb); + vb2_buffer_done(vb, + VB2_BUF_STATE_QUEUED); + break; + } + } + msm_comm_unmap_vidc_buffer(inst, temp); + list_del(&temp->list); + kref_put_mbuf(temp); + } + mutex_unlock(&inst->registeredbufs.lock); + } + return rc; +} + +static inline int stop_streaming(struct msm_vidc_inst *inst) +{ + int rc = 0; + + dprintk(VIDC_DBG, "%s: %x : inst %pK\n", __func__, + hash32_ptr(inst->session), inst); + + rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); + if (rc) + dprintk(VIDC_ERR, + "Failed to move inst: %pK to state %d\n", + inst, MSM_VIDC_RELEASE_RESOURCES_DONE); + + msm_clock_data_reset(inst); + + return rc; +} + +static int msm_vidc_unprepare_preprocess(struct msm_vidc_inst *inst) +{ + int rc = 0; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (!is_vidc_cvp_enabled(inst)) + return 0; + + rc = msm_vidc_cvp_unprepare_preprocess(inst); + if (rc) + dprintk(VIDC_ERR, + "%s: cvp unprepare preprocess failed with rc %d\n", + __func__, rc); + + return rc; +} + +static void msm_vidc_stop_streaming(struct vb2_queue *q) +{ + struct msm_vidc_inst *inst; + int rc = 0; + + if (!q || !q->drv_priv) { + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); + return; + } + + inst = q->drv_priv; + dprintk(VIDC_DBG, "Streamoff called on: %d capability\n", q->type); + + if (is_encode_session(inst) && q->type == + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + rc = msm_vidc_unprepare_preprocess(inst); + if (rc) + dprintk(VIDC_ERR, + "%s: failed to unprepare preprocess\n", + __func__); + } + + switch (q->type) { + case INPUT_MPLANE: + if (!inst->bufq[OUTPUT_PORT].vb2_bufq.streaming) + rc = stop_streaming(inst); + break; + case OUTPUT_MPLANE: + if (!inst->bufq[INPUT_PORT].vb2_bufq.streaming) + rc = stop_streaming(inst); + break; + default: + dprintk(VIDC_ERR, + "Q-type is not supported: %d\n", q->type); + rc = -EINVAL; + break; + } + + msm_comm_scale_clocks_and_bus(inst); + + if (rc) + dprintk(VIDC_ERR, + "Failed STOP Streaming inst = %pK on cap = %d\n", + inst, q->type); +} + +static int msm_vidc_queue_buf(struct msm_vidc_inst *inst, + struct vb2_buffer *vb2) +{ + int rc = 0; + struct msm_vidc_buffer *mbuf; + + if (!inst || !vb2) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + mbuf = msm_comm_get_vidc_buffer(inst, vb2); + if (IS_ERR_OR_NULL(mbuf)) { + /* + * if the buffer has RBR_PENDING flag (-EEXIST) then don't queue + * it now, it will be queued via msm_comm_qbuf_rbr() as part of + * RBR event processing. + */ + if (PTR_ERR(mbuf) == -EEXIST) + return 0; + dprintk(VIDC_ERR, "%s: failed to get vidc-buf\n", __func__); + return -EINVAL; + } + if (!kref_get_mbuf(inst, mbuf)) { + dprintk(VIDC_ERR, "%s: mbuf not found\n", __func__); + return -EINVAL; + } + rc = msm_comm_qbuf(inst, mbuf); + if (rc) + dprintk(VIDC_ERR, "%s: failed qbuf\n", __func__); + kref_put_mbuf(mbuf); + + return rc; +} + +static int msm_vidc_queue_buf_decode_batch(struct msm_vidc_inst *inst, + struct vb2_buffer *vb2) +{ + int rc; + struct msm_vidc_buffer *mbuf; + + if (!inst || !vb2) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + mbuf = msm_comm_get_vidc_buffer(inst, vb2); + if (IS_ERR_OR_NULL(mbuf)) { + dprintk(VIDC_ERR, "%s: failed to get vidc-buf\n", __func__); + return -EINVAL; + } + if (!kref_get_mbuf(inst, mbuf)) { + dprintk(VIDC_ERR, "%s: mbuf not found\n", __func__); + return -EINVAL; + } + /* + * If this buffer has RBR_EPNDING then it will not be queued + * but it may trigger full batch queuing in below function. + */ + rc = msm_comm_qbuf_decode_batch(inst, mbuf); + if (rc) + dprintk(VIDC_ERR, "%s: failed qbuf\n", __func__); + kref_put_mbuf(mbuf); + + return rc; +} + +static int msm_vidc_queue_buf_batch(struct msm_vidc_inst *inst, + struct vb2_buffer *vb2) +{ + int rc; + + if (!inst || !vb2) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (inst->session_type == MSM_VIDC_DECODER && + vb2->type == OUTPUT_MPLANE) + rc = msm_vidc_queue_buf_decode_batch(inst, vb2); + else + rc = msm_vidc_queue_buf(inst, vb2); + + return rc; +} + +static void msm_vidc_buf_queue(struct vb2_buffer *vb2) +{ + int rc = 0; + struct msm_vidc_inst *inst = NULL; + + inst = vb2_get_drv_priv(vb2->vb2_queue); + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid inst\n", __func__); + return; + } + + /* do preprocessing if any */ + rc = msm_vidc_preprocess(inst, vb2); + if (rc) { + dprintk(VIDC_ERR, "%s: preprocess failed %x\n", + __func__, hash32_ptr(inst->session)); + goto exit; + } + + if (inst->batch.enable) + rc = msm_vidc_queue_buf_batch(inst, vb2); + else + rc = msm_vidc_queue_buf(inst, vb2); + +exit: + if (rc) { + print_vb2_buffer(VIDC_ERR, "failed vb2-qbuf", inst, vb2); + msm_comm_generate_session_error(inst); + } +} + +static const struct vb2_ops msm_vidc_vb2q_ops = { + .queue_setup = msm_vidc_queue_setup, + .start_streaming = msm_vidc_start_streaming, + .buf_queue = msm_vidc_buf_queue, + .buf_cleanup = msm_vidc_cleanup_buffer, + .stop_streaming = msm_vidc_stop_streaming, +}; + +static inline int vb2_bufq_init(struct msm_vidc_inst *inst, + enum v4l2_buf_type type, enum session_type sess) +{ + struct vb2_queue *q = NULL; + + if (type == OUTPUT_MPLANE) { + q = &inst->bufq[OUTPUT_PORT].vb2_bufq; + } else if (type == INPUT_MPLANE) { + q = &inst->bufq[INPUT_PORT].vb2_bufq; + } else { + dprintk(VIDC_ERR, "buf_type = %d not recognised\n", type); + return -EINVAL; + } + + q->type = type; + q->io_modes = VB2_MMAP | VB2_USERPTR; + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + q->ops = &msm_vidc_vb2q_ops; + + q->mem_ops = &msm_vidc_vb2_mem_ops; + q->drv_priv = inst; + q->allow_zero_bytesused = !V4L2_TYPE_IS_OUTPUT(type); + q->copy_timestamp = 1; + return vb2_queue_init(q); +} + +static int setup_event_queue(void *inst, + struct video_device *pvdev) +{ + struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst; + + v4l2_fh_init(&vidc_inst->event_handler, pvdev); + v4l2_fh_add(&vidc_inst->event_handler); + + return 0; +} + +int msm_vidc_subscribe_event(void *inst, + const struct v4l2_event_subscription *sub) +{ + int rc = 0; + struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst; + + if (!inst || !sub) + return -EINVAL; + + rc = v4l2_event_subscribe(&vidc_inst->event_handler, + sub, MAX_EVENTS, NULL); + return rc; +} +EXPORT_SYMBOL(msm_vidc_subscribe_event); + +int msm_vidc_unsubscribe_event(void *inst, + const struct v4l2_event_subscription *sub) +{ + int rc = 0; + struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst; + + if (!inst || !sub) + return -EINVAL; + + rc = v4l2_event_unsubscribe(&vidc_inst->event_handler, sub); + return rc; +} +EXPORT_SYMBOL(msm_vidc_unsubscribe_event); + +int msm_vidc_dqevent(void *inst, struct v4l2_event *event) +{ + int rc = 0; + struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst; + + if (!inst || !event) + return -EINVAL; + + rc = v4l2_event_dequeue(&vidc_inst->event_handler, event, false); + return rc; +} +EXPORT_SYMBOL(msm_vidc_dqevent); + +int msm_vidc_private(void *vidc_inst, unsigned int cmd, + struct msm_vidc_arg *arg) +{ + int rc = 0; + struct msm_vidc_inst *inst = (struct msm_vidc_inst *)vidc_inst; + + if (!inst || !arg) { + dprintk(VIDC_ERR, "%s: invalid args\n", __func__); + return -EINVAL; + } + + if (inst->session_type == MSM_VIDC_CVP) { + rc = msm_vidc_cvp(inst, arg); + } else { + dprintk(VIDC_ERR, + "%s: private cmd %#x not supported for session_type %d\n", + __func__, cmd, inst->session_type); + rc = -EINVAL; + } + + return rc; +} +EXPORT_SYMBOL(msm_vidc_private); + +static int msm_vidc_try_set_ctrl(void *instance, struct v4l2_ctrl *ctrl) +{ + struct msm_vidc_inst *inst = instance; + + if (inst->session_type == MSM_VIDC_DECODER) + return msm_vdec_s_ctrl(instance, ctrl); + else if (inst->session_type == MSM_VIDC_ENCODER) + return msm_venc_s_ctrl(instance, ctrl); + return -EINVAL; +} + +static int msm_vidc_op_s_ctrl(struct v4l2_ctrl *ctrl) +{ + + int rc = 0; + unsigned int c = 0; + struct msm_vidc_inst *inst; + + if (!ctrl) { + dprintk(VIDC_ERR, "%s invalid parameters for ctrl\n", __func__); + return -EINVAL; + } + + inst = container_of(ctrl->handler, + struct msm_vidc_inst, ctrl_handler); + if (!inst) { + dprintk(VIDC_ERR, "%s invalid parameters for inst\n", __func__); + return -EINVAL; + } + + for (c = 0; c < ctrl->ncontrols; ++c) { + if (ctrl->cluster[c]->is_new) { + rc = msm_vidc_try_set_ctrl(inst, ctrl->cluster[c]); + if (rc) { + dprintk(VIDC_ERR, "Failed setting %x\n", + ctrl->cluster[c]->id); + break; + } + } + } + if (rc) + dprintk(VIDC_ERR, "Failed setting control: Inst = %pK (%s)\n", + inst, v4l2_ctrl_get_name(ctrl->id)); + return rc; +} + +static int try_get_ctrl_for_instance(struct msm_vidc_inst *inst, + struct v4l2_ctrl *ctrl) +{ + int rc = 0; + + switch (ctrl->id) { + case V4L2_CID_MPEG_VIDEO_H264_PROFILE: + ctrl->val = msm_comm_hfi_to_v4l2( + V4L2_CID_MPEG_VIDEO_H264_PROFILE, + inst->profile); + break; + case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: + ctrl->val = msm_comm_hfi_to_v4l2( + V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, + inst->profile); + break; + case V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE: + ctrl->val = inst->grid_enable; + break; + case V4L2_CID_MPEG_VIDEO_H264_LEVEL: + ctrl->val = msm_comm_hfi_to_v4l2( + V4L2_CID_MPEG_VIDEO_H264_LEVEL, + inst->level); + break; + case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL: + ctrl->val = msm_comm_hfi_to_v4l2( + V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL, + inst->level); + break; + case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: + ctrl->val = msm_comm_hfi_to_v4l2( + V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, + inst->level); + break; + case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: + ctrl->val = inst->fmts[OUTPUT_PORT].count_min_host; + dprintk(VIDC_DBG, "g_min: %x : hal_buffer %d min buffers %d\n", + hash32_ptr(inst->session), HAL_BUFFER_OUTPUT, + ctrl->val); + break; + case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: + ctrl->val = inst->fmts[INPUT_PORT].count_min_host; + dprintk(VIDC_DBG, "g_min: %x : hal_buffer %d min buffers %d\n", + hash32_ptr(inst->session), HAL_BUFFER_INPUT, ctrl->val); + break; + case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA: + ctrl->val = inst->prop.extradata_ctrls; + break; + default: + break; + } + + return rc; +} + +static const struct v4l2_ctrl_ops msm_vidc_ctrl_ops = { + + .s_ctrl = msm_vidc_op_s_ctrl, +}; + +static struct msm_vidc_inst_smem_ops msm_vidc_smem_ops = { + .smem_map_dma_buf = msm_smem_map_dma_buf, + .smem_unmap_dma_buf = msm_smem_unmap_dma_buf, +}; + +void *msm_vidc_open(int core_id, int session_type) +{ + struct msm_vidc_inst *inst = NULL; + struct msm_vidc_core *core = NULL; + int rc = 0; + int i = 0; + + if (core_id >= MSM_VIDC_CORES_MAX || + session_type >= MSM_VIDC_MAX_DEVICES) { + dprintk(VIDC_ERR, "Invalid input, core_id = %d, session = %d\n", + core_id, session_type); + goto err_invalid_core; + } + core = get_vidc_core(core_id); + if (!core) { + dprintk(VIDC_ERR, + "Failed to find core for core_id = %d\n", core_id); + goto err_invalid_core; + } + + inst = kzalloc(sizeof(*inst), GFP_KERNEL); + if (!inst) { + dprintk(VIDC_ERR, "Failed to allocate memory\n"); + rc = -ENOMEM; + goto err_invalid_core; + } + + pr_info(VIDC_DBG_TAG "Opening video instance: %pK, %d\n", + "info", inst, session_type); + mutex_init(&inst->sync_lock); + mutex_init(&inst->bufq[OUTPUT_PORT].lock); + mutex_init(&inst->bufq[INPUT_PORT].lock); + mutex_init(&inst->lock); + mutex_init(&inst->flush_lock); + + INIT_MSM_VIDC_LIST(&inst->scratchbufs); + INIT_MSM_VIDC_LIST(&inst->freqs); + INIT_MSM_VIDC_LIST(&inst->input_crs); + INIT_MSM_VIDC_LIST(&inst->persistbufs); + INIT_MSM_VIDC_LIST(&inst->pending_getpropq); + INIT_MSM_VIDC_LIST(&inst->outputbufs); + INIT_MSM_VIDC_LIST(&inst->registeredbufs); + INIT_MSM_VIDC_LIST(&inst->cvpbufs); + INIT_MSM_VIDC_LIST(&inst->reconbufs); + INIT_MSM_VIDC_LIST(&inst->eosbufs); + INIT_MSM_VIDC_LIST(&inst->etb_data); + INIT_MSM_VIDC_LIST(&inst->fbd_data); + + kref_init(&inst->kref); + + inst->session_type = session_type; + inst->state = MSM_VIDC_CORE_UNINIT_DONE; + inst->core = core; + inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT; + inst->clk_data.dpb_fourcc = V4L2_PIX_FMT_NV12_UBWC; + inst->clk_data.opb_fourcc = V4L2_PIX_FMT_NV12_UBWC; + inst->bit_depth = MSM_VIDC_BIT_DEPTH_8; + inst->pic_struct = MSM_VIDC_PIC_STRUCT_PROGRESSIVE; + inst->colour_space = MSM_VIDC_BT601_6_525; + inst->smem_ops = &msm_vidc_smem_ops; + inst->rc_type = RATE_CONTROL_OFF; + inst->dpb_extra_binfo = NULL; + + for (i = SESSION_MSG_INDEX(SESSION_MSG_START); + i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) { + init_completion(&inst->completions[i]); + } + + if (session_type == MSM_VIDC_DECODER) { + msm_vdec_inst_init(inst); + rc = msm_vdec_ctrl_init(inst, &msm_vidc_ctrl_ops); + } else if (session_type == MSM_VIDC_ENCODER) { + msm_venc_inst_init(inst); + rc = msm_venc_ctrl_init(inst, &msm_vidc_ctrl_ops); + } else if (session_type == MSM_VIDC_CVP) { + msm_cvp_inst_init(inst); + rc = msm_cvp_ctrl_init(inst, &msm_vidc_ctrl_ops); + } + if (rc) { + dprintk(VIDC_ERR, "Failed control initialization\n"); + goto fail_bufq_capture; + } + + rc = vb2_bufq_init(inst, OUTPUT_MPLANE, session_type); + if (rc) { + dprintk(VIDC_ERR, + "Failed to initialize vb2 queue on capture port\n"); + goto fail_bufq_capture; + } + rc = vb2_bufq_init(inst, INPUT_MPLANE, session_type); + if (rc) { + dprintk(VIDC_ERR, + "Failed to initialize vb2 queue on capture port\n"); + goto fail_bufq_output; + } + + setup_event_queue(inst, &core->vdev[session_type].vdev); + + mutex_lock(&core->lock); + list_add_tail(&inst->list, &core->instances); + mutex_unlock(&core->lock); + + rc = msm_comm_try_state(inst, MSM_VIDC_CORE_INIT_DONE); + if (rc) { + dprintk(VIDC_ERR, + "Failed to move video instance to init state\n"); + goto fail_init; + } + + msm_dcvs_try_enable(inst); + if (msm_comm_check_for_inst_overload(core)) { + dprintk(VIDC_ERR, + "Instance count reached Max limit, rejecting session"); + goto fail_init; + } + + msm_comm_scale_clocks_and_bus(inst); + + inst->debugfs_root = + msm_vidc_debugfs_init_inst(inst, core->debugfs_root); + + if (inst->session_type == MSM_VIDC_CVP) { + rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE); + if (rc) { + dprintk(VIDC_ERR, + "Failed to move video instance to open done state\n"); + goto fail_init; + } + } + + return inst; +fail_init: + mutex_lock(&core->lock); + list_del(&inst->list); + mutex_unlock(&core->lock); + + v4l2_fh_del(&inst->event_handler); + v4l2_fh_exit(&inst->event_handler); + vb2_queue_release(&inst->bufq[INPUT_PORT].vb2_bufq); +fail_bufq_output: + vb2_queue_release(&inst->bufq[OUTPUT_PORT].vb2_bufq); +fail_bufq_capture: + msm_comm_ctrl_deinit(inst); + mutex_destroy(&inst->sync_lock); + mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); + mutex_destroy(&inst->bufq[INPUT_PORT].lock); + mutex_destroy(&inst->lock); + mutex_destroy(&inst->flush_lock); + + DEINIT_MSM_VIDC_LIST(&inst->scratchbufs); + DEINIT_MSM_VIDC_LIST(&inst->persistbufs); + DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq); + DEINIT_MSM_VIDC_LIST(&inst->outputbufs); + DEINIT_MSM_VIDC_LIST(&inst->cvpbufs); + DEINIT_MSM_VIDC_LIST(&inst->registeredbufs); + DEINIT_MSM_VIDC_LIST(&inst->eosbufs); + DEINIT_MSM_VIDC_LIST(&inst->freqs); + DEINIT_MSM_VIDC_LIST(&inst->input_crs); + DEINIT_MSM_VIDC_LIST(&inst->etb_data); + DEINIT_MSM_VIDC_LIST(&inst->fbd_data); + + kfree(inst); + inst = NULL; +err_invalid_core: + return inst; +} +EXPORT_SYMBOL(msm_vidc_open); + +static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst) +{ + struct msm_vidc_buffer *temp, *dummy; + struct getprop_buf *temp_prop, *dummy_prop; + struct list_head *ptr, *next; + enum vidc_ports ports[] = {INPUT_PORT, OUTPUT_PORT}; + int c = 0; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return; + } + + for (c = 0; c < ARRAY_SIZE(ports); ++c) { + enum vidc_ports port = ports[c]; + + mutex_lock(&inst->bufq[port].lock); + list_for_each_safe(ptr, next, + &inst->bufq[port].vb2_bufq.queued_list) { + struct vb2_buffer *vb = container_of(ptr, + struct vb2_buffer, queued_entry); + if (vb->state == VB2_BUF_STATE_ACTIVE) { + vb->planes[0].bytesused = 0; + print_vb2_buffer(VIDC_ERR, "undequeud vb2", + inst, vb); + vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); + } + } + mutex_unlock(&inst->bufq[port].lock); + } + + mutex_lock(&inst->registeredbufs.lock); + list_for_each_entry_safe(temp, dummy, &inst->registeredbufs.list, + list) { + print_vidc_buffer(VIDC_ERR, "undequeud buf", inst, temp); + msm_comm_unmap_vidc_buffer(inst, temp); + list_del(&temp->list); + kref_put_mbuf(temp); + } + mutex_unlock(&inst->registeredbufs.lock); + + msm_comm_free_freq_table(inst); + + msm_comm_free_input_cr_table(inst); + + if (msm_comm_release_scratch_buffers(inst, false)) + dprintk(VIDC_ERR, + "Failed to release scratch buffers\n"); + + if (msm_comm_release_recon_buffers(inst)) + dprintk(VIDC_ERR, + "Failed to release recon buffers\n"); + + if (msm_comm_release_persist_buffers(inst)) + dprintk(VIDC_ERR, + "Failed to release persist buffers\n"); + + if (msm_comm_release_mark_data(inst)) + dprintk(VIDC_ERR, + "Failed to release mark_data buffers\n"); + + msm_comm_release_eos_buffers(inst); + + if (msm_comm_release_dpb_only_buffers(inst, true)) + dprintk(VIDC_ERR, + "Failed to release output buffers\n"); + + if (inst->extradata_handle) + msm_comm_smem_free(inst, inst->extradata_handle); + + mutex_lock(&inst->pending_getpropq.lock); + if (!list_empty(&inst->pending_getpropq.list)) { + dprintk(VIDC_ERR, + "pending_getpropq not empty for instance %pK\n", + inst); + list_for_each_entry_safe(temp_prop, dummy_prop, + &inst->pending_getpropq.list, list) { + kfree(temp_prop->data); + list_del(&temp_prop->list); + kfree(temp_prop); + } + } + mutex_unlock(&inst->pending_getpropq.lock); +} + +int msm_vidc_destroy(struct msm_vidc_inst *inst) +{ + struct msm_vidc_core *core; + int i = 0; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + core = inst->core; + + mutex_lock(&core->lock); + /* inst->list lives in core->instances */ + list_del(&inst->list); + mutex_unlock(&core->lock); + + msm_comm_ctrl_deinit(inst); + + v4l2_fh_del(&inst->event_handler); + v4l2_fh_exit(&inst->event_handler); + + for (i = 0; i < MAX_PORT_NUM; i++) + vb2_queue_release(&inst->bufq[i].vb2_bufq); + + DEINIT_MSM_VIDC_LIST(&inst->scratchbufs); + DEINIT_MSM_VIDC_LIST(&inst->persistbufs); + DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq); + DEINIT_MSM_VIDC_LIST(&inst->outputbufs); + DEINIT_MSM_VIDC_LIST(&inst->cvpbufs); + DEINIT_MSM_VIDC_LIST(&inst->registeredbufs); + DEINIT_MSM_VIDC_LIST(&inst->eosbufs); + DEINIT_MSM_VIDC_LIST(&inst->freqs); + DEINIT_MSM_VIDC_LIST(&inst->input_crs); + DEINIT_MSM_VIDC_LIST(&inst->etb_data); + DEINIT_MSM_VIDC_LIST(&inst->fbd_data); + + mutex_destroy(&inst->sync_lock); + mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); + mutex_destroy(&inst->bufq[INPUT_PORT].lock); + mutex_destroy(&inst->lock); + mutex_destroy(&inst->flush_lock); + + msm_vidc_debugfs_deinit_inst(inst); + + pr_info(VIDC_DBG_TAG "Closed video instance: %pK\n", + "info", inst); + kfree(inst); + return 0; +} + +static void close_helper(struct kref *kref) +{ + struct msm_vidc_inst *inst = container_of(kref, + struct msm_vidc_inst, kref); + + msm_vidc_destroy(inst); +} + +int msm_vidc_close(void *instance) +{ + struct msm_vidc_inst *inst = instance; + int rc = 0; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + /* + * Make sure that HW stop working on these buffers that + * we are going to free. + */ + rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); + if (rc) + dprintk(VIDC_ERR, + "Failed to move inst %pK to rel resource done state\n", + inst); + + /* + * deinit instance after REL_RES_DONE to ensure hardware + * released all buffers. + */ + if (inst->session_type == MSM_VIDC_CVP) + msm_cvp_inst_deinit(inst); + + /* clean up preprocess if not done already */ + if (is_encode_session(inst)) + msm_vidc_unprepare_preprocess(inst); + + msm_vidc_cleanup_instance(inst); + + rc = msm_comm_try_state(inst, MSM_VIDC_CORE_UNINIT); + if (rc) { + dprintk(VIDC_ERR, + "Failed to move inst %pK to uninit state\n", inst); + rc = msm_comm_force_cleanup(inst); + } + + msm_comm_session_clean(inst); + + kref_put(&inst->kref, close_helper); + return 0; +} +EXPORT_SYMBOL(msm_vidc_close); + +int msm_vidc_suspend(int core_id) +{ + return msm_comm_suspend(core_id); +} +EXPORT_SYMBOL(msm_vidc_suspend); + diff --git a/msm/vidc/msm_vidc.h b/msm/vidc/msm_vidc.h new file mode 100644 index 000000000000..44ea7c257ce1 --- /dev/null +++ b/msm/vidc/msm_vidc.h @@ -0,0 +1,135 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef _MSM_VIDC_H_ +#define _MSM_VIDC_H_ + +#include +#include +#include +#include +#include +#include + +#define HAL_BUFFER_MAX 0xe + +#define V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 22) +enum v4l2_mpeg_vidc_video_decoder_multi_stream { + V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY = 0, + V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY = 1, +}; + +enum smem_type { + SMEM_DMA = 1, +}; + +enum smem_prop { + SMEM_UNCACHED = 0x1, + SMEM_CACHED = 0x2, + SMEM_SECURE = 0x4, + SMEM_ADSP = 0x8, +}; + +/* NOTE: if you change this enum you MUST update the + * "buffer-type-tz-usage-table" for any affected target + * in arch/arm/boot/dts/.dtsi + */ +enum hal_buffer { + HAL_BUFFER_NONE = 0x0, + HAL_BUFFER_INPUT = 0x1, + HAL_BUFFER_OUTPUT = 0x2, + HAL_BUFFER_OUTPUT2 = 0x4, + HAL_BUFFER_EXTRADATA_INPUT = 0x8, + HAL_BUFFER_EXTRADATA_OUTPUT = 0x10, + HAL_BUFFER_EXTRADATA_OUTPUT2 = 0x20, + HAL_BUFFER_INTERNAL_SCRATCH = 0x40, + HAL_BUFFER_INTERNAL_SCRATCH_1 = 0x80, + HAL_BUFFER_INTERNAL_SCRATCH_2 = 0x100, + HAL_BUFFER_INTERNAL_PERSIST = 0x200, + HAL_BUFFER_INTERNAL_PERSIST_1 = 0x400, + HAL_BUFFER_INTERNAL_CMD_QUEUE = 0x800, + HAL_BUFFER_INTERNAL_RECON = 0x1000, +}; + +struct dma_mapping_info { + struct device *dev; + struct iommu_domain *domain; + struct sg_table *table; + struct dma_buf_attachment *attach; + struct dma_buf *buf; + void *cb_info; +}; + +struct msm_smem { + u32 refcount; + int fd; + void *dma_buf; + void *kvaddr; + u32 device_addr; + dma_addr_t dma_handle; + unsigned int offset; + unsigned int size; + unsigned long flags; + enum hal_buffer buffer_type; + struct dma_mapping_info mapping_info; +}; + +enum smem_cache_ops { + SMEM_CACHE_CLEAN, + SMEM_CACHE_INVALIDATE, + SMEM_CACHE_CLEAN_INVALIDATE, +}; + +enum core_id { + MSM_VIDC_CORE_VENUS = 0, + MSM_VIDC_CORE_Q6, + MSM_VIDC_CORES_MAX, +}; +enum session_type { + MSM_VIDC_ENCODER = 0, + MSM_VIDC_DECODER, + MSM_VIDC_CVP, + MSM_VIDC_UNKNOWN, + MSM_VIDC_MAX_DEVICES = MSM_VIDC_UNKNOWN, +}; + +union msm_v4l2_cmd { + struct v4l2_decoder_cmd dec; + struct v4l2_encoder_cmd enc; +}; + +void *msm_vidc_open(int core_id, int session_type); +int msm_vidc_close(void *instance); +int msm_vidc_suspend(int core_id); +int msm_vidc_querycap(void *instance, struct v4l2_capability *cap); +int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f); +int msm_vidc_s_fmt(void *instance, struct v4l2_format *f); +int msm_vidc_g_fmt(void *instance, struct v4l2_format *f); +int msm_vidc_s_ctrl(void *instance, struct v4l2_control *a); +int msm_vidc_s_ext_ctrl(void *instance, struct v4l2_ext_controls *a); +int msm_vidc_g_ext_ctrl(void *instance, struct v4l2_ext_controls *a); +int msm_vidc_g_ctrl(void *instance, struct v4l2_control *a); +int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b); +int msm_vidc_release_buffer(void *instance, int buffer_type, + unsigned int buffer_index); +int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b); +int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b); +int msm_vidc_streamon(void *instance, enum v4l2_buf_type i); +int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *ctrl); +int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i); +int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd); +int msm_vidc_poll(void *instance, struct file *filp, + struct poll_table_struct *pt); +int msm_vidc_subscribe_event(void *instance, + const struct v4l2_event_subscription *sub); +int msm_vidc_unsubscribe_event(void *instance, + const struct v4l2_event_subscription *sub); +int msm_vidc_dqevent(void *instance, struct v4l2_event *event); +int msm_vidc_g_crop(void *instance, struct v4l2_crop *a); +int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize); +int msm_vidc_private(void *vidc_inst, unsigned int cmd, + struct msm_vidc_arg *arg); +#endif diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c new file mode 100644 index 000000000000..116df605866b --- /dev/null +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -0,0 +1,1715 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include "msm_vidc_debug.h" +#include "msm_vidc_common.h" +#include "msm_vidc_buffer_calculations.h" +#include "msm_vidc_clocks.h" + +#define MIN_NUM_THUMBNAIL_MODE_INPUT_BUFFERS MIN_NUM_INPUT_BUFFERS +#define MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS MIN_NUM_OUTPUT_BUFFERS +#define MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS_VP9 8 + +/* extra o/p buffers in case of encoder dcvs */ +#define DCVS_ENC_EXTRA_INPUT_BUFFERS 4 + +/* extra o/p buffers in case of decoder dcvs */ +#define DCVS_DEC_EXTRA_OUTPUT_BUFFERS 4 + +#define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_WIDTH 32 +#define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_HEIGHT 8 +#define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_UV_TILE_WIDTH 16 +#define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_UV_TILE_HEIGHT 8 +#define HFI_COLOR_FORMAT_YUV420_TP10_UBWC_Y_TILE_WIDTH 48 +#define HFI_COLOR_FORMAT_YUV420_TP10_UBWC_Y_TILE_HEIGHT 4 +#define BUFFER_ALIGNMENT_4096_BYTES 4096 +#define VENUS_METADATA_STRIDE_MULTIPLE 64 +#define VENUS_METADATA_HEIGHT_MULTIPLE 16 +#define HFI_UBWC_CALC_METADATA_PLANE_STRIDE \ + ((metadataStride, width, metadataStrideMultiple, tileWidthInPels) \ + metadataStride = ALIGN(((width + (tileWidthInPels - 1)) / \ + tileWidthInPels), metadataStrideMultiple)) +#define HFI_UBWC_METADATA_PLANE_BUFHEIGHT \ + ((metadataBufHeight, height, metadataHeightMultiple, tileHeightInPels) \ + metadataBufHeight = ALIGN(((height + (tileHeightInPels - 1)) / \ + tileHeightInPels), metadataHeightMultiple)) +#define HFI_UBWC_METADATA_PLANE_BUFFER_SIZE \ + ((buffersize, MetadataStride, MetadataBufHeight) \ + buffersize = ALIGN(MetadataStride * MetadataBufHeight, \ + BUFFER_ALIGNMENT_4096_BYTES)) +#define HFI_UBWC_UV_METADATA_PLANE_STRIDE \ + ((metadataStride, width, metadataStrideMultiple, tileWidthInPels) \ + metadataStride = ALIGN(((((width + 1) >> 1) + \ + (tileWidthInPels - 1)) / tileWidthInPels), \ + metadataStrideMultiple)) +#define HFI_UBWC_UV_METADATA_PLANE_BUFHEIGHT \ + ((metadataBufHeight, height, metadataHeightMultiple, tileHeightInPels) \ + metadataBufHeight = ALIGN(((((height + 1) >> 1) + \ + (tileHeightInPels - 1)) / tileHeightInPels), \ + metadataHeightMultiple)) + +#define BUFFER_ALIGNMENT_SIZE(x) x + +#define VENUS_DMA_ALIGNMENT BUFFER_ALIGNMENT_SIZE(256) + +#define NUM_OF_VPP_PIPES 4 +#define MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 64 +#define MAX_FE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE 64 +#define MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE 64 +#define MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE 640 +#define MAX_FE_NBR_DATA_CB_LINE_BUFFER_SIZE 320 +#define MAX_FE_NBR_DATA_CR_LINE_BUFFER_SIZE 320 + +#define MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE (128 / 8) +#define MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE (128 / 8) +#define MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE (128 / 8) + +#define MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE (64 * 2 * 3) +#define MAX_PE_NBR_DATA_LCU32_LINE_BUFFER_SIZE (32 * 2 * 3) +#define MAX_PE_NBR_DATA_LCU16_LINE_BUFFER_SIZE (16 * 2 * 3) + +#define MAX_TILE_COLUMNS 32 /* 8K/256 */ + +#define NUM_HW_PIC_BUF 10 +#define BIN_BUFFER_THRESHOLD (1280 * 736) +#define H264D_MAX_SLICE 1800 +#define SIZE_H264D_BUFTAB_T 256 // sizeof(h264d_buftab_t) aligned to 256 +#define SIZE_H264D_HW_PIC_T (1 << 11) // sizeof(h264d_hw_pic_t) 32 aligned +#define SIZE_H264D_BSE_CMD_PER_BUF (32 * 4) +#define SIZE_H264D_VPP_CMD_PER_BUF 512 + +// Line Buffer definitions +/* one for luma and 1/2 for each chroma */ +#define SIZE_H264D_LB_FE_TOP_DATA(width, height) \ + (MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE * \ + ALIGN(width, 16) * 3) + +#define SIZE_H264D_LB_FE_TOP_CTRL(width, height) \ + (MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * \ + ((width + 15) >> 4)) + +#define SIZE_H264D_LB_FE_LEFT_CTRL(width, height) \ + (MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * \ + ((height + 15) >> 4)) + +#define SIZE_H264D_LB_SE_TOP_CTRL(width, height) \ + (MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * \ + ((width + 15) >> 4)) + +#define SIZE_H264D_LB_SE_LEFT_CTRL(width, height) \ + (MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * \ + ((height + 15) >> 4)) + +#define SIZE_H264D_LB_PE_TOP_DATA(width, height) \ + (MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE * \ + ((width + 15) >> 4)) + +#define SIZE_H264D_LB_VSP_TOP(width, height) \ + ((((width + 15) >> 4) << 7)) + +#define SIZE_H264D_LB_RECON_DMA_METADATA_WR(width, height) \ + (ALIGN(height, 8) * 32) + +#define SIZE_H264D_QP(width, height) \ + (((width + 63) >> 6) * ((height + 63) >> 6) * 128) + +#define SIZE_HW_PIC(sizePerBuf) \ + (NUM_HW_PIC_BUF * sizePerBuf) + +#define H264_CABAC_HDR_RATIO_HD_TOT_NUM 1 /* 0.25 */ +#define H264_CABAC_HDR_RATIO_HD_TOT_DEN 4 +#define H264_CABAC_RES_RATIO_HD_TOT_NUM 3 /* 0.75 */ +#define H264_CABAC_RES_RATIO_HD_TOT_DEN 4 +/* + * some content need more bin buffer, but limit buffer + * size for high resolution + */ + + +#define NUM_SLIST_BUF_H264 (256 + 32) +#define SIZE_SLIST_BUF_H264 512 + +#define LCU_MAX_SIZE_PELS 64 +#define LCU_MIN_SIZE_PELS 16 + +#define H265D_MAX_SLICE 600 +#define SIZE_H265D_HW_PIC_T SIZE_H264D_HW_PIC_T +#define SIZE_H265D_BSE_CMD_PER_BUF (16 * sizeof(u32)) +#define SIZE_H265D_VPP_CMD_PER_BUF 256 + +#define SIZE_H265D_LB_FE_TOP_DATA(width, height) \ + (MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE * \ + (ALIGN(width, 64) + 8) * 2) + +#define SIZE_H265D_LB_FE_TOP_CTRL(width, height) \ + (MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * \ + (ALIGN(width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) + +#define SIZE_H265D_LB_FE_LEFT_CTRL(width, height) \ + (MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * \ + (ALIGN(height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) + +#define SIZE_H265D_LB_SE_TOP_CTRL(width, height) \ + ((LCU_MAX_SIZE_PELS / 8 * (128 / 8)) * \ + ((width + 15) >> 4)) + +#define SIZE_H265D_LB_SE_LEFT_CTRL(width, height) \ + (max(((height + 16 - 1) / 8) * MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE,\ + max(((height + 32 - 1) / 8) * MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE, \ + ((height + 64 - 1) / 8) * MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE))) + +#define SIZE_H265D_LB_PE_TOP_DATA(width, height) \ + (MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE * \ + (ALIGN(width, LCU_MIN_SIZE_PELS) / LCU_MIN_SIZE_PELS)) + +#define SIZE_H265D_LB_VSP_TOP(width, height) \ + (((width + 63) >> 6) * 128) + +#define SIZE_H265D_LB_VSP_LEFT(width, height) \ + (((height + 63) >> 6) * 128) + +#define SIZE_H265D_LB_RECON_DMA_METADATA_WR(width, height) \ + SIZE_H264D_LB_RECON_DMA_METADATA_WR(width, height) + +#define SIZE_H265D_QP(width, height) SIZE_H264D_QP(width, height) + +#define H265_CABAC_HDR_RATIO_HD_TOT_NUM 1 +#define H265_CABAC_HDR_RATIO_HD_TOT_DEN 2 +#define H265_CABAC_RES_RATIO_HD_TOT_NUM 1 +#define H265_CABAC_RES_RATIO_HD_TOT_DEN 2 +/* + * some content need more bin buffer, but limit buffer size + * for high resolution + */ + +#define SIZE_SLIST_BUF_H265 (1 << 10) +#define NUM_SLIST_BUF_H265 (80 + 20) +#define H265_NUM_TILE_COL 32 +#define H265_NUM_TILE_ROW 128 +#define H265_NUM_TILE (H265_NUM_TILE_ROW * H265_NUM_TILE_COL + 1) + +#define SIZE_VPXD_LB_FE_LEFT_CTRL(width, height) \ + max(((height + 15) >> 4) * MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE, \ + max(((height + 31) >> 5) * MAX_FE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE, \ + ((height + 63) >> 6) * MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE)) +#define SIZE_VPXD_LB_FE_TOP_CTRL(width, height) \ + (((ALIGN(width, 64) + 8) * 10 * 2)) /* + small line */ +#define SIZE_VPXD_LB_SE_TOP_CTRL(width, height) \ + (((width + 15) >> 4) * MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE) +#define SIZE_VPXD_LB_SE_LEFT_CTRL(width, height) \ + max(((height + 15) >> 4) * MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE, \ + max(((height + 31) >> 5) * MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE, \ + ((height + 63) >> 6) * MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE)) +#define SIZE_VPXD_LB_RECON_DMA_METADATA_WR(width, height) \ + ALIGN((ALIGN(height, 8) / (4 / 2)) * 64, BUFFER_ALIGNMENT_SIZE(32)) +#define SIZE_VP8D_LB_FE_TOP_DATA(width, height) \ + ((ALIGN(width, 16) + 8) * 10 * 2) +#define SIZE_VP9D_LB_FE_TOP_DATA(width, height) \ + ((ALIGN(ALIGN(width, 8), 64) + 8) * 10 * 2) +#define SIZE_VP8D_LB_PE_TOP_DATA(width, height) \ + ((ALIGN(width, 16) >> 4) * 64) +#define SIZE_VP9D_LB_PE_TOP_DATA(width, height) \ + ((ALIGN(ALIGN(width, 8), 64) >> 6) * 176) +#define SIZE_VP8D_LB_VSP_TOP(width, height) \ + (((ALIGN(width, 16) >> 4) * 64 / 2) + 256) +#define SIZE_VP9D_LB_VSP_TOP(width, height) \ + (((ALIGN(ALIGN(width, 8), 64) >> 6) * 64 * 8) + 256) + + +#define HFI_IRIS2_VP9D_COMV_SIZE \ + ((((8192 + 63) >> 6) * ((4320 + 63) >> 6) * 8 * 8 * 2 * 8)) + +#define VPX_DECODER_FRAME_CONCURENCY_LVL 2 +#define VPX_DECODER_FRAME_BIN_HDR_BUDGET_RATIO_NUM 1 +#define VPX_DECODER_FRAME_BIN_HDR_BUDGET_RATIO_DEN 2 +#define VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO_NUM 3 +#define VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO_DEN 2 + +#define VP8_NUM_FRAME_INFO_BUF (5 + 1) +#define VP9_NUM_FRAME_INFO_BUF (8 + 2 + 1 + 8) +#define VP8_NUM_PROBABILITY_TABLE_BUF (VP8_NUM_FRAME_INFO_BUF) +#define VP9_NUM_PROBABILITY_TABLE_BUF (VP9_NUM_FRAME_INFO_BUF + 4) +#define VP8_PROB_TABLE_SIZE 3840 +#define VP9_PROB_TABLE_SIZE 3840 + +#define VP9_UDC_HEADER_BUF_SIZE (3 * 128) +#define MAX_SUPERFRAME_HEADER_LEN (34) +#define CCE_TILE_OFFSET_SIZE ALIGN(32 * 4 * 4, BUFFER_ALIGNMENT_SIZE(32)) + +#define QMATRIX_SIZE (sizeof(u32) * 128 + 256) +#define MP2D_QPDUMP_SIZE 115200 + +#define HFI_IRIS2_ENC_PERSIST_SIZE 102400 + +#define HFI_MAX_COL_FRAME 6 +#define HFI_VENUS_VENC_TRE_WB_BUFF_SIZE (65 << 4) // bytes +#define HFI_VENUS_VENC_DB_LINE_BUFF_PER_MB 512 +#define HFI_VENUS_VPPSG_MAX_REGISTERS 2048 +#define HFI_VENUS_WIDTH_ALIGNMENT 128 +#define HFI_VENUS_WIDTH_TEN_BIT_ALIGNMENT 192 +#define HFI_VENUS_HEIGHT_ALIGNMENT 32 + +#define SYSTEM_LAL_TILE10 192 +#define NUM_MBS_720P (((1280 + 15) >> 4) * ((720 + 15) >> 4)) +#define NUM_MBS_4k (((4096 + 15) >> 4) * ((2304 + 15) >> 4)) +#define MB_SIZE_IN_PIXEL (16 * 16) +#define HDR10PLUS_PAYLOAD_SIZE 1024 +#define HDR10_HIST_EXTRADATA_SIZE 4096 + +static inline u32 calculate_h264d_scratch_size(struct msm_vidc_inst *inst, + u32 width, u32 height, bool is_interlaced); +static inline u32 calculate_h265d_scratch_size(struct msm_vidc_inst *inst, + u32 width, u32 height, bool is_interlaced); +static inline u32 calculate_vpxd_scratch_size(struct msm_vidc_inst *inst, + u32 width, u32 height, bool is_interlaced); +static inline u32 calculate_mpeg2d_scratch_size(struct msm_vidc_inst *inst, + u32 width, u32 height, bool is_interlaced); + +static inline u32 calculate_enc_scratch_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 work_mode, u32 lcu_size); +static inline u32 calculate_h264e_scratch_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 work_mode); +static inline u32 calculate_h265e_scratch_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 work_mode); +static inline u32 calculate_vp8e_scratch_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 work_mode); + +static inline u32 calculate_h264d_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled); +static inline u32 calculate_h265d_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled); +static inline u32 calculate_vp8d_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled); +static inline u32 calculate_vp9d_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled); +static inline u32 calculate_mpeg2d_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled); + +static inline u32 calculate_h264e_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 num_ref, bool ten_bit); +static inline u32 calculate_h265e_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 num_ref, bool ten_bit); +static inline u32 calculate_vp8e_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 num_ref, bool ten_bit); + +static inline u32 calculate_enc_scratch2_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 num_ref, bool ten_bit); + +static inline u32 calculate_enc_persist_size(void); + +static inline u32 calculate_h264d_persist1_size(void); +static inline u32 calculate_h265d_persist1_size(void); +static inline u32 calculate_vp8d_persist1_size(void); +static inline u32 calculate_vp9d_persist1_size(void); +static inline u32 calculate_mpeg2d_persist1_size(void); + +static struct msm_vidc_dec_buff_size_calculators h264d_calculators = { + .calculate_scratch_size = calculate_h264d_scratch_size, + .calculate_scratch1_size = calculate_h264d_scratch1_size, + .calculate_persist1_size = calculate_h264d_persist1_size, +}; + +static struct msm_vidc_dec_buff_size_calculators h265d_calculators = { + .calculate_scratch_size = calculate_h265d_scratch_size, + .calculate_scratch1_size = calculate_h265d_scratch1_size, + .calculate_persist1_size = calculate_h265d_persist1_size, +}; + +static struct msm_vidc_dec_buff_size_calculators vp8d_calculators = { + .calculate_scratch_size = calculate_vpxd_scratch_size, + .calculate_scratch1_size = calculate_vp8d_scratch1_size, + .calculate_persist1_size = calculate_vp8d_persist1_size, +}; + +static struct msm_vidc_dec_buff_size_calculators vp9d_calculators = { + .calculate_scratch_size = calculate_vpxd_scratch_size, + .calculate_scratch1_size = calculate_vp9d_scratch1_size, + .calculate_persist1_size = calculate_vp9d_persist1_size, +}; + +static struct msm_vidc_dec_buff_size_calculators mpeg2d_calculators = { + .calculate_scratch_size = calculate_mpeg2d_scratch_size, + .calculate_scratch1_size = calculate_mpeg2d_scratch1_size, + .calculate_persist1_size = calculate_mpeg2d_persist1_size, +}; + +static struct msm_vidc_enc_buff_size_calculators h264e_calculators = { + .calculate_scratch_size = calculate_h264e_scratch_size, + .calculate_scratch1_size = calculate_h264e_scratch1_size, + .calculate_scratch2_size = calculate_enc_scratch2_size, + .calculate_persist_size = calculate_enc_persist_size, +}; + +static struct msm_vidc_enc_buff_size_calculators h265e_calculators = { + .calculate_scratch_size = calculate_h265e_scratch_size, + .calculate_scratch1_size = calculate_h265e_scratch1_size, + .calculate_scratch2_size = calculate_enc_scratch2_size, + .calculate_persist_size = calculate_enc_persist_size, +}; + +static struct msm_vidc_enc_buff_size_calculators vp8e_calculators = { + .calculate_scratch_size = calculate_vp8e_scratch_size, + .calculate_scratch1_size = calculate_vp8e_scratch1_size, + .calculate_scratch2_size = calculate_enc_scratch2_size, + .calculate_persist_size = calculate_enc_persist_size, +}; + +int msm_vidc_get_decoder_internal_buffer_sizes(struct msm_vidc_inst *inst) +{ + struct msm_vidc_dec_buff_size_calculators *dec_calculators; + u32 width, height, i, out_min_count; + struct v4l2_format *f; + + if (!inst) { + dprintk(VIDC_ERR, "Instance is null!"); + return -EINVAL; + } + + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + switch (f->fmt.pix_mp.pixelformat) { + case V4L2_PIX_FMT_H264: + dec_calculators = &h264d_calculators; + break; + case V4L2_PIX_FMT_HEVC: + dec_calculators = &h265d_calculators; + break; + case V4L2_PIX_FMT_VP8: + dec_calculators = &vp8d_calculators; + break; + case V4L2_PIX_FMT_VP9: + dec_calculators = &vp9d_calculators; + break; + case V4L2_PIX_FMT_MPEG2: + dec_calculators = &mpeg2d_calculators; + break; + default: + dprintk(VIDC_ERR, + "Invalid pix format. Internal buffer cal not defined : %x ", + f->fmt.pix_mp.pixelformat); + return -EINVAL; + } + + width = f->fmt.pix_mp.width; + height = f->fmt.pix_mp.height; + for (i = 0; i < HAL_BUFFER_MAX; i++) { + struct hal_buffer_requirements *curr_req; + bool valid_buffer_type = false; + + curr_req = &inst->buff_req.buffer[i]; + if (curr_req->buffer_type == HAL_BUFFER_INTERNAL_SCRATCH) { + bool is_interlaced = false; + + is_interlaced = (inst->pic_struct == + MSM_VIDC_PIC_STRUCT_MAYBE_INTERLACED); + curr_req->buffer_size = + dec_calculators->calculate_scratch_size( + inst, width, height, is_interlaced); + valid_buffer_type = true; + } else if (curr_req->buffer_type == + HAL_BUFFER_INTERNAL_SCRATCH_1) { + struct msm_vidc_format *fmt = NULL; + + fmt = &inst->fmts[OUTPUT_PORT]; + out_min_count = fmt->count_min; + curr_req->buffer_size = + dec_calculators->calculate_scratch1_size( + inst, width, height, out_min_count, + is_secondary_output_mode(inst)); + valid_buffer_type = true; + } else if (curr_req->buffer_type == + HAL_BUFFER_INTERNAL_PERSIST_1) { + curr_req->buffer_size = + dec_calculators->calculate_persist1_size(); + valid_buffer_type = true; + } + + if (valid_buffer_type) { + curr_req->buffer_alignment = 256; + curr_req->buffer_count_actual = + curr_req->buffer_count_min = + curr_req->buffer_count_min_host = 1; + } + } + return 0; +} + +int msm_vidc_get_num_ref_frames(struct msm_vidc_inst *inst) +{ + int num_ref = 1; + int num_bframes = -1, ltr_count = -1, num_hp_layers; + struct v4l2_ctrl *bframe_ctrl; + struct v4l2_ctrl *ltr_ctrl; + struct v4l2_ctrl *layer_ctrl; + u32 codec; + + bframe_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); + num_bframes = bframe_ctrl->val; + if (num_bframes > 0) + num_ref = num_bframes + 1; + + ltr_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); + ltr_count = ltr_ctrl->val; + /* B and LTR can't be at same time */ + if (ltr_count > 0) + num_ref = num_ref + ltr_count; + + layer_ctrl = get_ctrl(inst, + V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); + num_hp_layers = layer_ctrl->val; + codec = get_v4l2_codec(inst); + if (num_hp_layers > 0) { + /* LTR and B - frame not supported with hybrid HP */ + if (inst->hybrid_hp) + num_ref = (num_hp_layers - 1); + else if (codec == V4L2_PIX_FMT_HEVC) + num_ref = ((num_hp_layers + 1) / 2) + ltr_count; + else if ((codec == V4L2_PIX_FMT_H264) && (num_hp_layers <= 4)) + num_ref = ((1 << (num_hp_layers - 1)) - 1) + ltr_count; + else + num_ref = ((num_hp_layers + 1) / 2) + ltr_count; + } + return num_ref; +} + +int msm_vidc_get_encoder_internal_buffer_sizes(struct msm_vidc_inst *inst) +{ + struct msm_vidc_enc_buff_size_calculators *enc_calculators; + u32 width, height, i, num_ref; + bool is_tenbit = false; + int num_bframes; + struct v4l2_ctrl *bframe; + struct v4l2_format *f; + + if (!inst) { + dprintk(VIDC_ERR, "Instance is null!"); + return -EINVAL; + } + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + switch (f->fmt.pix_mp.pixelformat) { + case V4L2_PIX_FMT_H264: + enc_calculators = &h264e_calculators; + break; + case V4L2_PIX_FMT_HEVC: + enc_calculators = &h265e_calculators; + break; + case V4L2_PIX_FMT_VP8: + enc_calculators = &vp8e_calculators; + break; + default: + dprintk(VIDC_ERR, + "Invalid pix format. Internal buffer cal not defined : %x ", + f->fmt.pix_mp.pixelformat); + return -EINVAL; + } + + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + width = f->fmt.pix_mp.width; + height = f->fmt.pix_mp.height; + bframe = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); + num_bframes = bframe->val; + if (num_bframes < 0) { + dprintk(VIDC_ERR, + "%s: get num bframe failed\n", __func__); + return -EINVAL; + } + + num_ref = msm_vidc_get_num_ref_frames(inst); + is_tenbit = (inst->bit_depth == MSM_VIDC_BIT_DEPTH_10); + + for (i = 0; i < HAL_BUFFER_MAX; i++) { + struct hal_buffer_requirements *curr_req; + bool valid_buffer_type = false; + + curr_req = &inst->buff_req.buffer[i]; + if (curr_req->buffer_type == HAL_BUFFER_INTERNAL_SCRATCH) { + curr_req->buffer_size = + enc_calculators->calculate_scratch_size( + inst, width, height, + inst->clk_data.work_mode); + valid_buffer_type = true; + } else if (curr_req->buffer_type == + HAL_BUFFER_INTERNAL_SCRATCH_1) { + curr_req->buffer_size = + enc_calculators->calculate_scratch1_size( + inst, width, height, num_ref, + is_tenbit); + valid_buffer_type = true; + } else if (curr_req->buffer_type == + HAL_BUFFER_INTERNAL_SCRATCH_2) { + curr_req->buffer_size = + enc_calculators->calculate_scratch2_size( + inst, width, height, num_ref, + is_tenbit); + valid_buffer_type = true; + } else if (curr_req->buffer_type == + HAL_BUFFER_INTERNAL_PERSIST) { + curr_req->buffer_size = + enc_calculators->calculate_persist_size(); + } + + if (valid_buffer_type) { + curr_req->buffer_alignment = 256; + curr_req->buffer_count_actual = + curr_req->buffer_count_min = + curr_req->buffer_count_min_host = 1; + } + } + return 0; +} + +int msm_vidc_calculate_internal_buffer_sizes(struct msm_vidc_inst *inst) +{ + if (!inst) { + dprintk(VIDC_ERR, "Instance is null!"); + return -EINVAL; + } + + if (inst->session_type == MSM_VIDC_DECODER) + return msm_vidc_get_decoder_internal_buffer_sizes(inst); + else if (inst->session_type == MSM_VIDC_ENCODER) + return msm_vidc_get_encoder_internal_buffer_sizes(inst); + + return 0; +} + +void msm_vidc_init_buffer_size_calculators(struct msm_vidc_inst *inst) +{ + struct msm_vidc_core *core; + + if (!inst) + return; + + inst->buffer_size_calculators = NULL; + core = inst->core; + + /* Change this to IRIS2 when ready */ + if (core->platform_data->vpu_ver == VPU_VERSION_IRIS2) + inst->buffer_size_calculators = + msm_vidc_calculate_internal_buffer_sizes; +} + +int msm_vidc_init_buffer_count(struct msm_vidc_inst *inst) +{ + struct msm_vidc_format *fmt; + int extra_buff_count = 0; + u32 codec, input_min_count = 4, output_min_count = 4; + + if (!is_decode_session(inst) && !is_encode_session(inst)) + return 0; + + codec = get_v4l2_codec(inst); + /* + * Update input buff counts + * Extradata uses same count as input port + */ + fmt = &inst->fmts[INPUT_PORT]; + extra_buff_count = msm_vidc_get_extra_buff_count(inst, + HAL_BUFFER_INPUT); + fmt->count_min = input_min_count; + /* batching needs minimum batch size count of input buffers */ + if (inst->core->resources.decode_batching && + is_decode_session(inst) && + fmt->count_min < inst->batch.size) + fmt->count_min = inst->batch.size; + fmt->count_min_host = fmt->count_actual = + fmt->count_min + extra_buff_count; + + dprintk(VIDC_DBG, "%s: %x : input min %d min_host %d actual %d\n", + __func__, hash32_ptr(inst->session), + fmt->count_min, fmt->count_min_host, fmt->count_actual); + + /* Update output buff count: Changes for decoder based on codec */ + if (is_decode_session(inst)) { + switch (codec) { + case V4L2_PIX_FMT_MPEG2: + output_min_count = 6; + break; + case V4L2_PIX_FMT_H264: + output_min_count = 8; + break; + case V4L2_PIX_FMT_HEVC: + output_min_count = 8; + break; + case V4L2_PIX_FMT_VP8: + output_min_count = 6; + break; + case V4L2_PIX_FMT_VP9: + output_min_count = 11; + break; + } + } + fmt = &inst->fmts[OUTPUT_PORT]; + extra_buff_count = msm_vidc_get_extra_buff_count(inst, + HAL_BUFFER_OUTPUT); + fmt->count_min = output_min_count; + fmt->count_min_host = fmt->count_actual = + fmt->count_min + extra_buff_count; + + dprintk(VIDC_DBG, "%s: %x : output min %d min_host %d actual %d\n", + __func__, hash32_ptr(inst->session), + fmt->count_min, fmt->count_min_host, fmt->count_actual); + + return 0; +} +u32 msm_vidc_set_buffer_count_for_thumbnail(struct msm_vidc_inst *inst) +{ + struct msm_vidc_format *fmt; + + fmt = &inst->fmts[INPUT_PORT]; + fmt->count_min = MIN_NUM_THUMBNAIL_MODE_INPUT_BUFFERS; + fmt->count_min_host = MIN_NUM_THUMBNAIL_MODE_INPUT_BUFFERS; + fmt->count_actual = MIN_NUM_THUMBNAIL_MODE_INPUT_BUFFERS; + + fmt = &inst->fmts[OUTPUT_PORT]; + /* VP9 super frame requires multiple frames decoding */ + if (get_v4l2_codec(inst) == V4L2_PIX_FMT_VP9) { + fmt->count_min = MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS_VP9; + fmt->count_min_host = + MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS_VP9; + fmt->count_actual = + MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS_VP9; + } else { + fmt->count_min = MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS; + fmt->count_min_host = MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS; + fmt->count_actual = MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS; + } + return 0; +} + +int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, + enum hal_buffer buffer_type) +{ + unsigned int count = 0; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s Invalid args\n", __func__); + return 0; + } + /* + * no extra buffers for thumbnail session because + * neither dcvs nor batching will be enabled + */ + if (is_thumbnail_session(inst)) + return 0; + + /* Add DCVS extra buffer count */ + if (inst->core->resources.dcvs) { + if (is_decode_session(inst) && + buffer_type == HAL_BUFFER_OUTPUT) { + count += DCVS_DEC_EXTRA_OUTPUT_BUFFERS; + } else if ((is_encode_session(inst) && + buffer_type == HAL_BUFFER_INPUT)) { + count += DCVS_ENC_EXTRA_INPUT_BUFFERS; + } + } + + /* + * if platform supports decode batching ensure minimum + * batch size count of extra buffers added on output port + */ + if (buffer_type == HAL_BUFFER_OUTPUT) { + if (inst->core->resources.decode_batching && + is_decode_session(inst) && + count < inst->batch.size) + count = inst->batch.size; + } + + return count; +} + +u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) +{ + u32 frame_size, num_mbs; + u32 div_factor = 1; + u32 base_res_mbs = NUM_MBS_4k; + struct v4l2_format *f; + + /* + * Decoder input size calculation: + * If clip is 8k buffer size is calculated for 8k : 8k mbs/4 + * For 8k cases we expect width/height to be set always. + * In all other cases size is calculated for 4k: + * 4k mbs for VP8/VP9 and 4k/2 for remaining codecs + */ + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + num_mbs = msm_vidc_get_mbs_per_frame(inst); + if (num_mbs > NUM_MBS_4k) { + div_factor = 4; + base_res_mbs = inst->capability.cap[CAP_MBS_PER_FRAME].max; + } else { + base_res_mbs = NUM_MBS_4k; + if (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_VP9) + div_factor = 1; + else + div_factor = 2; + } + + frame_size = base_res_mbs * MB_SIZE_IN_PIXEL * 3 / 2 / div_factor; + + if (is_secure_session(inst)) { + u32 max_bitrate = inst->capability.cap[CAP_SECURE_BITRATE].max; + + /* + * for secure, calc frame_size based on max bitrate, + * peak bitrate can be 10 times more and + * frame rate assumed to be 30 fps at least + */ + frame_size = (max_bitrate * 10 / 8) / 30; + } + + /* multiply by 10/8 (1.25) to get size for 10 bit case */ + if ((f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_VP9) || + (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_HEVC)) + frame_size = frame_size + (frame_size >> 2); + + if (inst->buffer_size_limit && + (inst->buffer_size_limit < frame_size)) { + frame_size = inst->buffer_size_limit; + dprintk(VIDC_DBG, "input buffer size limited to %d\n", + frame_size); + } else { + dprintk(VIDC_DBG, "set input buffer size to %d\n", + frame_size); + } + + return ALIGN(frame_size, SZ_4K); +} + +u32 msm_vidc_calculate_dec_output_frame_size(struct msm_vidc_inst *inst) +{ + u32 hfi_fmt; + struct v4l2_format *f; + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + hfi_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat); + return VENUS_BUFFER_SIZE(hfi_fmt, f->fmt.pix_mp.width, + f->fmt.pix_mp.height); +} + +u32 msm_vidc_calculate_dec_output_extra_size(struct msm_vidc_inst *inst) +{ + struct v4l2_format *f; + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + return VENUS_EXTRADATA_SIZE(f->fmt.pix_mp.width, f->fmt.pix_mp.height); +} + +u32 msm_vidc_calculate_enc_input_frame_size(struct msm_vidc_inst *inst) +{ + u32 hfi_fmt; + struct v4l2_format *f; + + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + hfi_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat); + return VENUS_BUFFER_SIZE(hfi_fmt, f->fmt.pix_mp.width, + f->fmt.pix_mp.height); +} + +u32 msm_vidc_calculate_enc_output_frame_size(struct msm_vidc_inst *inst) +{ + u32 frame_size; + u32 mbs_per_frame; + u32 width, height; + struct v4l2_format *f; + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + /* + * Encoder output size calculation: 32 Align width/height + * For resolution < 720p : YUVsize * 4 + * For resolution > 720p & <= 4K : YUVsize / 2 + * For resolution > 4k : YUVsize / 4 + * Initially frame_size = YUVsize * 2; + */ + width = ALIGN(f->fmt.pix_mp.width, BUFFER_ALIGNMENT_SIZE(32)); + height = ALIGN(f->fmt.pix_mp.height, BUFFER_ALIGNMENT_SIZE(32)); + mbs_per_frame = NUM_MBS_PER_FRAME(width, height); + frame_size = (width * height * 3); + + if (mbs_per_frame < NUM_MBS_720P) + frame_size = frame_size << 1; + else if (mbs_per_frame <= NUM_MBS_4k) + frame_size = frame_size >> 2; + else + frame_size = frame_size >> 3; + + if ((inst->rc_type == RATE_CONTROL_OFF) || + (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ)) + frame_size = frame_size << 1; + + if (inst->rc_type == RATE_CONTROL_LOSSLESS) + frame_size = (width * height * 6); + + /* For 10-bit cases size = size * 1.25 */ + if (inst->bit_depth == MSM_VIDC_BIT_DEPTH_10) { + frame_size *= 5; + frame_size /= 4; + } + + return ALIGN(frame_size, SZ_4K); +} + +static inline u32 ROI_EXTRADATA_SIZE( + u32 width, u32 height, u32 lcu_size) { + u32 lcu_width = 0; + u32 lcu_height = 0; + u32 n_shift = 0; + + while (lcu_size && !(lcu_size & 0x1)) { + n_shift++; + lcu_size = lcu_size >> 1; + } + lcu_width = (width + (lcu_size - 1)) >> n_shift; + lcu_height = (height + (lcu_size - 1)) >> n_shift; + + return (((lcu_width + 7) >> 3) << 3) * lcu_height * 2; +} + +u32 msm_vidc_calculate_enc_input_extra_size(struct msm_vidc_inst *inst) +{ + u32 size = 0; + u32 extradata_count = 0; + struct v4l2_format *f; + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + /* Add size for default extradata */ + size += sizeof(struct msm_vidc_enc_cvp_metadata_payload); + extradata_count++; + + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_ROI) { + u32 lcu_size = 16; + + if (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_HEVC) + lcu_size = 32; + + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + size += ROI_EXTRADATA_SIZE(f->fmt.pix_mp.width, + f->fmt.pix_mp.height, lcu_size); + extradata_count++; + } + + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_HDR10PLUS) { + size += HDR10PLUS_PAYLOAD_SIZE; + extradata_count++; + } + + /* Add extradata header sizes including EXTRADATA_NONE */ + if (size) + size += sizeof(struct msm_vidc_extradata_header) * + (extradata_count + 1); + + return ALIGN(size, SZ_4K); +} + +u32 msm_vidc_calculate_enc_output_extra_size(struct msm_vidc_inst *inst) +{ + u32 size = 0; + + if (inst->prop.extradata_ctrls & EXTRADATA_ADVANCED) + size += sizeof(struct msm_vidc_metadata_ltr_payload); + + /* Add size for extradata none */ + if (size) + size += sizeof(struct msm_vidc_extradata_header); + + return ALIGN(size, SZ_4K); +} + +static inline u32 size_vpss_lb(u32 width, u32 height) +{ + u32 vpss_4tap_top_buffer_size, vpss_div2_top_buffer_size; + u32 vpss_4tap_left_buffer_size, vpss_div2_left_buffer_size; + u32 opb_wr_top_line_luma_buf_size, opb_wr_top_line_chroma_buf_size; + u32 opb_lb_wr_llb_y_buffer_size, opb_lb_wr_llb_uv_buffer_size; + u32 macrotiling_size; + u32 size = 0; + + vpss_4tap_top_buffer_size = vpss_div2_top_buffer_size = + vpss_4tap_left_buffer_size = vpss_div2_left_buffer_size = 0; + macrotiling_size = 32; + opb_wr_top_line_luma_buf_size = ALIGN(width, macrotiling_size) / + macrotiling_size * 256; + opb_wr_top_line_luma_buf_size = ALIGN(opb_wr_top_line_luma_buf_size, + VENUS_DMA_ALIGNMENT) + (MAX_TILE_COLUMNS - 1) * 256; + opb_wr_top_line_luma_buf_size = max(opb_wr_top_line_luma_buf_size, + (32 * ALIGN(height, 8))); + opb_wr_top_line_chroma_buf_size = opb_wr_top_line_luma_buf_size; + opb_lb_wr_llb_uv_buffer_size = opb_lb_wr_llb_y_buffer_size = + ALIGN((ALIGN(height, 8) / 2) * + 64, BUFFER_ALIGNMENT_SIZE(32)); + size = NUM_OF_VPP_PIPES * 2 * (vpss_4tap_top_buffer_size + + vpss_div2_top_buffer_size) + + 2 * (vpss_4tap_left_buffer_size + + vpss_div2_left_buffer_size) + + opb_wr_top_line_luma_buf_size + + opb_wr_top_line_chroma_buf_size + + opb_lb_wr_llb_uv_buffer_size + + opb_lb_wr_llb_y_buffer_size; + + return size; +} + +static inline u32 hfi_iris2_h264d_comv_size(u32 width, u32 height, + u32 yuv_buf_min_count) +{ + u32 comv_size = 0; + u32 frame_width_in_mbs = ((width + 15) >> 4); + u32 frame_height_in_mbs = ((height + 15) >> 4); + u32 col_mv_aligned_width = (frame_width_in_mbs << 6); + u32 col_zero_aligned_width = (frame_width_in_mbs << 2); + u32 col_zero_size = 0, size_colloc = 0; + + col_mv_aligned_width = ALIGN(col_mv_aligned_width, + BUFFER_ALIGNMENT_SIZE(16)); + col_zero_aligned_width = ALIGN(col_zero_aligned_width, + BUFFER_ALIGNMENT_SIZE(16)); + col_zero_size = col_zero_aligned_width * + ((frame_height_in_mbs + 1) >> 1); + col_zero_size = ALIGN(col_zero_size, BUFFER_ALIGNMENT_SIZE(64)); + col_zero_size <<= 1; + col_zero_size = ALIGN(col_zero_size, BUFFER_ALIGNMENT_SIZE(512)); + size_colloc = col_mv_aligned_width * ((frame_height_in_mbs + 1) >> 1); + size_colloc = ALIGN(size_colloc, BUFFER_ALIGNMENT_SIZE(64)); + size_colloc <<= 1; + size_colloc = ALIGN(size_colloc, BUFFER_ALIGNMENT_SIZE(512)); + size_colloc += (col_zero_size + SIZE_H264D_BUFTAB_T * 2); + comv_size = size_colloc * yuv_buf_min_count; + comv_size += BUFFER_ALIGNMENT_SIZE(512); + + return comv_size; +} + +static inline u32 size_h264d_bse_cmd_buf(u32 height) +{ + u32 aligned_height = ALIGN(height, BUFFER_ALIGNMENT_SIZE(32)); + + return min_t(u32, (((aligned_height + 15) >> 4) * 3 * 4), + H264D_MAX_SLICE) * + SIZE_H264D_BSE_CMD_PER_BUF; +} + +static inline u32 size_h264d_vpp_cmd_buf(u32 height) +{ + u32 aligned_height = ALIGN(height, BUFFER_ALIGNMENT_SIZE(32)); + + return min_t(u32, (((aligned_height + 15) >> 4) * 3 * 4), + H264D_MAX_SLICE) * + SIZE_H264D_VPP_CMD_PER_BUF; +} + +static inline u32 hfi_iris2_h264d_non_comv_size(u32 width, u32 height) +{ + u32 size; + u32 size_bse, size_vpp; + + size_bse = size_h264d_bse_cmd_buf(height); + size_vpp = size_h264d_vpp_cmd_buf(height); + size = ALIGN(size_bse, VENUS_DMA_ALIGNMENT) + + ALIGN(size_vpp, VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_HW_PIC(SIZE_H264D_HW_PIC_T), VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_H264D_LB_FE_TOP_DATA(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_H264D_LB_FE_TOP_CTRL(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_H264D_LB_FE_LEFT_CTRL(width, height), + VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + ALIGN(SIZE_H264D_LB_SE_TOP_CTRL(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_H264D_LB_SE_LEFT_CTRL(width, height), + VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + ALIGN(SIZE_H264D_LB_PE_TOP_DATA(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_H264D_LB_VSP_TOP(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_H264D_LB_RECON_DMA_METADATA_WR(width, height), + VENUS_DMA_ALIGNMENT) * 2 + + ALIGN(SIZE_H264D_QP(width, height), VENUS_DMA_ALIGNMENT); + size = ALIGN(size, VENUS_DMA_ALIGNMENT); + return size; +} + +static inline u32 size_h264d_hw_bin_buffer(u32 width, u32 height) +{ + u32 size_yuv, size_bin_hdr, size_bin_res; + u32 size = 0; + u32 product; + + product = width * height; + size_yuv = (product <= BIN_BUFFER_THRESHOLD) ? + ((BIN_BUFFER_THRESHOLD * 3) >> 1) : + ((product * 3) >> 1); + + size_bin_hdr = size_yuv * H264_CABAC_HDR_RATIO_HD_TOT_NUM / + H264_CABAC_HDR_RATIO_HD_TOT_DEN; + size_bin_res = size_yuv * H264_CABAC_RES_RATIO_HD_TOT_NUM / + H264_CABAC_RES_RATIO_HD_TOT_DEN; + size_bin_hdr = ALIGN(size_bin_hdr, VENUS_DMA_ALIGNMENT); + size_bin_res = ALIGN(size_bin_res, VENUS_DMA_ALIGNMENT); + size = size_bin_hdr + size_bin_res; + return size; +} + +static inline u32 calculate_h264d_scratch_size(struct msm_vidc_inst *inst, + u32 width, u32 height, bool is_interlaced) +{ + u32 aligned_width = ALIGN(width, BUFFER_ALIGNMENT_SIZE(16)); + u32 aligned_height = ALIGN(height, BUFFER_ALIGNMENT_SIZE(16)); + u32 size = 0; + + if (!is_interlaced) { + size = size_h264d_hw_bin_buffer(aligned_width, aligned_height); + size = size * NUM_OF_VPP_PIPES; + } else { + size = 0; + } + + return size; +} + +static inline u32 size_h265d_bse_cmd_buf(u32 width, u32 height) +{ + u32 size; + + size = ALIGN(((ALIGN(width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) + + (ALIGN(height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) * + NUM_HW_PIC_BUF, VENUS_DMA_ALIGNMENT); + size = min_t(u32, size, H265D_MAX_SLICE + 1); + size = 2 * size * SIZE_H265D_BSE_CMD_PER_BUF; + return size; +} + +static inline u32 size_h265d_vpp_cmd_buf(u32 width, u32 height) +{ + u32 size = 0; + + size = ALIGN(( + (ALIGN(width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) + + (ALIGN(height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) * + NUM_HW_PIC_BUF, VENUS_DMA_ALIGNMENT); + size = min_t(u32, size, H265D_MAX_SLICE + 1); + size = ALIGN(size, 4); + size = 2 * size * SIZE_H265D_VPP_CMD_PER_BUF; + + return size; +} + +static inline u32 hfi_iris2_h265d_comv_size(u32 width, u32 height, + u32 yuv_buf_count_min) +{ + u32 size = 0; + + size = ALIGN(((((width + 15) >> 4) * ((height + 15) >> 4)) << 8), + BUFFER_ALIGNMENT_SIZE(512)); + size *= yuv_buf_count_min; + size += BUFFER_ALIGNMENT_SIZE(512); + + return size; +} + +static inline u32 hfi_iris2_h265d_non_comv_size(u32 width, u32 height) +{ + u32 size_bse, size_vpp; + u32 size = 0; + + size_bse = size_h265d_bse_cmd_buf(width, height); + size_vpp = size_h265d_vpp_cmd_buf(width, height); + size = ALIGN(size_bse, VENUS_DMA_ALIGNMENT) + + ALIGN(size_vpp, VENUS_DMA_ALIGNMENT) + + ALIGN(NUM_HW_PIC_BUF * 20 * 22 * 4, VENUS_DMA_ALIGNMENT) + + ALIGN(2 * sizeof(u16) * + (ALIGN(width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) * + (ALIGN(height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_HW_PIC(SIZE_H265D_HW_PIC_T), VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_H265D_LB_FE_TOP_DATA(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_H265D_LB_FE_TOP_CTRL(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_H265D_LB_FE_LEFT_CTRL(width, height), + VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + ALIGN(SIZE_H265D_LB_SE_LEFT_CTRL(width, height), + VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + ALIGN(SIZE_H265D_LB_SE_TOP_CTRL(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_H265D_LB_PE_TOP_DATA(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_H265D_LB_VSP_TOP(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_H265D_LB_VSP_LEFT(width, height), + VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + ALIGN(SIZE_H265D_LB_RECON_DMA_METADATA_WR(width, height), + VENUS_DMA_ALIGNMENT) * 4 + + ALIGN(SIZE_H265D_QP(width, height), VENUS_DMA_ALIGNMENT); + size = ALIGN(size, VENUS_DMA_ALIGNMENT); + return size; +} + +static inline u32 size_h265d_hw_bin_buffer(u32 width, u32 height) +{ + u32 size = 0; + u32 size_yuv, size_bin_hdr, size_bin_res; + u32 product; + + product = width * height; + size_yuv = (product <= BIN_BUFFER_THRESHOLD) ? + ((BIN_BUFFER_THRESHOLD * 3) >> 1) : + ((product * 3) >> 1); + size_bin_hdr = size_yuv * H265_CABAC_HDR_RATIO_HD_TOT_NUM / + H265_CABAC_HDR_RATIO_HD_TOT_DEN; + size_bin_res = size_yuv * H265_CABAC_RES_RATIO_HD_TOT_NUM / + H265_CABAC_RES_RATIO_HD_TOT_DEN; + size_bin_hdr = ALIGN(size_bin_hdr, VENUS_DMA_ALIGNMENT); + size_bin_res = ALIGN(size_bin_res, VENUS_DMA_ALIGNMENT); + size = size_bin_hdr + size_bin_res; + + return size; +} + +static inline u32 calculate_h265d_scratch_size(struct msm_vidc_inst *inst, + u32 width, u32 height, bool is_interlaced) +{ + u32 aligned_width = ALIGN(width, BUFFER_ALIGNMENT_SIZE(16)); + u32 aligned_height = ALIGN(height, BUFFER_ALIGNMENT_SIZE(16)); + u32 size = 0; + + if (!is_interlaced) { + size = size_h265d_hw_bin_buffer(aligned_width, aligned_height); + size = size * NUM_OF_VPP_PIPES; + } else { + size = 0; + } + + return size; +} + +static inline u32 calculate_vpxd_scratch_size(struct msm_vidc_inst *inst, + u32 width, u32 height, bool is_interlaced) +{ + u32 aligned_width = ALIGN(width, BUFFER_ALIGNMENT_SIZE(16)); + u32 aligned_height = ALIGN(height, BUFFER_ALIGNMENT_SIZE(16)); + u32 size = 0; + u32 size_yuv = aligned_width * aligned_height * 3 / 2; + + if (!is_interlaced) { + /* binbuffer1_size + binbufer2_size */ + u32 binbuffer1_size = 0, binbufer2_size = 0; + + binbuffer1_size = max_t(u32, size_yuv, + ((BIN_BUFFER_THRESHOLD * 3) >> 1)) * + VPX_DECODER_FRAME_CONCURENCY_LVL * + VPX_DECODER_FRAME_BIN_HDR_BUDGET_RATIO_NUM / + VPX_DECODER_FRAME_BIN_HDR_BUDGET_RATIO_DEN; + binbufer2_size = max_t(u32, size_yuv, + ((BIN_BUFFER_THRESHOLD * 3) >> 1)) * + VPX_DECODER_FRAME_CONCURENCY_LVL * + VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO_NUM / + VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO_DEN; + size = ALIGN(binbuffer1_size + binbufer2_size, + VENUS_DMA_ALIGNMENT); + } else { + size = 0; + } + + return size; +} + +static inline u32 calculate_mpeg2d_scratch_size(struct msm_vidc_inst *inst, + u32 width, u32 height, bool is_interlaced) +{ + return 0; +} + +static inline u32 calculate_enc_scratch_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 work_mode, u32 lcu_size) +{ + u32 aligned_width, aligned_height, bitstream_size; + u32 total_bitbin_buffers = 0, size_singlePipe, bitbin_size = 0; + u32 sao_bin_buffer_size, padded_bin_size, size = 0; + + aligned_width = ALIGN(width, lcu_size); + aligned_height = ALIGN(height, lcu_size); + bitstream_size = msm_vidc_calculate_enc_output_frame_size(inst); + + bitstream_size = ALIGN(bitstream_size, VENUS_DMA_ALIGNMENT); + if (work_mode == HFI_WORKMODE_2) { + total_bitbin_buffers = 3; + bitbin_size = bitstream_size * 17 / 10; + bitbin_size = ALIGN(bitbin_size, VENUS_DMA_ALIGNMENT); + } else { + total_bitbin_buffers = 1; + bitstream_size = aligned_width * aligned_height * 3; + bitbin_size = ALIGN(bitstream_size, VENUS_DMA_ALIGNMENT); + } + size_singlePipe = bitbin_size / 2; + size_singlePipe = ALIGN(size_singlePipe, VENUS_DMA_ALIGNMENT); + sao_bin_buffer_size = (64 * (((width + BUFFER_ALIGNMENT_SIZE(32)) * + (height + BUFFER_ALIGNMENT_SIZE(32))) >> 10)) + 384; + padded_bin_size = ALIGN(size_singlePipe, VENUS_DMA_ALIGNMENT); + size_singlePipe = sao_bin_buffer_size + padded_bin_size; + size_singlePipe = ALIGN(size_singlePipe, VENUS_DMA_ALIGNMENT); + bitbin_size = size_singlePipe * NUM_OF_VPP_PIPES; + size = ALIGN(bitbin_size, VENUS_DMA_ALIGNMENT) * total_bitbin_buffers + + 512; + + return size; +} + +static inline u32 calculate_h264e_scratch_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 work_mode) +{ + return calculate_enc_scratch_size(inst, width, height, work_mode, 16); +} + +static inline u32 calculate_h265e_scratch_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 work_mode) +{ + return calculate_enc_scratch_size(inst, width, height, work_mode, 32); +} + +static inline u32 calculate_vp8e_scratch_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 work_mode) +{ + return calculate_enc_scratch_size(inst, width, height, work_mode, 16); +} + +static inline u32 calculate_h264d_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled) +{ + u32 co_mv_size = 0, nonco_mv_size = 0; + u32 vpss_lb_size = 0; + u32 size = 0; + + co_mv_size = hfi_iris2_h264d_comv_size(width, height, min_buf_count); + nonco_mv_size = hfi_iris2_h264d_non_comv_size(width, height); + if (split_mode_enabled) + vpss_lb_size = size_vpss_lb(width, height); + + size = co_mv_size + nonco_mv_size + vpss_lb_size; + return size; +} + +static inline u32 calculate_h265d_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled) +{ + u32 co_mv_size = 0, nonco_mv_size = 0; + u32 vpss_lb_size = 0; + u32 size = 0; + + co_mv_size = hfi_iris2_h265d_comv_size(width, height, min_buf_count); + nonco_mv_size = hfi_iris2_h265d_non_comv_size(width, height); + if (split_mode_enabled) + vpss_lb_size = size_vpss_lb(width, height); + + size = co_mv_size + nonco_mv_size + vpss_lb_size + + HDR10_HIST_EXTRADATA_SIZE; + return size; +} + +static inline u32 hfi_iris2_vp8d_comv_size(u32 width, u32 height, + u32 yuv_min_buf_count) +{ + return (((width + 15) >> 4) * ((height + 15) >> 4) * 8 * 2); +} + +static inline u32 calculate_vp8d_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled) +{ + u32 vpss_lb_size = 0; + u32 size = 0; + + size = hfi_iris2_vp8d_comv_size(width, height, 0); + size += ALIGN(SIZE_VPXD_LB_FE_LEFT_CTRL(width, height), + VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + ALIGN(SIZE_VPXD_LB_SE_LEFT_CTRL(width, height), + VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + ALIGN(SIZE_VP8D_LB_VSP_TOP(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_VPXD_LB_FE_TOP_CTRL(width, height), + VENUS_DMA_ALIGNMENT) + + 2 * ALIGN(SIZE_VPXD_LB_RECON_DMA_METADATA_WR(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_VPXD_LB_SE_TOP_CTRL(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_VP8D_LB_PE_TOP_DATA(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_VP8D_LB_FE_TOP_DATA(width, height), + VENUS_DMA_ALIGNMENT); + if (split_mode_enabled) + vpss_lb_size = size_vpss_lb(width, height); + + size += vpss_lb_size; + return size; +} + +static inline u32 calculate_vp9d_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled) +{ + u32 vpss_lb_size = 0; + u32 size = 0; + + size = ALIGN(SIZE_VPXD_LB_FE_LEFT_CTRL(width, height), + VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + ALIGN(SIZE_VPXD_LB_SE_LEFT_CTRL(width, height), + VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + ALIGN(SIZE_VP9D_LB_VSP_TOP(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_VPXD_LB_FE_TOP_CTRL(width, height), + VENUS_DMA_ALIGNMENT) + + 2 * ALIGN(SIZE_VPXD_LB_RECON_DMA_METADATA_WR(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_VPXD_LB_SE_TOP_CTRL(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_VP9D_LB_PE_TOP_DATA(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_VP9D_LB_FE_TOP_DATA(width, height), + VENUS_DMA_ALIGNMENT); + if (split_mode_enabled) + vpss_lb_size = size_vpss_lb(width, height); + + size += vpss_lb_size + HDR10_HIST_EXTRADATA_SIZE; + return size; +} + +static inline u32 calculate_mpeg2d_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled) +{ + u32 vpss_lb_size = 0; + u32 size = 0; + + size = ALIGN(SIZE_VPXD_LB_FE_LEFT_CTRL(width, height), + VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + ALIGN(SIZE_VPXD_LB_SE_LEFT_CTRL(width, height), + VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + ALIGN(SIZE_VP8D_LB_VSP_TOP(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_VPXD_LB_FE_TOP_CTRL(width, height), + VENUS_DMA_ALIGNMENT) + + 2 * ALIGN(SIZE_VPXD_LB_RECON_DMA_METADATA_WR(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_VPXD_LB_SE_TOP_CTRL(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_VP8D_LB_PE_TOP_DATA(width, height), + VENUS_DMA_ALIGNMENT) + + ALIGN(SIZE_VP8D_LB_FE_TOP_DATA(width, height), + VENUS_DMA_ALIGNMENT); + if (split_mode_enabled) + vpss_lb_size = size_vpss_lb(width, height); + + size += vpss_lb_size; + return size; +} + +static inline u32 calculate_enc_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 lcu_size, u32 num_ref, bool ten_bit, + u32 num_vpp_pipes, bool is_h265) +{ + u32 line_buf_ctrl_size, line_buf_data_size, leftline_buf_ctrl_size; + u32 line_buf_sde_size, sps_pps_slice_hdr, topline_buf_ctrl_size_FE; + u32 leftline_buf_ctrl_size_FE, line_buf_recon_pix_size; + u32 leftline_buf_recon_pix_size, lambda_lut_size, override_buffer_size; + u32 col_mv_buf_size, vpp_reg_buffer_size, ir_buffer_size; + u32 vpss_line_buf, leftline_buf_meta_recony, h265e_colrcbuf_size; + u32 h265e_framerc_bufsize, h265e_lcubitcnt_bufsize; + u32 h265e_lcubitmap_bufsize, se_stats_bufsize; + u32 bse_reg_buffer_size, bse_slice_cmd_buffer_size, slice_info_bufsize; + u32 line_buf_ctrl_size_buffid2, slice_cmd_buffer_size; + u32 width_lcu_num, height_lcu_num, width_coded, height_coded; + u32 frame_num_lcu, linebuf_meta_recon_uv, topline_bufsize_fe_1stg_sao; + u32 output_mv_bufsize = 0, temp_scratch_mv_bufsize = 0; + u32 size, bit_depth; + + width_lcu_num = ((width)+(lcu_size)-1) / (lcu_size); + height_lcu_num = ((height)+(lcu_size)-1) / (lcu_size); + frame_num_lcu = width_lcu_num * height_lcu_num; + width_coded = width_lcu_num * (lcu_size); + height_coded = height_lcu_num * (lcu_size); + slice_info_bufsize = (256 + (frame_num_lcu << 4)); + slice_info_bufsize = ALIGN(slice_info_bufsize, VENUS_DMA_ALIGNMENT); + line_buf_ctrl_size = ALIGN(width_coded, VENUS_DMA_ALIGNMENT); + line_buf_ctrl_size_buffid2 = ALIGN(width_coded, VENUS_DMA_ALIGNMENT); + + bit_depth = ten_bit ? 10 : 8; + line_buf_data_size = (((((bit_depth * width_coded + 1024) + + (VENUS_DMA_ALIGNMENT - 1)) & (~(VENUS_DMA_ALIGNMENT - 1))) * 1) + + (((((bit_depth * width_coded + 1024) >> 1) + + (VENUS_DMA_ALIGNMENT - 1)) & + (~(VENUS_DMA_ALIGNMENT - 1))) * 2)); + leftline_buf_ctrl_size = (is_h265) ? + ((height_coded + (BUFFER_ALIGNMENT_SIZE(32))) / + BUFFER_ALIGNMENT_SIZE(32) * 4 * 16) : + ((height_coded + 15) / 16 * 5 * 16); + if (num_vpp_pipes > 1) { + leftline_buf_ctrl_size += BUFFER_ALIGNMENT_SIZE(512); + leftline_buf_ctrl_size = ALIGN(leftline_buf_ctrl_size, + BUFFER_ALIGNMENT_SIZE(512)) * num_vpp_pipes; + } + leftline_buf_ctrl_size = ALIGN(leftline_buf_ctrl_size, + VENUS_DMA_ALIGNMENT); + leftline_buf_recon_pix_size = (((ten_bit + 1) * 2 * + (height_coded)+VENUS_DMA_ALIGNMENT) + + (VENUS_DMA_ALIGNMENT << (num_vpp_pipes - 1)) - 1) & + (~((VENUS_DMA_ALIGNMENT << (num_vpp_pipes - 1)) - 1)) * 1; + topline_buf_ctrl_size_FE = (is_h265) ? (64 * (width_coded >> 5)) : + (VENUS_DMA_ALIGNMENT + 16 * (width_coded >> 4)); + topline_buf_ctrl_size_FE = ALIGN(topline_buf_ctrl_size_FE, + VENUS_DMA_ALIGNMENT); + leftline_buf_ctrl_size_FE = ((VENUS_DMA_ALIGNMENT + 64 * + (height_coded >> 4)) + + (VENUS_DMA_ALIGNMENT << (num_vpp_pipes - 1)) - 1) & + (~((VENUS_DMA_ALIGNMENT << (num_vpp_pipes - 1)) - 1)) * + num_vpp_pipes; + leftline_buf_meta_recony = ((VENUS_DMA_ALIGNMENT + 64 * + ((height_coded) / (8 * (ten_bit ? 4 : 8)))) * num_vpp_pipes); + leftline_buf_meta_recony = ALIGN(leftline_buf_meta_recony, + VENUS_DMA_ALIGNMENT); + linebuf_meta_recon_uv = ((VENUS_DMA_ALIGNMENT + 64 * + ((height_coded) / (4 * (ten_bit ? 4 : 8)))) * num_vpp_pipes); + linebuf_meta_recon_uv = ALIGN(linebuf_meta_recon_uv, + VENUS_DMA_ALIGNMENT); + line_buf_recon_pix_size = ((ten_bit ? 3 : 2) * width_coded); + line_buf_recon_pix_size = ALIGN(line_buf_recon_pix_size, + VENUS_DMA_ALIGNMENT); + slice_cmd_buffer_size = ALIGN(20480, VENUS_DMA_ALIGNMENT); + sps_pps_slice_hdr = 2048 + 4096; + col_mv_buf_size = (is_h265) ? (16 * ((frame_num_lcu << 2) + + BUFFER_ALIGNMENT_SIZE(32))) : + (3 * 16 * (width_lcu_num * height_lcu_num + + BUFFER_ALIGNMENT_SIZE(32))); + col_mv_buf_size = ALIGN(col_mv_buf_size, VENUS_DMA_ALIGNMENT) + * (num_ref + 1); + h265e_colrcbuf_size = (((width_lcu_num + 7) >> 3) * + 16 * 2 * height_lcu_num); + if (num_vpp_pipes > 1) + h265e_colrcbuf_size = ALIGN(h265e_colrcbuf_size, + VENUS_DMA_ALIGNMENT) * num_vpp_pipes; + h265e_colrcbuf_size = ALIGN(h265e_colrcbuf_size, + VENUS_DMA_ALIGNMENT) * HFI_MAX_COL_FRAME; + h265e_framerc_bufsize = (is_h265) ? (256 + 16 * + (14 + (((height_coded >> 5) + 7) >> 3))) : + (256 + 16 * (14 + (((height_coded >> 4) + 7) >> 3))); + h265e_framerc_bufsize *= 6; /* multiply by max numtilescol*/ + if (num_vpp_pipes > 1) + h265e_framerc_bufsize = ALIGN(h265e_framerc_bufsize, + VENUS_DMA_ALIGNMENT) * num_vpp_pipes; + + h265e_framerc_bufsize = ALIGN(h265e_framerc_bufsize, + BUFFER_ALIGNMENT_SIZE(512)) * HFI_MAX_COL_FRAME; + h265e_lcubitcnt_bufsize = (256 + 4 * frame_num_lcu); + h265e_lcubitcnt_bufsize = ALIGN(h265e_lcubitcnt_bufsize, + VENUS_DMA_ALIGNMENT); + h265e_lcubitmap_bufsize = 256 + (frame_num_lcu >> 3); + h265e_lcubitmap_bufsize = ALIGN(h265e_lcubitmap_bufsize, + VENUS_DMA_ALIGNMENT); + line_buf_sde_size = 256 + 16 * (width_coded >> 4); + line_buf_sde_size = ALIGN(line_buf_sde_size, VENUS_DMA_ALIGNMENT); + if ((width_coded * height_coded) > (4096 * 2160)) + se_stats_bufsize = 0; + else if ((width_coded * height_coded) > (1920 * 1088)) + se_stats_bufsize = (40 * 4 * frame_num_lcu + 256 + 256); + else + se_stats_bufsize = (1024 * frame_num_lcu + 256 + 256); + + se_stats_bufsize = ALIGN(se_stats_bufsize, VENUS_DMA_ALIGNMENT) * 2; + bse_slice_cmd_buffer_size = ((((8192 << 2) + 7) & (~7)) * 6); + bse_reg_buffer_size = ((((512 << 3) + 7) & (~7)) * 4); + vpp_reg_buffer_size = ((((HFI_VENUS_VPPSG_MAX_REGISTERS << 3) + 31) & + (~31)) * 10); + lambda_lut_size = ((((52 << 1) + 7) & (~7)) * 11); + override_buffer_size = 16 * ((frame_num_lcu + 7) >> 3); + override_buffer_size = ALIGN(override_buffer_size, + VENUS_DMA_ALIGNMENT) * 2; + ir_buffer_size = (((frame_num_lcu << 1) + 7) & (~7)) * 3; + vpss_line_buf = ((((width_coded + 3) >> 2) << 5) + 256) * 16; + topline_bufsize_fe_1stg_sao = (16 * (width_coded >> 5)); + topline_bufsize_fe_1stg_sao = ALIGN(topline_bufsize_fe_1stg_sao, + VENUS_DMA_ALIGNMENT); + size = line_buf_ctrl_size + line_buf_data_size + + line_buf_ctrl_size_buffid2 + leftline_buf_ctrl_size + + vpss_line_buf + col_mv_buf_size + topline_buf_ctrl_size_FE + + leftline_buf_ctrl_size_FE + line_buf_recon_pix_size + + leftline_buf_recon_pix_size + leftline_buf_meta_recony + + linebuf_meta_recon_uv + h265e_colrcbuf_size + + h265e_framerc_bufsize + h265e_lcubitcnt_bufsize + + h265e_lcubitmap_bufsize + line_buf_sde_size + + topline_bufsize_fe_1stg_sao + override_buffer_size + + bse_reg_buffer_size + vpp_reg_buffer_size + + sps_pps_slice_hdr + slice_cmd_buffer_size + + bse_slice_cmd_buffer_size + ir_buffer_size + slice_info_bufsize + + lambda_lut_size + se_stats_bufsize + temp_scratch_mv_bufsize + + output_mv_bufsize + 1024; + return size; +} + +static inline u32 calculate_h264e_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 num_ref, bool ten_bit) +{ + return calculate_enc_scratch1_size(inst, width, height, 16, + num_ref, ten_bit, NUM_OF_VPP_PIPES, false); +} + +static inline u32 calculate_h265e_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 num_ref, bool ten_bit) +{ + return calculate_enc_scratch1_size(inst, width, height, 32, + num_ref, ten_bit, NUM_OF_VPP_PIPES, true); +} + +static inline u32 calculate_vp8e_scratch1_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 num_ref, bool ten_bit) +{ + return calculate_enc_scratch1_size(inst, width, height, 16, + num_ref, ten_bit, 1, false); +} + + +static inline u32 hfi_ubwc_calc_metadata_plane_stride(u32 width, + u32 metadata_stride_multi, u32 tile_width_pels) +{ + return ALIGN(((width + (tile_width_pels - 1)) / tile_width_pels), + metadata_stride_multi); +} + +static inline u32 hfi_ubwc_metadata_plane_bufheight(u32 height, + u32 metadata_height_multi, u32 tile_height_pels) +{ + return ALIGN(((height + (tile_height_pels - 1)) / tile_height_pels), + metadata_height_multi); +} + +static inline u32 hfi_ubwc_metadata_plane_buffer_size(u32 metadata_stride, + u32 metadata_buf_height) +{ + return ALIGN(metadata_stride * metadata_buf_height, + BUFFER_ALIGNMENT_4096_BYTES); +} + +static inline u32 hfi_ubwc_uv_metadata_plane_stride(u32 width, + u32 metadata_stride_multi, u32 tile_width_pels) +{ + return ALIGN(((((width + 1) >> 1) + (tile_width_pels - 1)) / + tile_width_pels), metadata_stride_multi); +} + +static inline u32 hfi_ubwc_uv_metadata_plane_bufheight(u32 height, + u32 metadata_height_multi, u32 tile_height_pels) +{ + return ALIGN(((((height + 1) >> 1) + (tile_height_pels - 1)) / + tile_height_pels), metadata_height_multi); +} + +static inline u32 calculate_enc_scratch2_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 num_ref, bool ten_bit) +{ + u32 aligned_width, aligned_height, chroma_height, ref_buf_height; + u32 luma_size, chroma_size; + u32 metadata_stride, meta_buf_height, meta_size_y, meta_size_c; + u32 ref_luma_stride_bytes, ref_chroma_height_bytes; + u32 ref_buf_size = 0, ref_stride; + u32 size; + + if (!ten_bit) { + aligned_height = ALIGN(height, HFI_VENUS_HEIGHT_ALIGNMENT); + chroma_height = height >> 1; + chroma_height = ALIGN(chroma_height, + HFI_VENUS_HEIGHT_ALIGNMENT); + aligned_width = ALIGN(width, HFI_VENUS_WIDTH_ALIGNMENT); + metadata_stride = hfi_ubwc_calc_metadata_plane_stride(width, + 64, HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_WIDTH); + meta_buf_height = hfi_ubwc_metadata_plane_bufheight(height, + 16, HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_HEIGHT); + meta_size_y = hfi_ubwc_metadata_plane_buffer_size( + metadata_stride, meta_buf_height); + meta_size_c = hfi_ubwc_metadata_plane_buffer_size( + metadata_stride, meta_buf_height); + size = (aligned_height + chroma_height) * aligned_width + + meta_size_y + meta_size_c; + size = (size * (num_ref+3)) + 4096; + } else { + ref_buf_height = (height + (HFI_VENUS_HEIGHT_ALIGNMENT - 1)) + & (~(HFI_VENUS_HEIGHT_ALIGNMENT - 1)); + ref_luma_stride_bytes = ((width + SYSTEM_LAL_TILE10 - 1) / + SYSTEM_LAL_TILE10) * SYSTEM_LAL_TILE10; + ref_stride = 4 * (ref_luma_stride_bytes / 3); + ref_stride = (ref_stride + (BUFFER_ALIGNMENT_SIZE(128) - 1)) & + (~(BUFFER_ALIGNMENT_SIZE(128) - 1)); + luma_size = ref_buf_height * ref_stride; + ref_chroma_height_bytes = (((height + 1) >> 1) + + (BUFFER_ALIGNMENT_SIZE(32) - 1)) & + (~(BUFFER_ALIGNMENT_SIZE(32) - 1)); + chroma_size = ref_stride * ref_chroma_height_bytes; + luma_size = (luma_size + (BUFFER_ALIGNMENT_4096_BYTES - 1)) & + (~(BUFFER_ALIGNMENT_4096_BYTES - 1)); + chroma_size = (chroma_size + + (BUFFER_ALIGNMENT_4096_BYTES - 1)) & + (~(BUFFER_ALIGNMENT_4096_BYTES - 1)); + ref_buf_size = luma_size + chroma_size; + metadata_stride = hfi_ubwc_calc_metadata_plane_stride( + width, + VENUS_METADATA_STRIDE_MULTIPLE, + HFI_COLOR_FORMAT_YUV420_TP10_UBWC_Y_TILE_WIDTH); + meta_buf_height = hfi_ubwc_metadata_plane_bufheight( + height, + VENUS_METADATA_HEIGHT_MULTIPLE, + HFI_COLOR_FORMAT_YUV420_TP10_UBWC_Y_TILE_HEIGHT); + meta_size_y = hfi_ubwc_metadata_plane_buffer_size( + metadata_stride, meta_buf_height); + meta_size_c = hfi_ubwc_metadata_plane_buffer_size( + metadata_stride, meta_buf_height); + size = ref_buf_size + meta_size_y + meta_size_c; + size = (size * (num_ref+3)) + 4096; + } + return size; +} + +static inline u32 calculate_enc_persist_size(void) +{ + return HFI_IRIS2_ENC_PERSIST_SIZE; +} + +static inline u32 calculate_h264d_persist1_size(void) +{ + u32 size = 0; + + size = ALIGN((SIZE_SLIST_BUF_H264 * NUM_SLIST_BUF_H264), + VENUS_DMA_ALIGNMENT); + return size; +} + +static inline u32 calculate_h265d_persist1_size(void) +{ + u32 size = 0; + + size = ALIGN((SIZE_SLIST_BUF_H265 * NUM_SLIST_BUF_H265 + H265_NUM_TILE + * sizeof(u32)), VENUS_DMA_ALIGNMENT); + return size; +} + +static inline u32 calculate_vp8d_persist1_size(void) +{ + u32 size = 0; + + size = ALIGN(VP8_NUM_PROBABILITY_TABLE_BUF * VP8_PROB_TABLE_SIZE, + VENUS_DMA_ALIGNMENT); + return size; +} + +static inline u32 calculate_vp9d_persist1_size(void) +{ + u32 size = 0; + + size = ALIGN(VP9_NUM_PROBABILITY_TABLE_BUF * VP9_PROB_TABLE_SIZE, + VENUS_DMA_ALIGNMENT) + + ALIGN(HFI_IRIS2_VP9D_COMV_SIZE, VENUS_DMA_ALIGNMENT) + + ALIGN(MAX_SUPERFRAME_HEADER_LEN, VENUS_DMA_ALIGNMENT) + + ALIGN(VP9_UDC_HEADER_BUF_SIZE, VENUS_DMA_ALIGNMENT) + + ALIGN(VP9_NUM_FRAME_INFO_BUF * CCE_TILE_OFFSET_SIZE, + VENUS_DMA_ALIGNMENT); + return size; +} + +static inline u32 calculate_mpeg2d_persist1_size(void) +{ + return QMATRIX_SIZE + MP2D_QPDUMP_SIZE; +} diff --git a/msm/vidc/msm_vidc_buffer_calculations.h b/msm/vidc/msm_vidc_buffer_calculations.h new file mode 100644 index 000000000000..29fe98c606f5 --- /dev/null +++ b/msm/vidc/msm_vidc_buffer_calculations.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#ifndef __H_MSM_VIDC_BUFFER_MEM_DEFS_H__ +#define __H_MSM_VIDC_BUFFER_MEM_DEFS_H__ + +struct msm_vidc_dec_buff_size_calculators { + u32 (*calculate_scratch_size)(struct msm_vidc_inst *inst, u32 width, + u32 height, bool is_interlaced); + u32 (*calculate_scratch1_size)(struct msm_vidc_inst *inst, u32 width, + u32 height, u32 min_buf_count, bool split_mode_enabled); + u32 (*calculate_persist1_size)(void); +}; + +struct msm_vidc_enc_buff_size_calculators { + u32 (*calculate_scratch_size)(struct msm_vidc_inst *inst, u32 width, + u32 height, u32 work_mode); + u32 (*calculate_scratch1_size)(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 num_ref, bool ten_bit); + u32 (*calculate_scratch2_size)(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 num_ref, bool ten_bit); + u32 (*calculate_persist_size)(void); +}; + +void msm_vidc_init_buffer_size_calculators(struct msm_vidc_inst *inst); +int msm_vidc_init_buffer_count(struct msm_vidc_inst *inst); +int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, + enum hal_buffer buffer_type); +u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst); +u32 msm_vidc_calculate_dec_output_frame_size(struct msm_vidc_inst *inst); +u32 msm_vidc_calculate_dec_output_extra_size(struct msm_vidc_inst *inst); +u32 msm_vidc_calculate_enc_input_frame_size(struct msm_vidc_inst *inst); +u32 msm_vidc_calculate_enc_output_frame_size(struct msm_vidc_inst *inst); +u32 msm_vidc_calculate_enc_input_extra_size(struct msm_vidc_inst *inst); +u32 msm_vidc_calculate_enc_output_extra_size(struct msm_vidc_inst *inst); +u32 msm_vidc_set_buffer_count_for_thumbnail(struct msm_vidc_inst *inst); + +#endif // __H_MSM_VIDC_BUFFER_MEM_DEFS_H__ diff --git a/msm/vidc/msm_vidc_bus.h b/msm/vidc/msm_vidc_bus.h new file mode 100644 index 000000000000..66d65d4b5ebd --- /dev/null +++ b/msm/vidc/msm_vidc_bus.h @@ -0,0 +1,283 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#ifndef __H_MSM_VIDC_BUS_DEFS_H__ +#define __H_MSM_VIDC_BUS_DEFS_H__ + +#include "fixedpoint.h" +#include "msm_vidc_debug.h" +#include "vidc_hfi_api.h" + +#define COMPRESSION_RATIO_MAX 5 + +enum vidc_bus_type { + PERF, + DDR, + LLCC, +}; + +/* + * Minimum dimensions for which to calculate bandwidth. + * This means that anything bandwidth(0, 0) == + * bandwidth(BASELINE_DIMENSIONS.width, BASELINE_DIMENSIONS.height) + */ +static const struct { + int height, width; +} BASELINE_DIMENSIONS = { + .width = 1280, + .height = 720, +}; + +/* converts Mbps to bps (the "b" part can be bits or bytes based on context) */ +#define kbps(__mbps) ((__mbps) * 1000) +#define bps(__mbps) (kbps(__mbps) * 1000) + +#define GENERATE_COMPRESSION_PROFILE(__bpp, __worst) { \ + .bpp = __bpp, \ + .ratio = __worst, \ +} + +/* + * The below table is a structural representation of the following table: + * Resolution | Bitrate | Compression Ratio | + * ............|............|.........................................| + * Width Height|Average High|Avg_8bpc Worst_8bpc Avg_10bpc Worst_10bpc| + * 1280 720| 7 14| 1.69 1.28 1.49 1.23| + * 1920 1080| 20 40| 1.69 1.28 1.49 1.23| + * 2560 1440| 32 64| 2.2 1.26 1.97 1.22| + * 3840 2160| 42 84| 2.2 1.26 1.97 1.22| + * 4096 2160| 44 88| 2.2 1.26 1.97 1.22| + * 4096 2304| 48 96| 2.2 1.26 1.97 1.22| + */ +static struct lut { + int frame_size; /* width x height */ + int frame_rate; + unsigned long bitrate; + struct { + int bpp; + fp_t ratio; + } compression_ratio[COMPRESSION_RATIO_MAX]; +} const LUT[] = { + { + .frame_size = 1280 * 720, + .frame_rate = 30, + .bitrate = 14, + .compression_ratio = { + GENERATE_COMPRESSION_PROFILE(8, + FP(1, 28, 100)), + GENERATE_COMPRESSION_PROFILE(10, + FP(1, 23, 100)), + } + }, + { + .frame_size = 1280 * 720, + .frame_rate = 60, + .bitrate = 22, + .compression_ratio = { + GENERATE_COMPRESSION_PROFILE(8, + FP(1, 28, 100)), + GENERATE_COMPRESSION_PROFILE(10, + FP(1, 23, 100)), + } + }, + { + .frame_size = 1920 * 1088, + .frame_rate = 30, + .bitrate = 40, + .compression_ratio = { + GENERATE_COMPRESSION_PROFILE(8, + FP(1, 28, 100)), + GENERATE_COMPRESSION_PROFILE(10, + FP(1, 23, 100)), + } + }, + { + .frame_size = 1920 * 1088, + .frame_rate = 60, + .bitrate = 64, + .compression_ratio = { + GENERATE_COMPRESSION_PROFILE(8, + FP(1, 28, 100)), + GENERATE_COMPRESSION_PROFILE(10, + FP(1, 23, 100)), + } + }, + { + .frame_size = 2560 * 1440, + .frame_rate = 30, + .bitrate = 64, + .compression_ratio = { + GENERATE_COMPRESSION_PROFILE(8, + FP(1, 26, 100)), + GENERATE_COMPRESSION_PROFILE(10, + FP(1, 22, 100)), + } + }, + { + .frame_size = 2560 * 1440, + .frame_rate = 60, + .bitrate = 102, + .compression_ratio = { + GENERATE_COMPRESSION_PROFILE(8, + FP(1, 26, 100)), + GENERATE_COMPRESSION_PROFILE(10, + FP(1, 22, 100)), + } + }, + { + .frame_size = 3840 * 2160, + .frame_rate = 30, + .bitrate = 84, + .compression_ratio = { + GENERATE_COMPRESSION_PROFILE(8, + FP(1, 26, 100)), + GENERATE_COMPRESSION_PROFILE(10, + FP(1, 22, 100)), + } + }, + { + .frame_size = 3840 * 2160, + .frame_rate = 60, + .bitrate = 134, + .compression_ratio = { + GENERATE_COMPRESSION_PROFILE(8, + FP(1, 26, 100)), + GENERATE_COMPRESSION_PROFILE(10, + FP(1, 22, 100)), + } + }, + { + .frame_size = 4096 * 2160, + .frame_rate = 30, + .bitrate = 88, + .compression_ratio = { + GENERATE_COMPRESSION_PROFILE(8, + FP(1, 26, 100)), + GENERATE_COMPRESSION_PROFILE(10, + FP(1, 22, 100)), + } + }, + { + .frame_size = 4096 * 2160, + .frame_rate = 60, + .bitrate = 141, + .compression_ratio = { + GENERATE_COMPRESSION_PROFILE(8, + FP(1, 26, 100)), + GENERATE_COMPRESSION_PROFILE(10, + FP(1, 22, 100)), + } + }, + { + .frame_size = 4096 * 2304, + .frame_rate = 30, + .bitrate = 96, + .compression_ratio = { + GENERATE_COMPRESSION_PROFILE(8, + FP(1, 26, 100)), + GENERATE_COMPRESSION_PROFILE(10, + FP(1, 22, 100)), + } + }, + { + .frame_size = 4096 * 2304, + .frame_rate = 60, + .bitrate = 154, + .compression_ratio = { + GENERATE_COMPRESSION_PROFILE(8, + FP(1, 26, 100)), + GENERATE_COMPRESSION_PROFILE(10, + FP(1, 22, 100)), + } + }, +}; + +static inline u32 get_type_frm_name(char *name) +{ + if (!strcmp(name, "venus-llcc")) + return LLCC; + else if (!strcmp(name, "venus-ddr")) + return DDR; + else + return PERF; +} + +#define DUMP_HEADER_MAGIC 0xdeadbeef +#define DUMP_FP_FMT "%FP" /* special format for fp_t */ + +struct dump { + char *key; + char *format; + size_t val; +}; + +struct vidc_bus_vote_data { + enum hal_domain domain; + enum hal_video_codec codec; + enum hal_uncompressed_format color_formats[2]; + int num_formats; /* 1 = DPB-OPB unified; 2 = split */ + int input_height, input_width, bitrate; + int output_height, output_width; + int rotation; + int compression_ratio; + int complexity_factor; + int input_cr; + u32 ddr_bw; + u32 sys_cache_bw; + bool use_dpb_read; + unsigned int lcu_size; + unsigned int fps; + enum msm_vidc_power_mode power_mode; + u32 work_mode; + bool use_sys_cache; + bool b_frames_enabled; +}; + +struct msm_vidc_bus_data { + struct vidc_bus_vote_data *data; + u32 data_count; + unsigned long (*calc_bw)(struct bus_info *bus, + struct msm_vidc_bus_data *data); +}; + +unsigned long calc_bw_iris1(struct bus_info *bus, + struct msm_vidc_bus_data *vidc_data); + +unsigned long calc_bw_iris2(struct bus_info *bus, + struct msm_vidc_bus_data *vidc_data); + +struct lut const *__lut(int width, int height, int fps); +fp_t __compression_ratio(struct lut const *entry, int bpp); +void __dump(struct dump dump[], int len); + +static inline bool __ubwc(enum hal_uncompressed_format f) +{ + switch (f) { + case HAL_COLOR_FORMAT_NV12_UBWC: + case HAL_COLOR_FORMAT_NV12_TP10_UBWC: + return true; + default: + return false; + } +} + +static inline int __bpp(enum hal_uncompressed_format f) +{ + switch (f) { + case HAL_COLOR_FORMAT_NV12: + case HAL_COLOR_FORMAT_NV21: + case HAL_COLOR_FORMAT_NV12_UBWC: + return 8; + case HAL_COLOR_FORMAT_NV12_TP10_UBWC: + case HAL_COLOR_FORMAT_P010: + return 10; + default: + dprintk(VIDC_ERR, + "Unsupported colorformat (%x)", f); + return INT_MAX; + } +} + +#endif // __H_MSM_VIDC_BUS_DEFS_H__ diff --git a/msm/vidc/msm_vidc_bus_iris1.c b/msm/vidc/msm_vidc_bus_iris1.c new file mode 100644 index 000000000000..3512f4d11032 --- /dev/null +++ b/msm/vidc/msm_vidc_bus_iris1.c @@ -0,0 +1,699 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + */ + +#include "msm_vidc_bus.h" +#include "msm_vidc_internal.h" + +struct lut const *__lut(int width, int height, int fps) +{ + int frame_size = height * width, c = 0; + + do { + if (LUT[c].frame_size >= frame_size && LUT[c].frame_rate >= fps) + return &LUT[c]; + } while (++c < ARRAY_SIZE(LUT)); + + return &LUT[ARRAY_SIZE(LUT) - 1]; +} + +fp_t __compression_ratio(struct lut const *entry, int bpp) +{ + int c = 0; + + for (c = 0; c < COMPRESSION_RATIO_MAX; ++c) { + if (entry->compression_ratio[c].bpp == bpp) + return entry->compression_ratio[c].ratio; + } + + WARN(true, "Shouldn't be here, LUT possibly corrupted?\n"); + return FP_ZERO; /* impossible */ +} + +void __dump(struct dump dump[], int len) +{ + int c = 0; + + for (c = 0; c < len; ++c) { + char format_line[128] = "", formatted_line[128] = ""; + + if (dump[c].val == DUMP_HEADER_MAGIC) { + snprintf(formatted_line, sizeof(formatted_line), "%s\n", + dump[c].key); + } else { + bool fp_format = !strcmp(dump[c].format, DUMP_FP_FMT); + + if (!fp_format) { + snprintf(format_line, sizeof(format_line), + " %-35s: %s\n", dump[c].key, + dump[c].format); + snprintf(formatted_line, sizeof(formatted_line), + format_line, dump[c].val); + } else { + size_t integer_part, fractional_part; + + integer_part = fp_int(dump[c].val); + fractional_part = fp_frac(dump[c].val); + snprintf(formatted_line, sizeof(formatted_line), + " %-35s: %zd + %zd/%zd\n", + dump[c].key, integer_part, + fractional_part, + fp_frac_base()); + + + } + } + dprintk(VIDC_DBG, "%s", formatted_line); + } +} + +static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d, + enum vidc_bus_type type) +{ + return 0; +} + +static unsigned long __calculate_cvp(struct vidc_bus_vote_data *d, + enum vidc_bus_type type) +{ + unsigned long ret = 0; + + switch (type) { + case DDR: + ret = d->ddr_bw; + break; + case LLCC: + ret = d->sys_cache_bw; + break; + default: + dprintk(VIDC_ERR, "%s - Unknown type\n", __func__); + break; + } + + return ret; +} + +static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, + enum vidc_bus_type type) +{ + /* + * XXX: Don't fool around with any of the hardcoded numbers unless you + * know /exactly/ what you're doing. Many of these numbers are + * measured heuristics and hardcoded numbers taken from the firmware. + */ + /* Decoder parameters */ + int width, height, lcu_size, fps, dpb_bpp; + bool unified_dpb_opb, dpb_compression_enabled = true, + opb_compression_enabled = false, + llc_ref_read_l2_cache_enabled = false, + llc_top_line_buf_enabled = false; + fp_t dpb_read_compression_factor, dpb_opb_scaling_ratio, + dpb_write_compression_factor, opb_write_compression_factor, + qsmmu_bw_overhead_factor; + bool is_h264_category = true; + + /* Derived parameters */ + int lcu_per_frame, collocated_bytes_per_lcu, tnbr_per_lcu; + unsigned long bitrate; + + fp_t bins_to_bit_factor, vsp_read_factor, vsp_write_factor, + dpb_factor, dpb_write_factor, + y_bw_no_ubwc_8bpp, y_bw_no_ubwc_10bpp, y_bw_10bpp_p010, + motion_vector_complexity = 0; + fp_t dpb_total = 0; + + /* Output parameters */ + struct { + fp_t vsp_read, vsp_write, collocated_read, collocated_write, + dpb_read, dpb_write, opb_read, opb_write, + line_buffer_read, line_buffer_write, + total; + } ddr = {0}; + + struct { + fp_t dpb_read, line_buffer_read, line_buffer_write, total; + } llc = {0}; + + unsigned long ret = 0; + unsigned int integer_part, frac_part; + + width = max(d->input_width, BASELINE_DIMENSIONS.width); + height = max(d->input_height, BASELINE_DIMENSIONS.height); + + fps = d->fps; + + lcu_size = d->lcu_size; + + dpb_bpp = d->num_formats >= 1 ? __bpp(d->color_formats[0]) : INT_MAX; + + unified_dpb_opb = d->num_formats == 1; + + dpb_opb_scaling_ratio = fp_div(FP_INT(d->input_width * d->input_height), + FP_INT(d->output_width * d->output_height)); + + opb_compression_enabled = d->num_formats >= 2 && + __ubwc(d->color_formats[1]); + + /* + * convert q16 number into integer and fractional part upto 2 places. + * ex : 105752 / 65536 = 1.61; 1.61 in q16 = 105752; + * integer part = 105752 / 65536 = 1; + * reminder = 105752 - 1 * 65536 = 40216; + * fractional part = 40216 * 100 / 65536 = 61; + * now converto to fp(1, 61, 100) for below code. + */ + + integer_part = d->compression_ratio >> 16; + frac_part = + ((d->compression_ratio - (integer_part << 16)) * 100) >> 16; + + dpb_read_compression_factor = FP(integer_part, frac_part, 100); + + integer_part = d->complexity_factor >> 16; + frac_part = + ((d->complexity_factor - (integer_part << 16)) * 100) >> 16; + + motion_vector_complexity = FP(integer_part, frac_part, 100); + + dpb_write_compression_factor = dpb_read_compression_factor; + opb_write_compression_factor = opb_compression_enabled ? + dpb_write_compression_factor : FP_ONE; + + if (d->codec == HAL_VIDEO_CODEC_HEVC || + d->codec == HAL_VIDEO_CODEC_VP9) { + /* H264, VP8, MPEG2 use the same settings */ + /* HEVC, VP9 use the same setting */ + is_h264_category = false; + } + if (d->use_sys_cache) { + llc_ref_read_l2_cache_enabled = true; + if (is_h264_category) + llc_top_line_buf_enabled = true; + } + + /* Derived parameters setup */ + lcu_per_frame = DIV_ROUND_UP(width, lcu_size) * + DIV_ROUND_UP(height, lcu_size); + + bitrate = (d->bitrate + 1000000 - 1) / 1000000; + + bins_to_bit_factor = FP_INT(4); + vsp_write_factor = bins_to_bit_factor; + vsp_read_factor = bins_to_bit_factor + FP_INT(2); + + collocated_bytes_per_lcu = lcu_size == 16 ? 16 : + lcu_size == 32 ? 64 : 256; + + dpb_factor = FP(1, 50, 100); + dpb_write_factor = FP(1, 5, 100); + + tnbr_per_lcu = lcu_size == 16 ? 128 : + lcu_size == 32 ? 64 : 128; + + /* .... For DDR & LLC ...... */ + ddr.vsp_read = fp_div(fp_mult(FP_INT(bitrate), + vsp_read_factor), FP_INT(8)); + ddr.vsp_write = fp_div(fp_mult(FP_INT(bitrate), + vsp_write_factor), FP_INT(8)); + + ddr.collocated_read = fp_div(FP_INT(lcu_per_frame * + collocated_bytes_per_lcu * fps), FP_INT(bps(1))); + ddr.collocated_write = ddr.collocated_read; + + y_bw_no_ubwc_8bpp = fp_div(fp_mult( + FP_INT((int)(width * height)), FP_INT((int)fps)), + FP_INT(1000 * 1000)); + y_bw_no_ubwc_10bpp = fp_div(fp_mult(y_bw_no_ubwc_8bpp, FP_INT(256)), + FP_INT(192)); + y_bw_10bpp_p010 = y_bw_no_ubwc_8bpp * 2; + + ddr.dpb_read = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; + ddr.dpb_read = fp_div(fp_mult(ddr.dpb_read, + fp_mult(dpb_factor, motion_vector_complexity)), + dpb_read_compression_factor); + + ddr.dpb_write = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; + ddr.dpb_write = fp_div(fp_mult(ddr.dpb_write, + fp_mult(dpb_factor, dpb_write_factor)), + dpb_write_compression_factor); + + dpb_total = ddr.dpb_read + ddr.dpb_write; + + if (llc_ref_read_l2_cache_enabled) { + ddr.dpb_read = fp_div(ddr.dpb_read, is_h264_category ? + FP(1, 15, 100) : FP(1, 30, 100)); + llc.dpb_read = dpb_total - ddr.dpb_write - ddr.dpb_read; + } + + ddr.opb_read = FP_ZERO; + ddr.opb_write = unified_dpb_opb ? FP_ZERO : (dpb_bpp == 8 ? + y_bw_no_ubwc_8bpp : (opb_compression_enabled ? + y_bw_no_ubwc_10bpp : y_bw_10bpp_p010)); + ddr.opb_write = fp_div(fp_mult(dpb_factor, ddr.opb_write), + fp_mult(dpb_opb_scaling_ratio, opb_write_compression_factor)); + + ddr.line_buffer_read = FP_INT(tnbr_per_lcu * + lcu_per_frame * fps / bps(1)); + ddr.line_buffer_write = ddr.line_buffer_read; + if (llc_top_line_buf_enabled) { + llc.line_buffer_read = ddr.line_buffer_read; + llc.line_buffer_write = ddr.line_buffer_write; + ddr.line_buffer_write = ddr.line_buffer_read = FP_ZERO; + } + + ddr.total = ddr.vsp_read + ddr.vsp_write + + ddr.collocated_read + ddr.collocated_write + + ddr.dpb_read + ddr.dpb_write + + ddr.opb_read + ddr.opb_write + + ddr.line_buffer_read + ddr.line_buffer_write; + + qsmmu_bw_overhead_factor = FP(1, 3, 100); + + ddr.total = fp_mult(ddr.total, qsmmu_bw_overhead_factor); + llc.total = llc.dpb_read + llc.line_buffer_read + + llc.line_buffer_write + ddr.total; + + /* Dump all the variables for easier debugging */ + if (msm_vidc_debug & VIDC_PROF) { + struct dump dump[] = { + {"DECODER PARAMETERS", "", DUMP_HEADER_MAGIC}, + {"lcu size", "%d", lcu_size}, + {"dpb bitdepth", "%d", dpb_bpp}, + {"frame rate", "%d", fps}, + {"dpb/opb unified", "%d", unified_dpb_opb}, + {"dpb/opb downscaling ratio", DUMP_FP_FMT, + dpb_opb_scaling_ratio}, + {"dpb compression", "%d", dpb_compression_enabled}, + {"opb compression", "%d", opb_compression_enabled}, + {"dpb read compression factor", DUMP_FP_FMT, + dpb_read_compression_factor}, + {"dpb write compression factor", DUMP_FP_FMT, + dpb_write_compression_factor}, + {"frame width", "%d", width}, + {"frame height", "%d", height}, + {"llc ref read l2 cache enabled", "%d", + llc_ref_read_l2_cache_enabled}, + {"llc top line buf enabled", "%d", + llc_top_line_buf_enabled}, + + {"DERIVED PARAMETERS (1)", "", DUMP_HEADER_MAGIC}, + {"lcus/frame", "%d", lcu_per_frame}, + {"bitrate (Mbit/sec)", "%d", bitrate}, + {"bins to bit factor", DUMP_FP_FMT, bins_to_bit_factor}, + {"dpb write factor", DUMP_FP_FMT, dpb_write_factor}, + {"vsp read factor", DUMP_FP_FMT, vsp_read_factor}, + {"vsp write factor", DUMP_FP_FMT, vsp_write_factor}, + {"tnbr/lcu", "%d", tnbr_per_lcu}, + {"collocated bytes/LCU", "%d", collocated_bytes_per_lcu}, + {"bw for NV12 8bpc)", DUMP_FP_FMT, y_bw_no_ubwc_8bpp}, + {"bw for NV12 10bpc)", DUMP_FP_FMT, y_bw_no_ubwc_10bpp}, + + {"DERIVED PARAMETERS (2)", "", DUMP_HEADER_MAGIC}, + {"mv complexity", DUMP_FP_FMT, motion_vector_complexity}, + {"qsmmu_bw_overhead_factor", DUMP_FP_FMT, + qsmmu_bw_overhead_factor}, + + {"INTERMEDIATE DDR B/W", "", DUMP_HEADER_MAGIC}, + {"vsp read", DUMP_FP_FMT, ddr.vsp_read}, + {"vsp write", DUMP_FP_FMT, ddr.vsp_write}, + {"collocated read", DUMP_FP_FMT, ddr.collocated_read}, + {"collocated write", DUMP_FP_FMT, ddr.collocated_write}, + {"line buffer read", DUMP_FP_FMT, ddr.line_buffer_read}, + {"line buffer write", DUMP_FP_FMT, ddr.line_buffer_write}, + {"opb read", DUMP_FP_FMT, ddr.opb_read}, + {"opb write", DUMP_FP_FMT, ddr.opb_write}, + {"dpb read", DUMP_FP_FMT, ddr.dpb_read}, + {"dpb write", DUMP_FP_FMT, ddr.dpb_write}, + {"dpb total", DUMP_FP_FMT, dpb_total}, + {"INTERMEDIATE LLC B/W", "", DUMP_HEADER_MAGIC}, + {"llc dpb read", DUMP_FP_FMT, llc.dpb_read}, + {"llc line buffer read", DUMP_FP_FMT, llc.line_buffer_read}, + {"llc line buffer write", DUMP_FP_FMT, llc.line_buffer_write}, + + }; + __dump(dump, ARRAY_SIZE(dump)); + } + + switch (type) { + case DDR: + ret = kbps(fp_round(ddr.total)); + break; + case LLCC: + ret = kbps(fp_round(llc.total)); + break; + default: + dprintk(VIDC_ERR, "%s - Unknown type\n", __func__); + } + + return ret; +} + +static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, + enum vidc_bus_type type) +{ + /* + * XXX: Don't fool around with any of the hardcoded numbers unless you + * know /exactly/ what you're doing. Many of these numbers are + * measured heuristics and hardcoded numbers taken from the firmware. + */ + /* Encoder Parameters */ + int width, height, fps, lcu_size, bitrate, lcu_per_frame, + collocated_bytes_per_lcu, tnbr_per_lcu, dpb_bpp, + original_color_format, vertical_tile_width; + bool work_mode_1, original_compression_enabled, + low_power, rotation, cropping_or_scaling, + b_frames_enabled = false, + llc_ref_chroma_cache_enabled = false, + llc_top_line_buf_enabled = false, + llc_vpss_rot_line_buf_enabled = false; + + fp_t bins_to_bit_factor, dpb_compression_factor, + original_compression_factor, + original_compression_factor_y, + y_bw_no_ubwc_8bpp, y_bw_no_ubwc_10bpp, y_bw_10bpp_p010, + input_compression_factor, + downscaling_ratio, + ref_y_read_bw_factor, ref_cbcr_read_bw_factor, + recon_write_bw_factor, mese_read_factor, + total_ref_read_crcb, + qsmmu_bw_overhead_factor; + fp_t integer_part, frac_part; + unsigned long ret = 0; + + /* Output parameters */ + struct { + fp_t vsp_read, vsp_write, collocated_read, collocated_write, + ref_read_y, ref_read_crcb, ref_write, + ref_write_overlap, orig_read, + line_buffer_read, line_buffer_write, + mese_read, mese_write, + total; + } ddr = {0}; + + struct { + fp_t ref_read_crcb, line_buffer, total; + } llc = {0}; + + /* Encoder Parameters setup */ + rotation = d->rotation; + cropping_or_scaling = false; + vertical_tile_width = 960; + recon_write_bw_factor = FP(1, 8, 100); + ref_y_read_bw_factor = FP(1, 30, 100); + ref_cbcr_read_bw_factor = FP(1, 50, 100); + + + /* Derived Parameters */ + fps = d->fps; + width = max(d->output_width, BASELINE_DIMENSIONS.width); + height = max(d->output_height, BASELINE_DIMENSIONS.height); + downscaling_ratio = fp_div(FP_INT(d->input_width * d->input_height), + FP_INT(d->output_width * d->output_height)); + downscaling_ratio = max(downscaling_ratio, FP_ONE); + bitrate = d->bitrate > 0 ? (d->bitrate + 1000000 - 1) / 1000000 : + __lut(width, height, fps)->bitrate; + lcu_size = d->lcu_size; + lcu_per_frame = DIV_ROUND_UP(width, lcu_size) * + DIV_ROUND_UP(height, lcu_size); + tnbr_per_lcu = 16; + + y_bw_no_ubwc_8bpp = fp_div(fp_mult( + FP_INT((int)(width * height)), FP_INT(fps)), + FP_INT(1000 * 1000)); + y_bw_no_ubwc_10bpp = fp_div(fp_mult(y_bw_no_ubwc_8bpp, + FP_INT(256)), FP_INT(192)); + y_bw_10bpp_p010 = y_bw_no_ubwc_8bpp * 2; + + b_frames_enabled = d->b_frames_enabled; + original_color_format = d->num_formats >= 1 ? + d->color_formats[0] : HAL_UNUSED_COLOR; + + dpb_bpp = d->num_formats >= 1 ? __bpp(d->color_formats[0]) : INT_MAX; + + original_compression_enabled = __ubwc(original_color_format); + + work_mode_1 = d->work_mode == HFI_WORKMODE_1; + low_power = d->power_mode == VIDC_POWER_LOW; + bins_to_bit_factor = FP_INT(4); + + if (d->use_sys_cache) { + llc_ref_chroma_cache_enabled = true; + llc_top_line_buf_enabled = true, + llc_vpss_rot_line_buf_enabled = true; + } + + /* + * Convert Q16 number into Integer and Fractional part upto 2 places. + * Ex : 105752 / 65536 = 1.61; 1.61 in Q16 = 105752; + * Integer part = 105752 / 65536 = 1; + * Reminder = 105752 - 1 * 65536 = 40216; + * Fractional part = 40216 * 100 / 65536 = 61; + * Now converto to FP(1, 61, 100) for below code. + */ + + integer_part = d->compression_ratio >> 16; + frac_part = + ((d->compression_ratio - (integer_part * 65536)) * 100) >> 16; + + dpb_compression_factor = FP(integer_part, frac_part, 100); + + integer_part = d->input_cr >> 16; + frac_part = + ((d->input_cr - (integer_part * 65536)) * 100) >> 16; + + input_compression_factor = FP(integer_part, frac_part, 100); + + original_compression_factor = original_compression_factor_y = + !original_compression_enabled ? FP_ONE : + __compression_ratio(__lut(width, height, fps), dpb_bpp); + /* use input cr if it is valid (not 1), otherwise use lut */ + if (original_compression_enabled && + input_compression_factor != FP_ONE) { + original_compression_factor = input_compression_factor; + /* Luma usually has lower compression factor than Chroma, + * input cf is overall cf, add 1.08 factor for Luma cf + */ + original_compression_factor_y = + input_compression_factor > FP(1, 8, 100) ? + fp_div(input_compression_factor, FP(1, 8, 100)) : + input_compression_factor; + } + + mese_read_factor = fp_div(FP_INT((width * height * fps)/4), + original_compression_factor_y); + mese_read_factor = fp_div(fp_mult(mese_read_factor, FP(2, 53, 100)), + FP_INT(1000 * 1000)); + + ddr.vsp_read = fp_div(fp_mult(FP_INT(bitrate), bins_to_bit_factor), + FP_INT(8)); + ddr.vsp_write = ddr.vsp_read + fp_div(FP_INT(bitrate), FP_INT(8)); + + collocated_bytes_per_lcu = lcu_size == 16 ? 16 : + lcu_size == 32 ? 64 : 256; + + ddr.collocated_read = fp_div(FP_INT(lcu_per_frame * + collocated_bytes_per_lcu * fps), FP_INT(bps(1))); + + ddr.collocated_write = ddr.collocated_read; + + ddr.ref_read_y = ddr.ref_read_crcb = dpb_bpp == 8 ? + y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; + + if (width != vertical_tile_width) { + ddr.ref_read_y = fp_mult(ddr.ref_read_y, + ref_y_read_bw_factor); + } + + ddr.ref_read_y = fp_div(ddr.ref_read_y, dpb_compression_factor); + if (b_frames_enabled) + ddr.ref_read_y = fp_mult(ddr.ref_read_y, FP_INT(2)); + + ddr.ref_read_crcb = fp_mult(ddr.ref_read_crcb, FP(0, 50, 100)); + ddr.ref_read_crcb = fp_div(ddr.ref_read_crcb, dpb_compression_factor); + if (b_frames_enabled) + ddr.ref_read_crcb = fp_mult(ddr.ref_read_crcb, FP_INT(2)); + + if (llc_ref_chroma_cache_enabled) { + total_ref_read_crcb = ddr.ref_read_crcb; + ddr.ref_read_crcb = fp_div(ddr.ref_read_crcb, + ref_cbcr_read_bw_factor); + llc.ref_read_crcb = total_ref_read_crcb - ddr.ref_read_crcb; + } + + ddr.ref_write = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; + ddr.ref_write = fp_mult(ddr.ref_write, + (fp_div(FP(1, 50, 100), dpb_compression_factor))); + + ddr.ref_write_overlap = fp_div(fp_mult(ddr.ref_write, + (recon_write_bw_factor - FP_ONE)), + recon_write_bw_factor); + + ddr.orig_read = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : + (original_compression_enabled ? y_bw_no_ubwc_10bpp : + y_bw_10bpp_p010); + ddr.orig_read = fp_div(fp_mult(fp_mult(ddr.orig_read, FP(1, 50, 100)), + downscaling_ratio), original_compression_factor); + if (rotation == 90 || rotation == 270) + ddr.orig_read *= lcu_size == 32 ? (dpb_bpp == 8 ? 1 : 3) : 2; + + ddr.line_buffer_read = FP_INT(tnbr_per_lcu * lcu_per_frame * + fps / bps(1)); + + ddr.line_buffer_write = ddr.line_buffer_read; + if (llc_top_line_buf_enabled) { + llc.line_buffer = ddr.line_buffer_read + ddr.line_buffer_write; + ddr.line_buffer_read = ddr.line_buffer_write = FP_ZERO; + } + + ddr.mese_read = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; + ddr.mese_read = fp_div(fp_mult(ddr.mese_read, FP(1, 37, 100)), + original_compression_factor_y) + mese_read_factor; + + ddr.mese_write = FP_INT((width * height)/512) + + fp_div(FP_INT((width * height)/4), + original_compression_factor_y) + + FP_INT((width * height)/128); + ddr.mese_write = fp_div(fp_mult(ddr.mese_write, FP_INT(fps)), + FP_INT(1000 * 1000)); + + ddr.total = ddr.vsp_read + ddr.vsp_write + + ddr.collocated_read + ddr.collocated_write + + ddr.ref_read_y + ddr.ref_read_crcb + + ddr.ref_write + ddr.ref_write_overlap + + ddr.orig_read + + ddr.line_buffer_read + ddr.line_buffer_write + + ddr.mese_read + ddr.mese_write; + + qsmmu_bw_overhead_factor = FP(1, 3, 100); + ddr.total = fp_mult(ddr.total, qsmmu_bw_overhead_factor); + llc.total = llc.ref_read_crcb + llc.line_buffer + ddr.total; + + if (msm_vidc_debug & VIDC_PROF) { + struct dump dump[] = { + {"ENCODER PARAMETERS", "", DUMP_HEADER_MAGIC}, + {"width", "%d", width}, + {"height", "%d", height}, + {"fps", "%d", fps}, + {"dpb bitdepth", "%d", dpb_bpp}, + {"input downscaling ratio", DUMP_FP_FMT, downscaling_ratio}, + {"rotation", "%d", rotation}, + {"cropping or scaling", "%d", cropping_or_scaling}, + {"low power mode", "%d", low_power}, + {"work Mode", "%d", work_mode_1}, + {"B frame enabled", "%d", b_frames_enabled}, + {"original frame format", "%#x", original_color_format}, + {"original compression enabled", "%d", + original_compression_enabled}, + {"dpb compression factor", DUMP_FP_FMT, + dpb_compression_factor}, + {"input compression factor", DUMP_FP_FMT, + input_compression_factor}, + {"llc ref chroma cache enabled", DUMP_FP_FMT, + llc_ref_chroma_cache_enabled}, + {"llc top line buf enabled", DUMP_FP_FMT, + llc_top_line_buf_enabled}, + {"llc vpss rot line buf enabled ", DUMP_FP_FMT, + llc_vpss_rot_line_buf_enabled}, + + {"DERIVED PARAMETERS", "", DUMP_HEADER_MAGIC}, + {"lcu size", "%d", lcu_size}, + {"bitrate (Mbit/sec)", "%lu", bitrate}, + {"bins to bit factor", DUMP_FP_FMT, bins_to_bit_factor}, + {"original compression factor", DUMP_FP_FMT, + original_compression_factor}, + {"original compression factor y", DUMP_FP_FMT, + original_compression_factor_y}, + {"mese read factor", DUMP_FP_FMT, + mese_read_factor}, + {"qsmmu_bw_overhead_factor", + DUMP_FP_FMT, qsmmu_bw_overhead_factor}, + {"bw for NV12 8bpc)", DUMP_FP_FMT, y_bw_no_ubwc_8bpp}, + {"bw for NV12 10bpc)", DUMP_FP_FMT, y_bw_no_ubwc_10bpp}, + + {"INTERMEDIATE B/W DDR", "", DUMP_HEADER_MAGIC}, + {"vsp read", DUMP_FP_FMT, ddr.vsp_read}, + {"vsp write", DUMP_FP_FMT, ddr.vsp_write}, + {"collocated read", DUMP_FP_FMT, ddr.collocated_read}, + {"collocated write", DUMP_FP_FMT, ddr.collocated_write}, + {"ref read y", DUMP_FP_FMT, ddr.ref_read_y}, + {"ref read crcb", DUMP_FP_FMT, ddr.ref_read_crcb}, + {"ref write", DUMP_FP_FMT, ddr.ref_write}, + {"ref write overlap", DUMP_FP_FMT, ddr.ref_write_overlap}, + {"original read", DUMP_FP_FMT, ddr.orig_read}, + {"line buffer read", DUMP_FP_FMT, ddr.line_buffer_read}, + {"line buffer write", DUMP_FP_FMT, ddr.line_buffer_write}, + {"mese read", DUMP_FP_FMT, ddr.mese_read}, + {"mese write", DUMP_FP_FMT, ddr.mese_write}, + {"INTERMEDIATE LLC B/W", "", DUMP_HEADER_MAGIC}, + {"llc ref read crcb", DUMP_FP_FMT, llc.ref_read_crcb}, + {"llc line buffer", DUMP_FP_FMT, llc.line_buffer}, + }; + __dump(dump, ARRAY_SIZE(dump)); + } + + switch (type) { + case DDR: + ret = kbps(fp_round(ddr.total)); + break; + case LLCC: + ret = kbps(fp_round(llc.total)); + break; + default: + dprintk(VIDC_ERR, "%s - Unknown type\n", __func__); + } + + return ret; +} + +static unsigned long __calculate(struct vidc_bus_vote_data *d, + enum vidc_bus_type type) +{ + unsigned long value = 0; + + switch (d->domain) { + case HAL_VIDEO_DOMAIN_VPE: + value = __calculate_vpe(d, type); + break; + case HAL_VIDEO_DOMAIN_ENCODER: + value = __calculate_encoder(d, type); + break; + case HAL_VIDEO_DOMAIN_DECODER: + value = __calculate_decoder(d, type); + break; + case HAL_VIDEO_DOMAIN_CVP: + value = __calculate_cvp(d, type); + break; + default: + dprintk(VIDC_ERR, "Unknown Domain"); + } + + return value; +} + +unsigned long calc_bw_iris1(struct bus_info *bus, + struct msm_vidc_bus_data *vidc_data) +{ + unsigned long ab_kbps = 0, c = 0; + enum vidc_bus_type type; + + if (!vidc_data || !vidc_data->data_count || !vidc_data->data) + goto exit; + + for (c = 0; c < vidc_data->data_count; ++c) { + if (vidc_data->data->power_mode == VIDC_POWER_TURBO) { + ab_kbps = INT_MAX; + goto exit; + } + } + + type = get_type_frm_name(bus->name); + + for (c = 0; c < vidc_data->data_count; ++c) + ab_kbps += __calculate(&vidc_data->data[c], type); + +exit: + trace_msm_vidc_perf_bus_vote(bus->name, ab_kbps); + return ab_kbps; +} + diff --git a/msm/vidc/msm_vidc_bus_iris2.c b/msm/vidc/msm_vidc_bus_iris2.c new file mode 100644 index 000000000000..400ca9991314 --- /dev/null +++ b/msm/vidc/msm_vidc_bus_iris2.c @@ -0,0 +1,637 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + */ + +#include "msm_vidc_bus.h" +#include "msm_vidc_internal.h" + +static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d, + enum vidc_bus_type type) +{ + return 0; +} + +static unsigned long __calculate_cvp(struct vidc_bus_vote_data *d, + enum vidc_bus_type type) +{ + unsigned long ret = 0; + + switch (type) { + case DDR: + ret = d->ddr_bw; + break; + case LLCC: + ret = d->sys_cache_bw; + break; + default: + dprintk(VIDC_ERR, "%s - Unknown type\n", __func__); + break; + } + + return ret; +} + +static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, + enum vidc_bus_type type) +{ + /* + * XXX: Don't fool around with any of the hardcoded numbers unless you + * know /exactly/ what you're doing. Many of these numbers are + * measured heuristics and hardcoded numbers taken from the firmware. + */ + /* Decoder parameters */ + int width, height, lcu_size, fps, dpb_bpp; + bool unified_dpb_opb, dpb_compression_enabled = true, + opb_compression_enabled = false, + llc_ref_read_l2_cache_enabled = false, + llc_top_line_buf_enabled = false; + fp_t dpb_read_compression_factor, dpb_opb_scaling_ratio, + dpb_write_compression_factor, opb_write_compression_factor, + qsmmu_bw_overhead_factor; + bool is_h264_category = true; + + /* Derived parameters */ + int lcu_per_frame, collocated_bytes_per_lcu, tnbr_per_lcu; + unsigned long bitrate; + + fp_t bins_to_bit_factor, vsp_read_factor, vsp_write_factor, + dpb_factor, dpb_write_factor, + y_bw_no_ubwc_8bpp, y_bw_no_ubwc_10bpp, y_bw_10bpp_p010, + motion_vector_complexity = 0; + fp_t dpb_total = 0; + + /* Output parameters */ + struct { + fp_t vsp_read, vsp_write, collocated_read, collocated_write, + dpb_read, dpb_write, opb_read, opb_write, + line_buffer_read, line_buffer_write, + total; + } ddr = {0}; + + struct { + fp_t dpb_read, line_buffer_read, line_buffer_write, total; + } llc = {0}; + + unsigned long ret = 0; + unsigned int integer_part, frac_part; + + width = max(d->input_width, BASELINE_DIMENSIONS.width); + height = max(d->input_height, BASELINE_DIMENSIONS.height); + + fps = d->fps; + + lcu_size = d->lcu_size; + + dpb_bpp = d->num_formats >= 1 ? __bpp(d->color_formats[0]) : INT_MAX; + + unified_dpb_opb = d->num_formats == 1; + + dpb_opb_scaling_ratio = fp_div(FP_INT(d->input_width * d->input_height), + FP_INT(d->output_width * d->output_height)); + + opb_compression_enabled = d->num_formats >= 2 && + __ubwc(d->color_formats[1]); + + /* + * convert q16 number into integer and fractional part upto 2 places. + * ex : 105752 / 65536 = 1.61; 1.61 in q16 = 105752; + * integer part = 105752 / 65536 = 1; + * reminder = 105752 - 1 * 65536 = 40216; + * fractional part = 40216 * 100 / 65536 = 61; + * now converto to fp(1, 61, 100) for below code. + */ + + integer_part = d->compression_ratio >> 16; + frac_part = + ((d->compression_ratio - (integer_part << 16)) * 100) >> 16; + + dpb_read_compression_factor = FP(integer_part, frac_part, 100); + + integer_part = d->complexity_factor >> 16; + frac_part = + ((d->complexity_factor - (integer_part << 16)) * 100) >> 16; + + motion_vector_complexity = FP(integer_part, frac_part, 100); + + dpb_write_compression_factor = dpb_read_compression_factor; + opb_write_compression_factor = opb_compression_enabled ? + dpb_write_compression_factor : FP_ONE; + + if (d->codec == HAL_VIDEO_CODEC_HEVC || + d->codec == HAL_VIDEO_CODEC_VP9) { + /* H264, VP8, MPEG2 use the same settings */ + /* HEVC, VP9 use the same setting */ + is_h264_category = false; + } + if (d->use_sys_cache) { + llc_ref_read_l2_cache_enabled = true; + if (is_h264_category) + llc_top_line_buf_enabled = true; + } + + /* Derived parameters setup */ + lcu_per_frame = DIV_ROUND_UP(width, lcu_size) * + DIV_ROUND_UP(height, lcu_size); + + bitrate = __lut(width, height, fps)->bitrate; + + bins_to_bit_factor = FP_INT(4); + + vsp_write_factor = bins_to_bit_factor; + vsp_read_factor = bins_to_bit_factor + FP_INT(2); + + collocated_bytes_per_lcu = lcu_size == 16 ? 16 : + lcu_size == 32 ? 64 : 256; + + dpb_factor = FP(1, 50, 100); + dpb_write_factor = FP(1, 5, 100); + + tnbr_per_lcu = lcu_size == 16 ? 128 : + lcu_size == 32 ? 64 : 128; + + /* .... For DDR & LLC ...... */ + ddr.vsp_read = fp_div(fp_mult(FP_INT(bitrate), + vsp_read_factor), FP_INT(8)); + ddr.vsp_write = fp_div(fp_mult(FP_INT(bitrate), + vsp_write_factor), FP_INT(8)); + + ddr.collocated_read = fp_div(FP_INT(lcu_per_frame * + collocated_bytes_per_lcu * fps), FP_INT(bps(1))); + ddr.collocated_write = ddr.collocated_read; + + y_bw_no_ubwc_8bpp = fp_div(fp_mult( + FP_INT((int)(width * height)), FP_INT((int)fps)), + FP_INT(1000 * 1000)); + y_bw_no_ubwc_10bpp = fp_div(fp_mult(y_bw_no_ubwc_8bpp, FP_INT(256)), + FP_INT(192)); + y_bw_10bpp_p010 = y_bw_no_ubwc_8bpp * 2; + + ddr.dpb_read = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; + ddr.dpb_read = fp_div(fp_mult(ddr.dpb_read, + fp_mult(dpb_factor, motion_vector_complexity)), + dpb_read_compression_factor); + + ddr.dpb_write = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; + ddr.dpb_write = fp_div(fp_mult(ddr.dpb_write, + fp_mult(dpb_factor, dpb_write_factor)), + dpb_write_compression_factor); + + dpb_total = ddr.dpb_read + ddr.dpb_write; + + if (llc_ref_read_l2_cache_enabled) { + ddr.dpb_read = fp_div(ddr.dpb_read, is_h264_category ? + FP(1, 15, 100) : FP(1, 30, 100)); + llc.dpb_read = dpb_total - ddr.dpb_write - ddr.dpb_read; + } + + ddr.opb_read = FP_ZERO; + ddr.opb_write = unified_dpb_opb ? FP_ZERO : (dpb_bpp == 8 ? + y_bw_no_ubwc_8bpp : (opb_compression_enabled ? + y_bw_no_ubwc_10bpp : y_bw_10bpp_p010)); + ddr.opb_write = fp_div(fp_mult(dpb_factor, ddr.opb_write), + fp_mult(dpb_opb_scaling_ratio, opb_write_compression_factor)); + + ddr.line_buffer_read = FP_INT(tnbr_per_lcu * + lcu_per_frame * fps / bps(1)); + ddr.line_buffer_write = ddr.line_buffer_read; + if (llc_top_line_buf_enabled) { + llc.line_buffer_read = ddr.line_buffer_read; + llc.line_buffer_write = ddr.line_buffer_write; + ddr.line_buffer_write = ddr.line_buffer_read = FP_ZERO; + } + + ddr.total = ddr.vsp_read + ddr.vsp_write + + ddr.collocated_read + ddr.collocated_write + + ddr.dpb_read + ddr.dpb_write + + ddr.opb_read + ddr.opb_write + + ddr.line_buffer_read + ddr.line_buffer_write; + + qsmmu_bw_overhead_factor = FP(1, 3, 100); + + ddr.total = fp_mult(ddr.total, qsmmu_bw_overhead_factor); + llc.total = llc.dpb_read + llc.line_buffer_read + + llc.line_buffer_write + ddr.total; + + /* Dump all the variables for easier debugging */ + if (msm_vidc_debug & VIDC_PROF) { + struct dump dump[] = { + {"DECODER PARAMETERS", "", DUMP_HEADER_MAGIC}, + {"lcu size", "%d", lcu_size}, + {"dpb bitdepth", "%d", dpb_bpp}, + {"frame rate", "%d", fps}, + {"dpb/opb unified", "%d", unified_dpb_opb}, + {"dpb/opb downscaling ratio", DUMP_FP_FMT, + dpb_opb_scaling_ratio}, + {"dpb compression", "%d", dpb_compression_enabled}, + {"opb compression", "%d", opb_compression_enabled}, + {"dpb read compression factor", DUMP_FP_FMT, + dpb_read_compression_factor}, + {"dpb write compression factor", DUMP_FP_FMT, + dpb_write_compression_factor}, + {"frame width", "%d", width}, + {"frame height", "%d", height}, + {"llc ref read l2 cache enabled", "%d", + llc_ref_read_l2_cache_enabled}, + {"llc top line buf enabled", "%d", + llc_top_line_buf_enabled}, + + {"DERIVED PARAMETERS (1)", "", DUMP_HEADER_MAGIC}, + {"lcus/frame", "%d", lcu_per_frame}, + {"bitrate (Mbit/sec)", "%d", bitrate}, + {"bins to bit factor", DUMP_FP_FMT, bins_to_bit_factor}, + {"dpb write factor", DUMP_FP_FMT, dpb_write_factor}, + {"vsp read factor", DUMP_FP_FMT, vsp_read_factor}, + {"vsp write factor", DUMP_FP_FMT, vsp_write_factor}, + {"tnbr/lcu", "%d", tnbr_per_lcu}, + {"collocated bytes/LCU", "%d", collocated_bytes_per_lcu}, + {"bw for NV12 8bpc)", DUMP_FP_FMT, y_bw_no_ubwc_8bpp}, + {"bw for NV12 10bpc)", DUMP_FP_FMT, y_bw_no_ubwc_10bpp}, + + {"DERIVED PARAMETERS (2)", "", DUMP_HEADER_MAGIC}, + {"mv complexity", DUMP_FP_FMT, motion_vector_complexity}, + {"qsmmu_bw_overhead_factor", DUMP_FP_FMT, + qsmmu_bw_overhead_factor}, + + {"INTERMEDIATE DDR B/W", "", DUMP_HEADER_MAGIC}, + {"vsp read", DUMP_FP_FMT, ddr.vsp_read}, + {"vsp write", DUMP_FP_FMT, ddr.vsp_write}, + {"collocated read", DUMP_FP_FMT, ddr.collocated_read}, + {"collocated write", DUMP_FP_FMT, ddr.collocated_write}, + {"line buffer read", DUMP_FP_FMT, ddr.line_buffer_read}, + {"line buffer write", DUMP_FP_FMT, ddr.line_buffer_write}, + {"opb read", DUMP_FP_FMT, ddr.opb_read}, + {"opb write", DUMP_FP_FMT, ddr.opb_write}, + {"dpb read", DUMP_FP_FMT, ddr.dpb_read}, + {"dpb write", DUMP_FP_FMT, ddr.dpb_write}, + {"dpb total", DUMP_FP_FMT, dpb_total}, + {"INTERMEDIATE LLC B/W", "", DUMP_HEADER_MAGIC}, + {"llc dpb read", DUMP_FP_FMT, llc.dpb_read}, + {"llc line buffer read", DUMP_FP_FMT, llc.line_buffer_read}, + {"llc line buffer write", DUMP_FP_FMT, llc.line_buffer_write}, + + }; + __dump(dump, ARRAY_SIZE(dump)); + } + + switch (type) { + case DDR: + ret = kbps(fp_round(ddr.total)); + break; + case LLCC: + ret = kbps(fp_round(llc.total)); + break; + default: + dprintk(VIDC_ERR, "%s - Unknown type\n", __func__); + } + + return ret; +} + +static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, + enum vidc_bus_type type) +{ + /* + * XXX: Don't fool around with any of the hardcoded numbers unless you + * know /exactly/ what you're doing. Many of these numbers are + * measured heuristics and hardcoded numbers taken from the firmware. + */ + /* Encoder Parameters */ + int width, height, fps, lcu_size, bitrate, lcu_per_frame, + collocated_bytes_per_lcu, tnbr_per_lcu, dpb_bpp, + original_color_format, vertical_tile_width, rotation; + bool work_mode_1, original_compression_enabled, + low_power, cropping_or_scaling, + b_frames_enabled = false, + llc_ref_chroma_cache_enabled = false, + llc_top_line_buf_enabled = false, + llc_vpss_rot_line_buf_enabled = false; + + fp_t bins_to_bit_factor, dpb_compression_factor, + original_compression_factor, + original_compression_factor_y, + y_bw_no_ubwc_8bpp, y_bw_no_ubwc_10bpp, y_bw_10bpp_p010, + input_compression_factor, + downscaling_ratio, + ref_y_read_bw_factor, ref_cbcr_read_bw_factor, + recon_write_bw_factor, mese_read_factor, + total_ref_read_crcb, + qsmmu_bw_overhead_factor; + fp_t integer_part, frac_part; + unsigned long ret = 0; + + /* Output parameters */ + struct { + fp_t vsp_read, vsp_write, collocated_read, collocated_write, + ref_read_y, ref_read_crcb, ref_write, + ref_write_overlap, orig_read, + line_buffer_read, line_buffer_write, + mese_read, mese_write, + total; + } ddr = {0}; + + struct { + fp_t ref_read_crcb, line_buffer, total; + } llc = {0}; + + /* Encoder Parameters setup */ + rotation = d->rotation; + cropping_or_scaling = false; + vertical_tile_width = 960; + recon_write_bw_factor = FP(1, 8, 100); + ref_y_read_bw_factor = FP(1, 30, 100); + ref_cbcr_read_bw_factor = FP(1, 50, 100); + + + /* Derived Parameters */ + fps = d->fps; + width = max(d->output_width, BASELINE_DIMENSIONS.width); + height = max(d->output_height, BASELINE_DIMENSIONS.height); + downscaling_ratio = fp_div(FP_INT(d->input_width * d->input_height), + FP_INT(d->output_width * d->output_height)); + downscaling_ratio = max(downscaling_ratio, FP_ONE); + bitrate = d->bitrate > 0 ? d->bitrate / 1000000 : + __lut(width, height, fps)->bitrate; + lcu_size = d->lcu_size; + lcu_per_frame = DIV_ROUND_UP(width, lcu_size) * + DIV_ROUND_UP(height, lcu_size); + tnbr_per_lcu = 16; + + y_bw_no_ubwc_8bpp = fp_div(fp_mult( + FP_INT((int)(width * height)), FP_INT(fps)), + FP_INT(1000 * 1000)); + y_bw_no_ubwc_10bpp = fp_div(fp_mult(y_bw_no_ubwc_8bpp, + FP_INT(256)), FP_INT(192)); + y_bw_10bpp_p010 = y_bw_no_ubwc_8bpp * 2; + + b_frames_enabled = d->b_frames_enabled; + original_color_format = d->num_formats >= 1 ? + d->color_formats[0] : HAL_UNUSED_COLOR; + + dpb_bpp = d->num_formats >= 1 ? __bpp(d->color_formats[0]) : INT_MAX; + + original_compression_enabled = __ubwc(original_color_format); + + work_mode_1 = d->work_mode == HFI_WORKMODE_1; + low_power = d->power_mode == VIDC_POWER_LOW; + bins_to_bit_factor = FP_INT(4); + + if (d->use_sys_cache) { + llc_ref_chroma_cache_enabled = true; + llc_top_line_buf_enabled = true, + llc_vpss_rot_line_buf_enabled = true; + } + + /* + * Convert Q16 number into Integer and Fractional part upto 2 places. + * Ex : 105752 / 65536 = 1.61; 1.61 in Q16 = 105752; + * Integer part = 105752 / 65536 = 1; + * Reminder = 105752 - 1 * 65536 = 40216; + * Fractional part = 40216 * 100 / 65536 = 61; + * Now converto to FP(1, 61, 100) for below code. + */ + + integer_part = d->compression_ratio >> 16; + frac_part = + ((d->compression_ratio - (integer_part * 65536)) * 100) >> 16; + + dpb_compression_factor = FP(integer_part, frac_part, 100); + + integer_part = d->input_cr >> 16; + frac_part = + ((d->input_cr - (integer_part * 65536)) * 100) >> 16; + + input_compression_factor = FP(integer_part, frac_part, 100); + + original_compression_factor = original_compression_factor_y = + !original_compression_enabled ? FP_ONE : + __compression_ratio(__lut(width, height, fps), dpb_bpp); + /* use input cr if it is valid (not 1), otherwise use lut */ + if (original_compression_enabled && + input_compression_factor != FP_ONE) { + original_compression_factor = input_compression_factor; + /* Luma usually has lower compression factor than Chroma, + * input cf is overall cf, add 1.08 factor for Luma cf + */ + original_compression_factor_y = + input_compression_factor > FP(1, 8, 100) ? + fp_div(input_compression_factor, FP(1, 8, 100)) : + input_compression_factor; + } + + mese_read_factor = fp_div(FP_INT((width * height * fps)/4), + original_compression_factor_y); + mese_read_factor = fp_div(fp_mult(mese_read_factor, FP(2, 53, 100)), + FP_INT(1000 * 1000)); + + ddr.vsp_read = fp_div(fp_mult(FP_INT(bitrate), bins_to_bit_factor), + FP_INT(8)); + ddr.vsp_write = ddr.vsp_read + fp_div(FP_INT(bitrate), FP_INT(8)); + + collocated_bytes_per_lcu = lcu_size == 16 ? 16 : + lcu_size == 32 ? 64 : 256; + + ddr.collocated_read = fp_div(FP_INT(lcu_per_frame * + collocated_bytes_per_lcu * fps), FP_INT(bps(1))); + + ddr.collocated_write = ddr.collocated_read; + + ddr.ref_read_y = ddr.ref_read_crcb = dpb_bpp == 8 ? + y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; + + if (width != vertical_tile_width) { + ddr.ref_read_y = fp_mult(ddr.ref_read_y, + ref_y_read_bw_factor); + } + + ddr.ref_read_y = fp_div(ddr.ref_read_y, dpb_compression_factor); + if (b_frames_enabled) + ddr.ref_read_y = fp_mult(ddr.ref_read_y, FP_INT(2)); + + ddr.ref_read_crcb = fp_mult(ddr.ref_read_crcb, FP(0, 50, 100)); + ddr.ref_read_crcb = fp_div(ddr.ref_read_crcb, dpb_compression_factor); + if (b_frames_enabled) + ddr.ref_read_crcb = fp_mult(ddr.ref_read_crcb, FP_INT(2)); + + if (llc_ref_chroma_cache_enabled) { + total_ref_read_crcb = ddr.ref_read_crcb; + ddr.ref_read_crcb = fp_div(ddr.ref_read_crcb, + ref_cbcr_read_bw_factor); + llc.ref_read_crcb = total_ref_read_crcb - ddr.ref_read_crcb; + } + + ddr.ref_write = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; + ddr.ref_write = fp_mult(ddr.ref_write, + (fp_div(FP(1, 50, 100), dpb_compression_factor))); + + ddr.ref_write_overlap = fp_div(fp_mult(ddr.ref_write, + (recon_write_bw_factor - FP_ONE)), + recon_write_bw_factor); + + ddr.orig_read = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : + (original_compression_enabled ? y_bw_no_ubwc_10bpp : + y_bw_10bpp_p010); + ddr.orig_read = fp_div(fp_mult(fp_mult(ddr.orig_read, FP(1, 50, 100)), + downscaling_ratio), original_compression_factor); + if (rotation == 90 || rotation == 270) + ddr.orig_read *= lcu_size == 32 ? (dpb_bpp == 8 ? 1 : 3) : 2; + + ddr.line_buffer_read = FP_INT(tnbr_per_lcu * lcu_per_frame * + fps / bps(1)); + + ddr.line_buffer_write = ddr.line_buffer_read; + if (llc_top_line_buf_enabled) { + llc.line_buffer = ddr.line_buffer_read + ddr.line_buffer_write; + ddr.line_buffer_read = ddr.line_buffer_write = FP_ZERO; + } + + ddr.mese_read = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; + ddr.mese_read = fp_div(fp_mult(ddr.mese_read, FP(1, 37, 100)), + original_compression_factor_y) + mese_read_factor; + + ddr.mese_write = FP_INT((width * height)/512) + + fp_div(FP_INT((width * height)/4), + original_compression_factor_y) + + FP_INT((width * height)/128); + ddr.mese_write = fp_div(fp_mult(ddr.mese_write, FP_INT(fps)), + FP_INT(1000 * 1000)); + + ddr.total = ddr.vsp_read + ddr.vsp_write + + ddr.collocated_read + ddr.collocated_write + + ddr.ref_read_y + ddr.ref_read_crcb + + ddr.ref_write + ddr.ref_write_overlap + + ddr.orig_read + + ddr.line_buffer_read + ddr.line_buffer_write + + ddr.mese_read + ddr.mese_write; + + qsmmu_bw_overhead_factor = FP(1, 3, 100); + ddr.total = fp_mult(ddr.total, qsmmu_bw_overhead_factor); + llc.total = llc.ref_read_crcb + llc.line_buffer + ddr.total; + + if (msm_vidc_debug & VIDC_PROF) { + struct dump dump[] = { + {"ENCODER PARAMETERS", "", DUMP_HEADER_MAGIC}, + {"width", "%d", width}, + {"height", "%d", height}, + {"fps", "%d", fps}, + {"dpb bitdepth", "%d", dpb_bpp}, + {"input downscaling ratio", DUMP_FP_FMT, downscaling_ratio}, + {"rotation", "%d", rotation}, + {"cropping or scaling", "%d", cropping_or_scaling}, + {"low power mode", "%d", low_power}, + {"work Mode", "%d", work_mode_1}, + {"B frame enabled", "%d", b_frames_enabled}, + {"original frame format", "%#x", original_color_format}, + {"original compression enabled", "%d", + original_compression_enabled}, + {"dpb compression factor", DUMP_FP_FMT, + dpb_compression_factor}, + {"input compression factor", DUMP_FP_FMT, + input_compression_factor}, + {"llc ref chroma cache enabled", DUMP_FP_FMT, + llc_ref_chroma_cache_enabled}, + {"llc top line buf enabled", DUMP_FP_FMT, + llc_top_line_buf_enabled}, + {"llc vpss rot line buf enabled ", DUMP_FP_FMT, + llc_vpss_rot_line_buf_enabled}, + + {"DERIVED PARAMETERS", "", DUMP_HEADER_MAGIC}, + {"lcu size", "%d", lcu_size}, + {"bitrate (Mbit/sec)", "%lu", bitrate}, + {"bins to bit factor", DUMP_FP_FMT, bins_to_bit_factor}, + {"original compression factor", DUMP_FP_FMT, + original_compression_factor}, + {"original compression factor y", DUMP_FP_FMT, + original_compression_factor_y}, + {"mese read factor", DUMP_FP_FMT, + mese_read_factor}, + {"qsmmu_bw_overhead_factor", + DUMP_FP_FMT, qsmmu_bw_overhead_factor}, + {"bw for NV12 8bpc)", DUMP_FP_FMT, y_bw_no_ubwc_8bpp}, + {"bw for NV12 10bpc)", DUMP_FP_FMT, y_bw_no_ubwc_10bpp}, + + {"INTERMEDIATE B/W DDR", "", DUMP_HEADER_MAGIC}, + {"vsp read", DUMP_FP_FMT, ddr.vsp_read}, + {"vsp write", DUMP_FP_FMT, ddr.vsp_write}, + {"collocated read", DUMP_FP_FMT, ddr.collocated_read}, + {"collocated write", DUMP_FP_FMT, ddr.collocated_write}, + {"ref read y", DUMP_FP_FMT, ddr.ref_read_y}, + {"ref read crcb", DUMP_FP_FMT, ddr.ref_read_crcb}, + {"ref write", DUMP_FP_FMT, ddr.ref_write}, + {"ref write overlap", DUMP_FP_FMT, ddr.ref_write_overlap}, + {"original read", DUMP_FP_FMT, ddr.orig_read}, + {"line buffer read", DUMP_FP_FMT, ddr.line_buffer_read}, + {"line buffer write", DUMP_FP_FMT, ddr.line_buffer_write}, + {"mese read", DUMP_FP_FMT, ddr.mese_read}, + {"mese write", DUMP_FP_FMT, ddr.mese_write}, + {"INTERMEDIATE LLC B/W", "", DUMP_HEADER_MAGIC}, + {"llc ref read crcb", DUMP_FP_FMT, llc.ref_read_crcb}, + {"llc line buffer", DUMP_FP_FMT, llc.line_buffer}, + }; + __dump(dump, ARRAY_SIZE(dump)); + } + + switch (type) { + case DDR: + ret = kbps(fp_round(ddr.total)); + break; + case LLCC: + ret = kbps(fp_round(llc.total)); + break; + default: + dprintk(VIDC_ERR, "%s - Unknown governor\n", __func__); + } + + return ret; +} + +static unsigned long __calculate(struct vidc_bus_vote_data *d, + enum vidc_bus_type type) +{ + unsigned long value = 0; + + switch (d->domain) { + case HAL_VIDEO_DOMAIN_VPE: + value = __calculate_vpe(d, type); + break; + case HAL_VIDEO_DOMAIN_ENCODER: + value = __calculate_encoder(d, type); + break; + case HAL_VIDEO_DOMAIN_DECODER: + value = __calculate_decoder(d, type); + break; + case HAL_VIDEO_DOMAIN_CVP: + value = __calculate_cvp(d, type); + break; + default: + dprintk(VIDC_ERR, "Unknown Domain"); + } + + return value; +} + +unsigned long calc_bw_iris2(struct bus_info *bus, + struct msm_vidc_bus_data *vidc_data) +{ + unsigned long ab_kbps = 0, c = 0; + enum vidc_bus_type type; + + if (!vidc_data || !vidc_data->data_count || !vidc_data->data) + goto exit; + + for (c = 0; c < vidc_data->data_count; ++c) { + if (vidc_data->data->power_mode == VIDC_POWER_TURBO) { + ab_kbps = INT_MAX; + goto exit; + } + } + + type = get_type_frm_name(bus->name); + + for (c = 0; c < vidc_data->data_count; ++c) + ab_kbps += __calculate(&vidc_data->data[c], type); + +exit: + trace_msm_vidc_perf_bus_vote(bus->name, ab_kbps); + return ab_kbps; +} diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c new file mode 100644 index 000000000000..b85ce570be64 --- /dev/null +++ b/msm/vidc/msm_vidc_clocks.c @@ -0,0 +1,1828 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + */ + +#include "msm_vidc_common.h" +#include "vidc_hfi_api.h" +#include "msm_vidc_debug.h" +#include "msm_vidc_clocks.h" +#include "msm_vidc_buffer_calculations.h" +#include "msm_vidc_bus.h" + +#define MSM_VIDC_MIN_UBWC_COMPLEXITY_FACTOR (1 << 16) +#define MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR (4 << 16) + +#define MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO (1 << 16) +#define MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO (5 << 16) + +static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst); +static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, + u32 filled_len); +static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst, + u32 filled_len); +static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, + u32 filled_len); + +struct msm_vidc_core_ops core_ops_ar50 = { + .calc_freq = msm_vidc_calc_freq_ar50, + .decide_work_route = NULL, + .decide_work_mode = msm_vidc_decide_work_mode_ar50, + .decide_core_and_power_mode = NULL, +}; + +struct msm_vidc_core_ops core_ops_iris1 = { + .calc_freq = msm_vidc_calc_freq_iris1, + .decide_work_route = msm_vidc_decide_work_route_iris1, + .decide_work_mode = msm_vidc_decide_work_mode_iris1, + .decide_core_and_power_mode = msm_vidc_decide_core_and_power_mode_iris1, +}; + +struct msm_vidc_core_ops core_ops_iris2 = { + .calc_freq = msm_vidc_calc_freq_iris2, + .decide_work_route = msm_vidc_decide_work_route_iris2, + .decide_work_mode = msm_vidc_decide_work_mode_iris2, + .decide_core_and_power_mode = msm_vidc_decide_core_and_power_mode_iris2, +}; + +static inline void msm_dcvs_print_dcvs_stats(struct clock_data *dcvs) +{ + dprintk(VIDC_PROF, + "DCVS: Load_Low %lld, Load Norm %lld, Load High %lld\n", + dcvs->load_low, + dcvs->load_norm, + dcvs->load_high); + + dprintk(VIDC_PROF, + "DCVS: min_threshold %d, max_threshold %d\n", + dcvs->min_threshold, dcvs->max_threshold); +} + +static inline unsigned long get_ubwc_compression_ratio( + struct ubwc_cr_stats_info_type ubwc_stats_info) +{ + unsigned long sum = 0, weighted_sum = 0; + unsigned long compression_ratio = 0; + + weighted_sum = + 32 * ubwc_stats_info.cr_stats_info0 + + 64 * ubwc_stats_info.cr_stats_info1 + + 96 * ubwc_stats_info.cr_stats_info2 + + 128 * ubwc_stats_info.cr_stats_info3 + + 160 * ubwc_stats_info.cr_stats_info4 + + 192 * ubwc_stats_info.cr_stats_info5 + + 256 * ubwc_stats_info.cr_stats_info6; + + sum = + ubwc_stats_info.cr_stats_info0 + + ubwc_stats_info.cr_stats_info1 + + ubwc_stats_info.cr_stats_info2 + + ubwc_stats_info.cr_stats_info3 + + ubwc_stats_info.cr_stats_info4 + + ubwc_stats_info.cr_stats_info5 + + ubwc_stats_info.cr_stats_info6; + + compression_ratio = (weighted_sum && sum) ? + ((256 * sum) << 16) / weighted_sum : compression_ratio; + + return compression_ratio; +} + +bool res_is_less_than(u32 width, u32 height, + u32 ref_width, u32 ref_height) +{ + u32 num_mbs = NUM_MBS_PER_FRAME(height, width); + u32 max_side = max(ref_width, ref_height); + + if (num_mbs < NUM_MBS_PER_FRAME(ref_height, ref_width) && + width < max_side && + height < max_side) + return true; + else + return false; +} + +bool res_is_greater_than(u32 width, u32 height, + u32 ref_width, u32 ref_height) +{ + u32 num_mbs = NUM_MBS_PER_FRAME(height, width); + u32 max_side = max(ref_width, ref_height); + + if (num_mbs > NUM_MBS_PER_FRAME(ref_height, ref_width) || + width > max_side || + height > max_side) + return true; + else + return false; +} + +int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst) +{ + int height, width; + struct v4l2_format *out_f; + struct v4l2_format *inp_f; + + out_f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + inp_f = &inst->fmts[INPUT_PORT].v4l2_fmt; + if (!inst->in_reconfig) { + height = max(out_f->fmt.pix_mp.height, + inp_f->fmt.pix_mp.height); + width = max(out_f->fmt.pix_mp.width, + inp_f->fmt.pix_mp.width); + } else { + height = inst->reconfig_height; + width = inst->reconfig_width; + } + + return NUM_MBS_PER_FRAME(height, width); +} + +static int msm_vidc_get_fps(struct msm_vidc_inst *inst) +{ + int fps; + + if (inst->clk_data.operating_rate > inst->clk_data.frame_rate) + fps = (inst->clk_data.operating_rate >> 16) ? + (inst->clk_data.operating_rate >> 16) : 1; + else + fps = inst->clk_data.frame_rate >> 16; + + return fps; +} + +void update_recon_stats(struct msm_vidc_inst *inst, + struct recon_stats_type *recon_stats) +{ + struct recon_buf *binfo; + u32 CR = 0, CF = 0; + u32 frame_size; + + CR = get_ubwc_compression_ratio(recon_stats->ubwc_stats_info); + + frame_size = (msm_vidc_get_mbs_per_frame(inst) / (32 * 8) * 3) / 2; + + if (frame_size) + CF = recon_stats->complexity_number / frame_size; + else + CF = MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR; + + mutex_lock(&inst->reconbufs.lock); + list_for_each_entry(binfo, &inst->reconbufs.list, list) { + if (binfo->buffer_index == + recon_stats->buffer_index) { + binfo->CR = CR; + binfo->CF = CF; + } + } + mutex_unlock(&inst->reconbufs.lock); +} + +static int fill_dynamic_stats(struct msm_vidc_inst *inst, + struct vidc_bus_vote_data *vote_data) +{ + struct recon_buf *binfo, *nextb; + struct vidc_input_cr_data *temp, *next; + u32 min_cf = MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR, max_cf = 0; + u32 min_input_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO, + max_input_cr = 0; + u32 min_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO, max_cr = 0; + + mutex_lock(&inst->reconbufs.lock); + list_for_each_entry_safe(binfo, nextb, &inst->reconbufs.list, list) { + if (binfo->CR) { + min_cr = min(min_cr, binfo->CR); + max_cr = max(max_cr, binfo->CR); + } + if (binfo->CF) { + min_cf = min(min_cf, binfo->CF); + max_cf = max(max_cf, binfo->CF); + } + } + mutex_unlock(&inst->reconbufs.lock); + + mutex_lock(&inst->input_crs.lock); + list_for_each_entry_safe(temp, next, &inst->input_crs.list, list) { + min_input_cr = min(min_input_cr, temp->input_cr); + max_input_cr = max(max_input_cr, temp->input_cr); + } + mutex_unlock(&inst->input_crs.lock); + + /* Sanitize CF values from HW . */ + max_cf = min_t(u32, max_cf, MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR); + min_cf = max_t(u32, min_cf, MSM_VIDC_MIN_UBWC_COMPLEXITY_FACTOR); + max_cr = min_t(u32, max_cr, MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO); + min_cr = max_t(u32, min_cr, MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO); + max_input_cr = min_t(u32, + max_input_cr, MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO); + min_input_cr = max_t(u32, + min_input_cr, MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO); + + vote_data->compression_ratio = min_cr; + vote_data->complexity_factor = max_cf; + vote_data->input_cr = min_input_cr; + vote_data->use_dpb_read = false; + + /* Check if driver can vote for lower bus BW */ + if (inst->clk_data.load < inst->clk_data.load_norm) { + vote_data->compression_ratio = max_cr; + vote_data->complexity_factor = min_cf; + vote_data->input_cr = max_input_cr; + vote_data->use_dpb_read = true; + } + + dprintk(VIDC_PROF, + "Input CR = %d Recon CR = %d Complexity Factor = %d\n", + vote_data->input_cr, vote_data->compression_ratio, + vote_data->complexity_factor); + + return 0; +} + +int msm_comm_vote_bus(struct msm_vidc_core *core) +{ + int rc = 0, vote_data_count = 0, i = 0; + struct hfi_device *hdev; + struct msm_vidc_inst *inst = NULL; + struct vidc_bus_vote_data *vote_data = NULL; + bool is_turbo = false; + struct v4l2_format *out_f; + struct v4l2_format *inp_f; + + if (!core || !core->device) { + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core); + return -EINVAL; + } + hdev = core->device; + + vote_data = kzalloc(sizeof(struct vidc_bus_vote_data) * + MAX_SUPPORTED_INSTANCES, GFP_ATOMIC); + if (!vote_data) { + dprintk(VIDC_DBG, + "vote_data allocation with GFP_ATOMIC failed\n"); + vote_data = kzalloc(sizeof(struct vidc_bus_vote_data) * + MAX_SUPPORTED_INSTANCES, GFP_KERNEL); + if (!vote_data) { + dprintk(VIDC_DBG, + "vote_data allocation failed\n"); + return -EINVAL; + } + } + + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) { + int codec = 0; + struct msm_vidc_buffer *temp, *next; + u32 filled_len = 0; + u32 device_addr = 0; + + mutex_lock(&inst->registeredbufs.lock); + list_for_each_entry_safe(temp, next, + &inst->registeredbufs.list, list) { + if (temp->vvb.vb2_buf.type == INPUT_MPLANE) { + filled_len = max(filled_len, + temp->vvb.vb2_buf.planes[0].bytesused); + device_addr = temp->smem[0].device_addr; + } + if (inst->session_type == MSM_VIDC_ENCODER && + (temp->vvb.flags & + V4L2_BUF_FLAG_PERF_MODE)) { + is_turbo = true; + } + } + mutex_unlock(&inst->registeredbufs.lock); + + if ((!filled_len || !device_addr) && + (inst->session_type != MSM_VIDC_CVP)) { + dprintk(VIDC_DBG, "%s: no input for session %x\n", + __func__, hash32_ptr(inst->session)); + continue; + } + + ++vote_data_count; + + out_f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + inp_f = &inst->fmts[INPUT_PORT].v4l2_fmt; + switch (inst->session_type) { + case MSM_VIDC_DECODER: + codec = inp_f->fmt.pix_mp.pixelformat; + break; + case MSM_VIDC_ENCODER: + codec = out_f->fmt.pix_mp.pixelformat; + break; + case MSM_VIDC_CVP: + codec = V4L2_PIX_FMT_CVP; + break; + default: + dprintk(VIDC_ERR, "%s: invalid session_type %#x\n", + __func__, inst->session_type); + break; + } + + memset(&(vote_data[i]), 0x0, sizeof(struct vidc_bus_vote_data)); + + vote_data[i].domain = get_hal_domain(inst->session_type); + vote_data[i].codec = get_hal_codec(codec); + vote_data[i].input_width = inp_f->fmt.pix_mp.width; + vote_data[i].input_height = inp_f->fmt.pix_mp.height; + vote_data[i].output_width = out_f->fmt.pix_mp.width; + vote_data[i].output_height = out_f->fmt.pix_mp.height; + vote_data[i].lcu_size = (codec == V4L2_PIX_FMT_HEVC || + codec == V4L2_PIX_FMT_VP9) ? 32 : 16; + + vote_data[i].fps = msm_vidc_get_fps(inst); + if (inst->session_type == MSM_VIDC_ENCODER) { + vote_data[i].bitrate = inst->clk_data.bitrate; + vote_data[i].rotation = + msm_comm_g_ctrl_for_id(inst, V4L2_CID_ROTATE); + vote_data[i].b_frames_enabled = + msm_comm_g_ctrl_for_id(inst, + V4L2_CID_MPEG_VIDEO_B_FRAMES) != 0; + /* scale bitrate if operating rate is larger than fps */ + if (vote_data[i].fps > (inst->clk_data.frame_rate >> 16) + && (inst->clk_data.frame_rate >> 16)) { + vote_data[i].bitrate = vote_data[i].bitrate / + (inst->clk_data.frame_rate >> 16) * + vote_data[i].fps; + } + } + + vote_data[i].power_mode = 0; + if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW && + inst->session_type != MSM_VIDC_CVP) + vote_data[i].power_mode = VIDC_POWER_TURBO; + if (msm_vidc_clock_voting || is_turbo) + vote_data[i].power_mode = VIDC_POWER_TURBO; + + if (msm_comm_get_stream_output_mode(inst) == + HAL_VIDEO_DECODER_PRIMARY) { + vote_data[i].color_formats[0] = + msm_comm_get_hal_uncompressed( + inst->clk_data.opb_fourcc); + vote_data[i].num_formats = 1; + } else { + vote_data[i].color_formats[0] = + msm_comm_get_hal_uncompressed( + inst->clk_data.dpb_fourcc); + vote_data[i].color_formats[1] = + msm_comm_get_hal_uncompressed( + inst->clk_data.opb_fourcc); + vote_data[i].num_formats = 2; + } + vote_data[i].work_mode = inst->clk_data.work_mode; + fill_dynamic_stats(inst, &vote_data[i]); + + if (core->resources.sys_cache_res_set) + vote_data[i].use_sys_cache = true; + + if (inst->session_type == MSM_VIDC_CVP) { + vote_data[i].domain = + get_hal_domain(inst->session_type); + vote_data[i].ddr_bw = inst->clk_data.ddr_bw; + vote_data[i].sys_cache_bw = + inst->clk_data.sys_cache_bw; + } + + i++; + } + mutex_unlock(&core->lock); + if (vote_data_count) + rc = call_hfi_op(hdev, vote_bus, hdev->hfi_device_data, + vote_data, vote_data_count); + + kfree(vote_data); + return rc; +} + +static int msm_dcvs_scale_clocks(struct msm_vidc_inst *inst, + unsigned long freq) +{ + int rc = 0; + int bufs_with_fw = 0; + int bufs_with_client = 0; + struct msm_vidc_format *fmt; + struct clock_data *dcvs; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s Invalid params\n", __func__); + return -EINVAL; + } + + /* assume no increment or decrement is required initially */ + inst->clk_data.dcvs_flags = 0; + + if (!inst->clk_data.dcvs_mode || inst->batch.enable) { + dprintk(VIDC_DBG, "Skip DCVS (dcvs %d, batching %d)\n", + inst->clk_data.dcvs_mode, inst->batch.enable); + /* update load (freq) with normal value */ + inst->clk_data.load = inst->clk_data.load_norm; + return 0; + } + + dcvs = &inst->clk_data; + + if (is_decode_session(inst)) { + bufs_with_fw = msm_comm_num_queued_bufs(inst, OUTPUT_MPLANE); + fmt = &inst->fmts[OUTPUT_PORT]; + } else { + bufs_with_fw = msm_comm_num_queued_bufs(inst, INPUT_MPLANE); + fmt = &inst->fmts[INPUT_PORT]; + } + /* +1 as one buffer is going to be queued after the function */ + bufs_with_fw += 1; + bufs_with_client = fmt->count_actual - bufs_with_fw; + + /* + * PMS decides clock level based on below algo + + * Limits : + * max_threshold : Client extra allocated buffers. Client + * reserves these buffers for it's smooth flow. + * min_output_buf : HW requested buffers for it's smooth + * flow of buffers. + * min_threshold : Driver requested extra buffers for PMS. + + * 1) When buffers outside FW are reaching client's extra buffers, + * FW is slow and will impact pipeline, Increase clock. + * 2) When pending buffers with FW are same as FW requested, + * pipeline has cushion to absorb FW slowness, Decrease clocks. + * 3) When none of 1) or 2) FW is just fast enough to maintain + * pipeline, request Right Clocks. + */ + + if (bufs_with_client <= dcvs->max_threshold) { + dcvs->load = dcvs->load_high; + dcvs->dcvs_flags |= MSM_VIDC_DCVS_INCR; + } else if (bufs_with_fw < (int) fmt->count_min) { + dcvs->load = dcvs->load_low; + dcvs->dcvs_flags |= MSM_VIDC_DCVS_DECR; + } else { + dcvs->load = dcvs->load_norm; + dcvs->dcvs_flags = 0; + } + + dprintk(VIDC_PROF, + "DCVS: %x : total bufs %d outside fw %d max threshold %d with fw %d min bufs %d flags %#x\n", + hash32_ptr(inst->session), fmt->count_actual, + bufs_with_client, dcvs->max_threshold, bufs_with_fw, + fmt->count_min, dcvs->dcvs_flags); + return rc; +} + +static void msm_vidc_update_freq_entry(struct msm_vidc_inst *inst, + unsigned long freq, u32 device_addr, bool is_turbo) +{ + struct vidc_freq_data *temp, *next; + bool found = false; + + mutex_lock(&inst->freqs.lock); + list_for_each_entry_safe(temp, next, &inst->freqs.list, list) { + if (temp->device_addr == device_addr) { + temp->freq = freq; + found = true; + break; + } + } + + if (!found) { + temp = kzalloc(sizeof(*temp), GFP_KERNEL); + if (!temp) { + dprintk(VIDC_WARN, "%s: malloc failure.\n", __func__); + goto exit; + } + temp->freq = freq; + temp->device_addr = device_addr; + list_add_tail(&temp->list, &inst->freqs.list); + } + temp->turbo = !!is_turbo; +exit: + mutex_unlock(&inst->freqs.lock); +} + +void msm_vidc_clear_freq_entry(struct msm_vidc_inst *inst, + u32 device_addr) +{ + struct vidc_freq_data *temp, *next; + + mutex_lock(&inst->freqs.lock); + list_for_each_entry_safe(temp, next, &inst->freqs.list, list) { + if (temp->device_addr == device_addr) + temp->freq = 0; + } + mutex_unlock(&inst->freqs.lock); + + inst->clk_data.buffer_counter++; +} + +static unsigned long msm_vidc_max_freq(struct msm_vidc_core *core) +{ + struct allowed_clock_rates_table *allowed_clks_tbl = NULL; + unsigned long freq = 0; + + allowed_clks_tbl = core->resources.allowed_clks_tbl; + freq = allowed_clks_tbl[0].clock_rate; + dprintk(VIDC_PROF, "Max rate = %lu\n", freq); + return freq; +} + +void msm_comm_free_freq_table(struct msm_vidc_inst *inst) +{ + struct vidc_freq_data *temp, *next; + + mutex_lock(&inst->freqs.lock); + list_for_each_entry_safe(temp, next, &inst->freqs.list, list) { + list_del(&temp->list); + kfree(temp); + } + INIT_LIST_HEAD(&inst->freqs.list); + mutex_unlock(&inst->freqs.lock); +} + +void msm_comm_free_input_cr_table(struct msm_vidc_inst *inst) +{ + struct vidc_input_cr_data *temp, *next; + + mutex_lock(&inst->input_crs.lock); + list_for_each_entry_safe(temp, next, &inst->input_crs.list, list) { + list_del(&temp->list); + kfree(temp); + } + INIT_LIST_HEAD(&inst->input_crs.list); + mutex_unlock(&inst->input_crs.lock); +} + +void msm_comm_update_input_cr(struct msm_vidc_inst *inst, + u32 index, u32 cr) +{ + struct vidc_input_cr_data *temp, *next; + bool found = false; + + mutex_lock(&inst->input_crs.lock); + list_for_each_entry_safe(temp, next, &inst->input_crs.list, list) { + if (temp->index == index) { + temp->input_cr = cr; + found = true; + break; + } + } + + if (!found) { + temp = kzalloc(sizeof(*temp), GFP_KERNEL); + if (!temp) { + dprintk(VIDC_WARN, "%s: malloc failure.\n", __func__); + goto exit; + } + temp->index = index; + temp->input_cr = cr; + list_add_tail(&temp->list, &inst->input_crs.list); + } +exit: + mutex_unlock(&inst->input_crs.lock); +} + +static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, + u32 filled_len) +{ + u64 freq = 0, vpp_cycles = 0, vsp_cycles = 0; + u64 fw_cycles = 0, fw_vpp_cycles = 0; + u32 vpp_cycles_per_mb; + u32 mbs_per_second; + struct msm_vidc_core *core = NULL; + int i = 0; + struct allowed_clock_rates_table *allowed_clks_tbl = NULL; + u64 rate = 0, fps; + struct clock_data *dcvs = NULL; + + core = inst->core; + dcvs = &inst->clk_data; + + mbs_per_second = msm_comm_get_inst_load_per_core(inst, + LOAD_CALC_NO_QUIRKS); + + fps = msm_vidc_get_fps(inst); + + /* + * Calculate vpp, vsp cycles separately for encoder and decoder. + * Even though, most part is common now, in future it may change + * between them. + */ + + fw_cycles = fps * inst->core->resources.fw_cycles; + fw_vpp_cycles = fps * inst->core->resources.fw_vpp_cycles; + + if (inst->session_type == MSM_VIDC_ENCODER) { + vpp_cycles_per_mb = inst->flags & VIDC_LOW_POWER ? + inst->clk_data.entry->low_power_cycles : + inst->clk_data.entry->vpp_cycles; + + vpp_cycles = mbs_per_second * vpp_cycles_per_mb; + /* 21 / 20 is minimum overhead factor */ + vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles); + + vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; + + /* 10 / 7 is overhead factor */ + vsp_cycles += (inst->clk_data.bitrate * 10) / 7; + } else if (inst->session_type == MSM_VIDC_DECODER) { + vpp_cycles = mbs_per_second * inst->clk_data.entry->vpp_cycles; + /* 21 / 20 is minimum overhead factor */ + vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles); + + vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; + /* 10 / 7 is overhead factor */ + vsp_cycles += ((fps * filled_len * 8) * 10) / 7; + + } else { + dprintk(VIDC_ERR, "Unknown session type = %s\n", __func__); + return msm_vidc_max_freq(inst->core); + } + + freq = max(vpp_cycles, vsp_cycles); + freq = max(freq, fw_cycles); + + dprintk(VIDC_DBG, "Update DCVS Load\n"); + allowed_clks_tbl = core->resources.allowed_clks_tbl; + for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) { + rate = allowed_clks_tbl[i].clock_rate; + if (rate >= freq) + break; + } + + dcvs->load_norm = rate; + dcvs->load_low = i < (int) (core->resources.allowed_clks_tbl_size - 1) ? + allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm; + dcvs->load_high = i > 0 ? allowed_clks_tbl[i-1].clock_rate : + dcvs->load_norm; + + msm_dcvs_print_dcvs_stats(dcvs); + + dprintk(VIDC_PROF, "%s Inst %pK : Filled Len = %d Freq = %llu\n", + __func__, inst, filled_len, freq); + + return (unsigned long) freq; +} + +static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst, + u32 filled_len) +{ + u64 vsp_cycles = 0, vpp_cycles = 0, fw_cycles = 0, freq = 0; + u64 fw_vpp_cycles = 0; + u32 vpp_cycles_per_mb; + u32 mbs_per_second; + struct msm_vidc_core *core = NULL; + int i = 0; + struct allowed_clock_rates_table *allowed_clks_tbl = NULL; + u64 rate = 0, fps; + struct clock_data *dcvs = NULL; + u32 operating_rate, vsp_factor_num = 10, vsp_factor_den = 5; + + core = inst->core; + dcvs = &inst->clk_data; + + mbs_per_second = msm_comm_get_inst_load_per_core(inst, + LOAD_CALC_NO_QUIRKS); + + fps = msm_vidc_get_fps(inst); + + /* + * Calculate vpp, vsp, fw cycles separately for encoder and decoder. + * Even though, most part is common now, in future it may change + * between them. + */ + + fw_cycles = fps * inst->core->resources.fw_cycles; + fw_vpp_cycles = fps * inst->core->resources.fw_vpp_cycles; + + if (inst->session_type == MSM_VIDC_ENCODER) { + vpp_cycles_per_mb = inst->flags & VIDC_LOW_POWER ? + inst->clk_data.entry->low_power_cycles : + inst->clk_data.entry->vpp_cycles; + + vpp_cycles = mbs_per_second * vpp_cycles_per_mb / + inst->clk_data.work_route; + /* 21 / 20 is minimum overhead factor */ + vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles); + + vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; + + /* bitrate is based on fps, scale it using operating rate */ + operating_rate = inst->clk_data.operating_rate >> 16; + if (operating_rate > (inst->clk_data.frame_rate >> 16) && + (inst->clk_data.frame_rate >> 16)) { + vsp_factor_num *= operating_rate; + vsp_factor_den *= inst->clk_data.frame_rate >> 16; + } + vsp_cycles += ((u64)inst->clk_data.bitrate * vsp_factor_num) / + vsp_factor_den; + + } else if (inst->session_type == MSM_VIDC_DECODER) { + vpp_cycles = mbs_per_second * inst->clk_data.entry->vpp_cycles / + inst->clk_data.work_route; + /* 21 / 20 is minimum overhead factor */ + vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles); + + vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; + + /* vsp perf is about 0.5 bits/cycle */ + vsp_cycles += ((fps * filled_len * 8) * 10) / 5; + + } else { + dprintk(VIDC_ERR, "Unknown session type = %s\n", __func__); + return msm_vidc_max_freq(inst->core); + } + + freq = max(vpp_cycles, vsp_cycles); + freq = max(freq, fw_cycles); + + allowed_clks_tbl = core->resources.allowed_clks_tbl; + for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) { + rate = allowed_clks_tbl[i].clock_rate; + if (rate >= freq) + break; + } + + dcvs->load_norm = rate; + dcvs->load_low = i < (int) (core->resources.allowed_clks_tbl_size - 1) ? + allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm; + dcvs->load_high = i > 0 ? allowed_clks_tbl[i-1].clock_rate : + dcvs->load_norm; + + dprintk(VIDC_PROF, + "%s: inst %pK: %x : filled len %d required freq %llu load_norm %llu\n", + __func__, inst, hash32_ptr(inst->session), + filled_len, freq, dcvs->load_norm); + + return (unsigned long) freq; +} + +static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, + u32 filled_len) +{ + u64 vsp_cycles = 0, vpp_cycles = 0, fw_cycles = 0, freq = 0; + u32 vpp_cycles_per_mb; + u32 mbs_per_second; + struct msm_vidc_core *core = NULL; + int i = 0; + struct allowed_clock_rates_table *allowed_clks_tbl = NULL; + u64 rate = 0, fps; + struct clock_data *dcvs = NULL; + u32 operating_rate, vsp_factor_num = 10, vsp_factor_den = 5; + + core = inst->core; + dcvs = &inst->clk_data; + + mbs_per_second = msm_comm_get_inst_load_per_core(inst, + LOAD_CALC_NO_QUIRKS); + + fps = msm_vidc_get_fps(inst); + + /* + * Calculate vpp, vsp, fw cycles separately for encoder and decoder. + * Even though, most part is common now, in future it may change + * between them. + */ + + if (inst->session_type == MSM_VIDC_ENCODER) { + vpp_cycles_per_mb = inst->flags & VIDC_LOW_POWER ? + inst->clk_data.entry->low_power_cycles : + inst->clk_data.entry->vpp_cycles; + + vpp_cycles = mbs_per_second * vpp_cycles_per_mb; + /* 21 / 20 is overhead factor */ + vpp_cycles = (vpp_cycles * 21)/ + (inst->clk_data.work_route * 20); + + vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; + + /* bitrate is based on fps, scale it using operating rate */ + operating_rate = inst->clk_data.operating_rate >> 16; + if (operating_rate > (inst->clk_data.frame_rate >> 16) && + (inst->clk_data.frame_rate >> 16)) { + vsp_factor_num *= operating_rate; + vsp_factor_den *= inst->clk_data.frame_rate >> 16; + } + vsp_cycles += ((u64)inst->clk_data.bitrate * vsp_factor_num) / + vsp_factor_den; + + fw_cycles = fps * inst->core->resources.fw_cycles; + + } else if (inst->session_type == MSM_VIDC_DECODER) { + vpp_cycles = mbs_per_second * inst->clk_data.entry->vpp_cycles; + /* 21 / 20 is overhead factor */ + vpp_cycles = (vpp_cycles * 21)/ + (inst->clk_data.work_route * 20); + + vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; + + /* vsp perf is about 0.5 bits/cycle */ + vsp_cycles += ((fps * filled_len * 8) * 10) / 5; + + fw_cycles = fps * inst->core->resources.fw_cycles; + + } else { + dprintk(VIDC_ERR, "Unknown session type = %s\n", __func__); + return msm_vidc_max_freq(inst->core); + } + + freq = max(vpp_cycles, vsp_cycles); + freq = max(freq, fw_cycles); + + allowed_clks_tbl = core->resources.allowed_clks_tbl; + for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) { + rate = allowed_clks_tbl[i].clock_rate; + if (rate >= freq) + break; + } + + dcvs->load_norm = rate; + dcvs->load_low = i < (int) (core->resources.allowed_clks_tbl_size - 1) ? + allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm; + dcvs->load_high = i > 0 ? allowed_clks_tbl[i-1].clock_rate : + dcvs->load_norm; + + dprintk(VIDC_PROF, + "%s: inst %pK: %x : filled len %d required freq %llu load_norm %llu\n", + __func__, inst, hash32_ptr(inst->session), + filled_len, freq, dcvs->load_norm); + + return (unsigned long) freq; +} + +int msm_vidc_set_clocks(struct msm_vidc_core *core) +{ + struct hfi_device *hdev; + unsigned long freq_core_1 = 0, freq_core_2 = 0, rate = 0; + unsigned long freq_core_max = 0; + struct msm_vidc_inst *inst = NULL; + struct msm_vidc_buffer *temp, *next; + u32 device_addr, filled_len; + int rc = 0, i = 0; + struct allowed_clock_rates_table *allowed_clks_tbl = NULL; + bool increment, decrement; + + hdev = core->device; + allowed_clks_tbl = core->resources.allowed_clks_tbl; + if (!allowed_clks_tbl) { + dprintk(VIDC_ERR, + "%s Invalid parameters\n", __func__); + return -EINVAL; + } + + mutex_lock(&core->lock); + increment = false; + decrement = true; + list_for_each_entry(inst, &core->instances, list) { + device_addr = 0; + filled_len = 0; + mutex_lock(&inst->registeredbufs.lock); + list_for_each_entry_safe(temp, next, + &inst->registeredbufs.list, list) { + if (temp->vvb.vb2_buf.type == INPUT_MPLANE) { + filled_len = max(filled_len, + temp->vvb.vb2_buf.planes[0].bytesused); + device_addr = temp->smem[0].device_addr; + } + } + mutex_unlock(&inst->registeredbufs.lock); + + if (!filled_len || !device_addr) { + dprintk(VIDC_DBG, "%s no input for session %x\n", + __func__, hash32_ptr(inst->session)); + continue; + } + + if (inst->clk_data.core_id == VIDC_CORE_ID_1) + freq_core_1 += inst->clk_data.min_freq; + else if (inst->clk_data.core_id == VIDC_CORE_ID_2) + freq_core_2 += inst->clk_data.min_freq; + else if (inst->clk_data.core_id == VIDC_CORE_ID_3) { + freq_core_1 += inst->clk_data.min_freq; + freq_core_2 += inst->clk_data.min_freq; + } + + freq_core_max = max_t(unsigned long, freq_core_1, freq_core_2); + + if (msm_vidc_clock_voting) { + dprintk(VIDC_PROF, + "msm_vidc_clock_voting %d\n", + msm_vidc_clock_voting); + freq_core_max = msm_vidc_clock_voting; + decrement = false; + break; + } + + /* increment even if one session requested for it */ + if (inst->clk_data.dcvs_flags & MSM_VIDC_DCVS_INCR) + increment = true; + /* decrement only if all sessions requested for it */ + if (!(inst->clk_data.dcvs_flags & MSM_VIDC_DCVS_DECR)) + decrement = false; + } + + /* + * keep checking from lowest to highest rate until + * table rate >= requested rate + */ + for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) { + rate = allowed_clks_tbl[i].clock_rate; + if (rate >= freq_core_max) + break; + } + if (increment) { + if (i > 0) + rate = allowed_clks_tbl[i-1].clock_rate; + } else if (decrement) { + if (i < (int) (core->resources.allowed_clks_tbl_size - 1)) + rate = allowed_clks_tbl[i+1].clock_rate; + } + + core->min_freq = freq_core_max; + core->curr_freq = rate; + mutex_unlock(&core->lock); + + dprintk(VIDC_PROF, + "%s: clock rate %lu requested %lu increment %d decrement %d\n", + __func__, core->curr_freq, core->min_freq, + increment, decrement); + rc = call_hfi_op(hdev, scale_clocks, + hdev->hfi_device_data, core->curr_freq); + + return rc; +} + +int msm_comm_scale_clocks(struct msm_vidc_inst *inst) +{ + struct msm_vidc_buffer *temp, *next; + unsigned long freq = 0; + u32 filled_len = 0; + u32 device_addr = 0; + bool is_turbo = false; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n", + __func__, inst); + return -EINVAL; + } + + mutex_lock(&inst->registeredbufs.lock); + list_for_each_entry_safe(temp, next, &inst->registeredbufs.list, list) { + if (temp->vvb.vb2_buf.type == INPUT_MPLANE) { + filled_len = max(filled_len, + temp->vvb.vb2_buf.planes[0].bytesused); + if (inst->session_type == MSM_VIDC_ENCODER && + (temp->vvb.flags & + V4L2_BUF_FLAG_PERF_MODE)) { + is_turbo = true; + } + device_addr = temp->smem[0].device_addr; + } + } + mutex_unlock(&inst->registeredbufs.lock); + + if (!filled_len || !device_addr) { + dprintk(VIDC_DBG, "%s no input for session %x\n", + __func__, hash32_ptr(inst->session)); + return 0; + } + + freq = call_core_op(inst->core, calc_freq, inst, filled_len); + inst->clk_data.min_freq = freq; + /* update dcvs flags */ + msm_dcvs_scale_clocks(inst, freq); + + if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW || is_turbo || + msm_vidc_clock_voting) { + inst->clk_data.min_freq = msm_vidc_max_freq(inst->core); + inst->clk_data.dcvs_flags = 0; + } + + msm_vidc_update_freq_entry(inst, freq, device_addr, is_turbo); + + msm_vidc_set_clocks(inst->core); + + return 0; +} + +int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst) +{ + struct msm_vidc_core *core; + struct hfi_device *hdev; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s Invalid params\n", __func__); + return -EINVAL; + } + core = inst->core; + hdev = core->device; + + if (msm_comm_scale_clocks(inst)) { + dprintk(VIDC_WARN, + "Failed to scale clocks. Performance might be impacted\n"); + } + if (msm_comm_vote_bus(core)) { + dprintk(VIDC_WARN, + "Failed to scale DDR bus. Performance might be impacted\n"); + } + return 0; +} + +int msm_dcvs_try_enable(struct msm_vidc_inst *inst) +{ + if (!inst) { + dprintk(VIDC_ERR, "%s: Invalid args: %p\n", __func__, inst); + return -EINVAL; + } + + if (msm_vidc_clock_voting || + inst->flags & VIDC_THUMBNAIL || + inst->clk_data.low_latency_mode || + inst->batch.enable) { + dprintk(VIDC_PROF, "DCVS disabled: %pK\n", inst); + inst->clk_data.dcvs_mode = false; + return false; + } + inst->clk_data.dcvs_mode = true; + dprintk(VIDC_PROF, "DCVS enabled: %pK\n", inst); + + return true; +} + +int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst) +{ + int rc = 0, j = 0; + int fourcc, count; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n", + __func__, inst); + return -EINVAL; + } + + if (inst->session_type == MSM_VIDC_CVP) { + dprintk(VIDC_DBG, "%s: cvp session\n", __func__); + return 0; + } + + count = inst->core->resources.codec_data_count; + fourcc = get_v4l2_codec(inst); + + for (j = 0; j < count; j++) { + if (inst->core->resources.codec_data[j].session_type == + inst->session_type && + inst->core->resources.codec_data[j].fourcc == + fourcc) { + inst->clk_data.entry = + &inst->core->resources.codec_data[j]; + break; + } + } + + if (!inst->clk_data.entry) { + dprintk(VIDC_ERR, "%s No match found\n", __func__); + rc = -EINVAL; + } + + return rc; +} + +void msm_clock_data_reset(struct msm_vidc_inst *inst) +{ + struct msm_vidc_core *core; + int i = 0, rc = 0; + struct allowed_clock_rates_table *allowed_clks_tbl = NULL; + u64 total_freq = 0, rate = 0, load; + int cycles; + struct clock_data *dcvs; + struct msm_vidc_format *fmt; + + dprintk(VIDC_DBG, "Init DCVS Load\n"); + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n", + __func__, inst); + return; + } + + core = inst->core; + dcvs = &inst->clk_data; + load = msm_comm_get_inst_load_per_core(inst, LOAD_CALC_NO_QUIRKS); + cycles = inst->clk_data.entry->vpp_cycles; + allowed_clks_tbl = core->resources.allowed_clks_tbl; + if (inst->session_type == MSM_VIDC_ENCODER) { + cycles = inst->flags & VIDC_LOW_POWER ? + inst->clk_data.entry->low_power_cycles : + cycles; + + dcvs->buffer_type = HAL_BUFFER_INPUT; + dcvs->min_threshold = + msm_vidc_get_extra_buff_count(inst, HAL_BUFFER_INPUT); + fmt = &inst->fmts[INPUT_PORT]; + dcvs->max_threshold = + fmt->count_actual - fmt->count_min_host + 2; + } else if (inst->session_type == MSM_VIDC_DECODER) { + dcvs->buffer_type = HAL_BUFFER_OUTPUT; + fmt = &inst->fmts[OUTPUT_PORT]; + dcvs->max_threshold = + fmt->count_actual - fmt->count_min_host + 2; + + dcvs->min_threshold = + msm_vidc_get_extra_buff_count(inst, dcvs->buffer_type); + } else { + dprintk(VIDC_ERR, "%s: invalid session type %#x\n", + __func__, inst->session_type); + return; + } + + total_freq = cycles * load; + + for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) { + rate = allowed_clks_tbl[i].clock_rate; + if (rate >= total_freq) + break; + } + + dcvs->load = dcvs->load_norm = rate; + + dcvs->load_low = i < (core->resources.allowed_clks_tbl_size - 1) ? + allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm; + dcvs->load_high = i > 0 ? allowed_clks_tbl[i-1].clock_rate : + dcvs->load_norm; + + inst->clk_data.buffer_counter = 0; + + msm_dcvs_print_dcvs_stats(dcvs); + + rc = msm_comm_scale_clocks_and_bus(inst); + + if (rc) + dprintk(VIDC_ERR, "%s Failed to scale Clocks and Bus\n", + __func__); +} + +int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_video_work_route pdata; + struct v4l2_format *f; + u32 codec; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, + "%s Invalid args: Inst = %pK\n", + __func__, inst); + return -EINVAL; + } + + hdev = inst->core->device; + + pdata.video_work_route = 2; + codec = get_v4l2_codec(inst); + if (inst->session_type == MSM_VIDC_DECODER) { + switch (codec) { + case V4L2_PIX_FMT_MPEG2: + pdata.video_work_route = 1; + break; + case V4L2_PIX_FMT_H264: + if (inst->pic_struct != + MSM_VIDC_PIC_STRUCT_PROGRESSIVE) + pdata.video_work_route = 1; + break; + } + } else if (inst->session_type == MSM_VIDC_ENCODER) { + u32 slice_mode = 0; + u32 output_width, output_height, fps, mbps; + + switch (codec) { + case V4L2_PIX_FMT_VP8: + case V4L2_PIX_FMT_TME: + pdata.video_work_route = 1; + goto decision_done; + } + + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) { + pdata.video_work_route = 2; + goto decision_done; + } + slice_mode = msm_comm_g_ctrl_for_id(inst, + V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + output_height = f->fmt.pix_mp.height; + output_width = f->fmt.pix_mp.width; + fps = inst->clk_data.frame_rate >> 16; + mbps = NUM_MBS_PER_SEC(output_height, output_width, fps); + if (slice_mode == + V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES || + (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR && + mbps <= CBR_MB_LIMIT) || + (inst->rc_type == + V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR && + mbps <= CBR_VFR_MB_LIMIT)) { + pdata.video_work_route = 1; + dprintk(VIDC_DBG, "Configured work route = 1"); + } + } else { + return -EINVAL; + } + +decision_done: + + inst->clk_data.work_route = pdata.video_work_route; + rc = call_hfi_op(hdev, session_set_property, + (void *)inst->session, HFI_PROPERTY_PARAM_WORK_ROUTE, + (void *)&pdata, sizeof(pdata)); + if (rc) + dprintk(VIDC_WARN, + " Failed to configure work route %pK\n", inst); + + return rc; +} + +int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_video_work_route pdata; + bool cbr_plus; + u32 codec; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, + "%s Invalid args: Inst = %pK\n", + __func__, inst); + return -EINVAL; + } + + hdev = inst->core->device; + cbr_plus = inst->clk_data.is_cbr_plus; + pdata.video_work_route = 4; + + codec = get_v4l2_codec(inst); + if (inst->session_type == MSM_VIDC_DECODER) { + if (codec == V4L2_PIX_FMT_MPEG2 || + inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE) + pdata.video_work_route = 1; + } else if (inst->session_type == MSM_VIDC_ENCODER) { + u32 slice_mode, width, height; + bool is_1080p_above; + struct v4l2_format *f; + + slice_mode = msm_comm_g_ctrl_for_id(inst, + V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + height = f->fmt.pix_mp.height; + width = f->fmt.pix_mp.width; + + is_1080p_above = res_is_greater_than(width, height, 1920, 1088); + + if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES || + codec == V4L2_PIX_FMT_VP8 || + (!is_1080p_above && !cbr_plus)) { + pdata.video_work_route = 1; + } + } else { + return -EINVAL; + } + + dprintk(VIDC_DBG, "Configurng work route = %u", + pdata.video_work_route); + + rc = call_hfi_op(hdev, session_set_property, + (void *)inst->session, HFI_PROPERTY_PARAM_WORK_ROUTE, + (void *)&pdata, sizeof(pdata)); + if (rc) + dprintk(VIDC_WARN, + " Failed to configure work route %pK\n", inst); + else + inst->clk_data.work_route = pdata.video_work_route; + + return rc; +} + +static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_video_work_mode pdata; + struct hfi_enable latency; + struct v4l2_format *f; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, + "%s Invalid args: Inst = %pK\n", + __func__, inst); + return -EINVAL; + } + + hdev = inst->core->device; + if (inst->clk_data.low_latency_mode) { + pdata.video_work_mode = HFI_WORKMODE_1; + goto decision_done; + } + + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + if (inst->session_type == MSM_VIDC_DECODER) { + pdata.video_work_mode = HFI_WORKMODE_2; + switch (f->fmt.pix_mp.pixelformat) { + case V4L2_PIX_FMT_MPEG2: + pdata.video_work_mode = HFI_WORKMODE_1; + break; + case V4L2_PIX_FMT_H264: + case V4L2_PIX_FMT_HEVC: + if (f->fmt.pix_mp.height * + f->fmt.pix_mp.width <= 1280 * 720) + pdata.video_work_mode = HFI_WORKMODE_1; + break; + } + } else if (inst->session_type == MSM_VIDC_ENCODER) + pdata.video_work_mode = HFI_WORKMODE_1; + else { + return -EINVAL; + } + +decision_done: + + inst->clk_data.work_mode = pdata.video_work_mode; + rc = call_hfi_op(hdev, session_set_property, + (void *)inst->session, HFI_PROPERTY_PARAM_WORK_MODE, + (void *)&pdata, sizeof(pdata)); + if (rc) + dprintk(VIDC_WARN, + " Failed to configure Work Mode %pK\n", inst); + + /* For WORK_MODE_1, set Low Latency mode by default to HW. */ + + if (inst->session_type == MSM_VIDC_ENCODER && + inst->clk_data.work_mode == HFI_WORKMODE_1) { + latency.enable = true; + rc = call_hfi_op(hdev, session_set_property, + (void *)inst->session, + HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE, + (void *)&latency, sizeof(latency)); + } + + rc = msm_comm_scale_clocks_and_bus(inst); + + return rc; +} + +int msm_vidc_decide_work_mode_iris1(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_video_work_mode pdata; + struct hfi_enable latency; + u32 yuv_size = 0; + struct v4l2_format *f; + u32 codec; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, + "%s Invalid args: Inst = %pK\n", + __func__, inst); + return -EINVAL; + } + + hdev = inst->core->device; + + if (inst->clk_data.low_latency_mode) { + pdata.video_work_mode = HFI_WORKMODE_1; + dprintk(VIDC_DBG, "Configured work mode = 1"); + goto decision_done; + } + + codec = get_v4l2_codec(inst); + if (inst->session_type == MSM_VIDC_DECODER) { + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + pdata.video_work_mode = HFI_WORKMODE_2; + switch (codec) { + case V4L2_PIX_FMT_MPEG2: + pdata.video_work_mode = HFI_WORKMODE_1; + break; + case V4L2_PIX_FMT_H264: + case V4L2_PIX_FMT_HEVC: + case V4L2_PIX_FMT_VP8: + case V4L2_PIX_FMT_VP9: + yuv_size = f->fmt.pix_mp.height * f->fmt.pix_mp.width; + if ((inst->pic_struct != + MSM_VIDC_PIC_STRUCT_PROGRESSIVE) || + (yuv_size <= 1280 * 720)) + pdata.video_work_mode = HFI_WORKMODE_1; + break; + } + } else if (inst->session_type == MSM_VIDC_ENCODER) { + pdata.video_work_mode = HFI_WORKMODE_2; + + switch (codec) { + case V4L2_PIX_FMT_VP8: + case V4L2_PIX_FMT_TME: + pdata.video_work_mode = HFI_WORKMODE_1; + goto decision_done; + } + + } else { + return -EINVAL; + } + +decision_done: + + inst->clk_data.work_mode = pdata.video_work_mode; + rc = call_hfi_op(hdev, session_set_property, + (void *)inst->session, HFI_PROPERTY_PARAM_WORK_MODE, + (void *)&pdata, sizeof(pdata)); + if (rc) + dprintk(VIDC_WARN, + " Failed to configure Work Mode %pK\n", inst); + + /* For WORK_MODE_1, set Low Latency mode by default to HW. */ + + if (inst->session_type == MSM_VIDC_ENCODER && + inst->clk_data.work_mode == HFI_WORKMODE_1) { + latency.enable = true; + rc = call_hfi_op(hdev, session_set_property, + (void *)inst->session, + HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE, + (void *)&latency, sizeof(latency)); + } + + return rc; +} + +int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_video_work_mode pdata; + struct hfi_enable latency; + u32 width, height; + bool res_ok = false; + struct v4l2_format *out_f; + struct v4l2_format *inp_f; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, + "%s Invalid args: Inst = %pK\n", + __func__, inst); + return -EINVAL; + } + + hdev = inst->core->device; + pdata.video_work_mode = HFI_WORKMODE_2; + latency.enable = inst->clk_data.low_latency_mode; + out_f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + inp_f = &inst->fmts[INPUT_PORT].v4l2_fmt; + if (inst->session_type == MSM_VIDC_DECODER) { + height = out_f->fmt.pix_mp.height; + width = out_f->fmt.pix_mp.width; + res_ok = res_is_less_than(width, height, 1280, 720); + if (inp_f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_MPEG2 || + inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE || + inst->clk_data.low_latency_mode || res_ok) { + pdata.video_work_mode = HFI_WORKMODE_1; + } + } else if (inst->session_type == MSM_VIDC_ENCODER) { + height = inp_f->fmt.pix_mp.height; + width = inp_f->fmt.pix_mp.width; + res_ok = !res_is_greater_than(width, height, 4096, 2160); + if (res_ok && + (out_f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_VP8 || + inst->clk_data.low_latency_mode)) { + pdata.video_work_mode = HFI_WORKMODE_1; + /* For WORK_MODE_1, set Low Latency mode by default */ + latency.enable = true; + } + if (inst->rc_type == RATE_CONTROL_LOSSLESS && + out_f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_H264) { + dprintk(VIDC_DBG, + "Set work mode to low latency for AVC lossless encoding."); + latency.enable = true; + } + } else { + return -EINVAL; + } + + dprintk(VIDC_DBG, "Configuring work mode = %u low latency = %u", + pdata.video_work_mode, + latency.enable); + + if (inst->session_type == MSM_VIDC_ENCODER) { + rc = call_hfi_op(hdev, session_set_property, + (void *)inst->session, + HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE, + (void *)&latency, sizeof(latency)); + if (rc) + dprintk(VIDC_WARN, + " Failed to configure low latency %pK\n", inst); + else + inst->clk_data.low_latency_mode = latency.enable; + } + + rc = call_hfi_op(hdev, session_set_property, + (void *)inst->session, HFI_PROPERTY_PARAM_WORK_MODE, + (void *)&pdata, sizeof(pdata)); + if (rc) + dprintk(VIDC_WARN, + " Failed to configure Work Mode %pK\n", inst); + else + inst->clk_data.work_mode = pdata.video_work_mode; + + return rc; +} + +static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, + bool enable) +{ + u32 rc = 0, mbs_per_frame, mbs_per_sec; + u32 prop_id = 0; + void *pdata = NULL; + struct hfi_device *hdev = NULL; + u32 hfi_perf_mode; + + hdev = inst->core->device; + if (inst->session_type != MSM_VIDC_ENCODER) { + dprintk(VIDC_DBG, + "%s : Not an encoder session. Nothing to do\n", + __func__); + return 0; + } + + /* Power saving always disabled for CQ and LOSSLESS RC modes. */ + mbs_per_frame = msm_vidc_get_mbs_per_frame(inst); + mbs_per_sec = mbs_per_frame * msm_vidc_get_fps(inst); + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ || + inst->rc_type == RATE_CONTROL_LOSSLESS || + (mbs_per_frame <= + inst->core->resources.max_hq_mbs_per_frame && + mbs_per_sec <= + inst->core->resources.max_hq_mbs_per_sec)) { + enable = false; + } + + prop_id = HFI_PROPERTY_CONFIG_VENC_PERF_MODE; + hfi_perf_mode = enable ? HFI_VENC_PERFMODE_POWER_SAVE : + HFI_VENC_PERFMODE_MAX_QUALITY; + pdata = &hfi_perf_mode; + rc = call_hfi_op(hdev, session_set_property, + (void *)inst->session, prop_id, pdata, + sizeof(hfi_perf_mode)); + if (rc) { + dprintk(VIDC_ERR, + "%s: Failed to set power save mode for inst: %pK\n", + __func__, inst); + goto fail_power_mode_set; + } + inst->flags = enable ? + inst->flags | VIDC_LOW_POWER : + inst->flags & ~VIDC_LOW_POWER; + + dprintk(VIDC_PROF, + "Power Save Mode for inst: %pK Enable = %d\n", inst, enable); +fail_power_mode_set: + return rc; +} + +static int msm_vidc_move_core_to_power_save_mode(struct msm_vidc_core *core, + u32 core_id) +{ + struct msm_vidc_inst *inst = NULL; + + dprintk(VIDC_PROF, "Core %d : Moving all inst to LP mode\n", core_id); + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) { + if (inst->clk_data.core_id == core_id && + inst->session_type == MSM_VIDC_ENCODER) + msm_vidc_power_save_mode_enable(inst, true); + } + mutex_unlock(&core->lock); + + return 0; +} + +static u32 get_core_load(struct msm_vidc_core *core, + u32 core_id, bool lp_mode, bool real_time) +{ + struct msm_vidc_inst *inst = NULL; + u32 current_inst_mbs_per_sec = 0, load = 0; + bool real_time_mode = false; + + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) { + u32 cycles, lp_cycles; + + real_time_mode = inst->flags & VIDC_REALTIME ? true : false; + if (!(inst->clk_data.core_id & core_id)) + continue; + if (real_time_mode != real_time) + continue; + if (inst->session_type == MSM_VIDC_DECODER) { + cycles = lp_cycles = inst->clk_data.entry->vpp_cycles; + } else if (inst->session_type == MSM_VIDC_ENCODER) { + lp_mode |= inst->flags & VIDC_LOW_POWER; + cycles = lp_mode ? + inst->clk_data.entry->low_power_cycles : + inst->clk_data.entry->vpp_cycles; + } else { + continue; + } + current_inst_mbs_per_sec = msm_comm_get_inst_load_per_core(inst, + LOAD_CALC_NO_QUIRKS); + load += current_inst_mbs_per_sec * cycles / + inst->clk_data.work_route; + } + mutex_unlock(&core->lock); + + return load; +} + +int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) +{ + int rc = 0, hier_mode = 0; + struct hfi_device *hdev; + struct msm_vidc_core *core; + unsigned long max_freq, lp_cycles = 0; + struct hfi_videocores_usage_type core_info; + u32 core0_load = 0, core1_load = 0, core0_lp_load = 0, + core1_lp_load = 0; + u32 current_inst_load = 0, cur_inst_lp_load = 0, + min_load = 0, min_lp_load = 0; + u32 min_core_id, min_lp_core_id; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, + "%s Invalid args: Inst = %pK\n", + __func__, inst); + return -EINVAL; + } + + core = inst->core; + hdev = core->device; + max_freq = msm_vidc_max_freq(inst->core); + inst->clk_data.core_id = 0; + + core0_load = get_core_load(core, VIDC_CORE_ID_1, false, true); + core1_load = get_core_load(core, VIDC_CORE_ID_2, false, true); + core0_lp_load = get_core_load(core, VIDC_CORE_ID_1, true, true); + core1_lp_load = get_core_load(core, VIDC_CORE_ID_2, true, true); + + min_load = min(core0_load, core1_load); + min_core_id = core0_load < core1_load ? + VIDC_CORE_ID_1 : VIDC_CORE_ID_2; + min_lp_load = min(core0_lp_load, core1_lp_load); + min_lp_core_id = core0_lp_load < core1_lp_load ? + VIDC_CORE_ID_1 : VIDC_CORE_ID_2; + + lp_cycles = inst->session_type == MSM_VIDC_ENCODER ? + inst->clk_data.entry->low_power_cycles : + inst->clk_data.entry->vpp_cycles; + /* + * Incase there is only 1 core enabled, mark it as the core + * with min load. This ensures that this core is selected and + * video session is set to run on the enabled core. + */ + if (inst->capability.cap[CAP_MAX_VIDEOCORES].max <= VIDC_CORE_ID_1) { + min_core_id = min_lp_core_id = VIDC_CORE_ID_1; + min_load = core0_load; + min_lp_load = core0_lp_load; + } + + current_inst_load = (msm_comm_get_inst_load(inst, LOAD_CALC_NO_QUIRKS) * + inst->clk_data.entry->vpp_cycles)/inst->clk_data.work_route; + + cur_inst_lp_load = (msm_comm_get_inst_load(inst, + LOAD_CALC_NO_QUIRKS) * lp_cycles)/inst->clk_data.work_route; + + dprintk(VIDC_DBG, "Core 0 RT Load = %d Core 1 RT Load = %d\n", + core0_load, core1_load); + dprintk(VIDC_DBG, "Core 0 RT LP Load = %d Core 1 RT LP Load = %d\n", + core0_lp_load, core1_lp_load); + dprintk(VIDC_DBG, "Max Load = %lu\n", max_freq); + dprintk(VIDC_DBG, "Current Load = %d Current LP Load = %d\n", + current_inst_load, cur_inst_lp_load); + + if (inst->session_type == MSM_VIDC_ENCODER) { + /* Hier mode can be normal HP or Hybrid HP. */ + u32 max_cores, work_mode; + + hier_mode = msm_comm_g_ctrl_for_id(inst, + V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); + max_cores = inst->capability.cap[CAP_MAX_VIDEOCORES].max; + work_mode = inst->clk_data.work_mode; + if (hier_mode && max_cores >= VIDC_CORE_ID_3 && + work_mode == HFI_WORKMODE_2) { + if (current_inst_load / 2 + core0_load <= max_freq && + current_inst_load / 2 + core1_load <= max_freq) { + inst->clk_data.core_id = VIDC_CORE_ID_3; + msm_vidc_power_save_mode_enable(inst, false); + goto decision_done; + } + if (cur_inst_lp_load / 2 + core0_lp_load <= max_freq && + cur_inst_lp_load / 2 + core1_lp_load <= max_freq) { + inst->clk_data.core_id = VIDC_CORE_ID_3; + msm_vidc_power_save_mode_enable(inst, true); + goto decision_done; + } + } + + } + + if (current_inst_load + min_load < max_freq) { + inst->clk_data.core_id = min_core_id; + dprintk(VIDC_DBG, + "Selected normally : Core ID = %d\n", + inst->clk_data.core_id); + msm_vidc_power_save_mode_enable(inst, false); + } else if (cur_inst_lp_load + min_load < max_freq) { + /* Move current instance to LP and return */ + inst->clk_data.core_id = min_core_id; + dprintk(VIDC_DBG, + "Selected by moving current to LP : Core ID = %d\n", + inst->clk_data.core_id); + msm_vidc_power_save_mode_enable(inst, true); + + } else if (cur_inst_lp_load + min_lp_load < max_freq) { + /* Move all instances to LP mode and return */ + inst->clk_data.core_id = min_lp_core_id; + dprintk(VIDC_DBG, + "Moved all inst's to LP: Core ID = %d\n", + inst->clk_data.core_id); + msm_vidc_move_core_to_power_save_mode(core, min_lp_core_id); + } else { + rc = -EINVAL; + dprintk(VIDC_ERR, + "Sorry ... Core Can't support this load\n"); + return rc; + } + +decision_done: + core_info.video_core_enable_mask = inst->clk_data.core_id; + dprintk(VIDC_DBG, + "Core Enable Mask %d\n", core_info.video_core_enable_mask); + + rc = call_hfi_op(hdev, session_set_property, + (void *)inst->session, + HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE, &core_info, + sizeof(core_info)); + if (rc) + dprintk(VIDC_WARN, + " Failed to configure CORE ID %pK\n", inst); + + rc = msm_comm_scale_clocks_and_bus(inst); + + msm_print_core_status(core, VIDC_CORE_ID_1); + msm_print_core_status(core, VIDC_CORE_ID_2); + + return rc; +} + +int msm_vidc_decide_core_and_power_mode_iris2(struct msm_vidc_inst *inst) +{ + inst->clk_data.core_id = VIDC_CORE_ID_1; + msm_print_core_status(inst->core, VIDC_CORE_ID_1); + + return msm_vidc_power_save_mode_enable(inst, true); +} + +void msm_vidc_init_core_clk_ops(struct msm_vidc_core *core) +{ + if (!core) + return; + + if (core->platform_data->vpu_ver == VPU_VERSION_AR50) + core->core_ops = &core_ops_ar50; + else if (core->platform_data->vpu_ver == VPU_VERSION_IRIS1) + core->core_ops = &core_ops_iris1; + else + core->core_ops = &core_ops_iris2; +} + +void msm_print_core_status(struct msm_vidc_core *core, u32 core_id) +{ + struct msm_vidc_inst *inst = NULL; + struct v4l2_format *out_f; + struct v4l2_format *inp_f; + + dprintk(VIDC_PROF, "Instances running on core %u", core_id); + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) { + + if ((inst->clk_data.core_id != core_id) && + (inst->clk_data.core_id != VIDC_CORE_ID_3)) + continue; + out_f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + inp_f = &inst->fmts[INPUT_PORT].v4l2_fmt; + dprintk(VIDC_PROF, + "inst %pK (%4ux%4u) to (%4ux%4u) %3u %s %s %s %s %lu\n", + inst, + inp_f->fmt.pix_mp.width, + inp_f->fmt.pix_mp.height, + out_f->fmt.pix_mp.width, + out_f->fmt.pix_mp.height, + inst->clk_data.frame_rate >> 16, + inst->session_type == MSM_VIDC_ENCODER ? "ENC" : "DEC", + inst->clk_data.work_mode == HFI_WORKMODE_1 ? + "WORK_MODE_1" : "WORK_MODE_2", + inst->flags & VIDC_LOW_POWER ? "LP" : "HQ", + inst->flags & VIDC_REALTIME ? "RealTime" : "NonRTime", + inst->clk_data.min_freq); + } + mutex_unlock(&core->lock); +} diff --git a/msm/vidc/msm_vidc_clocks.h b/msm/vidc/msm_vidc_clocks.h new file mode 100644 index 000000000000..ed0588fb6c4f --- /dev/null +++ b/msm/vidc/msm_vidc_clocks.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef _MSM_VIDC_CLOCKS_H_ +#define _MSM_VIDC_CLOCKS_H_ +#include "msm_vidc_internal.h" + +void msm_clock_data_reset(struct msm_vidc_inst *inst); +int msm_vidc_set_clocks(struct msm_vidc_core *core); +int msm_comm_vote_bus(struct msm_vidc_core *core); +int msm_dcvs_try_enable(struct msm_vidc_inst *inst); +int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst); +int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst); +int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst); +void msm_comm_free_freq_table(struct msm_vidc_inst *inst); +int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst); +int msm_vidc_decide_work_mode_iris1(struct msm_vidc_inst *inst); +int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst); +int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst); +int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst); +int msm_vidc_decide_core_and_power_mode_iris2(struct msm_vidc_inst *inst); +void msm_print_core_status(struct msm_vidc_core *core, u32 core_id); +void msm_vidc_clear_freq_entry(struct msm_vidc_inst *inst, + u32 device_addr); +void msm_comm_free_input_cr_table(struct msm_vidc_inst *inst); +void msm_comm_update_input_cr(struct msm_vidc_inst *inst, u32 index, + u32 cr); +void update_recon_stats(struct msm_vidc_inst *inst, + struct recon_stats_type *recon_stats); +void msm_vidc_init_core_clk_ops(struct msm_vidc_core *core); +#endif diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c new file mode 100644 index 000000000000..72e4a0cb310f --- /dev/null +++ b/msm/vidc/msm_vidc_common.c @@ -0,0 +1,6783 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "msm_vidc_common.h" +#include "vidc_hfi_api.h" +#include "vidc_hfi.h" +#include "msm_vidc_debug.h" +#include "msm_vidc_clocks.h" +#include "msm_cvp_internal.h" +#include "msm_vidc_buffer_calculations.h" + +#define IS_ALREADY_IN_STATE(__p, __d) (\ + (__p >= __d)\ +) + +#define V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT \ + V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT +#define V4L2_EVENT_RELEASE_BUFFER_REFERENCE \ + V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE +#define L_MODE V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY + +static void handle_session_error(enum hal_command_response cmd, void *data); +static void msm_vidc_print_running_insts(struct msm_vidc_core *core); + +#define V4L2_H264_LEVEL_UNKNOWN V4L2_MPEG_VIDEO_H264_LEVEL_UNKNOWN +#define V4L2_HEVC_LEVEL_UNKNOWN V4L2_MPEG_VIDEO_HEVC_LEVEL_UNKNOWN +#define V4L2_VP9_LEVEL_61 V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_61 + +int msm_comm_g_ctrl_for_id(struct msm_vidc_inst *inst, int id) +{ + struct v4l2_ctrl *ctrl; + + ctrl = get_ctrl(inst, id); + return ctrl->val; +} + +static struct v4l2_ctrl **get_super_cluster(struct msm_vidc_inst *inst, + int num_ctrls) +{ + int c = 0; + struct v4l2_ctrl **cluster = kmalloc(sizeof(struct v4l2_ctrl *) * + num_ctrls, GFP_KERNEL); + + if (!cluster || !inst) { + kfree(cluster); + return NULL; + } + + for (c = 0; c < num_ctrls; c++) + cluster[c] = inst->ctrls[c]; + + return cluster; +} + +int msm_comm_hfi_to_v4l2(int id, int value) +{ + switch (id) { + /* H264 */ + case V4L2_CID_MPEG_VIDEO_H264_PROFILE: + switch (value) { + case HFI_H264_PROFILE_BASELINE: + return V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE; + case HFI_H264_PROFILE_CONSTRAINED_BASE: + return + V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE; + case HFI_H264_PROFILE_MAIN: + return V4L2_MPEG_VIDEO_H264_PROFILE_MAIN; + case HFI_H264_PROFILE_HIGH: + return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH; + case HFI_H264_PROFILE_STEREO_HIGH: + return V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH; + case HFI_H264_PROFILE_MULTIVIEW_HIGH: + return V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH; + case HFI_H264_PROFILE_CONSTRAINED_HIGH: + return V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH; + default: + goto unknown_value; + } + case V4L2_CID_MPEG_VIDEO_H264_LEVEL: + switch (value) { + case HFI_H264_LEVEL_1: + return V4L2_MPEG_VIDEO_H264_LEVEL_1_0; + case HFI_H264_LEVEL_1b: + return V4L2_MPEG_VIDEO_H264_LEVEL_1B; + case HFI_H264_LEVEL_11: + return V4L2_MPEG_VIDEO_H264_LEVEL_1_1; + case HFI_H264_LEVEL_12: + return V4L2_MPEG_VIDEO_H264_LEVEL_1_2; + case HFI_H264_LEVEL_13: + return V4L2_MPEG_VIDEO_H264_LEVEL_1_3; + case HFI_H264_LEVEL_2: + return V4L2_MPEG_VIDEO_H264_LEVEL_2_0; + case HFI_H264_LEVEL_21: + return V4L2_MPEG_VIDEO_H264_LEVEL_2_1; + case HFI_H264_LEVEL_22: + return V4L2_MPEG_VIDEO_H264_LEVEL_2_2; + case HFI_H264_LEVEL_3: + return V4L2_MPEG_VIDEO_H264_LEVEL_3_0; + case HFI_H264_LEVEL_31: + return V4L2_MPEG_VIDEO_H264_LEVEL_3_1; + case HFI_H264_LEVEL_32: + return V4L2_MPEG_VIDEO_H264_LEVEL_3_2; + case HFI_H264_LEVEL_4: + return V4L2_MPEG_VIDEO_H264_LEVEL_4_0; + case HFI_H264_LEVEL_41: + return V4L2_MPEG_VIDEO_H264_LEVEL_4_1; + case HFI_H264_LEVEL_42: + return V4L2_MPEG_VIDEO_H264_LEVEL_4_2; + case HFI_H264_LEVEL_5: + return V4L2_MPEG_VIDEO_H264_LEVEL_5_0; + case HFI_H264_LEVEL_51: + return V4L2_MPEG_VIDEO_H264_LEVEL_5_1; + case HFI_H264_LEVEL_52: + return V4L2_MPEG_VIDEO_H264_LEVEL_5_2; + case HFI_H264_LEVEL_6: + return V4L2_MPEG_VIDEO_H264_LEVEL_6_0; + case HFI_H264_LEVEL_61: + return V4L2_MPEG_VIDEO_H264_LEVEL_6_1; + case HFI_H264_LEVEL_62: + return V4L2_MPEG_VIDEO_H264_LEVEL_6_2; + default: + goto unknown_value; + } + + case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: + switch (value) { + case HFI_H264_ENTROPY_CAVLC: + return V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC; + case HFI_H264_ENTROPY_CABAC: + return V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC; + default: + goto unknown_value; + } + case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: + switch (value) { + case HFI_HEVC_PROFILE_MAIN: + return V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN; + case HFI_HEVC_PROFILE_MAIN10: + return V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10; + case HFI_HEVC_PROFILE_MAIN_STILL_PIC: + return V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE; + default: + goto unknown_value; + } + case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: + switch (value) { + case HFI_HEVC_LEVEL_1: + return V4L2_MPEG_VIDEO_HEVC_LEVEL_1; + case HFI_HEVC_LEVEL_2: + return V4L2_MPEG_VIDEO_HEVC_LEVEL_2; + case HFI_HEVC_LEVEL_21: + return V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1; + case HFI_HEVC_LEVEL_3: + return V4L2_MPEG_VIDEO_HEVC_LEVEL_3; + case HFI_HEVC_LEVEL_31: + return V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1; + case HFI_HEVC_LEVEL_4: + return V4L2_MPEG_VIDEO_HEVC_LEVEL_4; + case HFI_HEVC_LEVEL_41: + return V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1; + case HFI_HEVC_LEVEL_5: + return V4L2_MPEG_VIDEO_HEVC_LEVEL_5; + case HFI_HEVC_LEVEL_51: + return V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1; + case HFI_HEVC_LEVEL_52: + return V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2; + case HFI_HEVC_LEVEL_6: + return V4L2_MPEG_VIDEO_HEVC_LEVEL_6; + case HFI_HEVC_LEVEL_61: + return V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1; + case HFI_HEVC_LEVEL_62: + return V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2; + case HFI_LEVEL_UNKNOWN: + return V4L2_MPEG_VIDEO_HEVC_LEVEL_UNKNOWN; + default: + goto unknown_value; + } + case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL: + switch (value) { + case HFI_VP8_LEVEL_VERSION_0: + return V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0; + case HFI_VP8_LEVEL_VERSION_1: + return V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1; + case HFI_VP8_LEVEL_VERSION_2: + return V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_2; + case HFI_VP8_LEVEL_VERSION_3: + return V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3; + case HFI_LEVEL_UNKNOWN: + return V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED; + default: + goto unknown_value; + } + case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: + switch (value) { + case HFI_VP9_PROFILE_P0: + return V4L2_MPEG_VIDEO_VP9_PROFILE_0; + case HFI_VP9_PROFILE_P2_10B: + return V4L2_MPEG_VIDEO_VP9_PROFILE_2; + default: + goto unknown_value; + } + case V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL: + switch (value) { + case HFI_VP9_LEVEL_1: + return V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_1; + case HFI_VP9_LEVEL_11: + return V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_11; + case HFI_VP9_LEVEL_2: + return V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_2; + case HFI_VP9_LEVEL_21: + return V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_21; + case HFI_VP9_LEVEL_3: + return V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_3; + case HFI_VP9_LEVEL_31: + return V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_31; + case HFI_VP9_LEVEL_4: + return V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_4; + case HFI_VP9_LEVEL_41: + return V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_41; + case HFI_VP9_LEVEL_5: + return V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_5; + case HFI_VP9_LEVEL_51: + return V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_51; + case HFI_VP9_LEVEL_6: + return V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6; + case HFI_VP9_LEVEL_61: + return V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_61; + case HFI_LEVEL_UNKNOWN: + return V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_UNUSED; + default: + goto unknown_value; + } + case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE: + switch (value) { + case HFI_MPEG2_PROFILE_SIMPLE: + return V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_SIMPLE; + case HFI_MPEG2_PROFILE_MAIN: + return V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_MAIN; + default: + goto unknown_value; + } + case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL: + /* This mapping is not defined properly in V4L2 */ + switch (value) { + case HFI_MPEG2_LEVEL_LL: + return V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_0; + case HFI_MPEG2_LEVEL_ML: + return V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_1; + case HFI_MPEG2_LEVEL_HL: + return V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_2; + default: + goto unknown_value; + } + } + +unknown_value: + dprintk(VIDC_WARN, "Unknown control (%x, %d)\n", id, value); + return -EINVAL; +} + +static int h264_level_v4l2_to_hfi(int value) +{ + switch (value) { + case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: + return HFI_H264_LEVEL_1; + case V4L2_MPEG_VIDEO_H264_LEVEL_1B: + return HFI_H264_LEVEL_1b; + case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: + return HFI_H264_LEVEL_11; + case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: + return HFI_H264_LEVEL_12; + case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: + return HFI_H264_LEVEL_13; + case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: + return HFI_H264_LEVEL_2; + case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: + return HFI_H264_LEVEL_21; + case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: + return HFI_H264_LEVEL_22; + case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: + return HFI_H264_LEVEL_3; + case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: + return HFI_H264_LEVEL_31; + case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: + return HFI_H264_LEVEL_32; + case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: + return HFI_H264_LEVEL_4; + case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: + return HFI_H264_LEVEL_41; + case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: + return HFI_H264_LEVEL_42; + case V4L2_MPEG_VIDEO_H264_LEVEL_5_0: + return HFI_H264_LEVEL_5; + case V4L2_MPEG_VIDEO_H264_LEVEL_5_1: + return HFI_H264_LEVEL_51; + case V4L2_MPEG_VIDEO_H264_LEVEL_5_2: + return HFI_H264_LEVEL_52; + case V4L2_MPEG_VIDEO_H264_LEVEL_6_0: + return HFI_H264_LEVEL_6; + case V4L2_MPEG_VIDEO_H264_LEVEL_6_1: + return HFI_H264_LEVEL_61; + case V4L2_MPEG_VIDEO_H264_LEVEL_6_2: + return HFI_H264_LEVEL_62; + case V4L2_MPEG_VIDEO_H264_LEVEL_UNKNOWN: + return HFI_LEVEL_UNKNOWN; + default: + goto unknown_value; + } + +unknown_value: + dprintk(VIDC_WARN, "Unknown level (%d)\n", value); + return -EINVAL; +} + +static int hevc_level_v4l2_to_hfi(int value) +{ + switch (value) { + case V4L2_MPEG_VIDEO_HEVC_LEVEL_1: + return HFI_HEVC_LEVEL_1; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_2: + return HFI_HEVC_LEVEL_2; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1: + return HFI_HEVC_LEVEL_21; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_3: + return HFI_HEVC_LEVEL_3; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1: + return HFI_HEVC_LEVEL_31; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_4: + return HFI_HEVC_LEVEL_4; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1: + return HFI_HEVC_LEVEL_41; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_5: + return HFI_HEVC_LEVEL_5; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1: + return HFI_HEVC_LEVEL_51; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2: + return HFI_HEVC_LEVEL_52; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_6: + return HFI_HEVC_LEVEL_6; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1: + return HFI_HEVC_LEVEL_61; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2: + return HFI_HEVC_LEVEL_62; + case V4L2_MPEG_VIDEO_HEVC_LEVEL_UNKNOWN: + return HFI_LEVEL_UNKNOWN; + default: + goto unknown_value; + } + +unknown_value: + dprintk(VIDC_WARN, "Unknown level (%d)\n", value); + return -EINVAL; +} + +static int vp9_level_v4l2_to_hfi(int value) +{ + switch (value) { + case V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_1: + return HFI_VP9_LEVEL_1; + case V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_11: + return HFI_VP9_LEVEL_11; + case V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_2: + return HFI_VP9_LEVEL_2; + case V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_21: + return HFI_VP9_LEVEL_21; + case V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_3: + return HFI_VP9_LEVEL_3; + case V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_31: + return HFI_VP9_LEVEL_31; + case V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_4: + return HFI_VP9_LEVEL_4; + case V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_41: + return HFI_VP9_LEVEL_41; + case V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_5: + return HFI_VP9_LEVEL_5; + case V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_51: + return HFI_VP9_LEVEL_51; + case V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6: + return HFI_VP9_LEVEL_6; + case V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_61: + return HFI_VP9_LEVEL_61; + case V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_UNUSED: + return HFI_LEVEL_UNKNOWN; + default: + goto unknown_value; + } + +unknown_value: + dprintk(VIDC_WARN, "Unknown level (%d)\n", value); + return -EINVAL; + +} +int msm_comm_v4l2_to_hfi(int id, int value) +{ + switch (id) { + /* H264 */ + case V4L2_CID_MPEG_VIDEO_H264_PROFILE: + switch (value) { + case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: + return HFI_H264_PROFILE_BASELINE; + case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: + return HFI_H264_PROFILE_CONSTRAINED_BASE; + case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: + return HFI_H264_PROFILE_MAIN; + case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: + return HFI_H264_PROFILE_HIGH; + case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH: + return HFI_H264_PROFILE_STEREO_HIGH; + case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH: + return HFI_H264_PROFILE_MULTIVIEW_HIGH; + case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH: + return HFI_H264_PROFILE_CONSTRAINED_HIGH; + default: + return HFI_H264_PROFILE_HIGH; + } + case V4L2_CID_MPEG_VIDEO_H264_LEVEL: + return h264_level_v4l2_to_hfi(value); + case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: + switch (value) { + case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC: + return HFI_H264_ENTROPY_CAVLC; + case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC: + return HFI_H264_ENTROPY_CABAC; + default: + return HFI_H264_ENTROPY_CABAC; + } + case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: + switch (value) { + case V4L2_MPEG_VIDEO_VP8_PROFILE_0: + return HFI_VP8_PROFILE_MAIN; + default: + return HFI_VP8_PROFILE_MAIN; + } + case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL: + switch (value) { + case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0: + return HFI_VP8_LEVEL_VERSION_0; + case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1: + return HFI_VP8_LEVEL_VERSION_1; + case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_2: + return HFI_VP8_LEVEL_VERSION_2; + case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3: + return HFI_VP8_LEVEL_VERSION_3; + case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED: + return HFI_LEVEL_UNKNOWN; + default: + return HFI_LEVEL_UNKNOWN; + } + case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: + switch (value) { + case V4L2_MPEG_VIDEO_VP9_PROFILE_0: + return HFI_VP9_PROFILE_P0; + case V4L2_MPEG_VIDEO_VP9_PROFILE_2: + return HFI_VP9_PROFILE_P2_10B; + default: + return HFI_VP9_PROFILE_P0; + } + case V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL: + return vp9_level_v4l2_to_hfi(value); + case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: + switch (value) { + case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN: + return HFI_HEVC_PROFILE_MAIN; + case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10: + return HFI_HEVC_PROFILE_MAIN10; + case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE: + return HFI_HEVC_PROFILE_MAIN_STILL_PIC; + default: + return HFI_HEVC_PROFILE_MAIN; + } + case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: + return hevc_level_v4l2_to_hfi(value); + case V4L2_CID_MPEG_VIDEO_HEVC_TIER: + switch (value) { + case V4L2_MPEG_VIDEO_HEVC_TIER_MAIN: + return HFI_HEVC_TIER_MAIN; + case V4L2_MPEG_VIDEO_HEVC_TIER_HIGH: + return HFI_HEVC_TIER_HIGH; + default: + return HFI_HEVC_TIER_HIGH; + } + case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE: + switch (value) { + case V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_SIMPLE: + return HFI_MPEG2_PROFILE_SIMPLE; + case V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_MAIN: + return HFI_MPEG2_PROFILE_MAIN; + default: + return HFI_MPEG2_PROFILE_MAIN; + } + case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL: + /* This mapping is not defined properly in V4L2 */ + switch (value) { + case V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_0: + return HFI_MPEG2_LEVEL_LL; + case V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_1: + return HFI_MPEG2_LEVEL_ML; + case V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_2: + return HFI_MPEG2_LEVEL_HL; + default: + return HFI_MPEG2_LEVEL_HL; + } + case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: + switch (value) { + case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED: + return HFI_H264_DB_MODE_DISABLE; + case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED: + return HFI_H264_DB_MODE_ALL_BOUNDARY; + case L_MODE: + return HFI_H264_DB_MODE_SKIP_SLICE_BOUNDARY; + default: + return HFI_H264_DB_MODE_ALL_BOUNDARY; + } + } + dprintk(VIDC_WARN, "Unknown control (%x, %d)\n", id, value); + return -EINVAL; +} + +int msm_comm_get_v4l2_profile(int fourcc, int profile) +{ + switch (fourcc) { + case V4L2_PIX_FMT_H264: + return msm_comm_hfi_to_v4l2( + V4L2_CID_MPEG_VIDEO_H264_PROFILE, + profile); + case V4L2_PIX_FMT_HEVC: + return msm_comm_hfi_to_v4l2( + V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, + profile); + case V4L2_PIX_FMT_VP8: + case V4L2_PIX_FMT_VP9: + case V4L2_PIX_FMT_MPEG2: + return 0; + default: + dprintk(VIDC_WARN, "Unknown codec id %x\n", fourcc); + return 0; + } +} + +int msm_comm_get_v4l2_level(int fourcc, int level) +{ + switch (fourcc) { + case V4L2_PIX_FMT_H264: + return msm_comm_hfi_to_v4l2( + V4L2_CID_MPEG_VIDEO_H264_LEVEL, + level); + case V4L2_PIX_FMT_HEVC: + level &= ~(0xF << 28); + return msm_comm_hfi_to_v4l2( + V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, + level); + case V4L2_PIX_FMT_VP8: + return msm_comm_hfi_to_v4l2( + V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL, + level); + case V4L2_PIX_FMT_VP9: + case V4L2_PIX_FMT_MPEG2: + return 0; + default: + dprintk(VIDC_WARN, "Unknown codec id %x\n", fourcc); + return 0; + } +} + +int msm_comm_ctrl_init(struct msm_vidc_inst *inst, + struct msm_vidc_ctrl *drv_ctrls, u32 num_ctrls, + const struct v4l2_ctrl_ops *ctrl_ops) +{ + int idx = 0; + struct v4l2_ctrl_config ctrl_cfg = {0}; + int ret_val = 0; + + if (!inst || !drv_ctrls || !ctrl_ops || !num_ctrls) { + dprintk(VIDC_ERR, "%s - invalid input\n", __func__); + return -EINVAL; + } + + inst->ctrls = kcalloc(num_ctrls, sizeof(struct v4l2_ctrl *), + GFP_KERNEL); + if (!inst->ctrls) { + dprintk(VIDC_ERR, "%s - failed to allocate ctrl\n", __func__); + return -ENOMEM; + } + + ret_val = v4l2_ctrl_handler_init(&inst->ctrl_handler, num_ctrls); + + if (ret_val) { + dprintk(VIDC_ERR, "CTRL ERR: Control handler init failed, %d\n", + inst->ctrl_handler.error); + return ret_val; + } + + for (; idx < (int) num_ctrls; idx++) { + struct v4l2_ctrl *ctrl = NULL; + + if (IS_PRIV_CTRL(drv_ctrls[idx].id)) { + /*add private control*/ + ctrl_cfg.def = drv_ctrls[idx].default_value; + ctrl_cfg.flags = 0; + ctrl_cfg.id = drv_ctrls[idx].id; + ctrl_cfg.max = drv_ctrls[idx].maximum; + ctrl_cfg.min = drv_ctrls[idx].minimum; + ctrl_cfg.menu_skip_mask = + drv_ctrls[idx].menu_skip_mask; + ctrl_cfg.name = drv_ctrls[idx].name; + ctrl_cfg.ops = ctrl_ops; + ctrl_cfg.step = drv_ctrls[idx].step; + ctrl_cfg.type = drv_ctrls[idx].type; + ctrl_cfg.qmenu = drv_ctrls[idx].qmenu; + + ctrl = v4l2_ctrl_new_custom(&inst->ctrl_handler, + &ctrl_cfg, NULL); + } else { + if (drv_ctrls[idx].type == V4L2_CTRL_TYPE_MENU) { + ctrl = v4l2_ctrl_new_std_menu( + &inst->ctrl_handler, + ctrl_ops, + drv_ctrls[idx].id, + (u8) drv_ctrls[idx].maximum, + drv_ctrls[idx].menu_skip_mask, + (u8) drv_ctrls[idx].default_value); + } else { + ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, + ctrl_ops, + drv_ctrls[idx].id, + drv_ctrls[idx].minimum, + drv_ctrls[idx].maximum, + drv_ctrls[idx].step, + drv_ctrls[idx].default_value); + } + } + + if (!ctrl) { + dprintk(VIDC_ERR, "%s - invalid ctrl %s\n", __func__, + drv_ctrls[idx].name); + return -EINVAL; + } + + ret_val = inst->ctrl_handler.error; + if (ret_val) { + dprintk(VIDC_ERR, + "Error adding ctrl (%s) to ctrl handle, %d\n", + drv_ctrls[idx].name, inst->ctrl_handler.error); + return ret_val; + } + + ctrl->flags |= drv_ctrls[idx].flags; + inst->ctrls[idx] = ctrl; + } + inst->num_ctrls = num_ctrls; + + /* Construct a super cluster of all controls */ + inst->cluster = get_super_cluster(inst, num_ctrls); + if (!inst->cluster) { + dprintk(VIDC_WARN, + "Failed to setup super cluster\n"); + return -EINVAL; + } + + v4l2_ctrl_cluster(num_ctrls, inst->cluster); + + return ret_val; +} + +int msm_comm_ctrl_deinit(struct msm_vidc_inst *inst) +{ + if (!inst) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + kfree(inst->ctrls); + kfree(inst->cluster); + v4l2_ctrl_handler_free(&inst->ctrl_handler); + + return 0; +} + +int msm_comm_set_stream_output_mode(struct msm_vidc_inst *inst, + enum multi_stream mode) +{ + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (!is_decode_session(inst)) { + dprintk(VIDC_DBG, "%s: not a decode session %x\n", + __func__, hash32_ptr(inst->session)); + return -EINVAL; + } + + if (mode == HAL_VIDEO_DECODER_SECONDARY) + inst->stream_output_mode = HAL_VIDEO_DECODER_SECONDARY; + else + inst->stream_output_mode = HAL_VIDEO_DECODER_PRIMARY; + + return 0; +} + +enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst) +{ + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params, return default mode\n", + __func__); + return HAL_VIDEO_DECODER_PRIMARY; + } + + if (!is_decode_session(inst)) + return HAL_VIDEO_DECODER_PRIMARY; + + if (inst->stream_output_mode == HAL_VIDEO_DECODER_SECONDARY) + return HAL_VIDEO_DECODER_SECONDARY; + else + return HAL_VIDEO_DECODER_PRIMARY; +} + +static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst) +{ + int input_port_mbs, output_port_mbs; + int fps; + struct v4l2_format *f; + + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + input_port_mbs = inst->in_reconfig ? + NUM_MBS_PER_FRAME(inst->reconfig_width, + inst->reconfig_height) : + NUM_MBS_PER_FRAME(f->fmt.pix_mp.width, + f->fmt.pix_mp.height); + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + output_port_mbs = NUM_MBS_PER_FRAME(f->fmt.pix_mp.width, + f->fmt.pix_mp.height); + + if (inst->clk_data.operating_rate > inst->clk_data.frame_rate) + fps = (inst->clk_data.operating_rate >> 16) ? + inst->clk_data.operating_rate >> 16 : 1; + else + fps = inst->clk_data.frame_rate >> 16; + + return max(input_port_mbs, output_port_mbs) * fps; +} + +int msm_comm_get_inst_load(struct msm_vidc_inst *inst, + enum load_calc_quirks quirks) +{ + int load = 0; + + mutex_lock(&inst->lock); + + if (!(inst->state >= MSM_VIDC_OPEN_DONE && + inst->state < MSM_VIDC_STOP_DONE)) + goto exit; + + load = msm_comm_get_mbs_per_sec(inst); + + if (is_thumbnail_session(inst)) { + if (quirks & LOAD_CALC_IGNORE_THUMBNAIL_LOAD) + load = 0; + } + + if (is_turbo_session(inst)) { + if (!(quirks & LOAD_CALC_IGNORE_TURBO_LOAD)) + load = inst->core->resources.max_load; + } + + /* Clock and Load calculations for REALTIME/NON-REALTIME + * OPERATING RATE SET/NO OPERATING RATE SET + * + * | OPERATING RATE SET | OPERATING RATE NOT SET | + * ----------------|--------------------- |------------------------| + * REALTIME | load = res * op_rate | load = res * fps | + * | clk = res * op_rate | clk = res * fps | + * ----------------|----------------------|------------------------| + * NON-REALTIME | load = res * 1 fps | load = res * 1 fps | + * | clk = res * op_rate | clk = res * fps | + * ----------------|----------------------|------------------------| + */ + + if (!is_realtime_session(inst) && + (quirks & LOAD_CALC_IGNORE_NON_REALTIME_LOAD)) { + if (!(inst->clk_data.frame_rate >> 16)) { + dprintk(VIDC_INFO, "instance:%pK fps = 0\n", inst); + load = 0; + } else { + load = msm_comm_get_mbs_per_sec(inst) / + (inst->clk_data.frame_rate >> 16); + } + } + +exit: + mutex_unlock(&inst->lock); + return load; +} + +int msm_comm_get_inst_load_per_core(struct msm_vidc_inst *inst, + enum load_calc_quirks quirks) +{ + int load = msm_comm_get_inst_load(inst, quirks); + + if (inst->clk_data.core_id == VIDC_CORE_ID_3) + load = load / 2; + + return load; +} + +int msm_comm_get_load(struct msm_vidc_core *core, + enum session_type type, enum load_calc_quirks quirks) +{ + struct msm_vidc_inst *inst = NULL; + int num_mbs_per_sec = 0; + + if (!core) { + dprintk(VIDC_ERR, "Invalid args: %pK\n", core); + return -EINVAL; + } + + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) { + if (inst->session_type != type) + continue; + + num_mbs_per_sec += msm_comm_get_inst_load(inst, quirks); + } + mutex_unlock(&core->lock); + + return num_mbs_per_sec; +} + +enum hal_domain get_hal_domain(int session_type) +{ + enum hal_domain domain; + + switch (session_type) { + case MSM_VIDC_ENCODER: + domain = HAL_VIDEO_DOMAIN_ENCODER; + break; + case MSM_VIDC_DECODER: + domain = HAL_VIDEO_DOMAIN_DECODER; + break; + case MSM_VIDC_CVP: + domain = HAL_VIDEO_DOMAIN_CVP; + break; + default: + dprintk(VIDC_ERR, "Wrong domain %d\n", session_type); + domain = HAL_UNUSED_DOMAIN; + break; + } + + return domain; +} + +enum hal_video_codec get_hal_codec(int fourcc) +{ + enum hal_video_codec codec; + + switch (fourcc) { + case V4L2_PIX_FMT_H264: + case V4L2_PIX_FMT_H264_NO_SC: + codec = HAL_VIDEO_CODEC_H264; + break; + case V4L2_PIX_FMT_H264_MVC: + codec = HAL_VIDEO_CODEC_MVC; + break; + case V4L2_PIX_FMT_MPEG1: + codec = HAL_VIDEO_CODEC_MPEG1; + break; + case V4L2_PIX_FMT_MPEG2: + codec = HAL_VIDEO_CODEC_MPEG2; + break; + case V4L2_PIX_FMT_VP8: + codec = HAL_VIDEO_CODEC_VP8; + break; + case V4L2_PIX_FMT_VP9: + codec = HAL_VIDEO_CODEC_VP9; + break; + case V4L2_PIX_FMT_HEVC: + codec = HAL_VIDEO_CODEC_HEVC; + break; + case V4L2_PIX_FMT_TME: + codec = HAL_VIDEO_CODEC_TME; + break; + case V4L2_PIX_FMT_CVP: + codec = HAL_VIDEO_CODEC_CVP; + break; + default: + dprintk(VIDC_ERR, "Wrong codec: %#x\n", fourcc); + codec = HAL_UNUSED_CODEC; + break; + } + + return codec; +} + +enum hal_uncompressed_format msm_comm_get_hal_uncompressed(int fourcc) +{ + enum hal_uncompressed_format format = HAL_UNUSED_COLOR; + + switch (fourcc) { + case V4L2_PIX_FMT_NV12: + format = HAL_COLOR_FORMAT_NV12; + break; + case V4L2_PIX_FMT_NV12_512: + format = HAL_COLOR_FORMAT_NV12_512; + break; + case V4L2_PIX_FMT_NV21: + format = HAL_COLOR_FORMAT_NV21; + break; + case V4L2_PIX_FMT_NV12_UBWC: + format = HAL_COLOR_FORMAT_NV12_UBWC; + break; + case V4L2_PIX_FMT_NV12_TP10_UBWC: + format = HAL_COLOR_FORMAT_NV12_TP10_UBWC; + break; + case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS: + format = HAL_COLOR_FORMAT_P010; + break; + default: + format = HAL_UNUSED_COLOR; + break; + } + + return format; +} + +u32 msm_comm_get_hfi_uncompressed(int fourcc) +{ + u32 format; + + switch (fourcc) { + case V4L2_PIX_FMT_NV12: + format = HFI_COLOR_FORMAT_NV12; + break; + case V4L2_PIX_FMT_NV12_512: + format = HFI_COLOR_FORMAT_NV12; + break; + case V4L2_PIX_FMT_NV21: + format = HFI_COLOR_FORMAT_NV21; + break; + case V4L2_PIX_FMT_NV12_UBWC: + format = HFI_COLOR_FORMAT_NV12_UBWC; + break; + case V4L2_PIX_FMT_NV12_TP10_UBWC: + format = HFI_COLOR_FORMAT_YUV420_TP10_UBWC; + break; + case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS: + format = HFI_COLOR_FORMAT_P010; + break; + default: + format = HFI_COLOR_FORMAT_NV12_UBWC; + dprintk(VIDC_ERR, "Invalid format, defaulting to UBWC"); + break; + } + + return format; +} +struct msm_vidc_core *get_vidc_core(int core_id) +{ + struct msm_vidc_core *core; + int found = 0; + + if (core_id > MSM_VIDC_CORES_MAX) { + dprintk(VIDC_ERR, "Core id = %d is greater than max = %d\n", + core_id, MSM_VIDC_CORES_MAX); + return NULL; + } + mutex_lock(&vidc_driver->lock); + list_for_each_entry(core, &vidc_driver->cores, list) { + if (core->id == core_id) { + found = 1; + break; + } + } + mutex_unlock(&vidc_driver->lock); + if (found) + return core; + return NULL; +} + +const struct msm_vidc_format_desc *msm_comm_get_pixel_fmt_index( + const struct msm_vidc_format_desc fmt[], int size, int index) +{ + int i, k = 0; + + if (!fmt || index < 0) { + dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK, index = %d\n", + fmt, index); + return NULL; + } + for (i = 0; i < size; i++) { + if (k == index) + break; + k++; + } + if (i == size) { + dprintk(VIDC_INFO, "Format not found\n"); + return NULL; + } + return &fmt[i]; +} +struct msm_vidc_format_desc *msm_comm_get_pixel_fmt_fourcc( + struct msm_vidc_format_desc fmt[], int size, int fourcc) +{ + int i; + + if (!fmt) { + dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK\n", fmt); + return NULL; + } + for (i = 0; i < size; i++) { + if (fmt[i].fourcc == fourcc) + break; + } + if (i == size) { + dprintk(VIDC_INFO, "Format not found\n"); + return NULL; + } + return &fmt[i]; +} + +struct msm_vidc_format_constraint *msm_comm_get_pixel_fmt_constraints( + struct msm_vidc_format_constraint fmt[], int size, int fourcc) +{ + int i; + + if (!fmt) { + dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK\n", fmt); + return NULL; + } + for (i = 0; i < size; i++) { + if (fmt[i].fourcc == fourcc) + break; + } + if (i == size) { + dprintk(VIDC_INFO, "Format constraint not found.\n"); + return NULL; + } + return &fmt[i]; +} + +struct buf_queue *msm_comm_get_vb2q( + struct msm_vidc_inst *inst, enum v4l2_buf_type type) +{ + if (type == OUTPUT_MPLANE) + return &inst->bufq[OUTPUT_PORT]; + if (type == INPUT_MPLANE) + return &inst->bufq[INPUT_PORT]; + return NULL; +} + +static void update_capability(struct msm_vidc_codec_capability *in, + struct msm_vidc_capability *capability) +{ + if (!in || !capability) { + dprintk(VIDC_ERR, "%s Invalid params\n", __func__); + return; + } + + if (in->capability_type < CAP_MAX) { + capability->cap[in->capability_type].capability_type = + in->capability_type; + capability->cap[in->capability_type].min = in->min; + capability->cap[in->capability_type].max = in->max; + capability->cap[in->capability_type].step_size = in->step_size; + capability->cap[in->capability_type].default_value = + in->default_value; + } else { + dprintk(VIDC_ERR, "%s: invalid capability_type %d\n", + __func__, in->capability_type); + } +} + +static int msm_vidc_capabilities(struct msm_vidc_core *core) +{ + int rc = 0; + struct msm_vidc_codec_capability *platform_caps; + int i, j, num_platform_caps; + + if (!core || !core->capabilities) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + platform_caps = core->resources.codec_caps; + num_platform_caps = core->resources.codec_caps_count; + + dprintk(VIDC_DBG, "%s: num caps %d\n", __func__, num_platform_caps); + /* loop over each platform capability */ + for (i = 0; i < num_platform_caps; i++) { + /* select matching core codec and update it */ + for (j = 0; j < core->resources.codecs_count; j++) { + if ((platform_caps[i].domains & + core->capabilities[j].domain) && + (platform_caps[i].codecs & + core->capabilities[j].codec)) { + /* update core capability */ + update_capability(&platform_caps[i], + &core->capabilities[j]); + } + } + } + + return rc; +} + +static void handle_sys_init_done(enum hal_command_response cmd, void *data) +{ + struct msm_vidc_cb_cmd_done *response = data; + struct msm_vidc_core *core; + + if (!IS_HAL_SYS_CMD(cmd)) { + dprintk(VIDC_ERR, "%s - invalid cmd\n", __func__); + return; + } + if (!response) { + dprintk(VIDC_ERR, + "Failed to get valid response for sys init\n"); + return; + } + core = get_vidc_core(response->device_id); + if (!core) { + dprintk(VIDC_ERR, "Wrong device_id received\n"); + return; + } + dprintk(VIDC_DBG, "%s: core %pK\n", __func__, core); + complete(&(core->completions[SYS_MSG_INDEX(cmd)])); +} + +static void put_inst_helper(struct kref *kref) +{ + struct msm_vidc_inst *inst = container_of(kref, + struct msm_vidc_inst, kref); + + msm_vidc_destroy(inst); +} + +void put_inst(struct msm_vidc_inst *inst) +{ + if (!inst) + return; + + kref_put(&inst->kref, put_inst_helper); +} + +struct msm_vidc_inst *get_inst(struct msm_vidc_core *core, + void *session_id) +{ + struct msm_vidc_inst *inst = NULL; + bool matches = false; + + if (!core || !session_id) + return NULL; + + mutex_lock(&core->lock); + /* + * This is as good as !list_empty(!inst->list), but at this point + * we don't really know if inst was kfree'd via close syscall before + * hardware could respond. So manually walk thru the list of active + * sessions + */ + list_for_each_entry(inst, &core->instances, list) { + if (inst == session_id) { + /* + * Even if the instance is valid, we really shouldn't + * be receiving or handling callbacks when we've deleted + * our session with HFI + */ + matches = !!inst->session; + break; + } + } + + /* + * kref_* is atomic_int backed, so no need for inst->lock. But we can + * always acquire inst->lock and release it in put_inst for a stronger + * locking system. + */ + inst = (matches && kref_get_unless_zero(&inst->kref)) ? inst : NULL; + mutex_unlock(&core->lock); + + return inst; +} + +static void handle_session_release_buf_done(enum hal_command_response cmd, + void *data) +{ + struct msm_vidc_cb_cmd_done *response = data; + struct msm_vidc_inst *inst; + struct internal_buf *buf; + struct list_head *ptr, *next; + struct hal_buffer_info *buffer; + u32 buf_found = false; + u32 address; + + if (!response) { + dprintk(VIDC_ERR, "Invalid release_buf_done response\n"); + return; + } + + inst = get_inst(get_vidc_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + return; + } + + buffer = &response->data.buffer_info; + address = buffer->buffer_addr; + + mutex_lock(&inst->scratchbufs.lock); + list_for_each_safe(ptr, next, &inst->scratchbufs.list) { + buf = list_entry(ptr, struct internal_buf, list); + if (address == buf->smem.device_addr) { + dprintk(VIDC_DBG, "releasing scratch: %x\n", + buf->smem.device_addr); + buf_found = true; + } + } + mutex_unlock(&inst->scratchbufs.lock); + + mutex_lock(&inst->persistbufs.lock); + list_for_each_safe(ptr, next, &inst->persistbufs.list) { + buf = list_entry(ptr, struct internal_buf, list); + if (address == buf->smem.device_addr) { + dprintk(VIDC_DBG, "releasing persist: %x\n", + buf->smem.device_addr); + buf_found = true; + } + } + mutex_unlock(&inst->persistbufs.lock); + + if (!buf_found) + dprintk(VIDC_ERR, "invalid buffer received from firmware"); + if (IS_HAL_SESSION_CMD(cmd)) + complete(&inst->completions[SESSION_MSG_INDEX(cmd)]); + else + dprintk(VIDC_ERR, "Invalid inst cmd response: %d\n", cmd); + + put_inst(inst); +} + +static void handle_sys_release_res_done( + enum hal_command_response cmd, void *data) +{ + struct msm_vidc_cb_cmd_done *response = data; + struct msm_vidc_core *core; + + if (!response) { + dprintk(VIDC_ERR, + "Failed to get valid response for sys init\n"); + return; + } + core = get_vidc_core(response->device_id); + if (!core) { + dprintk(VIDC_ERR, "Wrong device_id received\n"); + return; + } + complete(&core->completions[ + SYS_MSG_INDEX(HAL_SYS_RELEASE_RESOURCE_DONE)]); +} + +void change_inst_state(struct msm_vidc_inst *inst, enum instance_state state) +{ + if (!inst) { + dprintk(VIDC_ERR, "Invalid parameter %s\n", __func__); + return; + } + mutex_lock(&inst->lock); + if (inst->state == MSM_VIDC_CORE_INVALID) { + dprintk(VIDC_DBG, + "Inst: %pK is in bad state can't change state to %d\n", + inst, state); + goto exit; + } + dprintk(VIDC_DBG, "Moved inst: %pK from state: %d to state: %d\n", + inst, inst->state, state); + inst->state = state; +exit: + mutex_unlock(&inst->lock); +} + +static int signal_session_msg_receipt(enum hal_command_response cmd, + struct msm_vidc_inst *inst) +{ + if (!inst) { + dprintk(VIDC_ERR, "Invalid(%pK) instance id\n", inst); + return -EINVAL; + } + if (IS_HAL_SESSION_CMD(cmd)) { + complete(&inst->completions[SESSION_MSG_INDEX(cmd)]); + } else { + dprintk(VIDC_ERR, "Invalid inst cmd response: %d\n", cmd); + return -EINVAL; + } + return 0; +} + +static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst, + enum hal_command_response cmd) +{ + int rc = 0; + struct hfi_device *hdev; + + if (!IS_HAL_SESSION_CMD(cmd)) { + dprintk(VIDC_ERR, "Invalid inst cmd response: %d\n", cmd); + return -EINVAL; + } + hdev = (struct hfi_device *)(inst->core->device); + rc = wait_for_completion_timeout( + &inst->completions[SESSION_MSG_INDEX(cmd)], + msecs_to_jiffies( + inst->core->resources.msm_vidc_hw_rsp_timeout)); + if (!rc) { + dprintk(VIDC_ERR, "Wait interrupted or timed out: %d\n", + SESSION_MSG_INDEX(cmd)); + msm_comm_kill_session(inst); + rc = -EIO; + } else { + rc = 0; + } + return rc; +} + +static int wait_for_state(struct msm_vidc_inst *inst, + enum instance_state flipped_state, + enum instance_state desired_state, + enum hal_command_response hal_cmd) +{ + int rc = 0; + + if (IS_ALREADY_IN_STATE(flipped_state, desired_state)) { + dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", + inst, inst->state); + goto err_same_state; + } + dprintk(VIDC_DBG, "Waiting for hal_cmd: %d\n", hal_cmd); + rc = wait_for_sess_signal_receipt(inst, hal_cmd); + if (!rc) + change_inst_state(inst, desired_state); +err_same_state: + return rc; +} + +void msm_vidc_queue_v4l2_event(struct msm_vidc_inst *inst, int event_type) +{ + struct v4l2_event event = {.id = 0, .type = event_type}; + + v4l2_event_queue_fh(&inst->event_handler, &event); +} + +static void msm_comm_generate_max_clients_error(struct msm_vidc_inst *inst) +{ + enum hal_command_response cmd = HAL_SESSION_ERROR; + struct msm_vidc_cb_cmd_done response = {0}; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); + return; + } + dprintk(VIDC_ERR, "%s: Too many clients\n", __func__); + response.session_id = inst; + response.status = VIDC_ERR_MAX_CLIENTS; + handle_session_error(cmd, (void *)&response); +} + +static void print_cap(const char *type, + struct hal_capability_supported *cap) +{ + dprintk(VIDC_DBG, + "%-24s: %-10d %-10d %-10d %-10d\n", + type, cap->min, cap->max, cap->step_size, cap->default_value); +} + +static int msm_vidc_comm_update_ctrl(struct msm_vidc_inst *inst, + u32 id, struct hal_capability_supported *cap) +{ + struct v4l2_ctrl *ctrl = NULL; + int rc = 0; + + ctrl = v4l2_ctrl_find(&inst->ctrl_handler, id); + if (!ctrl) { + dprintk(VIDC_ERR, + "%s: Conrol id %d not found\n", __func__, id); + return -EINVAL; + } + + rc = v4l2_ctrl_modify_range(ctrl, cap->min, cap->max, + cap->step_size, cap->default_value); + if (rc) { + dprintk(VIDC_ERR, + "%s: failed: control name %s, min %d, max %d, step %d, default_value %d\n", + __func__, ctrl->name, cap->min, cap->max, + cap->step_size, cap->default_value); + goto error; + } + /* + * v4l2_ctrl_modify_range() is not updating default_value, + * so use v4l2_ctrl_s_ctrl() to update it. + */ + rc = v4l2_ctrl_s_ctrl(ctrl, cap->default_value); + if (rc) { + dprintk(VIDC_ERR, + "%s: failed s_ctrl: %s with value %d\n", + __func__, ctrl->name, cap->default_value); + goto error; + } + dprintk(VIDC_DBG, + "Updated control: %s: min %lld, max %lld, step %lld, default value = %lld\n", + ctrl->name, ctrl->minimum, ctrl->maximum, + ctrl->step, ctrl->default_value); + +error: + return rc; +} + +static void msm_vidc_comm_update_ctrl_limits(struct msm_vidc_inst *inst) +{ + struct v4l2_format *f; + + if (inst->session_type == MSM_VIDC_ENCODER) { + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + if (get_hal_codec(f->fmt.pix_mp.pixelformat) == + HAL_VIDEO_CODEC_TME) + return; + msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE, + &inst->capability.cap[CAP_BITRATE]); + msm_vidc_comm_update_ctrl(inst, + V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES, + &inst->capability.cap[CAP_SLICE_BYTE]); + msm_vidc_comm_update_ctrl(inst, + V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB, + &inst->capability.cap[CAP_SLICE_MB]); + msm_vidc_comm_update_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT, + &inst->capability.cap[CAP_LTR_COUNT]); + msm_vidc_comm_update_ctrl(inst, + V4L2_CID_MPEG_VIDEO_B_FRAMES, + &inst->capability.cap[CAP_BFRAME]); + } +} + +static void handle_session_init_done(enum hal_command_response cmd, void *data) +{ + struct msm_vidc_cb_cmd_done *response = data; + struct msm_vidc_inst *inst = NULL; + struct msm_vidc_capability *capability = NULL; + struct msm_vidc_core *core; + u32 i, codec; + + if (!response) { + dprintk(VIDC_ERR, + "Failed to get valid response for session init\n"); + return; + } + + inst = get_inst(get_vidc_core(response->device_id), + response->session_id); + + if (!inst) { + dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + return; + } + + if (response->status) { + dprintk(VIDC_ERR, + "Session init response from FW : %#x\n", + response->status); + goto error; + } + + if (inst->session_type == MSM_VIDC_CVP) { + dprintk(VIDC_DBG, "%s: cvp session %#x\n", + __func__, hash32_ptr(inst->session)); + signal_session_msg_receipt(cmd, inst); + put_inst(inst); + return; + } + + core = inst->core; + codec = get_v4l2_codec(inst); + + for (i = 0; i < core->resources.codecs_count; i++) { + if (core->capabilities[i].codec == + get_hal_codec(codec) && + core->capabilities[i].domain == + get_hal_domain(inst->session_type)) { + capability = &core->capabilities[i]; + break; + } + } + if (!capability) { + dprintk(VIDC_ERR, + "%s: capabilities not found for domain %#x codec %#x\n", + __func__, get_hal_domain(inst->session_type), + get_hal_codec(codec)); + goto error; + } + + dprintk(VIDC_DBG, + "%s: capabilities for domain %#x codec %#x\n", + __func__, capability->domain, capability->codec); + memcpy(&inst->capability, capability, + sizeof(struct msm_vidc_capability)); + + dprintk(VIDC_DBG, + "Capability type : min max step_size default_value\n"); + print_cap("width", &inst->capability.cap[CAP_FRAME_WIDTH]); + print_cap("height", &inst->capability.cap[CAP_FRAME_HEIGHT]); + print_cap("mbs_per_frame", &inst->capability.cap[CAP_MBS_PER_FRAME]); + print_cap("mbs_per_sec", &inst->capability.cap[CAP_MBS_PER_SECOND]); + print_cap("frame_rate", &inst->capability.cap[CAP_FRAMERATE]); + print_cap("bitrate", &inst->capability.cap[CAP_BITRATE]); + print_cap("scale_x", &inst->capability.cap[CAP_SCALE_X]); + print_cap("scale_y", &inst->capability.cap[CAP_SCALE_Y]); + print_cap("hier_p", &inst->capability.cap[CAP_HIER_P_NUM_ENH_LAYERS]); + print_cap("ltr_count", &inst->capability.cap[CAP_LTR_COUNT]); + print_cap("bframe", &inst->capability.cap[CAP_BFRAME]); + print_cap("mbs_per_sec_low_power", + &inst->capability.cap[CAP_MBS_PER_SECOND_POWER_SAVE]); + print_cap("i_qp", &inst->capability.cap[CAP_I_FRAME_QP]); + print_cap("p_qp", &inst->capability.cap[CAP_P_FRAME_QP]); + print_cap("b_qp", &inst->capability.cap[CAP_B_FRAME_QP]); + print_cap("slice_bytes", &inst->capability.cap[CAP_SLICE_BYTE]); + print_cap("slice_mbs", &inst->capability.cap[CAP_SLICE_MB]); + + msm_vidc_comm_update_ctrl_limits(inst); + + signal_session_msg_receipt(cmd, inst); + put_inst(inst); + return; + +error: + if (response->status == VIDC_ERR_MAX_CLIENTS) + msm_comm_generate_max_clients_error(inst); + else + msm_comm_generate_session_error(inst); + + signal_session_msg_receipt(cmd, inst); + put_inst(inst); +} + +static void msm_vidc_queue_rbr_event(struct msm_vidc_inst *inst, + int fd, u32 offset) +{ + struct v4l2_event buf_event = {0}; + u32 *ptr; + + buf_event.type = V4L2_EVENT_RELEASE_BUFFER_REFERENCE; + ptr = (u32 *)buf_event.u.data; + ptr[0] = fd; + ptr[1] = offset; + + v4l2_event_queue_fh(&inst->event_handler, &buf_event); +} + +static void handle_event_change(enum hal_command_response cmd, void *data) +{ + struct msm_vidc_inst *inst = NULL; + struct msm_vidc_cb_event *event_notify = data; + int event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT; + struct v4l2_event seq_changed_event = {0}; + int rc = 0; + struct hfi_device *hdev; + u32 *ptr = NULL; + struct msm_vidc_format *fmt; + struct v4l2_format *f; + int extra_buff_count = 0; + u32 codec; + + if (!event_notify) { + dprintk(VIDC_WARN, "Got an empty event from hfi\n"); + return; + } + + inst = get_inst(get_vidc_core(event_notify->device_id), + event_notify->session_id); + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + goto err_bad_event; + } + hdev = inst->core->device; + + switch (event_notify->hal_event_type) { + case HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES: + { + /* + * Check if there is some parameter has changed + * If there is no change then no need to notify client + * If there is a change, then raise an insufficient event + */ + bool event_fields_changed = false; + + dprintk(VIDC_DBG, "V4L2_EVENT_SEQ_CHANGED_SUFFICIENT\n"); + dprintk(VIDC_DBG, + "event_notify->height = %d event_notify->width = %d\n", + event_notify->height, + event_notify->width); + event_fields_changed |= (inst->bit_depth != + event_notify->bit_depth); + /* Check for change from hdr->non-hdr and vice versa */ + if ((event_notify->colour_space == MSM_VIDC_BT2020 && + inst->colour_space != MSM_VIDC_BT2020) || + (event_notify->colour_space != MSM_VIDC_BT2020 && + inst->colour_space == MSM_VIDC_BT2020)) + event_fields_changed = true; + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + event_fields_changed |= + (f->fmt.pix_mp.height != event_notify->height); + event_fields_changed |= + (f->fmt.pix_mp.width != event_notify->width); + + if (event_fields_changed) { + event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT; + } else { + dprintk(VIDC_DBG, + "No parameter change continue session\n"); + rc = call_hfi_op(hdev, session_continue, + (void *)inst->session); + if (rc) { + dprintk(VIDC_ERR, + "failed to send session_continue\n"); + } + goto err_bad_event; + } + break; + } + case HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES: + event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT; + break; + case HAL_EVENT_RELEASE_BUFFER_REFERENCE: + { + struct msm_vidc_buffer *mbuf; + u32 planes[VIDEO_MAX_PLANES] = {0}; + + dprintk(VIDC_DBG, + "%s: inst: %pK data_buffer: %x extradata_buffer: %x\n", + __func__, inst, event_notify->packet_buffer, + event_notify->extra_data_buffer); + + planes[0] = event_notify->packet_buffer; + planes[1] = event_notify->extra_data_buffer; + mbuf = msm_comm_get_buffer_using_device_planes(inst, + OUTPUT_MPLANE, planes); + if (!mbuf || !kref_get_mbuf(inst, mbuf)) { + dprintk(VIDC_ERR, + "%s: data_addr %x, extradata_addr %x not found\n", + __func__, planes[0], planes[1]); + } else { + handle_release_buffer_reference(inst, mbuf); + kref_put_mbuf(mbuf); + } + goto err_bad_event; + } + default: + break; + } + + /* Bit depth and pic struct changed event are combined into a single + * event (insufficient event) for the userspace. Currently bitdepth + * changes is only for HEVC and interlaced support is for all + * codecs except HEVC + * event data is now as follows: + * u32 *ptr = seq_changed_event.u.data; + * ptr[0] = height + * ptr[1] = width + * ptr[2] = bit depth + * ptr[3] = pic struct (progressive or interlaced) + * ptr[4] = colour space + * ptr[5] = crop_data(top) + * ptr[6] = crop_data(left) + * ptr[7] = crop_data(height) + * ptr[8] = crop_data(width) + * ptr[9] = profile + * ptr[10] = level + */ + + inst->profile = event_notify->profile; + inst->level = event_notify->level; + inst->prop.crop_info.left = + event_notify->crop_data.left; + inst->prop.crop_info.top = + event_notify->crop_data.top; + inst->prop.crop_info.height = + event_notify->crop_data.height; + inst->prop.crop_info.width = + event_notify->crop_data.width; + /* HW returns progressive_only flag in pic_struct. */ + inst->pic_struct = + event_notify->pic_struct ? + MSM_VIDC_PIC_STRUCT_PROGRESSIVE : + MSM_VIDC_PIC_STRUCT_MAYBE_INTERLACED; + inst->colour_space = event_notify->colour_space; + + ptr = (u32 *)seq_changed_event.u.data; + ptr[0] = event_notify->height; + ptr[1] = event_notify->width; + ptr[2] = event_notify->bit_depth; + ptr[3] = event_notify->pic_struct; + ptr[4] = event_notify->colour_space; + ptr[5] = event_notify->crop_data.top; + ptr[6] = event_notify->crop_data.left; + ptr[7] = event_notify->crop_data.height; + ptr[8] = event_notify->crop_data.width; + codec = get_v4l2_codec(inst); + ptr[9] = msm_comm_get_v4l2_profile(codec, + event_notify->profile); + ptr[10] = msm_comm_get_v4l2_level(codec, + event_notify->level); + + dprintk(VIDC_DBG, + "Event payload: height = %u width = %u profile = %u level = %u\n", + event_notify->height, event_notify->width, + ptr[9], ptr[10]); + + dprintk(VIDC_DBG, + "Event payload: bit_depth = %u pic_struct = %u colour_space = %u\n", + event_notify->bit_depth, event_notify->pic_struct, + event_notify->colour_space); + + dprintk(VIDC_DBG, + "Event payload: CROP top = %u left = %u Height = %u Width = %u\n", + event_notify->crop_data.top, + event_notify->crop_data.left, + event_notify->crop_data.height, + event_notify->crop_data.width); + + mutex_lock(&inst->lock); + inst->in_reconfig = true; + inst->reconfig_height = event_notify->height; + inst->reconfig_width = event_notify->width; + inst->bit_depth = event_notify->bit_depth; + + fmt = &inst->fmts[OUTPUT_PORT]; + extra_buff_count = msm_vidc_get_extra_buff_count(inst, + HAL_BUFFER_OUTPUT); + fmt->count_min = event_notify->capture_buf_count; + fmt->count_min_host = fmt->count_min + extra_buff_count; + + dprintk(VIDC_DBG, "%s: buffer[%d] count: min %d min_host %d\n", + __func__, HAL_BUFFER_OUTPUT, fmt->count_min, + fmt->count_min_host); + + mutex_unlock(&inst->lock); + + if (event == V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT) { + dprintk(VIDC_DBG, "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT\n"); + } + + rc = msm_vidc_check_session_supported(inst); + if (!rc) { + seq_changed_event.type = event; + v4l2_event_queue_fh(&inst->event_handler, &seq_changed_event); + } else if (rc == -ENOTSUPP) { + msm_vidc_queue_v4l2_event(inst, + V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED); + } else if (rc == -EBUSY) { + msm_vidc_queue_v4l2_event(inst, + V4L2_EVENT_MSM_VIDC_HW_OVERLOAD); + } + +err_bad_event: + put_inst(inst); +} + +static void handle_session_prop_info(enum hal_command_response cmd, void *data) +{ + struct msm_vidc_cb_cmd_done *response = data; + struct getprop_buf *getprop; + struct msm_vidc_inst *inst; + + if (!response) { + dprintk(VIDC_ERR, + "Failed to get valid response for prop info\n"); + return; + } + + inst = get_inst(get_vidc_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + return; + } + + getprop = kzalloc(sizeof(*getprop), GFP_KERNEL); + if (!getprop) { + dprintk(VIDC_ERR, "%s: getprop kzalloc failed\n", __func__); + goto err_prop_info; + } + + getprop->data = kmemdup((void *) (&response->data.property), + sizeof(union hal_get_property), GFP_KERNEL); + if (!getprop->data) { + dprintk(VIDC_ERR, "%s: kmemdup failed\n", __func__); + kfree(getprop); + goto err_prop_info; + } + + mutex_lock(&inst->pending_getpropq.lock); + list_add_tail(&getprop->list, &inst->pending_getpropq.list); + mutex_unlock(&inst->pending_getpropq.lock); + + signal_session_msg_receipt(cmd, inst); +err_prop_info: + put_inst(inst); +} + +static void handle_load_resource_done(enum hal_command_response cmd, void *data) +{ + struct msm_vidc_cb_cmd_done *response = data; + struct msm_vidc_inst *inst; + + if (!response) { + dprintk(VIDC_ERR, + "Failed to get valid response for load resource\n"); + return; + } + + inst = get_inst(get_vidc_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + return; + } + + if (response->status) { + dprintk(VIDC_ERR, + "Load resource response from FW : %#x\n", + response->status); + msm_comm_generate_session_error(inst); + } + + put_inst(inst); +} + +static void handle_start_done(enum hal_command_response cmd, void *data) +{ + struct msm_vidc_cb_cmd_done *response = data; + struct msm_vidc_inst *inst; + + if (!response) { + dprintk(VIDC_ERR, "Failed to get valid response for start\n"); + return; + } + + inst = get_inst(get_vidc_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + return; + } + + signal_session_msg_receipt(cmd, inst); + put_inst(inst); +} + +static void handle_stop_done(enum hal_command_response cmd, void *data) +{ + struct msm_vidc_cb_cmd_done *response = data; + struct msm_vidc_inst *inst; + + if (!response) { + dprintk(VIDC_ERR, "Failed to get valid response for stop\n"); + return; + } + + inst = get_inst(get_vidc_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + return; + } + + signal_session_msg_receipt(cmd, inst); + put_inst(inst); +} + +static void handle_release_res_done(enum hal_command_response cmd, void *data) +{ + struct msm_vidc_cb_cmd_done *response = data; + struct msm_vidc_inst *inst; + + if (!response) { + dprintk(VIDC_ERR, + "Failed to get valid response for release resource\n"); + return; + } + + inst = get_inst(get_vidc_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + return; + } + + signal_session_msg_receipt(cmd, inst); + put_inst(inst); +} + +void msm_comm_validate_output_buffers(struct msm_vidc_inst *inst) +{ + struct internal_buf *binfo; + u32 buffers_owned_by_driver = 0; + struct msm_vidc_format *fmt; + + fmt = &inst->fmts[OUTPUT_PORT]; + + mutex_lock(&inst->outputbufs.lock); + if (list_empty(&inst->outputbufs.list)) { + dprintk(VIDC_DBG, "%s: no OUTPUT buffers allocated\n", + __func__); + mutex_unlock(&inst->outputbufs.lock); + return; + } + list_for_each_entry(binfo, &inst->outputbufs.list, list) { + if (binfo->buffer_ownership != DRIVER) { + dprintk(VIDC_DBG, + "This buffer is with FW %x\n", + binfo->smem.device_addr); + continue; + } + buffers_owned_by_driver++; + } + mutex_unlock(&inst->outputbufs.lock); + + /* Only minimum number of DPBs are allocated */ + if (buffers_owned_by_driver != fmt->count_min) { + dprintk(VIDC_WARN, + "OUTPUT Buffer count mismatch %d of %d\n", + buffers_owned_by_driver, + fmt->count_min); + msm_vidc_handle_hw_error(inst->core); + } +} + +int msm_comm_queue_dpb_only_buffers(struct msm_vidc_inst *inst) +{ + struct internal_buf *binfo, *extra_info; + struct hfi_device *hdev; + struct vidc_frame_data frame_data = {0}; + int rc = 0; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + hdev = inst->core->device; + + extra_info = inst->dpb_extra_binfo; + mutex_lock(&inst->outputbufs.lock); + list_for_each_entry(binfo, &inst->outputbufs.list, list) { + if (binfo->buffer_ownership != DRIVER) + continue; + if (binfo->mark_remove) + continue; + frame_data.alloc_len = binfo->smem.size; + frame_data.filled_len = 0; + frame_data.offset = 0; + frame_data.device_addr = binfo->smem.device_addr; + frame_data.flags = 0; + frame_data.extradata_addr = + extra_info ? extra_info->smem.device_addr : 0; + frame_data.buffer_type = HAL_BUFFER_OUTPUT; + frame_data.extradata_size = + extra_info ? extra_info->smem.size : 0; + rc = call_hfi_op(hdev, session_ftb, + (void *) inst->session, &frame_data); + binfo->buffer_ownership = FIRMWARE; + } + mutex_unlock(&inst->outputbufs.lock); + + return rc; +} + +static void handle_session_flush(enum hal_command_response cmd, void *data) +{ + struct msm_vidc_cb_cmd_done *response = data; + struct msm_vidc_inst *inst; + struct v4l2_event flush_event = {0}; + u32 *ptr = NULL; + enum hal_flush flush_type; + int rc; + + if (!response) { + dprintk(VIDC_ERR, "Failed to get valid response for flush\n"); + return; + } + + inst = get_inst(get_vidc_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + return; + } + + mutex_lock(&inst->flush_lock); + if (msm_comm_get_stream_output_mode(inst) == + HAL_VIDEO_DECODER_SECONDARY) { + + if (!(get_v4l2_codec(inst) == V4L2_PIX_FMT_VP9 && + inst->in_reconfig)) + msm_comm_validate_output_buffers(inst); + + if (!inst->in_reconfig) { + rc = msm_comm_queue_dpb_only_buffers(inst); + if (rc) { + dprintk(VIDC_ERR, + "Failed to queue output buffers: %d\n", + rc); + } + } + } + inst->in_flush = false; + flush_event.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE; + ptr = (u32 *)flush_event.u.data; + + flush_type = response->data.flush_type; + switch (flush_type) { + case HAL_FLUSH_INPUT: + ptr[0] = V4L2_CMD_FLUSH_OUTPUT; + break; + case HAL_FLUSH_OUTPUT: + ptr[0] = V4L2_CMD_FLUSH_CAPTURE; + break; + case HAL_FLUSH_ALL: + ptr[0] |= V4L2_CMD_FLUSH_CAPTURE; + ptr[0] |= V4L2_CMD_FLUSH_OUTPUT; + break; + default: + dprintk(VIDC_ERR, "Invalid flush type received!"); + goto exit; + } + + dprintk(VIDC_DBG, + "Notify flush complete, flush_type: %x\n", flush_type); + v4l2_event_queue_fh(&inst->event_handler, &flush_event); + +exit: + mutex_unlock(&inst->flush_lock); + put_inst(inst); +} + +static void handle_session_error(enum hal_command_response cmd, void *data) +{ + struct msm_vidc_cb_cmd_done *response = data; + struct hfi_device *hdev = NULL; + struct msm_vidc_inst *inst = NULL; + int event = V4L2_EVENT_MSM_VIDC_SYS_ERROR; + + if (!response) { + dprintk(VIDC_ERR, + "Failed to get valid response for session error\n"); + return; + } + + inst = get_inst(get_vidc_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + return; + } + + hdev = inst->core->device; + dprintk(VIDC_ERR, "Session error received for inst %pK session %x\n", + inst, hash32_ptr(inst->session)); + + if (response->status == VIDC_ERR_MAX_CLIENTS) { + dprintk(VIDC_WARN, "Too many clients, rejecting %pK", inst); + event = V4L2_EVENT_MSM_VIDC_MAX_CLIENTS; + + /* + * Clean the HFI session now. Since inst->state is moved to + * INVALID, forward thread doesn't know FW has valid session + * or not. This is the last place driver knows that there is + * no session in FW. Hence clean HFI session now. + */ + + msm_comm_session_clean(inst); + } else if (response->status == VIDC_ERR_NOT_SUPPORTED) { + dprintk(VIDC_WARN, "Unsupported bitstream in %pK", inst); + event = V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED; + } else { + dprintk(VIDC_WARN, "Unknown session error (%d) for %pK\n", + response->status, inst); + event = V4L2_EVENT_MSM_VIDC_SYS_ERROR; + } + + /* change state before sending error to client */ + change_inst_state(inst, MSM_VIDC_CORE_INVALID); + msm_vidc_queue_v4l2_event(inst, event); + put_inst(inst); +} + +static void msm_comm_clean_notify_client(struct msm_vidc_core *core) +{ + struct msm_vidc_inst *inst = NULL; + + if (!core) { + dprintk(VIDC_ERR, "%s: Invalid params\n", __func__); + return; + } + + dprintk(VIDC_WARN, "%s: Core %pK\n", __func__, core); + mutex_lock(&core->lock); + + list_for_each_entry(inst, &core->instances, list) { + mutex_lock(&inst->lock); + inst->state = MSM_VIDC_CORE_INVALID; + mutex_unlock(&inst->lock); + dprintk(VIDC_WARN, + "%s Send sys error for inst %pK\n", __func__, inst); + msm_vidc_queue_v4l2_event(inst, + V4L2_EVENT_MSM_VIDC_SYS_ERROR); + } + mutex_unlock(&core->lock); +} + +static void handle_sys_error(enum hal_command_response cmd, void *data) +{ + struct msm_vidc_cb_cmd_done *response = data; + struct msm_vidc_core *core = NULL; + struct hfi_device *hdev = NULL; + struct msm_vidc_inst *inst = NULL; + int rc = 0; + + subsystem_crashed("venus"); + if (!response) { + dprintk(VIDC_ERR, + "Failed to get valid response for sys error\n"); + return; + } + + core = get_vidc_core(response->device_id); + if (!core) { + dprintk(VIDC_ERR, + "Got SYS_ERR but unable to identify core\n"); + return; + } + hdev = core->device; + + mutex_lock(&core->lock); + if (core->state == VIDC_CORE_UNINIT) { + dprintk(VIDC_ERR, + "%s: Core %pK already moved to state %d\n", + __func__, core, core->state); + mutex_unlock(&core->lock); + return; + } + + dprintk(VIDC_WARN, "SYS_ERROR received for core %pK\n", core); + msm_vidc_noc_error_info(core); + call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); + list_for_each_entry(inst, &core->instances, list) { + dprintk(VIDC_WARN, + "%s: Send sys error for inst %pK\n", __func__, inst); + change_inst_state(inst, MSM_VIDC_CORE_INVALID); + msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); + if (!core->trigger_ssr) + msm_comm_print_inst_info(inst); + } + + /* handle the hw error before core released to get full debug info */ + msm_vidc_handle_hw_error(core); + if (response->status == VIDC_ERR_NOC_ERROR) { + dprintk(VIDC_WARN, "Got NOC error"); + MSM_VIDC_ERROR(true); + } + + dprintk(VIDC_DBG, "Calling core_release\n"); + rc = call_hfi_op(hdev, core_release, hdev->hfi_device_data); + if (rc) { + dprintk(VIDC_ERR, "core_release failed\n"); + mutex_unlock(&core->lock); + return; + } + core->state = VIDC_CORE_UNINIT; + mutex_unlock(&core->lock); + + dprintk(VIDC_WARN, "SYS_ERROR handled.\n"); +} + +void msm_comm_session_clean(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev = NULL; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid params\n", __func__); + return; + } + if (!inst->session) { + dprintk(VIDC_DBG, "%s: inst %pK session already cleaned\n", + __func__, inst); + return; + } + + hdev = inst->core->device; + mutex_lock(&inst->lock); + dprintk(VIDC_DBG, "%s: inst %pK\n", __func__, inst); + rc = call_hfi_op(hdev, session_clean, + (void *)inst->session); + if (rc) { + dprintk(VIDC_ERR, + "Session clean failed :%pK\n", inst); + } + inst->session = NULL; + mutex_unlock(&inst->lock); +} + +static void handle_session_close(enum hal_command_response cmd, void *data) +{ + struct msm_vidc_cb_cmd_done *response = data; + struct msm_vidc_inst *inst; + + if (!response) { + dprintk(VIDC_ERR, + "Failed to get valid response for session close\n"); + return; + } + + inst = get_inst(get_vidc_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + return; + } + + signal_session_msg_receipt(cmd, inst); + show_stats(inst); + put_inst(inst); +} + +struct vb2_buffer *msm_comm_get_vb_using_vidc_buffer( + struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) +{ + u32 port = 0; + struct vb2_buffer *vb = NULL; + struct vb2_queue *q = NULL; + bool found = false; + + if (mbuf->vvb.vb2_buf.type == OUTPUT_MPLANE) { + port = OUTPUT_PORT; + } else if (mbuf->vvb.vb2_buf.type == INPUT_MPLANE) { + port = INPUT_PORT; + } else { + dprintk(VIDC_ERR, "%s: invalid type %d\n", + __func__, mbuf->vvb.vb2_buf.type); + return NULL; + } + + mutex_lock(&inst->bufq[port].lock); + found = false; + q = &inst->bufq[port].vb2_bufq; + if (!q->streaming) { + dprintk(VIDC_ERR, "port %d is not streaming", port); + goto unlock; + } + list_for_each_entry(vb, &q->queued_list, queued_entry) { + if (vb->state != VB2_BUF_STATE_ACTIVE) + continue; + if (msm_comm_compare_vb2_planes(inst, mbuf, vb)) { + found = true; + break; + } + } +unlock: + mutex_unlock(&inst->bufq[port].lock); + if (!found) { + print_vidc_buffer(VIDC_ERR, "vb2 not found for", inst, mbuf); + return NULL; + } + + return vb; +} + +int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf) +{ + struct vb2_buffer *vb2; + struct vb2_v4l2_buffer *vbuf; + u32 i, port; + + if (!inst || !mbuf) { + dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", + __func__, inst, mbuf); + return -EINVAL; + } + + if (mbuf->vvb.vb2_buf.type == OUTPUT_MPLANE) + port = OUTPUT_PORT; + else if (mbuf->vvb.vb2_buf.type == INPUT_MPLANE) + port = INPUT_PORT; + else + return -EINVAL; + + vb2 = msm_comm_get_vb_using_vidc_buffer(inst, mbuf); + if (!vb2) + return -EINVAL; + + /* + * access vb2 buffer under q->lock and if streaming only to + * ensure the buffer was not free'd by vb2 framework while + * we are accessing it here. + */ + mutex_lock(&inst->bufq[port].lock); + if (inst->bufq[port].vb2_bufq.streaming) { + vbuf = to_vb2_v4l2_buffer(vb2); + vbuf->flags = mbuf->vvb.flags; + vb2->timestamp = mbuf->vvb.vb2_buf.timestamp; + for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) { + vb2->planes[i].bytesused = + mbuf->vvb.vb2_buf.planes[i].bytesused; + vb2->planes[i].data_offset = + mbuf->vvb.vb2_buf.planes[i].data_offset; + } + vb2_buffer_done(vb2, VB2_BUF_STATE_DONE); + } else { + dprintk(VIDC_ERR, "%s: port %d is not streaming\n", + __func__, port); + } + mutex_unlock(&inst->bufq[port].lock); + + return 0; +} + +bool heic_encode_session_supported(struct msm_vidc_inst *inst) +{ + u32 slice_mode; + u32 idr_period = IDR_PERIOD; + u32 n_bframes; + u32 n_pframes; + struct v4l2_format *f; + + slice_mode = msm_comm_g_ctrl_for_id(inst, + V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); + n_bframes = msm_comm_g_ctrl_for_id(inst, + V4L2_CID_MPEG_VIDEO_B_FRAMES); + n_pframes = msm_comm_g_ctrl_for_id(inst, + V4L2_CID_MPEG_VIDEO_GOP_SIZE); + + /* + * HEIC Encode is supported for Constant Quality RC mode only. + * All configurations below except grid_enable are required for any + * HEIC session including FWK tiled HEIC encode. + * grid_enable flag along with dimension check enables HW tiling. + */ + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + if (inst->session_type == MSM_VIDC_ENCODER && + get_hal_codec(f->fmt.pix_mp.pixelformat) == + HAL_VIDEO_CODEC_HEVC && + inst->frame_quality >= MIN_FRAME_QUALITY && + inst->frame_quality <= MAX_FRAME_QUALITY && + slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE && + idr_period == 1 && + n_bframes == 0 && + n_pframes == 0) { + if (inst->grid_enable > 0) { + if (f->fmt.pix_mp.width < HEIC_GRID_DIMENSION || + f->fmt.pix_mp.height < HEIC_GRID_DIMENSION) + return false; + } + return true; + } else { + return false; + } +} + +static bool is_eos_buffer(struct msm_vidc_inst *inst, u32 device_addr) +{ + struct eos_buf *temp, *next; + bool found = false; + + mutex_lock(&inst->eosbufs.lock); + list_for_each_entry_safe(temp, next, &inst->eosbufs.list, list) { + if (temp->smem.device_addr == device_addr) { + found = true; + list_del(&temp->list); + msm_comm_smem_free(inst, &temp->smem); + kfree(temp); + break; + } + } + mutex_unlock(&inst->eosbufs.lock); + + return found; +} + +static void handle_ebd(enum hal_command_response cmd, void *data) +{ + struct msm_vidc_cb_data_done *response = data; + struct msm_vidc_buffer *mbuf; + struct vb2_buffer *vb; + struct msm_vidc_inst *inst; + struct vidc_hal_ebd *empty_buf_done; + u32 planes[VIDEO_MAX_PLANES] = {0}; + struct v4l2_format *f; + + if (!response) { + dprintk(VIDC_ERR, "Invalid response from vidc_hal\n"); + return; + } + + inst = get_inst(get_vidc_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + return; + } + + empty_buf_done = (struct vidc_hal_ebd *)&response->input_done; + /* If this is internal EOS buffer, handle it in driver */ + if (is_eos_buffer(inst, empty_buf_done->packet_buffer)) { + dprintk(VIDC_DBG, "Received EOS buffer 0x%x\n", + empty_buf_done->packet_buffer); + goto exit; + } + + planes[0] = empty_buf_done->packet_buffer; + planes[1] = empty_buf_done->extra_data_buffer; + + mbuf = msm_comm_get_buffer_using_device_planes(inst, + INPUT_MPLANE, planes); + if (!mbuf || !kref_get_mbuf(inst, mbuf)) { + dprintk(VIDC_ERR, + "%s: data_addr %x, extradata_addr %x not found\n", + __func__, planes[0], planes[1]); + goto exit; + } + mbuf->flags &= ~MSM_VIDC_FLAG_QUEUED; + vb = &mbuf->vvb.vb2_buf; + + vb->planes[0].bytesused = response->input_done.filled_len; + if (vb->planes[0].bytesused > vb->planes[0].length) + dprintk(VIDC_INFO, "bytesused overflow length\n"); + + vb->planes[0].data_offset = response->input_done.offset; + if (vb->planes[0].data_offset > vb->planes[0].length) + dprintk(VIDC_INFO, "data_offset overflow length\n"); + + if (empty_buf_done->status == VIDC_ERR_NOT_SUPPORTED) { + dprintk(VIDC_INFO, "Failed : Unsupported input stream\n"); + mbuf->vvb.flags |= V4L2_BUF_INPUT_UNSUPPORTED; + } + if (empty_buf_done->status == VIDC_ERR_BITSTREAM_ERR) { + dprintk(VIDC_INFO, "Failed : Corrupted input stream\n"); + mbuf->vvb.flags |= V4L2_BUF_FLAG_DATA_CORRUPT; + } + if (empty_buf_done->flags & HAL_BUFFERFLAG_SYNCFRAME) + mbuf->vvb.flags |= V4L2_BUF_FLAG_KEYFRAME; + + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + if (f->fmt.pix_mp.num_planes > 1) + vb->planes[1].bytesused = vb->planes[1].length; + + update_recon_stats(inst, &empty_buf_done->recon_stats); + msm_vidc_clear_freq_entry(inst, mbuf->smem[0].device_addr); + /* + * dma cache operations need to be performed before dma_unmap + * which is done inside msm_comm_put_vidc_buffer() + */ + msm_comm_dqbuf_cache_operations(inst, mbuf); + /* + * put_buffer should be done before vb2_buffer_done else + * client might queue the same buffer before it is unmapped + * in put_buffer. + */ + msm_comm_put_vidc_buffer(inst, mbuf); + msm_comm_vb2_buffer_done(inst, mbuf); + msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_EBD); + kref_put_mbuf(mbuf); +exit: + put_inst(inst); +} + +static int handle_multi_stream_buffers(struct msm_vidc_inst *inst, + u32 dev_addr) +{ + struct internal_buf *binfo; + struct msm_smem *smem; + bool found = false; + + mutex_lock(&inst->outputbufs.lock); + list_for_each_entry(binfo, &inst->outputbufs.list, list) { + smem = &binfo->smem; + if (smem && dev_addr == smem->device_addr) { + if (binfo->buffer_ownership == DRIVER) { + dprintk(VIDC_ERR, + "FW returned same buffer: %x\n", + dev_addr); + break; + } + binfo->buffer_ownership = DRIVER; + found = true; + break; + } + } + mutex_unlock(&inst->outputbufs.lock); + + if (!found) { + dprintk(VIDC_ERR, + "Failed to find output buffer in queued list: %x\n", + dev_addr); + } + + return 0; +} + +enum hal_buffer msm_comm_get_hal_output_buffer(struct msm_vidc_inst *inst) +{ + if (msm_comm_get_stream_output_mode(inst) == + HAL_VIDEO_DECODER_SECONDARY) + return HAL_BUFFER_OUTPUT2; + else + return HAL_BUFFER_OUTPUT; +} + +static void handle_fbd(enum hal_command_response cmd, void *data) +{ + struct msm_vidc_cb_data_done *response = data; + struct msm_vidc_buffer *mbuf; + struct msm_vidc_inst *inst; + struct vb2_buffer *vb; + struct vidc_hal_fbd *fill_buf_done; + enum hal_buffer buffer_type; + u64 time_usec = 0; + u32 planes[VIDEO_MAX_PLANES] = {0}; + struct v4l2_format *f; + + if (!response) { + dprintk(VIDC_ERR, "Invalid response from vidc_hal\n"); + return; + } + + inst = get_inst(get_vidc_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + return; + } + + fill_buf_done = (struct vidc_hal_fbd *)&response->output_done; + planes[0] = fill_buf_done->packet_buffer1; + planes[1] = fill_buf_done->extra_data_buffer; + + buffer_type = msm_comm_get_hal_output_buffer(inst); + if (fill_buf_done->buffer_type == buffer_type) { + mbuf = msm_comm_get_buffer_using_device_planes(inst, + OUTPUT_MPLANE, planes); + if (!mbuf || !kref_get_mbuf(inst, mbuf)) { + dprintk(VIDC_ERR, + "%s: data_addr %x, extradata_addr %x not found\n", + __func__, planes[0], planes[1]); + goto exit; + } + } else { + if (handle_multi_stream_buffers(inst, + fill_buf_done->packet_buffer1)) + dprintk(VIDC_ERR, + "Failed : Output buffer not found %pa\n", + &fill_buf_done->packet_buffer1); + goto exit; + } + mbuf->flags &= ~MSM_VIDC_FLAG_QUEUED; + vb = &mbuf->vvb.vb2_buf; + + if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DROP_FRAME) + fill_buf_done->filled_len1 = 0; + vb->planes[0].bytesused = fill_buf_done->filled_len1; + if (vb->planes[0].bytesused > vb->planes[0].length) + dprintk(VIDC_INFO, + "fbd:Overflow bytesused = %d; length = %d\n", + vb->planes[0].bytesused, + vb->planes[0].length); + vb->planes[0].data_offset = fill_buf_done->offset1; + if (vb->planes[0].data_offset > vb->planes[0].length) + dprintk(VIDC_INFO, + "fbd:Overflow data_offset = %d; length = %d\n", + vb->planes[0].data_offset, + vb->planes[0].length); + + time_usec = fill_buf_done->timestamp_hi; + time_usec = (time_usec << 32) | fill_buf_done->timestamp_lo; + + vb->timestamp = (time_usec * NSEC_PER_USEC); + + if (inst->session_type == MSM_VIDC_DECODER) { + msm_comm_store_mark_data(&inst->fbd_data, vb->index, + fill_buf_done->mark_data, fill_buf_done->mark_target); + } + if (inst->session_type == MSM_VIDC_ENCODER) { + msm_comm_store_filled_length(&inst->fbd_data, vb->index, + fill_buf_done->filled_len1); + } + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + if (f->fmt.pix_mp.num_planes > 1) + vb->planes[1].bytesused = vb->planes[1].length; + + mbuf->vvb.flags = 0; + if (fill_buf_done->flags1 & HAL_BUFFERFLAG_READONLY) + mbuf->vvb.flags |= V4L2_BUF_FLAG_READONLY; + if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOS) + mbuf->vvb.flags |= V4L2_BUF_FLAG_EOS; + if (fill_buf_done->flags1 & HAL_BUFFERFLAG_CODECCONFIG) + mbuf->vvb.flags |= V4L2_BUF_FLAG_CODECCONFIG; + if (fill_buf_done->flags1 & HAL_BUFFERFLAG_SYNCFRAME) + mbuf->vvb.flags |= V4L2_BUF_FLAG_KEYFRAME; + if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DATACORRUPT) + mbuf->vvb.flags |= V4L2_BUF_FLAG_DATA_CORRUPT; + switch (fill_buf_done->picture_type) { + case HFI_PICTURE_TYPE_P: + mbuf->vvb.flags |= V4L2_BUF_FLAG_PFRAME; + break; + case HFI_PICTURE_TYPE_B: + mbuf->vvb.flags |= V4L2_BUF_FLAG_BFRAME; + break; + case HFI_FRAME_NOTCODED: + case HFI_UNUSED_PICT: + /* Do we need to care about these? */ + case HFI_FRAME_YUV: + break; + default: + break; + } + + /* + * dma cache operations need to be performed before dma_unmap + * which is done inside msm_comm_put_vidc_buffer() + */ + msm_comm_dqbuf_cache_operations(inst, mbuf); + /* + * put_buffer should be done before vb2_buffer_done else + * client might queue the same buffer before it is unmapped + * in put_buffer. + */ + msm_comm_put_vidc_buffer(inst, mbuf); + msm_comm_vb2_buffer_done(inst, mbuf); + msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_FBD); + kref_put_mbuf(mbuf); + +exit: + put_inst(inst); +} + +void handle_cmd_response(enum hal_command_response cmd, void *data) +{ + dprintk(VIDC_DBG, "Command response = %d\n", cmd); + switch (cmd) { + case HAL_SYS_INIT_DONE: + handle_sys_init_done(cmd, data); + break; + case HAL_SYS_RELEASE_RESOURCE_DONE: + handle_sys_release_res_done(cmd, data); + break; + case HAL_SESSION_INIT_DONE: + handle_session_init_done(cmd, data); + break; + case HAL_SESSION_PROPERTY_INFO: + handle_session_prop_info(cmd, data); + break; + case HAL_SESSION_LOAD_RESOURCE_DONE: + handle_load_resource_done(cmd, data); + break; + case HAL_SESSION_START_DONE: + handle_start_done(cmd, data); + break; + case HAL_SESSION_ETB_DONE: + handle_ebd(cmd, data); + break; + case HAL_SESSION_FTB_DONE: + handle_fbd(cmd, data); + break; + case HAL_SESSION_STOP_DONE: + handle_stop_done(cmd, data); + break; + case HAL_SESSION_RELEASE_RESOURCE_DONE: + handle_release_res_done(cmd, data); + break; + case HAL_SESSION_END_DONE: + case HAL_SESSION_ABORT_DONE: + handle_session_close(cmd, data); + break; + case HAL_SESSION_EVENT_CHANGE: + handle_event_change(cmd, data); + break; + case HAL_SESSION_FLUSH_DONE: + handle_session_flush(cmd, data); + break; + case HAL_SYS_WATCHDOG_TIMEOUT: + case HAL_SYS_ERROR: + handle_sys_error(cmd, data); + break; + case HAL_SESSION_ERROR: + handle_session_error(cmd, data); + break; + case HAL_SESSION_RELEASE_BUFFER_DONE: + handle_session_release_buf_done(cmd, data); + break; + case HAL_SESSION_REGISTER_BUFFER_DONE: + handle_session_register_buffer_done(cmd, data); + break; + case HAL_SESSION_UNREGISTER_BUFFER_DONE: + handle_session_unregister_buffer_done(cmd, data); + break; + default: + dprintk(VIDC_DBG, "response unhandled: %d\n", cmd); + break; + } +} + +static inline enum msm_vidc_thermal_level msm_comm_vidc_thermal_level(int level) +{ + switch (level) { + case 0: + return VIDC_THERMAL_NORMAL; + case 1: + return VIDC_THERMAL_LOW; + case 2: + return VIDC_THERMAL_HIGH; + default: + return VIDC_THERMAL_CRITICAL; + } +} + +static bool is_core_turbo(struct msm_vidc_core *core, unsigned long freq) +{ + unsigned int i = 0; + struct allowed_clock_rates_table *allowed_clks_tbl = NULL; + u32 max_freq = 0; + + allowed_clks_tbl = core->resources.allowed_clks_tbl; + for (i = 0; i < core->resources.allowed_clks_tbl_size; i++) { + if (max_freq < allowed_clks_tbl[i].clock_rate) + max_freq = allowed_clks_tbl[i].clock_rate; + } + return freq >= max_freq; +} + +static bool is_thermal_permissible(struct msm_vidc_core *core) +{ + enum msm_vidc_thermal_level tl; + unsigned long freq = 0; + bool is_turbo = false; + + if (!core->resources.thermal_mitigable) + return true; + + if (msm_vidc_thermal_mitigation_disabled) { + dprintk(VIDC_DBG, + "Thermal mitigation not enabled. debugfs %d\n", + msm_vidc_thermal_mitigation_disabled); + return true; + } + + tl = msm_comm_vidc_thermal_level(vidc_driver->thermal_level); + freq = core->curr_freq; + + is_turbo = is_core_turbo(core, freq); + dprintk(VIDC_DBG, + "Core freq %ld Thermal level %d Turbo mode %d\n", + freq, tl, is_turbo); + + if (is_turbo && tl >= VIDC_THERMAL_LOW) { + dprintk(VIDC_ERR, + "Video session not allowed. Turbo mode %d Thermal level %d\n", + is_turbo, tl); + return false; + } + return true; +} + +bool is_batching_allowed(struct msm_vidc_inst *inst) +{ + u32 op_pixelformat, fps, maxmbs, maxfps; + + if (!inst || !inst->core) + return false; + + /* Enable decode batching based on below conditions */ + op_pixelformat = + inst->fmts[OUTPUT_PORT].v4l2_fmt.fmt.pix_mp.pixelformat; + fps = inst->clk_data.frame_rate >> 16; + maxmbs = inst->capability.cap[CAP_BATCH_MAX_MB_PER_FRAME].max; + maxfps = inst->capability.cap[CAP_BATCH_MAX_FPS].max; + + return (inst->core->resources.decode_batching && + is_decode_session(inst) && + !is_thumbnail_session(inst) && + !inst->clk_data.low_latency_mode && + (op_pixelformat == V4L2_PIX_FMT_NV12_UBWC || + op_pixelformat == V4L2_PIX_FMT_NV12_TP10_UBWC) && + fps <= maxfps && + msm_vidc_get_mbs_per_frame(inst) <= maxmbs); +} + +static int msm_comm_session_abort(struct msm_vidc_inst *inst) +{ + int rc = 0, abort_completion = 0; + struct hfi_device *hdev; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + abort_completion = SESSION_MSG_INDEX(HAL_SESSION_ABORT_DONE); + + dprintk(VIDC_WARN, "%s: inst %pK session %x\n", __func__, + inst, hash32_ptr(inst->session)); + rc = call_hfi_op(hdev, session_abort, (void *)inst->session); + if (rc) { + dprintk(VIDC_ERR, + "%s session_abort failed rc: %d\n", __func__, rc); + goto exit; + } + rc = wait_for_completion_timeout( + &inst->completions[abort_completion], + msecs_to_jiffies( + inst->core->resources.msm_vidc_hw_rsp_timeout)); + if (!rc) { + dprintk(VIDC_ERR, "%s: inst %pK session %x abort timed out\n", + __func__, inst, hash32_ptr(inst->session)); + msm_comm_generate_sys_error(inst); + rc = -EBUSY; + } else { + rc = 0; + } +exit: + return rc; +} + +static void handle_thermal_event(struct msm_vidc_core *core) +{ + int rc = 0; + struct msm_vidc_inst *inst; + + if (!core || !core->device) { + dprintk(VIDC_ERR, "%s Invalid params\n", __func__); + return; + } + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) { + if (!inst->session) + continue; + + mutex_unlock(&core->lock); + if (inst->state >= MSM_VIDC_OPEN_DONE && + inst->state < MSM_VIDC_CLOSE_DONE) { + dprintk(VIDC_WARN, "%s: abort inst %pK\n", + __func__, inst); + rc = msm_comm_session_abort(inst); + if (rc) { + dprintk(VIDC_ERR, + "%s session_abort failed rc: %d\n", + __func__, rc); + goto err_sess_abort; + } + change_inst_state(inst, MSM_VIDC_CORE_INVALID); + dprintk(VIDC_WARN, + "%s Send sys error for inst %pK\n", + __func__, inst); + msm_vidc_queue_v4l2_event(inst, + V4L2_EVENT_MSM_VIDC_SYS_ERROR); + } else { + msm_comm_generate_session_error(inst); + } + mutex_lock(&core->lock); + } + mutex_unlock(&core->lock); + return; + +err_sess_abort: + msm_comm_clean_notify_client(core); +} + +void msm_comm_handle_thermal_event(void) +{ + struct msm_vidc_core *core; + + list_for_each_entry(core, &vidc_driver->cores, list) { + if (!is_thermal_permissible(core)) { + dprintk(VIDC_WARN, + "Thermal level critical, stop all active sessions!\n"); + handle_thermal_event(core); + } + } +} + +int msm_comm_check_core_init(struct msm_vidc_core *core) +{ + int rc = 0; + + mutex_lock(&core->lock); + if (core->state >= VIDC_CORE_INIT_DONE) { + dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n", + core->id, core->state); + goto exit; + } + dprintk(VIDC_DBG, "Waiting for SYS_INIT_DONE\n"); + rc = wait_for_completion_timeout( + &core->completions[SYS_MSG_INDEX(HAL_SYS_INIT_DONE)], + msecs_to_jiffies(core->resources.msm_vidc_hw_rsp_timeout)); + if (!rc) { + dprintk(VIDC_ERR, "%s: Wait interrupted or timed out: %d\n", + __func__, SYS_MSG_INDEX(HAL_SYS_INIT_DONE)); + rc = -EIO; + goto exit; + } else { + core->state = VIDC_CORE_INIT_DONE; + rc = 0; + } + dprintk(VIDC_DBG, "SYS_INIT_DONE!!!\n"); +exit: + mutex_unlock(&core->lock); + return rc; +} + +static int msm_comm_init_core_done(struct msm_vidc_inst *inst) +{ + int rc = 0; + + rc = msm_comm_check_core_init(inst->core); + if (rc) { + dprintk(VIDC_ERR, "%s - failed to initialize core\n", __func__); + msm_comm_generate_sys_error(inst); + return rc; + } + change_inst_state(inst, MSM_VIDC_CORE_INIT_DONE); + return rc; +} + +static int msm_comm_init_core(struct msm_vidc_inst *inst) +{ + int rc, i; + struct hfi_device *hdev; + struct msm_vidc_core *core; + + if (!inst || !inst->core || !inst->core->device) + return -EINVAL; + + core = inst->core; + hdev = core->device; + mutex_lock(&core->lock); + if (core->state >= VIDC_CORE_INIT) { + dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n", + core->id, core->state); + goto core_already_inited; + } + dprintk(VIDC_DBG, "%s: core %pK\n", __func__, core); + rc = call_hfi_op(hdev, core_init, hdev->hfi_device_data); + if (rc) { + dprintk(VIDC_ERR, "Failed to init core, id = %d\n", + core->id); + goto fail_core_init; + } + + /* initialize core while firmware processing SYS_INIT cmd */ + core->state = VIDC_CORE_INIT; + core->smmu_fault_handled = false; + core->trigger_ssr = false; + core->resources.max_inst_count = MAX_SUPPORTED_INSTANCES; + core->resources.max_secure_inst_count = + core->resources.max_secure_inst_count ? + core->resources.max_secure_inst_count : + core->resources.max_inst_count; + dprintk(VIDC_DBG, "%s: codecs count %d, max inst count %d\n", + __func__, core->resources.codecs_count, + core->resources.max_inst_count); + if (!core->resources.codecs || !core->resources.codecs_count) { + dprintk(VIDC_ERR, "%s: invalid codecs\n", __func__); + rc = -EINVAL; + goto fail_core_init; + } + if (!core->capabilities) { + core->capabilities = kcalloc(core->resources.codecs_count, + sizeof(struct msm_vidc_capability), GFP_KERNEL); + if (!core->capabilities) { + dprintk(VIDC_ERR, + "%s: failed to allocate capabilities\n", + __func__); + rc = -ENOMEM; + goto fail_core_init; + } + } else { + dprintk(VIDC_WARN, + "%s: capabilities memory is expected to be freed\n", + __func__); + } + for (i = 0; i < core->resources.codecs_count; i++) { + core->capabilities[i].domain = + core->resources.codecs[i].domain; + core->capabilities[i].codec = + core->resources.codecs[i].codec; + } + rc = msm_vidc_capabilities(core); + if (rc) { + dprintk(VIDC_ERR, + "%s: default capabilities failed\n", __func__); + kfree(core->capabilities); + core->capabilities = NULL; + goto fail_core_init; + } + dprintk(VIDC_DBG, "%s: done\n", __func__); +core_already_inited: + change_inst_state(inst, MSM_VIDC_CORE_INIT); + mutex_unlock(&core->lock); + + rc = msm_comm_scale_clocks_and_bus(inst); + return rc; + +fail_core_init: + core->state = VIDC_CORE_UNINIT; + mutex_unlock(&core->lock); + return rc; +} + +static int msm_vidc_deinit_core(struct msm_vidc_inst *inst) +{ + struct msm_vidc_core *core; + struct hfi_device *hdev; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + core = inst->core; + hdev = core->device; + + mutex_lock(&core->lock); + if (core->state == VIDC_CORE_UNINIT) { + dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n", + core->id, core->state); + goto core_already_uninited; + } + mutex_unlock(&core->lock); + + msm_comm_scale_clocks_and_bus(inst); + + mutex_lock(&core->lock); + + if (!core->resources.never_unload_fw) { + cancel_delayed_work(&core->fw_unload_work); + + /* + * Delay unloading of firmware. This is useful + * in avoiding firmware download delays in cases where we + * will have a burst of back to back video playback sessions + * e.g. thumbnail generation. + */ + schedule_delayed_work(&core->fw_unload_work, + msecs_to_jiffies(core->state == VIDC_CORE_INIT_DONE ? + core->resources.msm_vidc_firmware_unload_delay : 0)); + + dprintk(VIDC_DBG, "firmware unload delayed by %u ms\n", + core->state == VIDC_CORE_INIT_DONE ? + core->resources.msm_vidc_firmware_unload_delay : 0); + } + +core_already_uninited: + change_inst_state(inst, MSM_VIDC_CORE_UNINIT); + mutex_unlock(&core->lock); + return 0; +} + +int msm_comm_force_cleanup(struct msm_vidc_inst *inst) +{ + msm_comm_kill_session(inst); + return msm_vidc_deinit_core(inst); +} + +static int msm_comm_session_init_done(int flipped_state, + struct msm_vidc_inst *inst) +{ + int rc; + + dprintk(VIDC_DBG, "inst %pK: waiting for session init done\n", inst); + rc = wait_for_state(inst, flipped_state, MSM_VIDC_OPEN_DONE, + HAL_SESSION_INIT_DONE); + if (rc) { + dprintk(VIDC_ERR, "Session init failed for inst %pK\n", inst); + msm_comm_generate_sys_error(inst); + return rc; + } + + return rc; +} + +static int msm_comm_session_init(int flipped_state, + struct msm_vidc_inst *inst) +{ + int rc = 0; + int fourcc = 0; + struct hfi_device *hdev; + struct v4l2_format *f; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_OPEN)) { + dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", + inst, inst->state); + goto exit; + } + if (inst->session_type == MSM_VIDC_DECODER) { + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + fourcc = f->fmt.pix_mp.pixelformat; + } else if (inst->session_type == MSM_VIDC_ENCODER) { + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + fourcc = f->fmt.pix_mp.pixelformat; + } else if (inst->session_type == MSM_VIDC_CVP) { + fourcc = V4L2_PIX_FMT_CVP; + } else { + dprintk(VIDC_ERR, "Invalid session\n"); + return -EINVAL; + } + + rc = msm_comm_init_clocks_and_bus_data(inst); + if (rc) { + dprintk(VIDC_ERR, "Failed to initialize clocks and bus data\n"); + goto exit; + } + + dprintk(VIDC_DBG, "%s: inst %pK\n", __func__, inst); + rc = call_hfi_op(hdev, session_init, hdev->hfi_device_data, + inst, get_hal_domain(inst->session_type), + get_hal_codec(fourcc), + &inst->session); + + if (rc || !inst->session) { + dprintk(VIDC_ERR, + "Failed to call session init for: %pK, %pK, %d, %d\n", + inst->core->device, inst, + inst->session_type, fourcc); + rc = -EINVAL; + goto exit; + } + + rc = msm_vidc_init_buffer_count(inst); + if (rc) { + dprintk(VIDC_ERR, "Failed to initialize buff counts\n"); + goto exit; + } + change_inst_state(inst, MSM_VIDC_OPEN); + +exit: + return rc; +} + +static void msm_vidc_print_running_insts(struct msm_vidc_core *core) +{ + struct msm_vidc_inst *temp; + int op_rate = 0; + struct v4l2_format *out_f; + struct v4l2_format *inp_f; + + dprintk(VIDC_ERR, "Running instances:\n"); + dprintk(VIDC_ERR, "%4s|%4s|%4s|%4s|%4s|%4s\n", + "type", "w", "h", "fps", "opr", "prop"); + + mutex_lock(&core->lock); + list_for_each_entry(temp, &core->instances, list) { + out_f = &temp->fmts[OUTPUT_PORT].v4l2_fmt; + inp_f = &temp->fmts[INPUT_PORT].v4l2_fmt; + if (temp->state >= MSM_VIDC_OPEN_DONE && + temp->state < MSM_VIDC_STOP_DONE) { + char properties[4] = ""; + + if (is_thumbnail_session(temp)) + strlcat(properties, "N", sizeof(properties)); + + if (is_turbo_session(temp)) + strlcat(properties, "T", sizeof(properties)); + + if (is_realtime_session(temp)) + strlcat(properties, "R", sizeof(properties)); + + if (temp->clk_data.operating_rate) + op_rate = temp->clk_data.operating_rate >> 16; + else + op_rate = temp->clk_data.frame_rate >> 16; + + dprintk(VIDC_ERR, "%4d|%4d|%4d|%4d|%4d|%4s\n", + temp->session_type, + max(out_f->fmt.pix_mp.width, + inp_f->fmt.pix_mp.width), + max(out_f->fmt.pix_mp.height, + inp_f->fmt.pix_mp.height), + temp->clk_data.frame_rate >> 16, + op_rate, properties); + } + } + mutex_unlock(&core->lock); +} + +static int msm_vidc_load_resources(int flipped_state, + struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + int num_mbs_per_sec = 0, max_load_adj = 0; + struct msm_vidc_core *core; + enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD | + LOAD_CALC_IGNORE_THUMBNAIL_LOAD | + LOAD_CALC_IGNORE_NON_REALTIME_LOAD; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + if (inst->state == MSM_VIDC_CORE_INVALID) { + dprintk(VIDC_ERR, + "%s: inst %pK is in invalid state\n", __func__, inst); + return -EINVAL; + } + if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_LOAD_RESOURCES)) { + dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", + inst, inst->state); + goto exit; + } + core = inst->core; + + num_mbs_per_sec = + msm_comm_get_load(core, MSM_VIDC_DECODER, quirks) + + msm_comm_get_load(core, MSM_VIDC_ENCODER, quirks); + + max_load_adj = core->resources.max_load + + inst->capability.cap[CAP_MBS_PER_FRAME].max; + + if (num_mbs_per_sec > max_load_adj) { + dprintk(VIDC_ERR, "HW is overloaded, needed: %d max: %d\n", + num_mbs_per_sec, max_load_adj); + msm_vidc_print_running_insts(core); + msm_comm_kill_session(inst); + return -EBUSY; + } + + hdev = core->device; + dprintk(VIDC_DBG, "%s: inst %pK\n", __func__, inst); + rc = call_hfi_op(hdev, session_load_res, (void *) inst->session); + if (rc) { + dprintk(VIDC_ERR, + "Failed to send load resources\n"); + goto exit; + } + change_inst_state(inst, MSM_VIDC_LOAD_RESOURCES); +exit: + return rc; +} + +static int msm_vidc_start(int flipped_state, struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + if (inst->state == MSM_VIDC_CORE_INVALID) { + dprintk(VIDC_ERR, + "%s: inst %pK is in invalid\n", __func__, inst); + return -EINVAL; + } + if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_START)) { + dprintk(VIDC_INFO, + "inst: %pK is already in state: %d\n", + inst, inst->state); + goto exit; + } + hdev = inst->core->device; + dprintk(VIDC_DBG, "%s: inst %pK\n", __func__, inst); + rc = call_hfi_op(hdev, session_start, (void *) inst->session); + if (rc) { + dprintk(VIDC_ERR, + "Failed to send start\n"); + goto exit; + } + change_inst_state(inst, MSM_VIDC_START); +exit: + return rc; +} + +static int msm_vidc_stop(int flipped_state, struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + if (inst->state == MSM_VIDC_CORE_INVALID) { + dprintk(VIDC_ERR, + "%s: inst %pK is in invalid state\n", __func__, inst); + return -EINVAL; + } + if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_STOP)) { + dprintk(VIDC_INFO, + "inst: %pK is already in state: %d\n", + inst, inst->state); + goto exit; + } + hdev = inst->core->device; + dprintk(VIDC_DBG, "%s: inst %pK\n", __func__, inst); + rc = call_hfi_op(hdev, session_stop, (void *) inst->session); + if (rc) { + dprintk(VIDC_ERR, "%s: inst %pK session_stop failed\n", + __func__, inst); + goto exit; + } + change_inst_state(inst, MSM_VIDC_STOP); +exit: + return rc; +} + +static int msm_vidc_release_res(int flipped_state, struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + if (inst->state == MSM_VIDC_CORE_INVALID) { + dprintk(VIDC_ERR, + "%s: inst %pK is in invalid state\n", __func__, inst); + return -EINVAL; + } + if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_RELEASE_RESOURCES)) { + dprintk(VIDC_INFO, + "inst: %pK is already in state: %d\n", + inst, inst->state); + goto exit; + } + hdev = inst->core->device; + dprintk(VIDC_DBG, "%s: inst %pK\n", __func__, inst); + rc = call_hfi_op(hdev, session_release_res, (void *) inst->session); + if (rc) { + dprintk(VIDC_ERR, + "Failed to send release resources\n"); + goto exit; + } + change_inst_state(inst, MSM_VIDC_RELEASE_RESOURCES); +exit: + return rc; +} + +static int msm_comm_session_close(int flipped_state, + struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid params\n", __func__); + return -EINVAL; + } + if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_CLOSE)) { + dprintk(VIDC_INFO, + "inst: %pK is already in state: %d\n", + inst, inst->state); + goto exit; + } + hdev = inst->core->device; + dprintk(VIDC_DBG, "%s: inst %pK\n", __func__, inst); + rc = call_hfi_op(hdev, session_end, (void *) inst->session); + if (rc) { + dprintk(VIDC_ERR, + "Failed to send close\n"); + goto exit; + } + change_inst_state(inst, MSM_VIDC_CLOSE); +exit: + return rc; +} + +int msm_comm_suspend(int core_id) +{ + struct hfi_device *hdev; + struct msm_vidc_core *core; + int rc = 0; + + core = get_vidc_core(core_id); + if (!core) { + dprintk(VIDC_ERR, + "%s: Failed to find core for core_id = %d\n", + __func__, core_id); + return -EINVAL; + } + + hdev = (struct hfi_device *)core->device; + if (!hdev) { + dprintk(VIDC_ERR, "%s Invalid device handle\n", __func__); + return -EINVAL; + } + + rc = call_hfi_op(hdev, suspend, hdev->hfi_device_data); + if (rc) + dprintk(VIDC_WARN, "Failed to suspend\n"); + + return rc; +} + +static int get_flipped_state(int present_state, + int desired_state) +{ + int flipped_state = present_state; + + if (flipped_state < MSM_VIDC_STOP + && desired_state > MSM_VIDC_STOP) { + flipped_state = MSM_VIDC_STOP + (MSM_VIDC_STOP - flipped_state); + flipped_state &= 0xFFFE; + flipped_state = flipped_state - 1; + } else if (flipped_state > MSM_VIDC_STOP + && desired_state < MSM_VIDC_STOP) { + flipped_state = MSM_VIDC_STOP - + (flipped_state - MSM_VIDC_STOP + 1); + flipped_state &= 0xFFFE; + flipped_state = flipped_state - 1; + } + return flipped_state; +} + +struct hal_buffer_requirements *get_buff_req_buffer( + struct msm_vidc_inst *inst, enum hal_buffer buffer_type) +{ + int i; + + for (i = 0; i < HAL_BUFFER_MAX; i++) { + if (inst->buff_req.buffer[i].buffer_type == buffer_type) + return &inst->buff_req.buffer[i]; + } + dprintk(VIDC_ERR, "Failed to get buff req for : %x", buffer_type); + return NULL; +} + +u32 msm_comm_convert_color_fmt(u32 v4l2_fmt) +{ + switch (v4l2_fmt) { + case V4L2_PIX_FMT_NV12: + return COLOR_FMT_NV12; + case V4L2_PIX_FMT_NV12_512: + return COLOR_FMT_NV12_512; + case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS: + return COLOR_FMT_P010; + case V4L2_PIX_FMT_NV12_UBWC: + return COLOR_FMT_NV12_UBWC; + case V4L2_PIX_FMT_NV12_TP10_UBWC: + return COLOR_FMT_NV12_BPP10_UBWC; + default: + dprintk(VIDC_WARN, + "Invalid v4l2 color fmt FMT : %x, Set default(NV12)", + v4l2_fmt); + return COLOR_FMT_NV12; + } +} + +static u32 get_hfi_buffer(int hal_buffer) +{ + u32 buffer; + + switch (hal_buffer) { + case HAL_BUFFER_INPUT: + buffer = HFI_BUFFER_INPUT; + break; + case HAL_BUFFER_OUTPUT: + buffer = HFI_BUFFER_OUTPUT; + break; + case HAL_BUFFER_OUTPUT2: + buffer = HFI_BUFFER_OUTPUT2; + break; + case HAL_BUFFER_EXTRADATA_INPUT: + buffer = HFI_BUFFER_EXTRADATA_INPUT; + break; + case HAL_BUFFER_EXTRADATA_OUTPUT: + buffer = HFI_BUFFER_EXTRADATA_OUTPUT; + break; + case HAL_BUFFER_EXTRADATA_OUTPUT2: + buffer = HFI_BUFFER_EXTRADATA_OUTPUT2; + break; + case HAL_BUFFER_INTERNAL_SCRATCH: + buffer = HFI_BUFFER_COMMON_INTERNAL_SCRATCH; + break; + case HAL_BUFFER_INTERNAL_SCRATCH_1: + buffer = HFI_BUFFER_COMMON_INTERNAL_SCRATCH_1; + break; + case HAL_BUFFER_INTERNAL_SCRATCH_2: + buffer = HFI_BUFFER_COMMON_INTERNAL_SCRATCH_2; + break; + case HAL_BUFFER_INTERNAL_PERSIST: + buffer = HFI_BUFFER_INTERNAL_PERSIST; + break; + case HAL_BUFFER_INTERNAL_PERSIST_1: + buffer = HFI_BUFFER_INTERNAL_PERSIST_1; + break; + default: + dprintk(VIDC_ERR, "Invalid buffer: %#x\n", + hal_buffer); + buffer = 0; + break; + } + return buffer; +} + +static int set_dpb_only_buffers(struct msm_vidc_inst *inst, + enum hal_buffer buffer_type) +{ + int rc = 0; + struct internal_buf *binfo = NULL; + u32 smem_flags = SMEM_UNCACHED, buffer_size, num_buffers, hfi_fmt; + struct msm_vidc_format *fmt; + unsigned int i; + struct hfi_device *hdev; + struct hfi_buffer_size_minimum b; + struct v4l2_format *f; + + hdev = inst->core->device; + + fmt = &inst->fmts[OUTPUT_PORT]; + + /* For DPB buffers, Always use min count */ + num_buffers = fmt->count_min; + hfi_fmt = msm_comm_convert_color_fmt(inst->clk_data.dpb_fourcc); + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + buffer_size = VENUS_BUFFER_SIZE(hfi_fmt, f->fmt.pix_mp.width, + f->fmt.pix_mp.height); + dprintk(VIDC_DBG, + "output: num = %d, size = %d\n", + num_buffers, + buffer_size); + + b.buffer_type = get_hfi_buffer(buffer_type); + if (!b.buffer_type) + return -EINVAL; + b.buffer_size = buffer_size; + rc = call_hfi_op(hdev, session_set_property, + inst->session, HFI_PROPERTY_PARAM_BUFFER_SIZE_MINIMUM, + &b, sizeof(b)); + + if (f->fmt.pix_mp.num_planes == 1 || + !f->fmt.pix_mp.plane_fmt[1].sizeimage) { + dprintk(VIDC_DBG, + "This extradata buffer not required, buffer_type: %x\n", + buffer_type); + } else { + dprintk(VIDC_DBG, + "extradata: num = 1, size = %d\n", + f->fmt.pix_mp.plane_fmt[1].sizeimage); + inst->dpb_extra_binfo = NULL; + inst->dpb_extra_binfo = kzalloc(sizeof(*binfo), GFP_KERNEL); + if (!inst->dpb_extra_binfo) { + dprintk(VIDC_ERR, "Out of memory\n"); + rc = -ENOMEM; + goto fail_kzalloc; + } + rc = msm_comm_smem_alloc(inst, + f->fmt.pix_mp.plane_fmt[1].sizeimage, 1, smem_flags, + buffer_type, 0, &inst->dpb_extra_binfo->smem); + if (rc) { + dprintk(VIDC_ERR, + "Failed to allocate output memory\n"); + goto err_no_mem; + } + } + + if (inst->flags & VIDC_SECURE) + smem_flags |= SMEM_SECURE; + + if (buffer_size) { + for (i = 0; i < num_buffers; i++) { + binfo = kzalloc(sizeof(*binfo), GFP_KERNEL); + if (!binfo) { + dprintk(VIDC_ERR, "Out of memory\n"); + rc = -ENOMEM; + goto fail_kzalloc; + } + rc = msm_comm_smem_alloc(inst, + buffer_size, 1, smem_flags, + buffer_type, 0, &binfo->smem); + if (rc) { + dprintk(VIDC_ERR, + "Failed to allocate output memory\n"); + goto err_no_mem; + } + binfo->buffer_type = buffer_type; + binfo->buffer_ownership = DRIVER; + dprintk(VIDC_DBG, "Output buffer address: %#x\n", + binfo->smem.device_addr); + + if (inst->buffer_mode_set[OUTPUT_PORT] == + HAL_BUFFER_MODE_STATIC) { + struct vidc_buffer_addr_info buffer_info = {0}; + + buffer_info.buffer_size = buffer_size; + buffer_info.buffer_type = buffer_type; + buffer_info.num_buffers = 1; + buffer_info.align_device_addr = + binfo->smem.device_addr; + buffer_info.extradata_addr = + inst->dpb_extra_binfo->smem.device_addr; + buffer_info.extradata_size = + inst->dpb_extra_binfo->smem.size; + rc = call_hfi_op(hdev, session_set_buffers, + (void *) inst->session, &buffer_info); + if (rc) { + dprintk(VIDC_ERR, + "%s : session_set_buffers failed\n", + __func__); + goto fail_set_buffers; + } + } + mutex_lock(&inst->outputbufs.lock); + list_add_tail(&binfo->list, &inst->outputbufs.list); + mutex_unlock(&inst->outputbufs.lock); + } + } + return rc; +fail_set_buffers: + msm_comm_smem_free(inst, &binfo->smem); +err_no_mem: + kfree(binfo); +fail_kzalloc: + return rc; +} + +static inline char *get_buffer_name(enum hal_buffer buffer_type) +{ + switch (buffer_type) { + case HAL_BUFFER_INPUT: return "input"; + case HAL_BUFFER_OUTPUT: return "output"; + case HAL_BUFFER_OUTPUT2: return "output_2"; + case HAL_BUFFER_EXTRADATA_INPUT: return "input_extra"; + case HAL_BUFFER_EXTRADATA_OUTPUT: return "output_extra"; + case HAL_BUFFER_EXTRADATA_OUTPUT2: return "output2_extra"; + case HAL_BUFFER_INTERNAL_SCRATCH: return "scratch"; + case HAL_BUFFER_INTERNAL_SCRATCH_1: return "scratch_1"; + case HAL_BUFFER_INTERNAL_SCRATCH_2: return "scratch_2"; + case HAL_BUFFER_INTERNAL_PERSIST: return "persist"; + case HAL_BUFFER_INTERNAL_PERSIST_1: return "persist_1"; + case HAL_BUFFER_INTERNAL_CMD_QUEUE: return "queue"; + default: return "????"; + } +} + +static int set_internal_buf_on_fw(struct msm_vidc_inst *inst, + enum hal_buffer buffer_type, + struct msm_smem *handle, bool reuse) +{ + struct vidc_buffer_addr_info buffer_info; + struct hfi_device *hdev; + int rc = 0; + + if (!inst || !inst->core || !inst->core->device || !handle) { + dprintk(VIDC_ERR, "%s - invalid params\n", __func__); + return -EINVAL; + } + + hdev = inst->core->device; + + buffer_info.buffer_size = handle->size; + buffer_info.buffer_type = buffer_type; + buffer_info.num_buffers = 1; + buffer_info.align_device_addr = handle->device_addr; + dprintk(VIDC_DBG, "%s %s buffer : %x\n", + reuse ? "Reusing" : "Allocated", + get_buffer_name(buffer_type), + buffer_info.align_device_addr); + + rc = call_hfi_op(hdev, session_set_buffers, + (void *) inst->session, &buffer_info); + if (rc) { + dprintk(VIDC_ERR, + "vidc_hal_session_set_buffers failed\n"); + return rc; + } + return 0; +} + +static bool reuse_internal_buffers(struct msm_vidc_inst *inst, + enum hal_buffer buffer_type, struct msm_vidc_list *buf_list) +{ + struct internal_buf *buf; + int rc = 0; + bool reused = false; + + if (!inst || !buf_list) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return false; + } + + mutex_lock(&buf_list->lock); + list_for_each_entry(buf, &buf_list->list, list) { + if (buf->buffer_type != buffer_type) + continue; + + /* + * Persist buffer size won't change with resolution. If they + * are in queue means that they are already allocated and + * given to HW. HW can use them without reallocation. These + * buffers are not released as part of port reconfig. So + * driver no need to set them again. + */ + + if (buffer_type != HAL_BUFFER_INTERNAL_PERSIST + && buffer_type != HAL_BUFFER_INTERNAL_PERSIST_1) { + + rc = set_internal_buf_on_fw(inst, buffer_type, + &buf->smem, true); + if (rc) { + dprintk(VIDC_ERR, + "%s: session_set_buffers failed\n", + __func__); + reused = false; + break; + } + } + reused = true; + dprintk(VIDC_DBG, + "Re-using internal buffer type : %d\n", buffer_type); + } + mutex_unlock(&buf_list->lock); + return reused; +} + +static int allocate_and_set_internal_bufs(struct msm_vidc_inst *inst, + struct hal_buffer_requirements *internal_bufreq, + struct msm_vidc_list *buf_list) +{ + struct internal_buf *binfo; + u32 smem_flags = SMEM_UNCACHED; + int rc = 0; + unsigned int i = 0; + + if (!inst || !internal_bufreq || !buf_list) + return -EINVAL; + + if (!internal_bufreq->buffer_size) + return 0; + + if (inst->flags & VIDC_SECURE) + smem_flags |= SMEM_SECURE; + + for (i = 0; i < internal_bufreq->buffer_count_actual; i++) { + binfo = kzalloc(sizeof(*binfo), GFP_KERNEL); + if (!binfo) { + dprintk(VIDC_ERR, "Out of memory\n"); + rc = -ENOMEM; + goto fail_kzalloc; + } + rc = msm_comm_smem_alloc(inst, internal_bufreq->buffer_size, + 1, smem_flags, internal_bufreq->buffer_type, + 0, &binfo->smem); + if (rc) { + dprintk(VIDC_ERR, + "Failed to allocate scratch memory\n"); + goto err_no_mem; + } + + binfo->buffer_type = internal_bufreq->buffer_type; + + rc = set_internal_buf_on_fw(inst, internal_bufreq->buffer_type, + &binfo->smem, false); + if (rc) + goto fail_set_buffers; + + mutex_lock(&buf_list->lock); + list_add_tail(&binfo->list, &buf_list->list); + mutex_unlock(&buf_list->lock); + } + return rc; + +fail_set_buffers: + msm_comm_smem_free(inst, &binfo->smem); +err_no_mem: + kfree(binfo); +fail_kzalloc: + return rc; + +} + +static int set_internal_buffers(struct msm_vidc_inst *inst, + enum hal_buffer buffer_type, struct msm_vidc_list *buf_list) +{ + struct hal_buffer_requirements *internal_buf; + + internal_buf = get_buff_req_buffer(inst, buffer_type); + if (!internal_buf) { + dprintk(VIDC_DBG, + "This internal buffer not required, buffer_type: %x\n", + buffer_type); + return 0; + } + + dprintk(VIDC_DBG, "Buffer type %s: num = %d, size = %d\n", + get_buffer_name(buffer_type), + internal_buf->buffer_count_actual, internal_buf->buffer_size); + + /* + * Try reusing existing internal buffers first. + * If it's not possible to reuse, allocate new buffers. + */ + if (reuse_internal_buffers(inst, buffer_type, buf_list)) + return 0; + + return allocate_and_set_internal_bufs(inst, internal_buf, + buf_list); +} + +int msm_comm_try_state(struct msm_vidc_inst *inst, int state) +{ + int rc = 0; + int flipped_state; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params %pK", __func__, inst); + return -EINVAL; + } + dprintk(VIDC_DBG, + "Trying to move inst: %pK (%#x) from: %#x to %#x\n", + inst, hash32_ptr(inst->session), inst->state, state); + + mutex_lock(&inst->sync_lock); + if (inst->state == MSM_VIDC_CORE_INVALID) { + dprintk(VIDC_ERR, "%s: inst %pK is in invalid\n", + __func__, inst); + rc = -EINVAL; + goto exit; + } + + flipped_state = get_flipped_state(inst->state, state); + dprintk(VIDC_DBG, + "inst: %pK (%#x) flipped_state = %#x\n", + inst, hash32_ptr(inst->session), flipped_state); + switch (flipped_state) { + case MSM_VIDC_CORE_UNINIT_DONE: + case MSM_VIDC_CORE_INIT: + rc = msm_comm_init_core(inst); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + case MSM_VIDC_CORE_INIT_DONE: + rc = msm_comm_init_core_done(inst); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + case MSM_VIDC_OPEN: + rc = msm_comm_session_init(flipped_state, inst); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + case MSM_VIDC_OPEN_DONE: + rc = msm_comm_session_init_done(flipped_state, inst); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + case MSM_VIDC_LOAD_RESOURCES: + rc = msm_vidc_load_resources(flipped_state, inst); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + case MSM_VIDC_LOAD_RESOURCES_DONE: + case MSM_VIDC_START: + rc = msm_vidc_start(flipped_state, inst); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + case MSM_VIDC_START_DONE: + rc = wait_for_state(inst, flipped_state, MSM_VIDC_START_DONE, + HAL_SESSION_START_DONE); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + case MSM_VIDC_STOP: + rc = msm_vidc_stop(flipped_state, inst); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + case MSM_VIDC_STOP_DONE: + rc = wait_for_state(inst, flipped_state, MSM_VIDC_STOP_DONE, + HAL_SESSION_STOP_DONE); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + dprintk(VIDC_DBG, "Moving to Stop Done state\n"); + case MSM_VIDC_RELEASE_RESOURCES: + rc = msm_vidc_release_res(flipped_state, inst); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + case MSM_VIDC_RELEASE_RESOURCES_DONE: + rc = wait_for_state(inst, flipped_state, + MSM_VIDC_RELEASE_RESOURCES_DONE, + HAL_SESSION_RELEASE_RESOURCE_DONE); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + dprintk(VIDC_DBG, + "Moving to release resources done state\n"); + case MSM_VIDC_CLOSE: + rc = msm_comm_session_close(flipped_state, inst); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + case MSM_VIDC_CLOSE_DONE: + rc = wait_for_state(inst, flipped_state, MSM_VIDC_CLOSE_DONE, + HAL_SESSION_END_DONE); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + msm_comm_session_clean(inst); + case MSM_VIDC_CORE_UNINIT: + case MSM_VIDC_CORE_INVALID: + dprintk(VIDC_DBG, "Sending core uninit\n"); + rc = msm_vidc_deinit_core(inst); + if (rc || state == get_flipped_state(inst->state, state)) + break; + default: + dprintk(VIDC_ERR, "State not recognized\n"); + rc = -EINVAL; + break; + } + +exit: + mutex_unlock(&inst->sync_lock); + + if (rc) { + dprintk(VIDC_ERR, + "Failed to move from state: %d to %d\n", + inst->state, state); + msm_comm_kill_session(inst); + } else { + trace_msm_vidc_common_state_change((void *)inst, + inst->state, state); + } + return rc; +} + +int msm_vidc_send_pending_eos_buffers(struct msm_vidc_inst *inst) +{ + struct vidc_frame_data data = {0}; + struct hfi_device *hdev; + struct eos_buf *binfo = NULL, *temp = NULL; + int rc = 0; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + return -EINVAL; + } + + mutex_lock(&inst->eosbufs.lock); + list_for_each_entry_safe(binfo, temp, &inst->eosbufs.list, list) { + data.alloc_len = binfo->smem.size; + data.device_addr = binfo->smem.device_addr; + data.clnt_data = data.device_addr; + data.buffer_type = HAL_BUFFER_INPUT; + data.filled_len = 0; + data.offset = 0; + data.flags = HAL_BUFFERFLAG_EOS; + data.timestamp = 0; + data.extradata_addr = data.device_addr; + data.extradata_size = 0; + dprintk(VIDC_DBG, "Queueing EOS buffer 0x%x\n", + data.device_addr); + hdev = inst->core->device; + + rc = call_hfi_op(hdev, session_etb, inst->session, + &data); + } + mutex_unlock(&inst->eosbufs.lock); + + return rc; +} + +int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd) +{ + struct msm_vidc_inst *inst = instance; + struct v4l2_decoder_cmd *dec = NULL; + struct v4l2_encoder_cmd *enc = NULL; + struct msm_vidc_core *core; + int which_cmd = 0, flags = 0, rc = 0; + + if (!inst || !inst->core || !cmd) { + dprintk(VIDC_ERR, "%s invalid params\n", __func__); + return -EINVAL; + } + core = inst->core; + if (inst->session_type == MSM_VIDC_ENCODER) { + enc = (struct v4l2_encoder_cmd *)cmd; + which_cmd = enc->cmd; + flags = enc->flags; + } else if (inst->session_type == MSM_VIDC_DECODER) { + dec = (struct v4l2_decoder_cmd *)cmd; + which_cmd = dec->cmd; + flags = dec->flags; + } + + + switch (which_cmd) { + case V4L2_CMD_FLUSH: + rc = msm_comm_flush(inst, flags); + if (rc) { + dprintk(VIDC_ERR, + "Failed to flush buffers: %d\n", rc); + } + break; + case V4L2_CMD_SESSION_CONTINUE: + { + rc = msm_comm_session_continue(inst); + break; + } + /* This case also for V4L2_ENC_CMD_STOP */ + case V4L2_DEC_CMD_STOP: + { + struct eos_buf *binfo = NULL; + u32 smem_flags = SMEM_UNCACHED; + + if (inst->state != MSM_VIDC_START_DONE) { + dprintk(VIDC_DBG, + "Inst = %pK is not ready for EOS\n", inst); + break; + } + + binfo = kzalloc(sizeof(*binfo), GFP_KERNEL); + if (!binfo) { + dprintk(VIDC_ERR, "%s: Out of memory\n", __func__); + rc = -ENOMEM; + break; + } + + if (inst->flags & VIDC_SECURE) + smem_flags |= SMEM_SECURE; + + rc = msm_comm_smem_alloc(inst, + SZ_4K, 1, smem_flags, + HAL_BUFFER_INPUT, 0, &binfo->smem); + if (rc) { + kfree(binfo); + dprintk(VIDC_ERR, + "Failed to allocate output memory\n"); + rc = -ENOMEM; + break; + } + + mutex_lock(&inst->eosbufs.lock); + list_add_tail(&binfo->list, &inst->eosbufs.list); + mutex_unlock(&inst->eosbufs.lock); + + rc = msm_vidc_send_pending_eos_buffers(inst); + if (rc) { + dprintk(VIDC_ERR, + "Failed pending_eos_buffers sending\n"); + list_del(&binfo->list); + kfree(binfo); + break; + } + break; + } + default: + dprintk(VIDC_ERR, "Unknown Command %d\n", which_cmd); + rc = -ENOTSUPP; + break; + } + return rc; +} + +static void populate_frame_data(struct vidc_frame_data *data, + struct msm_vidc_buffer *mbuf, struct msm_vidc_inst *inst) +{ + u64 time_usec; + struct v4l2_format *f = NULL; + struct vb2_buffer *vb; + struct vb2_v4l2_buffer *vbuf; + + if (!inst || !mbuf || !data) { + dprintk(VIDC_ERR, "%s: invalid params %pK %pK %pK\n", + __func__, inst, mbuf, data); + return; + } + + vb = &mbuf->vvb.vb2_buf; + vbuf = to_vb2_v4l2_buffer(vb); + + time_usec = vb->timestamp; + do_div(time_usec, NSEC_PER_USEC); + + data->alloc_len = vb->planes[0].length; + data->device_addr = mbuf->smem[0].device_addr; + data->timestamp = time_usec; + data->flags = 0; + data->clnt_data = data->device_addr; + + if (vb->type == INPUT_MPLANE) { + data->buffer_type = HAL_BUFFER_INPUT; + data->filled_len = vb->planes[0].bytesused; + data->offset = vb->planes[0].data_offset; + + if (vbuf->flags & V4L2_BUF_FLAG_EOS) + data->flags |= HAL_BUFFERFLAG_EOS; + + if (vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG) + data->flags |= HAL_BUFFERFLAG_CODECCONFIG; + + if (inst->session_type == MSM_VIDC_DECODER) { + msm_comm_fetch_mark_data(&inst->etb_data, vb->index, + &data->mark_data, &data->mark_target); + } + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + } else if (vb->type == OUTPUT_MPLANE) { + data->buffer_type = msm_comm_get_hal_output_buffer(inst); + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + } + + if (f && f->fmt.pix_mp.num_planes > 1) { + data->extradata_addr = mbuf->smem[1].device_addr; + data->extradata_size = vb->planes[1].length; + data->flags |= HAL_BUFFERFLAG_EXTRADATA; + } +} + +enum hal_buffer get_hal_buffer_type(unsigned int type, + unsigned int plane_num) +{ + if (type == INPUT_MPLANE) { + if (plane_num == 0) + return HAL_BUFFER_INPUT; + else + return HAL_BUFFER_EXTRADATA_INPUT; + } else if (type == OUTPUT_MPLANE) { + if (plane_num == 0) + return HAL_BUFFER_OUTPUT; + else + return HAL_BUFFER_EXTRADATA_OUTPUT; + } else { + return -EINVAL; + } +} + +int msm_comm_num_queued_bufs(struct msm_vidc_inst *inst, u32 type) +{ + int count = 0; + struct msm_vidc_buffer *mbuf; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return 0; + } + + mutex_lock(&inst->registeredbufs.lock); + list_for_each_entry(mbuf, &inst->registeredbufs.list, list) { + if (mbuf->vvb.vb2_buf.type != type) + continue; + if (!(mbuf->flags & MSM_VIDC_FLAG_QUEUED)) + continue; + count++; + } + mutex_unlock(&inst->registeredbufs.lock); + + return count; +} + +static int num_pending_qbufs(struct msm_vidc_inst *inst, u32 type) +{ + int count = 0; + struct msm_vidc_buffer *mbuf; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return 0; + } + + mutex_lock(&inst->registeredbufs.lock); + list_for_each_entry(mbuf, &inst->registeredbufs.list, list) { + if (mbuf->vvb.vb2_buf.type != type) + continue; + /* Count only deferred buffers */ + if (!(mbuf->flags & MSM_VIDC_FLAG_DEFERRED)) + continue; + count++; + } + mutex_unlock(&inst->registeredbufs.lock); + + return count; +} + +static int msm_comm_qbuf_to_hfi(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf) +{ + int rc = 0; + struct hfi_device *hdev; + enum msm_vidc_debugfs_event e; + struct vidc_frame_data frame_data = {0}; + + if (!inst || !inst->core || !inst->core->device || !mbuf) { + dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + populate_frame_data(&frame_data, mbuf, inst); + /* mbuf is not deferred anymore */ + mbuf->flags &= ~MSM_VIDC_FLAG_DEFERRED; + + if (mbuf->vvb.vb2_buf.type == INPUT_MPLANE) { + e = MSM_VIDC_DEBUGFS_EVENT_ETB; + rc = call_hfi_op(hdev, session_etb, inst->session, &frame_data); + } else if (mbuf->vvb.vb2_buf.type == OUTPUT_MPLANE) { + e = MSM_VIDC_DEBUGFS_EVENT_FTB; + rc = call_hfi_op(hdev, session_ftb, inst->session, &frame_data); + } else { + dprintk(VIDC_ERR, "%s: invalid qbuf type %d:\n", __func__, + mbuf->vvb.vb2_buf.type); + rc = -EINVAL; + } + if (rc) { + dprintk(VIDC_ERR, "%s: Failed to qbuf: %d\n", __func__, rc); + goto err_bad_input; + } + mbuf->flags |= MSM_VIDC_FLAG_QUEUED; + msm_vidc_debugfs_update(inst, e); + +err_bad_input: + return rc; +} + +static int msm_comm_qbuf_in_rbr(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf) +{ + int rc = 0; + + if (!inst || !mbuf) { + dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + return -EINVAL; + } + + if (inst->state == MSM_VIDC_CORE_INVALID) { + dprintk(VIDC_ERR, "%s: inst is in bad state\n", __func__); + return -EINVAL; + } + + rc = msm_comm_scale_clocks_and_bus(inst); + if (rc) + dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__); + + print_vidc_buffer(VIDC_DBG, "qbuf in rbr", inst, mbuf); + rc = msm_comm_qbuf_to_hfi(inst, mbuf); + if (rc) + dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", __func__, rc); + + return rc; +} + +int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) +{ + int rc = 0; + + if (!inst || !mbuf) { + dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + return -EINVAL; + } + + if (inst->state == MSM_VIDC_CORE_INVALID) { + dprintk(VIDC_ERR, "%s: inst is in bad state\n", __func__); + return -EINVAL; + } + + if (inst->state != MSM_VIDC_START_DONE) { + mbuf->flags |= MSM_VIDC_FLAG_DEFERRED; + print_vidc_buffer(VIDC_DBG, "qbuf deferred", inst, mbuf); + return 0; + } + + rc = msm_comm_scale_clocks_and_bus(inst); + if (rc) + dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__); + + print_vidc_buffer(VIDC_DBG, "qbuf", inst, mbuf); + rc = msm_comm_qbuf_to_hfi(inst, mbuf); + if (rc) + dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", __func__, rc); + + return rc; +} + +int msm_comm_qbufs(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_vidc_buffer *mbuf; + + if (!inst) { + dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + return -EINVAL; + } + + if (inst->state != MSM_VIDC_START_DONE) { + dprintk(VIDC_DBG, "%s: inst not in start state: %d\n", + __func__, inst->state); + return 0; + } + + rc = msm_comm_scale_clocks_and_bus(inst); + if (rc) + dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__); + + mutex_lock(&inst->registeredbufs.lock); + list_for_each_entry(mbuf, &inst->registeredbufs.list, list) { + /* Queue only deferred buffers */ + if (!(mbuf->flags & MSM_VIDC_FLAG_DEFERRED)) + continue; + print_vidc_buffer(VIDC_DBG, "qbufs", inst, mbuf); + rc = msm_comm_qbuf_to_hfi(inst, mbuf); + if (rc) { + dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", + __func__, rc); + break; + } + } + mutex_unlock(&inst->registeredbufs.lock); + + return rc; +} + +/* + * msm_comm_qbuf_decode_batch - count the buffers which are not queued to + * firmware yet (count includes rbr pending buffers too) and + * queue the buffers at once if full batch count reached. + * Don't queue rbr pending buffers as they would be queued + * when rbr event arrived from firmware. + */ +int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf) +{ + int rc = 0; + u32 count = 0; + struct msm_vidc_buffer *buf; + + if (!inst || !mbuf) { + dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + return -EINVAL; + } + + if (inst->state == MSM_VIDC_CORE_INVALID) { + dprintk(VIDC_ERR, "%s: inst is in bad state\n", __func__); + return -EINVAL; + } + + if (inst->state != MSM_VIDC_START_DONE) { + mbuf->flags |= MSM_VIDC_FLAG_DEFERRED; + print_vidc_buffer(VIDC_DBG, "qbuf deferred", inst, mbuf); + return 0; + } + + /* + * Don't defer buffers initially to avoid startup latency increase + * due to batching + */ + if (inst->clk_data.buffer_counter > SKIP_BATCH_WINDOW) { + count = num_pending_qbufs(inst, OUTPUT_MPLANE); + if (count < inst->batch.size) { + print_vidc_buffer(VIDC_DBG, + "batch-qbuf deferred", inst, mbuf); + return 0; + } + } + + rc = msm_comm_scale_clocks_and_bus(inst); + if (rc) + dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__); + + mutex_lock(&inst->registeredbufs.lock); + list_for_each_entry(buf, &inst->registeredbufs.list, list) { + /* Don't queue if buffer is not CAPTURE_MPLANE */ + if (buf->vvb.vb2_buf.type != OUTPUT_MPLANE) + goto loop_end; + /* Don't queue if buffer is not a deferred buffer */ + if (!(buf->flags & MSM_VIDC_FLAG_DEFERRED)) + goto loop_end; + /* Don't queue if RBR event is pending on this buffer */ + if (buf->flags & MSM_VIDC_FLAG_RBR_PENDING) + goto loop_end; + + print_vidc_buffer(VIDC_DBG, "batch-qbuf", inst, buf); + rc = msm_comm_qbuf_to_hfi(inst, buf); + if (rc) { + dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", + __func__, rc); + break; + } +loop_end: + /* Queue pending buffers till the current buffer only */ + if (buf == mbuf) + break; + } + mutex_unlock(&inst->registeredbufs.lock); + + return rc; +} + +int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst) +{ + int rc = -EINVAL, i = 0; + union hal_get_property hprop; + + memset(&hprop, 0x0, sizeof(hprop)); + /* + * First check if we can calculate bufffer sizes. + * If we can calculate then we do it within the driver. + * If we cannot then we get buffer requirements from firmware. + */ + if (inst->buffer_size_calculators) { + rc = inst->buffer_size_calculators(inst); + if (rc) + dprintk(VIDC_ERR, + "Failed calculating internal buffer sizes: %d", rc); + } + + /* + * Fallback to get buffreq from firmware if internal calculation + * is not done or if it fails + */ + if (rc) { + rc = msm_comm_try_get_buff_req(inst, &hprop); + if (rc) { + dprintk(VIDC_ERR, + "Failed getting buffer requirements: %d", rc); + return rc; + } + + for (i = 0; i < HAL_BUFFER_MAX; i++) { + struct hal_buffer_requirements req; + struct hal_buffer_requirements *curr_req; + + req = hprop.buf_req.buffer[i]; + /* + * Firmware buffer requirements are needed for internal + * buffers only and all other buffer requirements are + * calculated in driver. + */ + curr_req = get_buff_req_buffer(inst, req.buffer_type); + if (!curr_req) + return -EINVAL; + + if (req.buffer_type == HAL_BUFFER_INTERNAL_SCRATCH || + req.buffer_type == + HAL_BUFFER_INTERNAL_SCRATCH_1 || + req.buffer_type == + HAL_BUFFER_INTERNAL_SCRATCH_2 || + req.buffer_type == + HAL_BUFFER_INTERNAL_PERSIST || + req.buffer_type == + HAL_BUFFER_INTERNAL_PERSIST_1 || + req.buffer_type == HAL_BUFFER_INTERNAL_RECON) { + memcpy(curr_req, &req, + sizeof(struct hal_buffer_requirements)); + } + } + } + + dprintk(VIDC_DBG, "Buffer requirements :\n"); + dprintk(VIDC_DBG, "%15s %8s %8s %8s %8s %8s\n", + "buffer type", "count", "mincount_host", "mincount_fw", "size", + "alignment"); + for (i = 0; i < HAL_BUFFER_MAX; i++) { + struct hal_buffer_requirements req = inst->buff_req.buffer[i]; + + if (req.buffer_type != HAL_BUFFER_NONE) { + dprintk(VIDC_DBG, "%15s %8d %8d %8d %8d %8d\n", + get_buffer_name(req.buffer_type), + req.buffer_count_actual, + req.buffer_count_min_host, + req.buffer_count_min, req.buffer_size, + req.buffer_alignment); + } + } + return rc; +} + +int msm_comm_try_get_buff_req(struct msm_vidc_inst *inst, + union hal_get_property *hprop) +{ + int rc = 0; + struct hfi_device *hdev; + struct getprop_buf *buf; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + hdev = inst->core->device; + mutex_lock(&inst->sync_lock); + if (inst->state < MSM_VIDC_OPEN_DONE || + inst->state >= MSM_VIDC_CLOSE) { + + /* No need to check inst->state == MSM_VIDC_INVALID since + * INVALID is > CLOSE_DONE. When core went to INVALID state, + * we put all the active instances in INVALID. So > CLOSE_DONE + * is enough check to have. + */ + + dprintk(VIDC_ERR, + "In Wrong state to call Buf Req: Inst %pK or Core %pK\n", + inst, inst->core); + rc = -EAGAIN; + mutex_unlock(&inst->sync_lock); + goto exit; + } + mutex_unlock(&inst->sync_lock); + + rc = call_hfi_op(hdev, session_get_buf_req, inst->session); + if (rc) { + dprintk(VIDC_ERR, "Can't query hardware for property: %d\n", + rc); + goto exit; + } + + rc = wait_for_completion_timeout(&inst->completions[ + SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO)], + msecs_to_jiffies( + inst->core->resources.msm_vidc_hw_rsp_timeout)); + if (!rc) { + dprintk(VIDC_ERR, + "%s: Wait interrupted or timed out [%pK]: %d\n", + __func__, inst, + SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO)); + msm_comm_kill_session(inst); + rc = -ETIMEDOUT; + goto exit; + } else { + /* wait_for_completion_timeout returns jiffies before expiry */ + rc = 0; + } + + mutex_lock(&inst->pending_getpropq.lock); + if (!list_empty(&inst->pending_getpropq.list)) { + buf = list_first_entry(&inst->pending_getpropq.list, + struct getprop_buf, list); + *hprop = *(union hal_get_property *)buf->data; + kfree(buf->data); + list_del(&buf->list); + kfree(buf); + } else { + dprintk(VIDC_ERR, "%s getprop list empty\n", __func__); + rc = -EINVAL; + } + mutex_unlock(&inst->pending_getpropq.lock); +exit: + return rc; +} + +int msm_comm_release_dpb_only_buffers(struct msm_vidc_inst *inst, + bool force_release) +{ + struct msm_smem *handle; + struct internal_buf *buf, *dummy; + struct vidc_buffer_addr_info buffer_info; + int rc = 0; + struct msm_vidc_core *core; + struct hfi_device *hdev; + + if (!inst) { + dprintk(VIDC_ERR, + "Invalid instance pointer = %pK\n", inst); + return -EINVAL; + } + mutex_lock(&inst->outputbufs.lock); + if (list_empty(&inst->outputbufs.list)) { + dprintk(VIDC_DBG, "%s - No OUTPUT buffers allocated\n", + __func__); + mutex_unlock(&inst->outputbufs.lock); + return 0; + } + mutex_unlock(&inst->outputbufs.lock); + + core = inst->core; + if (!core) { + dprintk(VIDC_ERR, + "Invalid core pointer = %pK\n", core); + return -EINVAL; + } + hdev = core->device; + if (!hdev) { + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); + return -EINVAL; + } + mutex_lock(&inst->outputbufs.lock); + list_for_each_entry_safe(buf, dummy, &inst->outputbufs.list, list) { + handle = &buf->smem; + + if ((buf->buffer_ownership == FIRMWARE) && !force_release) { + dprintk(VIDC_INFO, "DPB is with f/w. Can't free it\n"); + /* + * mark this buffer to avoid sending it to video h/w + * again, this buffer belongs to old resolution and + * it will be removed when video h/w returns it. + */ + buf->mark_remove = true; + continue; + } + + buffer_info.buffer_size = handle->size; + buffer_info.buffer_type = buf->buffer_type; + buffer_info.num_buffers = 1; + buffer_info.align_device_addr = handle->device_addr; + if (inst->buffer_mode_set[OUTPUT_PORT] == + HAL_BUFFER_MODE_STATIC) { + buffer_info.response_required = false; + rc = call_hfi_op(hdev, session_release_buffers, + (void *)inst->session, &buffer_info); + if (rc) { + dprintk(VIDC_WARN, + "Rel output buf fail:%x, %d\n", + buffer_info.align_device_addr, + buffer_info.buffer_size); + } + } + + list_del(&buf->list); + msm_comm_smem_free(inst, &buf->smem); + kfree(buf); + } + + if (inst->dpb_extra_binfo) { + msm_comm_smem_free(inst, &inst->dpb_extra_binfo->smem); + kfree(inst->dpb_extra_binfo); + inst->dpb_extra_binfo = NULL; + } + + mutex_unlock(&inst->outputbufs.lock); + return rc; +} + +static enum hal_buffer scratch_buf_sufficient(struct msm_vidc_inst *inst, + enum hal_buffer buffer_type) +{ + struct hal_buffer_requirements *bufreq = NULL; + struct internal_buf *buf; + int count = 0; + + if (!inst) { + dprintk(VIDC_ERR, "%s - invalid param\n", __func__); + goto not_sufficient; + } + + bufreq = get_buff_req_buffer(inst, buffer_type); + if (!bufreq) + goto not_sufficient; + + /* Check if current scratch buffers are sufficient */ + mutex_lock(&inst->scratchbufs.lock); + + list_for_each_entry(buf, &inst->scratchbufs.list, list) { + if (buf->buffer_type == buffer_type && + buf->smem.size >= bufreq->buffer_size) + count++; + } + mutex_unlock(&inst->scratchbufs.lock); + + if (count != bufreq->buffer_count_actual) + goto not_sufficient; + + dprintk(VIDC_DBG, + "Existing scratch buffer is sufficient for buffer type %#x\n", + buffer_type); + + return buffer_type; + +not_sufficient: + return HAL_BUFFER_NONE; +} + +int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst, + bool check_for_reuse) +{ + struct msm_smem *handle; + struct internal_buf *buf, *dummy; + struct vidc_buffer_addr_info buffer_info; + int rc = 0; + struct msm_vidc_core *core; + struct hfi_device *hdev; + enum hal_buffer sufficiency = HAL_BUFFER_NONE; + + if (!inst) { + dprintk(VIDC_ERR, + "Invalid instance pointer = %pK\n", inst); + return -EINVAL; + } + core = inst->core; + if (!core) { + dprintk(VIDC_ERR, + "Invalid core pointer = %pK\n", core); + return -EINVAL; + } + hdev = core->device; + if (!hdev) { + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); + return -EINVAL; + } + + if (check_for_reuse) { + sufficiency |= scratch_buf_sufficient(inst, + HAL_BUFFER_INTERNAL_SCRATCH); + + sufficiency |= scratch_buf_sufficient(inst, + HAL_BUFFER_INTERNAL_SCRATCH_1); + + sufficiency |= scratch_buf_sufficient(inst, + HAL_BUFFER_INTERNAL_SCRATCH_2); + } + + mutex_lock(&inst->scratchbufs.lock); + list_for_each_entry_safe(buf, dummy, &inst->scratchbufs.list, list) { + handle = &buf->smem; + buffer_info.buffer_size = handle->size; + buffer_info.buffer_type = buf->buffer_type; + buffer_info.num_buffers = 1; + buffer_info.align_device_addr = handle->device_addr; + buffer_info.response_required = true; + rc = call_hfi_op(hdev, session_release_buffers, + (void *)inst->session, &buffer_info); + if (!rc) { + mutex_unlock(&inst->scratchbufs.lock); + rc = wait_for_sess_signal_receipt(inst, + HAL_SESSION_RELEASE_BUFFER_DONE); + if (rc) + dprintk(VIDC_WARN, + "%s: wait for signal failed, rc %d\n", + __func__, rc); + mutex_lock(&inst->scratchbufs.lock); + } else { + dprintk(VIDC_WARN, + "Rel scrtch buf fail:%x, %d\n", + buffer_info.align_device_addr, + buffer_info.buffer_size); + } + + /*If scratch buffers can be reused, do not free the buffers*/ + if (sufficiency & buf->buffer_type) + continue; + + list_del(&buf->list); + msm_comm_smem_free(inst, handle); + kfree(buf); + } + + mutex_unlock(&inst->scratchbufs.lock); + return rc; +} + +void msm_comm_release_eos_buffers(struct msm_vidc_inst *inst) +{ + struct eos_buf *buf, *next; + + if (!inst) { + dprintk(VIDC_ERR, + "Invalid instance pointer = %pK\n", inst); + return; + } + + mutex_lock(&inst->eosbufs.lock); + list_for_each_entry_safe(buf, next, &inst->eosbufs.list, list) { + list_del(&buf->list); + msm_comm_smem_free(inst, &buf->smem); + kfree(buf); + } + INIT_LIST_HEAD(&inst->eosbufs.list); + mutex_unlock(&inst->eosbufs.lock); +} + + +int msm_comm_release_recon_buffers(struct msm_vidc_inst *inst) +{ + struct recon_buf *buf, *next; + + if (!inst) { + dprintk(VIDC_ERR, + "Invalid instance pointer = %pK\n", inst); + return -EINVAL; + } + + mutex_lock(&inst->reconbufs.lock); + list_for_each_entry_safe(buf, next, &inst->reconbufs.list, list) { + list_del(&buf->list); + kfree(buf); + } + INIT_LIST_HEAD(&inst->reconbufs.list); + mutex_unlock(&inst->reconbufs.lock); + + return 0; +} + +int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst) +{ + struct msm_smem *handle; + struct list_head *ptr, *next; + struct internal_buf *buf; + struct vidc_buffer_addr_info buffer_info; + int rc = 0; + struct msm_vidc_core *core; + struct hfi_device *hdev; + + if (!inst) { + dprintk(VIDC_ERR, + "Invalid instance pointer = %pK\n", inst); + return -EINVAL; + } + core = inst->core; + if (!core) { + dprintk(VIDC_ERR, + "Invalid core pointer = %pK\n", core); + return -EINVAL; + } + hdev = core->device; + if (!hdev) { + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); + return -EINVAL; + } + + mutex_lock(&inst->persistbufs.lock); + list_for_each_safe(ptr, next, &inst->persistbufs.list) { + buf = list_entry(ptr, struct internal_buf, list); + handle = &buf->smem; + buffer_info.buffer_size = handle->size; + buffer_info.buffer_type = buf->buffer_type; + buffer_info.num_buffers = 1; + buffer_info.align_device_addr = handle->device_addr; + buffer_info.response_required = true; + rc = call_hfi_op(hdev, session_release_buffers, + (void *)inst->session, &buffer_info); + if (!rc) { + mutex_unlock(&inst->persistbufs.lock); + rc = wait_for_sess_signal_receipt(inst, + HAL_SESSION_RELEASE_BUFFER_DONE); + if (rc) + dprintk(VIDC_WARN, + "%s: wait for signal failed, rc %d\n", + __func__, rc); + mutex_lock(&inst->persistbufs.lock); + } else { + dprintk(VIDC_WARN, + "Rel prst buf fail:%x, %d\n", + buffer_info.align_device_addr, + buffer_info.buffer_size); + } + list_del(&buf->list); + msm_comm_smem_free(inst, handle); + kfree(buf); + } + mutex_unlock(&inst->persistbufs.lock); + return rc; +} + +int msm_comm_set_buffer_count(struct msm_vidc_inst *inst, + int host_count, int act_count, enum hal_buffer type) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_buffer_count_actual buf_count; + + hdev = inst->core->device; + + buf_count.buffer_type = get_hfi_buffer(type); + buf_count.buffer_count_actual = act_count; + buf_count.buffer_count_min_host = host_count; + dprintk(VIDC_DBG, "%s: %x : hal_buffer %d min_host %d actual %d\n", + __func__, hash32_ptr(inst->session), type, + host_count, act_count); + rc = call_hfi_op(hdev, session_set_property, + inst->session, HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL, + &buf_count, sizeof(buf_count)); + if (rc) + dprintk(VIDC_ERR, + "Failed to set actual buffer count %d for buffer type %d\n", + act_count, type); + return rc; +} + +int msm_comm_set_dpb_only_buffers(struct msm_vidc_inst *inst) +{ + int rc = 0; + bool force_release = true; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + if (get_v4l2_codec(inst) == V4L2_PIX_FMT_VP9) + force_release = false; + + if (msm_comm_release_dpb_only_buffers(inst, force_release)) + dprintk(VIDC_WARN, "Failed to release output buffers\n"); + + rc = set_dpb_only_buffers(inst, HAL_BUFFER_OUTPUT); + if (rc) + goto error; + return rc; +error: + msm_comm_release_dpb_only_buffers(inst, true); + return rc; +} + +int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst) +{ + int rc = 0; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + if (msm_comm_release_scratch_buffers(inst, true)) + dprintk(VIDC_WARN, "Failed to release scratch buffers\n"); + + rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH, + &inst->scratchbufs); + if (rc) + goto error; + + rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH_1, + &inst->scratchbufs); + if (rc) + goto error; + + rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH_2, + &inst->scratchbufs); + if (rc) + goto error; + + return rc; +error: + msm_comm_release_scratch_buffers(inst, false); + return rc; +} + +int msm_comm_set_recon_buffers(struct msm_vidc_inst *inst) +{ + int rc = 0; + unsigned int i = 0; + struct hal_buffer_requirements *internal_buf; + struct recon_buf *binfo; + struct msm_vidc_list *buf_list = &inst->reconbufs; + + if (!inst) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + if (inst->session_type != MSM_VIDC_ENCODER) { + dprintk(VIDC_DBG, "Recon buffs not req for decoder/cvp\n"); + return 0; + } + + internal_buf = get_buff_req_buffer(inst, + HAL_BUFFER_INTERNAL_RECON); + if (!internal_buf || !internal_buf->buffer_count_actual) { + dprintk(VIDC_DBG, "Inst : %pK Recon buffers not required\n", + inst); + return 0; + } + + msm_comm_release_recon_buffers(inst); + + for (i = 0; i < internal_buf->buffer_count_actual; i++) { + binfo = kzalloc(sizeof(*binfo), GFP_KERNEL); + if (!binfo) { + dprintk(VIDC_ERR, "Out of memory\n"); + rc = -ENOMEM; + goto fail_kzalloc; + } + + binfo->buffer_index = i; + mutex_lock(&buf_list->lock); + list_add_tail(&binfo->list, &buf_list->list); + mutex_unlock(&buf_list->lock); + } + +fail_kzalloc: + return rc; +} + +int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst) +{ + int rc = 0; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_PERSIST, + &inst->persistbufs); + if (rc) + goto error; + + rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_PERSIST_1, + &inst->persistbufs); + if (rc) + goto error; + return rc; +error: + msm_comm_release_persist_buffers(inst); + return rc; +} + +static void msm_comm_flush_in_invalid_state(struct msm_vidc_inst *inst) +{ + struct list_head *ptr, *next; + enum vidc_ports ports[] = {INPUT_PORT, OUTPUT_PORT}; + int c = 0; + + /* before flush ensure venus released all buffers */ + msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); + + for (c = 0; c < ARRAY_SIZE(ports); ++c) { + enum vidc_ports port = ports[c]; + + mutex_lock(&inst->bufq[port].lock); + list_for_each_safe(ptr, next, + &inst->bufq[port].vb2_bufq.queued_list) { + struct vb2_buffer *vb = container_of(ptr, + struct vb2_buffer, queued_entry); + if (vb->state == VB2_BUF_STATE_ACTIVE) { + vb->planes[0].bytesused = 0; + print_vb2_buffer(VIDC_ERR, "flush in invalid", + inst, vb); + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); + } else { + dprintk(VIDC_WARN, + "%s VB is in state %d not in ACTIVE state\n" + , __func__, vb->state); + } + } + mutex_unlock(&inst->bufq[port].lock); + } + msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_FLUSH_DONE); +} + +int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) +{ + unsigned int i = 0; + int rc = 0; + bool ip_flush = false; + bool op_flush = false; + struct msm_vidc_buffer *mbuf, *next; + struct msm_vidc_core *core; + struct hfi_device *hdev; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, + "Invalid params, inst %pK\n", inst); + return -EINVAL; + } + core = inst->core; + hdev = core->device; + + ip_flush = flags & V4L2_CMD_FLUSH_OUTPUT; + op_flush = flags & V4L2_CMD_FLUSH_CAPTURE; + + if (ip_flush && !op_flush) { + dprintk(VIDC_WARN, + "Input only flush not supported, making it flush all\n"); + op_flush = true; + return 0; + } + + msm_clock_data_reset(inst); + + if (inst->state == MSM_VIDC_CORE_INVALID) { + dprintk(VIDC_ERR, + "Core %pK and inst %pK are in bad state\n", + core, inst); + msm_comm_flush_in_invalid_state(inst); + return 0; + } + + mutex_lock(&inst->flush_lock); + /* enable in flush */ + inst->in_flush = true; + + mutex_lock(&inst->registeredbufs.lock); + list_for_each_entry_safe(mbuf, next, &inst->registeredbufs.list, list) { + /* don't flush input buffers if input flush is not requested */ + if (!ip_flush && mbuf->vvb.vb2_buf.type == INPUT_MPLANE) + continue; + + /* flush only deferred or rbr pending buffers */ + if (!(mbuf->flags & MSM_VIDC_FLAG_DEFERRED || + mbuf->flags & MSM_VIDC_FLAG_RBR_PENDING)) + continue; + + /* + * flush buffers which are queued by client already, + * the refcount will be two or more for those buffers. + */ + if (!(mbuf->smem[0].refcount >= 2)) + continue; + + print_vidc_buffer(VIDC_DBG, "flush buf", inst, mbuf); + msm_comm_flush_vidc_buffer(inst, mbuf); + + for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) { + if (inst->smem_ops->smem_unmap_dma_buf(inst, + &mbuf->smem[i])) + print_vidc_buffer(VIDC_ERR, + "dqbuf: unmap failed.", inst, mbuf); + if (inst->smem_ops->smem_unmap_dma_buf(inst, + &mbuf->smem[i])) + print_vidc_buffer(VIDC_ERR, + "dqbuf: unmap failed..", inst, mbuf); + } + if (!mbuf->smem[0].refcount) { + list_del(&mbuf->list); + kref_put_mbuf(mbuf); + } else { + /* buffer is no more a deferred buffer */ + mbuf->flags &= ~MSM_VIDC_FLAG_DEFERRED; + } + } + mutex_unlock(&inst->registeredbufs.lock); + + hdev = inst->core->device; + if (ip_flush) { + dprintk(VIDC_DBG, "Send flush on all ports to firmware\n"); + rc = call_hfi_op(hdev, session_flush, inst->session, + HAL_FLUSH_ALL); + } else { + dprintk(VIDC_DBG, "Send flush on output port to firmware\n"); + rc = call_hfi_op(hdev, session_flush, inst->session, + HAL_FLUSH_OUTPUT); + } + mutex_unlock(&inst->flush_lock); + if (rc) { + dprintk(VIDC_ERR, + "Sending flush to firmware failed, flush out all buffers\n"); + msm_comm_flush_in_invalid_state(inst); + /* disable in_flush */ + inst->in_flush = false; + } + + return rc; +} + +int msm_vidc_noc_error_info(struct msm_vidc_core *core) +{ + struct hfi_device *hdev; + + if (!core || !core->device) { + dprintk(VIDC_WARN, "%s: Invalid parameters: %pK\n", + __func__, core); + return -EINVAL; + } + + if (!core->resources.non_fatal_pagefaults) + return 0; + + if (!core->smmu_fault_handled) + return 0; + + hdev = core->device; + call_hfi_op(hdev, noc_error_info, hdev->hfi_device_data); + + return 0; +} + +int msm_vidc_trigger_ssr(struct msm_vidc_core *core, + enum hal_ssr_trigger_type type) +{ + if (!core) { + dprintk(VIDC_WARN, "%s: Invalid parameters\n", __func__); + return -EINVAL; + } + core->ssr_type = type; + schedule_work(&core->ssr_work); + return 0; +} + +void msm_vidc_ssr_handler(struct work_struct *work) +{ + int rc; + struct msm_vidc_core *core; + struct hfi_device *hdev; + + core = container_of(work, struct msm_vidc_core, ssr_work); + if (!core || !core->device) { + dprintk(VIDC_ERR, "%s: Invalid params\n", __func__); + return; + } + hdev = core->device; + + mutex_lock(&core->lock); + if (core->state == VIDC_CORE_INIT_DONE) { + dprintk(VIDC_WARN, "%s: ssr type %d\n", __func__, + core->ssr_type); + /* + * In current implementation user-initiated SSR triggers + * a fatal error from hardware. However, there is no way + * to know if fatal error is due to SSR or not. Handle + * user SSR as non-fatal. + */ + core->trigger_ssr = true; + rc = call_hfi_op(hdev, core_trigger_ssr, + hdev->hfi_device_data, core->ssr_type); + if (rc) { + dprintk(VIDC_ERR, "%s: trigger_ssr failed\n", + __func__); + core->trigger_ssr = false; + } + } else { + dprintk(VIDC_WARN, "%s: video core %pK not initialized\n", + __func__, core); + } + mutex_unlock(&core->lock); +} + +static int msm_vidc_load_supported(struct msm_vidc_inst *inst) +{ + int num_mbs_per_sec = 0, max_load_adj = 0; + enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD | + LOAD_CALC_IGNORE_THUMBNAIL_LOAD | + LOAD_CALC_IGNORE_NON_REALTIME_LOAD; + + if (inst->state == MSM_VIDC_OPEN_DONE) { + max_load_adj = inst->core->resources.max_load; + num_mbs_per_sec = msm_comm_get_load(inst->core, + MSM_VIDC_DECODER, quirks); + num_mbs_per_sec += msm_comm_get_load(inst->core, + MSM_VIDC_ENCODER, quirks); + if (num_mbs_per_sec > max_load_adj) { + dprintk(VIDC_ERR, + "H/W is overloaded. needed: %d max: %d\n", + num_mbs_per_sec, + max_load_adj); + msm_vidc_print_running_insts(inst->core); + return -EBUSY; + } + } + return 0; +} + +int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst) +{ + u32 x_min, x_max, y_min, y_max; + u32 input_height, input_width, output_height, output_width; + struct v4l2_format *f; + + if (inst->grid_enable > 0) { + dprintk(VIDC_DBG, "Skip scaling check for HEIC\n"); + return 0; + } + + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + input_height = f->fmt.pix_mp.height; + input_width = f->fmt.pix_mp.width; + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + output_height = f->fmt.pix_mp.height; + output_width = f->fmt.pix_mp.width; + + if (!input_height || !input_width || !output_height || !output_width) { + dprintk(VIDC_ERR, + "Invalid : Input height = %d width = %d", + input_height, input_width); + dprintk(VIDC_ERR, + " output height = %d width = %d\n", + output_height, output_width); + return -ENOTSUPP; + } + + if (!inst->capability.cap[CAP_SCALE_X].min || + !inst->capability.cap[CAP_SCALE_X].max || + !inst->capability.cap[CAP_SCALE_Y].min || + !inst->capability.cap[CAP_SCALE_Y].max) { + + if (input_width * input_height != + output_width * output_height) { + dprintk(VIDC_ERR, + "%s: scaling is not supported (%dx%d != %dx%d)\n", + __func__, input_width, input_height, + output_width, output_height); + return -ENOTSUPP; + } + + dprintk(VIDC_DBG, "%s: supported WxH = %dx%d\n", + __func__, input_width, input_height); + return 0; + } + + x_min = (1<<16)/inst->capability.cap[CAP_SCALE_X].min; + y_min = (1<<16)/inst->capability.cap[CAP_SCALE_Y].min; + x_max = inst->capability.cap[CAP_SCALE_X].max >> 16; + y_max = inst->capability.cap[CAP_SCALE_Y].max >> 16; + + if (input_height > output_height) { + if (input_height > x_min * output_height) { + dprintk(VIDC_ERR, + "Unsupported height min height %d vs %d\n", + input_height / x_min, output_height); + return -ENOTSUPP; + } + } else { + if (output_height > x_max * input_height) { + dprintk(VIDC_ERR, + "Unsupported height max height %d vs %d\n", + x_max * input_height, output_height); + return -ENOTSUPP; + } + } + if (input_width > output_width) { + if (input_width > y_min * output_width) { + dprintk(VIDC_ERR, + "Unsupported width min width %d vs %d\n", + input_width / y_min, output_width); + return -ENOTSUPP; + } + } else { + if (output_width > y_max * input_width) { + dprintk(VIDC_ERR, + "Unsupported width max width %d vs %d\n", + y_max * input_width, output_width); + return -ENOTSUPP; + } + } + return 0; +} + +int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) +{ + struct msm_vidc_capability *capability; + int rc = 0; + struct hfi_device *hdev; + struct msm_vidc_core *core; + u32 output_height, output_width, input_height, input_width; + u32 width_min, width_max, height_min, height_max; + u32 mbpf_max; + struct v4l2_format *f; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_WARN, "%s: Invalid parameter\n", __func__); + return -EINVAL; + } + capability = &inst->capability; + hdev = inst->core->device; + core = inst->core; + rc = msm_vidc_load_supported(inst); + if (rc) { + dprintk(VIDC_WARN, + "%s: Hardware is overloaded\n", __func__); + return rc; + } + + if (!is_thermal_permissible(core)) { + dprintk(VIDC_WARN, + "Thermal level critical, stop all active sessions!\n"); + return -ENOTSUPP; + } + + if (is_secure_session(inst)) { + width_min = capability->cap[CAP_SECURE_FRAME_WIDTH].min; + width_max = capability->cap[CAP_SECURE_FRAME_WIDTH].max; + height_min = capability->cap[CAP_SECURE_FRAME_HEIGHT].min; + height_max = capability->cap[CAP_SECURE_FRAME_HEIGHT].max; + mbpf_max = capability->cap[CAP_SECURE_MBS_PER_FRAME].max; + } else { + width_min = capability->cap[CAP_FRAME_WIDTH].min; + width_max = capability->cap[CAP_FRAME_WIDTH].max; + height_min = capability->cap[CAP_FRAME_HEIGHT].min; + height_max = capability->cap[CAP_FRAME_HEIGHT].max; + mbpf_max = capability->cap[CAP_MBS_PER_FRAME].max; + } + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + output_height = f->fmt.pix_mp.height; + output_width = f->fmt.pix_mp.width; + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + input_height = f->fmt.pix_mp.height; + input_width = f->fmt.pix_mp.width; + + if (inst->session_type == MSM_VIDC_ENCODER && (input_width % 2 != 0 || + input_height % 2 != 0 || output_width % 2 != 0 || + output_height % 2 != 0)) { + dprintk(VIDC_ERR, + "Height and Width should be even numbers for NV12\n"); + dprintk(VIDC_ERR, + "Input WxH = (%u)x(%u), Output WxH = (%u)x(%u)\n", + input_width, input_height, + output_width, output_height); + rc = -ENOTSUPP; + } + + output_height = ALIGN(output_height, 16); + output_width = ALIGN(output_width, 16); + + if (!rc) { + if (output_width < width_min || + output_height < height_min) { + dprintk(VIDC_ERR, + "Unsupported WxH = (%u)x(%u), min supported is - (%u)x(%u)\n", + output_width, output_height, + width_min, height_min); + rc = -ENOTSUPP; + } + if (!rc && output_width > width_max) { + dprintk(VIDC_ERR, + "Unsupported width = %u supported max width = %u\n", + output_width, width_max); + rc = -ENOTSUPP; + } + + if (!rc && output_height * output_width > + width_max * height_max) { + dprintk(VIDC_ERR, + "Unsupported WxH = (%u)x(%u), max supported is - (%u)x(%u)\n", + output_width, output_height, + width_max, height_max); + rc = -ENOTSUPP; + } + if (!rc && NUM_MBS_PER_FRAME(input_width, input_height) > + mbpf_max) { + dprintk(VIDC_ERR, "Unsupported mbpf %d, max %d\n", + NUM_MBS_PER_FRAME(input_width, input_height), + mbpf_max); + rc = -ENOTSUPP; + } + } + if (rc) { + dprintk(VIDC_ERR, + "%s: Resolution unsupported\n", __func__); + } + return rc; +} + +void msm_comm_generate_session_error(struct msm_vidc_inst *inst) +{ + enum hal_command_response cmd = HAL_SESSION_ERROR; + struct msm_vidc_cb_cmd_done response = {0}; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); + return; + } + dprintk(VIDC_WARN, "%s: inst %pK\n", __func__, inst); + response.session_id = inst; + response.status = VIDC_ERR_FAIL; + handle_session_error(cmd, (void *)&response); +} + +void msm_comm_generate_sys_error(struct msm_vidc_inst *inst) +{ + struct msm_vidc_core *core; + enum hal_command_response cmd = HAL_SYS_ERROR; + struct msm_vidc_cb_cmd_done response = {0}; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); + return; + } + dprintk(VIDC_WARN, "%s: inst %pK\n", __func__, inst); + core = inst->core; + response.device_id = (u32) core->id; + handle_sys_error(cmd, (void *) &response); + +} + +int msm_comm_kill_session(struct msm_vidc_inst *inst) +{ + int rc = 0; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); + return -EINVAL; + } else if (!inst->session) { + dprintk(VIDC_ERR, "%s: no session to kill for inst %pK\n", + __func__, inst); + return 0; + } + + dprintk(VIDC_ERR, "%s: inst %pK, session %x state %d\n", __func__, + inst, hash32_ptr(inst->session), inst->state); + /* + * We're internally forcibly killing the session, if fw is aware of + * the session send session_abort to firmware to clean up and release + * the session, else just kill the session inside the driver. + */ + if ((inst->state >= MSM_VIDC_OPEN_DONE && + inst->state < MSM_VIDC_CLOSE_DONE) || + inst->state == MSM_VIDC_CORE_INVALID) { + rc = msm_comm_session_abort(inst); + if (rc) { + dprintk(VIDC_ERR, + "%s: inst %pK session %x abort failed\n", + __func__, inst, hash32_ptr(inst->session)); + change_inst_state(inst, MSM_VIDC_CORE_INVALID); + } + } + + change_inst_state(inst, MSM_VIDC_CLOSE_DONE); + msm_comm_session_clean(inst); + + dprintk(VIDC_WARN, "%s: inst %pK session %x handled\n", __func__, + inst, hash32_ptr(inst->session)); + return rc; +} + +int msm_comm_smem_alloc(struct msm_vidc_inst *inst, + size_t size, u32 align, u32 flags, enum hal_buffer buffer_type, + int map_kernel, struct msm_smem *smem) +{ + int rc = 0; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst); + return -EINVAL; + } + rc = msm_smem_alloc(size, align, flags, buffer_type, map_kernel, + &(inst->core->resources), inst->session_type, + smem); + return rc; +} + +void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *mem) +{ + if (!inst || !inst->core || !mem) { + dprintk(VIDC_ERR, + "%s: invalid params: %pK %pK\n", __func__, inst, mem); + return; + } + msm_smem_free(mem); +} + +void msm_vidc_fw_unload_handler(struct work_struct *work) +{ + struct msm_vidc_core *core = NULL; + struct hfi_device *hdev = NULL; + int rc = 0; + + core = container_of(work, struct msm_vidc_core, fw_unload_work.work); + if (!core || !core->device) { + dprintk(VIDC_ERR, "%s - invalid work or core handle\n", + __func__); + return; + } + + hdev = core->device; + + mutex_lock(&core->lock); + if (list_empty(&core->instances) && + core->state != VIDC_CORE_UNINIT) { + if (core->state > VIDC_CORE_INIT) { + dprintk(VIDC_DBG, "Calling vidc_hal_core_release\n"); + rc = call_hfi_op(hdev, core_release, + hdev->hfi_device_data); + if (rc) { + dprintk(VIDC_ERR, + "Failed to release core, id = %d\n", + core->id); + mutex_unlock(&core->lock); + return; + } + } + core->state = VIDC_CORE_UNINIT; + kfree(core->capabilities); + core->capabilities = NULL; + } + mutex_unlock(&core->lock); +} + +int msm_comm_set_color_format(struct msm_vidc_inst *inst, + enum hal_buffer buffer_type, int fourcc) +{ + struct hfi_uncompressed_format_select hfi_fmt = {0}; + u32 format = HFI_COLOR_FORMAT_NV12_UBWC; + int rc = 0; + struct hfi_device *hdev; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s - invalid param\n", __func__); + return -EINVAL; + } + + hdev = inst->core->device; + + format = msm_comm_get_hfi_uncompressed(fourcc); + hfi_fmt.buffer_type = get_hfi_buffer(buffer_type); + hfi_fmt.format = format; + + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT, &hfi_fmt, + sizeof(hfi_fmt)); + if (rc) + dprintk(VIDC_ERR, + "Failed to set input color format\n"); + else + dprintk(VIDC_DBG, "Setting uncompressed colorformat to %#x\n", + format); + + return rc; +} + +void msm_comm_print_inst_info(struct msm_vidc_inst *inst) +{ + struct msm_vidc_buffer *mbuf; + struct internal_buf *buf; + bool is_decode = false; + enum vidc_ports port; + bool is_secure = false; + struct v4l2_format *f; + + if (!inst) { + dprintk(VIDC_ERR, "%s - invalid param %pK\n", + __func__, inst); + return; + } + + is_decode = inst->session_type == MSM_VIDC_DECODER; + port = is_decode ? INPUT_PORT : OUTPUT_PORT; + is_secure = inst->flags & VIDC_SECURE; + f = &inst->fmts[port].v4l2_fmt; + dprintk(VIDC_ERR, + "%s session, %s, Codec type: %s HxW: %d x %d fps: %d bitrate: %d bit-depth: %s\n", + is_decode ? "Decode" : "Encode", + is_secure ? "Secure" : "Non-Secure", + inst->fmts[port].name, + f->fmt.pix_mp.height, f->fmt.pix_mp.width, + inst->clk_data.frame_rate >> 16, inst->prop.bitrate, + !inst->bit_depth ? "8" : "10"); + + dprintk(VIDC_ERR, + "---Buffer details for inst: %pK of type: %d---\n", + inst, inst->session_type); + mutex_lock(&inst->registeredbufs.lock); + dprintk(VIDC_ERR, "registered buffer list:\n"); + list_for_each_entry(mbuf, &inst->registeredbufs.list, list) + print_vidc_buffer(VIDC_ERR, "buf", inst, mbuf); + mutex_unlock(&inst->registeredbufs.lock); + + mutex_lock(&inst->scratchbufs.lock); + dprintk(VIDC_ERR, "scratch buffer list:\n"); + list_for_each_entry(buf, &inst->scratchbufs.list, list) + dprintk(VIDC_ERR, "type: %d addr: %x size: %u\n", + buf->buffer_type, buf->smem.device_addr, + buf->smem.size); + mutex_unlock(&inst->scratchbufs.lock); + + mutex_lock(&inst->persistbufs.lock); + dprintk(VIDC_ERR, "persist buffer list:\n"); + list_for_each_entry(buf, &inst->persistbufs.list, list) + dprintk(VIDC_ERR, "type: %d addr: %x size: %u\n", + buf->buffer_type, buf->smem.device_addr, + buf->smem.size); + mutex_unlock(&inst->persistbufs.lock); + + mutex_lock(&inst->outputbufs.lock); + dprintk(VIDC_ERR, "dpb buffer list:\n"); + list_for_each_entry(buf, &inst->outputbufs.list, list) + dprintk(VIDC_ERR, "type: %d addr: %x size: %u\n", + buf->buffer_type, buf->smem.device_addr, + buf->smem.size); + mutex_unlock(&inst->outputbufs.lock); +} + +int msm_comm_session_continue(void *instance) +{ + struct msm_vidc_inst *inst = instance; + int rc = 0; + struct hfi_device *hdev; + struct v4l2_format *f; + + if (!inst || !inst->core || !inst->core->device) + return -EINVAL; + hdev = inst->core->device; + mutex_lock(&inst->lock); + if (inst->state >= MSM_VIDC_RELEASE_RESOURCES_DONE || + inst->state < MSM_VIDC_START_DONE) { + dprintk(VIDC_DBG, + "Inst %pK : Not in valid state to call %s\n", + inst, __func__); + goto sess_continue_fail; + } + if (inst->session_type == MSM_VIDC_DECODER && inst->in_reconfig) { + dprintk(VIDC_DBG, "send session_continue\n"); + rc = call_hfi_op(hdev, session_continue, + (void *)inst->session); + if (rc) { + dprintk(VIDC_ERR, + "failed to send session_continue\n"); + rc = -EINVAL; + goto sess_continue_fail; + } + inst->in_reconfig = false; + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + f->fmt.pix_mp.height = inst->reconfig_height; + f->fmt.pix_mp.width = inst->reconfig_width; + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + f->fmt.pix_mp.height = inst->reconfig_height; + f->fmt.pix_mp.width = inst->reconfig_width; + if (msm_comm_get_stream_output_mode(inst) == + HAL_VIDEO_DECODER_SECONDARY) { + rc = msm_comm_queue_dpb_only_buffers(inst); + if (rc) { + dprintk(VIDC_ERR, + "Failed to queue output buffers: %d\n", + rc); + goto sess_continue_fail; + } + } + } else if (inst->session_type == MSM_VIDC_ENCODER) { + dprintk(VIDC_DBG, + "session_continue not supported for encoder"); + } else { + dprintk(VIDC_ERR, + "session_continue called in wrong state for decoder"); + } + +sess_continue_fail: + mutex_unlock(&inst->lock); + return rc; +} + +void print_vidc_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf) +{ + struct vb2_buffer *vb2 = NULL; + + if (!(tag & msm_vidc_debug) || !inst || !mbuf) + return; + + vb2 = &mbuf->vvb.vb2_buf; + + if (vb2->num_planes == 1) + dprintk(tag, + "%s: %s: %x : idx %2d fd %d off %d daddr %x size %d filled %d flags 0x%x ts %lld refcnt %d mflags 0x%x\n", + str, vb2->type == INPUT_MPLANE ? + "OUTPUT" : "CAPTURE", hash32_ptr(inst->session), + vb2->index, vb2->planes[0].m.fd, + vb2->planes[0].data_offset, mbuf->smem[0].device_addr, + vb2->planes[0].length, vb2->planes[0].bytesused, + mbuf->vvb.flags, mbuf->vvb.vb2_buf.timestamp, + mbuf->smem[0].refcount, mbuf->flags); + else + dprintk(tag, + "%s: %s: %x : idx %2d fd %d off %d daddr %x size %d filled %d flags 0x%x ts %lld refcnt %d mflags 0x%x, extradata: fd %d off %d daddr %x size %d filled %d refcnt %d\n", + str, vb2->type == INPUT_MPLANE ? + "OUTPUT" : "CAPTURE", hash32_ptr(inst->session), + vb2->index, vb2->planes[0].m.fd, + vb2->planes[0].data_offset, mbuf->smem[0].device_addr, + vb2->planes[0].length, vb2->planes[0].bytesused, + mbuf->vvb.flags, mbuf->vvb.vb2_buf.timestamp, + mbuf->smem[0].refcount, mbuf->flags, + vb2->planes[1].m.fd, vb2->planes[1].data_offset, + mbuf->smem[1].device_addr, vb2->planes[1].length, + vb2->planes[1].bytesused, mbuf->smem[1].refcount); +} + +void print_vb2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, + struct vb2_buffer *vb2) +{ + if (!(tag & msm_vidc_debug) || !inst || !vb2) + return; + + if (vb2->num_planes == 1) + dprintk(tag, + "%s: %s: %x : idx %2d fd %d off %d size %d filled %d\n", + str, vb2->type == INPUT_MPLANE ? + "OUTPUT" : "CAPTURE", hash32_ptr(inst->session), + vb2->index, vb2->planes[0].m.fd, + vb2->planes[0].data_offset, vb2->planes[0].length, + vb2->planes[0].bytesused); + else + dprintk(tag, + "%s: %s: %x : idx %2d fd %d off %d size %d filled %d, extradata: fd %d off %d size %d filled %d\n", + str, vb2->type == INPUT_MPLANE ? + "OUTPUT" : "CAPTURE", hash32_ptr(inst->session), + vb2->index, vb2->planes[0].m.fd, + vb2->planes[0].data_offset, vb2->planes[0].length, + vb2->planes[0].bytesused, vb2->planes[1].m.fd, + vb2->planes[1].data_offset, vb2->planes[1].length, + vb2->planes[1].bytesused); +} + +void print_v4l2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, + struct v4l2_buffer *v4l2) +{ + if (!(tag & msm_vidc_debug) || !inst || !v4l2) + return; + + if (v4l2->length == 1) + dprintk(tag, + "%s: %s: %x : idx %2d fd %d off %d size %d filled %d\n", + str, v4l2->type == INPUT_MPLANE ? + "OUTPUT" : "CAPTURE", hash32_ptr(inst->session), + v4l2->index, v4l2->m.planes[0].m.fd, + v4l2->m.planes[0].data_offset, + v4l2->m.planes[0].length, + v4l2->m.planes[0].bytesused); + else + dprintk(tag, + "%s: %s: %x : idx %2d fd %d off %d size %d filled %d, extradata: fd %d off %d size %d filled %d\n", + str, v4l2->type == INPUT_MPLANE ? + "OUTPUT" : "CAPTURE", hash32_ptr(inst->session), + v4l2->index, v4l2->m.planes[0].m.fd, + v4l2->m.planes[0].data_offset, + v4l2->m.planes[0].length, + v4l2->m.planes[0].bytesused, + v4l2->m.planes[1].m.fd, + v4l2->m.planes[1].data_offset, + v4l2->m.planes[1].length, + v4l2->m.planes[1].bytesused); +} + +bool msm_comm_compare_vb2_plane(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf, struct vb2_buffer *vb2, u32 i) +{ + struct vb2_buffer *vb; + + if (!inst || !mbuf || !vb2) { + dprintk(VIDC_ERR, "%s: invalid params, %pK %pK %pK\n", + __func__, inst, mbuf, vb2); + return false; + } + + vb = &mbuf->vvb.vb2_buf; + if (vb->planes[i].m.fd == vb2->planes[i].m.fd && + vb->planes[i].length == vb2->planes[i].length) { + return true; + } + + return false; +} + +bool msm_comm_compare_vb2_planes(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf, struct vb2_buffer *vb2) +{ + unsigned int i = 0; + struct vb2_buffer *vb; + + if (!inst || !mbuf || !vb2) { + dprintk(VIDC_ERR, "%s: invalid params, %pK %pK %pK\n", + __func__, inst, mbuf, vb2); + return false; + } + + vb = &mbuf->vvb.vb2_buf; + + if (vb->num_planes != vb2->num_planes) + return false; + + for (i = 0; i < vb->num_planes; i++) { + if (!msm_comm_compare_vb2_plane(inst, mbuf, vb2, i)) + return false; + } + + return true; +} + +bool msm_comm_compare_dma_plane(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf, unsigned long *dma_planes, u32 i) +{ + if (!inst || !mbuf || !dma_planes) { + dprintk(VIDC_ERR, "%s: invalid params, %pK %pK %pK\n", + __func__, inst, mbuf, dma_planes); + return false; + } + + if ((unsigned long)mbuf->smem[i].dma_buf == dma_planes[i]) + return true; + + return false; +} + +bool msm_comm_compare_dma_planes(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf, unsigned long *dma_planes) +{ + unsigned int i = 0; + struct vb2_buffer *vb; + + if (!inst || !mbuf || !dma_planes) { + dprintk(VIDC_ERR, "%s: invalid params, %pK %pK %pK\n", + __func__, inst, mbuf, dma_planes); + return false; + } + + vb = &mbuf->vvb.vb2_buf; + for (i = 0; i < vb->num_planes; i++) { + if (!msm_comm_compare_dma_plane(inst, mbuf, dma_planes, i)) + return false; + } + + return true; +} + + +bool msm_comm_compare_device_plane(struct msm_vidc_buffer *mbuf, + u32 type, u32 *planes, u32 i) +{ + if (!mbuf || !planes) { + dprintk(VIDC_ERR, "%s: invalid params, %pK %pK\n", + __func__, mbuf, planes); + return false; + } + + if (mbuf->vvb.vb2_buf.type == type && + mbuf->smem[i].device_addr == planes[i]) + return true; + + return false; +} + +bool msm_comm_compare_device_planes(struct msm_vidc_buffer *mbuf, + u32 type, u32 *planes) +{ + unsigned int i = 0; + + if (!mbuf || !planes) + return false; + + for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) { + if (!msm_comm_compare_device_plane(mbuf, type, planes, i)) + return false; + } + + return true; +} + +struct msm_vidc_buffer *msm_comm_get_buffer_using_device_planes( + struct msm_vidc_inst *inst, u32 type, u32 *planes) +{ + struct msm_vidc_buffer *mbuf; + bool found = false; + + mutex_lock(&inst->registeredbufs.lock); + found = false; + list_for_each_entry(mbuf, &inst->registeredbufs.list, list) { + if (msm_comm_compare_device_planes(mbuf, type, planes)) { + found = true; + break; + } + } + mutex_unlock(&inst->registeredbufs.lock); + if (!found) { + dprintk(VIDC_ERR, + "%s: data_addr %x, extradata_addr %x not found\n", + __func__, planes[0], planes[1]); + mbuf = NULL; + } + + return mbuf; +} + +int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf) +{ + struct vb2_buffer *vb; + u32 port; + + if (!inst || !mbuf) { + dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", + __func__, inst, mbuf); + return -EINVAL; + } + + vb = msm_comm_get_vb_using_vidc_buffer(inst, mbuf); + if (!vb) { + print_vidc_buffer(VIDC_ERR, + "vb not found for buf", inst, mbuf); + return -EINVAL; + } + + if (mbuf->vvb.vb2_buf.type == OUTPUT_MPLANE) + port = OUTPUT_PORT; + else if (mbuf->vvb.vb2_buf.type == INPUT_MPLANE) + port = INPUT_PORT; + else + return -EINVAL; + + mutex_lock(&inst->bufq[port].lock); + if (inst->bufq[port].vb2_bufq.streaming) { + vb->planes[0].bytesused = 0; + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); + } else { + dprintk(VIDC_ERR, "%s: port %d is not streaming\n", + __func__, port); + } + mutex_unlock(&inst->bufq[port].lock); + + return 0; +} + +int msm_comm_qbuf_cache_operations(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf) +{ + int rc = 0; + unsigned int i; + struct vb2_buffer *vb; + bool skip; + + if (!inst || !mbuf) { + dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", + __func__, inst, mbuf); + return -EINVAL; + } + vb = &mbuf->vvb.vb2_buf; + + for (i = 0; i < vb->num_planes; i++) { + unsigned long offset, size; + enum smem_cache_ops cache_op; + + skip = true; + if (inst->session_type == MSM_VIDC_DECODER) { + if (vb->type == INPUT_MPLANE) { + if (!i) { /* bitstream */ + skip = false; + offset = vb->planes[i].data_offset; + size = vb->planes[i].bytesused; + cache_op = SMEM_CACHE_CLEAN_INVALIDATE; + } + } else if (vb->type == OUTPUT_MPLANE) { + if (!i) { /* yuv */ + skip = false; + offset = 0; + size = vb->planes[i].length; + cache_op = SMEM_CACHE_INVALIDATE; + } + } + } else if (inst->session_type == MSM_VIDC_ENCODER) { + if (vb->type == INPUT_MPLANE) { + if (!i) { /* yuv */ + skip = false; + offset = vb->planes[i].data_offset; + size = vb->planes[i].bytesused; + cache_op = SMEM_CACHE_CLEAN_INVALIDATE; + } + } else if (vb->type == OUTPUT_MPLANE) { + if (!i) { /* bitstream */ + u32 size_u32; + skip = false; + offset = 0; + size_u32 = vb->planes[i].length; + msm_comm_fetch_filled_length( + &inst->fbd_data, vb->index, + &size_u32); + size = size_u32; + cache_op = SMEM_CACHE_INVALIDATE; + } + } + } + + if (!skip) { + rc = msm_smem_cache_operations(mbuf->smem[i].dma_buf, + cache_op, offset, size); + if (rc) + print_vidc_buffer(VIDC_ERR, + "qbuf cache ops failed", inst, mbuf); + } + } + + return rc; +} + +int msm_comm_dqbuf_cache_operations(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf) +{ + int rc = 0; + unsigned int i; + struct vb2_buffer *vb; + bool skip; + + if (!inst || !mbuf) { + dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", + __func__, inst, mbuf); + return -EINVAL; + } + vb = &mbuf->vvb.vb2_buf; + + for (i = 0; i < vb->num_planes; i++) { + unsigned long offset, size; + enum smem_cache_ops cache_op; + + skip = true; + if (inst->session_type == MSM_VIDC_DECODER) { + if (vb->type == INPUT_MPLANE) { + /* bitstream and extradata */ + /* we do not need cache operations */ + } else if (vb->type == OUTPUT_MPLANE) { + if (!i) { /* yuv */ + skip = false; + offset = vb->planes[i].data_offset; + size = vb->planes[i].bytesused; + cache_op = SMEM_CACHE_INVALIDATE; + } + } + } else if (inst->session_type == MSM_VIDC_ENCODER) { + if (vb->type == INPUT_MPLANE) { + /* yuv and extradata */ + /* we do not need cache operations */ + } else if (vb->type == OUTPUT_MPLANE) { + if (!i) { /* bitstream */ + skip = false; + /* + * Include vp8e header bytes as well + * by making offset equal to zero + */ + offset = 0; + size = vb->planes[i].bytesused + + vb->planes[i].data_offset; + cache_op = SMEM_CACHE_INVALIDATE; + } + } + } + + if (!skip) { + rc = msm_smem_cache_operations(mbuf->smem[i].dma_buf, + cache_op, offset, size); + if (rc) + print_vidc_buffer(VIDC_ERR, + "dqbuf cache ops failed", inst, mbuf); + } + } + + return rc; +} + +struct msm_vidc_buffer *msm_comm_get_vidc_buffer(struct msm_vidc_inst *inst, + struct vb2_buffer *vb2) +{ + int rc = 0; + struct vb2_v4l2_buffer *vbuf; + struct vb2_buffer *vb; + unsigned long dma_planes[VB2_MAX_PLANES] = {0}; + struct msm_vidc_buffer *mbuf; + bool found = false; + unsigned int i; + + if (!inst || !vb2) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return NULL; + } + + for (i = 0; i < vb2->num_planes; i++) { + /* + * always compare dma_buf addresses which is guaranteed + * to be same across the processes (duplicate fds). + */ + dma_planes[i] = (unsigned long)msm_smem_get_dma_buf( + vb2->planes[i].m.fd); + if (!dma_planes[i]) + return NULL; + msm_smem_put_dma_buf((struct dma_buf *)dma_planes[i]); + } + + mutex_lock(&inst->registeredbufs.lock); + /* + * for encoder input, client may queue the same buffer with different + * fd before driver returned old buffer to the client. This buffer + * should be treated as new buffer Search the list with fd so that + * it will be treated as new msm_vidc_buffer. + */ + if (is_encode_session(inst) && vb2->type == INPUT_MPLANE) { + list_for_each_entry(mbuf, &inst->registeredbufs.list, list) { + if (msm_comm_compare_vb2_planes(inst, mbuf, vb2)) { + found = true; + break; + } + } + } else { + list_for_each_entry(mbuf, &inst->registeredbufs.list, list) { + if (msm_comm_compare_dma_planes(inst, mbuf, + dma_planes)) { + found = true; + break; + } + } + } + + if (!found) { + /* this is new vb2_buffer */ + mbuf = kzalloc(sizeof(struct msm_vidc_buffer), GFP_KERNEL); + if (!mbuf) { + dprintk(VIDC_ERR, "%s: alloc msm_vidc_buffer failed\n", + __func__); + rc = -ENOMEM; + goto exit; + } + kref_init(&mbuf->kref); + } + + /* Initially assume all the buffer are going to be deferred */ + mbuf->flags |= MSM_VIDC_FLAG_DEFERRED; + + vbuf = to_vb2_v4l2_buffer(vb2); + memcpy(&mbuf->vvb, vbuf, sizeof(struct vb2_v4l2_buffer)); + vb = &mbuf->vvb.vb2_buf; + + for (i = 0; i < vb->num_planes; i++) { + mbuf->smem[i].buffer_type = get_hal_buffer_type(vb->type, i); + mbuf->smem[i].fd = vb->planes[i].m.fd; + mbuf->smem[i].offset = vb->planes[i].data_offset; + mbuf->smem[i].size = vb->planes[i].length; + rc = inst->smem_ops->smem_map_dma_buf(inst, &mbuf->smem[i]); + if (rc) { + dprintk(VIDC_ERR, "%s: map failed.\n", __func__); + goto exit; + } + /* increase refcount as we get both fbd and rbr */ + rc = inst->smem_ops->smem_map_dma_buf(inst, &mbuf->smem[i]); + if (rc) { + dprintk(VIDC_ERR, "%s: map failed..\n", __func__); + goto exit; + } + } + /* dma cache operations need to be performed after dma_map */ + msm_comm_qbuf_cache_operations(inst, mbuf); + + /* special handling for decoder */ + if (inst->session_type == MSM_VIDC_DECODER) { + if (found) { + rc = -EEXIST; + } else { + bool found_plane0 = false; + struct msm_vidc_buffer *temp; + /* + * client might have queued same plane[0] but different + * plane[1] search plane[0] and if found don't queue the + * buffer, the buffer will be queued when rbr event + * arrived. + */ + list_for_each_entry(temp, &inst->registeredbufs.list, + list) { + if (msm_comm_compare_dma_plane(inst, temp, + dma_planes, 0)) { + found_plane0 = true; + break; + } + } + if (found_plane0) + rc = -EEXIST; + } + if (rc == -EEXIST) { + print_vidc_buffer(VIDC_DBG, + "existing qbuf", inst, mbuf); + /* enable RBR pending */ + mbuf->flags |= MSM_VIDC_FLAG_RBR_PENDING; + } + } + + /* add the new buffer to list */ + if (!found) + list_add_tail(&mbuf->list, &inst->registeredbufs.list); + + mutex_unlock(&inst->registeredbufs.lock); + + /* + * Return mbuf if decode batching is enabled as this buffer + * may trigger queuing full batch to firmware, also this buffer + * will not be queued to firmware while full batch queuing, + * it will be queued when rbr event arrived from firmware. + */ + if (rc == -EEXIST && !inst->batch.enable) + return ERR_PTR(rc); + + return mbuf; + +exit: + dprintk(VIDC_ERR, "%s: rc %d\n", __func__, rc); + msm_comm_unmap_vidc_buffer(inst, mbuf); + if (!found) + kref_put_mbuf(mbuf); + mutex_unlock(&inst->registeredbufs.lock); + + return ERR_PTR(rc); +} + +void msm_comm_put_vidc_buffer(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf) +{ + struct msm_vidc_buffer *temp; + bool found = false; + unsigned int i = 0; + + if (!inst || !mbuf) { + dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", + __func__, inst, mbuf); + return; + } + + mutex_lock(&inst->registeredbufs.lock); + /* check if mbuf was not removed by any chance */ + list_for_each_entry(temp, &inst->registeredbufs.list, list) { + if (msm_comm_compare_vb2_planes(inst, mbuf, + &temp->vvb.vb2_buf)) { + found = true; + break; + } + } + if (!found) { + print_vidc_buffer(VIDC_ERR, "buf was removed", inst, mbuf); + goto unlock; + } + + print_vidc_buffer(VIDC_DBG, "dqbuf", inst, mbuf); + for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) { + if (inst->smem_ops->smem_unmap_dma_buf(inst, &mbuf->smem[i])) + print_vidc_buffer(VIDC_ERR, + "dqbuf: unmap failed.", inst, mbuf); + + if (!(mbuf->vvb.flags & V4L2_BUF_FLAG_READONLY)) { + /* rbr won't come for this buffer */ + if (inst->smem_ops->smem_unmap_dma_buf(inst, + &mbuf->smem[i])) + print_vidc_buffer(VIDC_ERR, + "dqbuf: unmap failed..", inst, mbuf); + } else { + /* RBR event expected */ + mbuf->flags |= MSM_VIDC_FLAG_RBR_PENDING; + } + } + /* + * remove the entry if plane[0].refcount is zero else + * don't remove as client queued same buffer that's why + * plane[0].refcount is not zero + */ + if (!mbuf->smem[0].refcount) { + list_del(&mbuf->list); + kref_put_mbuf(mbuf); + } +unlock: + mutex_unlock(&inst->registeredbufs.lock); +} + +void handle_release_buffer_reference(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf) +{ + int rc = 0; + struct msm_vidc_buffer *temp; + bool found = false; + unsigned int i = 0; + u32 planes[VIDEO_MAX_PLANES] = {0}; + + mutex_lock(&inst->flush_lock); + mutex_lock(&inst->registeredbufs.lock); + found = false; + /* check if mbuf was not removed by any chance */ + list_for_each_entry(temp, &inst->registeredbufs.list, list) { + if (msm_comm_compare_vb2_planes(inst, mbuf, + &temp->vvb.vb2_buf)) { + found = true; + break; + } + } + if (found) { + /* save device_addr */ + for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) + planes[i] = mbuf->smem[i].device_addr; + + /* send RBR event to client */ + msm_vidc_queue_rbr_event(inst, + mbuf->vvb.vb2_buf.planes[0].m.fd, + mbuf->vvb.vb2_buf.planes[0].data_offset); + + /* clear RBR_PENDING flag */ + mbuf->flags &= ~MSM_VIDC_FLAG_RBR_PENDING; + + for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) { + if (inst->smem_ops->smem_unmap_dma_buf(inst, + &mbuf->smem[i])) + print_vidc_buffer(VIDC_ERR, + "rbr unmap failed.", inst, mbuf); + } + /* refcount is not zero if client queued the same buffer */ + if (!mbuf->smem[0].refcount) { + list_del(&mbuf->list); + kref_put_mbuf(mbuf); + mbuf = NULL; + } + } else { + print_vidc_buffer(VIDC_ERR, "mbuf not found", inst, mbuf); + goto unlock; + } + + /* + * 1. client might have pushed same planes in which case mbuf will be + * same and refcounts are positive and buffer wouldn't have been + * removed from the registeredbufs list. + * 2. client might have pushed same planes[0] but different planes[1] + * in which case mbuf will be different. + * 3. in either case we can search mbuf->smem[0].device_addr in the list + * and if found queue it to video hw (if not flushing). + */ + found = false; + list_for_each_entry(temp, &inst->registeredbufs.list, list) { + if (msm_comm_compare_device_plane(temp, + OUTPUT_MPLANE, planes, 0)) { + mbuf = temp; + found = true; + break; + } + } + if (!found) + goto unlock; + + /* buffer found means client queued the buffer already */ + if (inst->in_reconfig || inst->in_flush) { + print_vidc_buffer(VIDC_DBG, "rbr flush buf", inst, mbuf); + msm_comm_flush_vidc_buffer(inst, mbuf); + msm_comm_unmap_vidc_buffer(inst, mbuf); + /* remove from list */ + list_del(&mbuf->list); + kref_put_mbuf(mbuf); + + /* don't queue the buffer */ + found = false; + } + /* clear required flags as the buffer is going to be queued */ + if (found) { + mbuf->flags &= ~MSM_VIDC_FLAG_DEFERRED; + mbuf->flags &= ~MSM_VIDC_FLAG_RBR_PENDING; + } + +unlock: + mutex_unlock(&inst->registeredbufs.lock); + + if (found) { + rc = msm_comm_qbuf_in_rbr(inst, mbuf); + if (rc) + print_vidc_buffer(VIDC_ERR, + "rbr qbuf failed", inst, mbuf); + } + mutex_unlock(&inst->flush_lock); +} + +int msm_comm_unmap_vidc_buffer(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf) +{ + int rc = 0; + unsigned int i; + + if (!inst || !mbuf) { + dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", + __func__, inst, mbuf); + return -EINVAL; + } + if (mbuf->vvb.vb2_buf.num_planes > VIDEO_MAX_PLANES) { + dprintk(VIDC_ERR, "%s: invalid num_planes %d\n", __func__, + mbuf->vvb.vb2_buf.num_planes); + return -EINVAL; + } + + for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) { + u32 refcount = mbuf->smem[i].refcount; + + while (refcount) { + if (inst->smem_ops->smem_unmap_dma_buf(inst, + &mbuf->smem[i])) + print_vidc_buffer(VIDC_ERR, + "unmap failed for buf", inst, mbuf); + refcount--; + } + } + + return rc; +} + +static void kref_free_mbuf(struct kref *kref) +{ + struct msm_vidc_buffer *mbuf = container_of(kref, + struct msm_vidc_buffer, kref); + + kfree(mbuf); +} + +void kref_put_mbuf(struct msm_vidc_buffer *mbuf) +{ + if (!mbuf) + return; + + kref_put(&mbuf->kref, kref_free_mbuf); +} + +bool kref_get_mbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) +{ + struct msm_vidc_buffer *temp; + bool matches = false; + bool ret = false; + + if (!inst || !mbuf) + return false; + + mutex_lock(&inst->registeredbufs.lock); + list_for_each_entry(temp, &inst->registeredbufs.list, list) { + if (temp == mbuf) { + matches = true; + break; + } + } + ret = (matches && kref_get_unless_zero(&mbuf->kref)) ? true : false; + mutex_unlock(&inst->registeredbufs.lock); + + return ret; +} + +void msm_comm_store_filled_length(struct msm_vidc_list *data_list, + u32 index, u32 filled_length) +{ + struct msm_vidc_buf_data *pdata = NULL; + bool found = false; + + if (!data_list) { + dprintk(VIDC_ERR, "%s: invalid params %pK\n", + __func__, data_list); + return; + } + + mutex_lock(&data_list->lock); + list_for_each_entry(pdata, &data_list->list, list) { + if (pdata->index == index) { + pdata->filled_length = filled_length; + found = true; + break; + } + } + + if (!found) { + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + dprintk(VIDC_WARN, "%s: malloc failure.\n", __func__); + goto exit; + } + pdata->index = index; + pdata->filled_length = filled_length; + list_add_tail(&pdata->list, &data_list->list); + } + +exit: + mutex_unlock(&data_list->lock); +} + +void msm_comm_fetch_filled_length(struct msm_vidc_list *data_list, + u32 index, u32 *filled_length) +{ + struct msm_vidc_buf_data *pdata = NULL; + + if (!data_list || !filled_length) { + dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", + __func__, data_list, filled_length); + return; + } + + mutex_lock(&data_list->lock); + list_for_each_entry(pdata, &data_list->list, list) { + if (pdata->index == index) { + *filled_length = pdata->filled_length; + break; + } + } + mutex_unlock(&data_list->lock); +} + +void msm_comm_store_mark_data(struct msm_vidc_list *data_list, + u32 index, u32 mark_data, u32 mark_target) +{ + struct msm_vidc_buf_data *pdata = NULL; + bool found = false; + + if (!data_list) { + dprintk(VIDC_ERR, "%s: invalid params %pK\n", + __func__, data_list); + return; + } + + mutex_lock(&data_list->lock); + list_for_each_entry(pdata, &data_list->list, list) { + if (pdata->index == index) { + pdata->mark_data = mark_data; + pdata->mark_target = mark_target; + found = true; + break; + } + } + + if (!found) { + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + dprintk(VIDC_WARN, "%s: malloc failure.\n", __func__); + goto exit; + } + pdata->index = index; + pdata->mark_data = mark_data; + pdata->mark_target = mark_target; + list_add_tail(&pdata->list, &data_list->list); + } + +exit: + mutex_unlock(&data_list->lock); +} + +void msm_comm_fetch_mark_data(struct msm_vidc_list *data_list, + u32 index, u32 *mark_data, u32 *mark_target) +{ + struct msm_vidc_buf_data *pdata = NULL; + + if (!data_list || !mark_data || !mark_target) { + dprintk(VIDC_ERR, "%s: invalid params %pK %pK %pK\n", + __func__, data_list, mark_data, mark_target); + return; + } + + *mark_data = *mark_target = 0; + mutex_lock(&data_list->lock); + list_for_each_entry(pdata, &data_list->list, list) { + if (pdata->index == index) { + *mark_data = pdata->mark_data; + *mark_target = pdata->mark_target; + /* clear after fetch */ + pdata->mark_data = pdata->mark_target = 0; + break; + } + } + mutex_unlock(&data_list->lock); +} + +int msm_comm_release_mark_data(struct msm_vidc_inst *inst) +{ + struct msm_vidc_buf_data *pdata, *next; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params %pK\n", + __func__, inst); + return -EINVAL; + } + + mutex_lock(&inst->etb_data.lock); + list_for_each_entry_safe(pdata, next, &inst->etb_data.list, list) { + list_del(&pdata->list); + kfree(pdata); + } + mutex_unlock(&inst->etb_data.lock); + + mutex_lock(&inst->fbd_data.lock); + list_for_each_entry_safe(pdata, next, &inst->fbd_data.list, list) { + list_del(&pdata->list); + kfree(pdata); + } + mutex_unlock(&inst->fbd_data.lock); + + return 0; +} + +int msm_comm_set_color_format_constraints(struct msm_vidc_inst *inst, + enum hal_buffer buffer_type, + struct msm_vidc_format_constraint *pix_constraint) +{ + struct hfi_uncompressed_plane_actual_constraints_info + *pconstraint = NULL; + u32 num_planes = 2; + u32 size = 0; + int rc = 0; + struct hfi_device *hdev; + u32 hfi_fmt; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s - invalid param\n", __func__); + return -EINVAL; + } + + hdev = inst->core->device; + + size = 2 * sizeof(u32) + + num_planes + * sizeof(struct hfi_uncompressed_plane_constraints); + + pconstraint = kzalloc(size, GFP_KERNEL); + if (!pconstraint) { + dprintk(VIDC_ERR, "No memory cannot alloc constrain\n"); + rc = -ENOMEM; + goto exit; + } + + hfi_fmt = msm_comm_convert_color_fmt(pix_constraint->fourcc); + pconstraint->buffer_type = get_hfi_buffer(buffer_type); + pconstraint->num_planes = pix_constraint->num_planes; + //set Y plan constraints + dprintk(VIDC_INFO, "Set Y plan constraints.\n"); + pconstraint->rg_plane_format[0].stride_multiples = + VENUS_Y_STRIDE(hfi_fmt, 1); + pconstraint->rg_plane_format[0].max_stride = + pix_constraint->y_max_stride; + pconstraint->rg_plane_format[0].min_plane_buffer_height_multiple = + VENUS_Y_SCANLINES(hfi_fmt, 1); + pconstraint->rg_plane_format[0].buffer_alignment = + pix_constraint->y_buffer_alignment; + + //set UV plan constraints + dprintk(VIDC_INFO, "Set UV plan constraints.\n"); + pconstraint->rg_plane_format[1].stride_multiples = + VENUS_UV_STRIDE(hfi_fmt, 1); + pconstraint->rg_plane_format[1].max_stride = + pix_constraint->uv_max_stride; + pconstraint->rg_plane_format[1].min_plane_buffer_height_multiple = + VENUS_UV_SCANLINES(hfi_fmt, 1); + pconstraint->rg_plane_format[1].buffer_alignment = + pix_constraint->uv_buffer_alignment; + + rc = call_hfi_op(hdev, + session_set_property, + inst->session, + HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO, + pconstraint, + size); + if (rc) + dprintk(VIDC_ERR, + "Failed to set input color format constraint\n"); + else + dprintk(VIDC_DBG, "Set color format constraint success\n"); + +exit: + if (!pconstraint) + kfree(pconstraint); + return rc; +} + +int msm_comm_set_index_extradata(struct msm_vidc_inst *inst, + uint32_t extradata_id, uint32_t value) +{ + int rc = 0; + struct hfi_index_extradata_config extradata; + struct hfi_device *hdev; + + hdev = inst->core->device; + + extradata.index_extra_data_id = extradata_id; + extradata.enable = value; + + rc = call_hfi_op(hdev, session_set_property, (void *) + inst->session, HFI_PROPERTY_PARAM_INDEX_EXTRADATA, &extradata, + sizeof(extradata)); + + return rc; +} + +int msm_comm_set_extradata(struct msm_vidc_inst *inst, + uint32_t extradata_id, uint32_t value) +{ + int rc = 0; + struct hfi_index_extradata_config extradata; + struct hfi_device *hdev; + + hdev = inst->core->device; + + extradata.index_extra_data_id = extradata_id; + extradata.enable = value; + + rc = call_hfi_op(hdev, session_set_property, (void *) + inst->session, extradata_id, &extradata, + sizeof(extradata)); + + return rc; +} + +bool msm_comm_check_for_inst_overload(struct msm_vidc_core *core) +{ + u32 instance_count = 0; + u32 secure_instance_count = 0; + struct msm_vidc_inst *inst = NULL; + bool overload = false; + + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) { + instance_count++; + if (inst->flags & VIDC_SECURE) + secure_instance_count++; + } + mutex_unlock(&core->lock); + + if (instance_count > core->resources.max_inst_count || + secure_instance_count > core->resources.max_secure_inst_count) { + overload = true; + dprintk(VIDC_ERR, + "%s: inst_count:%u max_inst:%u sec_inst_count:%u max_sec_inst:%u\n", + __func__, instance_count, + core->resources.max_inst_count, secure_instance_count, + core->resources.max_secure_inst_count); + } + return overload; +} diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h new file mode 100644 index 000000000000..a71dabc61bde --- /dev/null +++ b/msm/vidc/msm_vidc_common.h @@ -0,0 +1,283 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef _MSM_VIDC_COMMON_H_ +#define _MSM_VIDC_COMMON_H_ +#include "msm_vidc_internal.h" +#include "msm_vidc_debug.h" + +#define MAX_DEC_BATCH_SIZE 6 +#define SKIP_BATCH_WINDOW 100 +#define MIN_FRAME_QUALITY 0 +#define MAX_FRAME_QUALITY 100 +#define DEFAULT_FRAME_QUALITY 95 +#define FRAME_QUALITY_STEP 1 +#define HEIC_GRID_DIMENSION 512 +#define CBR_MB_LIMIT (((1280+15)/16)*((720+15)/16)*30) +#define CBR_VFR_MB_LIMIT (((640+15)/16)*((480+15)/16)*30) +#define V4L2_CID_MPEG_VIDEO_UNKNOWN (V4L2_CID_MPEG_MSM_VIDC_BASE + 0xFFF) + +struct vb2_buf_entry { + struct list_head list; + struct vb2_buffer *vb; +}; + +struct getprop_buf { + struct list_head list; + void *data; +}; + +enum load_calc_quirks { + LOAD_CALC_NO_QUIRKS = 0, + LOAD_CALC_IGNORE_TURBO_LOAD = 1 << 0, + LOAD_CALC_IGNORE_THUMBNAIL_LOAD = 1 << 1, + LOAD_CALC_IGNORE_NON_REALTIME_LOAD = 1 << 2, +}; + +enum client_set_controls { + CLIENT_SET_I_QP = 0x1, + CLIENT_SET_P_QP = 0x2, + CLIENT_SET_B_QP = 0x4, + CLIENT_SET_MIN_QP = 0x8, + CLIENT_SET_MAX_QP = 0x10, +}; + +static inline bool is_turbo_session(struct msm_vidc_inst *inst) +{ + return !!(inst->flags & VIDC_TURBO); +} + +static inline bool is_thumbnail_session(struct msm_vidc_inst *inst) +{ + return !!(inst->flags & VIDC_THUMBNAIL); +} + +static inline bool is_low_power_session(struct msm_vidc_inst *inst) +{ + return !!(inst->flags & VIDC_LOW_POWER); +} + +static inline struct v4l2_ctrl *get_ctrl(struct msm_vidc_inst *inst, + u32 id) +{ + int i; + + for (i = 0; i < inst->num_ctrls; i++) { + if (inst->ctrls[i]->id == id) + return inst->ctrls[i]; + } + dprintk(VIDC_ERR, "%s: control id (%#x) not found\n", __func__, id); + MSM_VIDC_ERROR(true); + return inst->ctrls[0]; +} + +static inline u32 get_v4l2_codec(struct msm_vidc_inst *inst) +{ + struct v4l2_format *f; + u32 port; + + port = (inst->session_type == MSM_VIDC_DECODER) ? INPUT_PORT : + OUTPUT_PORT; + f = &inst->fmts[port].v4l2_fmt; + return f->fmt.pix_mp.pixelformat; +} + +static inline bool is_realtime_session(struct msm_vidc_inst *inst) +{ + return !!(inst->flags & VIDC_REALTIME); +} + +static inline bool is_secure_session(struct msm_vidc_inst *inst) +{ + return !!(inst->flags & VIDC_SECURE); +} + +static inline bool is_decode_session(struct msm_vidc_inst *inst) +{ + return inst->session_type == MSM_VIDC_DECODER; +} + +static inline bool is_encode_session(struct msm_vidc_inst *inst) +{ + return inst->session_type == MSM_VIDC_ENCODER; +} + +static inline bool is_primary_output_mode(struct msm_vidc_inst *inst) +{ + return inst->stream_output_mode == HAL_VIDEO_DECODER_PRIMARY; +} + +static inline bool is_secondary_output_mode(struct msm_vidc_inst *inst) +{ + return inst->stream_output_mode == HAL_VIDEO_DECODER_SECONDARY; +} + +static inline bool in_port_reconfig(struct msm_vidc_inst *inst) +{ + return inst->in_reconfig && inst->bufq[INPUT_PORT].vb2_bufq.streaming; +} + +static inline int msm_comm_g_ctrl(struct msm_vidc_inst *inst, + struct v4l2_control *ctrl) +{ + return v4l2_g_ctrl(&inst->ctrl_handler, ctrl); +} + +static inline int msm_comm_s_ctrl(struct msm_vidc_inst *inst, + struct v4l2_control *ctrl) +{ + return v4l2_s_ctrl(NULL, &inst->ctrl_handler, ctrl); +} +bool is_batching_allowed(struct msm_vidc_inst *inst); +enum hal_buffer get_hal_buffer_type(unsigned int type, + unsigned int plane_num); +void put_inst(struct msm_vidc_inst *inst); +struct msm_vidc_inst *get_inst(struct msm_vidc_core *core, + void *session_id); +void change_inst_state(struct msm_vidc_inst *inst, enum instance_state state); +struct msm_vidc_core *get_vidc_core(int core_id); +const struct msm_vidc_format_desc *msm_comm_get_pixel_fmt_index( + const struct msm_vidc_format_desc fmt[], int size, int index); +struct msm_vidc_format_desc *msm_comm_get_pixel_fmt_fourcc( + struct msm_vidc_format_desc fmt[], int size, int fourcc); +struct msm_vidc_format_constraint *msm_comm_get_pixel_fmt_constraints( + struct msm_vidc_format_constraint fmt[], int size, int fourcc); +int msm_comm_set_color_format_constraints(struct msm_vidc_inst *inst, + enum hal_buffer buffer_type, + struct msm_vidc_format_constraint *pix_constraint); +struct buf_queue *msm_comm_get_vb2q( + struct msm_vidc_inst *inst, enum v4l2_buf_type type); +int msm_comm_try_state(struct msm_vidc_inst *inst, int state); +int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst); +int msm_comm_try_get_buff_req(struct msm_vidc_inst *inst, + union hal_get_property *hprop); +int msm_comm_set_recon_buffers(struct msm_vidc_inst *inst); +int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst); +int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst); +int msm_comm_set_buffer_count(struct msm_vidc_inst *inst, + int host_count, int act_count, enum hal_buffer type); +int msm_comm_set_dpb_only_buffers(struct msm_vidc_inst *inst); +int msm_comm_queue_dpb_only_buffers(struct msm_vidc_inst *inst); +int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); +int msm_comm_qbufs(struct msm_vidc_inst *inst); +void msm_comm_flush_dynamic_buffers(struct msm_vidc_inst *inst); +int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags); +int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst, + bool check_for_reuse); +int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst); +int msm_comm_release_recon_buffers(struct msm_vidc_inst *inst); +void msm_comm_release_eos_buffers(struct msm_vidc_inst *inst); +int msm_comm_release_dpb_only_buffers(struct msm_vidc_inst *inst, + bool force_release); +void msm_comm_validate_output_buffers(struct msm_vidc_inst *inst); +int msm_comm_force_cleanup(struct msm_vidc_inst *inst); +int msm_comm_suspend(int core_id); +struct hal_buffer_requirements *get_buff_req_buffer( + struct msm_vidc_inst *inst, u32 buffer_type); +#define IS_PRIV_CTRL(idx) (\ + (V4L2_CTRL_ID2WHICH(idx) == V4L2_CTRL_CLASS_MPEG) && \ + V4L2_CTRL_DRIVER_PRIV(idx)) +void msm_comm_session_clean(struct msm_vidc_inst *inst); +int msm_comm_kill_session(struct msm_vidc_inst *inst); +void msm_comm_generate_session_error(struct msm_vidc_inst *inst); +void msm_comm_generate_sys_error(struct msm_vidc_inst *inst); +enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst); +int msm_comm_set_stream_output_mode(struct msm_vidc_inst *inst, + enum multi_stream mode); +enum hal_buffer msm_comm_get_hal_output_buffer(struct msm_vidc_inst *inst); +int msm_comm_smem_alloc(struct msm_vidc_inst *inst, size_t size, u32 align, + u32 flags, enum hal_buffer buffer_type, int map_kernel, + struct msm_smem *smem); +void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *smem); +int msm_comm_smem_cache_operations(struct msm_vidc_inst *inst, + struct msm_smem *mem, enum smem_cache_ops cache_ops); +enum hal_video_codec get_hal_codec(int fourcc); +enum hal_domain get_hal_domain(int session_type); +int msm_comm_check_core_init(struct msm_vidc_core *core); +int msm_comm_get_inst_load(struct msm_vidc_inst *inst, + enum load_calc_quirks quirks); +int msm_comm_get_inst_load_per_core(struct msm_vidc_inst *inst, + enum load_calc_quirks quirks); +int msm_comm_get_load(struct msm_vidc_core *core, + enum session_type type, enum load_calc_quirks quirks); +int msm_comm_set_color_format(struct msm_vidc_inst *inst, + enum hal_buffer buffer_type, int fourcc); +int msm_comm_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl); +int msm_comm_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl); +int msm_comm_g_ctrl_for_id(struct msm_vidc_inst *inst, int id); +int msm_comm_ctrl_init(struct msm_vidc_inst *inst, + struct msm_vidc_ctrl *drv_ctrls, u32 num_ctrls, + const struct v4l2_ctrl_ops *ctrl_ops); +int msm_comm_ctrl_deinit(struct msm_vidc_inst *inst); +void msm_comm_cleanup_internal_buffers(struct msm_vidc_inst *inst); +bool msm_comm_turbo_session(struct msm_vidc_inst *inst); +void msm_comm_print_inst_info(struct msm_vidc_inst *inst); +int msm_comm_v4l2_to_hfi(int id, int value); +int msm_comm_hfi_to_v4l2(int id, int value); +int msm_comm_get_v4l2_profile(int fourcc, int profile); +int msm_comm_get_v4l2_level(int fourcc, int level); +int msm_comm_session_continue(void *instance); +int msm_vidc_send_pending_eos_buffers(struct msm_vidc_inst *inst); +enum hal_uncompressed_format msm_comm_get_hal_uncompressed(int fourcc); +u32 msm_comm_get_hfi_uncompressed(int fourcc); +u32 msm_comm_convert_color_fmt(u32 v4l2_fmt); +struct vb2_buffer *msm_comm_get_vb_using_vidc_buffer( + struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); +struct msm_vidc_buffer *msm_comm_get_buffer_using_device_planes( + struct msm_vidc_inst *inst, u32 type, u32 *planes); +struct msm_vidc_buffer *msm_comm_get_vidc_buffer(struct msm_vidc_inst *inst, + struct vb2_buffer *vb2); +void msm_comm_put_vidc_buffer(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf); +void handle_release_buffer_reference(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf); +int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf); +int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf); +int msm_comm_unmap_vidc_buffer(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf); +bool msm_comm_compare_dma_plane(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf, unsigned long *dma_planes, u32 i); +bool msm_comm_compare_dma_planes(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf, unsigned long *dma_planes); +bool msm_comm_compare_vb2_plane(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf, struct vb2_buffer *vb2, u32 i); +bool msm_comm_compare_vb2_planes(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf, struct vb2_buffer *vb2); +bool msm_comm_compare_device_plane(struct msm_vidc_buffer *mbuf, + u32 type, u32 *planes, u32 i); +bool msm_comm_compare_device_planes(struct msm_vidc_buffer *mbuf, + u32 type, u32 *planes); +int msm_comm_qbuf_cache_operations(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf); +int msm_comm_dqbuf_cache_operations(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf); +void print_vidc_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf); +void print_vb2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, + struct vb2_buffer *vb2); +void print_v4l2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, + struct v4l2_buffer *v4l2); +void kref_put_mbuf(struct msm_vidc_buffer *mbuf); +bool kref_get_mbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); +void msm_comm_store_filled_length(struct msm_vidc_list *data_list, + u32 index, u32 filled_length); +void msm_comm_fetch_filled_length(struct msm_vidc_list *data_list, + u32 index, u32 *filled_length); +void msm_comm_store_mark_data(struct msm_vidc_list *data_list, + u32 index, u32 mark_data, u32 mark_target); +void msm_comm_fetch_mark_data(struct msm_vidc_list *data_list, + u32 index, u32 *mark_data, u32 *mark_target); +int msm_comm_release_mark_data(struct msm_vidc_inst *inst); +int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf); +int msm_comm_num_queued_bufs(struct msm_vidc_inst *inst, u32 type); +int msm_comm_set_index_extradata(struct msm_vidc_inst *inst, + uint32_t extradata_id, uint32_t value); +int msm_comm_set_extradata(struct msm_vidc_inst *inst, uint32_t extradata_id, + uint32_t value); +bool msm_comm_check_for_inst_overload(struct msm_vidc_core *core); +#endif diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c new file mode 100644 index 000000000000..17ff19228c83 --- /dev/null +++ b/msm/vidc/msm_vidc_debug.c @@ -0,0 +1,533 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#define CREATE_TRACE_POINTS +#define MAX_SSR_STRING_LEN 10 +#include "msm_vidc_debug.h" +#include "vidc_hfi_api.h" +#include + +int msm_vidc_debug = VIDC_ERR | VIDC_WARN; +EXPORT_SYMBOL(msm_vidc_debug); + +int msm_vidc_debug_out = VIDC_OUT_PRINTK; +EXPORT_SYMBOL(msm_vidc_debug_out); + +bool msm_vidc_lossless_encode = !true; +EXPORT_SYMBOL(msm_vidc_lossless_encode); + +int msm_vidc_fw_debug = HFI_DEBUG_MSG_HIGH | + HFI_DEBUG_MSG_ERROR | HFI_DEBUG_MSG_FATAL; +int msm_vidc_fw_debug_mode = 1; +bool msm_vidc_fw_coverage = !true; +bool msm_vidc_thermal_mitigation_disabled = !true; +int msm_vidc_clock_voting = !1; +bool msm_vidc_syscache_disable = !true; + +#define MAX_DBG_BUF_SIZE 4096 + +#define DYNAMIC_BUF_OWNER(__binfo) ({ \ + atomic_read(&__binfo->ref_count) >= 2 ? "video driver" : "firmware";\ +}) + +struct core_inst_pair { + struct msm_vidc_core *core; + struct msm_vidc_inst *inst; +}; + +static u32 write_str(char *buffer, + size_t size, const char *fmt, ...) +{ + va_list args; + u32 len; + + va_start(args, fmt); + len = vscnprintf(buffer, size, fmt, args); + va_end(args); + return len; +} + +static ssize_t core_info_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct msm_vidc_core *core = file->private_data; + struct hfi_device *hdev; + struct hal_fw_info fw_info = { {0} }; + char *dbuf, *cur, *end; + int i = 0, rc = 0; + ssize_t len = 0; + + if (!core || !core->device) { + dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core); + return 0; + } + + dbuf = kzalloc(MAX_DBG_BUF_SIZE, GFP_KERNEL); + if (!dbuf) { + dprintk(VIDC_ERR, "%s: Allocation failed!\n", __func__); + return -ENOMEM; + } + cur = dbuf; + end = cur + MAX_DBG_BUF_SIZE; + hdev = core->device; + + cur += write_str(cur, end - cur, "===============================\n"); + cur += write_str(cur, end - cur, "CORE %d: %pK\n", core->id, core); + cur += write_str(cur, end - cur, "===============================\n"); + cur += write_str(cur, end - cur, "Core state: %d\n", core->state); + rc = call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data, &fw_info); + if (rc) { + dprintk(VIDC_WARN, "Failed to read FW info\n"); + goto err_fw_info; + } + + cur += write_str(cur, end - cur, + "FW version : %s\n", &fw_info.version); + cur += write_str(cur, end - cur, + "base addr: 0x%x\n", fw_info.base_addr); + cur += write_str(cur, end - cur, + "register_base: 0x%x\n", fw_info.register_base); + cur += write_str(cur, end - cur, + "register_size: %u\n", fw_info.register_size); + cur += write_str(cur, end - cur, "irq: %u\n", fw_info.irq); + cur += write_str(cur, end - cur, + "ddr_type: %d\n", of_fdt_get_ddrtype()); + +err_fw_info: + for (i = SYS_MSG_START; i < SYS_MSG_END; i++) { + cur += write_str(cur, end - cur, "completions[%d]: %s\n", i, + completion_done(&core->completions[SYS_MSG_INDEX(i)]) ? + "pending" : "done"); + } + len = simple_read_from_buffer(buf, count, ppos, + dbuf, cur - dbuf); + + kfree(dbuf); + return len; +} + +static const struct file_operations core_info_fops = { + .open = simple_open, + .read = core_info_read, +}; + +static ssize_t trigger_ssr_write(struct file *filp, const char __user *buf, + size_t count, loff_t *ppos) +{ + unsigned long ssr_trigger_val = 0; + int rc = 0; + struct msm_vidc_core *core = filp->private_data; + size_t size = MAX_SSR_STRING_LEN; + char kbuf[MAX_SSR_STRING_LEN + 1] = {0}; + + if (!buf) + return -EINVAL; + + if (!count) + goto exit; + + if (count < size) + size = count; + + if (copy_from_user(kbuf, buf, size)) { + dprintk(VIDC_WARN, "%s User memory fault\n", __func__); + rc = -EFAULT; + goto exit; + } + + rc = kstrtoul(kbuf, 0, &ssr_trigger_val); + if (rc) { + dprintk(VIDC_WARN, "returning error err %d\n", rc); + rc = -EINVAL; + } else { + msm_vidc_trigger_ssr(core, ssr_trigger_val); + rc = count; + } +exit: + return rc; +} + +static const struct file_operations ssr_fops = { + .open = simple_open, + .write = trigger_ssr_write, +}; + +struct dentry *msm_vidc_debugfs_init_drv(void) +{ + bool ok = false; + struct dentry *dir = NULL; + + dir = debugfs_create_dir("msm_vidc", NULL); + if (IS_ERR_OR_NULL(dir)) { + dir = NULL; + goto failed_create_dir; + } + +#define __debugfs_create(__type, __name, __value) ({ \ + struct dentry *f = debugfs_create_##__type(__name, 0644, \ + dir, __value); \ + if (IS_ERR_OR_NULL(f)) { \ + dprintk(VIDC_ERR, "Failed creating debugfs file '%pd/%s'\n", \ + dir, __name); \ + f = NULL; \ + } \ + f; \ +}) + + ok = + __debugfs_create(x32, "debug_level", &msm_vidc_debug) && + __debugfs_create(x32, "fw_level", &msm_vidc_fw_debug) && + __debugfs_create(u32, "fw_debug_mode", &msm_vidc_fw_debug_mode) && + __debugfs_create(bool, "fw_coverage", &msm_vidc_fw_coverage) && + __debugfs_create(u32, "debug_output", &msm_vidc_debug_out) && + __debugfs_create(bool, "disable_thermal_mitigation", + &msm_vidc_thermal_mitigation_disabled) && + __debugfs_create(u32, "core_clock_voting", + &msm_vidc_clock_voting) && + __debugfs_create(bool, "disable_video_syscache", + &msm_vidc_syscache_disable) && + __debugfs_create(bool, "lossless_encoding", + &msm_vidc_lossless_encode); + +#undef __debugfs_create + + if (!ok) + goto failed_create_dir; + + return dir; + +failed_create_dir: + if (dir) + debugfs_remove_recursive(vidc_driver->debugfs_root); + + return NULL; +} + +struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core, + struct dentry *parent) +{ + struct dentry *dir = NULL; + char debugfs_name[MAX_DEBUGFS_NAME]; + + if (!core) { + dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core); + goto failed_create_dir; + } + + snprintf(debugfs_name, MAX_DEBUGFS_NAME, "core%d", core->id); + dir = debugfs_create_dir(debugfs_name, parent); + if (!dir) { + dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n"); + goto failed_create_dir; + } + if (!debugfs_create_file("info", 0444, dir, core, &core_info_fops)) { + dprintk(VIDC_ERR, "debugfs_create_file: fail\n"); + goto failed_create_dir; + } + if (!debugfs_create_file("trigger_ssr", 0200, + dir, core, &ssr_fops)) { + dprintk(VIDC_ERR, "debugfs_create_file: fail\n"); + goto failed_create_dir; + } +failed_create_dir: + return dir; +} + +static int inst_info_open(struct inode *inode, struct file *file) +{ + dprintk(VIDC_INFO, "Open inode ptr: %pK\n", inode->i_private); + file->private_data = inode->i_private; + return 0; +} + +static int publish_unreleased_reference(struct msm_vidc_inst *inst, + char **dbuf, char *end) +{ + struct msm_vidc_buffer *temp = NULL; + char *cur = *dbuf; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid param\n", __func__); + return -EINVAL; + } + + if (inst->buffer_mode_set[OUTPUT_PORT] == HAL_BUFFER_MODE_DYNAMIC) { + cur += write_str(cur, end - cur, "Pending buffer references\n"); + + mutex_lock(&inst->registeredbufs.lock); + list_for_each_entry(temp, &inst->registeredbufs.list, list) { + struct vb2_buffer *vb2 = &temp->vvb.vb2_buf; + + if (vb2->type == OUTPUT_MPLANE) { + cur += write_str(cur, end - cur, + "\tbuffer: %#x fd[0] = %d size %d refcount = %d\n", + temp->smem[0].device_addr, + vb2->planes[0].m.fd, + vb2->planes[0].length, + temp->smem[0].refcount); + } + } + mutex_unlock(&inst->registeredbufs.lock); + } + + *dbuf = cur; + return 0; +} + +static void put_inst_helper(struct kref *kref) +{ + struct msm_vidc_inst *inst = container_of(kref, + struct msm_vidc_inst, kref); + + msm_vidc_destroy(inst); +} + +static ssize_t inst_info_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct core_inst_pair *idata = file->private_data; + struct msm_vidc_core *core; + struct msm_vidc_inst *inst, *temp = NULL; + char *dbuf, *cur, *end; + int i, j; + ssize_t len = 0; + struct v4l2_format *f; + + if (!idata || !idata->core || !idata->inst) { + dprintk(VIDC_ERR, "%s: Invalid params\n", __func__); + return 0; + } + + core = idata->core; + inst = idata->inst; + + mutex_lock(&core->lock); + list_for_each_entry(temp, &core->instances, list) { + if (temp == inst) + break; + } + inst = ((temp == inst) && kref_get_unless_zero(&inst->kref)) ? + inst : NULL; + mutex_unlock(&core->lock); + + if (!inst) { + dprintk(VIDC_ERR, "%s: Instance has become obsolete", __func__); + return 0; + } + + dbuf = kzalloc(MAX_DBG_BUF_SIZE, GFP_KERNEL); + if (!dbuf) { + dprintk(VIDC_ERR, "%s: Allocation failed!\n", __func__); + len = -ENOMEM; + goto failed_alloc; + } + cur = dbuf; + end = cur + MAX_DBG_BUF_SIZE; + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + cur += write_str(cur, end - cur, "==============================\n"); + cur += write_str(cur, end - cur, "INSTANCE: %pK (%s)\n", inst, + inst->session_type == MSM_VIDC_ENCODER ? "Encoder" : "Decoder"); + cur += write_str(cur, end - cur, "==============================\n"); + cur += write_str(cur, end - cur, "core: %pK\n", inst->core); + cur += write_str(cur, end - cur, "height: %d\n", f->fmt.pix_mp.height); + cur += write_str(cur, end - cur, "width: %d\n", f->fmt.pix_mp.width); + cur += write_str(cur, end - cur, "fps: %d\n", + inst->clk_data.frame_rate >> 16); + cur += write_str(cur, end - cur, "state: %d\n", inst->state); + cur += write_str(cur, end - cur, "secure: %d\n", + !!(inst->flags & VIDC_SECURE)); + cur += write_str(cur, end - cur, "-----------Formats-------------\n"); + for (i = 0; i < MAX_PORT_NUM; i++) { + f = &inst->fmts[i].v4l2_fmt; + cur += write_str(cur, end - cur, "capability: %s\n", + i == INPUT_PORT ? "Output" : "Capture"); + cur += write_str(cur, end - cur, "name : %s\n", + inst->fmts[i].name); + cur += write_str(cur, end - cur, "planes : %d\n", + f->fmt.pix_mp.num_planes); + cur += write_str(cur, end - cur, + "type: %s\n", i == INPUT_PORT ? + "Output" : "Capture"); + switch (inst->buffer_mode_set[i]) { + case HAL_BUFFER_MODE_STATIC: + cur += write_str(cur, end - cur, + "buffer mode : %s\n", "static"); + break; + case HAL_BUFFER_MODE_DYNAMIC: + cur += write_str(cur, end - cur, + "buffer mode : %s\n", "dynamic"); + break; + default: + cur += write_str(cur, end - cur, + "buffer mode : unsupported\n"); + } + + cur += write_str(cur, end - cur, "count: %u\n", + inst->bufq[i].vb2_bufq.num_buffers); + + for (j = 0; j < f->fmt.pix_mp.num_planes; j++) + cur += write_str(cur, end - cur, + "size for plane %d: %u\n", + j, f->fmt.pix_mp.plane_fmt[j].sizeimage); + + if (i < MAX_PORT_NUM - 1) + cur += write_str(cur, end - cur, "\n"); + } + cur += write_str(cur, end - cur, "-------------------------------\n"); + for (i = SESSION_MSG_START; i < SESSION_MSG_END; i++) { + cur += write_str(cur, end - cur, "completions[%d]: %s\n", i, + completion_done(&inst->completions[SESSION_MSG_INDEX(i)]) ? + "pending" : "done"); + } + cur += write_str(cur, end - cur, "ETB Count: %d\n", inst->count.etb); + cur += write_str(cur, end - cur, "EBD Count: %d\n", inst->count.ebd); + cur += write_str(cur, end - cur, "FTB Count: %d\n", inst->count.ftb); + cur += write_str(cur, end - cur, "FBD Count: %d\n", inst->count.fbd); + + publish_unreleased_reference(inst, &cur, end); + len = simple_read_from_buffer(buf, count, ppos, + dbuf, cur - dbuf); + + kfree(dbuf); +failed_alloc: + kref_put(&inst->kref, put_inst_helper); + return len; +} + +static int inst_info_release(struct inode *inode, struct file *file) +{ + dprintk(VIDC_INFO, "Release inode ptr: %pK\n", inode->i_private); + file->private_data = NULL; + return 0; +} + +static const struct file_operations inst_info_fops = { + .open = inst_info_open, + .read = inst_info_read, + .release = inst_info_release, +}; + +struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst, + struct dentry *parent) +{ + struct dentry *dir = NULL, *info = NULL; + char debugfs_name[MAX_DEBUGFS_NAME]; + struct core_inst_pair *idata = NULL; + + if (!inst) { + dprintk(VIDC_ERR, "Invalid params, inst: %pK\n", inst); + goto exit; + } + snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%p", inst); + + idata = kzalloc(sizeof(struct core_inst_pair), GFP_KERNEL); + if (!idata) { + dprintk(VIDC_ERR, "%s: Allocation failed!\n", __func__); + goto exit; + } + + idata->core = inst->core; + idata->inst = inst; + + dir = debugfs_create_dir(debugfs_name, parent); + if (!dir) { + dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n"); + goto failed_create_dir; + } + + info = debugfs_create_file("info", 0444, dir, + idata, &inst_info_fops); + if (!info) { + dprintk(VIDC_ERR, "debugfs_create_file: fail\n"); + goto failed_create_file; + } + + dir->d_inode->i_private = info->d_inode->i_private; + inst->debug.pdata[FRAME_PROCESSING].sampling = true; + return dir; + +failed_create_file: + debugfs_remove_recursive(dir); + dir = NULL; +failed_create_dir: + kfree(idata); +exit: + return dir; +} + +void msm_vidc_debugfs_deinit_inst(struct msm_vidc_inst *inst) +{ + struct dentry *dentry = NULL; + + if (!inst || !inst->debugfs_root) + return; + + dentry = inst->debugfs_root; + if (dentry->d_inode) { + dprintk(VIDC_INFO, "Destroy %pK\n", dentry->d_inode->i_private); + kfree(dentry->d_inode->i_private); + dentry->d_inode->i_private = NULL; + } + debugfs_remove_recursive(dentry); + inst->debugfs_root = NULL; +} + +void msm_vidc_debugfs_update(struct msm_vidc_inst *inst, + enum msm_vidc_debugfs_event e) +{ + struct msm_vidc_debug *d = &inst->debug; + char a[64] = "Frame processing"; + + switch (e) { + case MSM_VIDC_DEBUGFS_EVENT_ETB: + inst->count.etb++; + if (inst->count.ebd && inst->count.ftb > inst->count.fbd) { + d->pdata[FRAME_PROCESSING].name[0] = '\0'; + tic(inst, FRAME_PROCESSING, a); + } + break; + case MSM_VIDC_DEBUGFS_EVENT_EBD: + inst->count.ebd++; + if (inst->count.ebd && inst->count.ebd == inst->count.etb) { + toc(inst, FRAME_PROCESSING); + dprintk(VIDC_PROF, "EBD: FW needs input buffers\n"); + } + if (inst->count.ftb == inst->count.fbd) + dprintk(VIDC_PROF, "EBD: FW needs output buffers\n"); + break; + case MSM_VIDC_DEBUGFS_EVENT_FTB: { + inst->count.ftb++; + if (inst->count.ebd && inst->count.etb > inst->count.ebd) { + d->pdata[FRAME_PROCESSING].name[0] = '\0'; + tic(inst, FRAME_PROCESSING, a); + } + } + break; + case MSM_VIDC_DEBUGFS_EVENT_FBD: + inst->count.fbd++; + inst->debug.samples++; + if (inst->count.fbd && + inst->count.fbd == inst->count.ftb) { + toc(inst, FRAME_PROCESSING); + dprintk(VIDC_PROF, "FBD: FW needs output buffers\n"); + } + if (inst->count.etb == inst->count.ebd) + dprintk(VIDC_PROF, "FBD: FW needs input buffers\n"); + break; + default: + dprintk(VIDC_ERR, "Invalid state in debugfs: %d\n", e); + break; + } +} + +int msm_vidc_check_ratelimit(void) +{ + static DEFINE_RATELIMIT_STATE(_rs, + VIDC_DBG_SESSION_RATELIMIT_INTERVAL, + VIDC_DBG_SESSION_RATELIMIT_BURST); + return __ratelimit(&_rs); +} + diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h new file mode 100644 index 000000000000..a06bf2b2f844 --- /dev/null +++ b/msm/vidc/msm_vidc_debug.h @@ -0,0 +1,209 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef __MSM_VIDC_DEBUG__ +#define __MSM_VIDC_DEBUG__ +#include +#include +#include +#include "msm_vidc_internal.h" +#include "trace/events/msm_vidc_events.h" + +#ifndef VIDC_DBG_LABEL +#define VIDC_DBG_LABEL "msm_vidc" +#endif + +/* + * This enforces a rate limit: not more than 6 messages + * in every 1s. + */ + +#define VIDC_DBG_SESSION_RATELIMIT_INTERVAL (1 * HZ) +#define VIDC_DBG_SESSION_RATELIMIT_BURST 6 + +#define VIDC_DBG_TAG VIDC_DBG_LABEL ": %4s: " + +/* To enable messages OR these values and + * echo the result to debugfs file. + * + * To enable all messages set debug_level = 0x101F + */ + +enum vidc_msg_prio { + VIDC_ERR = 0x0001, + VIDC_WARN = 0x0002, + VIDC_INFO = 0x0004, + VIDC_DBG = 0x0008, + VIDC_PROF = 0x0010, + VIDC_PKT = 0x0020, + VIDC_FW = 0x1000, +}; + +enum vidc_msg_out { + VIDC_OUT_PRINTK = 0, +}; + +enum msm_vidc_debugfs_event { + MSM_VIDC_DEBUGFS_EVENT_ETB, + MSM_VIDC_DEBUGFS_EVENT_EBD, + MSM_VIDC_DEBUGFS_EVENT_FTB, + MSM_VIDC_DEBUGFS_EVENT_FBD, +}; + +extern int msm_vidc_debug; +extern int msm_vidc_debug_out; +extern int msm_vidc_fw_debug; +extern int msm_vidc_fw_debug_mode; +extern bool msm_vidc_fw_coverage; +extern bool msm_vidc_thermal_mitigation_disabled; +extern int msm_vidc_clock_voting; +extern bool msm_vidc_syscache_disable; +extern bool msm_vidc_lossless_encode; + +#define dprintk(__level, __fmt, ...) \ + do { \ + if (msm_vidc_debug & __level) { \ + if (msm_vidc_debug_out == VIDC_OUT_PRINTK) { \ + pr_info(VIDC_DBG_TAG __fmt, \ + get_debug_level_str(__level), \ + ##__VA_ARGS__); \ + } \ + } \ + } while (0) + +#define dprintk_ratelimit(__level, __fmt, arg...) \ + do { \ + if (msm_vidc_debug & __level) { \ + if (msm_vidc_debug_out == VIDC_OUT_PRINTK && \ + msm_vidc_check_ratelimit()) { \ + pr_info(VIDC_DBG_TAG __fmt, \ + get_debug_level_str(__level), \ + ## arg); \ + } \ + } \ + } while (0) + +#define MSM_VIDC_ERROR(value) \ + do { if (value) \ + dprintk(VIDC_DBG, "BugOn"); \ + BUG_ON(value); \ + } while (0) + + +struct dentry *msm_vidc_debugfs_init_drv(void); +struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core, + struct dentry *parent); +struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst, + struct dentry *parent); +void msm_vidc_debugfs_deinit_inst(struct msm_vidc_inst *inst); +void msm_vidc_debugfs_update(struct msm_vidc_inst *inst, + enum msm_vidc_debugfs_event e); +int msm_vidc_check_ratelimit(void); + +static inline char *get_debug_level_str(int level) +{ + switch (level) { + case VIDC_ERR: + return "err"; + case VIDC_WARN: + return "warn"; + case VIDC_INFO: + return "info"; + case VIDC_DBG: + return "dbg"; + case VIDC_PROF: + return "prof"; + case VIDC_PKT: + return "pkt"; + case VIDC_FW: + return "fw"; + default: + return "???"; + } +} + +static inline void tic(struct msm_vidc_inst *i, enum profiling_points p, + char *b) +{ + struct timeval __ddl_tv; + + if (!i->debug.pdata[p].name[0]) + memcpy(i->debug.pdata[p].name, b, 64); + if ((msm_vidc_debug & VIDC_PROF) && + i->debug.pdata[p].sampling) { + do_gettimeofday(&__ddl_tv); + i->debug.pdata[p].start = + (__ddl_tv.tv_sec * 1000) + (__ddl_tv.tv_usec / 1000); + i->debug.pdata[p].sampling = false; + } +} + +static inline void toc(struct msm_vidc_inst *i, enum profiling_points p) +{ + struct timeval __ddl_tv; + + if ((msm_vidc_debug & VIDC_PROF) && + !i->debug.pdata[p].sampling) { + do_gettimeofday(&__ddl_tv); + i->debug.pdata[p].stop = (__ddl_tv.tv_sec * 1000) + + (__ddl_tv.tv_usec / 1000); + i->debug.pdata[p].cumulative += i->debug.pdata[p].stop - + i->debug.pdata[p].start; + i->debug.pdata[p].sampling = true; + } +} + +static inline void show_stats(struct msm_vidc_inst *i) +{ + int x; + + for (x = 0; x < MAX_PROFILING_POINTS; x++) { + if (i->debug.pdata[x].name[0] && + (msm_vidc_debug & VIDC_PROF)) { + if (i->debug.samples) { + dprintk(VIDC_PROF, "%s averaged %d ms/sample\n", + i->debug.pdata[x].name, + i->debug.pdata[x].cumulative / + i->debug.samples); + } + + dprintk(VIDC_PROF, "%s Samples: %d\n", + i->debug.pdata[x].name, + i->debug.samples); + } + } +} + +static inline void msm_vidc_res_handle_fatal_hw_error( + struct msm_vidc_platform_resources *resources, + bool enable_fatal) +{ + enable_fatal &= resources->debug_timeout; + MSM_VIDC_ERROR(enable_fatal); +} + +static inline void msm_vidc_handle_hw_error(struct msm_vidc_core *core) +{ + bool enable_fatal = true; + + /* + * In current implementation user-initiated SSR triggers + * a fatal error from hardware. However, there is no way + * to know if fatal error is due to SSR or not. Handle + * user SSR as non-fatal. + */ + if (core->trigger_ssr) { + core->trigger_ssr = false; + enable_fatal = false; + } + + /* Video driver can decide FATAL handling of HW errors + * based on multiple factors. This condition check will + * be enhanced later. + */ + msm_vidc_res_handle_fatal_hw_error(&core->resources, enable_fatal); +} + +#endif diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h new file mode 100644 index 000000000000..d9af3b29c574 --- /dev/null +++ b/msm/vidc/msm_vidc_internal.h @@ -0,0 +1,593 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef _MSM_VIDC_INTERNAL_H_ +#define _MSM_VIDC_INTERNAL_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm_vidc.h" +#include +#include "vidc_hfi_api.h" +#include "vidc_hfi_helper.h" + +#define MSM_VIDC_DRV_NAME "msm_vidc_driver" + +/* kernel/msm-4.19 */ +#define MSM_VIDC_VERSION ((0 << 16) + (4 << 8) + 19) + +#define MAX_DEBUGFS_NAME 50 +#define DEFAULT_TIMEOUT 3 +#define DEFAULT_HEIGHT 1088 +#define DEFAULT_WIDTH 1920 +#define MIN_SUPPORTED_WIDTH 32 +#define MIN_SUPPORTED_HEIGHT 32 +#define DEFAULT_FPS 30 +#define MINIMUM_FPS 1 +#define MAXIMUM_FPS 960 +#define MIN_NUM_INPUT_BUFFERS 1 +#define MIN_NUM_OUTPUT_BUFFERS 1 +#define MAX_NUM_INPUT_BUFFERS VIDEO_MAX_FRAME // same as VB2_MAX_FRAME +#define MAX_NUM_OUTPUT_BUFFERS VIDEO_MAX_FRAME // same as VB2_MAX_FRAME + +#define MAX_SUPPORTED_INSTANCES 16 + +/* Maintains the number of FTB's between each FBD over a window */ +#define DCVS_FTB_WINDOW 16 + +#define V4L2_EVENT_VIDC_BASE 10 +#define INPUT_MPLANE V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE +#define OUTPUT_MPLANE V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE + +#define RATE_CONTROL_OFF (V4L2_MPEG_VIDEO_BITRATE_MODE_CQ + 1) +#define RATE_CONTROL_LOSSLESS (V4L2_MPEG_VIDEO_BITRATE_MODE_CQ + 2) +#define SYS_MSG_START HAL_SYS_INIT_DONE +#define SYS_MSG_END HAL_SYS_ERROR +#define SESSION_MSG_START HAL_SESSION_EVENT_CHANGE +#define SESSION_MSG_END HAL_SESSION_ERROR +#define SYS_MSG_INDEX(__msg) (__msg - SYS_MSG_START) +#define SESSION_MSG_INDEX(__msg) (__msg - SESSION_MSG_START) + +#define MAX_NAME_LENGTH 64 + +#define NUM_MBS_PER_SEC(__height, __width, __fps) \ + (NUM_MBS_PER_FRAME(__height, __width) * __fps) + +#define NUM_MBS_PER_FRAME(__height, __width) \ + ((ALIGN(__height, 16) / 16) * (ALIGN(__width, 16) / 16)) + +#define call_core_op(c, op, ...) \ + (((c) && (c)->core_ops && (c)->core_ops->op) ? \ + ((c)->core_ops->op(__VA_ARGS__)) : 0) + +struct msm_vidc_inst; + +enum vidc_ports { + INPUT_PORT, + OUTPUT_PORT, + MAX_PORT_NUM +}; + +enum vidc_core_state { + VIDC_CORE_UNINIT = 0, + VIDC_CORE_INIT, + VIDC_CORE_INIT_DONE, +}; + +/* + * Do not change the enum values unless + * you know what you are doing + */ +enum instance_state { + MSM_VIDC_CORE_UNINIT_DONE = 0x0001, + MSM_VIDC_CORE_INIT, + MSM_VIDC_CORE_INIT_DONE, + MSM_VIDC_OPEN, + MSM_VIDC_OPEN_DONE, + MSM_VIDC_LOAD_RESOURCES, + MSM_VIDC_LOAD_RESOURCES_DONE, + MSM_VIDC_START, + MSM_VIDC_START_DONE, + MSM_VIDC_STOP, + MSM_VIDC_STOP_DONE, + MSM_VIDC_RELEASE_RESOURCES, + MSM_VIDC_RELEASE_RESOURCES_DONE, + MSM_VIDC_CLOSE, + MSM_VIDC_CLOSE_DONE, + MSM_VIDC_CORE_UNINIT, + MSM_VIDC_CORE_INVALID +}; + +struct buf_info { + struct list_head list; + struct vb2_buffer *buf; +}; + +struct msm_vidc_list { + struct list_head list; + struct mutex lock; +}; + +static inline void INIT_MSM_VIDC_LIST(struct msm_vidc_list *mlist) +{ + mutex_init(&mlist->lock); + INIT_LIST_HEAD(&mlist->list); +} + +static inline void DEINIT_MSM_VIDC_LIST(struct msm_vidc_list *mlist) +{ + mutex_destroy(&mlist->lock); +} + +enum buffer_owner { + DRIVER, + FIRMWARE, + CLIENT, + MAX_OWNER +}; + +struct vidc_freq_data { + struct list_head list; + u32 device_addr; + unsigned long freq; + bool turbo; +}; + +struct vidc_input_cr_data { + struct list_head list; + u32 index; + u32 input_cr; +}; + +struct recon_buf { + struct list_head list; + u32 buffer_index; + u32 CR; + u32 CF; +}; + +struct eos_buf { + struct list_head list; + struct msm_smem smem; +}; + +struct internal_buf { + struct list_head list; + enum hal_buffer buffer_type; + struct msm_smem smem; + enum buffer_owner buffer_ownership; + bool mark_remove; +}; + +struct msm_vidc_csc_coeff { + u32 *vpe_csc_custom_matrix_coeff; + u32 *vpe_csc_custom_bias_coeff; + u32 *vpe_csc_custom_limit_coeff; +}; + +struct msm_vidc_buf_data { + struct list_head list; + u32 index; + u32 mark_data; + u32 mark_target; + u32 filled_length; +}; + +struct msm_vidc_common_data { + char key[128]; + int value; +}; + +struct msm_vidc_codec_data { + u32 fourcc; + enum session_type session_type; + int vpp_cycles; + int vsp_cycles; + int low_power_cycles; +}; + +struct msm_vidc_codec_capability { + enum hal_capability capability_type; + enum hal_domain domains; + enum hal_video_codec codecs; + u32 min; + u32 max; + u32 step_size; + u32 default_value; +}; + +struct msm_vidc_codec { + enum hal_domain domain; + enum hal_video_codec codec; +}; + +enum efuse_purpose { + SKU_VERSION = 0, +}; + +enum sku_version { + SKU_VERSION_0 = 0, + SKU_VERSION_1, + SKU_VERSION_2, +}; + +struct msm_vidc_efuse_data { + u32 start_address; + u32 size; + u32 mask; + u32 shift; + enum efuse_purpose purpose; +}; + +enum vpu_version { + VPU_VERSION_AR50 = 1, + VPU_VERSION_IRIS1, + VPU_VERSION_IRIS2, +}; + +struct msm_vidc_ubwc_config_data { + struct { + u32 max_channel_override : 1; + u32 mal_length_override : 1; + u32 hb_override : 1; + u32 bank_swzl_level_override : 1; + u32 bank_spreading_override : 1; + u32 reserved : 27; + } override_bit_info; + + u32 max_channels; + u32 mal_length; + u32 highest_bank_bit; + u32 bank_swzl_level; + u32 bank_spreading; +}; + +struct msm_vidc_platform_data { + struct msm_vidc_common_data *common_data; + unsigned int common_data_length; + struct msm_vidc_codec_data *codec_data; + unsigned int codec_data_length; + struct msm_vidc_codec *codecs; + uint32_t codecs_count; + struct msm_vidc_codec_capability *codec_caps; + uint32_t codec_caps_count; + struct msm_vidc_csc_coeff csc_data; + struct msm_vidc_efuse_data *efuse_data; + unsigned int efuse_data_length; + unsigned int sku_version; + uint32_t vpu_ver; + struct msm_vidc_ubwc_config_data *ubwc_config; +}; + +struct msm_vidc_format_desc { + char name[MAX_NAME_LENGTH]; + u8 description[32]; + u32 fourcc; +}; + +struct msm_vidc_format { + char name[MAX_NAME_LENGTH]; + u8 description[32]; + u32 count_min; + u32 count_min_host; + u32 count_actual; + struct v4l2_format v4l2_fmt; +}; + +struct msm_vidc_format_constraint { + u32 fourcc; + u32 num_planes; + u32 y_max_stride; + u32 y_buffer_alignment; + u32 uv_max_stride; + u32 uv_buffer_alignment; +}; + +struct msm_vidc_drv { + struct mutex lock; + struct list_head cores; + int num_cores; + struct dentry *debugfs_root; + int thermal_level; + u32 sku_version; +}; + +struct msm_video_device { + int type; + struct video_device vdev; +}; + +struct session_crop { + u32 left; + u32 top; + u32 width; + u32 height; +}; + +struct session_prop { + struct session_crop crop_info; + u32 fps; + u32 bitrate; + bool bframe_changed; + u32 extradata_ctrls; +}; + +struct buf_queue { + struct vb2_queue vb2_bufq; + struct mutex lock; +}; + +enum profiling_points { + SYS_INIT = 0, + SESSION_INIT, + LOAD_RESOURCES, + FRAME_PROCESSING, + FW_IDLE, + MAX_PROFILING_POINTS, +}; + +struct buf_count { + int etb; + int ftb; + int fbd; + int ebd; +}; + +struct batch_mode { + bool enable; + u32 size; +}; + +enum dcvs_flags { + MSM_VIDC_DCVS_INCR = BIT(0), + MSM_VIDC_DCVS_DECR = BIT(1), +}; + +struct clock_data { + int buffer_counter; + u64 load; + u64 load_low; + u64 load_norm; + u64 load_high; + int min_threshold; + int max_threshold; + enum hal_buffer buffer_type; + bool dcvs_mode; + unsigned long bitrate; + unsigned long min_freq; + unsigned long curr_freq; + u32 vpss_cycles; + u32 ise_cycles; + u32 ddr_bw; + u32 sys_cache_bw; + u32 operating_rate; + struct msm_vidc_codec_data *entry; + u32 core_id; + u32 dpb_fourcc; + u32 opb_fourcc; + u32 work_mode; + bool low_latency_mode; + bool is_cbr_plus; + u32 work_route; + u32 dcvs_flags; + u32 frame_rate; +}; + +struct profile_data { + int start; + int stop; + int cumulative; + char name[64]; + int sampling; + int average; +}; + +struct msm_vidc_debug { + struct profile_data pdata[MAX_PROFILING_POINTS]; + int profile; + int samples; +}; + +enum msm_vidc_modes { + VIDC_SECURE = BIT(0), + VIDC_TURBO = BIT(1), + VIDC_THUMBNAIL = BIT(2), + VIDC_LOW_POWER = BIT(3), + VIDC_REALTIME = BIT(4), +}; + +struct msm_vidc_core_ops { + unsigned long (*calc_freq)(struct msm_vidc_inst *inst, u32 filled_len); + int (*decide_work_route)(struct msm_vidc_inst *inst); + int (*decide_work_mode)(struct msm_vidc_inst *inst); + int (*decide_core_and_power_mode)(struct msm_vidc_inst *inst); +}; + +struct msm_vidc_core { + struct list_head list; + struct mutex lock; + int id; + struct hfi_device *device; + struct msm_vidc_platform_data *platform_data; + struct msm_video_device vdev[MSM_VIDC_MAX_DEVICES]; + struct v4l2_device v4l2_dev; + struct list_head instances; + struct dentry *debugfs_root; + enum vidc_core_state state; + struct completion completions[SYS_MSG_END - SYS_MSG_START + 1]; + enum msm_vidc_hfi_type hfi_type; + struct msm_vidc_platform_resources resources; + struct msm_vidc_capability *capabilities; + struct delayed_work fw_unload_work; + struct work_struct ssr_work; + enum hal_ssr_trigger_type ssr_type; + bool smmu_fault_handled; + bool trigger_ssr; + unsigned long min_freq; + unsigned long curr_freq; + struct msm_vidc_core_ops *core_ops; +}; + +struct msm_vidc_inst; +struct msm_vidc_inst_smem_ops { + int (*smem_map_dma_buf)(struct msm_vidc_inst *inst, + struct msm_smem *smem); + int (*smem_unmap_dma_buf)(struct msm_vidc_inst *inst, + struct msm_smem *smem); +}; + +struct msm_vidc_inst { + struct list_head list; + struct mutex sync_lock, lock, flush_lock; + struct msm_vidc_core *core; + enum session_type session_type; + void *session; + struct msm_cvp_external *cvp; + struct session_prop prop; + enum instance_state state; + struct msm_vidc_format fmts[MAX_PORT_NUM]; + struct buf_queue bufq[MAX_PORT_NUM]; + struct msm_vidc_list freqs; + struct msm_vidc_list input_crs; + struct msm_vidc_list scratchbufs; + struct msm_vidc_list persistbufs; + struct msm_vidc_list pending_getpropq; + struct msm_vidc_list outputbufs; + struct msm_vidc_list reconbufs; + struct msm_vidc_list eosbufs; + struct msm_vidc_list registeredbufs; + struct msm_vidc_list cvpbufs; + struct msm_vidc_list etb_data; + struct msm_vidc_list fbd_data; + struct buffer_requirements buff_req; + struct v4l2_ctrl_handler ctrl_handler; + struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1]; + struct v4l2_ctrl **cluster; + struct v4l2_fh event_handler; + struct msm_smem *extradata_handle; + bool in_reconfig; + u32 reconfig_width; + u32 reconfig_height; + struct dentry *debugfs_root; + void *priv; + struct msm_vidc_debug debug; + struct buf_count count; + struct clock_data clk_data; + enum msm_vidc_modes flags; + struct msm_vidc_capability capability; + u32 buffer_size_limit; + enum buffer_mode_type buffer_mode_set[MAX_PORT_NUM]; + enum multi_stream stream_output_mode; + struct v4l2_ctrl **ctrls; + u32 num_ctrls; + int bit_depth; + struct kref kref; + bool in_flush; + u32 pic_struct; + u32 colour_space; + u32 profile; + u32 level; + u32 grid_enable; + u32 frame_quality; + u32 rc_type; + u32 hybrid_hp; + u32 layer_bitrate; + u32 client_set_ctrls; + struct internal_buf *dpb_extra_binfo; + struct msm_vidc_codec_data *codec_data; + struct hal_hdr10_pq_sei hdr10_sei_params; + struct batch_mode batch; + struct msm_vidc_inst_smem_ops *smem_ops; + int (*buffer_size_calculators)(struct msm_vidc_inst *inst); +}; + +extern struct msm_vidc_drv *vidc_driver; + +struct msm_vidc_ctrl_cluster { + struct v4l2_ctrl **cluster; + struct list_head list; +}; + +struct msm_vidc_ctrl { + u32 id; + char name[MAX_NAME_LENGTH]; + enum v4l2_ctrl_type type; + s64 minimum; + s64 maximum; + s64 default_value; + u32 step; + u32 menu_skip_mask; + u32 flags; + const char * const *qmenu; +}; + +void handle_cmd_response(enum hal_command_response cmd, void *data); +int msm_vidc_trigger_ssr(struct msm_vidc_core *core, + enum hal_ssr_trigger_type type); +int msm_vidc_noc_error_info(struct msm_vidc_core *core); +bool heic_encode_session_supported(struct msm_vidc_inst *inst); +int msm_vidc_check_session_supported(struct msm_vidc_inst *inst); +int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst); +void msm_vidc_queue_v4l2_event(struct msm_vidc_inst *inst, int event_type); + +enum msm_vidc_flags { + MSM_VIDC_FLAG_DEFERRED = BIT(0), + MSM_VIDC_FLAG_RBR_PENDING = BIT(1), + MSM_VIDC_FLAG_QUEUED = BIT(2), +}; + +struct msm_vidc_buffer { + struct list_head list; + struct kref kref; + struct msm_smem smem[VIDEO_MAX_PLANES]; + struct vb2_v4l2_buffer vvb; + enum msm_vidc_flags flags; +}; + +struct msm_vidc_cvp_buffer { + struct list_head list; + struct msm_smem smem; + struct msm_cvp_buffer buf; +}; + +void msm_comm_handle_thermal_event(void); +int msm_smem_alloc(size_t size, u32 align, u32 flags, + enum hal_buffer buffer_type, int map_kernel, + void *res, u32 session_type, struct msm_smem *smem); +int msm_smem_free(struct msm_smem *smem); + +struct context_bank_info *msm_smem_get_context_bank(u32 session_type, + bool is_secure, struct msm_vidc_platform_resources *res, + enum hal_buffer buffer_type); +int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem); +int msm_smem_unmap_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem); +struct dma_buf *msm_smem_get_dma_buf(int fd); +void msm_smem_put_dma_buf(void *dma_buf); +int msm_smem_cache_operations(struct dma_buf *dbuf, + enum smem_cache_ops cache_op, unsigned long offset, unsigned long size); +void msm_vidc_fw_unload_handler(struct work_struct *work); +void msm_vidc_ssr_handler(struct work_struct *work); +/* + * XXX: normally should be in msm_vidc.h, but that's meant for public APIs, + * whereas this is private + */ +int msm_vidc_destroy(struct msm_vidc_inst *inst); +void *vidc_get_drv_data(struct device *dev); +#endif diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c new file mode 100644 index 000000000000..2f5b6a05dac6 --- /dev/null +++ b/msm/vidc/msm_vidc_platform.c @@ -0,0 +1,1024 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm_vidc_internal.h" +#include "msm_vidc_debug.h" + + +#define DDR_TYPE_LPDDR4 0x6 +#define DDR_TYPE_LPDDR4X 0x7 +#define DDR_TYPE_LPDDR4Y 0x8 +#define DDR_TYPE_LPDDR5 0x9 + +#define CODEC_ENTRY(n, p, vsp, vpp, lp) \ +{ \ + .fourcc = n, \ + .session_type = p, \ + .vsp_cycles = vsp, \ + .vpp_cycles = vpp, \ + .low_power_cycles = lp \ +} + +#define EFUSE_ENTRY(sa, s, m, sh, p) \ +{ \ + .start_address = sa, \ + .size = s, \ + .mask = m, \ + .shift = sh, \ + .purpose = p \ +} + +#define UBWC_CONFIG(mco, mlo, hbo, bslo, bso, rs, mc, ml, hbb, bsl, bsp) \ +{ \ + .override_bit_info.max_channel_override = mco, \ + .override_bit_info.mal_length_override = mlo, \ + .override_bit_info.hb_override = hbo, \ + .override_bit_info.bank_swzl_level_override = bslo, \ + .override_bit_info.bank_spreading_override = bso, \ + .override_bit_info.reserved = rs, \ + .max_channels = mc, \ + .mal_length = ml, \ + .highest_bank_bit = hbb, \ + .bank_swzl_level = bsl, \ + .bank_spreading = bsp, \ +} + +static struct msm_vidc_codec_data default_codec_data[] = { + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 125, 675, 320), +}; + +/* Update with lito data */ +static struct msm_vidc_codec_data lito_codec_data[] = { + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 10, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 10, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 10, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), + CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 10, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 10, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 10, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 10, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 10, 200, 200), +}; + +/* Update with Kona data */ +static struct msm_vidc_codec_data kona_codec_data[] = { + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 10, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 10, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 10, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), + CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 10, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 10, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 10, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 10, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 10, 200, 200), +}; + +/* Update with SM6150 data */ +static struct msm_vidc_codec_data sm6150_codec_data[] = { + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 125, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 125, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), + CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 50, 200, 200), +}; + +/* Update with 855 data */ +static struct msm_vidc_codec_data sm8150_codec_data[] = { + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 10, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 10, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 10, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), + CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 10, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 10, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 10, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 10, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 10, 200, 200), +}; + +static struct msm_vidc_codec_data sdm845_codec_data[] = { + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 125, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 125, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), + CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 50, 200, 200), +}; + +static struct msm_vidc_codec_data sdm670_codec_data[] = { + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 125, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 125, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), + CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 50, 200, 200), +}; + +#define ENC HAL_VIDEO_DOMAIN_ENCODER +#define DEC HAL_VIDEO_DOMAIN_DECODER +#define H264 HAL_VIDEO_CODEC_H264 +#define HEVC HAL_VIDEO_CODEC_HEVC +#define VP8 HAL_VIDEO_CODEC_VP8 +#define VP9 HAL_VIDEO_CODEC_VP9 +#define MPEG2 HAL_VIDEO_CODEC_MPEG2 +#define DOMAINS_ALL (HAL_VIDEO_DOMAIN_ENCODER | HAL_VIDEO_DOMAIN_DECODER) +#define CODECS_ALL (HAL_VIDEO_CODEC_H264 | HAL_VIDEO_CODEC_HEVC | \ + HAL_VIDEO_CODEC_VP8 | HAL_VIDEO_CODEC_VP9 | \ + HAL_VIDEO_CODEC_MPEG2) + +static struct msm_vidc_codec default_codecs[] = { + /* {domain, codec} */ + {DEC, H264}, {DEC, HEVC}, {DEC, VP8}, {DEC, VP9}, {DEC, MPEG2}, + {ENC, H264}, {ENC, HEVC}, {ENC, VP8}, +}; + +static struct msm_vidc_codec_capability kona_capabilities[] = { + /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ + {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 8192, 1, 1920}, + {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 8192, 1, 1080}, + /* (8192 * 4320) / 256 */ + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 1, 138240, 1, 138240}, + /* ((1920 * 1088) / 256) * 960 fps */ + {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 1, 7833600, 1, 7833600}, + {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 960, 1, 30}, + {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 220000000, 1, 20000000}, + {CAP_SCALE_X, DOMAINS_ALL, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_SCALE_Y, DOMAINS_ALL, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, + {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, + {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 6, 1, 0}, + /* ((4096 * 2304) / 256) * 60 fps */ + {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, + 0, 2211840, 1, 2211840}, + {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, + {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_I_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 20}, + {CAP_P_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 40}, + {CAP_B_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 40}, + /* 10 slices */ + {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_SLICE_MB, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, + + /* VP8 specific */ + {CAP_FRAME_WIDTH, ENC|DEC, VP8, 128, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 128, 4096, 1, 1080}, + /* (4096 * 2304) / 256 */ + {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 1, 36864, 1, 8160}, + /* ((4096 * 2304) / 256) * 120 */ + {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 1, 4423680, 1, 244800}, + {CAP_FRAMERATE, ENC|DEC, VP8, 1, 120, 1, 30}, + {CAP_BITRATE, ENC, VP8, 1, 74000000, 1, 20000000}, + {CAP_BITRATE, DEC, VP8, 1, 220000000, 1, 20000000}, + + /* Mpeg2 decoder specific */ + {CAP_FRAME_WIDTH, DEC, MPEG2, 128, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, MPEG2, 128, 1920, 1, 1080}, + /* (1920 * 1088) / 256 */ + {CAP_MBS_PER_FRAME, DEC, MPEG2, 1, 8160, 1, 8160}, + /* ((1920 * 1088) / 256) * 30*/ + {CAP_MBS_PER_SECOND, DEC, MPEG2, 1, 244800, 1, 244800}, + {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, + {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, + + /* Secure usecase specific */ + {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1080}, + /* (4096 * 2304) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 1, 36864, 1, 36864}, + {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, + + /* Batch Mode Decode */ + {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 128, 34560, 1, 34560}, + /* (4096 * 2160) / 256 */ + {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 120, 1, 120}, +}; + +/* + * Custom conversion coefficients for resolution: 176x144 negative + * coeffs are converted to s4.9 format + * (e.g. -22 converted to ((1 << 13) - 22) + * 3x3 transformation matrix coefficients in s4.9 fixed point format + */ +static u32 vpe_csc_custom_matrix_coeff[HAL_MAX_MATRIX_COEFFS] = { + 470, 8170, 8148, 0, 490, 50, 0, 34, 483 +}; + +/* offset coefficients in s9 fixed point format */ +static u32 vpe_csc_custom_bias_coeff[HAL_MAX_BIAS_COEFFS] = { + 34, 0, 4 +}; + +/* clamping value for Y/U/V([min,max] for Y/U/V) */ +static u32 vpe_csc_custom_limit_coeff[HAL_MAX_LIMIT_COEFFS] = { + 16, 235, 16, 240, 16, 240 +}; + +static struct msm_vidc_common_data default_common_data[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, +}; + +/* Update with lito */ +static struct msm_vidc_common_data lito_common_data_v0[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 5, + }, + { + .key = "qcom,max-hw-load", + .value = 3110400,/* ((4096x2160)/256)@90fps */ + /* 4k@60 decode + 4k@30 encode */ + }, + { + .key = "qcom,max-hq-mbs-per-frame", + .value = 8160,/* ((1920x1088)/256) */ + }, + { + .key = "qcom,qcom,max-hq-mbs-per-sec", + .value = 244800,/* ((1920x1088)/256) MBs@30fps */ + }, + { + .key = "qcom,max-b-frame-mbs-per-frame", + .value = 8160,/* ((1920x1088)/256) */ + }, + { + .key = "qcom,max-b-frame-mbs-per-sec", + .value = 244800,/* ((1920x1088)/256) MBs@30fps */ + }, + { + .key = "qcom,power-collapse-delay", + .value = 1500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,debug-timeout", + .value = 0, + }, + { + .key = "qcom,domain-cvp", + .value = 1, + }, + { + .key = "qcom,decode-batching", + .value = 1, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, + { + .key = "qcom,fw-cycles", + .value = 760000, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 166667, + }, +}; + +static struct msm_vidc_common_data lito_common_data_v1[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 5, + }, + { + .key = "qcom,max-hw-load", + .value = 1281600,/* 4K@30 decode + 1080@30 encode */ + }, + { + .key = "qcom,max-hq-mbs-per-frame", + .value = 8160,/* ((1920x1088)/256) */ + }, + { + .key = "qcom,qcom,max-hq-mbs-per-sec", + .value = 244800,/* ((1920x1088)/256) MBs@30fps */ + }, + { + .key = "qcom,max-b-frame-mbs-per-frame", + .value = 8160,/* ((1920x1088)/256) */ + }, + { + .key = "qcom,max-b-frame-mbs-per-sec", + .value = 244800,/* ((1920x1088)/256) MBs@30fps */ + }, + { + .key = "qcom,power-collapse-delay", + .value = 1500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,debug-timeout", + .value = 0, + }, + { + .key = "qcom,domain-cvp", + .value = 1, + }, + { + .key = "qcom,decode-batching", + .value = 1, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, + { + .key = "qcom,fw-cycles", + .value = 760000, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 166667, + }, +}; + +static struct msm_vidc_common_data kona_common_data[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 3, + }, + { + .key = "qcom,max-hw-load", + .value = 7776000, /* + * 7680x4320@60fps, 3840x2160@240fps + * Greater than 4096x2160@120fps, + * 8192x4320@48fps + */ + }, + { + .key = "qcom,max-hq-mbs-per-frame", + .value = 34560, /* 4096x2160 */ + }, + { + .key = "qcom,max-hq-mbs-per-sec", + .value = 1036800, /* 4096x2160@30fps */ + }, + { + .key = "qcom,max-b-frame-mbs-per-frame", + .value = 32400, /* 3840x2160/256 */ + }, + { + .key = "qcom,max-b-frame-mbs-per-sec", + .value = 1944000, /* 3840x2160/256 MBs@60fps */ + }, + { + .key = "qcom,power-collapse-delay", + .value = 1500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,debug-timeout", + .value = 0, + }, + { + .key = "qcom,domain-cvp", + .value = 0, + }, + { + .key = "qcom,decode-batching", + .value = 1, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, + { + .key = "qcom,fw-cycles", + .value = 326389, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 44156, + }, +}; + +static struct msm_vidc_common_data sm6150_common_data[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 5, + }, + { + .key = "qcom,max-hw-load", + .value = 1216800, + }, + { + .key = "qcom,max-hq-mbs-per-frame", + .value = 8160, + }, + { + .key = "qcom,max-hq-mbs-per-sec", + .value = 244800, /* 1920 x 1088 @ 30 fps */ + }, + { + .key = "qcom,max-b-frame-mbs-per-frame", + .value = 8160, + }, + { + .key = "qcom,max-b-frame-mbs-per-sec", + .value = 489600, + }, + { + .key = "qcom,power-collapse-delay", + .value = 1500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, + { + .key = "qcom,fw-cycles", + .value = 733003, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 225975, + }, +}; + +static struct msm_vidc_common_data sm8150_common_data[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 2, /* + * As per design driver allows 3rd + * instance as well since the secure + * flags were updated later for the + * current instance. Hence total + * secure sessions would be + * max-secure-instances + 1. + */ + }, + { + .key = "qcom,max-hw-load", + .value = 3916800, /* + * 1920x1088/256 MBs@480fps. It is less + * any other usecases (ex: + * 3840x2160@120fps, 4096x2160@96ps, + * 7680x4320@30fps) + */ + }, + { + .key = "qcom,max-hq-mbs-per-frame", + .value = 8160, + }, + { + .key = "qcom,max-hq-mbs-per-sec", + .value = 244800, /* 1920 x 1088 @ 30 fps */ + }, + { + .key = "qcom,max-b-frame-mbs-per-frame", + .value = 8160, + }, + { + .key = "qcom,max-b-frame-mbs-per-sec", + .value = 489600, + }, + { + .key = "qcom,power-collapse-delay", + .value = 1500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,debug-timeout", + .value = 0, + }, + { + .key = "qcom,domain-cvp", + .value = 1, + }, + { + .key = "qcom,decode-batching", + .value = 1, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, + { + .key = "qcom,fw-cycles", + .value = 760000, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 166667, + }, +}; + +static struct msm_vidc_common_data sdm845_common_data[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,domain-attr-cache-pagetables", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 5, + }, + { + .key = "qcom,max-hw-load", + .value = 3110400, /* 4096x2160@90 */ + }, + { + .key = "qcom,max-hq-mbs-per-frame", + .value = 8160, + }, + { + .key = "qcom,max-hq-mbs-per-sec", + .value = 244800, /* 1920 x 1088 @ 30 fps */ + }, + { + .key = "qcom,max-b-frame-mbs-per-frame", + .value = 8160, + }, + { + .key = "qcom,max-b-frame-mbs-per-sec", + .value = 489600, + }, + { + .key = "qcom,power-collapse-delay", + .value = 500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 250, + }, + { + .key = "qcom,debug-timeout", + .value = 0, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, +}; + +static struct msm_vidc_common_data sdm670_common_data_v0[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 5, + }, + { + .key = "qcom,max-hw-load", + .value = 1944000, + }, + { + .key = "qcom,max-hq-mbs-per-frame", + .value = 8160, + }, + { + .key = "qcom,max-hq-mbs-per-sec", + .value = 244800, /* 1920 x 1088 @ 30 fps */ + }, + { + .key = "qcom,max-b-frame-mbs-per-frame", + .value = 8160, + }, + { + .key = "qcom,max-b-frame-mbs-per-sec", + .value = 489600, + }, + { + .key = "qcom,power-collapse-delay", + .value = 500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 250, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, +}; + +static struct msm_vidc_common_data sdm670_common_data_v1[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 5, + }, + { + .key = "qcom,max-hw-load", + .value = 1216800, + }, + { + .key = "qcom,max-hq-mbs-per-frame", + .value = 8160, + }, + { + .key = "qcom,max-hq-mbs-per-sec", + .value = 244800, /* 1920 x 1088 @ 30 fps */ + }, + { + .key = "qcom,max-b-frame-mbs-per-frame", + .value = 8160, + }, + { + .key = "qcom,max-b-frame-mbs-per-sec", + .value = 489600, + }, + { + .key = "qcom,power-collapse-delay", + .value = 500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 250, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, +}; + +static struct msm_vidc_efuse_data lito_efuse_data[] = { + EFUSE_ENTRY(0x00786018, 4, 0x00000400, 0x0a, SKU_VERSION), +}; + +static struct msm_vidc_efuse_data sdm670_efuse_data[] = { + EFUSE_ENTRY(0x007801A0, 4, 0x00008000, 0x0f, SKU_VERSION), +}; + +/* Default UBWC config for LPDDR5 */ +static struct msm_vidc_ubwc_config_data kona_ubwc_data[] = { + UBWC_CONFIG(1, 1, 1, 0, 0, 0, 8, 32, 15, 0, 0), +}; + +static struct msm_vidc_platform_data default_data = { + .codec_data = default_codec_data, + .codec_data_length = ARRAY_SIZE(default_codec_data), + .common_data = default_common_data, + .common_data_length = ARRAY_SIZE(default_common_data), + .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, + .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, + .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, + .efuse_data = NULL, + .efuse_data_length = 0, + .sku_version = 0, + .vpu_ver = VPU_VERSION_IRIS2, + .ubwc_config = 0x0, +}; + +static struct msm_vidc_platform_data lito_data = { + .codec_data = lito_codec_data, + .codec_data_length = ARRAY_SIZE(lito_codec_data), + .common_data = lito_common_data_v0, + .common_data_length = ARRAY_SIZE(lito_common_data_v0), + .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, + .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, + .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, + .efuse_data = lito_efuse_data, + .efuse_data_length = ARRAY_SIZE(lito_efuse_data), + .sku_version = 0, + .vpu_ver = VPU_VERSION_IRIS1, + .ubwc_config = 0x0, +}; + +static struct msm_vidc_platform_data kona_data = { + .codec_data = kona_codec_data, + .codec_data_length = ARRAY_SIZE(kona_codec_data), + .common_data = kona_common_data, + .common_data_length = ARRAY_SIZE(kona_common_data), + .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, + .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, + .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, + .efuse_data = NULL, + .efuse_data_length = 0, + .sku_version = 0, + .vpu_ver = VPU_VERSION_IRIS2, + .ubwc_config = kona_ubwc_data, + .codecs = default_codecs, + .codecs_count = ARRAY_SIZE(default_codecs), + .codec_caps = kona_capabilities, + .codec_caps_count = ARRAY_SIZE(kona_capabilities), +}; + +static struct msm_vidc_platform_data sm6150_data = { + .codec_data = sm6150_codec_data, + .codec_data_length = ARRAY_SIZE(sm6150_codec_data), + .common_data = sm6150_common_data, + .common_data_length = ARRAY_SIZE(sm6150_common_data), + .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, + .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, + .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, + .efuse_data = NULL, + .efuse_data_length = 0, + .sku_version = 0, + .vpu_ver = VPU_VERSION_AR50, + .ubwc_config = 0x0, +}; + +static struct msm_vidc_platform_data sm8150_data = { + .codec_data = sm8150_codec_data, + .codec_data_length = ARRAY_SIZE(sm8150_codec_data), + .common_data = sm8150_common_data, + .common_data_length = ARRAY_SIZE(sm8150_common_data), + .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, + .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, + .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, + .efuse_data = NULL, + .efuse_data_length = 0, + .sku_version = 0, + .vpu_ver = VPU_VERSION_IRIS1, + .ubwc_config = 0x0, +}; + +static struct msm_vidc_platform_data sdm845_data = { + .codec_data = sdm845_codec_data, + .codec_data_length = ARRAY_SIZE(sdm845_codec_data), + .common_data = sdm845_common_data, + .common_data_length = ARRAY_SIZE(sdm845_common_data), + .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, + .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, + .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, + .efuse_data = NULL, + .efuse_data_length = 0, + .sku_version = 0, + .vpu_ver = VPU_VERSION_AR50, + .ubwc_config = 0x0, +}; + +static struct msm_vidc_platform_data sdm670_data = { + .codec_data = sdm670_codec_data, + .codec_data_length = ARRAY_SIZE(sdm670_codec_data), + .common_data = sdm670_common_data_v0, + .common_data_length = ARRAY_SIZE(sdm670_common_data_v0), + .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, + .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, + .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, + .efuse_data = sdm670_efuse_data, + .efuse_data_length = ARRAY_SIZE(sdm670_efuse_data), + .sku_version = 0, + .vpu_ver = VPU_VERSION_AR50, + .ubwc_config = 0x0, +}; + +static const struct of_device_id msm_vidc_dt_match[] = { + { + .compatible = "qcom,lito-vidc", + .data = &lito_data, + }, + { + .compatible = "qcom,kona-vidc", + .data = &kona_data, + }, + { + .compatible = "qcom,sm6150-vidc", + .data = &sm6150_data, + }, + { + .compatible = "qcom,sm8150-vidc", + .data = &sm8150_data, + }, + { + .compatible = "qcom,sdm845-vidc", + .data = &sdm845_data, + }, + { + .compatible = "qcom,sdm670-vidc", + .data = &sdm670_data, + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, msm_vidc_dt_match); + +static int msm_vidc_read_efuse( + struct msm_vidc_platform_data *data, struct device *dev) +{ + void __iomem *base; + uint32_t i; + struct msm_vidc_efuse_data *efuse_data = data->efuse_data; + uint32_t efuse_data_count = data->efuse_data_length; + + for (i = 0; i < efuse_data_count; i++) { + + switch ((efuse_data[i]).purpose) { + + case SKU_VERSION: + base = devm_ioremap(dev, (efuse_data[i]).start_address, + (efuse_data[i]).size); + if (!base) { + dprintk(VIDC_ERR, + "failed efuse ioremap: res->start %#x, size %d\n", + (efuse_data[i]).start_address, + (efuse_data[i]).size); + return -EINVAL; + } else { + u32 efuse = 0; + + efuse = readl_relaxed(base); + data->sku_version = + (efuse & (efuse_data[i]).mask) >> + (efuse_data[i]).shift; + dprintk(VIDC_DBG, + "efuse 0x%x, platform version 0x%x\n", + efuse, data->sku_version); + + devm_iounmap(dev, base); + } + break; + + default: + break; + } + } + return 0; +} + +void *vidc_get_drv_data(struct device *dev) +{ + struct msm_vidc_platform_data *driver_data = NULL; + const struct of_device_id *match; + uint32_t ddr_type = DDR_TYPE_LPDDR5; + int rc = 0; + + if (!IS_ENABLED(CONFIG_OF) || !dev->of_node) { + driver_data = &default_data; + goto exit; + } + + match = of_match_node(msm_vidc_dt_match, dev->of_node); + + if (match) + driver_data = (struct msm_vidc_platform_data *)match->data; + + if (!of_find_property(dev->of_node, "sku-index", NULL) || + !driver_data) { + goto exit; + } else if (!strcmp(match->compatible, "qcom,sdm670-vidc")) { + rc = msm_vidc_read_efuse(driver_data, dev); + if (rc) + goto exit; + + if (driver_data->sku_version == SKU_VERSION_1) { + driver_data->common_data = sdm670_common_data_v1; + driver_data->common_data_length = + ARRAY_SIZE(sdm670_common_data_v1); + } + } else if (!strcmp(match->compatible, "qcom,kona-vidc")) { + ddr_type = of_fdt_get_ddrtype(); + if (ddr_type == -ENOENT) { + dprintk(VIDC_ERR, + "Failed to get ddr type, use LPDDR5\n"); + } + dprintk(VIDC_DBG, "DDR Type %x\n", ddr_type); + + if (driver_data->ubwc_config && + (ddr_type == DDR_TYPE_LPDDR4 || + ddr_type == DDR_TYPE_LPDDR4X || + ddr_type == DDR_TYPE_LPDDR4Y)) + driver_data->ubwc_config->highest_bank_bit = 0xf; + } else if (!strcmp(match->compatible, "qcom,lito-vidc")) { + rc = msm_vidc_read_efuse(driver_data, dev); + if (rc) + goto exit; + + if (driver_data->sku_version == SKU_VERSION_1) { + driver_data->common_data = lito_common_data_v1; + driver_data->common_data_length = + ARRAY_SIZE(lito_common_data_v1); + } + } + +exit: + return driver_data; +} diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c new file mode 100644 index 000000000000..855078b9aaf2 --- /dev/null +++ b/msm/vidc/msm_vidc_res_parse.c @@ -0,0 +1,1258 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include "msm_vidc_debug.h" +#include "msm_vidc_resources.h" +#include "msm_vidc_res_parse.h" +#include "soc/qcom/secure_buffer.h" + +enum clock_properties { + CLOCK_PROP_HAS_SCALING = 1 << 0, + CLOCK_PROP_HAS_MEM_RETENTION = 1 << 1, +}; + +static inline struct device *msm_iommu_get_ctx(const char *ctx_name) +{ + return NULL; +} + +static int msm_vidc_populate_legacy_context_bank( + struct msm_vidc_platform_resources *res); + +static size_t get_u32_array_num_elements(struct device_node *np, + char *name) +{ + int len; + size_t num_elements = 0; + + if (!of_get_property(np, name, &len)) { + dprintk(VIDC_ERR, "Failed to read %s from device tree\n", + name); + goto fail_read; + } + + num_elements = len / sizeof(u32); + if (num_elements <= 0) { + dprintk(VIDC_ERR, "%s not specified in device tree\n", + name); + goto fail_read; + } + return num_elements; + +fail_read: + return 0; +} + +static inline void msm_vidc_free_allowed_clocks_table( + struct msm_vidc_platform_resources *res) +{ + res->allowed_clks_tbl = NULL; +} + +static inline void msm_vidc_free_cycles_per_mb_table( + struct msm_vidc_platform_resources *res) +{ + res->clock_freq_tbl.clk_prof_entries = NULL; +} + +static inline void msm_vidc_free_reg_table( + struct msm_vidc_platform_resources *res) +{ + res->reg_set.reg_tbl = NULL; +} + +static inline void msm_vidc_free_qdss_addr_table( + struct msm_vidc_platform_resources *res) +{ + res->qdss_addr_set.addr_tbl = NULL; +} + +static inline void msm_vidc_free_bus_vectors( + struct msm_vidc_platform_resources *res) +{ + kfree(res->bus_set.bus_tbl); + res->bus_set.bus_tbl = NULL; + res->bus_set.count = 0; +} + +static inline void msm_vidc_free_buffer_usage_table( + struct msm_vidc_platform_resources *res) +{ + res->buffer_usage_set.buffer_usage_tbl = NULL; +} + +static inline void msm_vidc_free_regulator_table( + struct msm_vidc_platform_resources *res) +{ + int c = 0; + + for (c = 0; c < res->regulator_set.count; ++c) { + struct regulator_info *rinfo = + &res->regulator_set.regulator_tbl[c]; + + rinfo->name = NULL; + } + + res->regulator_set.regulator_tbl = NULL; + res->regulator_set.count = 0; +} + +static inline void msm_vidc_free_clock_table( + struct msm_vidc_platform_resources *res) +{ + res->clock_set.clock_tbl = NULL; + res->clock_set.count = 0; +} + +void msm_vidc_free_platform_resources( + struct msm_vidc_platform_resources *res) +{ + msm_vidc_free_clock_table(res); + msm_vidc_free_regulator_table(res); + msm_vidc_free_allowed_clocks_table(res); + msm_vidc_free_reg_table(res); + msm_vidc_free_qdss_addr_table(res); + msm_vidc_free_bus_vectors(res); + msm_vidc_free_buffer_usage_table(res); +} + +static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res) +{ + struct reg_set *reg_set; + struct platform_device *pdev = res->pdev; + int i; + int rc = 0; + + if (!of_find_property(pdev->dev.of_node, "qcom,reg-presets", NULL)) { + /* + * qcom,reg-presets is an optional property. It likely won't be + * present if we don't have any register settings to program + */ + dprintk(VIDC_DBG, "qcom,reg-presets not found\n"); + return 0; + } + + reg_set = &res->reg_set; + reg_set->count = get_u32_array_num_elements(pdev->dev.of_node, + "qcom,reg-presets"); + reg_set->count /= sizeof(*reg_set->reg_tbl) / sizeof(u32); + + if (!reg_set->count) { + dprintk(VIDC_DBG, "no elements in reg set\n"); + return rc; + } + + reg_set->reg_tbl = devm_kzalloc(&pdev->dev, reg_set->count * + sizeof(*(reg_set->reg_tbl)), GFP_KERNEL); + if (!reg_set->reg_tbl) { + dprintk(VIDC_ERR, "%s Failed to alloc register table\n", + __func__); + return -ENOMEM; + } + + if (of_property_read_u32_array(pdev->dev.of_node, "qcom,reg-presets", + (u32 *)reg_set->reg_tbl, reg_set->count * 2)) { + dprintk(VIDC_ERR, "Failed to read register table\n"); + msm_vidc_free_reg_table(res); + return -EINVAL; + } + for (i = 0; i < reg_set->count; i++) { + dprintk(VIDC_DBG, + "reg = %x, value = %x\n", + reg_set->reg_tbl[i].reg, + reg_set->reg_tbl[i].value + ); + } + return rc; +} +static int msm_vidc_load_qdss_table(struct msm_vidc_platform_resources *res) +{ + struct addr_set *qdss_addr_set; + struct platform_device *pdev = res->pdev; + int i; + int rc = 0; + + if (!of_find_property(pdev->dev.of_node, "qcom,qdss-presets", NULL)) { + /* + * qcom,qdss-presets is an optional property. It likely won't be + * present if we don't have any register settings to program + */ + dprintk(VIDC_DBG, "qcom,qdss-presets not found\n"); + return rc; + } + + qdss_addr_set = &res->qdss_addr_set; + qdss_addr_set->count = get_u32_array_num_elements(pdev->dev.of_node, + "qcom,qdss-presets"); + qdss_addr_set->count /= sizeof(*qdss_addr_set->addr_tbl) / sizeof(u32); + + if (!qdss_addr_set->count) { + dprintk(VIDC_DBG, "no elements in qdss reg set\n"); + return rc; + } + + qdss_addr_set->addr_tbl = devm_kzalloc(&pdev->dev, + qdss_addr_set->count * sizeof(*qdss_addr_set->addr_tbl), + GFP_KERNEL); + if (!qdss_addr_set->addr_tbl) { + dprintk(VIDC_ERR, "%s Failed to alloc register table\n", + __func__); + rc = -ENOMEM; + goto err_qdss_addr_tbl; + } + + rc = of_property_read_u32_array(pdev->dev.of_node, "qcom,qdss-presets", + (u32 *)qdss_addr_set->addr_tbl, qdss_addr_set->count * 2); + if (rc) { + dprintk(VIDC_ERR, "Failed to read qdss address table\n"); + msm_vidc_free_qdss_addr_table(res); + rc = -EINVAL; + goto err_qdss_addr_tbl; + } + + for (i = 0; i < qdss_addr_set->count; i++) { + dprintk(VIDC_DBG, "qdss addr = %x, value = %x\n", + qdss_addr_set->addr_tbl[i].start, + qdss_addr_set->addr_tbl[i].size); + } +err_qdss_addr_tbl: + return rc; +} + +static int msm_vidc_load_subcache_info(struct msm_vidc_platform_resources *res) +{ + int rc = 0, num_subcaches = 0, c; + struct platform_device *pdev = res->pdev; + struct subcache_set *subcaches = &res->subcache_set; + + num_subcaches = of_property_count_strings(pdev->dev.of_node, + "cache-slice-names"); + if (num_subcaches <= 0) { + dprintk(VIDC_DBG, "No subcaches found\n"); + goto err_load_subcache_table_fail; + } + + subcaches->subcache_tbl = devm_kzalloc(&pdev->dev, + sizeof(*subcaches->subcache_tbl) * num_subcaches, GFP_KERNEL); + if (!subcaches->subcache_tbl) { + dprintk(VIDC_ERR, + "Failed to allocate memory for subcache tbl\n"); + rc = -ENOMEM; + goto err_load_subcache_table_fail; + } + + subcaches->count = num_subcaches; + dprintk(VIDC_DBG, "Found %d subcaches\n", num_subcaches); + + for (c = 0; c < num_subcaches; ++c) { + struct subcache_info *vsc = &res->subcache_set.subcache_tbl[c]; + + of_property_read_string_index(pdev->dev.of_node, + "cache-slice-names", c, &vsc->name); + } + + res->sys_cache_present = true; + + return 0; + +err_load_subcache_table_fail: + res->sys_cache_present = false; + subcaches->count = 0; + subcaches->subcache_tbl = NULL; + + return rc; +} + +/** + * msm_vidc_load_u32_table() - load dtsi table entries + * @pdev: A pointer to the platform device. + * @of_node: A pointer to the device node. + * @table_name: A pointer to the dtsi table entry name. + * @struct_size: The size of the structure which is nothing but + * a single entry in the dtsi table. + * @table: A pointer to the table pointer which needs to be + * filled by the dtsi table entries. + * @num_elements: Number of elements pointer which needs to be filled + * with the number of elements in the table. + * + * This is a generic implementation to load single or multiple array + * table from dtsi. The array elements should be of size equal to u32. + * + * Return: Return '0' for success else appropriate error value. + */ +int msm_vidc_load_u32_table(struct platform_device *pdev, + struct device_node *of_node, char *table_name, int struct_size, + u32 **table, u32 *num_elements) +{ + int rc = 0, num_elemts = 0; + u32 *ptbl = NULL; + + if (!of_find_property(of_node, table_name, NULL)) { + dprintk(VIDC_DBG, "%s not found\n", table_name); + return 0; + } + + num_elemts = get_u32_array_num_elements(of_node, table_name); + if (!num_elemts) { + dprintk(VIDC_ERR, "no elements in %s\n", table_name); + return 0; + } + num_elemts /= struct_size / sizeof(u32); + + ptbl = devm_kzalloc(&pdev->dev, num_elemts * struct_size, GFP_KERNEL); + if (!ptbl) { + dprintk(VIDC_ERR, "Failed to alloc table %s\n", table_name); + return -ENOMEM; + } + + if (of_property_read_u32_array(of_node, table_name, ptbl, + num_elemts * struct_size / sizeof(u32))) { + dprintk(VIDC_ERR, "Failed to read %s\n", table_name); + return -EINVAL; + } + + *table = ptbl; + if (num_elements) + *num_elements = num_elemts; + + return rc; +} +EXPORT_SYMBOL(msm_vidc_load_u32_table); + +/* A comparator to compare loads (needed later on) */ +static int cmp(const void *a, const void *b) +{ + /* want to sort in reverse so flip the comparison */ + return ((struct allowed_clock_rates_table *)b)->clock_rate - + ((struct allowed_clock_rates_table *)a)->clock_rate; +} + +static int msm_vidc_load_allowed_clocks_table( + struct msm_vidc_platform_resources *res) +{ + int rc = 0; + struct platform_device *pdev = res->pdev; + + if (!of_find_property(pdev->dev.of_node, + "qcom,allowed-clock-rates", NULL)) { + dprintk(VIDC_DBG, "qcom,allowed-clock-rates not found\n"); + return 0; + } + + rc = msm_vidc_load_u32_table(pdev, pdev->dev.of_node, + "qcom,allowed-clock-rates", + sizeof(*res->allowed_clks_tbl), + (u32 **)&res->allowed_clks_tbl, + &res->allowed_clks_tbl_size); + if (rc) { + dprintk(VIDC_ERR, + "%s: failed to read allowed clocks table\n", __func__); + return rc; + } + + sort(res->allowed_clks_tbl, res->allowed_clks_tbl_size, + sizeof(*res->allowed_clks_tbl), cmp, NULL); + + return 0; +} + +static int msm_vidc_populate_mem_cdsp(struct device *dev, + struct msm_vidc_platform_resources *res) +{ + res->mem_cdsp.dev = dev; + + return 0; +} + +static int msm_vidc_populate_bus(struct device *dev, + struct msm_vidc_platform_resources *res) +{ + struct bus_set *buses = &res->bus_set; + const char *temp_name = NULL; + struct bus_info *bus = NULL, *temp_table; + u32 range[2]; + int rc = 0; + + temp_table = krealloc(buses->bus_tbl, sizeof(*temp_table) * + (buses->count + 1), GFP_KERNEL); + if (!temp_table) { + dprintk(VIDC_ERR, "%s: Failed to allocate memory", __func__); + rc = -ENOMEM; + goto err_bus; + } + + buses->bus_tbl = temp_table; + bus = &buses->bus_tbl[buses->count]; + + memset(bus, 0x0, sizeof(struct bus_info)); + + rc = of_property_read_string(dev->of_node, "label", &temp_name); + if (rc) { + dprintk(VIDC_ERR, "'label' not found in node\n"); + goto err_bus; + } + /* need a non-const version of name, hence copying it over */ + bus->name = devm_kstrdup(dev, temp_name, GFP_KERNEL); + if (!bus->name) { + rc = -ENOMEM; + goto err_bus; + } + + rc = of_property_read_u32(dev->of_node, "qcom,bus-master", + &bus->master); + if (rc) { + dprintk(VIDC_ERR, "'qcom,bus-master' not found in node\n"); + goto err_bus; + } + + rc = of_property_read_u32(dev->of_node, "qcom,bus-slave", &bus->slave); + if (rc) { + dprintk(VIDC_ERR, "'qcom,bus-slave' not found in node\n"); + goto err_bus; + } + + rc = of_property_read_string(dev->of_node, "qcom,mode", + &bus->mode); + + if (!rc && !strcmp(bus->mode, "performance")) + bus->is_prfm_mode = true; + + rc = of_property_read_u32_array(dev->of_node, "qcom,bus-range-kbps", + range, ARRAY_SIZE(range)); + if (rc) { + rc = 0; + dprintk(VIDC_DBG, + "'qcom,range' not found defaulting to <0 INT_MAX>\n"); + range[0] = 0; + range[1] = INT_MAX; + } + + bus->range[0] = range[0]; /* min */ + bus->range[1] = range[1]; /* max */ + + buses->count++; + bus->dev = dev; + dprintk(VIDC_DBG, "Found bus %s [%d->%d] with mode %s\n", + bus->name, bus->master, bus->slave, bus->mode); +err_bus: + return rc; +} + +static int msm_vidc_load_buffer_usage_table( + struct msm_vidc_platform_resources *res) +{ + int rc = 0; + struct platform_device *pdev = res->pdev; + struct buffer_usage_set *buffer_usage_set = &res->buffer_usage_set; + + if (!of_find_property(pdev->dev.of_node, + "qcom,buffer-type-tz-usage-table", NULL)) { + /* + * qcom,buffer-type-tz-usage-table is an optional property. It + * likely won't be present if the core doesn't support content + * protection + */ + dprintk(VIDC_DBG, "buffer-type-tz-usage-table not found\n"); + return 0; + } + + buffer_usage_set->count = get_u32_array_num_elements( + pdev->dev.of_node, "qcom,buffer-type-tz-usage-table"); + buffer_usage_set->count /= + sizeof(*buffer_usage_set->buffer_usage_tbl) / sizeof(u32); + if (!buffer_usage_set->count) { + dprintk(VIDC_DBG, "no elements in buffer usage set\n"); + return 0; + } + + buffer_usage_set->buffer_usage_tbl = devm_kzalloc(&pdev->dev, + buffer_usage_set->count * + sizeof(*buffer_usage_set->buffer_usage_tbl), + GFP_KERNEL); + if (!buffer_usage_set->buffer_usage_tbl) { + dprintk(VIDC_ERR, "%s Failed to alloc buffer usage table\n", + __func__); + rc = -ENOMEM; + goto err_load_buf_usage; + } + + rc = of_property_read_u32_array(pdev->dev.of_node, + "qcom,buffer-type-tz-usage-table", + (u32 *)buffer_usage_set->buffer_usage_tbl, + buffer_usage_set->count * + sizeof(*buffer_usage_set->buffer_usage_tbl) / sizeof(u32)); + if (rc) { + dprintk(VIDC_ERR, "Failed to read buffer usage table\n"); + goto err_load_buf_usage; + } + + return 0; +err_load_buf_usage: + msm_vidc_free_buffer_usage_table(res); + return rc; +} + +static int msm_vidc_load_regulator_table( + struct msm_vidc_platform_resources *res) +{ + int rc = 0; + struct platform_device *pdev = res->pdev; + struct regulator_set *regulators = &res->regulator_set; + struct device_node *domains_parent_node = NULL; + struct property *domains_property = NULL; + int reg_count = 0; + + regulators->count = 0; + regulators->regulator_tbl = NULL; + + domains_parent_node = pdev->dev.of_node; + for_each_property_of_node(domains_parent_node, domains_property) { + const char *search_string = "-supply"; + char *supply; + bool matched = false; + + /* check if current property is possibly a regulator */ + supply = strnstr(domains_property->name, search_string, + strlen(domains_property->name) + 1); + matched = supply && (*(supply + strlen(search_string)) == '\0'); + if (!matched) + continue; + + reg_count++; + } + + regulators->regulator_tbl = devm_kzalloc(&pdev->dev, + sizeof(*regulators->regulator_tbl) * + reg_count, GFP_KERNEL); + + if (!regulators->regulator_tbl) { + rc = -ENOMEM; + dprintk(VIDC_ERR, + "Failed to alloc memory for regulator table\n"); + goto err_reg_tbl_alloc; + } + + for_each_property_of_node(domains_parent_node, domains_property) { + const char *search_string = "-supply"; + char *supply; + bool matched = false; + struct device_node *regulator_node = NULL; + struct regulator_info *rinfo = NULL; + + /* check if current property is possibly a regulator */ + supply = strnstr(domains_property->name, search_string, + strlen(domains_property->name) + 1); + matched = supply && (supply[strlen(search_string)] == '\0'); + if (!matched) + continue; + + /* make sure prop isn't being misused */ + regulator_node = of_parse_phandle(domains_parent_node, + domains_property->name, 0); + if (IS_ERR(regulator_node)) { + dprintk(VIDC_WARN, "%s is not a phandle\n", + domains_property->name); + continue; + } + regulators->count++; + + /* populate regulator info */ + rinfo = ®ulators->regulator_tbl[regulators->count - 1]; + rinfo->name = devm_kzalloc(&pdev->dev, + (supply - domains_property->name) + 1, GFP_KERNEL); + if (!rinfo->name) { + rc = -ENOMEM; + dprintk(VIDC_ERR, + "Failed to alloc memory for regulator name\n"); + goto err_reg_name_alloc; + } + strlcpy(rinfo->name, domains_property->name, + (supply - domains_property->name) + 1); + + rinfo->has_hw_power_collapse = of_property_read_bool( + regulator_node, "qcom,support-hw-trigger"); + + dprintk(VIDC_DBG, "Found regulator %s: h/w collapse = %s\n", + rinfo->name, + rinfo->has_hw_power_collapse ? "yes" : "no"); + } + + if (!regulators->count) + dprintk(VIDC_DBG, "No regulators found"); + + return 0; + +err_reg_name_alloc: +err_reg_tbl_alloc: + msm_vidc_free_regulator_table(res); + return rc; +} + +static int msm_vidc_load_clock_table( + struct msm_vidc_platform_resources *res) +{ + int rc = 0, num_clocks = 0, c = 0; + struct platform_device *pdev = res->pdev; + int *clock_props = NULL; + struct clock_set *clocks = &res->clock_set; + + num_clocks = of_property_count_strings(pdev->dev.of_node, + "clock-names"); + if (num_clocks <= 0) { + dprintk(VIDC_DBG, "No clocks found\n"); + clocks->count = 0; + rc = 0; + goto err_load_clk_table_fail; + } + + clock_props = devm_kzalloc(&pdev->dev, num_clocks * + sizeof(*clock_props), GFP_KERNEL); + if (!clock_props) { + dprintk(VIDC_ERR, "No memory to read clock properties\n"); + rc = -ENOMEM; + goto err_load_clk_table_fail; + } + + rc = of_property_read_u32_array(pdev->dev.of_node, + "qcom,clock-configs", clock_props, + num_clocks); + if (rc) { + dprintk(VIDC_ERR, "Failed to read clock properties: %d\n", rc); + goto err_load_clk_prop_fail; + } + + clocks->clock_tbl = devm_kzalloc(&pdev->dev, sizeof(*clocks->clock_tbl) + * num_clocks, GFP_KERNEL); + if (!clocks->clock_tbl) { + dprintk(VIDC_ERR, "Failed to allocate memory for clock tbl\n"); + rc = -ENOMEM; + goto err_load_clk_prop_fail; + } + + clocks->count = num_clocks; + dprintk(VIDC_DBG, "Found %d clocks\n", num_clocks); + + for (c = 0; c < num_clocks; ++c) { + struct clock_info *vc = &res->clock_set.clock_tbl[c]; + + of_property_read_string_index(pdev->dev.of_node, + "clock-names", c, &vc->name); + + if (clock_props[c] & CLOCK_PROP_HAS_SCALING) { + vc->has_scaling = true; + } else { + vc->has_scaling = false; + } + + if (clock_props[c] & CLOCK_PROP_HAS_MEM_RETENTION) + vc->has_mem_retention = true; + else + vc->has_mem_retention = false; + + dprintk(VIDC_DBG, "Found clock %s: scale-able = %s\n", vc->name, + vc->has_scaling ? "yes" : "no"); + } + + + return 0; + +err_load_clk_prop_fail: +err_load_clk_table_fail: + return rc; +} + +static int msm_vidc_load_reset_table( + struct msm_vidc_platform_resources *res) +{ + struct platform_device *pdev = res->pdev; + struct reset_set *rst = &res->reset_set; + int num_clocks = 0, c = 0; + + num_clocks = of_property_count_strings(pdev->dev.of_node, + "reset-names"); + if (num_clocks <= 0) { + dprintk(VIDC_DBG, "No reset clocks found\n"); + rst->count = 0; + return 0; + } + + rst->reset_tbl = devm_kcalloc(&pdev->dev, num_clocks, + sizeof(*rst->reset_tbl), GFP_KERNEL); + if (!rst->reset_tbl) + return -ENOMEM; + + rst->count = num_clocks; + dprintk(VIDC_DBG, "Found %d reset clocks\n", num_clocks); + + for (c = 0; c < num_clocks; ++c) { + struct reset_info *rc = &res->reset_set.reset_tbl[c]; + + of_property_read_string_index(pdev->dev.of_node, + "reset-names", c, &rc->name); + } + + return 0; +} + +static int msm_decide_dt_node( + struct msm_vidc_platform_resources *res) +{ + struct platform_device *pdev = res->pdev; + int rc = 0; + u32 sku_index = 0; + + rc = of_property_read_u32(pdev->dev.of_node, "sku-index", + &sku_index); + if (rc) { + dprintk(VIDC_DBG, "'sku_index' not found in node\n"); + return 0; + } + + if (sku_index != res->sku_version) { + dprintk(VIDC_DBG, + "Failed to parser dt: sku_index %d res->sku_version - %d\n", + sku_index, res->sku_version); + return -EINVAL; + } + + return 0; +} + +static int find_key_value(struct msm_vidc_platform_data *platform_data, + const char *key) +{ + int i = 0; + struct msm_vidc_common_data *common_data = platform_data->common_data; + int size = platform_data->common_data_length; + + for (i = 0; i < size; i++) { + if (!strcmp(common_data[i].key, key)) + return common_data[i].value; + } + return 0; +} + +int read_platform_resources_from_drv_data( + struct msm_vidc_core *core) +{ + struct msm_vidc_platform_data *platform_data; + struct msm_vidc_platform_resources *res; + int rc = 0; + + if (!core || !core->platform_data) { + dprintk(VIDC_ERR, "%s Invalid data\n", __func__); + return -ENOENT; + } + platform_data = core->platform_data; + res = &core->resources; + + res->codecs = platform_data->codecs; + res->codecs_count = platform_data->codecs_count; + res->codec_caps = platform_data->codec_caps; + res->codec_caps_count = platform_data->codec_caps_count; + res->codec_data_count = platform_data->codec_data_length; + res->codec_data = platform_data->codec_data; + + res->sku_version = platform_data->sku_version; + + res->fw_name = "venus"; + + dprintk(VIDC_DBG, "Firmware filename: %s\n", res->fw_name); + + res->max_load = find_key_value(platform_data, + "qcom,max-hw-load"); + + res->max_hq_mbs_per_frame = find_key_value(platform_data, + "qcom,max-hq-mbs-per-frame"); + + res->max_hq_mbs_per_sec = find_key_value(platform_data, + "qcom,max-hq-mbs-per-sec"); + + res->max_bframe_mbs_per_frame = find_key_value(platform_data, + "qcom,max-b-frame-mbs-per-frame"); + + res->max_bframe_mbs_per_sec = find_key_value(platform_data, + "qcom,max-b-frame-mbs-per-sec"); + + res->sw_power_collapsible = find_key_value(platform_data, + "qcom,sw-power-collapse"); + + res->never_unload_fw = find_key_value(platform_data, + "qcom,never-unload-fw"); + + res->debug_timeout = find_key_value(platform_data, + "qcom,debug-timeout"); + + res->pm_qos_latency_us = find_key_value(platform_data, + "qcom,pm-qos-latency-us"); + + res->max_secure_inst_count = find_key_value(platform_data, + "qcom,max-secure-instances"); + + res->slave_side_cp = find_key_value(platform_data, + "qcom,slave-side-cp"); + res->thermal_mitigable = find_key_value(platform_data, + "qcom,enable-thermal-mitigation"); + res->msm_vidc_pwr_collapse_delay = find_key_value(platform_data, + "qcom,power-collapse-delay"); + res->msm_vidc_firmware_unload_delay = find_key_value(platform_data, + "qcom,fw-unload-delay"); + res->msm_vidc_hw_rsp_timeout = find_key_value(platform_data, + "qcom,hw-resp-timeout"); + res->domain_cvp = find_key_value(platform_data, + "qcom,domain-cvp"); + res->non_fatal_pagefaults = find_key_value(platform_data, + "qcom,domain-attr-non-fatal-faults"); + res->cache_pagetables = find_key_value(platform_data, + "qcom,domain-attr-cache-pagetables"); + res->decode_batching = find_key_value(platform_data, + "qcom,decode-batching"); + res->dcvs = find_key_value(platform_data, + "qcom,dcvs"); + res->fw_cycles = find_key_value(platform_data, + "qcom,fw-cycles"); + res->fw_vpp_cycles = find_key_value(platform_data, + "qcom,fw-vpp-cycles"); + + res->csc_coeff_data = &platform_data->csc_data; + + res->vpu_ver = platform_data->vpu_ver; + res->ubwc_config = platform_data->ubwc_config; + + return rc; + +} + +int read_platform_resources_from_dt( + struct msm_vidc_platform_resources *res) +{ + struct platform_device *pdev = res->pdev; + struct resource *kres = NULL; + int rc = 0; + uint32_t firmware_base = 0; + + if (!pdev->dev.of_node) { + dprintk(VIDC_ERR, "DT node not found\n"); + return -ENOENT; + } + + rc = msm_decide_dt_node(res); + if (rc) + return rc; + + + INIT_LIST_HEAD(&res->context_banks); + + res->firmware_base = (phys_addr_t)firmware_base; + + kres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + res->register_base = kres ? kres->start : -1; + res->register_size = kres ? (kres->end + 1 - kres->start) : -1; + + kres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + res->irq = kres ? kres->start : -1; + + rc = msm_vidc_load_subcache_info(res); + if (rc) + dprintk(VIDC_WARN, "Failed to load subcache info: %d\n", rc); + + rc = msm_vidc_load_qdss_table(res); + if (rc) + dprintk(VIDC_WARN, "Failed to load qdss reg table: %d\n", rc); + + rc = msm_vidc_load_reg_table(res); + if (rc) { + dprintk(VIDC_ERR, "Failed to load reg table: %d\n", rc); + goto err_load_reg_table; + } + + rc = msm_vidc_load_buffer_usage_table(res); + if (rc) { + dprintk(VIDC_ERR, + "Failed to load buffer usage table: %d\n", rc); + goto err_load_buffer_usage_table; + } + + rc = msm_vidc_load_regulator_table(res); + if (rc) { + dprintk(VIDC_ERR, "Failed to load list of regulators %d\n", rc); + goto err_load_regulator_table; + } + + rc = msm_vidc_load_clock_table(res); + if (rc) { + dprintk(VIDC_ERR, + "Failed to load clock table: %d\n", rc); + goto err_load_clock_table; + } + + rc = msm_vidc_load_allowed_clocks_table(res); + if (rc) { + dprintk(VIDC_ERR, + "Failed to load allowed clocks table: %d\n", rc); + goto err_load_allowed_clocks_table; + } + + rc = msm_vidc_load_reset_table(res); + if (rc) { + dprintk(VIDC_ERR, + "Failed to load reset table: %d\n", rc); + goto err_load_reset_table; + } + + rc = msm_vidc_populate_legacy_context_bank(res); + if (rc) { + dprintk(VIDC_ERR, + "Failed to setup context banks %d\n", rc); + goto err_setup_legacy_cb; + } + +return rc; + +err_load_reset_table: +err_setup_legacy_cb: + msm_vidc_free_allowed_clocks_table(res); +err_load_allowed_clocks_table: + msm_vidc_free_clock_table(res); +err_load_clock_table: + msm_vidc_free_regulator_table(res); +err_load_regulator_table: + msm_vidc_free_buffer_usage_table(res); +err_load_buffer_usage_table: + msm_vidc_free_reg_table(res); +err_load_reg_table: + return rc; +} + +static int msm_vidc_setup_context_bank(struct msm_vidc_platform_resources *res, + struct context_bank_info *cb, struct device *dev) +{ + int rc = 0; + struct bus_type *bus; + + if (!dev || !cb || !res) { + dprintk(VIDC_ERR, + "%s: Invalid Input params\n", __func__); + return -EINVAL; + } + cb->dev = dev; + + bus = cb->dev->bus; + if (IS_ERR_OR_NULL(bus)) { + dprintk(VIDC_ERR, "%s - failed to get bus type\n", __func__); + rc = PTR_ERR(bus) ? PTR_ERR(bus) : -ENODEV; + goto remove_cb; + } + + cb->domain = iommu_get_domain_for_dev(cb->dev); + + /* + * configure device segment size and segment boundary to ensure + * iommu mapping returns one mapping (which is required for partial + * cache operations) + */ + if (!dev->dma_parms) + dev->dma_parms = + devm_kzalloc(dev, sizeof(*dev->dma_parms), GFP_KERNEL); + dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); + dma_set_seg_boundary(dev, DMA_BIT_MASK(64)); + + dprintk(VIDC_DBG, "Attached %s and created mapping\n", dev_name(dev)); + dprintk(VIDC_DBG, + "Context bank name:%s, buffer_type: %#x, is_secure: %d, address range start: %#x, size: %#x, dev: %pK, domain: %pK", + cb->name, cb->buffer_type, cb->is_secure, cb->addr_range.start, + cb->addr_range.size, cb->dev, cb->domain); + +remove_cb: + return rc; +} + +int msm_vidc_smmu_fault_handler(struct iommu_domain *domain, + struct device *dev, unsigned long iova, int flags, void *token) +{ + struct msm_vidc_core *core = token; + struct msm_vidc_inst *inst; + + if (!domain || !core) { + dprintk(VIDC_ERR, "%s - invalid param %pK %pK\n", + __func__, domain, core); + return -EINVAL; + } + + if (core->smmu_fault_handled) { + if (core->resources.non_fatal_pagefaults) { + dprintk_ratelimit(VIDC_ERR, + "%s: non-fatal pagefault address: %lx\n", + __func__, iova); + return 0; + } + } + + dprintk(VIDC_ERR, "%s - faulting address: %lx\n", __func__, iova); + + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) { + msm_comm_print_inst_info(inst); + } + core->smmu_fault_handled = true; + mutex_unlock(&core->lock); + /* + * Return -EINVAL to elicit the default behaviour of smmu driver. + * If we return -EINVAL, then smmu driver assumes page fault handler + * is not installed and prints a list of useful debug information like + * FAR, SID etc. This information is not printed if we return 0. + */ + return -EINVAL; +} + +static int msm_vidc_populate_context_bank(struct device *dev, + struct msm_vidc_core *core) +{ + int rc = 0; + struct context_bank_info *cb = NULL; + struct device_node *np = NULL; + + if (!dev || !core) { + dprintk(VIDC_ERR, "%s - invalid inputs\n", __func__); + return -EINVAL; + } + + np = dev->of_node; + cb = devm_kzalloc(dev, sizeof(*cb), GFP_KERNEL); + if (!cb) { + dprintk(VIDC_ERR, "%s - Failed to allocate cb\n", __func__); + return -ENOMEM; + } + + INIT_LIST_HEAD(&cb->list); + list_add_tail(&cb->list, &core->resources.context_banks); + + rc = of_property_read_string(np, "label", &cb->name); + if (rc) { + dprintk(VIDC_DBG, + "Failed to read cb label from device tree\n"); + rc = 0; + } + + dprintk(VIDC_DBG, "%s: context bank has name %s\n", __func__, cb->name); + rc = of_property_read_u32_array(np, "virtual-addr-pool", + (u32 *)&cb->addr_range, 2); + if (rc) { + dprintk(VIDC_ERR, + "Could not read addr pool for context bank : %s %d\n", + cb->name, rc); + goto err_setup_cb; + } + + cb->is_secure = of_property_read_bool(np, "qcom,secure-context-bank"); + dprintk(VIDC_DBG, "context bank %s : secure = %d\n", + cb->name, cb->is_secure); + + /* setup buffer type for each sub device*/ + rc = of_property_read_u32(np, "buffer-types", &cb->buffer_type); + if (rc) { + dprintk(VIDC_ERR, "failed to load buffer_type info %d\n", rc); + rc = -ENOENT; + goto err_setup_cb; + } + dprintk(VIDC_DBG, + "context bank %s address start = %x address size = %x buffer_type = %x\n", + cb->name, cb->addr_range.start, + cb->addr_range.size, cb->buffer_type); + + rc = msm_vidc_setup_context_bank(&core->resources, cb, dev); + if (rc) { + dprintk(VIDC_ERR, "Cannot setup context bank %d\n", rc); + goto err_setup_cb; + } + + iommu_set_fault_handler(cb->domain, + msm_vidc_smmu_fault_handler, (void *)core); + + return 0; + +err_setup_cb: + list_del(&cb->list); + return rc; +} + +static int msm_vidc_populate_legacy_context_bank( + struct msm_vidc_platform_resources *res) +{ + int rc = 0; + struct platform_device *pdev = NULL; + struct device_node *domains_parent_node = NULL; + struct device_node *domains_child_node = NULL; + struct device_node *ctx_node = NULL; + struct context_bank_info *cb; + + if (!res || !res->pdev) { + dprintk(VIDC_ERR, "%s - invalid inputs\n", __func__); + return -EINVAL; + } + pdev = res->pdev; + + domains_parent_node = of_find_node_by_name(pdev->dev.of_node, + "qcom,vidc-iommu-domains"); + if (!domains_parent_node) { + dprintk(VIDC_DBG, + "%s legacy iommu domains not present\n", __func__); + return 0; + } + + /* set up each context bank for legacy DT bindings*/ + for_each_child_of_node(domains_parent_node, + domains_child_node) { + cb = devm_kzalloc(&pdev->dev, sizeof(*cb), GFP_KERNEL); + if (!cb) { + dprintk(VIDC_ERR, + "%s - Failed to allocate cb\n", __func__); + return -ENOMEM; + } + INIT_LIST_HEAD(&cb->list); + list_add_tail(&cb->list, &res->context_banks); + + ctx_node = of_parse_phandle(domains_child_node, + "qcom,vidc-domain-phandle", 0); + if (!ctx_node) { + dprintk(VIDC_ERR, + "%s Unable to parse pHandle\n", __func__); + rc = -EBADHANDLE; + goto err_setup_cb; + } + + rc = of_property_read_string(ctx_node, "label", &(cb->name)); + if (rc) { + dprintk(VIDC_ERR, + "%s Could not find label\n", __func__); + goto err_setup_cb; + } + + rc = of_property_read_u32_array(ctx_node, + "qcom,virtual-addr-pool", (u32 *)&cb->addr_range, 2); + if (rc) { + dprintk(VIDC_ERR, + "%s Could not read addr pool for group : %s (%d)\n", + __func__, cb->name, rc); + goto err_setup_cb; + } + + cb->is_secure = + of_property_read_bool(ctx_node, "qcom,secure-domain"); + + rc = of_property_read_u32(domains_child_node, + "qcom,vidc-buffer-types", &cb->buffer_type); + if (rc) { + dprintk(VIDC_ERR, + "%s Could not read buffer type (%d)\n", + __func__, rc); + goto err_setup_cb; + } + + cb->dev = msm_iommu_get_ctx(cb->name); + if (IS_ERR_OR_NULL(cb->dev)) { + dprintk(VIDC_ERR, "%s could not get device for cb %s\n", + __func__, cb->name); + rc = -ENOENT; + goto err_setup_cb; + } + + rc = msm_vidc_setup_context_bank(res, cb, cb->dev); + if (rc) { + dprintk(VIDC_ERR, "Cannot setup context bank %d\n", rc); + goto err_setup_cb; + } + dprintk(VIDC_DBG, + "%s: context bank %s secure %d addr start = %#x addr size = %#x buffer_type = %#x\n", + __func__, cb->name, cb->is_secure, cb->addr_range.start, + cb->addr_range.size, cb->buffer_type); + } + return rc; + +err_setup_cb: + list_del(&cb->list); + return rc; +} + +int read_context_bank_resources_from_dt(struct platform_device *pdev) +{ + struct msm_vidc_core *core; + int rc = 0; + + if (!pdev) { + dprintk(VIDC_ERR, "Invalid platform device\n"); + return -EINVAL; + } else if (!pdev->dev.parent) { + dprintk(VIDC_ERR, "Failed to find a parent for %s\n", + dev_name(&pdev->dev)); + return -ENODEV; + } + + core = dev_get_drvdata(pdev->dev.parent); + if (!core) { + dprintk(VIDC_ERR, "Failed to find cookie in parent device %s", + dev_name(pdev->dev.parent)); + return -EINVAL; + } + + rc = msm_vidc_populate_context_bank(&pdev->dev, core); + if (rc) + dprintk(VIDC_ERR, "Failed to probe context bank\n"); + else + dprintk(VIDC_DBG, "Successfully probed context bank\n"); + + return rc; +} + +int read_bus_resources_from_dt(struct platform_device *pdev) +{ + struct msm_vidc_core *core; + + if (!pdev) { + dprintk(VIDC_ERR, "Invalid platform device\n"); + return -EINVAL; + } else if (!pdev->dev.parent) { + dprintk(VIDC_ERR, "Failed to find a parent for %s\n", + dev_name(&pdev->dev)); + return -ENODEV; + } + + core = dev_get_drvdata(pdev->dev.parent); + if (!core) { + dprintk(VIDC_ERR, "Failed to find cookie in parent device %s", + dev_name(pdev->dev.parent)); + return -EINVAL; + } + + return msm_vidc_populate_bus(&pdev->dev, &core->resources); +} + +int read_mem_cdsp_resources_from_dt(struct platform_device *pdev) +{ + struct msm_vidc_core *core; + + if (!pdev) { + dprintk(VIDC_ERR, "%s: invalid platform device\n", __func__); + return -EINVAL; + } else if (!pdev->dev.parent) { + dprintk(VIDC_ERR, "Failed to find a parent for %s\n", + dev_name(&pdev->dev)); + return -ENODEV; + } + + core = dev_get_drvdata(pdev->dev.parent); + if (!core) { + dprintk(VIDC_ERR, "Failed to find cookie in parent device %s", + dev_name(pdev->dev.parent)); + return -EINVAL; + } + + return msm_vidc_populate_mem_cdsp(&pdev->dev, &core->resources); +} diff --git a/msm/vidc/msm_vidc_res_parse.h b/msm/vidc/msm_vidc_res_parse.h new file mode 100644 index 000000000000..5254d2900c07 --- /dev/null +++ b/msm/vidc/msm_vidc_res_parse.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + */ + +#ifndef DT_PARSE +#define DT_PARSE +#include +#include "msm_vidc_resources.h" +#include "msm_vidc_common.h" +void msm_vidc_free_platform_resources( + struct msm_vidc_platform_resources *res); + +int read_hfi_type(struct platform_device *pdev); + +int read_platform_resources_from_drv_data( + struct msm_vidc_core *core); +int read_platform_resources_from_dt( + struct msm_vidc_platform_resources *res); + +int read_context_bank_resources_from_dt(struct platform_device *pdev); + +int read_bus_resources_from_dt(struct platform_device *pdev); +int read_mem_cdsp_resources_from_dt(struct platform_device *pdev); + +int msm_vidc_load_u32_table(struct platform_device *pdev, + struct device_node *of_node, char *table_name, int struct_size, + u32 **table, u32 *num_elements); + +#endif diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h new file mode 100644 index 000000000000..7043b81d396b --- /dev/null +++ b/msm/vidc/msm_vidc_resources.h @@ -0,0 +1,216 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef __MSM_VIDC_RESOURCES_H__ +#define __MSM_VIDC_RESOURCES_H__ + +#include +#include "msm_vidc.h" +#include + +#define MAX_BUFFER_TYPES 32 + +struct dcvs_table { + u32 load; + u32 load_low; + u32 load_high; + u32 supported_codecs; +}; + +struct dcvs_limit { + u32 min_mbpf; + u32 fps; +}; + +struct reg_value_pair { + u32 reg; + u32 value; +}; + +struct reg_set { + struct reg_value_pair *reg_tbl; + int count; +}; + +struct addr_range { + u32 start; + u32 size; +}; + +struct addr_set { + struct addr_range *addr_tbl; + int count; +}; + +struct context_bank_info { + struct list_head list; + const char *name; + u32 buffer_type; + bool is_secure; + struct addr_range addr_range; + struct device *dev; + struct iommu_domain *domain; +}; + +struct buffer_usage_table { + u32 buffer_type; + u32 tz_usage; +}; + +struct buffer_usage_set { + struct buffer_usage_table *buffer_usage_tbl; + u32 count; +}; + +struct regulator_info { + struct regulator *regulator; + bool has_hw_power_collapse; + char *name; +}; + +struct regulator_set { + struct regulator_info *regulator_tbl; + u32 count; +}; + +struct clock_info { + const char *name; + struct clk *clk; + u32 count; + bool has_scaling; + bool has_mem_retention; +}; + +struct clock_set { + struct clock_info *clock_tbl; + u32 count; +}; + +struct bus_info { + char *name; + int master; + int slave; + unsigned int range[2]; + struct device *dev; + struct msm_bus_client_handle *client; + bool is_prfm_mode; + const char *mode; +}; + +struct bus_set { + struct bus_info *bus_tbl; + u32 count; +}; + +struct reset_info { + struct reset_control *rst; + const char *name; +}; + +struct reset_set { + struct reset_info *reset_tbl; + u32 count; +}; + +struct allowed_clock_rates_table { + u32 clock_rate; +}; + +struct clock_profile_entry { + u32 codec_mask; + u32 vpp_cycles; + u32 vsp_cycles; + u32 low_power_cycles; +}; + +struct clock_freq_table { + struct clock_profile_entry *clk_prof_entries; + u32 count; +}; + +struct subcache_info { + const char *name; + bool isactive; + bool isset; + struct llcc_slice_desc *subcache; +}; + +struct subcache_set { + struct subcache_info *subcache_tbl; + u32 count; +}; + +struct msm_vidc_mem_cdsp { + struct device *dev; +}; + +struct msm_vidc_platform_resources { + phys_addr_t firmware_base; + phys_addr_t register_base; + uint32_t register_size; + uint32_t irq; + uint32_t sku_version; + struct allowed_clock_rates_table *allowed_clks_tbl; + u32 allowed_clks_tbl_size; + struct clock_freq_table clock_freq_tbl; + struct dcvs_table *dcvs_tbl; + uint32_t dcvs_tbl_size; + struct dcvs_limit *dcvs_limit; + bool sys_cache_present; + bool sys_cache_res_set; + struct subcache_set subcache_set; + struct reg_set reg_set; + struct addr_set qdss_addr_set; + struct buffer_usage_set buffer_usage_set; + uint32_t max_load; + uint32_t max_hq_mbs_per_frame; + uint32_t max_hq_mbs_per_sec; + uint32_t max_bframe_mbs_per_frame; + uint32_t max_bframe_mbs_per_sec; + struct platform_device *pdev; + struct regulator_set regulator_set; + struct clock_set clock_set; + struct bus_set bus_set; + struct reset_set reset_set; + bool sw_power_collapsible; + bool slave_side_cp; + struct list_head context_banks; + bool thermal_mitigable; + const char *fw_name; + const char *hfi_version; + bool never_unload_fw; + bool debug_timeout; + uint32_t pm_qos_latency_us; + uint32_t max_inst_count; + uint32_t max_secure_inst_count; + int msm_vidc_hw_rsp_timeout; + int msm_vidc_firmware_unload_delay; + uint32_t msm_vidc_pwr_collapse_delay; + bool domain_cvp; + bool non_fatal_pagefaults; + bool cache_pagetables; + bool decode_batching; + bool dcvs; + struct msm_vidc_codec_data *codec_data; + int codec_data_count; + struct msm_vidc_codec *codecs; + uint32_t codecs_count; + struct msm_vidc_codec_capability *codec_caps; + uint32_t codec_caps_count; + struct msm_vidc_csc_coeff *csc_coeff_data; + struct msm_vidc_mem_cdsp mem_cdsp; + uint32_t vpu_ver; + uint32_t fw_cycles; + uint32_t fw_vpp_cycles; + struct msm_vidc_ubwc_config_data *ubwc_config; +}; + +static inline bool is_iommu_present(struct msm_vidc_platform_resources *res) +{ + return !list_empty(&res->context_banks); +} + +#endif + diff --git a/msm/vidc/venus_hfi.c b/msm/vidc/venus_hfi.c new file mode 100644 index 000000000000..43b6a7f08f32 --- /dev/null +++ b/msm/vidc/venus_hfi.c @@ -0,0 +1,5203 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hfi_packetization.h" +#include "msm_vidc_debug.h" +#include "venus_hfi.h" +#include "vidc_hfi_io.h" + +#define FIRMWARE_SIZE 0X00A00000 +#define REG_ADDR_OFFSET_BITMASK 0x000FFFFF +#define QDSS_IOVA_START 0x80001000 + +static struct hal_device_data hal_ctxt; + +#define TZBSP_MEM_PROTECT_VIDEO_VAR 0x8 +struct tzbsp_memprot { + u32 cp_start; + u32 cp_size; + u32 cp_nonpixel_start; + u32 cp_nonpixel_size; +}; + +struct tzbsp_resp { + int ret; +}; + +#define TZBSP_VIDEO_SET_STATE 0xa + +/* Poll interval in uS */ +#define POLL_INTERVAL_US 50 + +enum tzbsp_video_state { + TZBSP_VIDEO_STATE_SUSPEND = 0, + TZBSP_VIDEO_STATE_RESUME = 1, + TZBSP_VIDEO_STATE_RESTORE_THRESHOLD = 2, +}; + +struct tzbsp_video_set_state_req { + u32 state; /* should be tzbsp_video_state enum value */ + u32 spare; /* reserved for future, should be zero */ +}; + +const struct msm_vidc_bus_data DEFAULT_BUS_VOTE = { + .data = NULL, + .data_count = 0, +}; + +const int max_packets = 1000; + +static void venus_hfi_pm_handler(struct work_struct *work); +static DECLARE_DELAYED_WORK(venus_hfi_pm_work, venus_hfi_pm_handler); +static inline int __resume(struct venus_hfi_device *device); +static inline int __suspend(struct venus_hfi_device *device); +static int __disable_regulators(struct venus_hfi_device *device); +static int __enable_regulators(struct venus_hfi_device *device); +static inline int __prepare_enable_clks(struct venus_hfi_device *device); +static inline void __disable_unprepare_clks(struct venus_hfi_device *device); +static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet); +static int __initialize_packetization(struct venus_hfi_device *device); +static struct hal_session *__get_session(struct venus_hfi_device *device, + u32 session_id); +static bool __is_session_valid(struct venus_hfi_device *device, + struct hal_session *session, const char *func); +static int __set_clocks(struct venus_hfi_device *device, u32 freq); +static int __iface_cmdq_write(struct venus_hfi_device *device, + void *pkt); +static int __load_fw(struct venus_hfi_device *device); +static void __unload_fw(struct venus_hfi_device *device); +static int __tzbsp_set_video_state(enum tzbsp_video_state state); +static int __enable_subcaches(struct venus_hfi_device *device); +static int __set_subcaches(struct venus_hfi_device *device); +static int __release_subcaches(struct venus_hfi_device *device); +static int __disable_subcaches(struct venus_hfi_device *device); +static int __power_collapse(struct venus_hfi_device *device, bool force); +static int venus_hfi_noc_error_info(void *dev); + +static void interrupt_init_vpu4(struct venus_hfi_device *device); +static void interrupt_init_iris1(struct venus_hfi_device *device); +static void setup_dsp_uc_memmap_iris1(struct venus_hfi_device *device); +static void clock_config_on_enable_iris1(struct venus_hfi_device *device); +static int reset_ahb2axi_bridge(struct venus_hfi_device *device); +static int __set_ubwc_config(struct venus_hfi_device *device); +static void power_off_common(struct venus_hfi_device *device); +static void power_off_iris2(struct venus_hfi_device *device); +static void noc_error_info_common(struct venus_hfi_device *device); +static void noc_error_info_iris2(struct venus_hfi_device *device); + +struct venus_hfi_vpu_ops vpu4_ops = { + .interrupt_init = interrupt_init_vpu4, + .setup_dsp_uc_memmap = NULL, + .clock_config_on_enable = NULL, + .reset_ahb2axi_bridge = NULL, + .power_off = power_off_common, + .noc_error_info = noc_error_info_common, +}; + +struct venus_hfi_vpu_ops iris1_ops = { + .interrupt_init = interrupt_init_iris1, + .setup_dsp_uc_memmap = setup_dsp_uc_memmap_iris1, + .clock_config_on_enable = clock_config_on_enable_iris1, + .reset_ahb2axi_bridge = reset_ahb2axi_bridge, + .power_off = power_off_common, + .noc_error_info = noc_error_info_common, +}; + +struct venus_hfi_vpu_ops iris2_ops = { + .interrupt_init = interrupt_init_iris1, + .setup_dsp_uc_memmap = NULL, + .clock_config_on_enable = NULL, + .reset_ahb2axi_bridge = reset_ahb2axi_bridge, + .power_off = power_off_iris2, + .noc_error_info = noc_error_info_iris2, +}; + +/** + * Utility function to enforce some of our assumptions. Spam calls to this + * in hotspots in code to double check some of the assumptions that we hold. + */ +static inline void __strict_check(struct venus_hfi_device *device) +{ + msm_vidc_res_handle_fatal_hw_error(device->res, + !mutex_is_locked(&device->lock)); +} + +static inline void __set_state(struct venus_hfi_device *device, + enum venus_hfi_state state) +{ + device->state = state; +} + +static inline bool __core_in_valid_state(struct venus_hfi_device *device) +{ + return device->state != VENUS_STATE_DEINIT; +} + +static inline bool is_sys_cache_present(struct venus_hfi_device *device) +{ + return device->res->sys_cache_present; +} + +static void __dump_packet(u8 *packet, enum vidc_msg_prio log_level) +{ + u32 c = 0, packet_size = *(u32 *)packet; + const int row_size = 32; + /* + * row must contain enough for 0xdeadbaad * 8 to be converted into + * "de ad ba ab " * 8 + '\0' + */ + char row[3 * 32]; + + for (c = 0; c * row_size < packet_size; ++c) { + int bytes_to_read = ((c + 1) * row_size > packet_size) ? + packet_size % row_size : row_size; + hex_dump_to_buffer(packet + c * row_size, bytes_to_read, + row_size, 4, row, sizeof(row), false); + dprintk(log_level, "%s\n", row); + } +} + +static void __sim_modify_cmd_packet(u8 *packet, struct venus_hfi_device *device) +{ + struct hfi_cmd_sys_session_init_packet *sys_init; + struct hal_session *session = NULL; + u8 i; + phys_addr_t fw_bias = 0; + + if (!device || !packet) { + dprintk(VIDC_ERR, "Invalid Param\n"); + return; + } else if (!device->hal_data->firmware_base + || is_iommu_present(device->res)) { + return; + } + + fw_bias = device->hal_data->firmware_base; + sys_init = (struct hfi_cmd_sys_session_init_packet *)packet; + + session = __get_session(device, sys_init->session_id); + if (!session) { + dprintk(VIDC_DBG, "%s :Invalid session id: %x\n", + __func__, sys_init->session_id); + return; + } + + switch (sys_init->packet_type) { + case HFI_CMD_SESSION_EMPTY_BUFFER: + if (session->is_decoder) { + struct hfi_cmd_session_empty_buffer_compressed_packet + *pkt = (struct + hfi_cmd_session_empty_buffer_compressed_packet + *) packet; + pkt->packet_buffer -= fw_bias; + } else { + struct + hfi_cmd_session_empty_buffer_uncompressed_plane0_packet + *pkt = (struct + hfi_cmd_session_empty_buffer_uncompressed_plane0_packet + *) packet; + pkt->packet_buffer -= fw_bias; + } + break; + case HFI_CMD_SESSION_FILL_BUFFER: + { + struct hfi_cmd_session_fill_buffer_packet *pkt = + (struct hfi_cmd_session_fill_buffer_packet *)packet; + pkt->packet_buffer -= fw_bias; + break; + } + case HFI_CMD_SESSION_SET_BUFFERS: + { + struct hfi_cmd_session_set_buffers_packet *pkt = + (struct hfi_cmd_session_set_buffers_packet *)packet; + if (pkt->buffer_type == HFI_BUFFER_OUTPUT || + pkt->buffer_type == HFI_BUFFER_OUTPUT2) { + struct hfi_buffer_info *buff; + + buff = (struct hfi_buffer_info *) pkt->rg_buffer_info; + buff->buffer_addr -= fw_bias; + if (buff->extra_data_addr >= fw_bias) + buff->extra_data_addr -= fw_bias; + } else { + for (i = 0; i < pkt->num_buffers; i++) + pkt->rg_buffer_info[i] -= fw_bias; + } + break; + } + case HFI_CMD_SESSION_RELEASE_BUFFERS: + { + struct hfi_cmd_session_release_buffer_packet *pkt = + (struct hfi_cmd_session_release_buffer_packet *)packet; + + if (pkt->buffer_type == HFI_BUFFER_OUTPUT || + pkt->buffer_type == HFI_BUFFER_OUTPUT2) { + struct hfi_buffer_info *buff; + + buff = (struct hfi_buffer_info *) pkt->rg_buffer_info; + buff->buffer_addr -= fw_bias; + buff->extra_data_addr -= fw_bias; + } else { + for (i = 0; i < pkt->num_buffers; i++) + pkt->rg_buffer_info[i] -= fw_bias; + } + break; + } + case HFI_CMD_SESSION_REGISTER_BUFFERS: + { + struct hfi_cmd_session_register_buffers_packet *pkt = + (struct hfi_cmd_session_register_buffers_packet *) + packet; + struct hfi_buffer_mapping_type *buf = + (struct hfi_buffer_mapping_type *)pkt->buffer; + for (i = 0; i < pkt->num_buffers; i++) + buf[i].device_addr -= fw_bias; + break; + } + default: + break; + } +} + +static int __dsp_send_hfi_queue(struct venus_hfi_device *device) +{ + int rc; + + if (!device->res->domain_cvp) + return 0; + + if (!device->dsp_iface_q_table.mem_data.dma_handle) { + dprintk(VIDC_ERR, "%s: invalid dsm_handle\n", __func__); + return -EINVAL; + } + + if (device->dsp_flags & DSP_INIT) { + dprintk(VIDC_DBG, "%s: dsp already inited\n", __func__); + return 0; + } + + dprintk(VIDC_DBG, "%s: hfi queue %#llx size %d\n", + __func__, device->dsp_iface_q_table.mem_data.dma_handle, + device->dsp_iface_q_table.mem_data.size); + rc = fastcvpd_video_send_cmd_hfi_queue( + (phys_addr_t *)device->dsp_iface_q_table.mem_data.dma_handle, + device->dsp_iface_q_table.mem_data.size); + if (rc) { + dprintk(VIDC_ERR, "%s: dsp init failed\n", __func__); + return rc; + } + + device->dsp_flags |= DSP_INIT; + dprintk(VIDC_DBG, "%s: dsp inited\n", __func__); + return rc; +} + +static int __dsp_suspend(struct venus_hfi_device *device, bool force, u32 flags) +{ + int rc; + struct hal_session *temp; + + if (!device->res->domain_cvp) + return 0; + + if (!(device->dsp_flags & DSP_INIT)) + return 0; + + if (device->dsp_flags & DSP_SUSPEND) + return 0; + + list_for_each_entry(temp, &device->sess_head, list) { + /* if forceful suspend, don't check session pause info */ + if (force) + continue; + if (temp->domain == HAL_VIDEO_DOMAIN_CVP) { + /* don't suspend if cvp session is not paused */ + if (!(temp->flags & SESSION_PAUSE)) { + dprintk(VIDC_DBG, + "%s: cvp session %x not paused\n", + __func__, hash32_ptr(temp)); + return -EBUSY; + } + } + } + + dprintk(VIDC_DBG, "%s: suspend dsp\n", __func__); + rc = fastcvpd_video_suspend(flags); + if (rc) { + dprintk(VIDC_ERR, "%s: dsp suspend failed with error %d\n", + __func__, rc); + return -EINVAL; + } + + device->dsp_flags |= DSP_SUSPEND; + dprintk(VIDC_DBG, "%s: dsp suspended\n", __func__); + return 0; +} + +static int __dsp_resume(struct venus_hfi_device *device, u32 flags) +{ + int rc; + + if (!device->res->domain_cvp) + return 0; + + if (!(device->dsp_flags & DSP_SUSPEND)) { + dprintk(VIDC_DBG, "%s: dsp not suspended\n", __func__); + return 0; + } + + dprintk(VIDC_DBG, "%s: resume dsp\n", __func__); + rc = fastcvpd_video_resume(flags); + if (rc) { + dprintk(VIDC_ERR, + "%s: dsp resume failed with error %d\n", + __func__, rc); + return rc; + } + + device->dsp_flags &= ~DSP_SUSPEND; + dprintk(VIDC_DBG, "%s: dsp resumed\n", __func__); + return rc; +} + +static int __dsp_shutdown(struct venus_hfi_device *device, u32 flags) +{ + int rc; + + if (!device->res->domain_cvp) + return 0; + + if (!(device->dsp_flags & DSP_INIT)) { + dprintk(VIDC_DBG, "%s: dsp not inited\n", __func__); + return 0; + } + + dprintk(VIDC_DBG, "%s: shutdown dsp\n", __func__); + rc = fastcvpd_video_shutdown(flags); + if (rc) { + dprintk(VIDC_ERR, + "%s: dsp shutdown failed with error %d\n", + __func__, rc); + WARN_ON(1); + } + + device->dsp_flags &= ~DSP_INIT; + dprintk(VIDC_DBG, "%s: dsp shutdown successful\n", __func__); + return rc; +} + +static int __session_pause(struct venus_hfi_device *device, + struct hal_session *session) +{ + int rc = 0; + + /* ignore if session paused already */ + if (session->flags & SESSION_PAUSE) + return 0; + + session->flags |= SESSION_PAUSE; + dprintk(VIDC_DBG, "%s: cvp session %x paused\n", __func__, + hash32_ptr(session)); + + return rc; +} + +static int __session_resume(struct venus_hfi_device *device, + struct hal_session *session) +{ + int rc = 0; + + /* ignore if session already resumed */ + if (!(session->flags & SESSION_PAUSE)) + return 0; + + session->flags &= ~SESSION_PAUSE; + dprintk(VIDC_DBG, "%s: cvp session %x resumed\n", __func__, + hash32_ptr(session)); + + rc = __resume(device); + if (rc) { + dprintk(VIDC_ERR, "%s: resume failed\n", __func__); + goto exit; + } + + if (device->dsp_flags & DSP_SUSPEND) { + dprintk(VIDC_ERR, "%s: dsp not resumed\n", __func__); + rc = -EINVAL; + goto exit; + } + +exit: + return rc; +} + +static int venus_hfi_session_pause(void *sess) +{ + int rc; + struct hal_session *session = sess; + struct venus_hfi_device *device; + + if (!session || !session->device) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + device = session->device; + + mutex_lock(&device->lock); + rc = __session_pause(device, session); + mutex_unlock(&device->lock); + + return rc; +} + +static int venus_hfi_session_resume(void *sess) +{ + int rc; + struct hal_session *session = sess; + struct venus_hfi_device *device; + + if (!session || !session->device) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + device = session->device; + + mutex_lock(&device->lock); + rc = __session_resume(device, session); + mutex_unlock(&device->lock); + + return rc; +} + +static int __acquire_regulator(struct regulator_info *rinfo, + struct venus_hfi_device *device) +{ + int rc = 0; + + if (rinfo->has_hw_power_collapse) { + rc = regulator_set_mode(rinfo->regulator, + REGULATOR_MODE_NORMAL); + if (rc) { + /* + * This is somewhat fatal, but nothing we can do + * about it. We can't disable the regulator w/o + * getting it back under s/w control + */ + dprintk(VIDC_WARN, + "Failed to acquire regulator control: %s\n", + rinfo->name); + } else { + + dprintk(VIDC_DBG, + "Acquire regulator control from HW: %s\n", + rinfo->name); + + } + } + + if (!regulator_is_enabled(rinfo->regulator)) { + dprintk(VIDC_WARN, "Regulator is not enabled %s\n", + rinfo->name); + msm_vidc_res_handle_fatal_hw_error(device->res, true); + } + + return rc; +} + +static int __hand_off_regulator(struct regulator_info *rinfo) +{ + int rc = 0; + + if (rinfo->has_hw_power_collapse) { + rc = regulator_set_mode(rinfo->regulator, + REGULATOR_MODE_FAST); + if (rc) { + dprintk(VIDC_WARN, + "Failed to hand off regulator control: %s\n", + rinfo->name); + } else { + dprintk(VIDC_DBG, + "Hand off regulator control to HW: %s\n", + rinfo->name); + } + } + + return rc; +} + +static int __hand_off_regulators(struct venus_hfi_device *device) +{ + struct regulator_info *rinfo; + int rc = 0, c = 0; + + venus_hfi_for_each_regulator(device, rinfo) { + rc = __hand_off_regulator(rinfo); + /* + * If one regulator hand off failed, driver should take + * the control for other regulators back. + */ + if (rc) + goto err_reg_handoff_failed; + c++; + } + + return rc; +err_reg_handoff_failed: + venus_hfi_for_each_regulator_reverse_continue(device, rinfo, c) + __acquire_regulator(rinfo, device); + + return rc; +} + +static int __write_queue(struct vidc_iface_q_info *qinfo, u8 *packet, + bool *rx_req_is_set) +{ + struct hfi_queue_header *queue; + u32 packet_size_in_words, new_write_idx; + u32 empty_space, read_idx, write_idx; + u32 *write_ptr; + + if (!qinfo || !packet) { + dprintk(VIDC_ERR, "Invalid Params\n"); + return -EINVAL; + } else if (!qinfo->q_array.align_virtual_addr) { + dprintk(VIDC_WARN, "Queues have already been freed\n"); + return -EINVAL; + } + + queue = (struct hfi_queue_header *) qinfo->q_hdr; + if (!queue) { + dprintk(VIDC_ERR, "queue not present\n"); + return -ENOENT; + } + + if (msm_vidc_debug & VIDC_PKT) { + dprintk(VIDC_PKT, "%s: %pK\n", __func__, qinfo); + __dump_packet(packet, VIDC_PKT); + } + + packet_size_in_words = (*(u32 *)packet) >> 2; + if (!packet_size_in_words || packet_size_in_words > + qinfo->q_array.mem_size>>2) { + dprintk(VIDC_ERR, "Invalid packet size\n"); + return -ENODATA; + } + + read_idx = queue->qhdr_read_idx; + write_idx = queue->qhdr_write_idx; + + empty_space = (write_idx >= read_idx) ? + ((qinfo->q_array.mem_size>>2) - (write_idx - read_idx)) : + (read_idx - write_idx); + if (empty_space <= packet_size_in_words) { + queue->qhdr_tx_req = 1; + dprintk(VIDC_ERR, "Insufficient size (%d) to write (%d)\n", + empty_space, packet_size_in_words); + return -ENOTEMPTY; + } + + queue->qhdr_tx_req = 0; + + new_write_idx = write_idx + packet_size_in_words; + write_ptr = (u32 *)((qinfo->q_array.align_virtual_addr) + + (write_idx << 2)); + if (write_ptr < (u32 *)qinfo->q_array.align_virtual_addr || + write_ptr > (u32 *)(qinfo->q_array.align_virtual_addr + + qinfo->q_array.mem_size)) { + dprintk(VIDC_ERR, "Invalid write index"); + return -ENODATA; + } + + if (new_write_idx < (qinfo->q_array.mem_size >> 2)) { + memcpy(write_ptr, packet, packet_size_in_words << 2); + } else { + new_write_idx -= qinfo->q_array.mem_size >> 2; + memcpy(write_ptr, packet, (packet_size_in_words - + new_write_idx) << 2); + memcpy((void *)qinfo->q_array.align_virtual_addr, + packet + ((packet_size_in_words - new_write_idx) << 2), + new_write_idx << 2); + } + + /* + * Memory barrier to make sure packet is written before updating the + * write index + */ + mb(); + queue->qhdr_write_idx = new_write_idx; + if (rx_req_is_set) + *rx_req_is_set = queue->qhdr_rx_req == 1; + /* + * Memory barrier to make sure write index is updated before an + * interrupt is raised on venus. + */ + mb(); + return 0; +} + +static void __hal_sim_modify_msg_packet(u8 *packet, + struct venus_hfi_device *device) +{ + struct hfi_msg_sys_session_init_done_packet *init_done; + struct hal_session *session = NULL; + phys_addr_t fw_bias = 0; + + if (!device || !packet) { + dprintk(VIDC_ERR, "Invalid Param\n"); + return; + } else if (!device->hal_data->firmware_base + || is_iommu_present(device->res)) { + return; + } + + fw_bias = device->hal_data->firmware_base; + init_done = (struct hfi_msg_sys_session_init_done_packet *)packet; + session = __get_session(device, init_done->session_id); + + if (!session) { + dprintk(VIDC_DBG, "%s: Invalid session id: %x\n", + __func__, init_done->session_id); + return; + } + + switch (init_done->packet_type) { + case HFI_MSG_SESSION_FILL_BUFFER_DONE: + if (session->is_decoder) { + struct + hfi_msg_session_fbd_uncompressed_plane0_packet + *pkt_uc = (struct + hfi_msg_session_fbd_uncompressed_plane0_packet + *) packet; + pkt_uc->packet_buffer += fw_bias; + } else { + struct + hfi_msg_session_fill_buffer_done_compressed_packet + *pkt = (struct + hfi_msg_session_fill_buffer_done_compressed_packet + *) packet; + pkt->packet_buffer += fw_bias; + } + break; + case HFI_MSG_SESSION_EMPTY_BUFFER_DONE: + { + struct hfi_msg_session_empty_buffer_done_packet *pkt = + (struct hfi_msg_session_empty_buffer_done_packet *)packet; + pkt->packet_buffer += fw_bias; + break; + } + default: + break; + } +} + +static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, + u32 *pb_tx_req_is_set) +{ + struct hfi_queue_header *queue; + u32 packet_size_in_words, new_read_idx; + u32 *read_ptr; + u32 receive_request = 0; + u32 read_idx, write_idx; + int rc = 0; + + if (!qinfo || !packet || !pb_tx_req_is_set) { + dprintk(VIDC_ERR, "Invalid Params\n"); + return -EINVAL; + } else if (!qinfo->q_array.align_virtual_addr) { + dprintk(VIDC_WARN, "Queues have already been freed\n"); + return -EINVAL; + } + + /* + * Memory barrier to make sure data is valid before + *reading it + */ + mb(); + queue = (struct hfi_queue_header *) qinfo->q_hdr; + + if (!queue) { + dprintk(VIDC_ERR, "Queue memory is not allocated\n"); + return -ENOMEM; + } + + /* + * Do not set receive request for debug queue, if set, + * Venus generates interrupt for debug messages even + * when there is no response message available. + * In general debug queue will not become full as it + * is being emptied out for every interrupt from Venus. + * Venus will anyway generates interrupt if it is full. + */ + if (queue->qhdr_type & HFI_Q_ID_CTRL_TO_HOST_MSG_Q) + receive_request = 1; + + read_idx = queue->qhdr_read_idx; + write_idx = queue->qhdr_write_idx; + + if (read_idx == write_idx) { + queue->qhdr_rx_req = receive_request; + /* + * mb() to ensure qhdr is updated in main memory + * so that venus reads the updated header values + */ + mb(); + *pb_tx_req_is_set = 0; + dprintk(VIDC_DBG, + "%s queue is empty, rx_req = %u, tx_req = %u, read_idx = %u\n", + receive_request ? "message" : "debug", + queue->qhdr_rx_req, queue->qhdr_tx_req, + queue->qhdr_read_idx); + return -ENODATA; + } + + read_ptr = (u32 *)((qinfo->q_array.align_virtual_addr) + + (read_idx << 2)); + if (read_ptr < (u32 *)qinfo->q_array.align_virtual_addr || + read_ptr > (u32 *)(qinfo->q_array.align_virtual_addr + + qinfo->q_array.mem_size - sizeof(*read_ptr))) { + dprintk(VIDC_ERR, "Invalid read index\n"); + return -ENODATA; + } + + packet_size_in_words = (*read_ptr) >> 2; + if (!packet_size_in_words) { + dprintk(VIDC_ERR, "Zero packet size\n"); + return -ENODATA; + } + + new_read_idx = read_idx + packet_size_in_words; + if (((packet_size_in_words << 2) <= VIDC_IFACEQ_VAR_HUGE_PKT_SIZE) && + read_idx <= (qinfo->q_array.mem_size >> 2)) { + if (new_read_idx < (qinfo->q_array.mem_size >> 2)) { + memcpy(packet, read_ptr, + packet_size_in_words << 2); + } else { + new_read_idx -= (qinfo->q_array.mem_size >> 2); + memcpy(packet, read_ptr, + (packet_size_in_words - new_read_idx) << 2); + memcpy(packet + ((packet_size_in_words - + new_read_idx) << 2), + (u8 *)qinfo->q_array.align_virtual_addr, + new_read_idx << 2); + } + } else { + dprintk(VIDC_WARN, + "BAD packet received, read_idx: %#x, pkt_size: %d\n", + read_idx, packet_size_in_words << 2); + dprintk(VIDC_WARN, "Dropping this packet\n"); + new_read_idx = write_idx; + rc = -ENODATA; + } + + if (new_read_idx != write_idx) + queue->qhdr_rx_req = 0; + else + queue->qhdr_rx_req = receive_request; + + queue->qhdr_read_idx = new_read_idx; + /* + * mb() to ensure qhdr is updated in main memory + * so that venus reads the updated header values + */ + mb(); + + *pb_tx_req_is_set = (queue->qhdr_tx_req == 1) ? 1 : 0; + + if ((msm_vidc_debug & VIDC_PKT) && + !(queue->qhdr_type & HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q)) { + dprintk(VIDC_PKT, "%s: %pK\n", __func__, qinfo); + __dump_packet(packet, VIDC_PKT); + } + + return rc; +} + +static int __smem_alloc(struct venus_hfi_device *dev, + struct vidc_mem_addr *mem, u32 size, u32 align, + u32 flags, u32 usage) +{ + struct msm_smem *alloc = &mem->mem_data; + int rc = 0; + + if (!dev || !mem || !size) { + dprintk(VIDC_ERR, "Invalid Params\n"); + return -EINVAL; + } + + dprintk(VIDC_INFO, "start to alloc size: %d, flags: %d\n", size, flags); + rc = msm_smem_alloc( + size, align, flags, usage, 1, (void *)dev->res, + MSM_VIDC_UNKNOWN, alloc); + if (rc) { + dprintk(VIDC_ERR, "Alloc failed\n"); + rc = -ENOMEM; + goto fail_smem_alloc; + } + + dprintk(VIDC_DBG, "%s: ptr = %pK, size = %d\n", __func__, + alloc->kvaddr, size); + + mem->mem_size = alloc->size; + mem->align_virtual_addr = alloc->kvaddr; + mem->align_device_addr = alloc->device_addr; + + return rc; +fail_smem_alloc: + return rc; +} + +static void __smem_free(struct venus_hfi_device *dev, struct msm_smem *mem) +{ + if (!dev || !mem) { + dprintk(VIDC_ERR, "invalid param %pK %pK\n", dev, mem); + return; + } + + msm_smem_free(mem); +} + +static void __write_register(struct venus_hfi_device *device, + u32 reg, u32 value) +{ + u32 hwiosymaddr = reg; + u8 *base_addr; + + if (!device) { + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); + return; + } + + __strict_check(device); + + if (!device->power_enabled) { + dprintk(VIDC_WARN, + "HFI Write register failed : Power is OFF\n"); + msm_vidc_res_handle_fatal_hw_error(device->res, true); + return; + } + + base_addr = device->hal_data->register_base; + dprintk(VIDC_DBG, "Base addr: %pK, writing to: %#x, Value: %#x...\n", + base_addr, hwiosymaddr, value); + base_addr += hwiosymaddr; + writel_relaxed(value, base_addr); + + /* + * Memory barrier to make sure value is written into the register. + */ + wmb(); +} + +static int __read_register(struct venus_hfi_device *device, u32 reg) +{ + int rc = 0; + u8 *base_addr; + + if (!device) { + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); + return -EINVAL; + } + + __strict_check(device); + + if (!device->power_enabled) { + dprintk(VIDC_WARN, + "HFI Read register failed : Power is OFF\n"); + msm_vidc_res_handle_fatal_hw_error(device->res, true); + return -EINVAL; + } + + base_addr = device->hal_data->register_base; + + rc = readl_relaxed(base_addr + reg); + /* + * Memory barrier to make sure value is read correctly from the + * register. + */ + rmb(); + dprintk(VIDC_DBG, "Base addr: %pK, read from: %#x, value: %#x...\n", + base_addr, reg, rc); + + return rc; +} + +static void __set_registers(struct venus_hfi_device *device) +{ + struct reg_set *reg_set; + int i; + + if (!device->res) { + dprintk(VIDC_ERR, + "device resources null, cannot set registers\n"); + return; + } + + reg_set = &device->res->reg_set; + for (i = 0; i < reg_set->count; i++) { + __write_register(device, reg_set->reg_tbl[i].reg, + reg_set->reg_tbl[i].value); + } +} + +/* + * The existence of this function is a hack for 8996 (or certain Venus versions) + * to overcome a hardware bug. Whenever the GDSCs momentarily power collapse + * (after calling __hand_off_regulators()), the values of the threshold + * registers (typically programmed by TZ) are incorrectly reset. As a result + * reprogram these registers at certain agreed upon points. + */ +static void __set_threshold_registers(struct venus_hfi_device *device) +{ + u32 version = __read_register(device, VIDC_WRAPPER_HW_VERSION); + + version &= ~GENMASK(15, 0); + if (version != (0x3 << 28 | 0x43 << 16)) + return; + + if (__tzbsp_set_video_state(TZBSP_VIDEO_STATE_RESTORE_THRESHOLD)) + dprintk(VIDC_ERR, "Failed to restore threshold values\n"); +} + +static int __vote_bandwidth(struct bus_info *bus, + unsigned long *freq) +{ + int rc = 0; + uint64_t ab = 0; + + if (*freq) + *freq = clamp_t(typeof(*freq), *freq, bus->range[0], + bus->range[1]); + + /* Bus Driver expects values in Bps */ + ab = *freq * 1000; + dprintk(VIDC_PROF, "Voting bus %s to ab %llu\n", bus->name, ab); + rc = msm_bus_scale_update_bw(bus->client, ab, 0); + if (rc) + dprintk(VIDC_ERR, "Failed voting bus %s to ab %llu, rc=%d\n", + bus->name, ab, rc); + + return rc; +} + +static int __unvote_buses(struct venus_hfi_device *device) +{ + int rc = 0; + struct bus_info *bus = NULL; + unsigned long freq = 0, zero = 0; + + kfree(device->bus_vote.data); + device->bus_vote.data = NULL; + device->bus_vote.data_count = 0; + + venus_hfi_for_each_bus(device, bus) { + if (!bus->is_prfm_mode) { + freq = device->bus_vote.calc_bw(bus, &device->bus_vote); + rc = __vote_bandwidth(bus, &freq); + } + else + rc = __vote_bandwidth(bus, &zero); + + if (rc) + goto err_unknown_device; + } + +err_unknown_device: + return rc; +} + +static int __vote_buses(struct venus_hfi_device *device, + struct vidc_bus_vote_data *data, int num_data) +{ + int rc = 0; + struct bus_info *bus = NULL; + struct vidc_bus_vote_data *new_data = NULL; + unsigned long freq = 0; + + if (!num_data) { + dprintk(VIDC_DBG, "No vote data available\n"); + goto no_data_count; + } else if (!data) { + dprintk(VIDC_ERR, "Invalid voting data\n"); + return -EINVAL; + } + + new_data = kmemdup(data, num_data * sizeof(*new_data), GFP_KERNEL); + if (!new_data) { + dprintk(VIDC_ERR, "Can't alloc memory to cache bus votes\n"); + rc = -ENOMEM; + goto err_no_mem; + } + +no_data_count: + kfree(device->bus_vote.data); + device->bus_vote.data = new_data; + device->bus_vote.data_count = num_data; + + venus_hfi_for_each_bus(device, bus) { + if (bus && bus->client) { + if (!bus->is_prfm_mode) + freq = device->bus_vote.calc_bw + (bus, &device->bus_vote); + else + freq = bus->range[1]; + + rc = __vote_bandwidth(bus, &freq); + } else { + dprintk(VIDC_ERR, "No BUS to Vote\n"); + } + } + +err_no_mem: + return rc; +} + +static int venus_hfi_vote_buses(void *dev, struct vidc_bus_vote_data *d, int n) +{ + int rc = 0; + struct venus_hfi_device *device = dev; + + if (!device) + return -EINVAL; + + mutex_lock(&device->lock); + rc = __vote_buses(device, d, n); + mutex_unlock(&device->lock); + + return rc; + +} +static int __core_set_resource(struct venus_hfi_device *device, + struct vidc_resource_hdr *resource_hdr, void *resource_value) +{ + struct hfi_cmd_sys_set_resource_packet *pkt; + u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE]; + int rc = 0; + + if (!device || !resource_hdr || !resource_value) { + dprintk(VIDC_ERR, "set_res: Invalid Params\n"); + return -EINVAL; + } + + pkt = (struct hfi_cmd_sys_set_resource_packet *) packet; + + rc = call_hfi_pkt_op(device, sys_set_resource, + pkt, resource_hdr, resource_value); + if (rc) { + dprintk(VIDC_ERR, "set_res: failed to create packet\n"); + goto err_create_pkt; + } + + rc = __iface_cmdq_write(device, pkt); + if (rc) + rc = -ENOTEMPTY; + +err_create_pkt: + return rc; +} + +static int __core_release_resource(struct venus_hfi_device *device, + struct vidc_resource_hdr *resource_hdr) +{ + struct hfi_cmd_sys_release_resource_packet *pkt; + u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE]; + int rc = 0; + + if (!device || !resource_hdr) { + dprintk(VIDC_ERR, "release_res: Invalid Params\n"); + return -EINVAL; + } + + pkt = (struct hfi_cmd_sys_release_resource_packet *) packet; + + rc = call_hfi_pkt_op(device, sys_release_resource, + pkt, resource_hdr); + + if (rc) { + dprintk(VIDC_ERR, "release_res: failed to create packet\n"); + goto err_create_pkt; + } + + rc = __iface_cmdq_write(device, pkt); + if (rc) + rc = -ENOTEMPTY; + +err_create_pkt: + return rc; +} + +static int __tzbsp_set_video_state(enum tzbsp_video_state state) +{ + struct tzbsp_video_set_state_req cmd = {0}; + int tzbsp_rsp = 0; + int rc = 0; + struct scm_desc desc = {0}; + + desc.args[0] = cmd.state = state; + desc.args[1] = cmd.spare = 0; + desc.arginfo = SCM_ARGS(2); + + rc = scm_call2(SCM_SIP_FNID(SCM_SVC_BOOT, + TZBSP_VIDEO_SET_STATE), &desc); + tzbsp_rsp = desc.ret[0]; + + if (rc) { + dprintk(VIDC_ERR, "Failed scm_call %d\n", rc); + return rc; + } + + dprintk(VIDC_DBG, "Set state %d, resp %d\n", state, tzbsp_rsp); + if (tzbsp_rsp) { + dprintk(VIDC_ERR, + "Failed to set video core state to suspend: %d\n", + tzbsp_rsp); + return -EINVAL; + } + + return 0; +} + +static inline int __boot_firmware(struct venus_hfi_device *device) +{ + int rc = 0; + u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 10000; + + ctrl_init_val = BIT(0); + if (device->res->domain_cvp) + ctrl_init_val |= BIT(1); + + __write_register(device, VIDC_CTRL_INIT, ctrl_init_val); + while (!ctrl_status && count < max_tries) { + ctrl_status = __read_register(device, VIDC_CTRL_STATUS); + if ((ctrl_status & VIDC_CTRL_ERROR_STATUS__M) == 0x4) { + dprintk(VIDC_ERR, "invalid setting for UC_REGION\n"); + break; + } + + usleep_range(50, 100); + count++; + } + + if (count >= max_tries) { + dprintk(VIDC_ERR, "Error booting up vidc firmware\n"); + rc = -ETIME; + } + + /* Enable interrupt before sending commands to venus */ + __write_register(device, VIDC_CPU_CS_H2XSOFTINTEN, 0x1); + __write_register(device, VIDC_CPU_CS_X2RPMh, 0x0); + + return rc; +} + +static int venus_hfi_suspend(void *dev) +{ + int rc = 0; + struct venus_hfi_device *device = (struct venus_hfi_device *) dev; + + if (!device) { + dprintk(VIDC_ERR, "%s invalid device\n", __func__); + return -EINVAL; + } else if (!device->res->sw_power_collapsible) { + return -ENOTSUPP; + } + + dprintk(VIDC_DBG, "Suspending Venus\n"); + mutex_lock(&device->lock); + rc = __power_collapse(device, true); + if (rc) { + dprintk(VIDC_WARN, "%s: Venus is busy\n", __func__); + rc = -EBUSY; + } + mutex_unlock(&device->lock); + + /* Cancel pending delayed works if any */ + if (!rc) + cancel_delayed_work(&venus_hfi_pm_work); + + return rc; +} + +static int venus_hfi_flush_debug_queue(void *dev) +{ + int rc = 0; + struct venus_hfi_device *device = (struct venus_hfi_device *) dev; + + if (!device) { + dprintk(VIDC_ERR, "%s invalid device\n", __func__); + return -EINVAL; + } + + mutex_lock(&device->lock); + + if (!device->power_enabled) { + dprintk(VIDC_WARN, "%s: venus power off\n", __func__); + rc = -EINVAL; + goto exit; + } + __flush_debug_queue(device, NULL); +exit: + mutex_unlock(&device->lock); + return rc; +} + +static enum hal_default_properties venus_hfi_get_default_properties(void *dev) +{ + enum hal_default_properties prop = 0; + struct venus_hfi_device *device = (struct venus_hfi_device *) dev; + + if (!device) { + dprintk(VIDC_ERR, "%s invalid device\n", __func__); + return -EINVAL; + } + + mutex_lock(&device->lock); + + prop = HAL_VIDEO_DYNAMIC_BUF_MODE; + + mutex_unlock(&device->lock); + return prop; +} + +static int __set_clocks(struct venus_hfi_device *device, u32 freq) +{ + struct clock_info *cl; + int rc = 0; + + venus_hfi_for_each_clock(device, cl) { + if (cl->has_scaling) {/* has_scaling */ + device->clk_freq = freq; + rc = clk_set_rate(cl->clk, freq); + if (rc) { + dprintk(VIDC_ERR, + "Failed to set clock rate %u %s: %d %s\n", + freq, cl->name, rc, __func__); + return rc; + } + + trace_msm_vidc_perf_clock_scale(cl->name, freq); + dprintk(VIDC_PROF, "Scaling clock %s to %u\n", + cl->name, freq); + } + } + + return 0; +} + +static int venus_hfi_scale_clocks(void *dev, u32 freq) +{ + int rc = 0; + struct venus_hfi_device *device = dev; + + if (!device) { + dprintk(VIDC_ERR, "Invalid args: %pK\n", device); + return -EINVAL; + } + + mutex_lock(&device->lock); + + if (__resume(device)) { + dprintk(VIDC_ERR, "Resume from power collapse failed\n"); + rc = -ENODEV; + goto exit; + } + + rc = __set_clocks(device, freq); +exit: + mutex_unlock(&device->lock); + + return rc; +} + +static int __scale_clocks(struct venus_hfi_device *device) +{ + int rc = 0; + struct allowed_clock_rates_table *allowed_clks_tbl = NULL; + u32 rate = 0; + + allowed_clks_tbl = device->res->allowed_clks_tbl; + + dprintk(VIDC_DBG, "%s: NULL scale data\n", __func__); + rate = device->clk_freq ? device->clk_freq : + allowed_clks_tbl[0].clock_rate; + + rc = __set_clocks(device, rate); + return rc; +} + +/* Writes into cmdq without raising an interrupt */ +static int __iface_cmdq_write_relaxed(struct venus_hfi_device *device, + void *pkt, bool *requires_interrupt) +{ + struct vidc_iface_q_info *q_info; + struct vidc_hal_cmd_pkt_hdr *cmd_packet; + int result = -E2BIG; + + if (!device || !pkt) { + dprintk(VIDC_ERR, "Invalid Params\n"); + return -EINVAL; + } + + __strict_check(device); + + if (!__core_in_valid_state(device)) { + dprintk(VIDC_ERR, "%s - fw not in init state\n", __func__); + result = -EINVAL; + goto err_q_null; + } + + cmd_packet = (struct vidc_hal_cmd_pkt_hdr *)pkt; + device->last_packet_type = cmd_packet->packet_type; + + q_info = &device->iface_queues[VIDC_IFACEQ_CMDQ_IDX]; + if (!q_info) { + dprintk(VIDC_ERR, "cannot write to shared Q's\n"); + goto err_q_null; + } + + if (!q_info->q_array.align_virtual_addr) { + dprintk(VIDC_ERR, "cannot write to shared CMD Q's\n"); + result = -ENODATA; + goto err_q_null; + } + + __sim_modify_cmd_packet((u8 *)pkt, device); + if (__resume(device)) { + dprintk(VIDC_ERR, "%s: Power on failed\n", __func__); + goto err_q_write; + } + + if (!__write_queue(q_info, (u8 *)pkt, requires_interrupt)) { + if (device->res->sw_power_collapsible) { + cancel_delayed_work(&venus_hfi_pm_work); + if (!queue_delayed_work(device->venus_pm_workq, + &venus_hfi_pm_work, + msecs_to_jiffies( + device->res->msm_vidc_pwr_collapse_delay))) { + dprintk(VIDC_DBG, + "PM work already scheduled\n"); + } + } + + result = 0; + } else { + dprintk(VIDC_ERR, "__iface_cmdq_write: queue full\n"); + } + +err_q_write: +err_q_null: + return result; +} + +static int __iface_cmdq_write(struct venus_hfi_device *device, void *pkt) +{ + bool needs_interrupt = false; + int rc = __iface_cmdq_write_relaxed(device, pkt, &needs_interrupt); + + if (!rc && needs_interrupt) { + /* Consumer of cmdq prefers that we raise an interrupt */ + rc = 0; + __write_register(device, VIDC_CPU_IC_SOFTINT, + 1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT); + } + + return rc; +} + +static int __iface_msgq_read(struct venus_hfi_device *device, void *pkt) +{ + u32 tx_req_is_set = 0; + int rc = 0; + struct vidc_iface_q_info *q_info; + + if (!pkt) { + dprintk(VIDC_ERR, "Invalid Params\n"); + return -EINVAL; + } + + __strict_check(device); + + if (!__core_in_valid_state(device)) { + dprintk(VIDC_DBG, "%s - fw not in init state\n", __func__); + rc = -EINVAL; + goto read_error_null; + } + + q_info = &device->iface_queues[VIDC_IFACEQ_MSGQ_IDX]; + if (!q_info->q_array.align_virtual_addr) { + dprintk(VIDC_ERR, "cannot read from shared MSG Q's\n"); + rc = -ENODATA; + goto read_error_null; + } + + if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) { + __hal_sim_modify_msg_packet((u8 *)pkt, device); + if (tx_req_is_set) + __write_register(device, VIDC_CPU_IC_SOFTINT, + 1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT); + rc = 0; + } else + rc = -ENODATA; + +read_error_null: + return rc; +} + +static int __iface_dbgq_read(struct venus_hfi_device *device, void *pkt) +{ + u32 tx_req_is_set = 0; + int rc = 0; + struct vidc_iface_q_info *q_info; + + if (!pkt) { + dprintk(VIDC_ERR, "Invalid Params\n"); + return -EINVAL; + } + + __strict_check(device); + + q_info = &device->iface_queues[VIDC_IFACEQ_DBGQ_IDX]; + if (!q_info->q_array.align_virtual_addr) { + dprintk(VIDC_ERR, "cannot read from shared DBG Q's\n"); + rc = -ENODATA; + goto dbg_error_null; + } + + if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) { + if (tx_req_is_set) + __write_register(device, VIDC_CPU_IC_SOFTINT, + 1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT); + rc = 0; + } else + rc = -ENODATA; + +dbg_error_null: + return rc; +} + +static void __set_queue_hdr_defaults(struct hfi_queue_header *q_hdr) +{ + q_hdr->qhdr_status = 0x1; + q_hdr->qhdr_type = VIDC_IFACEQ_DFLT_QHDR; + q_hdr->qhdr_q_size = VIDC_IFACEQ_QUEUE_SIZE / 4; + q_hdr->qhdr_pkt_size = 0; + q_hdr->qhdr_rx_wm = 0x1; + q_hdr->qhdr_tx_wm = 0x1; + q_hdr->qhdr_rx_req = 0x1; + q_hdr->qhdr_tx_req = 0x0; + q_hdr->qhdr_rx_irq_status = 0x0; + q_hdr->qhdr_tx_irq_status = 0x0; + q_hdr->qhdr_read_idx = 0x0; + q_hdr->qhdr_write_idx = 0x0; +} + +static void __interface_dsp_queues_release(struct venus_hfi_device *device) +{ + int i; + struct msm_smem *mem_data = &device->dsp_iface_q_table.mem_data; + struct context_bank_info *cb = mem_data->mapping_info.cb_info; + + if (!device->dsp_iface_q_table.align_virtual_addr) { + dprintk(VIDC_ERR, "%s: already released\n", __func__); + return; + } + + dma_unmap_single_attrs(cb->dev, mem_data->device_addr, + mem_data->size, DMA_BIDIRECTIONAL, 0); + dma_free_coherent(device->res->mem_cdsp.dev, mem_data->size, + mem_data->kvaddr, mem_data->dma_handle); + + for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) { + device->dsp_iface_queues[i].q_hdr = NULL; + device->dsp_iface_queues[i].q_array.align_virtual_addr = NULL; + device->dsp_iface_queues[i].q_array.align_device_addr = 0; + } + device->dsp_iface_q_table.align_virtual_addr = NULL; + device->dsp_iface_q_table.align_device_addr = 0; +} + +static int __interface_dsp_queues_init(struct venus_hfi_device *dev) +{ + int rc = 0; + u32 i; + struct hfi_queue_table_header *q_tbl_hdr; + struct hfi_queue_header *q_hdr; + struct vidc_iface_q_info *iface_q; + int offset = 0; + phys_addr_t fw_bias = 0; + size_t q_size; + struct msm_smem *mem_data; + void *kvaddr; + dma_addr_t dma_handle; + dma_addr_t iova; + struct context_bank_info *cb; + + q_size = ALIGN(QUEUE_SIZE, SZ_1M); + mem_data = &dev->dsp_iface_q_table.mem_data; + + /* Allocate dsp queues from ADSP device memory */ + kvaddr = dma_alloc_coherent(dev->res->mem_cdsp.dev, q_size, + &dma_handle, GFP_KERNEL); + if (IS_ERR_OR_NULL(kvaddr)) { + dprintk(VIDC_ERR, "%s: failed dma allocation\n", __func__); + goto fail_dma_alloc; + } + cb = msm_smem_get_context_bank(MSM_VIDC_UNKNOWN, 0, + dev->res, HAL_BUFFER_INTERNAL_CMD_QUEUE); + if (!cb) { + dprintk(VIDC_ERR, + "%s: failed to get context bank\n", __func__); + goto fail_dma_map; + } + iova = dma_map_single_attrs(cb->dev, phys_to_virt(dma_handle), + q_size, DMA_BIDIRECTIONAL, 0); + if (dma_mapping_error(cb->dev, iova)) { + dprintk(VIDC_ERR, "%s: failed dma mapping\n", __func__); + goto fail_dma_map; + } + dprintk(VIDC_DBG, + "%s: kvaddr %pK dma_handle %#llx iova %#llx size %zd\n", + __func__, kvaddr, dma_handle, iova, q_size); + + memset(mem_data, 0, sizeof(struct msm_smem)); + mem_data->kvaddr = kvaddr; + mem_data->device_addr = iova; + mem_data->dma_handle = dma_handle; + mem_data->size = q_size; + mem_data->buffer_type = HAL_BUFFER_INTERNAL_CMD_QUEUE; + mem_data->mapping_info.cb_info = cb; + + if (!is_iommu_present(dev->res)) + fw_bias = dev->hal_data->firmware_base; + + dev->dsp_iface_q_table.align_virtual_addr = kvaddr; + dev->dsp_iface_q_table.align_device_addr = iova - fw_bias; + dev->dsp_iface_q_table.mem_size = VIDC_IFACEQ_TABLE_SIZE; + offset = dev->dsp_iface_q_table.mem_size; + + for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) { + iface_q = &dev->dsp_iface_queues[i]; + iface_q->q_array.align_device_addr = iova + offset - fw_bias; + iface_q->q_array.align_virtual_addr = + (void *)((char *)kvaddr + offset); + iface_q->q_array.mem_size = VIDC_IFACEQ_QUEUE_SIZE; + offset += iface_q->q_array.mem_size; + iface_q->q_hdr = VIDC_IFACEQ_GET_QHDR_START_ADDR( + dev->dsp_iface_q_table.align_virtual_addr, i); + __set_queue_hdr_defaults(iface_q->q_hdr); + } + + q_tbl_hdr = (struct hfi_queue_table_header *) + dev->dsp_iface_q_table.align_virtual_addr; + q_tbl_hdr->qtbl_version = 0; + q_tbl_hdr->device_addr = (void *)dev; + strlcpy(q_tbl_hdr->name, "msm_v4l2_vidc", sizeof(q_tbl_hdr->name)); + q_tbl_hdr->qtbl_size = VIDC_IFACEQ_TABLE_SIZE; + q_tbl_hdr->qtbl_qhdr0_offset = sizeof(struct hfi_queue_table_header); + q_tbl_hdr->qtbl_qhdr_size = sizeof(struct hfi_queue_header); + q_tbl_hdr->qtbl_num_q = VIDC_IFACEQ_NUMQ; + q_tbl_hdr->qtbl_num_active_q = VIDC_IFACEQ_NUMQ; + + iface_q = &dev->dsp_iface_queues[VIDC_IFACEQ_CMDQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_HOST_TO_CTRL_CMD_Q; + + iface_q = &dev->dsp_iface_queues[VIDC_IFACEQ_MSGQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_MSG_Q; + + iface_q = &dev->dsp_iface_queues[VIDC_IFACEQ_DBGQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q; + /* + * Set receive request to zero on debug queue as there is no + * need of interrupt from video hardware for debug messages + */ + q_hdr->qhdr_rx_req = 0; + return rc; + +fail_dma_map: + dma_free_coherent(dev->res->mem_cdsp.dev, q_size, kvaddr, dma_handle); +fail_dma_alloc: + return -ENOMEM; +} + +static void __interface_queues_release(struct venus_hfi_device *device) +{ + int i; + struct hfi_mem_map_table *qdss; + struct hfi_mem_map *mem_map; + int num_entries = device->res->qdss_addr_set.count; + unsigned long mem_map_table_base_addr; + struct context_bank_info *cb; + + if (device->qdss.align_virtual_addr) { + qdss = (struct hfi_mem_map_table *) + device->qdss.align_virtual_addr; + qdss->mem_map_num_entries = num_entries; + mem_map_table_base_addr = + device->qdss.align_device_addr + + sizeof(struct hfi_mem_map_table); + qdss->mem_map_table_base_addr = + (u32)mem_map_table_base_addr; + if ((unsigned long)qdss->mem_map_table_base_addr != + mem_map_table_base_addr) { + dprintk(VIDC_ERR, + "Invalid mem_map_table_base_addr %#lx", + mem_map_table_base_addr); + } + + mem_map = (struct hfi_mem_map *)(qdss + 1); + cb = msm_smem_get_context_bank(MSM_VIDC_UNKNOWN, + false, device->res, HAL_BUFFER_INTERNAL_CMD_QUEUE); + + for (i = 0; cb && i < num_entries; i++) { + iommu_unmap(cb->domain, + mem_map[i].virtual_addr, + mem_map[i].size); + } + + __smem_free(device, &device->qdss.mem_data); + } + + __smem_free(device, &device->iface_q_table.mem_data); + __smem_free(device, &device->sfr.mem_data); + + for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) { + device->iface_queues[i].q_hdr = NULL; + device->iface_queues[i].q_array.align_virtual_addr = NULL; + device->iface_queues[i].q_array.align_device_addr = 0; + } + + device->iface_q_table.align_virtual_addr = NULL; + device->iface_q_table.align_device_addr = 0; + + device->qdss.align_virtual_addr = NULL; + device->qdss.align_device_addr = 0; + + device->sfr.align_virtual_addr = NULL; + device->sfr.align_device_addr = 0; + + device->mem_addr.align_virtual_addr = NULL; + device->mem_addr.align_device_addr = 0; + + if (device->res->domain_cvp) + __interface_dsp_queues_release(device); +} + +static int __get_qdss_iommu_virtual_addr(struct venus_hfi_device *dev, + struct hfi_mem_map *mem_map, struct iommu_domain *domain) +{ + int i; + int rc = 0; + dma_addr_t iova = QDSS_IOVA_START; + int num_entries = dev->res->qdss_addr_set.count; + struct addr_range *qdss_addr_tbl = dev->res->qdss_addr_set.addr_tbl; + + if (!num_entries) + return -ENODATA; + + for (i = 0; i < num_entries; i++) { + if (domain) { + rc = iommu_map(domain, iova, + qdss_addr_tbl[i].start, + qdss_addr_tbl[i].size, + IOMMU_READ | IOMMU_WRITE); + + if (rc) { + dprintk(VIDC_ERR, + "IOMMU QDSS mapping failed for addr %#x\n", + qdss_addr_tbl[i].start); + rc = -ENOMEM; + break; + } + } else { + iova = qdss_addr_tbl[i].start; + } + + mem_map[i].virtual_addr = (u32)iova; + mem_map[i].physical_addr = qdss_addr_tbl[i].start; + mem_map[i].size = qdss_addr_tbl[i].size; + mem_map[i].attr = 0x0; + + iova += mem_map[i].size; + } + + if (i < num_entries) { + dprintk(VIDC_ERR, + "QDSS mapping failed, Freeing other entries %d\n", i); + + for (--i; domain && i >= 0; i--) { + iommu_unmap(domain, + mem_map[i].virtual_addr, + mem_map[i].size); + } + } + + return rc; +} + +static void __setup_ucregion_memory_map(struct venus_hfi_device *device) +{ + __write_register(device, VIDC_UC_REGION_ADDR, + (u32)device->iface_q_table.align_device_addr); + __write_register(device, VIDC_UC_REGION_SIZE, SHARED_QSIZE); + __write_register(device, VIDC_QTBL_ADDR, + (u32)device->iface_q_table.align_device_addr); + __write_register(device, VIDC_QTBL_INFO, 0x01); + if (device->sfr.align_device_addr) + __write_register(device, VIDC_SFR_ADDR, + (u32)device->sfr.align_device_addr); + if (device->qdss.align_device_addr) + __write_register(device, VIDC_MMAP_ADDR, + (u32)device->qdss.align_device_addr); + call_venus_op(device, setup_dsp_uc_memmap, device); +} + +static int __interface_queues_init(struct venus_hfi_device *dev) +{ + struct hfi_queue_table_header *q_tbl_hdr; + struct hfi_queue_header *q_hdr; + u32 i; + int rc = 0; + struct hfi_mem_map_table *qdss; + struct hfi_mem_map *mem_map; + struct vidc_iface_q_info *iface_q; + struct hfi_sfr_struct *vsfr; + struct vidc_mem_addr *mem_addr; + int offset = 0; + int num_entries = dev->res->qdss_addr_set.count; + phys_addr_t fw_bias = 0; + size_t q_size; + unsigned long mem_map_table_base_addr; + struct context_bank_info *cb; + + q_size = SHARED_QSIZE - ALIGNED_SFR_SIZE - ALIGNED_QDSS_SIZE; + mem_addr = &dev->mem_addr; + if (!is_iommu_present(dev->res)) + fw_bias = dev->hal_data->firmware_base; + rc = __smem_alloc(dev, mem_addr, q_size, 1, SMEM_UNCACHED, + HAL_BUFFER_INTERNAL_CMD_QUEUE); + if (rc) { + dprintk(VIDC_ERR, "iface_q_table_alloc_fail\n"); + goto fail_alloc_queue; + } + + dev->iface_q_table.align_virtual_addr = mem_addr->align_virtual_addr; + dev->iface_q_table.align_device_addr = mem_addr->align_device_addr - + fw_bias; + dev->iface_q_table.mem_size = VIDC_IFACEQ_TABLE_SIZE; + dev->iface_q_table.mem_data = mem_addr->mem_data; + offset += dev->iface_q_table.mem_size; + + for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) { + iface_q = &dev->iface_queues[i]; + iface_q->q_array.align_device_addr = mem_addr->align_device_addr + + offset - fw_bias; + iface_q->q_array.align_virtual_addr = + mem_addr->align_virtual_addr + offset; + iface_q->q_array.mem_size = VIDC_IFACEQ_QUEUE_SIZE; + offset += iface_q->q_array.mem_size; + iface_q->q_hdr = VIDC_IFACEQ_GET_QHDR_START_ADDR( + dev->iface_q_table.align_virtual_addr, i); + __set_queue_hdr_defaults(iface_q->q_hdr); + } + + if ((msm_vidc_fw_debug_mode & HFI_DEBUG_MODE_QDSS) && num_entries) { + rc = __smem_alloc(dev, mem_addr, + ALIGNED_QDSS_SIZE, 1, SMEM_UNCACHED, + HAL_BUFFER_INTERNAL_CMD_QUEUE); + if (rc) { + dprintk(VIDC_WARN, + "qdss_alloc_fail: QDSS messages logging will not work\n"); + dev->qdss.align_device_addr = 0; + } else { + dev->qdss.align_device_addr = + mem_addr->align_device_addr - fw_bias; + dev->qdss.align_virtual_addr = + mem_addr->align_virtual_addr; + dev->qdss.mem_size = ALIGNED_QDSS_SIZE; + dev->qdss.mem_data = mem_addr->mem_data; + } + } + + rc = __smem_alloc(dev, mem_addr, + ALIGNED_SFR_SIZE, 1, SMEM_UNCACHED, + HAL_BUFFER_INTERNAL_CMD_QUEUE); + if (rc) { + dprintk(VIDC_WARN, "sfr_alloc_fail: SFR not will work\n"); + dev->sfr.align_device_addr = 0; + } else { + dev->sfr.align_device_addr = mem_addr->align_device_addr - + fw_bias; + dev->sfr.align_virtual_addr = mem_addr->align_virtual_addr; + dev->sfr.mem_size = ALIGNED_SFR_SIZE; + dev->sfr.mem_data = mem_addr->mem_data; + vsfr = (struct hfi_sfr_struct *) dev->sfr.align_virtual_addr; + vsfr->bufSize = ALIGNED_SFR_SIZE; + } + + q_tbl_hdr = (struct hfi_queue_table_header *) + dev->iface_q_table.align_virtual_addr; + q_tbl_hdr->qtbl_version = 0; + q_tbl_hdr->device_addr = (void *)dev; + strlcpy(q_tbl_hdr->name, "msm_v4l2_vidc", sizeof(q_tbl_hdr->name)); + q_tbl_hdr->qtbl_size = VIDC_IFACEQ_TABLE_SIZE; + q_tbl_hdr->qtbl_qhdr0_offset = sizeof(struct hfi_queue_table_header); + q_tbl_hdr->qtbl_qhdr_size = sizeof(struct hfi_queue_header); + q_tbl_hdr->qtbl_num_q = VIDC_IFACEQ_NUMQ; + q_tbl_hdr->qtbl_num_active_q = VIDC_IFACEQ_NUMQ; + + iface_q = &dev->iface_queues[VIDC_IFACEQ_CMDQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_HOST_TO_CTRL_CMD_Q; + + iface_q = &dev->iface_queues[VIDC_IFACEQ_MSGQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_MSG_Q; + + iface_q = &dev->iface_queues[VIDC_IFACEQ_DBGQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q; + /* + * Set receive request to zero on debug queue as there is no + * need of interrupt from video hardware for debug messages + */ + q_hdr->qhdr_rx_req = 0; + + if (dev->qdss.align_virtual_addr) { + qdss = (struct hfi_mem_map_table *)dev->qdss.align_virtual_addr; + qdss->mem_map_num_entries = num_entries; + mem_map_table_base_addr = dev->qdss.align_device_addr + + sizeof(struct hfi_mem_map_table); + qdss->mem_map_table_base_addr = mem_map_table_base_addr; + + mem_map = (struct hfi_mem_map *)(qdss + 1); + cb = msm_smem_get_context_bank(MSM_VIDC_UNKNOWN, false, + dev->res, HAL_BUFFER_INTERNAL_CMD_QUEUE); + if (!cb) { + dprintk(VIDC_ERR, + "%s: failed to get context bank\n", __func__); + return -EINVAL; + } + + rc = __get_qdss_iommu_virtual_addr(dev, mem_map, cb->domain); + if (rc) { + dprintk(VIDC_ERR, + "IOMMU mapping failed, Freeing qdss memdata\n"); + __smem_free(dev, &dev->qdss.mem_data); + dev->qdss.align_virtual_addr = NULL; + dev->qdss.align_device_addr = 0; + } + } + + + if (dev->res->domain_cvp) { + rc = __interface_dsp_queues_init(dev); + if (rc) { + dprintk(VIDC_ERR, "dsp_queues_init failed\n"); + goto fail_alloc_queue; + } + } + + __setup_ucregion_memory_map(dev); + return 0; +fail_alloc_queue: + return -ENOMEM; +} + +static int __sys_set_debug(struct venus_hfi_device *device, u32 debug) +{ + u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE]; + int rc = 0; + struct hfi_cmd_sys_set_property_packet *pkt = + (struct hfi_cmd_sys_set_property_packet *) &packet; + + rc = call_hfi_pkt_op(device, sys_debug_config, pkt, debug); + if (rc) { + dprintk(VIDC_WARN, + "Debug mode setting to FW failed\n"); + return -ENOTEMPTY; + } + + if (__iface_cmdq_write(device, pkt)) + return -ENOTEMPTY; + return 0; +} + +static int __sys_set_coverage(struct venus_hfi_device *device, u32 mode) +{ + u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE]; + int rc = 0; + struct hfi_cmd_sys_set_property_packet *pkt = + (struct hfi_cmd_sys_set_property_packet *) &packet; + + rc = call_hfi_pkt_op(device, sys_coverage_config, + pkt, mode); + if (rc) { + dprintk(VIDC_WARN, + "Coverage mode setting to FW failed\n"); + return -ENOTEMPTY; + } + + if (__iface_cmdq_write(device, pkt)) { + dprintk(VIDC_WARN, "Failed to send coverage pkt to f/w\n"); + return -ENOTEMPTY; + } + + return 0; +} + +static int __sys_set_power_control(struct venus_hfi_device *device, + bool enable) +{ + struct regulator_info *rinfo; + bool supported = false; + u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE]; + struct hfi_cmd_sys_set_property_packet *pkt = + (struct hfi_cmd_sys_set_property_packet *) &packet; + + venus_hfi_for_each_regulator(device, rinfo) { + if (rinfo->has_hw_power_collapse) { + supported = true; + break; + } + } + + if (!supported) + return 0; + + call_hfi_pkt_op(device, sys_power_control, pkt, enable); + if (__iface_cmdq_write(device, pkt)) + return -ENOTEMPTY; + return 0; +} + +static int venus_hfi_core_init(void *device) +{ + int rc = 0; + struct hfi_cmd_sys_init_packet pkt; + struct hfi_cmd_sys_get_property_packet version_pkt; + struct venus_hfi_device *dev; + + if (!device) { + dprintk(VIDC_ERR, "Invalid device\n"); + return -ENODEV; + } + + dev = device; + + dprintk(VIDC_DBG, "Core initializing\n"); + + mutex_lock(&dev->lock); + + dev->bus_vote.data = + kzalloc(sizeof(struct vidc_bus_vote_data), GFP_KERNEL); + if (!dev->bus_vote.data) { + dprintk(VIDC_ERR, "Bus vote data memory is not allocated\n"); + rc = -ENOMEM; + goto err_no_mem; + } + + dev->bus_vote.data_count = 1; + dev->bus_vote.data->power_mode = VIDC_POWER_TURBO; + + rc = __load_fw(dev); + if (rc) { + dprintk(VIDC_ERR, "Failed to load Venus FW\n"); + goto err_load_fw; + } + + __set_state(dev, VENUS_STATE_INIT); + + dprintk(VIDC_DBG, "Dev_Virt: %pa, Reg_Virt: %pK\n", + &dev->hal_data->firmware_base, + dev->hal_data->register_base); + + + rc = __interface_queues_init(dev); + if (rc) { + dprintk(VIDC_ERR, "failed to init queues\n"); + rc = -ENOMEM; + goto err_core_init; + } + + rc = __boot_firmware(dev); + if (rc) { + dprintk(VIDC_ERR, "Failed to start core\n"); + rc = -ENODEV; + goto err_core_init; + } + + rc = call_hfi_pkt_op(dev, sys_init, &pkt, HFI_VIDEO_ARCH_OX); + if (rc) { + dprintk(VIDC_ERR, "Failed to create sys init pkt\n"); + goto err_core_init; + } + + if (__iface_cmdq_write(dev, &pkt)) { + rc = -ENOTEMPTY; + goto err_core_init; + } + + rc = call_hfi_pkt_op(dev, sys_image_version, &version_pkt); + if (rc || __iface_cmdq_write(dev, &version_pkt)) + dprintk(VIDC_WARN, "Failed to send image version pkt to f/w\n"); + + __sys_set_debug(device, msm_vidc_fw_debug); + + __enable_subcaches(device); + __set_subcaches(device); + __dsp_send_hfi_queue(device); + + __set_ubwc_config(device); + + if (dev->res->pm_qos_latency_us) { +#ifdef CONFIG_SMP + dev->qos.type = PM_QOS_REQ_AFFINE_IRQ; + dev->qos.irq = dev->hal_data->irq; +#endif + pm_qos_add_request(&dev->qos, PM_QOS_CPU_DMA_LATENCY, + dev->res->pm_qos_latency_us); + } + dprintk(VIDC_DBG, "Core inited successfully\n"); + mutex_unlock(&dev->lock); + return rc; +err_core_init: + __set_state(dev, VENUS_STATE_DEINIT); + __unload_fw(dev); +err_load_fw: +err_no_mem: + dprintk(VIDC_ERR, "Core init failed\n"); + mutex_unlock(&dev->lock); + return rc; +} + +static int venus_hfi_core_release(void *dev) +{ + int rc = 0; + struct venus_hfi_device *device = dev; + struct hal_session *session, *next; + + if (!device) { + dprintk(VIDC_ERR, "invalid device\n"); + return -ENODEV; + } + + mutex_lock(&device->lock); + dprintk(VIDC_DBG, "Core releasing\n"); + if (device->res->pm_qos_latency_us && + pm_qos_request_active(&device->qos)) + pm_qos_remove_request(&device->qos); + + __resume(device); + __set_state(device, VENUS_STATE_DEINIT); + __dsp_shutdown(device, 0); + + __unload_fw(device); + + /* unlink all sessions from device */ + list_for_each_entry_safe(session, next, &device->sess_head, list) + list_del(&session->list); + + dprintk(VIDC_DBG, "Core released successfully\n"); + mutex_unlock(&device->lock); + + return rc; +} + +static int __get_q_size(struct venus_hfi_device *dev, unsigned int q_index) +{ + struct hfi_queue_header *queue; + struct vidc_iface_q_info *q_info; + u32 write_ptr, read_ptr; + + if (q_index >= VIDC_IFACEQ_NUMQ) { + dprintk(VIDC_ERR, "Invalid q index: %d\n", q_index); + return -ENOENT; + } + + q_info = &dev->iface_queues[q_index]; + if (!q_info) { + dprintk(VIDC_ERR, "cannot read shared Q's\n"); + return -ENOENT; + } + + queue = (struct hfi_queue_header *)q_info->q_hdr; + if (!queue) { + dprintk(VIDC_ERR, "queue not present\n"); + return -ENOENT; + } + + write_ptr = (u32)queue->qhdr_write_idx; + read_ptr = (u32)queue->qhdr_read_idx; + return read_ptr - write_ptr; +} + +static void __core_clear_interrupt(struct venus_hfi_device *device) +{ + u32 intr_status = 0, mask = 0; + + if (!device) { + dprintk(VIDC_ERR, "%s: NULL device\n", __func__); + return; + } + + intr_status = __read_register(device, VIDC_WRAPPER_INTR_STATUS); + mask = (VIDC_WRAPPER_INTR_STATUS_A2H_BMSK | + VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK | + VIDC_CTRL_INIT_IDLE_MSG_BMSK); + + if (intr_status & mask) { + device->intr_status |= intr_status; + device->reg_count++; + dprintk(VIDC_DBG, + "INTERRUPT for device: %pK: times: %d interrupt_status: %d\n", + device, device->reg_count, intr_status); + } else { + device->spur_count++; + } + + __write_register(device, VIDC_CPU_CS_A2HSOFTINTCLR, 1); +} + +static int venus_hfi_core_trigger_ssr(void *device, + enum hal_ssr_trigger_type type) +{ + struct hfi_cmd_sys_test_ssr_packet pkt; + int rc = 0; + struct venus_hfi_device *dev; + + if (!device) { + dprintk(VIDC_ERR, "invalid device\n"); + return -ENODEV; + } + + dev = device; + mutex_lock(&dev->lock); + + rc = call_hfi_pkt_op(dev, ssr_cmd, type, &pkt); + if (rc) { + dprintk(VIDC_ERR, "core_ping: failed to create packet\n"); + goto err_create_pkt; + } + + if (__iface_cmdq_write(dev, &pkt)) + rc = -ENOTEMPTY; + +err_create_pkt: + mutex_unlock(&dev->lock); + return rc; +} + +static int venus_hfi_session_set_property(void *sess, + u32 ptype, void *pdata, u32 size) +{ + u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE]; + struct hfi_cmd_session_set_property_packet *pkt = + (struct hfi_cmd_session_set_property_packet *) &packet; + struct hal_session *session = sess; + struct venus_hfi_device *device; + int rc = 0; + + if (!session || !session->device) { + dprintk(VIDC_ERR, "Invalid Params\n"); + return -EINVAL; + } + + device = session->device; + mutex_lock(&device->lock); + + dprintk(VIDC_INFO, "in set_prop,with prop id: %#x\n", ptype); + if (!__is_session_valid(device, session, __func__)) { + rc = -EINVAL; + goto err_set_prop; + } + + rc = call_hfi_pkt_op(device, session_set_property, + pkt, session, ptype, pdata, size); + + if (rc == -ENOTSUPP) { + dprintk(VIDC_DBG, + "set property: unsupported prop id: %#x\n", ptype); + rc = 0; + goto err_set_prop; + } else if (rc) { + dprintk(VIDC_ERR, "set property: failed to create packet\n"); + rc = -EINVAL; + goto err_set_prop; + } + + if (__iface_cmdq_write(session->device, pkt)) { + rc = -ENOTEMPTY; + goto err_set_prop; + } + +err_set_prop: + mutex_unlock(&device->lock); + return rc; +} + +static void __set_default_sys_properties(struct venus_hfi_device *device) +{ + if (__sys_set_debug(device, msm_vidc_fw_debug)) + dprintk(VIDC_WARN, "Setting fw_debug msg ON failed\n"); + if (__sys_set_power_control(device, true)) + dprintk(VIDC_WARN, "Setting h/w power collapse ON failed\n"); +} + +static void __session_clean(struct hal_session *session) +{ + struct hal_session *temp, *next; + struct venus_hfi_device *device; + + if (!session || !session->device) { + dprintk(VIDC_WARN, "%s: invalid params\n", __func__); + return; + } + device = session->device; + dprintk(VIDC_DBG, "deleted the session: %pK\n", session); + /* + * session might have been removed from the device list in + * core_release, so check and remove if it is in the list + */ + list_for_each_entry_safe(temp, next, &device->sess_head, list) { + if (session == temp) { + list_del(&session->list); + break; + } + } + /* Poison the session handle with zeros */ + *session = (struct hal_session){ {0} }; + kfree(session); +} + +static int venus_hfi_session_clean(void *session) +{ + struct hal_session *sess_close; + struct venus_hfi_device *device; + + if (!session) { + dprintk(VIDC_ERR, "Invalid Params %s\n", __func__); + return -EINVAL; + } + + sess_close = session; + device = sess_close->device; + + if (!device) { + dprintk(VIDC_ERR, "Invalid device handle %s\n", __func__); + return -EINVAL; + } + + mutex_lock(&device->lock); + + __session_clean(sess_close); + + mutex_unlock(&device->lock); + return 0; +} + +static int venus_hfi_session_init(void *device, void *session_id, + enum hal_domain session_type, enum hal_video_codec codec_type, + void **new_session) +{ + struct hfi_cmd_sys_session_init_packet pkt; + struct venus_hfi_device *dev; + struct hal_session *s; + + if (!device || !new_session) { + dprintk(VIDC_ERR, "%s - invalid input\n", __func__); + return -EINVAL; + } + + dev = device; + mutex_lock(&dev->lock); + + s = kzalloc(sizeof(struct hal_session), GFP_KERNEL); + if (!s) { + dprintk(VIDC_ERR, "new session fail: Out of memory\n"); + goto err_session_init_fail; + } + + s->session_id = session_id; + s->is_decoder = (session_type == HAL_VIDEO_DOMAIN_DECODER); + s->device = dev; + s->codec = codec_type; + s->domain = session_type; + dprintk(VIDC_DBG, + "%s: inst %pK, session %pK, codec 0x%x, domain 0x%x\n", + __func__, session_id, s, s->codec, s->domain); + + list_add_tail(&s->list, &dev->sess_head); + + __set_default_sys_properties(device); + + if (call_hfi_pkt_op(dev, session_init, &pkt, + s, session_type, codec_type)) { + dprintk(VIDC_ERR, "session_init: failed to create packet\n"); + goto err_session_init_fail; + } + + *new_session = s; + if (__iface_cmdq_write(dev, &pkt)) + goto err_session_init_fail; + + mutex_unlock(&dev->lock); + return 0; + +err_session_init_fail: + if (s) + __session_clean(s); + *new_session = NULL; + mutex_unlock(&dev->lock); + return -EINVAL; +} + +static int __send_session_cmd(struct hal_session *session, int pkt_type) +{ + struct vidc_hal_session_cmd_pkt pkt; + int rc = 0; + struct venus_hfi_device *device = session->device; + + if (!__is_session_valid(device, session, __func__)) + return -EINVAL; + + rc = call_hfi_pkt_op(device, session_cmd, + &pkt, pkt_type, session); + if (rc == -EPERM) + return 0; + + if (rc) { + dprintk(VIDC_ERR, "send session cmd: create pkt failed\n"); + goto err_create_pkt; + } + + if (__iface_cmdq_write(session->device, &pkt)) + rc = -ENOTEMPTY; + +err_create_pkt: + return rc; +} + +static int venus_hfi_session_end(void *session) +{ + struct hal_session *sess; + struct venus_hfi_device *device; + int rc = 0; + + if (!session) { + dprintk(VIDC_ERR, "Invalid Params %s\n", __func__); + return -EINVAL; + } + + sess = session; + device = sess->device; + + mutex_lock(&device->lock); + + if (msm_vidc_fw_coverage) { + if (__sys_set_coverage(sess->device, msm_vidc_fw_coverage)) + dprintk(VIDC_WARN, "Fw_coverage msg ON failed\n"); + } + + rc = __send_session_cmd(session, HFI_CMD_SYS_SESSION_END); + + mutex_unlock(&device->lock); + + return rc; +} + +static int venus_hfi_session_abort(void *sess) +{ + struct hal_session *session = sess; + struct venus_hfi_device *device; + int rc = 0; + + if (!session || !session->device) { + dprintk(VIDC_ERR, "Invalid Params %s\n", __func__); + return -EINVAL; + } + + device = session->device; + + mutex_lock(&device->lock); + + __flush_debug_queue(device, NULL); + rc = __send_session_cmd(session, HFI_CMD_SYS_SESSION_ABORT); + + mutex_unlock(&device->lock); + + return rc; +} + +static int venus_hfi_session_set_buffers(void *sess, + struct vidc_buffer_addr_info *buffer_info) +{ + struct hfi_cmd_session_set_buffers_packet *pkt; + u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE]; + int rc = 0; + struct hal_session *session = sess; + struct venus_hfi_device *device; + + if (!session || !session->device || !buffer_info) { + dprintk(VIDC_ERR, "Invalid Params\n"); + return -EINVAL; + } + + device = session->device; + mutex_lock(&device->lock); + + if (!__is_session_valid(device, session, __func__)) { + rc = -EINVAL; + goto err_create_pkt; + } + if (buffer_info->buffer_type == HAL_BUFFER_INPUT) { + /* + * Hardware doesn't care about input buffers being + * published beforehand + */ + rc = 0; + goto err_create_pkt; + } + + pkt = (struct hfi_cmd_session_set_buffers_packet *)packet; + + rc = call_hfi_pkt_op(device, session_set_buffers, + pkt, session, buffer_info); + if (rc) { + dprintk(VIDC_ERR, "set buffers: failed to create packet\n"); + goto err_create_pkt; + } + + dprintk(VIDC_INFO, "set buffers: %#x\n", buffer_info->buffer_type); + if (__iface_cmdq_write(session->device, pkt)) + rc = -ENOTEMPTY; + +err_create_pkt: + mutex_unlock(&device->lock); + return rc; +} + +static int venus_hfi_session_release_buffers(void *sess, + struct vidc_buffer_addr_info *buffer_info) +{ + struct hfi_cmd_session_release_buffer_packet *pkt; + u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE]; + int rc = 0; + struct hal_session *session = sess; + struct venus_hfi_device *device; + + if (!session || !session->device || !buffer_info) { + dprintk(VIDC_ERR, "Invalid Params\n"); + return -EINVAL; + } + + device = session->device; + mutex_lock(&device->lock); + + if (!__is_session_valid(device, session, __func__)) { + rc = -EINVAL; + goto err_create_pkt; + } + if (buffer_info->buffer_type == HAL_BUFFER_INPUT) { + rc = 0; + goto err_create_pkt; + } + + pkt = (struct hfi_cmd_session_release_buffer_packet *) packet; + + rc = call_hfi_pkt_op(device, session_release_buffers, + pkt, session, buffer_info); + if (rc) { + dprintk(VIDC_ERR, "release buffers: failed to create packet\n"); + goto err_create_pkt; + } + + dprintk(VIDC_INFO, "Release buffers: %#x\n", buffer_info->buffer_type); + if (__iface_cmdq_write(session->device, pkt)) + rc = -ENOTEMPTY; + +err_create_pkt: + mutex_unlock(&device->lock); + return rc; +} + +static int venus_hfi_session_register_buffer(void *sess, + struct vidc_register_buffer *buffer) +{ + int rc = 0; + u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE]; + struct hfi_cmd_session_register_buffers_packet *pkt; + struct hal_session *session = sess; + struct venus_hfi_device *device; + + if (!session || !session->device || !buffer) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + device = session->device; + + mutex_lock(&device->lock); + if (!__is_session_valid(device, session, __func__)) { + rc = -EINVAL; + goto exit; + } + pkt = (struct hfi_cmd_session_register_buffers_packet *)packet; + rc = call_hfi_pkt_op(device, session_register_buffer, pkt, + session, buffer); + if (rc) { + dprintk(VIDC_ERR, "%s: failed to create packet\n", __func__); + goto exit; + } + if (__iface_cmdq_write(session->device, pkt)) + rc = -ENOTEMPTY; +exit: + mutex_unlock(&device->lock); + + return rc; +} + +static int venus_hfi_session_unregister_buffer(void *sess, + struct vidc_unregister_buffer *buffer) +{ + int rc = 0; + u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE]; + struct hfi_cmd_session_unregister_buffers_packet *pkt; + struct hal_session *session = sess; + struct venus_hfi_device *device; + + if (!session || !session->device || !buffer) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + device = session->device; + + mutex_lock(&device->lock); + if (!__is_session_valid(device, session, __func__)) { + rc = -EINVAL; + goto exit; + } + pkt = (struct hfi_cmd_session_unregister_buffers_packet *)packet; + rc = call_hfi_pkt_op(device, session_unregister_buffer, pkt, + session, buffer); + if (rc) { + dprintk(VIDC_ERR, "%s: failed to create packet\n", __func__); + goto exit; + } + if (__iface_cmdq_write(session->device, pkt)) + rc = -ENOTEMPTY; +exit: + mutex_unlock(&device->lock); + + return rc; +} + +static int venus_hfi_session_load_res(void *session) +{ + struct hal_session *sess; + struct venus_hfi_device *device; + int rc = 0; + + if (!session) { + dprintk(VIDC_ERR, "Invalid Params %s\n", __func__); + return -EINVAL; + } + + sess = session; + device = sess->device; + + mutex_lock(&device->lock); + rc = __send_session_cmd(sess, HFI_CMD_SESSION_LOAD_RESOURCES); + mutex_unlock(&device->lock); + + return rc; +} + +static int venus_hfi_session_release_res(void *session) +{ + struct hal_session *sess; + struct venus_hfi_device *device; + int rc = 0; + + if (!session) { + dprintk(VIDC_ERR, "Invalid Params %s\n", __func__); + return -EINVAL; + } + + sess = session; + device = sess->device; + + mutex_lock(&device->lock); + rc = __send_session_cmd(sess, HFI_CMD_SESSION_RELEASE_RESOURCES); + mutex_unlock(&device->lock); + + return rc; +} + +static int venus_hfi_session_start(void *session) +{ + struct hal_session *sess; + struct venus_hfi_device *device; + int rc = 0; + + if (!session) { + dprintk(VIDC_ERR, "Invalid Params %s\n", __func__); + return -EINVAL; + } + + sess = session; + device = sess->device; + + mutex_lock(&device->lock); + rc = __send_session_cmd(sess, HFI_CMD_SESSION_START); + mutex_unlock(&device->lock); + + return rc; +} + +static int venus_hfi_session_continue(void *session) +{ + struct hal_session *sess; + struct venus_hfi_device *device; + int rc = 0; + + if (!session) { + dprintk(VIDC_ERR, "Invalid Params %s\n", __func__); + return -EINVAL; + } + + sess = session; + device = sess->device; + + mutex_lock(&device->lock); + rc = __send_session_cmd(sess, HFI_CMD_SESSION_CONTINUE); + mutex_unlock(&device->lock); + + return rc; +} + +static int venus_hfi_session_stop(void *session) +{ + struct hal_session *sess; + struct venus_hfi_device *device; + int rc = 0; + + if (!session) { + dprintk(VIDC_ERR, "Invalid Params %s\n", __func__); + return -EINVAL; + } + + sess = session; + device = sess->device; + + mutex_lock(&device->lock); + rc = __send_session_cmd(sess, HFI_CMD_SESSION_STOP); + mutex_unlock(&device->lock); + + return rc; +} + +static int __session_etb(struct hal_session *session, + struct vidc_frame_data *input_frame, bool relaxed) +{ + int rc = 0; + struct venus_hfi_device *device = session->device; + + if (!__is_session_valid(device, session, __func__)) + return -EINVAL; + + if (session->is_decoder) { + struct hfi_cmd_session_empty_buffer_compressed_packet pkt; + + rc = call_hfi_pkt_op(device, session_etb_decoder, + &pkt, session, input_frame); + if (rc) { + dprintk(VIDC_ERR, + "Session etb decoder: failed to create pkt\n"); + goto err_create_pkt; + } + + if (!relaxed) + rc = __iface_cmdq_write(session->device, &pkt); + else + rc = __iface_cmdq_write_relaxed(session->device, + &pkt, NULL); + if (rc) + goto err_create_pkt; + } else { + struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet + pkt; + + rc = call_hfi_pkt_op(device, session_etb_encoder, + &pkt, session, input_frame); + if (rc) { + dprintk(VIDC_ERR, + "Session etb encoder: failed to create pkt\n"); + goto err_create_pkt; + } + + if (!relaxed) + rc = __iface_cmdq_write(session->device, &pkt); + else + rc = __iface_cmdq_write_relaxed(session->device, + &pkt, NULL); + if (rc) + goto err_create_pkt; + } + +err_create_pkt: + return rc; +} + +static int venus_hfi_session_etb(void *sess, + struct vidc_frame_data *input_frame) +{ + int rc = 0; + struct hal_session *session = sess; + struct venus_hfi_device *device; + + if (!session || !session->device || !input_frame) { + dprintk(VIDC_ERR, "Invalid Params\n"); + return -EINVAL; + } + + device = session->device; + mutex_lock(&device->lock); + rc = __session_etb(session, input_frame, false); + mutex_unlock(&device->lock); + return rc; +} + +static int __session_ftb(struct hal_session *session, + struct vidc_frame_data *output_frame, bool relaxed) +{ + int rc = 0; + struct venus_hfi_device *device = session->device; + struct hfi_cmd_session_fill_buffer_packet pkt; + + if (!__is_session_valid(device, session, __func__)) + return -EINVAL; + + rc = call_hfi_pkt_op(device, session_ftb, + &pkt, session, output_frame); + if (rc) { + dprintk(VIDC_ERR, "Session ftb: failed to create pkt\n"); + goto err_create_pkt; + } + + if (!relaxed) + rc = __iface_cmdq_write(session->device, &pkt); + else + rc = __iface_cmdq_write_relaxed(session->device, + &pkt, NULL); + +err_create_pkt: + return rc; +} + +static int venus_hfi_session_ftb(void *sess, + struct vidc_frame_data *output_frame) +{ + int rc = 0; + struct hal_session *session = sess; + struct venus_hfi_device *device; + + if (!session || !session->device || !output_frame) { + dprintk(VIDC_ERR, "Invalid Params\n"); + return -EINVAL; + } + + device = session->device; + mutex_lock(&device->lock); + rc = __session_ftb(session, output_frame, false); + mutex_unlock(&device->lock); + return rc; +} + +static int venus_hfi_session_process_batch(void *sess, + int num_etbs, struct vidc_frame_data etbs[], + int num_ftbs, struct vidc_frame_data ftbs[]) +{ + int rc = 0, c = 0; + struct hal_session *session = sess; + struct venus_hfi_device *device; + struct hfi_cmd_session_sync_process_packet pkt; + + if (!session || !session->device) { + dprintk(VIDC_ERR, "%s: Invalid Params\n", __func__); + return -EINVAL; + } + + device = session->device; + + mutex_lock(&device->lock); + + if (!__is_session_valid(device, session, __func__)) { + rc = -EINVAL; + goto err_etbs_and_ftbs; + } + + for (c = 0; c < num_ftbs; ++c) { + rc = __session_ftb(session, &ftbs[c], true); + if (rc) { + dprintk(VIDC_ERR, "Failed to queue batched ftb: %d\n", + rc); + goto err_etbs_and_ftbs; + } + } + + for (c = 0; c < num_etbs; ++c) { + rc = __session_etb(session, &etbs[c], true); + if (rc) { + dprintk(VIDC_ERR, "Failed to queue batched etb: %d\n", + rc); + goto err_etbs_and_ftbs; + } + } + + rc = call_hfi_pkt_op(device, session_sync_process, &pkt, session); + if (rc) { + dprintk(VIDC_ERR, "Failed to create sync packet\n"); + goto err_etbs_and_ftbs; + } + + if (__iface_cmdq_write(session->device, &pkt)) + rc = -ENOTEMPTY; + +err_etbs_and_ftbs: + mutex_unlock(&device->lock); + return rc; +} + +static int venus_hfi_session_get_buf_req(void *sess) +{ + struct hfi_cmd_session_get_property_packet pkt; + int rc = 0; + struct hal_session *session = sess; + struct venus_hfi_device *device; + + if (!session || !session->device) { + dprintk(VIDC_ERR, "invalid session"); + return -ENODEV; + } + + device = session->device; + mutex_lock(&device->lock); + + if (!__is_session_valid(device, session, __func__)) { + rc = -EINVAL; + goto err_create_pkt; + } + rc = call_hfi_pkt_op(device, session_get_buf_req, + &pkt, session); + if (rc) { + dprintk(VIDC_ERR, + "Session get buf req: failed to create pkt\n"); + goto err_create_pkt; + } + + if (__iface_cmdq_write(session->device, &pkt)) + rc = -ENOTEMPTY; +err_create_pkt: + mutex_unlock(&device->lock); + return rc; +} + +static int venus_hfi_session_flush(void *sess, enum hal_flush flush_mode) +{ + struct hfi_cmd_session_flush_packet pkt; + int rc = 0; + struct hal_session *session = sess; + struct venus_hfi_device *device; + + if (!session || !session->device) { + dprintk(VIDC_ERR, "invalid session"); + return -ENODEV; + } + + device = session->device; + mutex_lock(&device->lock); + + if (!__is_session_valid(device, session, __func__)) { + rc = -EINVAL; + goto err_create_pkt; + } + rc = call_hfi_pkt_op(device, session_flush, + &pkt, session, flush_mode); + if (rc) { + dprintk(VIDC_ERR, "Session flush: failed to create pkt\n"); + goto err_create_pkt; + } + + if (__iface_cmdq_write(session->device, &pkt)) + rc = -ENOTEMPTY; +err_create_pkt: + mutex_unlock(&device->lock); + return rc; +} + +static int __check_core_registered(struct hal_device_data core, + phys_addr_t fw_addr, u8 *reg_addr, u32 reg_size, + phys_addr_t irq) +{ + struct venus_hfi_device *device; + struct hal_data *hal_data; + struct list_head *curr, *next; + + if (!core.dev_count) { + dprintk(VIDC_INFO, "no device Registered\n"); + return -EINVAL; + } + + list_for_each_safe(curr, next, &core.dev_head) { + device = list_entry(curr, + struct venus_hfi_device, list); + hal_data = device->hal_data; + if (device && hal_data->irq == irq && + (CONTAINS(hal_data->firmware_base, + FIRMWARE_SIZE, fw_addr) || + CONTAINS(fw_addr, FIRMWARE_SIZE, + hal_data->firmware_base) || + CONTAINS(hal_data->register_base, + reg_size, reg_addr) || + CONTAINS(reg_addr, reg_size, + hal_data->register_base) || + OVERLAPS(hal_data->register_base, + reg_size, reg_addr, reg_size) || + OVERLAPS(reg_addr, reg_size, + hal_data->register_base, + reg_size) || + OVERLAPS(hal_data->firmware_base, + FIRMWARE_SIZE, fw_addr, + FIRMWARE_SIZE) || + OVERLAPS(fw_addr, FIRMWARE_SIZE, + hal_data->firmware_base, + FIRMWARE_SIZE))) { + return 0; + } + + dprintk(VIDC_INFO, "Device not registered\n"); + return -EINVAL; + } + return -EINVAL; +} + +static void __process_fatal_error( + struct venus_hfi_device *device) +{ + struct msm_vidc_cb_cmd_done cmd_done = {0}; + + cmd_done.device_id = device->device_id; + device->callback(HAL_SYS_ERROR, &cmd_done); +} + +static int __prepare_pc(struct venus_hfi_device *device) +{ + int rc = 0; + struct hfi_cmd_sys_pc_prep_packet pkt; + + rc = call_hfi_pkt_op(device, sys_pc_prep, &pkt); + if (rc) { + dprintk(VIDC_ERR, "Failed to create sys pc prep pkt\n"); + goto err_pc_prep; + } + + if (__iface_cmdq_write(device, &pkt)) + rc = -ENOTEMPTY; + if (rc) + dprintk(VIDC_ERR, "Failed to prepare venus for power off"); +err_pc_prep: + return rc; +} + +static void venus_hfi_pm_handler(struct work_struct *work) +{ + int rc = 0; + struct venus_hfi_device *device = list_first_entry( + &hal_ctxt.dev_head, struct venus_hfi_device, list); + + if (!device) { + dprintk(VIDC_ERR, "%s: NULL device\n", __func__); + return; + } + + dprintk(VIDC_PROF, + "Entering %s\n", __func__); + /* + * It is ok to check this variable outside the lock since + * it is being updated in this context only + */ + if (device->skip_pc_count >= VIDC_MAX_PC_SKIP_COUNT) { + dprintk(VIDC_WARN, "Failed to PC for %d times\n", + device->skip_pc_count); + device->skip_pc_count = 0; + __process_fatal_error(device); + return; + } + + mutex_lock(&device->lock); + rc = __power_collapse(device, false); + mutex_unlock(&device->lock); + switch (rc) { + case 0: + device->skip_pc_count = 0; + /* Cancel pending delayed works if any */ + cancel_delayed_work(&venus_hfi_pm_work); + dprintk(VIDC_PROF, "%s: power collapse successful!\n", + __func__); + break; + case -EBUSY: + device->skip_pc_count = 0; + dprintk(VIDC_DBG, "%s: retry PC as dsp is busy\n", __func__); + queue_delayed_work(device->venus_pm_workq, + &venus_hfi_pm_work, msecs_to_jiffies( + device->res->msm_vidc_pwr_collapse_delay)); + break; + case -EAGAIN: + device->skip_pc_count++; + dprintk(VIDC_WARN, "%s: retry power collapse (count %d)\n", + __func__, device->skip_pc_count); + queue_delayed_work(device->venus_pm_workq, + &venus_hfi_pm_work, msecs_to_jiffies( + device->res->msm_vidc_pwr_collapse_delay)); + break; + default: + dprintk(VIDC_ERR, "%s: power collapse failed\n", __func__); + break; + } +} + +static int __power_collapse(struct venus_hfi_device *device, bool force) +{ + int rc = 0; + u32 wfi_status = 0, idle_status = 0, pc_ready = 0; + u32 ctrl_status = 0; + u32 flags = 0; + int count = 0; + const int max_tries = 10; + + if (!device) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + if (!device->power_enabled) { + dprintk(VIDC_DBG, "%s: Power already disabled\n", + __func__); + goto exit; + } + + if (!__core_in_valid_state(device)) { + dprintk(VIDC_WARN, "%s - Core not in init state\n", __func__); + return -EINVAL; + } + + rc = __dsp_suspend(device, force, flags); + if (rc == -EBUSY) + goto exit; + else if (rc) + goto skip_power_off; + + ctrl_status = __read_register(device, VIDC_CTRL_STATUS); + pc_ready = ctrl_status & VIDC_CTRL_STATUS_PC_READY; + idle_status = ctrl_status & BIT(30); + + if (!pc_ready) { + wfi_status = BIT(0) & + __read_register(device, + VIDC_WRAPPER_TZ_CPU_STATUS); + if (!wfi_status || !idle_status) { + dprintk(VIDC_WARN, + "Skipping PC, wfi or idle status not set.\n"); + goto skip_power_off; + } + + rc = __prepare_pc(device); + if (rc) { + dprintk(VIDC_WARN, "Failed __prepare_pc %d\n", rc); + goto skip_power_off; + } + + while (count < max_tries) { + wfi_status = BIT(0) & + __read_register(device, + VIDC_WRAPPER_TZ_CPU_STATUS); + ctrl_status = __read_register(device, + VIDC_CTRL_STATUS); + if (wfi_status && + (ctrl_status & VIDC_CTRL_STATUS_PC_READY)) + break; + usleep_range(150, 250); + count++; + } + + if (count == max_tries) { + dprintk(VIDC_ERR, + "Skip PC. Core is not in right state.\n"); + goto skip_power_off; + } + } + + __flush_debug_queue(device, device->raw_packet); + + rc = __suspend(device); + if (rc) + dprintk(VIDC_ERR, "Failed __suspend\n"); + +exit: + return rc; + +skip_power_off: + dprintk(VIDC_WARN, "Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n", + wfi_status, idle_status, pc_ready, ctrl_status); + + return -EAGAIN; +} + +static void __process_sys_error(struct venus_hfi_device *device) +{ + struct hfi_sfr_struct *vsfr = NULL; + + vsfr = (struct hfi_sfr_struct *)device->sfr.align_virtual_addr; + if (vsfr) { + void *p = memchr(vsfr->rg_data, '\0', vsfr->bufSize); + /* + * SFR isn't guaranteed to be NULL terminated + * since SYS_ERROR indicates that Venus is in the + * process of crashing. + */ + if (p == NULL) + vsfr->rg_data[vsfr->bufSize - 1] = '\0'; + + dprintk(VIDC_ERR, "SFR Message from FW: %s\n", + vsfr->rg_data); + } +} + +static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) +{ + bool local_packet = false; + enum vidc_msg_prio log_level = VIDC_FW; + + if (!device) { + dprintk(VIDC_ERR, "%s: Invalid params\n", __func__); + return; + } + + if (!packet) { + packet = kzalloc(VIDC_IFACEQ_VAR_HUGE_PKT_SIZE, GFP_KERNEL); + if (!packet) { + dprintk(VIDC_ERR, "In %s() Fail to allocate mem\n", + __func__); + return; + } + + local_packet = true; + + /* + * Local packek is used when something FATAL occurred. + * It is good to print these logs by default. + */ + + log_level = VIDC_ERR; + } + + while (!__iface_dbgq_read(device, packet)) { + struct hfi_msg_sys_coverage_packet *pkt = + (struct hfi_msg_sys_coverage_packet *) packet; + + if (pkt->packet_type == HFI_MSG_SYS_COV) { + int stm_size = 0; + + stm_size = stm_log_inv_ts(0, 0, + pkt->rg_msg_data, pkt->msg_size); + if (stm_size == 0) + dprintk(VIDC_ERR, + "In %s, stm_log returned size of 0\n", + __func__); + } else { + struct hfi_msg_sys_debug_packet *pkt = + (struct hfi_msg_sys_debug_packet *) packet; + /* + * All fw messages starts with new line character. This + * causes dprintk to print this message in two lines + * in the kernel log. Ignoring the first character + * from the message fixes this to print it in a single + * line. + */ + dprintk(log_level, "%s", &pkt->rg_msg_data[1]); + } + } + + if (local_packet) + kfree(packet); +} + +static bool __is_session_valid(struct venus_hfi_device *device, + struct hal_session *session, const char *func) +{ + struct hal_session *temp = NULL; + + if (!device || !session) + goto invalid; + + list_for_each_entry(temp, &device->sess_head, list) + if (session == temp) + return true; + +invalid: + dprintk(VIDC_WARN, "%s: device %pK, invalid session %pK\n", + func, device, session); + return false; +} + +static struct hal_session *__get_session(struct venus_hfi_device *device, + u32 session_id) +{ + struct hal_session *temp = NULL; + + list_for_each_entry(temp, &device->sess_head, list) { + if (session_id == hash32_ptr(temp)) + return temp; + } + + return NULL; +} + +static int __response_handler(struct venus_hfi_device *device) +{ + struct msm_vidc_cb_info *packets; + int packet_count = 0; + u8 *raw_packet = NULL; + bool requeue_pm_work = true; + + if (!device || device->state != VENUS_STATE_INIT) + return 0; + + packets = device->response_pkt; + + raw_packet = device->raw_packet; + + if (!raw_packet || !packets) { + dprintk(VIDC_ERR, + "%s: Invalid args : Res packet = %p, Raw packet = %p\n", + __func__, packets, raw_packet); + return 0; + } + + if (device->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK) { + struct hfi_sfr_struct *vsfr = (struct hfi_sfr_struct *) + device->sfr.align_virtual_addr; + struct msm_vidc_cb_info info = { + .response_type = HAL_SYS_WATCHDOG_TIMEOUT, + .response.cmd = { + .device_id = device->device_id, + } + }; + + if (vsfr) + dprintk(VIDC_ERR, "SFR Message from FW: %s\n", + vsfr->rg_data); + + dprintk(VIDC_ERR, "Received watchdog timeout\n"); + packets[packet_count++] = info; + goto exit; + } + + /* Bleed the msg queue dry of packets */ + while (!__iface_msgq_read(device, raw_packet)) { + void **session_id = NULL; + struct msm_vidc_cb_info *info = &packets[packet_count++]; + int rc = 0; + + rc = hfi_process_msg_packet(device->device_id, + (struct vidc_hal_msg_pkt_hdr *)raw_packet, info); + if (rc) { + dprintk(VIDC_WARN, + "Corrupt/unknown packet found, discarding\n"); + --packet_count; + continue; + } + + /* Process the packet types that we're interested in */ + switch (info->response_type) { + case HAL_SYS_ERROR: + __process_sys_error(device); + break; + case HAL_SYS_RELEASE_RESOURCE_DONE: + dprintk(VIDC_DBG, "Received SYS_RELEASE_RESOURCE\n"); + break; + case HAL_SYS_INIT_DONE: + dprintk(VIDC_DBG, "Received SYS_INIT_DONE\n"); + break; + case HAL_SESSION_LOAD_RESOURCE_DONE: + /* + * Work around for H/W bug, need to re-program these + * registers as part of a handshake agreement with the + * firmware. This strictly only needs to be done for + * decoder secure sessions, but there's no harm in doing + * so for all sessions as it's at worst a NO-OP. + */ + __set_threshold_registers(device); + break; + default: + break; + } + + /* For session-related packets, validate session */ + switch (info->response_type) { + case HAL_SESSION_LOAD_RESOURCE_DONE: + case HAL_SESSION_INIT_DONE: + case HAL_SESSION_END_DONE: + case HAL_SESSION_ABORT_DONE: + case HAL_SESSION_START_DONE: + case HAL_SESSION_STOP_DONE: + case HAL_SESSION_FLUSH_DONE: + case HAL_SESSION_SUSPEND_DONE: + case HAL_SESSION_RESUME_DONE: + case HAL_SESSION_SET_PROP_DONE: + case HAL_SESSION_GET_PROP_DONE: + case HAL_SESSION_RELEASE_BUFFER_DONE: + case HAL_SESSION_REGISTER_BUFFER_DONE: + case HAL_SESSION_UNREGISTER_BUFFER_DONE: + case HAL_SESSION_RELEASE_RESOURCE_DONE: + case HAL_SESSION_PROPERTY_INFO: + session_id = &info->response.cmd.session_id; + break; + case HAL_SESSION_ERROR: + case HAL_SESSION_ETB_DONE: + case HAL_SESSION_FTB_DONE: + session_id = &info->response.data.session_id; + break; + case HAL_SESSION_EVENT_CHANGE: + session_id = &info->response.event.session_id; + break; + case HAL_RESPONSE_UNUSED: + default: + session_id = NULL; + break; + } + + /* + * hfi_process_msg_packet provides a session_id that's a hashed + * value of struct hal_session, we need to coerce the hashed + * value back to pointer that we can use. Ideally, hfi_process\ + * _msg_packet should take care of this, but it doesn't have + * required information for it + */ + if (session_id) { + struct hal_session *session = NULL; + + if (upper_32_bits((uintptr_t)*session_id) != 0) { + dprintk(VIDC_ERR, + "Upper 32-bits != 0 for sess_id=%pK\n", + *session_id); + } + session = __get_session(device, + (u32)(uintptr_t)*session_id); + if (!session) { + dprintk(VIDC_ERR, + "Received a packet (%#x) for an unrecognized session (%pK), discarding\n", + info->response_type, + *session_id); + --packet_count; + continue; + } + + *session_id = session->session_id; + } + + if (packet_count >= max_packets && + __get_q_size(device, VIDC_IFACEQ_MSGQ_IDX)) { + dprintk(VIDC_WARN, + "Too many packets in message queue to handle at once, deferring read\n"); + break; + } + + /* do not read packets after sys error packet */ + if (info->response_type == HAL_SYS_ERROR) + break; + } + + if (requeue_pm_work && device->res->sw_power_collapsible) { + cancel_delayed_work(&venus_hfi_pm_work); + if (!queue_delayed_work(device->venus_pm_workq, + &venus_hfi_pm_work, + msecs_to_jiffies( + device->res->msm_vidc_pwr_collapse_delay))) { + dprintk(VIDC_ERR, "PM work already scheduled\n"); + } + } + +exit: + __flush_debug_queue(device, raw_packet); + + return packet_count; +} + +static void venus_hfi_core_work_handler(struct work_struct *work) +{ + struct venus_hfi_device *device = list_first_entry( + &hal_ctxt.dev_head, struct venus_hfi_device, list); + int num_responses = 0, i = 0; + u32 intr_status; + + mutex_lock(&device->lock); + + + if (!__core_in_valid_state(device)) { + dprintk(VIDC_DBG, "%s - Core not in init state\n", __func__); + goto err_no_work; + } + + if (!device->callback) { + dprintk(VIDC_ERR, "No interrupt callback function: %pK\n", + device); + goto err_no_work; + } + + if (__resume(device)) { + dprintk(VIDC_ERR, "%s: Power enable failed\n", __func__); + goto err_no_work; + } + + __core_clear_interrupt(device); + num_responses = __response_handler(device); + +err_no_work: + + /* Keep the interrupt status before releasing device lock */ + intr_status = device->intr_status; + mutex_unlock(&device->lock); + + /* + * Issue the callbacks outside of the locked contex to preserve + * re-entrancy. + */ + + for (i = 0; !IS_ERR_OR_NULL(device->response_pkt) && + i < num_responses; ++i) { + struct msm_vidc_cb_info *r = &device->response_pkt[i]; + + if (!__core_in_valid_state(device)) { + dprintk(VIDC_ERR, + "Ignore responses from %d to %d as device is in invalid state", + (i + 1), num_responses); + break; + } + dprintk(VIDC_DBG, "Processing response %d of %d, type %d\n", + (i + 1), num_responses, r->response_type); + device->callback(r->response_type, &r->response); + } + + /* We need re-enable the irq which was disabled in ISR handler */ + if (!(intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK)) + enable_irq(device->hal_data->irq); + + /* + * XXX: Don't add any code beyond here. Reacquiring locks after release + * it above doesn't guarantee the atomicity that we're aiming for. + */ +} + +static DECLARE_WORK(venus_hfi_work, venus_hfi_core_work_handler); + +static irqreturn_t venus_hfi_isr(int irq, void *dev) +{ + struct venus_hfi_device *device = dev; + + disable_irq_nosync(irq); + queue_work(device->vidc_workq, &venus_hfi_work); + return IRQ_HANDLED; +} + +static int __init_regs_and_interrupts(struct venus_hfi_device *device, + struct msm_vidc_platform_resources *res) +{ + struct hal_data *hal = NULL; + int rc = 0; + + rc = __check_core_registered(hal_ctxt, res->firmware_base, + (u8 *)(uintptr_t)res->register_base, + res->register_size, res->irq); + if (!rc) { + dprintk(VIDC_ERR, "Core present/Already added\n"); + rc = -EEXIST; + goto err_core_init; + } + + dprintk(VIDC_DBG, "HAL_DATA will be assigned now\n"); + hal = kzalloc(sizeof(struct hal_data), GFP_KERNEL); + if (!hal) { + dprintk(VIDC_ERR, "Failed to alloc\n"); + rc = -ENOMEM; + goto err_core_init; + } + + hal->irq = res->irq; + hal->firmware_base = res->firmware_base; + hal->register_base = devm_ioremap_nocache(&res->pdev->dev, + res->register_base, res->register_size); + hal->register_size = res->register_size; + if (!hal->register_base) { + dprintk(VIDC_ERR, + "could not map reg addr %pa of size %d\n", + &res->register_base, res->register_size); + goto error_irq_fail; + } + + device->hal_data = hal; + rc = request_irq(res->irq, venus_hfi_isr, IRQF_TRIGGER_HIGH, + "msm_vidc", device); + if (unlikely(rc)) { + dprintk(VIDC_ERR, "() :request_irq failed\n"); + goto error_irq_fail; + } + + disable_irq_nosync(res->irq); + dprintk(VIDC_INFO, + "firmware_base = %pa, register_base = %pa, register_size = %d\n", + &res->firmware_base, &res->register_base, + res->register_size); + + return rc; + +error_irq_fail: + kfree(hal); +err_core_init: + return rc; + +} + +static inline void __deinit_clocks(struct venus_hfi_device *device) +{ + struct clock_info *cl; + + device->clk_freq = 0; + venus_hfi_for_each_clock_reverse(device, cl) { + if (cl->clk) { + clk_put(cl->clk); + cl->clk = NULL; + } + } +} + +static inline int __init_clocks(struct venus_hfi_device *device) +{ + int rc = 0; + struct clock_info *cl = NULL; + + if (!device) { + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); + return -EINVAL; + } + + venus_hfi_for_each_clock(device, cl) { + + dprintk(VIDC_DBG, "%s: scalable? %d, count %d\n", + cl->name, cl->has_scaling, cl->count); + } + + venus_hfi_for_each_clock(device, cl) { + if (!cl->clk) { + cl->clk = clk_get(&device->res->pdev->dev, cl->name); + if (IS_ERR_OR_NULL(cl->clk)) { + dprintk(VIDC_ERR, + "Failed to get clock: %s\n", cl->name); + rc = PTR_ERR(cl->clk) ? + PTR_ERR(cl->clk) : -EINVAL; + cl->clk = NULL; + goto err_clk_get; + } + } + } + device->clk_freq = 0; + return 0; + +err_clk_get: + __deinit_clocks(device); + return rc; +} + +static int __handle_reset_clk(struct msm_vidc_platform_resources *res, + int reset_index, enum reset_state state) +{ + int rc = 0; + struct reset_control *rst; + struct reset_set *rst_set = &res->reset_set; + + if (!rst_set->reset_tbl) + return 0; + + rst = rst_set->reset_tbl[reset_index].rst; + dprintk(VIDC_DBG, "reset_clk: name %s reset_state %d rst %pK\n", + rst_set->reset_tbl[reset_index].name, state, rst); + + switch (state) { + case INIT: + if (rst) + goto skip_reset_init; + + rst = devm_reset_control_get(&res->pdev->dev, + rst_set->reset_tbl[reset_index].name); + if (IS_ERR(rst)) + rc = PTR_ERR(rst); + + rst_set->reset_tbl[reset_index].rst = rst; + break; + case ASSERT: + if (!rst) { + rc = PTR_ERR(rst); + goto failed_to_reset; + } + + rc = reset_control_assert(rst); + break; + case DEASSERT: + if (!rst) { + rc = PTR_ERR(rst); + goto failed_to_reset; + } + rc = reset_control_deassert(rst); + break; + default: + dprintk(VIDC_ERR, "Invalid reset request\n"); + if (rc) + goto failed_to_reset; + } + + return 0; + +skip_reset_init: +failed_to_reset: + return rc; +} + +static inline void __disable_unprepare_clks(struct venus_hfi_device *device) +{ + struct clock_info *cl; + int rc = 0; + + if (!device) { + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); + return; + } + + venus_hfi_for_each_clock_reverse(device, cl) { + dprintk(VIDC_DBG, "Clock: %s disable and unprepare\n", + cl->name); + rc = clk_set_flags(cl->clk, CLKFLAG_NORETAIN_PERIPH); + if (rc) { + dprintk(VIDC_WARN, + "Failed set flag NORETAIN_PERIPH %s\n", + cl->name); + } + rc = clk_set_flags(cl->clk, CLKFLAG_NORETAIN_MEM); + if (rc) { + dprintk(VIDC_WARN, + "Failed set flag NORETAIN_MEM %s\n", + cl->name); + } + clk_disable_unprepare(cl->clk); + } +} + +static int reset_ahb2axi_bridge(struct venus_hfi_device *device) +{ + int rc, i; + + if (!device) { + dprintk(VIDC_ERR, "NULL device\n"); + rc = -EINVAL; + goto failed_to_reset; + } + + for (i = 0; i < device->res->reset_set.count; i++) { + rc = __handle_reset_clk(device->res, i, ASSERT); + if (rc) { + dprintk(VIDC_ERR, + "failed to assert reset clocks\n"); + goto failed_to_reset; + } + + /* wait for deassert */ + usleep_range(150, 250); + + rc = __handle_reset_clk(device->res, i, DEASSERT); + if (rc) { + dprintk(VIDC_ERR, + "failed to deassert reset clocks\n"); + goto failed_to_reset; + } + } + + return 0; + +failed_to_reset: + return rc; +} + +static inline int __prepare_enable_clks(struct venus_hfi_device *device) +{ + struct clock_info *cl = NULL, *cl_fail = NULL; + int rc = 0, c = 0; + + if (!device) { + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); + return -EINVAL; + } + + venus_hfi_for_each_clock(device, cl) { + /* + * For the clocks we control, set the rate prior to preparing + * them. Since we don't really have a load at this point, scale + * it to the lowest frequency possible + */ + if (cl->has_scaling) + clk_set_rate(cl->clk, clk_round_rate(cl->clk, 0)); + + rc = clk_set_flags(cl->clk, CLKFLAG_RETAIN_PERIPH); + if (rc) { + dprintk(VIDC_WARN, + "Failed set flag RETAIN_PERIPH %s\n", + cl->name); + } + rc = clk_set_flags(cl->clk, CLKFLAG_RETAIN_MEM); + if (rc) { + dprintk(VIDC_WARN, + "Failed set flag RETAIN_MEM %s\n", + cl->name); + } + rc = clk_prepare_enable(cl->clk); + if (rc) { + dprintk(VIDC_ERR, "Failed to enable clocks\n"); + cl_fail = cl; + goto fail_clk_enable; + } + + c++; + dprintk(VIDC_DBG, "Clock: %s prepared and enabled\n", cl->name); + } + + call_venus_op(device, clock_config_on_enable, device); + return rc; + +fail_clk_enable: + venus_hfi_for_each_clock_reverse_continue(device, cl, c) { + dprintk(VIDC_ERR, "Clock: %s disable and unprepare\n", + cl->name); + clk_disable_unprepare(cl->clk); + } + + return rc; +} + +static void __deinit_bus(struct venus_hfi_device *device) +{ + struct bus_info *bus = NULL; + + if (!device) + return; + + kfree(device->bus_vote.data); + device->bus_vote = DEFAULT_BUS_VOTE; + + venus_hfi_for_each_bus_reverse(device, bus) { + msm_bus_scale_unregister(bus->client); + bus->client = NULL; + } +} + +static int __init_bus(struct venus_hfi_device *device) +{ + struct bus_info *bus = NULL; + int rc = 0; + + if (!device) + return -EINVAL; + + venus_hfi_for_each_bus(device, bus) { + if (!strcmp(bus->mode, "msm-vidc-llcc")) { + if (msm_vidc_syscache_disable) { + dprintk(VIDC_DBG, + "Skipping LLC bus init %s: %s\n", + bus->name, bus->mode); + continue; + } + } + bus->client = msm_bus_scale_register(bus->master, bus->slave, + bus->name, false); + if (IS_ERR_OR_NULL(bus->client)) { + rc = PTR_ERR(bus->client) ? + PTR_ERR(bus->client) : -EBADHANDLE; + dprintk(VIDC_ERR, "Failed to register bus %s: %d\n", + bus->name, rc); + bus->client = NULL; + goto err_add_dev; + } + } + + if (device->res->vpu_ver == VPU_VERSION_IRIS1) + device->bus_vote.calc_bw = calc_bw_iris1; + else + device->bus_vote.calc_bw = calc_bw_iris2; + + return 0; + +err_add_dev: + __deinit_bus(device); + return rc; +} + +static void __deinit_regulators(struct venus_hfi_device *device) +{ + struct regulator_info *rinfo = NULL; + + venus_hfi_for_each_regulator_reverse(device, rinfo) { + if (rinfo->regulator) { + regulator_put(rinfo->regulator); + rinfo->regulator = NULL; + } + } +} + +static int __init_regulators(struct venus_hfi_device *device) +{ + int rc = 0; + struct regulator_info *rinfo = NULL; + + venus_hfi_for_each_regulator(device, rinfo) { + rinfo->regulator = regulator_get(&device->res->pdev->dev, + rinfo->name); + if (IS_ERR_OR_NULL(rinfo->regulator)) { + rc = PTR_ERR(rinfo->regulator) ? + PTR_ERR(rinfo->regulator) : -EBADHANDLE; + dprintk(VIDC_ERR, "Failed to get regulator: %s\n", + rinfo->name); + rinfo->regulator = NULL; + goto err_reg_get; + } + } + + return 0; + +err_reg_get: + __deinit_regulators(device); + return rc; +} + +static void __deinit_subcaches(struct venus_hfi_device *device) +{ + struct subcache_info *sinfo = NULL; + + if (!device) { + dprintk(VIDC_ERR, "deinit_subcaches: invalid device %pK\n", + device); + goto exit; + } + + if (!is_sys_cache_present(device)) + goto exit; + + venus_hfi_for_each_subcache_reverse(device, sinfo) { + if (sinfo->subcache) { + dprintk(VIDC_DBG, "deinit_subcaches: %s\n", + sinfo->name); + llcc_slice_putd(sinfo->subcache); + sinfo->subcache = NULL; + } + } + +exit: + return; +} + +static int __init_subcaches(struct venus_hfi_device *device) +{ + int rc = 0; + struct subcache_info *sinfo = NULL; + + if (!device) { + dprintk(VIDC_ERR, "init_subcaches: invalid device %pK\n", + device); + return -EINVAL; + } + + if (!is_sys_cache_present(device)) + return 0; + + venus_hfi_for_each_subcache(device, sinfo) { + if (!strcmp("vidsc0", sinfo->name)) { + sinfo->subcache = llcc_slice_getd(LLCC_VIDSC0); + } else if (!strcmp("vidsc1", sinfo->name)) { + sinfo->subcache = llcc_slice_getd(LLCC_VIDSC1); + } else if (!strcmp("vidscfw", sinfo->name)) { + sinfo->subcache = llcc_slice_getd(LLCC_VIDFW); + } else { + dprintk(VIDC_ERR, "Invalid subcache name %s\n", + sinfo->name); + } + if (IS_ERR_OR_NULL(sinfo->subcache)) { + rc = PTR_ERR(sinfo->subcache) ? + PTR_ERR(sinfo->subcache) : -EBADHANDLE; + dprintk(VIDC_ERR, + "init_subcaches: invalid subcache: %s rc %d\n", + sinfo->name, rc); + sinfo->subcache = NULL; + goto err_subcache_get; + } + dprintk(VIDC_DBG, "init_subcaches: %s\n", + sinfo->name); + } + + return 0; + +err_subcache_get: + __deinit_subcaches(device); + return rc; +} + +static int __init_resources(struct venus_hfi_device *device, + struct msm_vidc_platform_resources *res) +{ + int i, rc = 0; + + rc = __init_regulators(device); + if (rc) { + dprintk(VIDC_ERR, "Failed to get all regulators\n"); + return -ENODEV; + } + + rc = __init_clocks(device); + if (rc) { + dprintk(VIDC_ERR, "Failed to init clocks\n"); + rc = -ENODEV; + goto err_init_clocks; + } + + for (i = 0; i < device->res->reset_set.count; i++) { + rc = __handle_reset_clk(res, i, INIT); + if (rc) { + dprintk(VIDC_ERR, "Failed to init reset clocks\n"); + rc = -ENODEV; + goto err_init_reset_clk; + } + } + + rc = __init_bus(device); + if (rc) { + dprintk(VIDC_ERR, "Failed to init bus: %d\n", rc); + goto err_init_bus; + } + + rc = __init_subcaches(device); + if (rc) + dprintk(VIDC_WARN, "Failed to init subcaches: %d\n", rc); + + return rc; + +err_init_reset_clk: +err_init_bus: + __deinit_clocks(device); +err_init_clocks: + __deinit_regulators(device); + return rc; +} + +static void __deinit_resources(struct venus_hfi_device *device) +{ + __deinit_subcaches(device); + __deinit_bus(device); + __deinit_clocks(device); + __deinit_regulators(device); +} + +static int __protect_cp_mem(struct venus_hfi_device *device) +{ + struct tzbsp_memprot memprot; + unsigned int resp = 0; + int rc = 0; + struct context_bank_info *cb; + struct scm_desc desc = {0}; + + if (!device) + return -EINVAL; + + memprot.cp_start = 0x0; + memprot.cp_size = 0x0; + memprot.cp_nonpixel_start = 0x0; + memprot.cp_nonpixel_size = 0x0; + + list_for_each_entry(cb, &device->res->context_banks, list) { + if (!strcmp(cb->name, "venus_ns")) { + desc.args[1] = memprot.cp_size = + cb->addr_range.start; + dprintk(VIDC_DBG, "%s memprot.cp_size: %#x\n", + __func__, memprot.cp_size); + } + + if (!strcmp(cb->name, "venus_sec_non_pixel")) { + desc.args[2] = memprot.cp_nonpixel_start = + cb->addr_range.start; + desc.args[3] = memprot.cp_nonpixel_size = + cb->addr_range.size; + dprintk(VIDC_DBG, + "%s memprot.cp_nonpixel_start: %#x size: %#x\n", + __func__, memprot.cp_nonpixel_start, + memprot.cp_nonpixel_size); + } + } + + desc.arginfo = SCM_ARGS(4); + rc = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, + TZBSP_MEM_PROTECT_VIDEO_VAR), &desc); + resp = desc.ret[0]; + + if (rc) { + dprintk(VIDC_ERR, "Failed to protect memory(%d) response: %d\n", + rc, resp); + } + + trace_venus_hfi_var_done( + memprot.cp_start, memprot.cp_size, + memprot.cp_nonpixel_start, memprot.cp_nonpixel_size); + return rc; +} + +static int __disable_regulator(struct regulator_info *rinfo, + struct venus_hfi_device *device) +{ + int rc = 0; + + dprintk(VIDC_DBG, "Disabling regulator %s\n", rinfo->name); + + /* + * This call is needed. Driver needs to acquire the control back + * from HW in order to disable the regualtor. Else the behavior + * is unknown. + */ + + rc = __acquire_regulator(rinfo, device); + if (rc) { + /* + * This is somewhat fatal, but nothing we can do + * about it. We can't disable the regulator w/o + * getting it back under s/w control + */ + dprintk(VIDC_WARN, + "Failed to acquire control on %s\n", + rinfo->name); + + goto disable_regulator_failed; + } + + rc = regulator_disable(rinfo->regulator); + if (rc) { + dprintk(VIDC_WARN, + "Failed to disable %s: %d\n", + rinfo->name, rc); + goto disable_regulator_failed; + } + + return 0; +disable_regulator_failed: + + /* Bring attention to this issue */ + msm_vidc_res_handle_fatal_hw_error(device->res, true); + return rc; +} + +static int __enable_hw_power_collapse(struct venus_hfi_device *device) +{ + int rc = 0; + + rc = __hand_off_regulators(device); + if (rc) + dprintk(VIDC_WARN, + "%s : Failed to enable HW power collapse %d\n", + __func__, rc); + return rc; +} + +static int __enable_regulators(struct venus_hfi_device *device) +{ + int rc = 0, c = 0; + struct regulator_info *rinfo; + + dprintk(VIDC_DBG, "Enabling regulators\n"); + + venus_hfi_for_each_regulator(device, rinfo) { + rc = regulator_enable(rinfo->regulator); + if (rc) { + dprintk(VIDC_ERR, + "Failed to enable %s: %d\n", + rinfo->name, rc); + goto err_reg_enable_failed; + } + + dprintk(VIDC_DBG, "Enabled regulator %s\n", + rinfo->name); + c++; + } + + return 0; + +err_reg_enable_failed: + venus_hfi_for_each_regulator_reverse_continue(device, rinfo, c) + __disable_regulator(rinfo, device); + + return rc; +} + +static int __disable_regulators(struct venus_hfi_device *device) +{ + struct regulator_info *rinfo; + + dprintk(VIDC_DBG, "Disabling regulators\n"); + + venus_hfi_for_each_regulator_reverse(device, rinfo) + __disable_regulator(rinfo, device); + + return 0; +} + +static int __enable_subcaches(struct venus_hfi_device *device) +{ + int rc = 0; + u32 c = 0; + struct subcache_info *sinfo; + + if (msm_vidc_syscache_disable || !is_sys_cache_present(device)) + return 0; + + /* Activate subcaches */ + venus_hfi_for_each_subcache(device, sinfo) { + rc = llcc_slice_activate(sinfo->subcache); + if (rc) { + dprintk(VIDC_WARN, "Failed to activate %s: %d\n", + sinfo->name, rc); + msm_vidc_res_handle_fatal_hw_error(device->res, true); + goto err_activate_fail; + } + sinfo->isactive = true; + dprintk(VIDC_DBG, "Activated subcache %s\n", sinfo->name); + c++; + } + + dprintk(VIDC_DBG, "Activated %d Subcaches to Venus\n", c); + + return 0; + +err_activate_fail: + __release_subcaches(device); + __disable_subcaches(device); + return 0; +} + +static int __set_subcaches(struct venus_hfi_device *device) +{ + int rc = 0; + u32 c = 0; + struct subcache_info *sinfo; + u32 resource[VIDC_MAX_SUBCACHE_SIZE]; + struct hfi_resource_syscache_info_type *sc_res_info; + struct hfi_resource_subcache_type *sc_res; + struct vidc_resource_hdr rhdr; + + if (device->res->sys_cache_res_set) { + dprintk(VIDC_DBG, "Subcaches already set to Venus\n"); + return 0; + } + + memset((void *)resource, 0x0, (sizeof(u32) * VIDC_MAX_SUBCACHE_SIZE)); + + sc_res_info = (struct hfi_resource_syscache_info_type *)resource; + sc_res = &(sc_res_info->rg_subcache_entries[0]); + + venus_hfi_for_each_subcache(device, sinfo) { + if (sinfo->isactive) { + sc_res[c].size = sinfo->subcache->slice_size; + sc_res[c].sc_id = sinfo->subcache->slice_id; + c++; + } + } + + /* Set resource to Venus for activated subcaches */ + if (c) { + dprintk(VIDC_DBG, "Setting %d Subcaches\n", c); + + rhdr.resource_handle = sc_res_info; /* cookie */ + rhdr.resource_id = VIDC_RESOURCE_SYSCACHE; + + sc_res_info->num_entries = c; + + rc = __core_set_resource(device, &rhdr, (void *)sc_res_info); + if (rc) { + dprintk(VIDC_WARN, "Failed to set subcaches %d\n", rc); + goto err_fail_set_subacaches; + } + + venus_hfi_for_each_subcache(device, sinfo) { + if (sinfo->isactive) + sinfo->isset = true; + } + + dprintk(VIDC_DBG, "Set Subcaches done to Venus\n"); + device->res->sys_cache_res_set = true; + } + + return 0; + +err_fail_set_subacaches: + __disable_subcaches(device); + + return 0; +} + +static int __release_subcaches(struct venus_hfi_device *device) +{ + struct subcache_info *sinfo; + int rc = 0; + u32 c = 0; + u32 resource[VIDC_MAX_SUBCACHE_SIZE]; + struct hfi_resource_syscache_info_type *sc_res_info; + struct hfi_resource_subcache_type *sc_res; + struct vidc_resource_hdr rhdr; + + if (msm_vidc_syscache_disable || !is_sys_cache_present(device)) + return 0; + + memset((void *)resource, 0x0, (sizeof(u32) * VIDC_MAX_SUBCACHE_SIZE)); + + sc_res_info = (struct hfi_resource_syscache_info_type *)resource; + sc_res = &(sc_res_info->rg_subcache_entries[0]); + + /* Release resource command to Venus */ + venus_hfi_for_each_subcache_reverse(device, sinfo) { + if (sinfo->isset) { + /* Update the entry */ + sc_res[c].size = sinfo->subcache->slice_size; + sc_res[c].sc_id = sinfo->subcache->slice_id; + c++; + sinfo->isset = false; + } + } + + if (c > 0) { + dprintk(VIDC_DBG, "Releasing %d subcaches\n", c); + rhdr.resource_handle = sc_res_info; /* cookie */ + rhdr.resource_id = VIDC_RESOURCE_SYSCACHE; + + rc = __core_release_resource(device, &rhdr); + if (rc) + dprintk(VIDC_WARN, + "Failed to release %d subcaches\n", c); + } + + device->res->sys_cache_res_set = false; + + return 0; +} + +static int __disable_subcaches(struct venus_hfi_device *device) +{ + struct subcache_info *sinfo; + int rc = 0; + + if (msm_vidc_syscache_disable || !is_sys_cache_present(device)) + return 0; + + /* De-activate subcaches */ + venus_hfi_for_each_subcache_reverse(device, sinfo) { + if (sinfo->isactive) { + dprintk(VIDC_DBG, "De-activate subcache %s\n", + sinfo->name); + rc = llcc_slice_deactivate(sinfo->subcache); + if (rc) { + dprintk(VIDC_WARN, + "Failed to de-activate %s: %d\n", + sinfo->name, rc); + } + sinfo->isactive = false; + } + } + + return 0; +} + +static void interrupt_init_iris1(struct venus_hfi_device *device) +{ + u32 mask_val = 0; + + /* All interrupts should be disabled initially 0x1F6 : Reset value */ + mask_val = __read_register(device, VIDC_WRAPPER_INTR_MASK); + + /* Write 0 to unmask CPU and WD interrupts */ + mask_val &= ~(VIDC_WRAPPER_INTR_MASK_A2HWD_BMSK | + VIDC_WRAPPER_INTR_MASK_A2HCPU_BMSK); + __write_register(device, VIDC_WRAPPER_INTR_MASK, mask_val); +} + +static void interrupt_init_vpu4(struct venus_hfi_device *device) +{ + __write_register(device, VIDC_WRAPPER_INTR_MASK, + VIDC_WRAPPER_INTR_MASK_A2HVCODEC_BMSK); +} + +static void setup_dsp_uc_memmap_iris1(struct venus_hfi_device *device) +{ + /* initialize DSP QTBL & UCREGION with CPU queues */ + __write_register(device, HFI_DSP_QTBL_ADDR, + (u32)device->iface_q_table.align_device_addr); + __write_register(device, HFI_DSP_UC_REGION_ADDR, + (u32)device->iface_q_table.align_device_addr); + __write_register(device, HFI_DSP_UC_REGION_SIZE, SHARED_QSIZE); + if (device->res->domain_cvp) { + __write_register(device, HFI_DSP_QTBL_ADDR, + (u32)device->dsp_iface_q_table.align_device_addr); + __write_register(device, HFI_DSP_UC_REGION_ADDR, + (u32)device->dsp_iface_q_table.align_device_addr); + __write_register(device, HFI_DSP_UC_REGION_SIZE, + device->dsp_iface_q_table.mem_data.size); + } +} + +static void clock_config_on_enable_iris1(struct venus_hfi_device *device) +{ + __write_register(device, VIDC_WRAPPER_CPU_CGC_DIS, 0); + __write_register(device, VIDC_WRAPPER_CPU_CLOCK_CONFIG, 0); +} + + +static int __set_ubwc_config(struct venus_hfi_device *device) +{ + u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE]; + int rc = 0; + + struct hfi_cmd_sys_set_property_packet *pkt = + (struct hfi_cmd_sys_set_property_packet *) &packet; + + if (!device->res->ubwc_config) + return 0; + + rc = call_hfi_pkt_op(device, sys_ubwc_config, pkt, + device->res->ubwc_config); + if (rc) { + dprintk(VIDC_WARN, + "ubwc config setting to FW failed\n"); + rc = -ENOTEMPTY; + goto fail_to_set_ubwc_config; + } + + if (__iface_cmdq_write(device, pkt)) { + rc = -ENOTEMPTY; + goto fail_to_set_ubwc_config; + } + + dprintk(VIDC_DBG, + "Configured UBWC Config to Venus\n"); + +fail_to_set_ubwc_config: + return rc; +} + +static int __venus_power_on(struct venus_hfi_device *device) +{ + int rc = 0; + + + if (device->power_enabled) + return 0; + + device->power_enabled = true; + /* Vote for all hardware resources */ + rc = __vote_buses(device, device->bus_vote.data, + device->bus_vote.data_count); + if (rc) { + dprintk(VIDC_ERR, "Failed to vote buses, err: %d\n", rc); + goto fail_vote_buses; + } + + rc = __enable_regulators(device); + if (rc) { + dprintk(VIDC_ERR, "Failed to enable GDSC, err = %d\n", rc); + goto fail_enable_gdsc; + } + + rc = call_venus_op(device, reset_ahb2axi_bridge, device); + if (rc) { + dprintk(VIDC_ERR, "Failed to reset ahb2axi: %d\n", rc); + goto fail_enable_clks; + } + + rc = __prepare_enable_clks(device); + if (rc) { + dprintk(VIDC_ERR, "Failed to enable clocks: %d\n", rc); + goto fail_enable_clks; + } + + rc = __scale_clocks(device); + if (rc) { + dprintk(VIDC_WARN, + "Failed to scale clocks, performance might be affected\n"); + rc = 0; + } + + /* + * Re-program all of the registers that get reset as a result of + * regulator_disable() and _enable() + */ + __set_registers(device); + + call_venus_op(device, interrupt_init, device); + device->intr_status = 0; + enable_irq(device->hal_data->irq); + + /* + * Hand off control of regulators to h/w _after_ enabling clocks. + * Note that the GDSC will turn off when switching from normal + * (s/w triggered) to fast (HW triggered) unless the h/w vote is + * present. Since Venus isn't up yet, the GDSC will be off briefly. + */ + if (__enable_hw_power_collapse(device)) + dprintk(VIDC_ERR, "Failed to enabled inter-frame PC\n"); + + return rc; + +fail_enable_clks: + __disable_regulators(device); +fail_enable_gdsc: + __unvote_buses(device); +fail_vote_buses: + device->power_enabled = false; + return rc; +} + +static void power_off_common(struct venus_hfi_device *device) +{ + if (!device->power_enabled) + return; + + if (!(device->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK)) + disable_irq_nosync(device->hal_data->irq); + device->intr_status = 0; + + __disable_unprepare_clks(device); + if (call_venus_op(device, reset_ahb2axi_bridge, device)) + dprintk(VIDC_ERR, "Failed to reset ahb2axi\n"); + + if (__disable_regulators(device)) + dprintk(VIDC_WARN, "Failed to disable regulators\n"); + + if (__unvote_buses(device)) + dprintk(VIDC_WARN, "Failed to unvote for buses\n"); + device->power_enabled = false; +} + +static void power_off_iris2(struct venus_hfi_device *device) +{ + u32 lpi_status, reg_status = 0, count = 0, max_count = 10; + + if (!device->power_enabled) + return; + + if (!(device->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK)) + disable_irq_nosync(device->hal_data->irq); + device->intr_status = 0; + + /* HPG 6.1.2 Step 1 */ + __write_register(device, VIDC_CPU_CS_X2RPMh, 0x3); + + /* HPG 6.1.2 Step 2, noc to low power */ + __write_register(device, VIDC_AON_WRAPPER_MVP_NOC_LPI_CONTROL, 0x1); + while (!reg_status && count < max_count) { + lpi_status = + __read_register(device, + VIDC_AON_WRAPPER_MVP_NOC_LPI_STATUS); + reg_status = lpi_status & BIT(0); + dprintk(VIDC_DBG, + "Noc: lpi_status %d noc_status %d (count %d)\n", + lpi_status, reg_status, count); + usleep_range(50, 100); + count++; + } + if (count == max_count) { + dprintk(VIDC_ERR, + "NOC not in qaccept status %d\n", reg_status); + } + + /* HPG 6.1.2 Step 3, debug bridge to low power */ + __write_register(device, + VIDC_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL, 0x7); + reg_status = 0; + count = 0; + while ((reg_status != 0x7) && count < max_count) { + lpi_status = __read_register(device, + VIDC_WRAPPER_DEBUG_BRIDGE_LPI_STATUS); + reg_status = lpi_status & 0x7; + dprintk(VIDC_DBG, + "DBLP Set : lpi_status %d reg_status %d (count %d)\n", + lpi_status, reg_status, count); + usleep_range(50, 100); + count++; + } + if (count == max_count) { + dprintk(VIDC_ERR, + "DBLP Set: status %d\n", reg_status); + } + + /* HPG 6.1.2 Step 4, debug bridge to lpi release */ + __write_register(device, + VIDC_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL, 0x0); + lpi_status = 0x1; + count = 0; + while (lpi_status && count < max_count) { + lpi_status = __read_register(device, + VIDC_WRAPPER_DEBUG_BRIDGE_LPI_STATUS); + dprintk(VIDC_DBG, + "DBLP Release: lpi_status %d(count %d)\n", + lpi_status, count); + usleep_range(50, 100); + count++; + } + if (count == max_count) { + dprintk(VIDC_ERR, + "DBLP Release: lpi_status %d\n", lpi_status); + } + + /* HPG 6.1.2 Step 6 */ + __disable_unprepare_clks(device); + + /* HPG 6.1.2 Step 7 & 8 */ + if (call_venus_op(device, reset_ahb2axi_bridge, device)) + dprintk(VIDC_ERR, "Failed to reset ahb2axi\n"); + + /* HPG 6.1.2 Step 5 */ + if (__disable_regulators(device)) + dprintk(VIDC_WARN, "Failed to disable regulators\n"); + + if (__unvote_buses(device)) + dprintk(VIDC_WARN, "Failed to unvote for buses\n"); + device->power_enabled = false; +} + +static inline int __suspend(struct venus_hfi_device *device) +{ + int rc = 0; + + if (!device) { + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); + return -EINVAL; + } else if (!device->power_enabled) { + dprintk(VIDC_DBG, "Power already disabled\n"); + return 0; + } + + dprintk(VIDC_PROF, "Entering suspend\n"); + + if (device->res->pm_qos_latency_us && + pm_qos_request_active(&device->qos)) + pm_qos_remove_request(&device->qos); + + rc = __tzbsp_set_video_state(TZBSP_VIDEO_STATE_SUSPEND); + if (rc) { + dprintk(VIDC_WARN, "Failed to suspend video core %d\n", rc); + goto err_tzbsp_suspend; + } + + __disable_subcaches(device); + + call_venus_op(device, power_off, device); + dprintk(VIDC_PROF, "Venus power off\n"); + return rc; + +err_tzbsp_suspend: + return rc; +} + +static inline int __resume(struct venus_hfi_device *device) +{ + int rc = 0; + u32 flags = 0; + + if (!device) { + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); + return -EINVAL; + } else if (device->power_enabled) { + goto exit; + } else if (!__core_in_valid_state(device)) { + dprintk(VIDC_DBG, "venus_hfi_device in deinit state."); + return -EINVAL; + } + + dprintk(VIDC_PROF, "Resuming from power collapse\n"); + rc = __venus_power_on(device); + if (rc) { + dprintk(VIDC_ERR, "Failed to power on venus\n"); + goto err_venus_power_on; + } + + /* Reboot the firmware */ + rc = __tzbsp_set_video_state(TZBSP_VIDEO_STATE_RESUME); + if (rc) { + dprintk(VIDC_ERR, "Failed to resume video core %d\n", rc); + goto err_set_video_state; + } + + __setup_ucregion_memory_map(device); + /* Wait for boot completion */ + rc = __boot_firmware(device); + if (rc) { + dprintk(VIDC_ERR, "Failed to reset venus core\n"); + goto err_reset_core; + } + + /* + * Work around for H/W bug, need to reprogram these registers once + * firmware is out reset + */ + __set_threshold_registers(device); + + if (device->res->pm_qos_latency_us) { +#ifdef CONFIG_SMP + device->qos.type = PM_QOS_REQ_AFFINE_IRQ; + device->qos.irq = device->hal_data->irq; +#endif + pm_qos_add_request(&device->qos, PM_QOS_CPU_DMA_LATENCY, + device->res->pm_qos_latency_us); + } + + __sys_set_debug(device, msm_vidc_fw_debug); + + __enable_subcaches(device); + __set_subcaches(device); + __dsp_resume(device, flags); + + dprintk(VIDC_PROF, "Resumed from power collapse\n"); +exit: + /* Don't reset skip_pc_count for SYS_PC_PREP cmd */ + if (device->last_packet_type != HFI_CMD_SYS_PC_PREP) + device->skip_pc_count = 0; + return rc; +err_reset_core: + __tzbsp_set_video_state(TZBSP_VIDEO_STATE_SUSPEND); +err_set_video_state: + call_venus_op(device, power_off, device); +err_venus_power_on: + dprintk(VIDC_ERR, "Failed to resume from power collapse\n"); + return rc; +} + +static int __load_fw(struct venus_hfi_device *device) +{ + int rc = 0; + + /* Initialize resources */ + rc = __init_resources(device, device->res); + if (rc) { + dprintk(VIDC_ERR, "Failed to init resources: %d\n", rc); + goto fail_init_res; + } + + rc = __initialize_packetization(device); + if (rc) { + dprintk(VIDC_ERR, "Failed to initialize packetization\n"); + goto fail_init_pkt; + } + trace_msm_v4l2_vidc_fw_load_start("msm_v4l2_vidc venus_fw load start"); + + rc = __venus_power_on(device); + if (rc) { + dprintk(VIDC_ERR, "Failed to power on venus in in load_fw\n"); + goto fail_venus_power_on; + } + + if (!device->res->firmware_base) { + if (!device->resources.fw.cookie) + device->resources.fw.cookie = + subsystem_get_with_fwname("venus", + device->res->fw_name); + + if (IS_ERR_OR_NULL(device->resources.fw.cookie)) { + dprintk(VIDC_ERR, "Failed to download firmware\n"); + device->resources.fw.cookie = NULL; + rc = -ENOMEM; + goto fail_load_fw; + } + } else { + dprintk(VIDC_ERR, "Firmware base must be 0\n"); + } + + if (!device->res->firmware_base) { + rc = __protect_cp_mem(device); + if (rc) { + dprintk(VIDC_ERR, "Failed to protect memory\n"); + goto fail_protect_mem; + } + } + trace_msm_v4l2_vidc_fw_load_end("msm_v4l2_vidc venus_fw load end"); + return rc; +fail_protect_mem: + if (device->resources.fw.cookie) + subsystem_put(device->resources.fw.cookie); + device->resources.fw.cookie = NULL; +fail_load_fw: + call_venus_op(device, power_off, device); +fail_venus_power_on: +fail_init_pkt: + __deinit_resources(device); +fail_init_res: + trace_msm_v4l2_vidc_fw_load_end("msm_v4l2_vidc venus_fw load end"); + return rc; +} + +static void __unload_fw(struct venus_hfi_device *device) +{ + if (!device->resources.fw.cookie) + return; + + cancel_delayed_work(&venus_hfi_pm_work); + if (device->state != VENUS_STATE_DEINIT) + flush_workqueue(device->venus_pm_workq); + + __vote_buses(device, NULL, 0); + subsystem_put(device->resources.fw.cookie); + __interface_queues_release(device); + call_venus_op(device, power_off, device); + device->resources.fw.cookie = NULL; + __deinit_resources(device); + + dprintk(VIDC_PROF, "Firmware unloaded successfully\n"); +} + +static int venus_hfi_get_fw_info(void *dev, struct hal_fw_info *fw_info) +{ + int i = 0, j = 0; + struct venus_hfi_device *device = dev; + size_t smem_block_size = 0; + u8 *smem_table_ptr; + char version[VENUS_VERSION_LENGTH] = ""; + const u32 smem_image_index_venus = 14 * 128; + + if (!device || !fw_info) { + dprintk(VIDC_ERR, + "%s Invalid parameter: device = %pK fw_info = %pK\n", + __func__, device, fw_info); + return -EINVAL; + } + + mutex_lock(&device->lock); + + smem_table_ptr = qcom_smem_get(QCOM_SMEM_HOST_ANY, + SMEM_IMAGE_VERSION_TABLE, &smem_block_size); + if (smem_table_ptr && + ((smem_image_index_venus + + VENUS_VERSION_LENGTH) <= smem_block_size)) + memcpy(version, + smem_table_ptr + smem_image_index_venus, + VENUS_VERSION_LENGTH); + + while (version[i++] != 'V' && i < VENUS_VERSION_LENGTH) + ; + + if (i == VENUS_VERSION_LENGTH - 1) { + dprintk(VIDC_WARN, "Venus version string is not proper\n"); + fw_info->version[0] = '\0'; + goto fail_version_string; + } + + for (i--; i < VENUS_VERSION_LENGTH && j < VENUS_VERSION_LENGTH - 1; i++) + fw_info->version[j++] = version[i]; + fw_info->version[j] = '\0'; + +fail_version_string: + dprintk(VIDC_DBG, "F/W version retrieved : %s\n", fw_info->version); + fw_info->base_addr = device->hal_data->firmware_base; + fw_info->register_base = device->res->register_base; + fw_info->register_size = device->hal_data->register_size; + fw_info->irq = device->hal_data->irq; + + mutex_unlock(&device->lock); + return 0; +} + +static int venus_hfi_get_core_capabilities(void *dev) +{ + struct venus_hfi_device *device = dev; + int rc = 0; + + if (!device) + return -EINVAL; + + mutex_lock(&device->lock); + + rc = HAL_VIDEO_ENCODER_ROTATION_CAPABILITY | + HAL_VIDEO_ENCODER_SCALING_CAPABILITY | + HAL_VIDEO_ENCODER_DEINTERLACE_CAPABILITY | + HAL_VIDEO_DECODER_MULTI_STREAM_CAPABILITY; + + mutex_unlock(&device->lock); + + return rc; +} + +static void __noc_error_info(struct venus_hfi_device *device, u32 core_num) +{ + u32 vcodec_core_video_noc_base_offs, val; + + if (!device) { + dprintk(VIDC_ERR, "%s: null device\n", __func__); + return; + } + if (!core_num) { + vcodec_core_video_noc_base_offs = + VCODEC_CORE0_VIDEO_NOC_BASE_OFFS; + } else if (core_num == 1) { + vcodec_core_video_noc_base_offs = + VCODEC_CORE1_VIDEO_NOC_BASE_OFFS; + } else { + dprintk(VIDC_ERR, "%s: invalid core_num %u\n", + __func__, core_num); + return; + } + + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_SWID_LOW_OFFS); + dprintk(VIDC_ERR, "CORE%d_NOC_ERR_SWID_LOW: %#x\n", core_num, val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_SWID_HIGH_OFFS); + dprintk(VIDC_ERR, "CORE%d_NOC_ERR_SWID_HIGH: %#x\n", core_num, val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_MAINCTL_LOW_OFFS); + dprintk(VIDC_ERR, "CORE%d_NOC_ERR_MAINCTL_LOW: %#x\n", core_num, val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_LOW_OFFS); + dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG0_LOW: %#x\n", core_num, val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_HIGH_OFFS); + dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG0_HIGH: %#x\n", core_num, val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_LOW_OFFS); + dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG1_LOW: %#x\n", core_num, val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_HIGH_OFFS); + dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG1_HIGH: %#x\n", core_num, val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_LOW_OFFS); + dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG2_LOW: %#x\n", core_num, val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_HIGH_OFFS); + dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG2_HIGH: %#x\n", core_num, val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_LOW_OFFS); + dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG3_LOW: %#x\n", core_num, val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_HIGH_OFFS); + dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG3_HIGH: %#x\n", core_num, val); +} + +static void noc_error_info_common(struct venus_hfi_device *device) +{ + const u32 core0 = 0, core1 = 1; + + if (__read_register(device, VCODEC_CORE0_VIDEO_NOC_BASE_OFFS + + VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS)) + __noc_error_info(device, core0); + + if (__read_register(device, VCODEC_CORE1_VIDEO_NOC_BASE_OFFS + + VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS)) + __noc_error_info(device, core1); +} + +static void noc_error_info_iris2(struct venus_hfi_device *device) +{ + u32 val = 0; + + val = __read_register(device, VCODEC_NOC_ERL_MAIN_SWID_LOW); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_SWID_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_SWID_HIGH); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_SWID_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_MAINCTL_LOW); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_MAINCTL_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRVLD_LOW); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRVLD_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRCLR_LOW); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRCLR_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val); +} + +static int venus_hfi_noc_error_info(void *dev) +{ + struct venus_hfi_device *device; + + if (!dev) { + dprintk(VIDC_ERR, "%s: null device\n", __func__); + return -EINVAL; + } + device = dev; + + mutex_lock(&device->lock); + dprintk(VIDC_ERR, "%s: non error information\n", __func__); + + call_venus_op(device, noc_error_info, device); + + mutex_unlock(&device->lock); + + return 0; +} + +static int __initialize_packetization(struct venus_hfi_device *device) +{ + int rc = 0; + + if (!device || !device->res) { + dprintk(VIDC_ERR, "%s - invalid param\n", __func__); + return -EINVAL; + } + + device->packetization_type = HFI_PACKETIZATION_4XX; + + device->pkt_ops = hfi_get_pkt_ops_handle(device->packetization_type); + if (!device->pkt_ops) { + rc = -EINVAL; + dprintk(VIDC_ERR, "Failed to get pkt_ops handle\n"); + } + + return rc; +} + +void __init_venus_ops(struct venus_hfi_device *device) +{ + if (device->res->vpu_ver == VPU_VERSION_AR50) + device->vpu_ops = &vpu4_ops; + else if (device->res->vpu_ver == VPU_VERSION_IRIS1) + device->vpu_ops = &iris1_ops; + else + device->vpu_ops = &iris2_ops; +} + +static struct venus_hfi_device *__add_device(u32 device_id, + struct msm_vidc_platform_resources *res, + hfi_cmd_response_callback callback) +{ + struct venus_hfi_device *hdevice = NULL; + int rc = 0; + + if (!res || !callback) { + dprintk(VIDC_ERR, "Invalid Parameters\n"); + return NULL; + } + + dprintk(VIDC_INFO, "entered , device_id: %d\n", device_id); + + hdevice = kzalloc(sizeof(struct venus_hfi_device), GFP_KERNEL); + if (!hdevice) { + dprintk(VIDC_ERR, "failed to allocate new device\n"); + goto exit; + } + + hdevice->response_pkt = kmalloc_array(max_packets, + sizeof(*hdevice->response_pkt), GFP_KERNEL); + if (!hdevice->response_pkt) { + dprintk(VIDC_ERR, "failed to allocate response_pkt\n"); + goto err_cleanup; + } + + hdevice->raw_packet = + kzalloc(VIDC_IFACEQ_VAR_HUGE_PKT_SIZE, GFP_KERNEL); + if (!hdevice->raw_packet) { + dprintk(VIDC_ERR, "failed to allocate raw packet\n"); + goto err_cleanup; + } + + rc = __init_regs_and_interrupts(hdevice, res); + if (rc) + goto err_cleanup; + + hdevice->res = res; + hdevice->device_id = device_id; + hdevice->callback = (msm_vidc_callback) callback; + + __init_venus_ops(hdevice); + + hdevice->vidc_workq = create_singlethread_workqueue( + "msm_vidc_workerq_venus"); + if (!hdevice->vidc_workq) { + dprintk(VIDC_ERR, ": create vidc workq failed\n"); + goto err_cleanup; + } + + hdevice->venus_pm_workq = create_singlethread_workqueue( + "pm_workerq_venus"); + if (!hdevice->venus_pm_workq) { + dprintk(VIDC_ERR, ": create pm workq failed\n"); + goto err_cleanup; + } + + if (!hal_ctxt.dev_count) + INIT_LIST_HEAD(&hal_ctxt.dev_head); + + mutex_init(&hdevice->lock); + INIT_LIST_HEAD(&hdevice->list); + INIT_LIST_HEAD(&hdevice->sess_head); + list_add_tail(&hdevice->list, &hal_ctxt.dev_head); + hal_ctxt.dev_count++; + + return hdevice; + +err_cleanup: + if (hdevice->vidc_workq) + destroy_workqueue(hdevice->vidc_workq); + kfree(hdevice->response_pkt); + kfree(hdevice->raw_packet); + kfree(hdevice); +exit: + return NULL; +} + +static struct venus_hfi_device *__get_device(u32 device_id, + struct msm_vidc_platform_resources *res, + hfi_cmd_response_callback callback) +{ + if (!res || !callback) { + dprintk(VIDC_ERR, "Invalid params: %pK %pK\n", res, callback); + return NULL; + } + + return __add_device(device_id, res, callback); +} + +void venus_hfi_delete_device(void *device) +{ + struct venus_hfi_device *close, *tmp, *dev; + + if (!device) + return; + + dev = (struct venus_hfi_device *) device; + + list_for_each_entry_safe(close, tmp, &hal_ctxt.dev_head, list) { + if (close->hal_data->irq == dev->hal_data->irq) { + hal_ctxt.dev_count--; + list_del(&close->list); + mutex_destroy(&close->lock); + destroy_workqueue(close->vidc_workq); + destroy_workqueue(close->venus_pm_workq); + free_irq(dev->hal_data->irq, close); + iounmap(dev->hal_data->register_base); + kfree(close->hal_data); + kfree(close->response_pkt); + kfree(close->raw_packet); + kfree(close); + break; + } + } +} + +static void venus_init_hfi_callbacks(struct hfi_device *hdev) +{ + hdev->core_init = venus_hfi_core_init; + hdev->core_release = venus_hfi_core_release; + hdev->core_trigger_ssr = venus_hfi_core_trigger_ssr; + hdev->session_init = venus_hfi_session_init; + hdev->session_end = venus_hfi_session_end; + hdev->session_abort = venus_hfi_session_abort; + hdev->session_clean = venus_hfi_session_clean; + hdev->session_set_buffers = venus_hfi_session_set_buffers; + hdev->session_release_buffers = venus_hfi_session_release_buffers; + hdev->session_register_buffer = venus_hfi_session_register_buffer; + hdev->session_unregister_buffer = venus_hfi_session_unregister_buffer; + hdev->session_load_res = venus_hfi_session_load_res; + hdev->session_release_res = venus_hfi_session_release_res; + hdev->session_start = venus_hfi_session_start; + hdev->session_continue = venus_hfi_session_continue; + hdev->session_stop = venus_hfi_session_stop; + hdev->session_etb = venus_hfi_session_etb; + hdev->session_ftb = venus_hfi_session_ftb; + hdev->session_process_batch = venus_hfi_session_process_batch; + hdev->session_get_buf_req = venus_hfi_session_get_buf_req; + hdev->session_flush = venus_hfi_session_flush; + hdev->session_set_property = venus_hfi_session_set_property; + hdev->session_pause = venus_hfi_session_pause; + hdev->session_resume = venus_hfi_session_resume; + hdev->scale_clocks = venus_hfi_scale_clocks; + hdev->vote_bus = venus_hfi_vote_buses; + hdev->get_fw_info = venus_hfi_get_fw_info; + hdev->get_core_capabilities = venus_hfi_get_core_capabilities; + hdev->suspend = venus_hfi_suspend; + hdev->flush_debug_queue = venus_hfi_flush_debug_queue; + hdev->noc_error_info = venus_hfi_noc_error_info; + hdev->get_default_properties = venus_hfi_get_default_properties; +} + +int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id, + struct msm_vidc_platform_resources *res, + hfi_cmd_response_callback callback) +{ + int rc = 0; + + if (!hdev || !res || !callback) { + dprintk(VIDC_ERR, "Invalid params: %pK %pK %pK\n", + hdev, res, callback); + rc = -EINVAL; + goto err_venus_hfi_init; + } + + hdev->hfi_device_data = __get_device(device_id, res, callback); + + if (IS_ERR_OR_NULL(hdev->hfi_device_data)) { + rc = PTR_ERR(hdev->hfi_device_data) ? + PTR_ERR(hdev->hfi_device_data) : -EINVAL; + goto err_venus_hfi_init; + } + + venus_init_hfi_callbacks(hdev); + +err_venus_hfi_init: + return rc; +} diff --git a/msm/vidc/venus_hfi.h b/msm/vidc/venus_hfi.h new file mode 100644 index 000000000000..2bc1890c8a34 --- /dev/null +++ b/msm/vidc/venus_hfi.h @@ -0,0 +1,289 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef __H_VENUS_HFI_H__ +#define __H_VENUS_HFI_H__ + +#include +#include +#include +#include +#include +#include "vidc_hfi_api.h" +#include "vidc_hfi_helper.h" +#include "vidc_hfi_api.h" +#include "vidc_hfi.h" +#include "msm_vidc_resources.h" +#include "hfi_packetization.h" +#include "msm_vidc_bus.h" + +#define HFI_MASK_QHDR_TX_TYPE 0xFF000000 +#define HFI_MASK_QHDR_RX_TYPE 0x00FF0000 +#define HFI_MASK_QHDR_PRI_TYPE 0x0000FF00 +#define HFI_MASK_QHDR_Q_ID_TYPE 0x000000FF +#define HFI_Q_ID_HOST_TO_CTRL_CMD_Q 0x00 +#define HFI_Q_ID_CTRL_TO_HOST_MSG_Q 0x01 +#define HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q 0x02 +#define HFI_MASK_QHDR_STATUS 0x000000FF + +#define VIDC_MAX_UNCOMPRESSED_FMT_PLANES 3 + +#define VIDC_IFACEQ_NUMQ 3 +#define VIDC_IFACEQ_CMDQ_IDX 0 +#define VIDC_IFACEQ_MSGQ_IDX 1 +#define VIDC_IFACEQ_DBGQ_IDX 2 +#define VIDC_IFACEQ_MAX_BUF_COUNT 50 +#define VIDC_IFACE_MAX_PARALLEL_CLNTS 16 +#define VIDC_IFACEQ_DFLT_QHDR 0x01010000 + +#define VIDC_MAX_NAME_LENGTH 64 +#define VIDC_MAX_PC_SKIP_COUNT 10 +#define VIDC_MAX_SUBCACHES 4 +#define VIDC_MAX_SUBCACHE_SIZE 52 + +struct hfi_queue_table_header { + u32 qtbl_version; + u32 qtbl_size; + u32 qtbl_qhdr0_offset; + u32 qtbl_qhdr_size; + u32 qtbl_num_q; + u32 qtbl_num_active_q; + void *device_addr; + char name[256]; +}; + +struct hfi_queue_header { + u32 qhdr_status; + u32 qhdr_start_addr; + u32 qhdr_type; + u32 qhdr_q_size; + u32 qhdr_pkt_size; + u32 qhdr_pkt_drop_cnt; + u32 qhdr_rx_wm; + u32 qhdr_tx_wm; + u32 qhdr_rx_req; + u32 qhdr_tx_req; + u32 qhdr_rx_irq_status; + u32 qhdr_tx_irq_status; + u32 qhdr_read_idx; + u32 qhdr_write_idx; +}; + +struct hfi_mem_map_table { + u32 mem_map_num_entries; + u32 mem_map_table_base_addr; +}; + +struct hfi_mem_map { + u32 virtual_addr; + u32 physical_addr; + u32 size; + u32 attr; +}; + +#define VIDC_IFACEQ_TABLE_SIZE (sizeof(struct hfi_queue_table_header) \ + + sizeof(struct hfi_queue_header) * VIDC_IFACEQ_NUMQ) + +#define VIDC_IFACEQ_QUEUE_SIZE (VIDC_IFACEQ_MAX_PKT_SIZE * \ + VIDC_IFACEQ_MAX_BUF_COUNT * VIDC_IFACE_MAX_PARALLEL_CLNTS) + +#define VIDC_IFACEQ_GET_QHDR_START_ADDR(ptr, i) \ + (void *)((ptr + sizeof(struct hfi_queue_table_header)) + \ + (i * sizeof(struct hfi_queue_header))) + +#define QDSS_SIZE 4096 +#define SFR_SIZE 4096 + +#define QUEUE_SIZE (VIDC_IFACEQ_TABLE_SIZE + \ + (VIDC_IFACEQ_QUEUE_SIZE * VIDC_IFACEQ_NUMQ)) + +#define ALIGNED_QDSS_SIZE ALIGN(QDSS_SIZE, SZ_4K) +#define ALIGNED_SFR_SIZE ALIGN(SFR_SIZE, SZ_4K) +#define ALIGNED_QUEUE_SIZE ALIGN(QUEUE_SIZE, SZ_4K) +#define SHARED_QSIZE ALIGN(ALIGNED_SFR_SIZE + ALIGNED_QUEUE_SIZE + \ + ALIGNED_QDSS_SIZE, SZ_1M) + +enum vidc_hw_reg { + VIDC_HWREG_CTRL_STATUS = 0x1, + VIDC_HWREG_QTBL_INFO = 0x2, + VIDC_HWREG_QTBL_ADDR = 0x3, + VIDC_HWREG_CTRLR_RESET = 0x4, + VIDC_HWREG_IFACEQ_FWRXREQ = 0x5, + VIDC_HWREG_IFACEQ_FWTXREQ = 0x6, + VIDC_HWREG_VHI_SOFTINTEN = 0x7, + VIDC_HWREG_VHI_SOFTINTSTATUS = 0x8, + VIDC_HWREG_VHI_SOFTINTCLR = 0x9, + VIDC_HWREG_HVI_SOFTINTEN = 0xA, +}; + +struct vidc_mem_addr { + u32 align_device_addr; + u8 *align_virtual_addr; + u32 mem_size; + struct msm_smem mem_data; +}; + +struct vidc_iface_q_info { + void *q_hdr; + struct vidc_mem_addr q_array; +}; + +/* + * These are helper macros to iterate over various lists within + * venus_hfi_device->res. The intention is to cut down on a lot of boiler-plate + * code + */ + +/* Read as "for each 'thing' in a set of 'thingies'" */ +#define venus_hfi_for_each_thing(__device, __thing, __thingy) \ + venus_hfi_for_each_thing_continue(__device, __thing, __thingy, 0) + +#define venus_hfi_for_each_thing_reverse(__device, __thing, __thingy) \ + venus_hfi_for_each_thing_reverse_continue(__device, __thing, __thingy, \ + (__device)->res->__thingy##_set.count - 1) + +/* TODO: the __from parameter technically not required since we can figure it + * out with some pointer magic (i.e. __thing - __thing##_tbl[0]). If this macro + * sees extensive use, probably worth cleaning it up but for now omitting it + * since it introduces unnecessary complexity. + */ +#define venus_hfi_for_each_thing_continue(__device, __thing, __thingy, __from) \ + for (__thing = &(__device)->res->\ + __thingy##_set.__thingy##_tbl[__from]; \ + __thing < &(__device)->res->__thingy##_set.__thingy##_tbl[0] + \ + ((__device)->res->__thingy##_set.count - __from); \ + ++__thing) + +#define venus_hfi_for_each_thing_reverse_continue(__device, __thing, __thingy, \ + __from) \ + for (__thing = &(__device)->res->\ + __thingy##_set.__thingy##_tbl[__from]; \ + __thing >= &(__device)->res->__thingy##_set.__thingy##_tbl[0]; \ + --__thing) + +/* Regular set helpers */ +#define venus_hfi_for_each_regulator(__device, __rinfo) \ + venus_hfi_for_each_thing(__device, __rinfo, regulator) + +#define venus_hfi_for_each_regulator_reverse(__device, __rinfo) \ + venus_hfi_for_each_thing_reverse(__device, __rinfo, regulator) + +#define venus_hfi_for_each_regulator_reverse_continue(__device, __rinfo, \ + __from) \ + venus_hfi_for_each_thing_reverse_continue(__device, __rinfo, \ + regulator, __from) + +/* Clock set helpers */ +#define venus_hfi_for_each_clock(__device, __cinfo) \ + venus_hfi_for_each_thing(__device, __cinfo, clock) + +#define venus_hfi_for_each_clock_reverse(__device, __cinfo) \ + venus_hfi_for_each_thing_reverse(__device, __cinfo, clock) + +#define venus_hfi_for_each_clock_reverse_continue(__device, __rinfo, \ + __from) \ + venus_hfi_for_each_thing_reverse_continue(__device, __rinfo, \ + clock, __from) + +/* Bus set helpers */ +#define venus_hfi_for_each_bus(__device, __binfo) \ + venus_hfi_for_each_thing(__device, __binfo, bus) +#define venus_hfi_for_each_bus_reverse(__device, __binfo) \ + venus_hfi_for_each_thing_reverse(__device, __binfo, bus) + +/* Subcache set helpers */ +#define venus_hfi_for_each_subcache(__device, __sinfo) \ + venus_hfi_for_each_thing(__device, __sinfo, subcache) +#define venus_hfi_for_each_subcache_reverse(__device, __sinfo) \ + venus_hfi_for_each_thing_reverse(__device, __sinfo, subcache) + +#define call_venus_op(d, op, ...) \ + (((d) && (d)->vpu_ops && (d)->vpu_ops->op) ? \ + ((d)->vpu_ops->op(__VA_ARGS__)):0) + +/* Internal data used in vidc_hal not exposed to msm_vidc*/ +struct hal_data { + u32 irq; + phys_addr_t firmware_base; + u8 __iomem *register_base; + u32 register_size; +}; + +struct venus_resources { + struct msm_vidc_fw fw; +}; + +enum dsp_flag { + DSP_INIT = BIT(0), + DSP_SUSPEND = BIT(1), +}; + +enum venus_hfi_state { + VENUS_STATE_DEINIT = 1, + VENUS_STATE_INIT, +}; + +enum reset_state { + INIT = 1, + ASSERT, + DEASSERT, +}; + +struct venus_hfi_device; + +struct venus_hfi_vpu_ops { + void (*interrupt_init)(struct venus_hfi_device *ptr); + void (*setup_dsp_uc_memmap)(struct venus_hfi_device *device); + void (*clock_config_on_enable)(struct venus_hfi_device *device); + int (*reset_ahb2axi_bridge)(struct venus_hfi_device *device); + void (*power_off)(struct venus_hfi_device *device); + void (*noc_error_info)(struct venus_hfi_device *device); +}; + +struct venus_hfi_device { + struct list_head list; + struct list_head sess_head; + u32 intr_status; + u32 device_id; + u32 clk_freq; + u32 last_packet_type; + unsigned long clk_bitrate; + unsigned long scaled_rate; + struct msm_vidc_bus_data bus_vote; + bool power_enabled; + struct mutex lock; + msm_vidc_callback callback; + struct vidc_mem_addr iface_q_table; + struct vidc_mem_addr dsp_iface_q_table; + struct vidc_mem_addr qdss; + struct vidc_mem_addr sfr; + struct vidc_mem_addr mem_addr; + struct vidc_iface_q_info iface_queues[VIDC_IFACEQ_NUMQ]; + struct vidc_iface_q_info dsp_iface_queues[VIDC_IFACEQ_NUMQ]; + u32 dsp_flags; + struct hal_data *hal_data; + struct workqueue_struct *vidc_workq; + struct workqueue_struct *venus_pm_workq; + int spur_count; + int reg_count; + struct venus_resources resources; + struct msm_vidc_platform_resources *res; + enum venus_hfi_state state; + struct hfi_packetization_ops *pkt_ops; + enum hfi_packetization_type packetization_type; + struct msm_vidc_cb_info *response_pkt; + u8 *raw_packet; + struct pm_qos_request qos; + unsigned int skip_pc_count; + struct venus_hfi_vpu_ops *vpu_ops; +}; + +void venus_hfi_delete_device(void *device); + +int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id, + struct msm_vidc_platform_resources *res, + hfi_cmd_response_callback callback); + +#endif diff --git a/msm/vidc/vidc_hfi.c b/msm/vidc/vidc_hfi.c new file mode 100644 index 000000000000..cedf0c1dea00 --- /dev/null +++ b/msm/vidc/vidc_hfi.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + */ +#include +#include "msm_vidc_debug.h" +#include "vidc_hfi_api.h" +#include "venus_hfi.h" + +struct hfi_device *vidc_hfi_initialize(enum msm_vidc_hfi_type hfi_type, + u32 device_id, struct msm_vidc_platform_resources *res, + hfi_cmd_response_callback callback) +{ + struct hfi_device *hdev = NULL; + int rc = 0; + + hdev = kzalloc(sizeof(struct hfi_device), GFP_KERNEL); + if (!hdev) { + dprintk(VIDC_ERR, "%s: failed to allocate hdev\n", __func__); + return NULL; + } + + switch (hfi_type) { + case VIDC_HFI_VENUS: + rc = venus_hfi_initialize(hdev, device_id, res, callback); + break; + default: + dprintk(VIDC_ERR, "Unsupported host-firmware interface\n"); + goto err_hfi_init; + } + + if (rc) { + if (rc != -EPROBE_DEFER) + dprintk(VIDC_ERR, "%s device init failed rc = %d", + __func__, rc); + goto err_hfi_init; + } + + return hdev; + +err_hfi_init: + kfree(hdev); + return ERR_PTR(rc); +} + +void vidc_hfi_deinitialize(enum msm_vidc_hfi_type hfi_type, + struct hfi_device *hdev) +{ + if (!hdev) { + dprintk(VIDC_ERR, "%s invalid device %pK", __func__, hdev); + return; + } + + switch (hfi_type) { + case VIDC_HFI_VENUS: + venus_hfi_delete_device(hdev->hfi_device_data); + break; + default: + dprintk(VIDC_ERR, "Unsupported host-firmware interface\n"); + } + + kfree(hdev); +} + diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h new file mode 100644 index 000000000000..d3ab844a2499 --- /dev/null +++ b/msm/vidc/vidc_hfi.h @@ -0,0 +1,841 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ +#ifndef __H_VIDC_HFI_H__ +#define __H_VIDC_HFI_H__ + +#include +#include "vidc_hfi_helper.h" +#include "vidc_hfi_api.h" + +#define HFI_EVENT_SESSION_SEQUENCE_CHANGED (HFI_OX_BASE + 0x3) +#define HFI_EVENT_SESSION_PROPERTY_CHANGED (HFI_OX_BASE + 0x4) +#define HFI_EVENT_SESSION_LTRUSE_FAILED (HFI_OX_BASE + 0x5) +#define HFI_EVENT_RELEASE_BUFFER_REFERENCE (HFI_OX_BASE + 0x6) + +#define HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUFFER_RESOURCES \ + (HFI_OX_BASE + 0x1) +#define HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUFFER_RESOURCES \ + (HFI_OX_BASE + 0x2) + +#define HFI_BUFFERFLAG_EOS 0x00000001 +#define HFI_BUFFERFLAG_STARTTIME 0x00000002 +#define HFI_BUFFERFLAG_DECODEONLY 0x00000004 +#define HFI_BUFFERFLAG_DATACORRUPT 0x00000008 +#define HFI_BUFFERFLAG_ENDOFFRAME 0x00000010 +#define HFI_BUFFERFLAG_SYNCFRAME 0x00000020 +#define HFI_BUFFERFLAG_EXTRADATA 0x00000040 +#define HFI_BUFFERFLAG_CODECCONFIG 0x00000080 +#define HFI_BUFFERFLAG_TIMESTAMPINVALID 0x00000100 +#define HFI_BUFFERFLAG_READONLY 0x00000200 +#define HFI_BUFFERFLAG_ENDOFSUBFRAME 0x00000400 +#define HFI_BUFFERFLAG_EOSEQ 0x00200000 +#define HFI_BUFFER_FLAG_MBAFF 0x08000000 +#define HFI_BUFFERFLAG_VPE_YUV_601_709_CSC_CLAMP \ + 0x10000000 +#define HFI_BUFFERFLAG_DROP_FRAME 0x20000000 +#define HFI_BUFFERFLAG_TEI 0x40000000 +#define HFI_BUFFERFLAG_DISCONTINUITY 0x80000000 + + +#define HFI_ERR_SESSION_EMPTY_BUFFER_DONE_OUTPUT_PENDING \ + (HFI_OX_BASE + 0x1001) +#define HFI_ERR_SESSION_SAME_STATE_OPERATION \ + (HFI_OX_BASE + 0x1002) +#define HFI_ERR_SESSION_SYNC_FRAME_NOT_DETECTED \ + (HFI_OX_BASE + 0x1003) +#define HFI_ERR_SESSION_START_CODE_NOT_FOUND \ + (HFI_OX_BASE + 0x1004) + + +#define HFI_BUFFER_MODE_DYNAMIC (HFI_OX_BASE + 0x3) + +#define HFI_FLUSH_INPUT (HFI_OX_BASE + 0x1) +#define HFI_FLUSH_OUTPUT (HFI_OX_BASE + 0x2) +#define HFI_FLUSH_ALL (HFI_OX_BASE + 0x4) + +#define HFI_EXTRADATA_NONE 0x00000000 +#define HFI_EXTRADATA_MB_QUANTIZATION 0x00000001 +#define HFI_EXTRADATA_INTERLACE_VIDEO 0x00000002 +#define HFI_EXTRADATA_TIMESTAMP 0x00000005 +#define HFI_EXTRADATA_S3D_FRAME_PACKING 0x00000006 +#define HFI_EXTRADATA_FRAME_RATE 0x00000007 +#define HFI_EXTRADATA_PANSCAN_WINDOW 0x00000008 +#define HFI_EXTRADATA_RECOVERY_POINT_SEI 0x00000009 +#define HFI_EXTRADATA_MPEG2_SEQDISP 0x0000000D +#define HFI_EXTRADATA_STREAM_USERDATA 0x0000000E +#define HFI_EXTRADATA_FRAME_QP 0x0000000F +#define HFI_EXTRADATA_FRAME_BITS_INFO 0x00000010 +#define HFI_EXTRADATA_VPX_COLORSPACE 0x00000014 +#define HFI_EXTRADATA_UBWC_CR_STAT_INFO 0x00000019 +#define HFI_EXTRADATA_MULTISLICE_INFO 0x7F100000 +#define HFI_EXTRADATA_NUM_CONCEALED_MB 0x7F100001 +#define HFI_EXTRADATA_INDEX 0x7F100002 +#define HFI_EXTRADATA_METADATA_LTR 0x7F100004 +#define HFI_EXTRADATA_METADATA_FILLER 0x7FE00002 + +#define HFI_INDEX_EXTRADATA_INPUT_CROP 0x0700000E +#define HFI_INDEX_EXTRADATA_OUTPUT_CROP 0x0700000F +#define HFI_INDEX_EXTRADATA_ASPECT_RATIO 0x7F100003 + +struct hfi_buffer_alloc_mode { + u32 buffer_type; + u32 buffer_mode; +}; + + +struct hfi_index_extradata_config { + int enable; + u32 index_extra_data_id; +}; + +struct hfi_extradata_header { + u32 size; + u32 version; + u32 port_index; + u32 type; + u32 data_size; + u8 rg_data[1]; +}; + +#define HFI_INTERLACE_FRAME_PROGRESSIVE 0x01 +#define HFI_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST 0x02 +#define HFI_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST 0x04 +#define HFI_INTERLACE_FRAME_TOPFIELDFIRST 0x08 +#define HFI_INTERLACE_FRAME_BOTTOMFIELDFIRST 0x10 +#define HFI_INTERLACE_FRAME_MBAFF 0x20 + +#define HFI_PROPERTY_SYS_OX_START \ + (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + 0x0000) + +#define HFI_PROPERTY_PARAM_OX_START \ + (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + 0x1000) +#define HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL \ + (HFI_PROPERTY_PARAM_OX_START + 0x001) +#define HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO \ + (HFI_PROPERTY_PARAM_OX_START + 0x002) +#define HFI_PROPERTY_PARAM_INDEX_EXTRADATA \ + (HFI_PROPERTY_PARAM_OX_START + 0x006) +#define HFI_PROPERTY_PARAM_S3D_FRAME_PACKING_EXTRADATA \ + (HFI_PROPERTY_PARAM_OX_START + 0x009) +#define HFI_PROPERTY_PARAM_BUFFER_SIZE_MINIMUM \ + (HFI_PROPERTY_PARAM_OX_START + 0x00C) +#define HFI_PROPERTY_PARAM_SYNC_BASED_INTERRUPT \ + (HFI_PROPERTY_PARAM_OX_START + 0x00E) + +#define HFI_PROPERTY_CONFIG_OX_START \ + (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + 0x02000) +#define HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS \ + (HFI_PROPERTY_CONFIG_OX_START + 0x001) +#define HFI_PROPERTY_CONFIG_REALTIME \ + (HFI_PROPERTY_CONFIG_OX_START + 0x002) +#define HFI_PROPERTY_CONFIG_PRIORITY \ + (HFI_PROPERTY_CONFIG_OX_START + 0x003) +#define HFI_PROPERTY_PARAM_VDEC_OX_START \ + (HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x3000) +#define HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001) +#define HFI_PROPERTY_PARAM_VDEC_MULTI_VIEW_SELECT \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x003) +#define HFI_PROPERTY_PARAM_VDEC_PICTURE_TYPE_DECODE \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x004) +#define HFI_PROPERTY_PARAM_VDEC_OUTPUT_ORDER \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x005) +#define HFI_PROPERTY_PARAM_VDEC_MB_QUANTIZATION \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x006) +#define HFI_PROPERTY_PARAM_VDEC_NUM_CONCEALED_MB \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x007) +#define HFI_PROPERTY_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO\ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x009) +#define HFI_PROPERTY_PARAM_VDEC_FRAME_RATE_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00A) +#define HFI_PROPERTY_PARAM_VDEC_PANSCAN_WNDW_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00B) +#define HFI_PROPERTY_PARAM_VDEC_RECOVERY_POINT_SEI_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00C) +#define HFI_PROPERTY_PARAM_VDEC_THUMBNAIL_MODE \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00D) +#define HFI_PROPERTY_PARAM_VDEC_TIMESTAMP_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x013) +#define HFI_PROPERTY_PARAM_VDEC_INTERLACE_VIDEO_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x014) +#define HFI_PROPERTY_PARAM_VDEC_AVC_SESSION_SELECT \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x015) +#define HFI_PROPERTY_PARAM_VDEC_MPEG2_SEQDISP_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x016) +#define HFI_PROPERTY_PARAM_VDEC_STREAM_USERDATA_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x017) +#define HFI_PROPERTY_PARAM_VDEC_FRAME_QP_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x018) +#define HFI_PROPERTY_PARAM_VDEC_FRAME_BITS_INFO_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x019) +#define HFI_PROPERTY_PARAM_VUI_DISPLAY_INFO_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x01B) +#define HFI_PROPERTY_PARAM_VDEC_VQZIP_SEI_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001C) +#define HFI_PROPERTY_PARAM_VDEC_VPX_COLORSPACE_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001D) +#define HFI_PROPERTY_PARAM_VDEC_MASTER_DISP_COL_SEI_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001E) +#define HFI_PROPERTY_PARAM_VDEC_CLL_SEI_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001F) +#define HFI_PROPERTY_PARAM_VDEC_COLOUR_REMAPPING_INFO_SEI_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x0020) +#define HFI_PROPERTY_PARAM_VDEC_DOWN_SCALAR \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x0021) +#define HFI_PROPERTY_PARAM_VDEC_UBWC_CR_STAT_INFO_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x0022) +#define HFI_PROPERTY_PARAM_HDR10_HIST_EXTRADATA \ + (HFI_PROPERTY_PARAM_OX_START + 0x0023) + +#define HFI_PROPERTY_CONFIG_VDEC_OX_START \ + (HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x4000) +#define HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP_REPORTING \ + (HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x002) +#define HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP \ + (HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x003) +#define HFI_PROPERTY_CONFIG_VDEC_ENTROPY \ + (HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x004) + +#define HFI_PROPERTY_PARAM_VENC_OX_START \ + (HFI_DOMAIN_BASE_VENC + HFI_ARCH_OX_OFFSET + 0x5000) +#define HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_INFO \ + (HFI_PROPERTY_PARAM_VENC_OX_START + 0x001) +#define HFI_PROPERTY_PARAM_VENC_H264_IDR_S3D_FRAME_PACKING_NAL \ + (HFI_PROPERTY_PARAM_VENC_OX_START + 0x002) +#define HFI_PROPERTY_PARAM_VENC_LTR_INFO \ + (HFI_PROPERTY_PARAM_VENC_OX_START + 0x003) +#define HFI_PROPERTY_PARAM_VENC_MBI_DUMPING \ + (HFI_PROPERTY_PARAM_VENC_OX_START + 0x005) +#define HFI_PROPERTY_PARAM_VENC_FRAME_QP_EXTRADATA \ + (HFI_PROPERTY_PARAM_VENC_OX_START + 0x006) +#define HFI_PROPERTY_PARAM_VENC_ROI_QP_EXTRADATA \ + (HFI_PROPERTY_PARAM_VENC_OX_START + 0x008) +#define HFI_PROPERTY_PARAM_VENC_HDR10PLUS_METADATA_EXTRADATA \ + (HFI_PROPERTY_PARAM_VENC_OX_START + 0x00A) +#define HFI_PROPERTY_PARAM_VENC_CVP_METADATA_EXTRADATA \ + (HFI_PROPERTY_PARAM_VENC_OX_START + 0x00B) + +#define HFI_PROPERTY_CONFIG_VENC_OX_START \ + (HFI_DOMAIN_BASE_VENC + HFI_ARCH_OX_OFFSET + 0x6000) +#define HFI_PROPERTY_PARAM_VPE_OX_START \ + (HFI_DOMAIN_BASE_VPE + HFI_ARCH_OX_OFFSET + 0x7000) + +#define HFI_PROPERTY_CONFIG_VPE_OX_START \ + (HFI_DOMAIN_BASE_VPE + HFI_ARCH_OX_OFFSET + 0x8000) + +struct hfi_batch_info { + u32 input_batch_count; + u32 output_batch_count; +}; + +struct hfi_buffer_count_actual { + u32 buffer_type; + u32 buffer_count_actual; + u32 buffer_count_min_host; +}; + +struct hfi_buffer_size_minimum { + u32 buffer_type; + u32 buffer_size; +}; + +struct hfi_buffer_requirements { + u32 buffer_type; + u32 buffer_size; + u32 buffer_region_size; + u32 buffer_count_min; + u32 buffer_count_min_host; + u32 buffer_count_actual; + u32 contiguous; + u32 buffer_alignment; +}; + +struct hfi_data_payload { + u32 size; + u8 rg_data[1]; +}; + +struct hfi_enable_picture { + u32 picture_type; +}; + +struct hfi_mb_error_map { + u32 error_map_size; + u8 rg_error_map[1]; +}; + +struct hfi_metadata_pass_through { + int enable; + u32 size; +}; + +struct hfi_multi_view_select { + u32 view_index; +}; + +struct hfi_hybrid_hierp { + u32 layers; +}; + +#define HFI_PRIORITY_LOW 10 +#define HFI_PRIOIRTY_MEDIUM 20 +#define HFI_PRIORITY_HIGH 30 + +#define HFI_OUTPUT_ORDER_DISPLAY (HFI_OX_BASE + 0x1) +#define HFI_OUTPUT_ORDER_DECODE (HFI_OX_BASE + 0x2) + +#define HFI_RATE_CONTROL_OFF (HFI_OX_BASE + 0x1) +#define HFI_RATE_CONTROL_VBR_VFR (HFI_OX_BASE + 0x2) +#define HFI_RATE_CONTROL_VBR_CFR (HFI_OX_BASE + 0x3) +#define HFI_RATE_CONTROL_CBR_VFR (HFI_OX_BASE + 0x4) +#define HFI_RATE_CONTROL_CBR_CFR (HFI_OX_BASE + 0x5) +#define HFI_RATE_CONTROL_MBR_CFR (HFI_OX_BASE + 0x6) +#define HFI_RATE_CONTROL_MBR_VFR (HFI_OX_BASE + 0x7) +#define HFI_RATE_CONTROL_CQ (HFI_OX_BASE + 0x8) + + +struct hfi_uncompressed_plane_actual_constraints_info { + u32 buffer_type; + u32 num_planes; + struct hfi_uncompressed_plane_constraints rg_plane_format[1]; +}; + +#define HFI_CMD_SYS_OX_START \ +(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_CMD_START_OFFSET + 0x0000) +#define HFI_CMD_SYS_SESSION_ABORT (HFI_CMD_SYS_OX_START + 0x001) + +#define HFI_CMD_SESSION_OX_START \ +(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_CMD_START_OFFSET + 0x1000) +#define HFI_CMD_SESSION_LOAD_RESOURCES (HFI_CMD_SESSION_OX_START + 0x001) +#define HFI_CMD_SESSION_START (HFI_CMD_SESSION_OX_START + 0x002) +#define HFI_CMD_SESSION_STOP (HFI_CMD_SESSION_OX_START + 0x003) +#define HFI_CMD_SESSION_EMPTY_BUFFER (HFI_CMD_SESSION_OX_START + 0x004) +#define HFI_CMD_SESSION_FILL_BUFFER (HFI_CMD_SESSION_OX_START + 0x005) +#define HFI_CMD_SESSION_SUSPEND (HFI_CMD_SESSION_OX_START + 0x006) +#define HFI_CMD_SESSION_RESUME (HFI_CMD_SESSION_OX_START + 0x007) +#define HFI_CMD_SESSION_FLUSH (HFI_CMD_SESSION_OX_START + 0x008) +#define HFI_CMD_SESSION_GET_PROPERTY (HFI_CMD_SESSION_OX_START + 0x009) +#define HFI_CMD_SESSION_PARSE_SEQUENCE_HEADER \ + (HFI_CMD_SESSION_OX_START + 0x00A) +#define HFI_CMD_SESSION_RELEASE_BUFFERS \ + (HFI_CMD_SESSION_OX_START + 0x00B) +#define HFI_CMD_SESSION_RELEASE_RESOURCES \ + (HFI_CMD_SESSION_OX_START + 0x00C) +#define HFI_CMD_SESSION_CONTINUE (HFI_CMD_SESSION_OX_START + 0x00D) +#define HFI_CMD_SESSION_SYNC (HFI_CMD_SESSION_OX_START + 0x00E) + +#define HFI_CMD_SESSION_CVP_START \ + (HFI_DOMAIN_BASE_CVP + HFI_ARCH_COMMON_OFFSET + \ + HFI_CMD_START_OFFSET + 0x1000) +#define HFI_CMD_SESSION_REGISTER_BUFFERS \ + (HFI_CMD_SESSION_CVP_START + 0x0A0) +#define HFI_CMD_SESSION_UNREGISTER_BUFFERS \ + (HFI_CMD_SESSION_CVP_START + 0x0A1) + +#define HFI_MSG_SYS_OX_START \ +(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_MSG_START_OFFSET + 0x0000) +#define HFI_MSG_SYS_SESSION_ABORT_DONE (HFI_MSG_SYS_OX_START + 0x4) + +#define HFI_MSG_SESSION_OX_START \ +(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_MSG_START_OFFSET + 0x1000) +#define HFI_MSG_SESSION_LOAD_RESOURCES_DONE (HFI_MSG_SESSION_OX_START + 0x1) +#define HFI_MSG_SESSION_START_DONE (HFI_MSG_SESSION_OX_START + 0x2) +#define HFI_MSG_SESSION_STOP_DONE (HFI_MSG_SESSION_OX_START + 0x3) +#define HFI_MSG_SESSION_SUSPEND_DONE (HFI_MSG_SESSION_OX_START + 0x4) +#define HFI_MSG_SESSION_RESUME_DONE (HFI_MSG_SESSION_OX_START + 0x5) +#define HFI_MSG_SESSION_FLUSH_DONE (HFI_MSG_SESSION_OX_START + 0x6) +#define HFI_MSG_SESSION_EMPTY_BUFFER_DONE (HFI_MSG_SESSION_OX_START + 0x7) +#define HFI_MSG_SESSION_FILL_BUFFER_DONE (HFI_MSG_SESSION_OX_START + 0x8) +#define HFI_MSG_SESSION_PROPERTY_INFO (HFI_MSG_SESSION_OX_START + 0x9) +#define HFI_MSG_SESSION_RELEASE_RESOURCES_DONE \ + (HFI_MSG_SESSION_OX_START + 0xA) +#define HFI_MSG_SESSION_RELEASE_BUFFERS_DONE \ + (HFI_MSG_SESSION_OX_START + 0xC) + +#define HFI_MSG_SESSION_CVP_START \ + (HFI_DOMAIN_BASE_CVP + HFI_ARCH_COMMON_OFFSET + \ + HFI_MSG_START_OFFSET + 0x1000) +#define HFI_MSG_SESSION_REGISTER_BUFFERS_DONE \ + (HFI_MSG_SESSION_CVP_START + 0x0A0) +#define HFI_MSG_SESSION_UNREGISTER_BUFFERS_DONE \ + (HFI_MSG_SESSION_CVP_START + 0x0A1) + +#define VIDC_IFACEQ_MAX_PKT_SIZE 1024 +#define VIDC_IFACEQ_MED_PKT_SIZE 768 +#define VIDC_IFACEQ_MIN_PKT_SIZE 8 +#define VIDC_IFACEQ_VAR_SMALL_PKT_SIZE 100 +#define VIDC_IFACEQ_VAR_LARGE_PKT_SIZE 512 +#define VIDC_IFACEQ_VAR_HUGE_PKT_SIZE (1024*12) + + +struct hfi_cmd_sys_session_abort_packet { + u32 size; + u32 packet_type; + u32 session_id; +}; + +struct hfi_cmd_session_load_resources_packet { + u32 size; + u32 packet_type; + u32 session_id; +}; + +struct hfi_cmd_session_start_packet { + u32 size; + u32 packet_type; + u32 session_id; +}; + +struct hfi_cmd_session_stop_packet { + u32 size; + u32 packet_type; + u32 session_id; +}; + +struct hfi_cmd_session_empty_buffer_compressed_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 time_stamp_hi; + u32 time_stamp_lo; + u32 flags; + u32 mark_target; + u32 mark_data; + u32 offset; + u32 alloc_len; + u32 filled_len; + u32 input_tag; + u32 packet_buffer; + u32 extra_data_buffer; + u32 rgData[1]; +}; + +struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 view_id; + u32 time_stamp_hi; + u32 time_stamp_lo; + u32 flags; + u32 mark_target; + u32 mark_data; + u32 alloc_len; + u32 filled_len; + u32 offset; + u32 input_tag; + u32 packet_buffer; + u32 extra_data_buffer; + u32 rgData[1]; +}; + +struct hfi_cmd_session_empty_buffer_uncompressed_plane1_packet { + u32 flags; + u32 alloc_len; + u32 filled_len; + u32 offset; + u32 packet_buffer2; + u32 rgData[1]; +}; + +struct hfi_cmd_session_empty_buffer_uncompressed_plane2_packet { + u32 flags; + u32 alloc_len; + u32 filled_len; + u32 offset; + u32 packet_buffer3; + u32 rgData[1]; +}; + +struct hfi_cmd_session_fill_buffer_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 stream_id; + u32 offset; + u32 alloc_len; + u32 filled_len; + u32 output_tag; + u32 packet_buffer; + u32 extra_data_buffer; + u32 rgData[1]; +}; + +struct hfi_cmd_session_flush_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 flush_type; +}; + +struct hfi_cmd_session_suspend_packet { + u32 size; + u32 packet_type; + u32 session_id; +}; + +struct hfi_cmd_session_resume_packet { + u32 size; + u32 packet_type; + u32 session_id; +}; + +struct hfi_cmd_session_get_property_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 num_properties; + u32 rg_property_data[1]; +}; + +struct hfi_cmd_session_release_buffer_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 buffer_type; + u32 buffer_size; + u32 extra_data_size; + int response_req; + u32 num_buffers; + u32 rg_buffer_info[1]; +}; + +struct hfi_cmd_session_release_resources_packet { + u32 size; + u32 packet_type; + u32 session_id; +}; + +struct hfi_msg_sys_session_abort_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; +}; + +struct hfi_msg_sys_property_info_packet { + u32 size; + u32 packet_type; + u32 num_properties; + u32 rg_property_data[1]; +}; + +struct hfi_msg_session_load_resources_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; +}; + +struct hfi_msg_session_start_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; +}; + +struct hfi_msg_session_stop_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; +}; + +struct hfi_msg_session_suspend_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; +}; + +struct hfi_msg_session_resume_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; +}; + +struct hfi_msg_session_flush_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; + u32 flush_type; +}; + +struct hfi_ubwc_cr_stats_info_type { + u32 cr_stats_info0; + u32 cr_stats_info1; + u32 cr_stats_info2; + u32 cr_stats_info3; + u32 cr_stats_info4; + u32 cr_stats_info5; + u32 cr_stats_info6; +}; + +struct hfi_frame_cr_stats_type { + u32 frame_index; + struct hfi_ubwc_cr_stats_info_type ubwc_stats_info; + u32 complexity_number; +}; + +struct hfi_msg_session_empty_buffer_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; + u32 offset; + u32 filled_len; + u32 input_tag; + u32 packet_buffer; + u32 extra_data_buffer; + u32 flags; + struct hfi_frame_cr_stats_type ubwc_cr_stats; + u32 rgData[0]; +}; + +struct hfi_msg_session_fill_buffer_done_compressed_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 time_stamp_hi; + u32 time_stamp_lo; + u32 error_type; + u32 flags; + u32 mark_target; + u32 mark_data; + u32 stats; + u32 offset; + u32 alloc_len; + u32 filled_len; + u32 input_tag; + u32 output_tag; + u32 picture_type; + u32 packet_buffer; + u32 extra_data_buffer; + u32 rgData[0]; +}; + +struct hfi_msg_session_fbd_uncompressed_plane0_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 stream_id; + u32 view_id; + u32 error_type; + u32 time_stamp_hi; + u32 time_stamp_lo; + u32 flags; + u32 mark_target; + u32 mark_data; + u32 stats; + u32 alloc_len; + u32 filled_len; + u32 offset; + u32 frame_width; + u32 frame_height; + u32 start_x_coord; + u32 start_y_coord; + u32 input_tag; + u32 input_tag2; + u32 output_tag; + u32 picture_type; + u32 packet_buffer; + u32 extra_data_buffer; + u32 rgData[0]; +}; + +struct hfi_msg_session_fill_buffer_done_uncompressed_plane1_packet { + u32 flags; + u32 alloc_len; + u32 filled_len; + u32 offset; + u32 packet_buffer2; + u32 rgData[0]; +}; + +struct hfi_msg_session_fill_buffer_done_uncompressed_plane2_packet { + u32 flags; + u32 alloc_len; + u32 filled_len; + u32 offset; + u32 packet_buffer3; + u32 rgData[0]; +}; + +struct hfi_msg_session_property_info_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 num_properties; + u32 rg_property_data[1]; +}; + +struct hfi_msg_session_release_resources_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; +}; + +struct hfi_msg_session_release_buffers_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; + u32 num_buffers; + u32 rg_buffer_info[1]; +}; + +struct hfi_msg_session_register_buffers_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 client_data; + u32 error_type; +}; + +struct hfi_msg_session_unregister_buffers_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 client_data; + u32 error_type; +}; + +struct hfi_extradata_mb_quantization_payload { + u8 rg_mb_qp[1]; +}; + +struct hfi_extradata_timestamp_payload { + u32 time_stamp_low; + u32 time_stamp_high; +}; + + +struct hfi_extradata_s3d_frame_packing_payload { + u32 fpa_id; + int cancel_flag; + u32 fpa_type; + int quin_cunx_flag; + u32 content_interprtation_type; + int spatial_flipping_flag; + int frame0_flipped_flag; + int field_views_flag; + int current_frame_isFrame0_flag; + int frame0_self_contained_flag; + int frame1_self_contained_flag; + u32 frame0_graid_pos_x; + u32 frame0_graid_pos_y; + u32 frame1_graid_pos_x; + u32 frame1_graid_pos_y; + u32 fpa_reserved_byte; + u32 fpa_repetition_period; + int fpa_extension_flag; +}; + +struct hfi_extradata_interlace_video_payload { + u32 format; +}; + +struct hfi_conceal_color_type { + u32 value_8bit; + u32 value_10bit; +}; + +struct hfi_extradata_num_concealed_mb_payload { + u32 num_mb_concealed; +}; + +struct hfi_extradata_sliceinfo { + u32 offset_in_stream; + u32 slice_length; +}; + +struct hfi_extradata_multislice_info_payload { + u32 num_slices; + struct hfi_extradata_sliceinfo rg_slice_info[1]; +}; + +struct hfi_index_extradata_input_crop_payload { + u32 size; + u32 version; + u32 port_index; + u32 left; + u32 top; + u32 width; + u32 height; +}; + +struct hfi_index_extradata_output_crop_payload { + u32 size; + u32 version; + u32 port_index; + u32 left; + u32 top; + u32 display_width; + u32 display_height; + u32 width; + u32 height; +}; + +struct hfi_index_extradata_digital_zoom_payload { + u32 size; + u32 version; + u32 port_index; + int width; + int height; +}; + +struct hfi_index_extradata_aspect_ratio_payload { + u32 size; + u32 version; + u32 port_index; + u32 aspect_width; + u32 aspect_height; +}; + +struct hfi_extradata_frame_type_payload { + u32 frame_rate; +}; + +struct hfi_extradata_recovery_point_sei_payload { + u32 flag; +}; + +struct hfi_cmd_session_continue_packet { + u32 size; + u32 packet_type; + u32 session_id; +}; + +enum session_flags { + SESSION_PAUSE = BIT(1), +}; + +struct hal_session { + struct list_head list; + void *session_id; + bool is_decoder; + enum hal_video_codec codec; + enum hal_domain domain; + u32 flags; + void *device; +}; + +struct hal_device_data { + struct list_head dev_head; + int dev_count; +}; + +struct msm_vidc_fw { + void *cookie; +}; + +int hfi_process_msg_packet(u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr, + struct msm_vidc_cb_info *info); + +#endif + diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h new file mode 100644 index 000000000000..eed788b7b270 --- /dev/null +++ b/msm/vidc/vidc_hfi_api.h @@ -0,0 +1,752 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef __VIDC_HFI_API_H__ +#define __VIDC_HFI_API_H__ + +#include +#include +#include +#include +#include +#include "msm_vidc.h" +#include "msm_vidc_resources.h" + +#define CONTAINS(__a, __sz, __t) (\ + (__t >= __a) && \ + (__t < __a + __sz) \ +) + +#define OVERLAPS(__t, __tsz, __a, __asz) (\ + (__t <= __a) && \ + (__t + __tsz >= __a + __asz) \ +) + +#define HAL_BUFFERFLAG_EOS 0x00000001 +#define HAL_BUFFERFLAG_STARTTIME 0x00000002 +#define HAL_BUFFERFLAG_DATACORRUPT 0x00000008 +#define HAL_BUFFERFLAG_ENDOFFRAME 0x00000010 +#define HAL_BUFFERFLAG_SYNCFRAME 0x00000020 +#define HAL_BUFFERFLAG_EXTRADATA 0x00000040 +#define HAL_BUFFERFLAG_CODECCONFIG 0x00000080 +#define HAL_BUFFERFLAG_READONLY 0x00000200 +#define HAL_BUFFERFLAG_ENDOFSUBFRAME 0x00000400 +#define HAL_BUFFERFLAG_MBAFF 0x08000000 +#define HAL_BUFFERFLAG_YUV_601_709_CSC_CLAMP 0x10000000 +#define HAL_BUFFERFLAG_DROP_FRAME 0x20000000 +#define HAL_BUFFERFLAG_TS_DISCONTINUITY 0x40000000 +#define HAL_BUFFERFLAG_TS_ERROR 0x80000000 + + + +#define HAL_DEBUG_MSG_LOW 0x00000001 +#define HAL_DEBUG_MSG_MEDIUM 0x00000002 +#define HAL_DEBUG_MSG_HIGH 0x00000004 +#define HAL_DEBUG_MSG_ERROR 0x00000008 +#define HAL_DEBUG_MSG_FATAL 0x00000010 +#define MAX_PROFILE_COUNT 16 + +#define HAL_MAX_MATRIX_COEFFS 9 +#define HAL_MAX_BIAS_COEFFS 3 +#define HAL_MAX_LIMIT_COEFFS 6 +#define VENUS_VERSION_LENGTH 128 + +#define IDR_PERIOD 1 + +/* 16 video sessions */ +#define VIDC_MAX_SESSIONS 16 + +struct vidc_bus_vote_data; + +enum vidc_status { + VIDC_ERR_NONE = 0x0, + VIDC_ERR_FAIL = 0x80000000, + VIDC_ERR_ALLOC_FAIL, + VIDC_ERR_ILLEGAL_OP, + VIDC_ERR_BAD_PARAM, + VIDC_ERR_BAD_HANDLE, + VIDC_ERR_NOT_SUPPORTED, + VIDC_ERR_BAD_STATE, + VIDC_ERR_MAX_CLIENTS, + VIDC_ERR_IFRAME_EXPECTED, + VIDC_ERR_HW_FATAL, + VIDC_ERR_BITSTREAM_ERR, + VIDC_ERR_INDEX_NOMORE, + VIDC_ERR_SEQHDR_PARSE_FAIL, + VIDC_ERR_INSUFFICIENT_BUFFER, + VIDC_ERR_BAD_POWER_STATE, + VIDC_ERR_NO_VALID_SESSION, + VIDC_ERR_TIMEOUT, + VIDC_ERR_CMDQFULL, + VIDC_ERR_START_CODE_NOT_FOUND, + VIDC_ERR_NOC_ERROR, + VIDC_ERR_CLIENT_PRESENT = 0x90000001, + VIDC_ERR_CLIENT_FATAL, + VIDC_ERR_CMD_QUEUE_FULL, + VIDC_ERR_UNUSED = 0x10000000 +}; + +enum hal_domain { + HAL_VIDEO_DOMAIN_VPE = BIT(0), + HAL_VIDEO_DOMAIN_ENCODER = BIT(1), + HAL_VIDEO_DOMAIN_DECODER = BIT(2), + HAL_VIDEO_DOMAIN_CVP = BIT(3), + HAL_UNUSED_DOMAIN = 0x10000000, +}; + +enum multi_stream { + HAL_VIDEO_DECODER_NONE = 0x00000000, + HAL_VIDEO_DECODER_PRIMARY = 0x00000001, + HAL_VIDEO_DECODER_SECONDARY = 0x00000002, + HAL_VIDEO_DECODER_BOTH_OUTPUTS = 0x00000004, + HAL_VIDEO_UNUSED_OUTPUTS = 0x10000000, +}; + +enum hal_core_capabilities { + HAL_VIDEO_ENCODER_ROTATION_CAPABILITY = 0x00000001, + HAL_VIDEO_ENCODER_SCALING_CAPABILITY = 0x00000002, + HAL_VIDEO_ENCODER_DEINTERLACE_CAPABILITY = 0x00000004, + HAL_VIDEO_DECODER_MULTI_STREAM_CAPABILITY = 0x00000008, + HAL_VIDEO_UNUSED_CAPABILITY = 0x10000000, +}; + +enum hal_default_properties { + HAL_VIDEO_DYNAMIC_BUF_MODE = 0x00000001, + HAL_VIDEO_CONTINUE_DATA_TRANSFER = 0x00000002, +}; + +enum hal_video_codec { + HAL_VIDEO_CODEC_UNKNOWN = 0x00000000, + HAL_VIDEO_CODEC_MVC = 0x00000001, + HAL_VIDEO_CODEC_H264 = 0x00000002, + HAL_VIDEO_CODEC_H263 = 0x00000004, + HAL_VIDEO_CODEC_MPEG1 = 0x00000008, + HAL_VIDEO_CODEC_MPEG2 = 0x00000010, + HAL_VIDEO_CODEC_MPEG4 = 0x00000020, + HAL_VIDEO_CODEC_DIVX_311 = 0x00000040, + HAL_VIDEO_CODEC_DIVX = 0x00000080, + HAL_VIDEO_CODEC_VC1 = 0x00000100, + HAL_VIDEO_CODEC_SPARK = 0x00000200, + HAL_VIDEO_CODEC_VP6 = 0x00000400, + HAL_VIDEO_CODEC_VP7 = 0x00000800, + HAL_VIDEO_CODEC_VP8 = 0x00001000, + HAL_VIDEO_CODEC_HEVC = 0x00002000, + HAL_VIDEO_CODEC_VP9 = 0x00004000, + HAL_VIDEO_CODEC_TME = 0x00008000, + HAL_VIDEO_CODEC_CVP = 0x00010000, + HAL_VIDEO_CODEC_HEVC_HYBRID = 0x80000000, + HAL_UNUSED_CODEC = 0x10000000, +}; + +enum hal_uncompressed_format { + HAL_COLOR_FORMAT_MONOCHROME = 0x00000001, + HAL_COLOR_FORMAT_NV12 = 0x00000002, + HAL_COLOR_FORMAT_NV21 = 0x00000004, + HAL_COLOR_FORMAT_NV12_4x4TILE = 0x00000008, + HAL_COLOR_FORMAT_NV21_4x4TILE = 0x00000010, + HAL_COLOR_FORMAT_YUYV = 0x00000020, + HAL_COLOR_FORMAT_YVYU = 0x00000040, + HAL_COLOR_FORMAT_UYVY = 0x00000080, + HAL_COLOR_FORMAT_VYUY = 0x00000100, + HAL_COLOR_FORMAT_RGB565 = 0x00000200, + HAL_COLOR_FORMAT_BGR565 = 0x00000400, + HAL_COLOR_FORMAT_RGB888 = 0x00000800, + HAL_COLOR_FORMAT_BGR888 = 0x00001000, + HAL_COLOR_FORMAT_NV12_UBWC = 0x00002000, + HAL_COLOR_FORMAT_NV12_TP10_UBWC = 0x00004000, + HAL_COLOR_FORMAT_RGBA8888 = 0x00008000, + HAL_COLOR_FORMAT_RGBA8888_UBWC = 0x00010000, + HAL_COLOR_FORMAT_P010 = 0x00020000, + HAL_COLOR_FORMAT_NV12_512 = 0x00040000, + HAL_UNUSED_COLOR = 0x10000000, +}; + +enum hal_ssr_trigger_type { + SSR_ERR_FATAL = 1, + SSR_SW_DIV_BY_ZERO, + SSR_HW_WDOG_IRQ, +}; + +struct hal_profile_level { + u32 profile; + u32 level; +}; + +struct hal_profile_level_supported { + u32 profile_count; + struct hal_profile_level profile_level[MAX_PROFILE_COUNT]; +}; + +enum hal_intra_refresh_mode { + HAL_INTRA_REFRESH_NONE = 0x1, + HAL_INTRA_REFRESH_CYCLIC = 0x2, + HAL_INTRA_REFRESH_RANDOM = 0x5, + HAL_UNUSED_INTRA = 0x10000000, +}; + +struct hal_intra_refresh { + enum hal_intra_refresh_mode mode; + u32 ir_mbs; +}; + +struct hal_buffer_requirements { + enum hal_buffer buffer_type; + u32 buffer_size; + u32 buffer_region_size; + u32 buffer_count_min; + u32 buffer_count_min_host; + u32 buffer_count_actual; + u32 contiguous; + u32 buffer_alignment; +}; + +enum hal_priority {/* Priority increases with number */ + HAL_PRIORITY_LOW = 10, + HAL_PRIOIRTY_MEDIUM = 20, + HAL_PRIORITY_HIGH = 30, + HAL_UNUSED_PRIORITY = 0x10000000, +}; + +struct hal_batch_info { + u32 input_batch_count; + u32 output_batch_count; +}; + +struct hal_uncompressed_format_supported { + enum hal_buffer buffer_type; + u32 format_entries; + u32 rg_format_info[1]; +}; + +enum hal_interlace_format { + HAL_INTERLACE_FRAME_PROGRESSIVE = 0x01, + HAL_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST = 0x02, + HAL_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST = 0x04, + HAL_INTERLACE_FRAME_TOPFIELDFIRST = 0x08, + HAL_INTERLACE_FRAME_BOTTOMFIELDFIRST = 0x10, + HAL_UNUSED_INTERLACE = 0x10000000, +}; + +struct hal_interlace_format_supported { + enum hal_buffer buffer_type; + enum hal_interlace_format format; +}; + +enum hal_chroma_site { + HAL_CHROMA_SITE_0, + HAL_CHROMA_SITE_1, + HAL_UNUSED_CHROMA = 0x10000000, +}; + +enum hal_capability { + CAP_FRAME_WIDTH = 0x1, + CAP_FRAME_HEIGHT, + CAP_MBS_PER_FRAME, + CAP_MBS_PER_SECOND, + CAP_FRAMERATE, + CAP_SCALE_X, + CAP_SCALE_Y, + CAP_BITRATE, + CAP_BFRAME, + CAP_PEAKBITRATE, + CAP_HIER_P_NUM_ENH_LAYERS, + CAP_LTR_COUNT, + CAP_SECURE_OUTPUT2_THRESHOLD, + CAP_HIER_B_NUM_ENH_LAYERS, + CAP_LCU_SIZE, + CAP_HIER_P_HYBRID_NUM_ENH_LAYERS, + CAP_MBS_PER_SECOND_POWER_SAVE, + CAP_EXTRADATA, + CAP_PROFILE, + CAP_LEVEL, + CAP_I_FRAME_QP, + CAP_P_FRAME_QP, + CAP_B_FRAME_QP, + CAP_RATE_CONTROL_MODES, + CAP_BLUR_WIDTH, + CAP_BLUR_HEIGHT, + CAP_SLICE_BYTE, + CAP_SLICE_MB, + CAP_SECURE, + CAP_MAX_NUM_B_FRAMES, + CAP_MAX_VIDEOCORES, + CAP_MAX_WORKMODES, + CAP_UBWC_CR_STATS, + CAP_SECURE_FRAME_WIDTH, + CAP_SECURE_FRAME_HEIGHT, + CAP_SECURE_MBS_PER_FRAME, + CAP_SECURE_BITRATE, + CAP_BATCH_MAX_MB_PER_FRAME, + CAP_BATCH_MAX_FPS, + CAP_MAX, +}; + +struct hal_capability_supported { + enum hal_capability capability_type; + u32 min; + u32 max; + u32 step_size; + u32 default_value; +}; + +struct hal_nal_stream_format_supported { + u32 nal_stream_format_supported; +}; + +struct hal_nal_stream_format_select { + u32 nal_stream_format_select; +}; + +struct hal_multi_view_format { + u32 views; + u32 rg_view_order[1]; +}; + +enum hal_buffer_layout_type { + HAL_BUFFER_LAYOUT_TOP_BOTTOM, + HAL_BUFFER_LAYOUT_SEQ, + HAL_UNUSED_BUFFER_LAYOUT = 0x10000000, +}; + +struct hal_codec_supported { + u32 decoder_codec_supported; + u32 encoder_codec_supported; +}; + +enum hal_core_id { + VIDC_CORE_ID_DEFAULT = 0, + VIDC_CORE_ID_1 = 1, /* 0b01 */ + VIDC_CORE_ID_2 = 2, /* 0b10 */ + VIDC_CORE_ID_3 = 3, /* 0b11 */ + VIDC_CORE_ID_UNUSED = 0x10000000, +}; + +enum vidc_resource_id { + VIDC_RESOURCE_NONE, + VIDC_RESOURCE_SYSCACHE, + VIDC_UNUSED_RESOURCE = 0x10000000, +}; + +struct vidc_resource_hdr { + enum vidc_resource_id resource_id; + void *resource_handle; +}; + +struct vidc_register_buffer { + enum hal_buffer type; + u32 index; + u32 size; + u32 device_addr; + u32 response_required; + u32 client_data; +}; + +struct vidc_unregister_buffer { + enum hal_buffer type; + u32 index; + u32 size; + u32 device_addr; + u32 response_required; + u32 client_data; +}; + +struct vidc_buffer_addr_info { + enum hal_buffer buffer_type; + u32 buffer_size; + u32 num_buffers; + u32 align_device_addr; + u32 extradata_addr; + u32 extradata_size; + u32 response_required; +}; + +/* Needs to be exactly the same as hfi_buffer_info */ +struct hal_buffer_info { + u32 buffer_addr; + u32 extra_data_addr; +}; + +struct vidc_frame_plane_config { + u32 left; + u32 top; + u32 width; + u32 height; + u32 stride; + u32 scan_lines; +}; + +struct vidc_uncompressed_frame_config { + struct vidc_frame_plane_config luma_plane; + struct vidc_frame_plane_config chroma_plane; +}; + +struct vidc_frame_data { + enum hal_buffer buffer_type; + u32 device_addr; + u32 extradata_addr; + int64_t timestamp; + u32 flags; + u32 offset; + u32 alloc_len; + u32 filled_len; + u32 mark_target; + u32 mark_data; + u32 clnt_data; + u32 extradata_size; +}; + +struct hal_fw_info { + char version[VENUS_VERSION_LENGTH]; + phys_addr_t base_addr; + int register_base; + int register_size; + int irq; +}; + +enum hal_flush { + HAL_FLUSH_INPUT, + HAL_FLUSH_OUTPUT, + HAL_FLUSH_ALL, + HAL_UNUSED_FLUSH = 0x10000000, +}; + +enum hal_event_type { + HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES, + HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES, + HAL_EVENT_RELEASE_BUFFER_REFERENCE, + HAL_UNUSED_SEQCHG = 0x10000000, +}; + +enum buffer_mode_type { + HAL_BUFFER_MODE_DYNAMIC = 0x100, + HAL_BUFFER_MODE_STATIC = 0x001, +}; + +struct hal_buffer_alloc_mode { + enum hal_buffer buffer_type; + enum buffer_mode_type buffer_mode; +}; + +enum ltr_mode { + HAL_LTR_MODE_DISABLE, + HAL_LTR_MODE_MANUAL, +}; + +struct buffer_requirements { + struct hal_buffer_requirements buffer[HAL_BUFFER_MAX]; +}; + +struct hal_conceal_color { + u32 conceal_color_8bit; + u32 conceal_color_10bit; +}; + +union hal_get_property { + struct hal_batch_info batch_info; + struct hal_uncompressed_format_supported uncompressed_format_supported; + struct hal_interlace_format_supported interlace_format_supported; + struct hal_nal_stream_format_supported nal_stream_format_supported; + struct hal_nal_stream_format_select nal_stream_format_select; + struct hal_multi_view_format multi_view_format; + struct hal_buffer_info buffer_info; + struct hal_buffer_alloc_mode buffer_alloc_mode; + struct buffer_requirements buf_req; + struct hal_conceal_color conceal_color; +}; + +/* HAL Response */ +#define IS_HAL_SYS_CMD(cmd) ((cmd) >= HAL_SYS_INIT_DONE && \ + (cmd) <= HAL_SYS_ERROR) +#define IS_HAL_SESSION_CMD(cmd) ((cmd) >= HAL_SESSION_EVENT_CHANGE && \ + (cmd) <= HAL_SESSION_ERROR) +enum hal_command_response { + /* SYSTEM COMMANDS_DONE*/ + HAL_SYS_INIT_DONE, + HAL_SYS_SET_RESOURCE_DONE, + HAL_SYS_RELEASE_RESOURCE_DONE, + HAL_SYS_PC_PREP_DONE, + HAL_SYS_IDLE, + HAL_SYS_DEBUG, + HAL_SYS_WATCHDOG_TIMEOUT, + HAL_SYS_ERROR, + /* SESSION COMMANDS_DONE */ + HAL_SESSION_EVENT_CHANGE, + HAL_SESSION_LOAD_RESOURCE_DONE, + HAL_SESSION_INIT_DONE, + HAL_SESSION_END_DONE, + HAL_SESSION_ABORT_DONE, + HAL_SESSION_START_DONE, + HAL_SESSION_STOP_DONE, + HAL_SESSION_ETB_DONE, + HAL_SESSION_FTB_DONE, + HAL_SESSION_FLUSH_DONE, + HAL_SESSION_SUSPEND_DONE, + HAL_SESSION_RESUME_DONE, + HAL_SESSION_SET_PROP_DONE, + HAL_SESSION_GET_PROP_DONE, + HAL_SESSION_RELEASE_BUFFER_DONE, + HAL_SESSION_REGISTER_BUFFER_DONE, + HAL_SESSION_UNREGISTER_BUFFER_DONE, + HAL_SESSION_RELEASE_RESOURCE_DONE, + HAL_SESSION_PROPERTY_INFO, + HAL_SESSION_ERROR, + HAL_RESPONSE_UNUSED = 0x10000000, +}; + +struct ubwc_cr_stats_info_type { + u32 cr_stats_info0; + u32 cr_stats_info1; + u32 cr_stats_info2; + u32 cr_stats_info3; + u32 cr_stats_info4; + u32 cr_stats_info5; + u32 cr_stats_info6; +}; + +struct recon_stats_type { + u32 buffer_index; + u32 complexity_number; + struct ubwc_cr_stats_info_type ubwc_stats_info; +}; + +struct vidc_hal_ebd { + u32 timestamp_hi; + u32 timestamp_lo; + u32 flags; + enum vidc_status status; + u32 mark_target; + u32 mark_data; + u32 stats; + u32 offset; + u32 alloc_len; + u32 filled_len; + u32 picture_type; + struct recon_stats_type recon_stats; + u32 packet_buffer; + u32 extra_data_buffer; +}; + +struct vidc_hal_fbd { + u32 stream_id; + u32 view_id; + u32 timestamp_hi; + u32 timestamp_lo; + u32 flags1; + u32 mark_target; + u32 mark_data; + u32 stats; + u32 alloc_len1; + u32 filled_len1; + u32 offset1; + u32 frame_width; + u32 frame_height; + u32 start_x_coord; + u32 start_y_coord; + u32 input_tag; + u32 input_tag1; + u32 picture_type; + u32 packet_buffer1; + u32 extra_data_buffer; + u32 flags2; + u32 alloc_len2; + u32 filled_len2; + u32 offset2; + u32 packet_buffer2; + u32 flags3; + u32 alloc_len3; + u32 filled_len3; + u32 offset3; + u32 packet_buffer3; + enum hal_buffer buffer_type; +}; + +struct msm_vidc_capability { + enum hal_domain domain; + enum hal_video_codec codec; + struct hal_capability_supported cap[CAP_MAX]; +}; + +struct vidc_hal_sys_init_done { + u32 dec_codec_supported; + u32 enc_codec_supported; + u32 max_sessions_supported; +}; + +struct vidc_hal_session_init_done { + struct msm_vidc_capability capability; +}; + +struct msm_vidc_cb_cmd_done { + u32 device_id; + void *session_id; + enum vidc_status status; + u32 size; + union { + struct vidc_resource_hdr resource_hdr; + struct vidc_buffer_addr_info buffer_addr_info; + struct vidc_frame_plane_config frame_plane_config; + struct vidc_uncompressed_frame_config uncompressed_frame_config; + struct vidc_frame_data frame_data; + struct vidc_hal_ebd ebd; + struct vidc_hal_fbd fbd; + struct vidc_hal_sys_init_done sys_init_done; + struct vidc_hal_session_init_done session_init_done; + struct hal_buffer_info buffer_info; + struct vidc_register_buffer regbuf; + struct vidc_unregister_buffer unregbuf; + union hal_get_property property; + enum hal_flush flush_type; + } data; +}; + +struct hal_index_extradata_input_crop_payload { + u32 size; + u32 version; + u32 port_index; + u32 left; + u32 top; + u32 width; + u32 height; +}; + +struct msm_vidc_cb_event { + u32 device_id; + void *session_id; + enum vidc_status status; + u32 height; + u32 width; + int bit_depth; + u32 hal_event_type; + u32 packet_buffer; + u32 extra_data_buffer; + u32 pic_struct; + u32 colour_space; + u32 profile; + u32 level; + u32 entropy_mode; + u32 capture_buf_count; + struct hal_index_extradata_input_crop_payload crop_data; +}; + +struct msm_vidc_cb_data_done { + u32 device_id; + void *session_id; + enum vidc_status status; + u32 size; + u32 clnt_data; + union { + struct vidc_hal_ebd input_done; + struct vidc_hal_fbd output_done; + }; +}; + +struct msm_vidc_cb_info { + enum hal_command_response response_type; + union { + struct msm_vidc_cb_cmd_done cmd; + struct msm_vidc_cb_event event; + struct msm_vidc_cb_data_done data; + } response; +}; + +enum msm_vidc_hfi_type { + VIDC_HFI_VENUS, +}; + +enum msm_vidc_thermal_level { + VIDC_THERMAL_NORMAL = 0, + VIDC_THERMAL_LOW, + VIDC_THERMAL_HIGH, + VIDC_THERMAL_CRITICAL +}; + +enum msm_vidc_power_mode { + VIDC_POWER_NORMAL = 0, + VIDC_POWER_LOW, + VIDC_POWER_TURBO +}; + +struct hal_cmd_sys_get_property_packet { + u32 size; + u32 packet_type; + u32 num_properties; + u32 rg_property_data[1]; +}; + +struct hal_hdr10_pq_sei { + struct msm_vidc_mastering_display_colour_sei_payload disp_color_sei; + struct msm_vidc_content_light_level_sei_payload cll_sei; +}; + +struct hal_vbv_hdr_buf_size { + u32 vbv_hdr_buf_size; +}; + +#define call_hfi_op(q, op, ...) \ + (((q) && (q)->op) ? ((q)->op(__VA_ARGS__)) : 0) + +struct hfi_device { + void *hfi_device_data; + + /*Add function pointers for all the hfi functions below*/ + int (*core_init)(void *device); + int (*core_release)(void *device); + int (*core_trigger_ssr)(void *device, enum hal_ssr_trigger_type); + int (*session_init)(void *device, void *session_id, + enum hal_domain session_type, enum hal_video_codec codec_type, + void **new_session); + int (*session_end)(void *session); + int (*session_abort)(void *session); + int (*session_set_buffers)(void *sess, + struct vidc_buffer_addr_info *buffer_info); + int (*session_release_buffers)(void *sess, + struct vidc_buffer_addr_info *buffer_info); + int (*session_register_buffer)(void *sess, + struct vidc_register_buffer *buffer); + int (*session_unregister_buffer)(void *sess, + struct vidc_unregister_buffer *buffer); + int (*session_load_res)(void *sess); + int (*session_release_res)(void *sess); + int (*session_start)(void *sess); + int (*session_continue)(void *sess); + int (*session_stop)(void *sess); + int (*session_etb)(void *sess, struct vidc_frame_data *input_frame); + int (*session_ftb)(void *sess, struct vidc_frame_data *output_frame); + int (*session_process_batch)(void *sess, + int num_etbs, struct vidc_frame_data etbs[], + int num_ftbs, struct vidc_frame_data ftbs[]); + int (*session_get_buf_req)(void *sess); + int (*session_flush)(void *sess, enum hal_flush flush_mode); + int (*session_set_property)(void *sess, u32 ptype, + void *pdata, u32 size); + int (*session_pause)(void *sess); + int (*session_resume)(void *sess); + int (*scale_clocks)(void *dev, u32 freq); + int (*vote_bus)(void *dev, struct vidc_bus_vote_data *data, + int num_data); + int (*get_fw_info)(void *dev, struct hal_fw_info *fw_info); + int (*session_clean)(void *sess); + int (*get_core_capabilities)(void *dev); + int (*suspend)(void *dev); + int (*flush_debug_queue)(void *dev); + int (*noc_error_info)(void *dev); + enum hal_default_properties (*get_default_properties)(void *dev); +}; + +typedef void (*hfi_cmd_response_callback) (enum hal_command_response cmd, + void *data); +typedef void (*msm_vidc_callback) (u32 response, void *callback); + +struct hfi_device *vidc_hfi_initialize(enum msm_vidc_hfi_type hfi_type, + u32 device_id, struct msm_vidc_platform_resources *res, + hfi_cmd_response_callback callback); +void vidc_hfi_deinitialize(enum msm_vidc_hfi_type hfi_type, + struct hfi_device *hdev); +u32 vidc_get_hfi_domain(enum hal_domain hal_domain); +u32 vidc_get_hfi_codec(enum hal_video_codec hal_codec); +enum hal_domain vidc_get_hal_domain(u32 hfi_domain); +enum hal_video_codec vidc_get_hal_codec(u32 hfi_codec); + +#endif /*__VIDC_HFI_API_H__ */ diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h new file mode 100644 index 000000000000..c7c0aa1f68eb --- /dev/null +++ b/msm/vidc/vidc_hfi_helper.h @@ -0,0 +1,1083 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef __H_VIDC_HFI_HELPER_H__ +#define __H_VIDC_HFI_HELPER_H__ + +#include +#include +#define HFI_COMMON_BASE (0) +#define HFI_OX_BASE (0x01000000) + +#define HFI_VIDEO_DOMAIN_ENCODER (HFI_COMMON_BASE + 0x1) +#define HFI_VIDEO_DOMAIN_DECODER (HFI_COMMON_BASE + 0x2) +#define HFI_VIDEO_DOMAIN_VPE (HFI_COMMON_BASE + 0x4) +#define HFI_VIDEO_DOMAIN_CVP (HFI_COMMON_BASE + 0x8) + +#define HFI_DOMAIN_BASE_COMMON (HFI_COMMON_BASE + 0) +#define HFI_DOMAIN_BASE_VDEC (HFI_COMMON_BASE + 0x01000000) +#define HFI_DOMAIN_BASE_VENC (HFI_COMMON_BASE + 0x02000000) +#define HFI_DOMAIN_BASE_VPE (HFI_COMMON_BASE + 0x03000000) +#define HFI_DOMAIN_BASE_CVP (HFI_COMMON_BASE + 0x04000000) + +#define HFI_VIDEO_ARCH_OX (HFI_COMMON_BASE + 0x1) + +#define HFI_ARCH_COMMON_OFFSET (0) +#define HFI_ARCH_OX_OFFSET (0x00200000) + +#define HFI_CMD_START_OFFSET (0x00010000) +#define HFI_MSG_START_OFFSET (0x00020000) + +#define HFI_ERR_NONE HFI_COMMON_BASE +#define HFI_ERR_SYS_FATAL (HFI_COMMON_BASE + 0x1) +#define HFI_ERR_SYS_INVALID_PARAMETER (HFI_COMMON_BASE + 0x2) +#define HFI_ERR_SYS_VERSION_MISMATCH (HFI_COMMON_BASE + 0x3) +#define HFI_ERR_SYS_INSUFFICIENT_RESOURCES (HFI_COMMON_BASE + 0x4) +#define HFI_ERR_SYS_MAX_SESSIONS_REACHED (HFI_COMMON_BASE + 0x5) +#define HFI_ERR_SYS_UNSUPPORTED_CODEC (HFI_COMMON_BASE + 0x6) +#define HFI_ERR_SYS_SESSION_IN_USE (HFI_COMMON_BASE + 0x7) +#define HFI_ERR_SYS_SESSION_ID_OUT_OF_RANGE (HFI_COMMON_BASE + 0x8) +#define HFI_ERR_SYS_UNSUPPORTED_DOMAIN (HFI_COMMON_BASE + 0x9) +#define HFI_ERR_SYS_NOC_ERROR (HFI_COMMON_BASE + 0x11) +#define HFI_ERR_SESSION_FATAL (HFI_COMMON_BASE + 0x1001) +#define HFI_ERR_SESSION_INVALID_PARAMETER (HFI_COMMON_BASE + 0x1002) +#define HFI_ERR_SESSION_BAD_POINTER (HFI_COMMON_BASE + 0x1003) +#define HFI_ERR_SESSION_INVALID_SESSION_ID (HFI_COMMON_BASE + 0x1004) +#define HFI_ERR_SESSION_INVALID_STREAM_ID (HFI_COMMON_BASE + 0x1005) +#define HFI_ERR_SESSION_INCORRECT_STATE_OPERATION \ + (HFI_COMMON_BASE + 0x1006) +#define HFI_ERR_SESSION_UNSUPPORTED_PROPERTY (HFI_COMMON_BASE + 0x1007) + +#define HFI_ERR_SESSION_UNSUPPORTED_SETTING (HFI_COMMON_BASE + 0x1008) + +#define HFI_ERR_SESSION_INSUFFICIENT_RESOURCES (HFI_COMMON_BASE + 0x1009) + +#define HFI_ERR_SESSION_STREAM_CORRUPT_OUTPUT_STALLED \ + (HFI_COMMON_BASE + 0x100A) + +#define HFI_ERR_SESSION_STREAM_CORRUPT (HFI_COMMON_BASE + 0x100B) +#define HFI_ERR_SESSION_ENC_OVERFLOW (HFI_COMMON_BASE + 0x100C) +#define HFI_ERR_SESSION_UNSUPPORTED_STREAM (HFI_COMMON_BASE + 0x100D) +#define HFI_ERR_SESSION_CMDSIZE (HFI_COMMON_BASE + 0x100E) +#define HFI_ERR_SESSION_UNSUPPORT_CMD (HFI_COMMON_BASE + 0x100F) +#define HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE (HFI_COMMON_BASE + 0x1010) +#define HFI_ERR_SESSION_BUFFERCOUNT_TOOSMALL (HFI_COMMON_BASE + 0x1011) +#define HFI_ERR_SESSION_INVALID_SCALE_FACTOR (HFI_COMMON_BASE + 0x1012) +#define HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED (HFI_COMMON_BASE + 0x1013) + +#define HFI_EVENT_SYS_ERROR (HFI_COMMON_BASE + 0x1) +#define HFI_EVENT_SESSION_ERROR (HFI_COMMON_BASE + 0x2) + +#define HFI_VIDEO_CODEC_H264 0x00000002 +#define HFI_VIDEO_CODEC_MPEG1 0x00000008 +#define HFI_VIDEO_CODEC_MPEG2 0x00000010 +#define HFI_VIDEO_CODEC_VP8 0x00001000 +#define HFI_VIDEO_CODEC_HEVC 0x00002000 +#define HFI_VIDEO_CODEC_VP9 0x00004000 +#define HFI_VIDEO_CODEC_TME 0x00008000 +#define HFI_VIDEO_CODEC_CVP 0x00010000 + +#define HFI_PROFILE_UNKNOWN 0x00000000 +#define HFI_LEVEL_UNKNOWN 0x00000000 + +#define HFI_H264_PROFILE_BASELINE 0x00000001 +#define HFI_H264_PROFILE_MAIN 0x00000002 +#define HFI_H264_PROFILE_HIGH 0x00000004 +#define HFI_H264_PROFILE_STEREO_HIGH 0x00000008 +#define HFI_H264_PROFILE_MULTIVIEW_HIGH 0x00000010 +#define HFI_H264_PROFILE_CONSTRAINED_BASE 0x00000020 +#define HFI_H264_PROFILE_CONSTRAINED_HIGH 0x00000040 + +#define HFI_LEVEL_UNKNOWN 0x00000000 +#define HFI_H264_LEVEL_1 0x00000001 +#define HFI_H264_LEVEL_1b 0x00000002 +#define HFI_H264_LEVEL_11 0x00000004 +#define HFI_H264_LEVEL_12 0x00000008 +#define HFI_H264_LEVEL_13 0x00000010 +#define HFI_H264_LEVEL_2 0x00000020 +#define HFI_H264_LEVEL_21 0x00000040 +#define HFI_H264_LEVEL_22 0x00000080 +#define HFI_H264_LEVEL_3 0x00000100 +#define HFI_H264_LEVEL_31 0x00000200 +#define HFI_H264_LEVEL_32 0x00000400 +#define HFI_H264_LEVEL_4 0x00000800 +#define HFI_H264_LEVEL_41 0x00001000 +#define HFI_H264_LEVEL_42 0x00002000 +#define HFI_H264_LEVEL_5 0x00004000 +#define HFI_H264_LEVEL_51 0x00008000 +#define HFI_H264_LEVEL_52 0x00010000 +#define HFI_H264_LEVEL_6 0x00020000 +#define HFI_H264_LEVEL_61 0x00040000 +#define HFI_H264_LEVEL_62 0x00080000 + +#define HFI_MPEG2_PROFILE_SIMPLE 0x00000001 +#define HFI_MPEG2_PROFILE_MAIN 0x00000002 + +#define HFI_MPEG2_LEVEL_LL 0x00000001 +#define HFI_MPEG2_LEVEL_ML 0x00000002 +#define HFI_MPEG2_LEVEL_HL 0x00000004 + +#define HFI_VP8_PROFILE_MAIN 0x00000001 + +#define HFI_VP8_LEVEL_VERSION_0 0x00000001 +#define HFI_VP8_LEVEL_VERSION_1 0x00000002 +#define HFI_VP8_LEVEL_VERSION_2 0x00000004 +#define HFI_VP8_LEVEL_VERSION_3 0x00000008 + +#define HFI_VP9_PROFILE_P0 0x00000001 +#define HFI_VP9_PROFILE_P2_10B 0x00000004 + +#define HFI_VP9_LEVEL_1 0x00000001 +#define HFI_VP9_LEVEL_11 0x00000002 +#define HFI_VP9_LEVEL_2 0x00000004 +#define HFI_VP9_LEVEL_21 0x00000008 +#define HFI_VP9_LEVEL_3 0x00000010 +#define HFI_VP9_LEVEL_31 0x00000020 +#define HFI_VP9_LEVEL_4 0x00000040 +#define HFI_VP9_LEVEL_41 0x00000080 +#define HFI_VP9_LEVEL_5 0x00000100 +#define HFI_VP9_LEVEL_51 0x00000200 +#define HFI_VP9_LEVEL_6 0x00000400 +#define HFI_VP9_LEVEL_61 0x00000800 + +#define HFI_HEVC_PROFILE_MAIN 0x00000001 +#define HFI_HEVC_PROFILE_MAIN10 0x00000002 +#define HFI_HEVC_PROFILE_MAIN_STILL_PIC 0x00000004 + +#define HFI_HEVC_LEVEL_1 0x00000001 +#define HFI_HEVC_LEVEL_2 0x00000002 +#define HFI_HEVC_LEVEL_21 0x00000004 +#define HFI_HEVC_LEVEL_3 0x00000008 +#define HFI_HEVC_LEVEL_31 0x00000010 +#define HFI_HEVC_LEVEL_4 0x00000020 +#define HFI_HEVC_LEVEL_41 0x00000040 +#define HFI_HEVC_LEVEL_5 0x00000080 +#define HFI_HEVC_LEVEL_51 0x00000100 +#define HFI_HEVC_LEVEL_52 0x00000200 +#define HFI_HEVC_LEVEL_6 0x00000400 +#define HFI_HEVC_LEVEL_61 0x00000800 +#define HFI_HEVC_LEVEL_62 0x00001000 + +#define HFI_HEVC_TIER_MAIN 0x1 +#define HFI_HEVC_TIER_HIGH 0x2 + +#define HFI_TME_PROFILE_DEFAULT 0x00000001 +#define HFI_TME_PROFILE_FRC 0x00000002 +#define HFI_TME_PROFILE_ASW 0x00000004 +#define HFI_TME_PROFILE_DFS_BOKEH 0x00000008 + +#define HFI_TME_LEVEL_INTEGER 0x00000001 + +#define HFI_BUFFER_INPUT (HFI_COMMON_BASE + 0x1) +#define HFI_BUFFER_OUTPUT (HFI_COMMON_BASE + 0x2) +#define HFI_BUFFER_OUTPUT2 (HFI_COMMON_BASE + 0x3) +#define HFI_BUFFER_INTERNAL_PERSIST (HFI_COMMON_BASE + 0x4) +#define HFI_BUFFER_INTERNAL_PERSIST_1 (HFI_COMMON_BASE + 0x5) +#define HFI_BUFFER_COMMON_INTERNAL_SCRATCH (HFI_COMMON_BASE + 0x6) +#define HFI_BUFFER_COMMON_INTERNAL_SCRATCH_1 (HFI_COMMON_BASE + 0x7) +#define HFI_BUFFER_COMMON_INTERNAL_SCRATCH_2 (HFI_COMMON_BASE + 0x8) +#define HFI_BUFFER_COMMON_INTERNAL_RECON (HFI_COMMON_BASE + 0x9) +#define HFI_BUFFER_EXTRADATA_OUTPUT (HFI_COMMON_BASE + 0xA) +#define HFI_BUFFER_EXTRADATA_OUTPUT2 (HFI_COMMON_BASE + 0xB) +#define HFI_BUFFER_EXTRADATA_INPUT (HFI_COMMON_BASE + 0xC) + +#define HFI_BITDEPTH_8 (HFI_COMMON_BASE + 0x0) +#define HFI_BITDEPTH_9 (HFI_COMMON_BASE + 0x1) +#define HFI_BITDEPTH_10 (HFI_COMMON_BASE + 0x2) + +#define HFI_VENC_PERFMODE_MAX_QUALITY 0x1 +#define HFI_VENC_PERFMODE_POWER_SAVE 0x2 + +#define HFI_WORKMODE_1 (HFI_COMMON_BASE + 0x1) +#define HFI_WORKMODE_2 (HFI_COMMON_BASE + 0x2) + +struct hfi_buffer_info { + u32 buffer_addr; + u32 extra_data_addr; +}; + +#define HFI_PROPERTY_SYS_COMMON_START \ + (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + 0x0000) +#define HFI_PROPERTY_SYS_DEBUG_CONFIG \ + (HFI_PROPERTY_SYS_COMMON_START + 0x001) +#define HFI_PROPERTY_SYS_RESOURCE_OCMEM_REQUIREMENT_INFO \ + (HFI_PROPERTY_SYS_COMMON_START + 0x002) +#define HFI_PROPERTY_SYS_CONFIG_VCODEC_CLKFREQ \ + (HFI_PROPERTY_SYS_COMMON_START + 0x003) +#define HFI_PROPERTY_SYS_IDLE_INDICATOR \ + (HFI_PROPERTY_SYS_COMMON_START + 0x004) +#define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL \ + (HFI_PROPERTY_SYS_COMMON_START + 0x005) +#define HFI_PROPERTY_SYS_IMAGE_VERSION \ + (HFI_PROPERTY_SYS_COMMON_START + 0x006) +#define HFI_PROPERTY_SYS_CONFIG_COVERAGE \ + (HFI_PROPERTY_SYS_COMMON_START + 0x007) +#define HFI_PROPERTY_SYS_UBWC_CONFIG \ + (HFI_PROPERTY_SYS_COMMON_START + 0x008) + +#define HFI_PROPERTY_PARAM_COMMON_START \ + (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + 0x1000) +#define HFI_PROPERTY_PARAM_FRAME_SIZE \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x001) +#define HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x002) +#define HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x003) +#define HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x004) +#define HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x005) +#define HFI_PROPERTY_PARAM_PROFILE_LEVEL_SUPPORTED \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x006) +#define HFI_PROPERTY_PARAM_CAPABILITY_SUPPORTED \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x007) +#define HFI_PROPERTY_PARAM_PROPERTIES_SUPPORTED \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x008) +#define HFI_PROPERTY_PARAM_CODEC_SUPPORTED \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x009) +#define HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SUPPORTED \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x00A) +#define HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x00B) +#define HFI_PROPERTY_PARAM_MULTI_VIEW_FORMAT \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x00C) +#define HFI_PROPERTY_PARAM_CODEC_MASK_SUPPORTED \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x00E) +#define HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x010) +#define HFI_PROPERTY_PARAM_SECURE_SESSION \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x011) +#define HFI_PROPERTY_PARAM_WORK_MODE \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x015) +#define HFI_PROPERTY_TME_VERSION_SUPPORTED \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x016) +#define HFI_PROPERTY_PARAM_WORK_ROUTE \ + (HFI_PROPERTY_PARAM_COMMON_START + 0x017) + +#define HFI_PROPERTY_CONFIG_COMMON_START \ + (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + 0x2000) +#define HFI_PROPERTY_CONFIG_FRAME_RATE \ + (HFI_PROPERTY_CONFIG_COMMON_START + 0x001) +#define HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE \ + (HFI_PROPERTY_CONFIG_COMMON_START + 0x002) +#define HFI_PROPERTY_CONFIG_OPERATING_RATE \ + (HFI_PROPERTY_CONFIG_COMMON_START + 0x003) + +#define HFI_PROPERTY_PARAM_VDEC_COMMON_START \ + (HFI_DOMAIN_BASE_VDEC + HFI_ARCH_COMMON_OFFSET + 0x3000) +#define HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM \ + (HFI_PROPERTY_PARAM_VDEC_COMMON_START + 0x001) +#define HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR \ + (HFI_PROPERTY_PARAM_VDEC_COMMON_START + 0x002) +#define HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH \ + (HFI_PROPERTY_PARAM_VDEC_COMMON_START + 0x007) +#define HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT \ + (HFI_PROPERTY_PARAM_VDEC_COMMON_START + 0x009) +#define HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE \ + (HFI_PROPERTY_PARAM_VDEC_COMMON_START + 0x00A) + + +#define HFI_PROPERTY_CONFIG_VDEC_COMMON_START \ + (HFI_DOMAIN_BASE_VDEC + HFI_ARCH_COMMON_OFFSET + 0x4000) + +#define HFI_PROPERTY_PARAM_VENC_COMMON_START \ + (HFI_DOMAIN_BASE_VENC + HFI_ARCH_COMMON_OFFSET + 0x5000) +#define HFI_PROPERTY_PARAM_VENC_SLICE_DELIVERY_MODE \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x001) +#define HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x002) +#define HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x003) +#define HFI_PROPERTY_PARAM_VENC_RATE_CONTROL \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x004) +#define HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x009) +#define HFI_PROPERTY_PARAM_VENC_OPEN_GOP \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x00C) +#define HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x00D) +#define HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_CONTROL \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x00E) +#define HFI_PROPERTY_PARAM_VENC_VBV_HRD_BUF_SIZE \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x00F) +#define HFI_PROPERTY_PARAM_VENC_QUALITY_VS_SPEED \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x010) +#define HFI_PROPERTY_PARAM_VENC_H264_SPS_ID \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x014) +#define HFI_PROPERTY_PARAM_VENC_H264_PPS_ID \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x015) +#define HFI_PROPERTY_PARAM_VENC_GENERATE_AUDNAL \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x016) +#define HFI_PROPERTY_PARAM_VENC_ASPECT_RATIO \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x017) +#define HFI_PROPERTY_PARAM_VENC_NUMREF \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x018) +#define HFI_PROPERTY_PARAM_VENC_LTRMODE \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01C) +#define HFI_PROPERTY_PARAM_VENC_VIDEO_SIGNAL_INFO \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01D) +#define HFI_PROPERTY_PARAM_VENC_VUI_TIMING_INFO \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01E) +#define HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x022) +#define HFI_PROPERTY_PARAM_VENC_PRESERVE_TEXT_QUALITY \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x023) +#define HFI_PROPERTY_PARAM_VENC_H264_8X8_TRANSFORM \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x025) +#define HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x026) +#define HFI_PROPERTY_PARAM_VENC_DISABLE_RC_TIMESTAMP \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x027) +#define HFI_PROPERTY_PARAM_VENC_VPX_ERROR_RESILIENCE_MODE \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x029) +#define HFI_PROPERTY_PARAM_VENC_HIER_B_MAX_NUM_ENH_LAYER \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x02C) +#define HFI_PROPERTY_PARAM_VENC_HIER_P_HYBRID_MODE \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x02F) +#define HFI_PROPERTY_PARAM_VENC_BITRATE_TYPE \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x031) +#define HFI_PROPERTY_PARAM_VENC_IFRAMESIZE \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x034) +#define HFI_PROPERTY_PARAM_VENC_SEND_OUTPUT_FOR_SKIPPED_FRAMES \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x035) +#define HFI_PROPERTY_PARAM_VENC_HDR10_PQ_SEI \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x036) +#define HFI_PROPERTY_PARAM_VENC_ADAPTIVE_B \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x037) +#define HFI_PROPERTY_PARAM_VENC_BITRATE_SAVINGS \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x038) +#define HFI_PROPERTY_PARAM_VENC_LOSSLESS_ENCODING \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x039) + +#define HFI_PROPERTY_CONFIG_VENC_COMMON_START \ + (HFI_DOMAIN_BASE_VENC + HFI_ARCH_COMMON_OFFSET + 0x6000) +#define HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x001) +#define HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x002) +#define HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x003) +#define HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x004) +#define HFI_PROPERTY_CONFIG_VENC_SLICE_SIZE \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x005) +#define HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x008) +#define HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x009) +#define HFI_PROPERTY_CONFIG_VENC_USELTRFRAME \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x00A) +#define HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x00B) +#define HFI_PROPERTY_CONFIG_VENC_VBV_HRD_BUF_SIZE \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x00D) +#define HFI_PROPERTY_CONFIG_VENC_PERF_MODE \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x00E) +#define HFI_PROPERTY_CONFIG_VENC_BASELAYER_PRIORITYID \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x00F) +#define HFI_PROPERTY_CONFIG_VENC_BLUR_FRAME_SIZE \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x010) +#define HFI_PROPERTY_CONFIG_VENC_FRAME_QP \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x012) +#define HFI_PROPERTY_CONFIG_HEIC_FRAME_CROP_INFO \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x013) +#define HFI_PROPERTY_CONFIG_HEIC_FRAME_QUALITY \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x014) +#define HFI_PROPERTY_CONFIG_HEIC_GRID_ENABLE \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x015) + +#define HFI_PROPERTY_PARAM_VPE_COMMON_START \ + (HFI_DOMAIN_BASE_VPE + HFI_ARCH_COMMON_OFFSET + 0x7000) +#define HFI_PROPERTY_PARAM_VPE_ROTATION \ + (HFI_PROPERTY_PARAM_VPE_COMMON_START + 0x001) +#define HFI_PROPERTY_PARAM_VPE_COLOR_SPACE_CONVERSION \ + (HFI_PROPERTY_PARAM_VPE_COMMON_START + 0x002) + +#define HFI_PROPERTY_CONFIG_VPE_COMMON_START \ + (HFI_DOMAIN_BASE_VPE + HFI_ARCH_COMMON_OFFSET + 0x8000) + +struct hfi_pic_struct { + u32 progressive_only; +}; + +struct hfi_bitrate { + u32 bit_rate; + u32 layer_id; +}; + +struct hfi_colour_space { + u32 colour_space; +}; + +#define HFI_CAPABILITY_FRAME_WIDTH (HFI_COMMON_BASE + 0x1) +#define HFI_CAPABILITY_FRAME_HEIGHT (HFI_COMMON_BASE + 0x2) +#define HFI_CAPABILITY_MBS_PER_FRAME (HFI_COMMON_BASE + 0x3) +#define HFI_CAPABILITY_MBS_PER_SECOND (HFI_COMMON_BASE + 0x4) +#define HFI_CAPABILITY_FRAMERATE (HFI_COMMON_BASE + 0x5) +#define HFI_CAPABILITY_SCALE_X (HFI_COMMON_BASE + 0x6) +#define HFI_CAPABILITY_SCALE_Y (HFI_COMMON_BASE + 0x7) +#define HFI_CAPABILITY_BITRATE (HFI_COMMON_BASE + 0x8) +#define HFI_CAPABILITY_BFRAME (HFI_COMMON_BASE + 0x9) +#define HFI_CAPABILITY_PEAKBITRATE (HFI_COMMON_BASE + 0xa) +#define HFI_CAPABILITY_HIER_P_NUM_ENH_LAYERS (HFI_COMMON_BASE + 0x10) +#define HFI_CAPABILITY_ENC_LTR_COUNT (HFI_COMMON_BASE + 0x11) +#define HFI_CAPABILITY_CP_OUTPUT2_THRESH (HFI_COMMON_BASE + 0x12) +#define HFI_CAPABILITY_HIER_B_NUM_ENH_LAYERS (HFI_COMMON_BASE + 0x13) +#define HFI_CAPABILITY_LCU_SIZE (HFI_COMMON_BASE + 0x14) +#define HFI_CAPABILITY_HIER_P_HYBRID_NUM_ENH_LAYERS (HFI_COMMON_BASE + 0x15) +#define HFI_CAPABILITY_MBS_PER_SECOND_POWERSAVE (HFI_COMMON_BASE + 0x16) +#define HFI_CAPABILITY_EXTRADATA (HFI_COMMON_BASE + 0X17) +#define HFI_CAPABILITY_PROFILE (HFI_COMMON_BASE + 0X18) +#define HFI_CAPABILITY_LEVEL (HFI_COMMON_BASE + 0X19) +#define HFI_CAPABILITY_I_FRAME_QP (HFI_COMMON_BASE + 0X20) +#define HFI_CAPABILITY_P_FRAME_QP (HFI_COMMON_BASE + 0X21) +#define HFI_CAPABILITY_B_FRAME_QP (HFI_COMMON_BASE + 0X22) +#define HFI_CAPABILITY_RATE_CONTROL_MODES (HFI_COMMON_BASE + 0X23) +#define HFI_CAPABILITY_BLUR_WIDTH (HFI_COMMON_BASE + 0X24) +#define HFI_CAPABILITY_BLUR_HEIGHT (HFI_COMMON_BASE + 0X25) +#define HFI_CAPABILITY_SLICE_DELIVERY_MODES (HFI_COMMON_BASE + 0X26) +#define HFI_CAPABILITY_SLICE_BYTE (HFI_COMMON_BASE + 0X27) +#define HFI_CAPABILITY_SLICE_MB (HFI_COMMON_BASE + 0X28) +#define HFI_CAPABILITY_SECURE (HFI_COMMON_BASE + 0X29) +#define HFI_CAPABILITY_MAX_NUM_B_FRAMES (HFI_COMMON_BASE + 0X2A) +#define HFI_CAPABILITY_MAX_VIDEOCORES (HFI_COMMON_BASE + 0X2B) +#define HFI_CAPABILITY_MAX_WORKMODES (HFI_COMMON_BASE + 0X2C) +#define HFI_CAPABILITY_UBWC_CR_STATS (HFI_COMMON_BASE + 0X2D) +#define HFI_CAPABILITY_MAX_WORKROUTES (HFI_COMMON_BASE + 0X31) +#define HFI_CAPABILITY_CQ_QUALITY_LEVEL (HFI_COMMON_BASE + 0X32) + + +#define HFI_DEBUG_MSG_LOW 0x00000001 +#define HFI_DEBUG_MSG_MEDIUM 0x00000002 +#define HFI_DEBUG_MSG_HIGH 0x00000004 +#define HFI_DEBUG_MSG_ERROR 0x00000008 +#define HFI_DEBUG_MSG_FATAL 0x00000010 +#define HFI_DEBUG_MSG_PERF 0x00000020 + +#define HFI_DEBUG_MODE_QUEUE 0x00000001 +#define HFI_DEBUG_MODE_QDSS 0x00000002 + +struct hfi_debug_config { + u32 debug_config; + u32 debug_mode; +}; + +struct hfi_enable { + u32 enable; +}; + +#define HFI_H264_DB_MODE_DISABLE (HFI_COMMON_BASE + 0x1) +#define HFI_H264_DB_MODE_SKIP_SLICE_BOUNDARY \ + (HFI_COMMON_BASE + 0x2) +#define HFI_H264_DB_MODE_ALL_BOUNDARY (HFI_COMMON_BASE + 0x3) + +struct hfi_h264_db_control { + u32 mode; + u32 slice_alpha_offset; + u32 slice_beta_offset; +}; + +#define HFI_H264_ENTROPY_CAVLC (HFI_COMMON_BASE + 0x1) +#define HFI_H264_ENTROPY_CABAC (HFI_COMMON_BASE + 0x2) + +#define HFI_H264_CABAC_MODEL_0 (HFI_COMMON_BASE + 0x1) +#define HFI_H264_CABAC_MODEL_1 (HFI_COMMON_BASE + 0x2) +#define HFI_H264_CABAC_MODEL_2 (HFI_COMMON_BASE + 0x3) + +struct hfi_h264_entropy_control { + u32 entropy_mode; + u32 cabac_model; +}; + +struct hfi_frame_rate { + u32 buffer_type; + u32 frame_rate; +}; + +struct hfi_heic_frame_quality { + u32 frame_quality; + u32 reserved[3]; +}; + +struct hfi_heic_grid_enable { + u32 grid_enable; +}; + +struct hfi_operating_rate { + u32 operating_rate; +}; + +#define HFI_INTRA_REFRESH_NONE (HFI_COMMON_BASE + 0x1) +#define HFI_INTRA_REFRESH_CYCLIC (HFI_COMMON_BASE + 0x2) +#define HFI_INTRA_REFRESH_RANDOM (HFI_COMMON_BASE + 0x5) + +struct hfi_intra_refresh { + u32 mode; + u32 mbs; +}; + +struct hfi_idr_period { + u32 idr_period; +}; + +struct hfi_vpe_rotation_type { + u32 rotation; + u32 flip; +}; + +struct hfi_conceal_color { + u32 conceal_color_8bit; + u32 conceal_color_10bit; +}; + +struct hfi_intra_period { + u32 pframes; + u32 bframes; +}; + +struct hfi_multi_stream { + u32 buffer_type; + u32 enable; +}; + +#define HFI_MULTI_SLICE_OFF (HFI_COMMON_BASE + 0x1) +#define HFI_MULTI_SLICE_BY_MB_COUNT (HFI_COMMON_BASE + 0x2) +#define HFI_MULTI_SLICE_BY_BYTE_COUNT (HFI_COMMON_BASE + 0x3) + +struct hfi_multi_slice_control { + u32 multi_slice; + u32 slice_size; +}; + +#define HFI_NAL_FORMAT_STARTCODES 0x00000001 +#define HFI_NAL_FORMAT_ONE_NAL_PER_BUFFER 0x00000002 +#define HFI_NAL_FORMAT_ONE_BYTE_LENGTH 0x00000004 +#define HFI_NAL_FORMAT_TWO_BYTE_LENGTH 0x00000008 +#define HFI_NAL_FORMAT_FOUR_BYTE_LENGTH 0x00000010 + +struct hfi_nal_stream_format_supported { + u32 nal_stream_format_supported; +}; + +struct hfi_nal_stream_format_select { + u32 nal_stream_format_select; +}; +#define HFI_PICTURE_TYPE_I 0x01 +#define HFI_PICTURE_TYPE_P 0x02 +#define HFI_PICTURE_TYPE_B 0x04 +#define HFI_PICTURE_TYPE_IDR 0x08 +#define HFI_PICTURE_TYPE_CRA 0x10 +#define HFI_FRAME_NOTCODED 0x7F002000 +#define HFI_FRAME_YUV 0x7F004000 +#define HFI_UNUSED_PICT 0x10000000 + +struct hfi_profile_level { + u32 profile; + u32 level; +}; + +struct hfi_profile_level_supported { + u32 profile_count; + struct hfi_profile_level rg_profile_level[1]; +}; + +struct hfi_quality_vs_speed { + u32 quality_vs_speed; +}; + +struct hfi_quantization { + u32 qp_packed; + u32 layer_id; + u32 enable; + u32 reserved[3]; +}; + +struct hfi_quantization_range { + struct hfi_quantization min_qp; + struct hfi_quantization max_qp; + u32 reserved[4]; +}; + +#define HFI_LTR_MODE_DISABLE 0x0 +#define HFI_LTR_MODE_MANUAL 0x1 + +struct hfi_ltr_mode { + u32 ltr_mode; + u32 ltr_count; + u32 trust_mode; +}; + +struct hfi_ltr_use { + u32 ref_ltr; + u32 use_constrnt; + u32 frames; +}; + +struct hfi_ltr_mark { + u32 mark_frame; +}; + +struct hfi_frame_size { + u32 buffer_type; + u32 width; + u32 height; +}; + +struct hfi_videocores_usage_type { + u32 video_core_enable_mask; +}; + +struct hfi_video_work_mode { + u32 video_work_mode; +}; + +struct hfi_video_work_route { + u32 video_work_route; +}; + +struct hfi_video_signal_metadata { + u32 enable; + u32 video_format; + u32 video_full_range; + u32 color_description; + u32 color_primaries; + u32 transfer_characteristics; + u32 matrix_coeffs; +}; + +struct hfi_vui_timing_info { + u32 enable; + u32 fixed_frame_rate; + u32 time_scale; +}; + +struct hfi_bit_depth { + u32 buffer_type; + u32 bit_depth; +}; + +struct hfi_picture_type { + u32 is_sync_frame; + u32 picture_type; +}; + +/* Base Offset for UBWC color formats */ +#define HFI_COLOR_FORMAT_UBWC_BASE (0x8000) +/* Base Offset for 10-bit color formats */ +#define HFI_COLOR_FORMAT_10_BIT_BASE (0x4000) + +#define HFI_COLOR_FORMAT_NV12 (HFI_COMMON_BASE + 0x2) +#define HFI_COLOR_FORMAT_NV21 (HFI_COMMON_BASE + 0x3) +#define HFI_COLOR_FORMAT_RGBA8888 (HFI_COMMON_BASE + 0x10) + +#define HFI_COLOR_FORMAT_YUV420_TP10 \ + (HFI_COLOR_FORMAT_10_BIT_BASE + HFI_COLOR_FORMAT_NV12) +#define HFI_COLOR_FORMAT_P010 \ + (HFI_COLOR_FORMAT_10_BIT_BASE + HFI_COLOR_FORMAT_NV12 + 0x1) + +#define HFI_COLOR_FORMAT_NV12_UBWC \ + (HFI_COLOR_FORMAT_UBWC_BASE + HFI_COLOR_FORMAT_NV12) + +#define HFI_COLOR_FORMAT_YUV420_TP10_UBWC \ + (HFI_COLOR_FORMAT_UBWC_BASE + HFI_COLOR_FORMAT_YUV420_TP10) + +#define HFI_COLOR_FORMAT_RGBA8888_UBWC \ + (HFI_COLOR_FORMAT_UBWC_BASE + HFI_COLOR_FORMAT_RGBA8888) + +#define HFI_MAX_MATRIX_COEFFS 9 +#define HFI_MAX_BIAS_COEFFS 3 +#define HFI_MAX_LIMIT_COEFFS 6 + +struct hfi_uncompressed_format_select { + u32 buffer_type; + u32 format; +}; + +struct hfi_uncompressed_format_supported { + u32 buffer_type; + u32 format_entries; + u32 rg_format_info[1]; +}; + +struct hfi_uncompressed_plane_actual { + u32 actual_stride; + u32 actual_plane_buffer_height; +}; + +struct hfi_uncompressed_plane_actual_info { + u32 buffer_type; + u32 num_planes; + struct hfi_uncompressed_plane_actual rg_plane_format[1]; +}; + +struct hfi_uncompressed_plane_constraints { + u32 stride_multiples; + u32 max_stride; + u32 min_plane_buffer_height_multiple; + u32 buffer_alignment; +}; + +struct hfi_uncompressed_plane_info { + u32 format; + u32 num_planes; + struct hfi_uncompressed_plane_constraints rg_plane_format[1]; +}; + +struct hfi_vpe_color_space_conversion { + u32 input_color_primaries; + u32 custom_matrix_enabled; + u32 csc_matrix[HFI_MAX_MATRIX_COEFFS]; + u32 csc_bias[HFI_MAX_BIAS_COEFFS]; + u32 csc_limit[HFI_MAX_LIMIT_COEFFS]; +}; + +#define HFI_ROTATE_NONE (HFI_COMMON_BASE + 0x1) +#define HFI_ROTATE_90 (HFI_COMMON_BASE + 0x2) +#define HFI_ROTATE_180 (HFI_COMMON_BASE + 0x3) +#define HFI_ROTATE_270 (HFI_COMMON_BASE + 0x4) + +#define HFI_FLIP_NONE (HFI_COMMON_BASE + 0x1) +#define HFI_FLIP_HORIZONTAL (HFI_COMMON_BASE + 0x2) +#define HFI_FLIP_VERTICAL (HFI_COMMON_BASE + 0x4) + +#define HFI_RESOURCE_SYSCACHE 0x00000002 + +struct hfi_resource_subcache_type { + u32 size; + u32 sc_id; +}; + +struct hfi_resource_syscache_info_type { + u32 num_entries; + struct hfi_resource_subcache_type rg_subcache_entries[1]; +}; + +struct hfi_property_sys_image_version_info_type { + u32 string_size; + u8 str_image_version[1]; +}; + +struct hfi_vbv_hrd_bufsize { + u32 buffer_size; +}; + +struct hfi_codec_mask_supported { + u32 codecs; + u32 video_domains; +}; + +struct hfi_aspect_ratio { + u32 aspect_width; + u32 aspect_height; +}; + +#define HFI_CMD_SYS_COMMON_START \ +(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + HFI_CMD_START_OFFSET \ + + 0x0000) +#define HFI_CMD_SYS_INIT (HFI_CMD_SYS_COMMON_START + 0x001) +#define HFI_CMD_SYS_PC_PREP (HFI_CMD_SYS_COMMON_START + 0x002) +#define HFI_CMD_SYS_SET_RESOURCE (HFI_CMD_SYS_COMMON_START + 0x003) +#define HFI_CMD_SYS_RELEASE_RESOURCE (HFI_CMD_SYS_COMMON_START + 0x004) +#define HFI_CMD_SYS_SET_PROPERTY (HFI_CMD_SYS_COMMON_START + 0x005) +#define HFI_CMD_SYS_GET_PROPERTY (HFI_CMD_SYS_COMMON_START + 0x006) +#define HFI_CMD_SYS_SESSION_INIT (HFI_CMD_SYS_COMMON_START + 0x007) +#define HFI_CMD_SYS_SESSION_END (HFI_CMD_SYS_COMMON_START + 0x008) +#define HFI_CMD_SYS_SET_BUFFERS (HFI_CMD_SYS_COMMON_START + 0x009) +#define HFI_CMD_SYS_TEST_START (HFI_CMD_SYS_COMMON_START + 0x100) + +#define HFI_CMD_SESSION_COMMON_START \ + (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + \ + HFI_CMD_START_OFFSET + 0x1000) +#define HFI_CMD_SESSION_SET_PROPERTY \ + (HFI_CMD_SESSION_COMMON_START + 0x001) +#define HFI_CMD_SESSION_SET_BUFFERS \ + (HFI_CMD_SESSION_COMMON_START + 0x002) +#define HFI_CMD_SESSION_GET_SEQUENCE_HEADER \ + (HFI_CMD_SESSION_COMMON_START + 0x003) + +#define HFI_MSG_SYS_COMMON_START \ + (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + \ + HFI_MSG_START_OFFSET + 0x0000) +#define HFI_MSG_SYS_INIT_DONE (HFI_MSG_SYS_COMMON_START + 0x1) +#define HFI_MSG_SYS_PC_PREP_DONE (HFI_MSG_SYS_COMMON_START + 0x2) +#define HFI_MSG_SYS_RELEASE_RESOURCE (HFI_MSG_SYS_COMMON_START + 0x3) +#define HFI_MSG_SYS_DEBUG (HFI_MSG_SYS_COMMON_START + 0x4) +#define HFI_MSG_SYS_SESSION_INIT_DONE (HFI_MSG_SYS_COMMON_START + 0x6) +#define HFI_MSG_SYS_SESSION_END_DONE (HFI_MSG_SYS_COMMON_START + 0x7) +#define HFI_MSG_SYS_IDLE (HFI_MSG_SYS_COMMON_START + 0x8) +#define HFI_MSG_SYS_COV (HFI_MSG_SYS_COMMON_START + 0x9) +#define HFI_MSG_SYS_PROPERTY_INFO (HFI_MSG_SYS_COMMON_START + 0xA) +#define HFI_MSG_SESSION_SYNC_DONE (HFI_MSG_SESSION_OX_START + 0xD) + +#define HFI_MSG_SESSION_COMMON_START \ + (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + \ + HFI_MSG_START_OFFSET + 0x1000) +#define HFI_MSG_EVENT_NOTIFY (HFI_MSG_SESSION_COMMON_START + 0x1) +#define HFI_MSG_SESSION_GET_SEQUENCE_HEADER_DONE \ + (HFI_MSG_SESSION_COMMON_START + 0x2) + +#define HFI_CMD_SYS_TEST_SSR (HFI_CMD_SYS_TEST_START + 0x1) +#define HFI_TEST_SSR_SW_ERR_FATAL 0x1 +#define HFI_TEST_SSR_SW_DIV_BY_ZERO 0x2 +#define HFI_TEST_SSR_HW_WDOG_IRQ 0x3 + +struct vidc_hal_cmd_pkt_hdr { + u32 size; + u32 packet_type; +}; + +struct vidc_hal_msg_pkt_hdr { + u32 size; + u32 packet; +}; + +struct vidc_hal_session_cmd_pkt { + u32 size; + u32 packet_type; + u32 session_id; +}; + +struct hfi_cmd_sys_init_packet { + u32 size; + u32 packet_type; + u32 arch_type; +}; + +struct hfi_cmd_sys_pc_prep_packet { + u32 size; + u32 packet_type; +}; + +struct hfi_cmd_sys_set_resource_packet { + u32 size; + u32 packet_type; + u32 resource_handle; + u32 resource_type; + u32 rg_resource_data[1]; +}; + +struct hfi_cmd_sys_release_resource_packet { + u32 size; + u32 packet_type; + u32 resource_type; + u32 resource_handle; +}; + +struct hfi_cmd_sys_set_property_packet { + u32 size; + u32 packet_type; + u32 num_properties; + u32 rg_property_data[1]; +}; + +struct hfi_cmd_sys_get_property_packet { + u32 size; + u32 packet_type; + u32 num_properties; + u32 rg_property_data[1]; +}; + +struct hfi_cmd_sys_session_init_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 session_domain; + u32 session_codec; +}; + +struct hfi_cmd_sys_session_end_packet { + u32 size; + u32 packet_type; + u32 session_id; +}; + +struct hfi_cmd_sys_set_buffers_packet { + u32 size; + u32 packet_type; + u32 buffer_type; + u32 buffer_size; + u32 num_buffers; + u32 rg_buffer_addr[1]; +}; + +struct hfi_cmd_sys_set_ubwc_config_packet_type { + u32 size; + u32 packet_type; + struct { + u32 max_channel_override : 1; + u32 mal_length_override : 1; + u32 hb_override : 1; + u32 bank_swzl_level_override : 1; + u32 bank_spreading_override : 1; + u32 reserved : 27; + } override_bit_info; + u32 max_channels; + u32 mal_length; + u32 highest_bank_bit; + u32 bank_swzl_level; + u32 bank_spreading; + u32 reserved[2]; +}; + +struct hfi_cmd_session_set_property_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 num_properties; + u32 rg_property_data[1]; +}; + +struct hfi_cmd_session_set_buffers_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 buffer_type; + u32 buffer_size; + u32 extra_data_size; + u32 min_buffer_size; + u32 num_buffers; + u32 rg_buffer_info[1]; +}; + +struct hfi_buffer_mapping_type { + u32 index; + u32 device_addr; + u32 size; +}; + +struct hfi_cmd_session_register_buffers_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 client_data; + u32 response_req; + u32 num_buffers; + struct hfi_buffer_mapping_type buffer[1]; +}; + +struct hfi_cmd_session_unregister_buffers_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 client_data; + u32 response_req; + u32 num_buffers; + struct hfi_buffer_mapping_type buffer[1]; +}; + +struct hfi_cmd_session_sync_process_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 sync_id; + u32 rg_data[1]; +}; + +struct hfi_msg_event_notify_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 event_id; + u32 event_data1; + u32 event_data2; + u32 rg_ext_event_data[1]; +}; + +struct hfi_msg_release_buffer_ref_event_packet { + u32 packet_buffer; + u32 extra_data_buffer; + u32 output_tag; +}; + +struct hfi_msg_sys_init_done_packet { + u32 size; + u32 packet_type; + u32 error_type; + u32 num_properties; + u32 rg_property_data[1]; +}; + +struct hfi_msg_sys_pc_prep_done_packet { + u32 size; + u32 packet_type; + u32 error_type; +}; + +struct hfi_msg_sys_release_resource_done_packet { + u32 size; + u32 packet_type; + u32 resource_handle; + u32 error_type; +}; + +struct hfi_msg_sys_session_init_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; + u32 num_properties; + u32 rg_property_data[1]; +}; + +struct hfi_msg_sys_session_end_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; +}; + +struct hfi_msg_sys_debug_packet { + u32 size; + u32 packet_type; + u32 msg_type; + u32 msg_size; + u32 time_stamp_hi; + u32 time_stamp_lo; + u8 rg_msg_data[1]; +}; + +struct hfi_msg_sys_coverage_packet { + u32 size; + u32 packet_type; + u32 msg_size; + u32 time_stamp_hi; + u32 time_stamp_lo; + u8 rg_msg_data[1]; +}; + +enum HFI_VENUS_QTBL_STATUS { + HFI_VENUS_QTBL_DISABLED = 0x00, + HFI_VENUS_QTBL_ENABLED = 0x01, + HFI_VENUS_QTBL_INITIALIZING = 0x02, + HFI_VENUS_QTBL_DEINITIALIZING = 0x03 +}; + +enum HFI_VENUS_CTRL_INIT_STATUS { + HFI_VENUS_CTRL_NOT_INIT = 0x0, + HFI_VENUS_CTRL_READY = 0x1, + HFI_VENUS_CTRL_ERROR_FATAL = 0x2 +}; + +struct hfi_sfr_struct { + u32 bufSize; + u8 rg_data[1]; +}; + +struct hfi_cmd_sys_test_ssr_packet { + u32 size; + u32 packet_type; + u32 trigger_type; +}; + +struct hfi_hdr10_pq_sei { + struct msm_vidc_mastering_display_colour_sei_payload mdisp_info; + struct msm_vidc_content_light_level_sei_payload cll_info; +}; + +struct hfi_vbv_hrd_buf_size { + u32 vbv_hrd_buf_size; +}; + +#endif diff --git a/msm/vidc/vidc_hfi_io.h b/msm/vidc/vidc_hfi_io.h new file mode 100644 index 000000000000..388d1ac1cc98 --- /dev/null +++ b/msm/vidc/vidc_hfi_io.h @@ -0,0 +1,220 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef __VIDC_HFI_IO_H__ +#define __VIDC_HFI_IO_H__ + +#include + +#define VIDC_VBIF_BASE_OFFS 0x00080000 + +#define VIDC_CPU_BASE_OFFS 0x000A0000 +#define VIDEO_CC_BASE_OFFS 0x000F0000 +#define VIDC_AON_BASE_OFFS 0x000E0000 +#define VIDC_CPU_CS_BASE_OFFS (VIDC_CPU_BASE_OFFS) +#define VIDC_CPU_IC_BASE_OFFS (VIDC_CPU_BASE_OFFS) + +#define VIDC_CPU_CS_A2HSOFTINTEN (VIDC_CPU_CS_BASE_OFFS + 0x10) +#define VIDC_CPU_CS_A2HSOFTINTENCLR (VIDC_CPU_CS_BASE_OFFS + 0x14) +#define VIDC_CPU_CS_A2HSOFTINT (VIDC_CPU_CS_BASE_OFFS + 0x18) +#define VIDC_CPU_CS_A2HSOFTINTCLR (VIDC_CPU_CS_BASE_OFFS + 0x1C) +#define VIDC_CPU_CS_VMIMSG (VIDC_CPU_CS_BASE_OFFS + 0x34) +#define VIDC_CPU_CS_VMIMSGAG0 (VIDC_CPU_CS_BASE_OFFS + 0x38) +#define VIDC_CPU_CS_VMIMSGAG1 (VIDC_CPU_CS_BASE_OFFS + 0x3C) +#define VIDC_CPU_CS_VMIMSGAG2 (VIDC_CPU_CS_BASE_OFFS + 0x40) +#define VIDC_CPU_CS_VMIMSGAG3 (VIDC_CPU_CS_BASE_OFFS + 0x44) +#define VIDC_CPU_CS_SCIACMD (VIDC_CPU_CS_BASE_OFFS + 0x48) +#define VIDC_CPU_CS_H2XSOFTINTEN (VIDC_CPU_CS_BASE_OFFS + 0x148) + +/* HFI_CTRL_STATUS */ +#define VIDC_CPU_CS_SCIACMDARG0 (VIDC_CPU_CS_BASE_OFFS + 0x4C) +#define VIDC_CPU_CS_SCIACMDARG0_BMSK 0xff +#define VIDC_CPU_CS_SCIACMDARG0_SHFT 0x0 +#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK 0xfe +#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_SHFT 0x1 +#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_BMSK 0x1 +#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_SHFT 0x0 +#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY 0x100 +#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK 0x40000000 + +/* HFI_QTBL_INFO */ +#define VIDC_CPU_CS_SCIACMDARG1 (VIDC_CPU_CS_BASE_OFFS + 0x50) + +/* HFI_QTBL_ADDR */ +#define VIDC_CPU_CS_SCIACMDARG2 (VIDC_CPU_CS_BASE_OFFS + 0x54) + +/* HFI_VERSION_INFO */ +#define VIDC_CPU_CS_SCIACMDARG3 (VIDC_CPU_CS_BASE_OFFS + 0x58) + +/* VIDC_SFR_ADDR */ +#define VIDC_CPU_CS_SCIBCMD (VIDC_CPU_CS_BASE_OFFS + 0x5C) + +/* VIDC_MMAP_ADDR */ +#define VIDC_CPU_CS_SCIBCMDARG0 (VIDC_CPU_CS_BASE_OFFS + 0x60) + +/* VIDC_UC_REGION_ADDR */ +#define VIDC_CPU_CS_SCIBARG1 (VIDC_CPU_CS_BASE_OFFS + 0x64) + +/* VIDC_UC_REGION_ADDR */ +#define VIDC_CPU_CS_SCIBARG2 (VIDC_CPU_CS_BASE_OFFS + 0x68) + +#define VIDC_CPU_CS_SCIBARG3 (VIDC_CPU_CS_BASE_OFFS + 0x6C) + +/* FAL10 Feature Control */ +#define VIDC_CPU_CS_X2RPMh (VIDC_CPU_CS_BASE_OFFS + 0x168) +#define VIDC_CPU_CS_X2RPMh_MASK0_BMSK 0x1 +#define VIDC_CPU_CS_X2RPMh_MASK0_SHFT 0x0 +#define VIDC_CPU_CS_X2RPMh_MASK1_BMSK 0x2 +#define VIDC_CPU_CS_X2RPMh_MASK1_SHFT 0x1 +#define VIDC_CPU_CS_X2RPMh_SWOVERRIDE_BMSK 0x4 +#define VIDC_CPU_CS_X2RPMh_SWOVERRIDE_SHFT 0x3 + +#define VIDC_CPU_IC_SOFTINT (VIDC_CPU_IC_BASE_OFFS + 0x150) +#define VIDC_CPU_IC_SOFTINT_H2A_BMSK 0x1 +#define VIDC_CPU_IC_SOFTINT_H2A_SHFT 0x0 +#define VIDC_CPU_IC_SOFTINTCLEAR (VIDC_CPU_IC_BASE_OFFS + 0x154) + +/* + * -------------------------------------------------------------------------- + * MODULE: vidc_wrapper + * -------------------------------------------------------------------------- + */ +#define VIDC_WRAPPER_BASE_OFFS 0x000B0000 + +#define VIDC_WRAPPER_HW_VERSION (VIDC_WRAPPER_BASE_OFFS + 0x00) +#define VIDC_WRAPPER_HW_VERSION_MAJOR_VERSION_MASK 0x78000000 +#define VIDC_WRAPPER_HW_VERSION_MAJOR_VERSION_SHIFT 28 +#define VIDC_WRAPPER_HW_VERSION_MINOR_VERSION_MASK 0xFFF0000 +#define VIDC_WRAPPER_HW_VERSION_MINOR_VERSION_SHIFT 16 +#define VIDC_WRAPPER_HW_VERSION_STEP_VERSION_MASK 0xFFFF +#define VIDC_WRAPPER_CLOCK_CONFIG (VIDC_WRAPPER_BASE_OFFS + 0x04) + +#define VIDC_WRAPPER_INTR_STATUS (VIDC_WRAPPER_BASE_OFFS + 0x0C) +#define VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK 0x8 +#define VIDC_WRAPPER_INTR_STATUS_A2HWD_SHFT 0x3 +#define VIDC_WRAPPER_INTR_STATUS_A2H_BMSK 0x4 +#define VIDC_WRAPPER_INTR_STATUS_A2H_SHFT 0x2 + +#define VIDC_WRAPPER_INTR_MASK (VIDC_WRAPPER_BASE_OFFS + 0x10) +#define VIDC_WRAPPER_INTR_MASK_A2HWD_BMSK 0x8 +#define VIDC_WRAPPER_INTR_MASK_A2HWD_SHFT 0x3 +#define VIDC_WRAPPER_INTR_MASK_A2HVCODEC_BMSK 0x8 +#define VIDC_WRAPPER_INTR_MASK_A2HCPU_BMSK 0x4 +#define VIDC_WRAPPER_INTR_MASK_A2HCPU_SHFT 0x2 + +#define VIDC_WRAPPER_CPU_CLOCK_CONFIG (VIDC_WRAPPER_BASE_OFFS + 0x2000) +#define VIDC_WRAPPER_CPU_CGC_DIS (VIDC_WRAPPER_BASE_OFFS + 0x2010) +#define VIDC_WRAPPER_CPU_STATUS (VIDC_WRAPPER_BASE_OFFS + 0x2014) + +#define VIDC_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (VIDC_WRAPPER_BASE_OFFS + 0x54) +#define VIDC_WRAPPER_DEBUG_BRIDGE_LPI_STATUS (VIDC_WRAPPER_BASE_OFFS + 0x58) +/* + * -------------------------------------------------------------------------- + * MODULE: vidc_tz_wrapper + * -------------------------------------------------------------------------- + */ +#define VIDC_WRAPPER_TZ_BASE_OFFS 0x000C0000 +#define VIDC_WRAPPER_TZ_CPU_CLOCK_CONFIG (VIDC_WRAPPER_TZ_BASE_OFFS) +#define VIDC_WRAPPER_TZ_CPU_STATUS (VIDC_WRAPPER_TZ_BASE_OFFS + 0x10) + +#define VIDC_VENUS_VBIF_CLK_ON (VIDC_VBIF_BASE_OFFS + 0x4) +#define VENUS_VBIF_AXI_HALT_CTRL0 (VIDC_VBIF_BASE_OFFS + 0x208) +#define VENUS_VBIF_AXI_HALT_CTRL1 (VIDC_VBIF_BASE_OFFS + 0x20C) + +#define VENUS_VBIF_AXI_HALT_CTRL0_HALT_REQ BIT(0) +#define VENUS_VBIF_AXI_HALT_CTRL1_HALT_ACK BIT(0) +#define VENUS_VBIF_AXI_HALT_ACK_TIMEOUT_US 500000 + + +#define VIDC_CTRL_INIT VIDC_CPU_CS_SCIACMD + +#define VIDC_CTRL_STATUS VIDC_CPU_CS_SCIACMDARG0 +#define VIDC_CTRL_ERROR_STATUS__M \ + VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK +#define VIDC_CTRL_INIT_IDLE_MSG_BMSK \ + VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK +#define VIDC_CTRL_STATUS_PC_READY \ + VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY + + +#define VIDC_QTBL_INFO VIDC_CPU_CS_SCIACMDARG1 + +#define VIDC_QTBL_ADDR VIDC_CPU_CS_SCIACMDARG2 + +#define VIDC_VERSION_INFO VIDC_CPU_CS_SCIACMDARG3 + +#define VIDC_SFR_ADDR VIDC_CPU_CS_SCIBCMD +#define VIDC_MMAP_ADDR VIDC_CPU_CS_SCIBCMDARG0 +#define VIDC_UC_REGION_ADDR VIDC_CPU_CS_SCIBARG1 +#define VIDC_UC_REGION_SIZE VIDC_CPU_CS_SCIBARG2 + +/* HFI_DSP_QTBL_ADDR + * 31:3 - HFI_DSP_QTBL_ADDR + * 4-byte aligned Address + */ +#define HFI_DSP_QTBL_ADDR VIDC_CPU_CS_VMIMSG + +/* HFI_DSP_UC_REGION_ADDR + * 31:20 - HFI_DSP_UC_REGION_ADDR + * 1MB aligned address. + * Uncached Region start Address. This region covers + * HFI DSP QTable, + * HFI DSP Queue Headers, + * HFI DSP Queues, + */ +#define HFI_DSP_UC_REGION_ADDR VIDC_CPU_CS_VMIMSGAG0 + +/* HFI_DSP_UC_REGION_SIZE + * 31:20 - HFI_DSP_UC_REGION_SIZE + * Multiples of 1MB. + * Size of the DSP_UC_REGION Uncached Region + */ +#define HFI_DSP_UC_REGION_SIZE VIDC_CPU_CS_VMIMSGAG1 + +/* + * -------------------------------------------------------------------------- + * MODULE: vcodec noc error log registers (iris1) + * -------------------------------------------------------------------------- + */ +#define VCODEC_CORE0_VIDEO_NOC_BASE_OFFS 0x00004000 +#define VCODEC_CORE1_VIDEO_NOC_BASE_OFFS 0x0000C000 +#define VCODEC_COREX_VIDEO_NOC_ERR_SWID_LOW_OFFS 0x0500 +#define VCODEC_COREX_VIDEO_NOC_ERR_SWID_HIGH_OFFS 0x0504 +#define VCODEC_COREX_VIDEO_NOC_ERR_MAINCTL_LOW_OFFS 0x0508 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS 0x0510 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRCLR_LOW_OFFS 0x0518 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_LOW_OFFS 0x0520 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_HIGH_OFFS 0x0524 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_LOW_OFFS 0x0528 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_HIGH_OFFS 0x052C +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_LOW_OFFS 0x0530 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_HIGH_OFFS 0x0534 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_LOW_OFFS 0x0538 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_HIGH_OFFS 0x053C + +#define VIDC_AON_WRAPPER_MVP_NOC_LPI_CONTROL (VIDC_AON_BASE_OFFS) +#define VIDC_AON_WRAPPER_MVP_NOC_LPI_STATUS (VIDC_AON_BASE_OFFS + 0x4) + +/* + * -------------------------------------------------------------------------- + * MODULE: vcodec noc error log registers (iris2) + * -------------------------------------------------------------------------- + */ +#define VCODEC_NOC_VIDEO_A_NOC_BASE_OFFS 0x00010000 +#define VCODEC_NOC_ERL_MAIN_SWID_LOW 0x00011200 +#define VCODEC_NOC_ERL_MAIN_SWID_HIGH 0x00011204 +#define VCODEC_NOC_ERL_MAIN_MAINCTL_LOW 0x00011208 +#define VCODEC_NOC_ERL_MAIN_ERRVLD_LOW 0x00011210 +#define VCODEC_NOC_ERL_MAIN_ERRCLR_LOW 0x00011218 +#define VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW 0x00011220 +#define VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH 0x00011224 +#define VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW 0x00011228 +#define VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH 0x0001122C +#define VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW 0x00011230 +#define VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH 0x00011234 +#define VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW 0x00011238 +#define VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH 0x0001123C +# +#endif From ae78fd954ba7b8046e1ba455aad965c00067918c Mon Sep 17 00:00:00 2001 From: Shivendra Kakrania Date: Thu, 2 May 2019 23:07:45 -0700 Subject: [PATCH 004/452] techpack: video: Updating video kernel snapshot Video kernel snapshot before disabling msm/vidc compilation from base kernel. Change-Id: Id1178c3aca00706ad4822537f7f9a28141478771 Signed-off-by: Shivendra Kakrania --- msm/Makefile | 5 +- msm/vidc/hfi_ar50.c | 13 + msm/vidc/{venus_hfi.c => hfi_common.c} | 496 ++++++++----------------- msm/vidc/{venus_hfi.h => hfi_common.h} | 39 +- msm/vidc/hfi_io_common.h | 139 +++++++ msm/vidc/hfi_iris1.c | 60 +++ msm/vidc/hfi_iris2.c | 411 ++++++++++++++++++++ msm/vidc/hfi_response_handler.c | 1 - msm/vidc/msm_venc.c | 45 ++- msm/vidc/msm_vidc_common.c | 6 - msm/vidc/vidc_hfi.c | 4 +- msm/vidc/vidc_hfi_io.h | 220 ----------- 12 files changed, 846 insertions(+), 593 deletions(-) create mode 100644 msm/vidc/hfi_ar50.c rename msm/vidc/{venus_hfi.c => hfi_common.c} (90%) rename msm/vidc/{venus_hfi.h => hfi_common.h} (81%) create mode 100644 msm/vidc/hfi_io_common.h create mode 100644 msm/vidc/hfi_iris1.c create mode 100644 msm/vidc/hfi_iris2.c delete mode 100644 msm/vidc/vidc_hfi_io.h diff --git a/msm/Makefile b/msm/Makefile index f71400929de6..d16933a7f464 100644 --- a/msm/Makefile +++ b/msm/Makefile @@ -14,7 +14,10 @@ msm-vidc-objs := vidc/msm_v4l2_vidc.o \ vidc/msm_smem.o \ vidc/msm_vidc_debug.o \ vidc/msm_vidc_res_parse.o \ - vidc/venus_hfi.o \ + vidc/hfi_common.o \ + vidc/hfi_ar50.o \ + vidc/hfi_iris1.o \ + vidc/hfi_iris2.o \ vidc/hfi_response_handler.o \ vidc/hfi_packetization.o \ vidc/vidc_hfi.o \ diff --git a/msm/vidc/hfi_ar50.c b/msm/vidc/hfi_ar50.c new file mode 100644 index 000000000000..a5428dbfe246 --- /dev/null +++ b/msm/vidc/hfi_ar50.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include "hfi_common.h" +#include "hfi_io_common.h" + +void __interrupt_init_ar50(struct venus_hfi_device *device) +{ + __write_register(device, WRAPPER_INTR_MASK, + WRAPPER_INTR_MASK_A2HVCODEC_BMSK); +} diff --git a/msm/vidc/venus_hfi.c b/msm/vidc/hfi_common.c similarity index 90% rename from msm/vidc/venus_hfi.c rename to msm/vidc/hfi_common.c index 43b6a7f08f32..430d07c82330 100644 --- a/msm/vidc/venus_hfi.c +++ b/msm/vidc/hfi_common.c @@ -29,8 +29,8 @@ #include #include "hfi_packetization.h" #include "msm_vidc_debug.h" -#include "venus_hfi.h" -#include "vidc_hfi_io.h" +#include "hfi_common.h" +#include "hfi_io_common.h" #define FIRMWARE_SIZE 0X00A00000 #define REG_ADDR_OFFSET_BITMASK 0x000FFFFF @@ -77,10 +77,8 @@ static void venus_hfi_pm_handler(struct work_struct *work); static DECLARE_DELAYED_WORK(venus_hfi_pm_work, venus_hfi_pm_handler); static inline int __resume(struct venus_hfi_device *device); static inline int __suspend(struct venus_hfi_device *device); -static int __disable_regulators(struct venus_hfi_device *device); static int __enable_regulators(struct venus_hfi_device *device); static inline int __prepare_enable_clks(struct venus_hfi_device *device); -static inline void __disable_unprepare_clks(struct venus_hfi_device *device); static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet); static int __initialize_packetization(struct venus_hfi_device *device); static struct hal_session *__get_session(struct venus_hfi_device *device, @@ -99,43 +97,56 @@ static int __release_subcaches(struct venus_hfi_device *device); static int __disable_subcaches(struct venus_hfi_device *device); static int __power_collapse(struct venus_hfi_device *device, bool force); static int venus_hfi_noc_error_info(void *dev); - -static void interrupt_init_vpu4(struct venus_hfi_device *device); -static void interrupt_init_iris1(struct venus_hfi_device *device); -static void setup_dsp_uc_memmap_iris1(struct venus_hfi_device *device); -static void clock_config_on_enable_iris1(struct venus_hfi_device *device); -static int reset_ahb2axi_bridge(struct venus_hfi_device *device); static int __set_ubwc_config(struct venus_hfi_device *device); -static void power_off_common(struct venus_hfi_device *device); -static void power_off_iris2(struct venus_hfi_device *device); -static void noc_error_info_common(struct venus_hfi_device *device); -static void noc_error_info_iris2(struct venus_hfi_device *device); +static void __power_off_common(struct venus_hfi_device *device); +static int __prepare_pc_common(struct venus_hfi_device *device); +static void __raise_interrupt_common(struct venus_hfi_device *device); +static bool __watchdog_common(u32 intr_status); +static void __noc_error_info_common(struct venus_hfi_device *device); +static void __core_clear_interrupt_common(struct venus_hfi_device *device); +static inline int __boot_firmware_common(struct venus_hfi_device *device); +static void __setup_ucregion_memory_map_common(struct venus_hfi_device *device); struct venus_hfi_vpu_ops vpu4_ops = { - .interrupt_init = interrupt_init_vpu4, - .setup_dsp_uc_memmap = NULL, + .interrupt_init = __interrupt_init_ar50, + .setup_ucregion_memmap = __setup_ucregion_memory_map_common, .clock_config_on_enable = NULL, .reset_ahb2axi_bridge = NULL, - .power_off = power_off_common, - .noc_error_info = noc_error_info_common, + .power_off = __power_off_common, + .prepare_pc = __prepare_pc_common, + .raise_interrupt = __raise_interrupt_common, + .watchdog = __watchdog_common, + .noc_error_info = __noc_error_info_common, + .core_clear_interrupt = __core_clear_interrupt_common, + .boot_firmware = __boot_firmware_common, }; struct venus_hfi_vpu_ops iris1_ops = { - .interrupt_init = interrupt_init_iris1, - .setup_dsp_uc_memmap = setup_dsp_uc_memmap_iris1, - .clock_config_on_enable = clock_config_on_enable_iris1, - .reset_ahb2axi_bridge = reset_ahb2axi_bridge, - .power_off = power_off_common, - .noc_error_info = noc_error_info_common, + .interrupt_init = __interrupt_init_iris1, + .setup_ucregion_memmap = __setup_ucregion_memory_map_iris1, + .clock_config_on_enable = __clock_config_on_enable_iris1, + .reset_ahb2axi_bridge = __reset_ahb2axi_bridge_common, + .power_off = __power_off_common, + .prepare_pc = __prepare_pc_common, + .raise_interrupt = __raise_interrupt_common, + .watchdog = __watchdog_common, + .noc_error_info = __noc_error_info_common, + .core_clear_interrupt = __core_clear_interrupt_common, + .boot_firmware = __boot_firmware_common, }; struct venus_hfi_vpu_ops iris2_ops = { - .interrupt_init = interrupt_init_iris1, - .setup_dsp_uc_memmap = NULL, + .interrupt_init = __interrupt_init_iris2, + .setup_ucregion_memmap = __setup_ucregion_memory_map_iris2, .clock_config_on_enable = NULL, - .reset_ahb2axi_bridge = reset_ahb2axi_bridge, - .power_off = power_off_iris2, - .noc_error_info = noc_error_info_iris2, + .reset_ahb2axi_bridge = __reset_ahb2axi_bridge_common, + .power_off = __power_off_iris2, + .prepare_pc = __prepare_pc_iris2, + .raise_interrupt = __raise_interrupt_iris2, + .watchdog = __watchdog_iris2, + .noc_error_info = __noc_error_info_iris2, + .core_clear_interrupt = __core_clear_interrupt_iris2, + .boot_firmware = __boot_firmware_iris2, }; /** @@ -881,7 +892,7 @@ static void __smem_free(struct venus_hfi_device *dev, struct msm_smem *mem) msm_smem_free(mem); } -static void __write_register(struct venus_hfi_device *device, +void __write_register(struct venus_hfi_device *device, u32 reg, u32 value) { u32 hwiosymaddr = reg; @@ -913,7 +924,7 @@ static void __write_register(struct venus_hfi_device *device, wmb(); } -static int __read_register(struct venus_hfi_device *device, u32 reg) +int __read_register(struct venus_hfi_device *device, u32 reg) { int rc = 0; u8 *base_addr; @@ -964,37 +975,13 @@ static void __set_registers(struct venus_hfi_device *device) } } -/* - * The existence of this function is a hack for 8996 (or certain Venus versions) - * to overcome a hardware bug. Whenever the GDSCs momentarily power collapse - * (after calling __hand_off_regulators()), the values of the threshold - * registers (typically programmed by TZ) are incorrectly reset. As a result - * reprogram these registers at certain agreed upon points. - */ -static void __set_threshold_registers(struct venus_hfi_device *device) -{ - u32 version = __read_register(device, VIDC_WRAPPER_HW_VERSION); - - version &= ~GENMASK(15, 0); - if (version != (0x3 << 28 | 0x43 << 16)) - return; - - if (__tzbsp_set_video_state(TZBSP_VIDEO_STATE_RESTORE_THRESHOLD)) - dprintk(VIDC_ERR, "Failed to restore threshold values\n"); -} - -static int __vote_bandwidth(struct bus_info *bus, - unsigned long *freq) +static int __vote_bandwidth(struct bus_info *bus, unsigned long freq) { int rc = 0; uint64_t ab = 0; - if (*freq) - *freq = clamp_t(typeof(*freq), *freq, bus->range[0], - bus->range[1]); - /* Bus Driver expects values in Bps */ - ab = *freq * 1000; + ab = freq * 1000; dprintk(VIDC_PROF, "Voting bus %s to ab %llu\n", bus->name, ab); rc = msm_bus_scale_update_bw(bus->client, ab, 0); if (rc) @@ -1004,24 +991,17 @@ static int __vote_bandwidth(struct bus_info *bus, return rc; } -static int __unvote_buses(struct venus_hfi_device *device) +int __unvote_buses(struct venus_hfi_device *device) { int rc = 0; struct bus_info *bus = NULL; - unsigned long freq = 0, zero = 0; kfree(device->bus_vote.data); device->bus_vote.data = NULL; device->bus_vote.data_count = 0; venus_hfi_for_each_bus(device, bus) { - if (!bus->is_prfm_mode) { - freq = device->bus_vote.calc_bw(bus, &device->bus_vote); - rc = __vote_bandwidth(bus, &freq); - } - else - rc = __vote_bandwidth(bus, &zero); - + rc = __vote_bandwidth(bus, 0); if (rc) goto err_unknown_device; } @@ -1066,7 +1046,11 @@ static int __vote_buses(struct venus_hfi_device *device, else freq = bus->range[1]; - rc = __vote_bandwidth(bus, &freq); + /* ensure freq is within limits */ + freq = clamp_t(typeof(freq), freq, + bus->range[0], bus->range[1]); + + rc = __vote_bandwidth(bus, freq); } else { dprintk(VIDC_ERR, "No BUS to Vote\n"); } @@ -1181,7 +1165,7 @@ static int __tzbsp_set_video_state(enum tzbsp_video_state state) return 0; } -static inline int __boot_firmware(struct venus_hfi_device *device) +static inline int __boot_firmware_common(struct venus_hfi_device *device) { int rc = 0; u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 10000; @@ -1190,10 +1174,10 @@ static inline int __boot_firmware(struct venus_hfi_device *device) if (device->res->domain_cvp) ctrl_init_val |= BIT(1); - __write_register(device, VIDC_CTRL_INIT, ctrl_init_val); + __write_register(device, CTRL_INIT, ctrl_init_val); while (!ctrl_status && count < max_tries) { - ctrl_status = __read_register(device, VIDC_CTRL_STATUS); - if ((ctrl_status & VIDC_CTRL_ERROR_STATUS__M) == 0x4) { + ctrl_status = __read_register(device, CTRL_STATUS); + if ((ctrl_status & CTRL_ERROR_STATUS__M) == 0x4) { dprintk(VIDC_ERR, "invalid setting for UC_REGION\n"); break; } @@ -1207,10 +1191,6 @@ static inline int __boot_firmware(struct venus_hfi_device *device) rc = -ETIME; } - /* Enable interrupt before sending commands to venus */ - __write_register(device, VIDC_CPU_CS_H2XSOFTINTEN, 0x1); - __write_register(device, VIDC_CPU_CS_X2RPMh, 0x0); - return rc; } @@ -1413,17 +1393,19 @@ static int __iface_cmdq_write_relaxed(struct venus_hfi_device *device, return result; } +static void __raise_interrupt_common(struct venus_hfi_device *device) +{ + __write_register(device, CPU_IC_SOFTINT, + 1 << CPU_IC_SOFTINT_H2A_SHFT); +} + static int __iface_cmdq_write(struct venus_hfi_device *device, void *pkt) { bool needs_interrupt = false; int rc = __iface_cmdq_write_relaxed(device, pkt, &needs_interrupt); - if (!rc && needs_interrupt) { - /* Consumer of cmdq prefers that we raise an interrupt */ - rc = 0; - __write_register(device, VIDC_CPU_IC_SOFTINT, - 1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT); - } + if (!rc && needs_interrupt) + call_venus_op(device, raise_interrupt, device); return rc; } @@ -1457,8 +1439,7 @@ static int __iface_msgq_read(struct venus_hfi_device *device, void *pkt) if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) { __hal_sim_modify_msg_packet((u8 *)pkt, device); if (tx_req_is_set) - __write_register(device, VIDC_CPU_IC_SOFTINT, - 1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT); + call_venus_op(device, raise_interrupt, device); rc = 0; } else rc = -ENODATA; @@ -1489,8 +1470,7 @@ static int __iface_dbgq_read(struct venus_hfi_device *device, void *pkt) if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) { if (tx_req_is_set) - __write_register(device, VIDC_CPU_IC_SOFTINT, - 1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT); + call_venus_op(device, raise_interrupt, device); rc = 0; } else rc = -ENODATA; @@ -1764,21 +1744,20 @@ static int __get_qdss_iommu_virtual_addr(struct venus_hfi_device *dev, return rc; } -static void __setup_ucregion_memory_map(struct venus_hfi_device *device) +static void __setup_ucregion_memory_map_common(struct venus_hfi_device *device) { - __write_register(device, VIDC_UC_REGION_ADDR, + __write_register(device, UC_REGION_ADDR, (u32)device->iface_q_table.align_device_addr); - __write_register(device, VIDC_UC_REGION_SIZE, SHARED_QSIZE); - __write_register(device, VIDC_QTBL_ADDR, + __write_register(device, UC_REGION_SIZE, SHARED_QSIZE); + __write_register(device, QTBL_ADDR, (u32)device->iface_q_table.align_device_addr); - __write_register(device, VIDC_QTBL_INFO, 0x01); + __write_register(device, QTBL_INFO, 0x01); if (device->sfr.align_device_addr) - __write_register(device, VIDC_SFR_ADDR, + __write_register(device, SFR_ADDR, (u32)device->sfr.align_device_addr); if (device->qdss.align_device_addr) - __write_register(device, VIDC_MMAP_ADDR, + __write_register(device, MMAP_ADDR, (u32)device->qdss.align_device_addr); - call_venus_op(device, setup_dsp_uc_memmap, device); } static int __interface_queues_init(struct venus_hfi_device *dev) @@ -1930,7 +1909,7 @@ static int __interface_queues_init(struct venus_hfi_device *dev) } } - __setup_ucregion_memory_map(dev); + call_venus_op(dev, setup_ucregion_memmap, dev); return 0; fail_alloc_queue: return -ENOMEM; @@ -2052,7 +2031,7 @@ static int venus_hfi_core_init(void *device) goto err_core_init; } - rc = __boot_firmware(dev); + rc = call_venus_op(dev, boot_firmware, dev); if (rc) { dprintk(VIDC_ERR, "Failed to start core\n"); rc = -ENODEV; @@ -2164,7 +2143,7 @@ static int __get_q_size(struct venus_hfi_device *dev, unsigned int q_index) return read_ptr - write_ptr; } -static void __core_clear_interrupt(struct venus_hfi_device *device) +static void __core_clear_interrupt_common(struct venus_hfi_device *device) { u32 intr_status = 0, mask = 0; @@ -2173,10 +2152,10 @@ static void __core_clear_interrupt(struct venus_hfi_device *device) return; } - intr_status = __read_register(device, VIDC_WRAPPER_INTR_STATUS); - mask = (VIDC_WRAPPER_INTR_STATUS_A2H_BMSK | - VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK | - VIDC_CTRL_INIT_IDLE_MSG_BMSK); + intr_status = __read_register(device, WRAPPER_INTR_STATUS); + mask = (WRAPPER_INTR_STATUS_A2H_BMSK | + WRAPPER_INTR_STATUS_A2HWD_BMSK | + CTRL_INIT_IDLE_MSG_BMSK); if (intr_status & mask) { device->intr_status |= intr_status; @@ -2188,7 +2167,8 @@ static void __core_clear_interrupt(struct venus_hfi_device *device) device->spur_count++; } - __write_register(device, VIDC_CPU_CS_A2HSOFTINTCLR, 1); + __write_register(device, CPU_CS_A2HSOFTINTCLR, 1); + __write_register(device, WRAPPER_INTR_CLEAR, intr_status); } static int venus_hfi_core_trigger_ssr(void *device, @@ -2984,7 +2964,7 @@ static int __check_core_registered(struct hal_device_data core, device = list_entry(curr, struct venus_hfi_device, list); hal_data = device->hal_data; - if (device && hal_data->irq == irq && + if (hal_data && hal_data->irq == irq && (CONTAINS(hal_data->firmware_base, FIRMWARE_SIZE, fw_addr) || CONTAINS(fw_addr, FIRMWARE_SIZE, @@ -3022,7 +3002,7 @@ static void __process_fatal_error( device->callback(HAL_SYS_ERROR, &cmd_done); } -static int __prepare_pc(struct venus_hfi_device *device) +int __prepare_pc(struct venus_hfi_device *device) { int rc = 0; struct hfi_cmd_sys_pc_prep_packet pkt; @@ -3098,15 +3078,64 @@ static void venus_hfi_pm_handler(struct work_struct *work) } } -static int __power_collapse(struct venus_hfi_device *device, bool force) +static int __prepare_pc_common(struct venus_hfi_device *device) { int rc = 0; u32 wfi_status = 0, idle_status = 0, pc_ready = 0; u32 ctrl_status = 0; - u32 flags = 0; int count = 0; const int max_tries = 10; + ctrl_status = __read_register(device, CTRL_STATUS); + pc_ready = ctrl_status & CTRL_STATUS_PC_READY; + idle_status = ctrl_status & BIT(30); + + if (pc_ready) { + dprintk(VIDC_DBG, "Already in pc_ready state\n"); + return 0; + } + + wfi_status = BIT(0) & __read_register(device, + WRAPPER_CPU_STATUS); + if (!wfi_status || !idle_status) { + dprintk(VIDC_WARN, "Skipping PC, wfi status not set\n"); + goto skip_power_off; + } + + rc = __prepare_pc(device); + if (rc) { + dprintk(VIDC_WARN, "Failed __prepare_pc %d\n", rc); + goto skip_power_off; + } + + while (count < max_tries) { + wfi_status = BIT(0) & __read_register(device, + WRAPPER_CPU_STATUS); + ctrl_status = __read_register(device, CTRL_STATUS); + if (wfi_status && (ctrl_status & CTRL_STATUS_PC_READY)) + break; + usleep_range(150, 250); + count++; + } + + if (count == max_tries) { + dprintk(VIDC_ERR, "Skip PC. Core is not in right state\n"); + goto skip_power_off; + } + + return rc; + +skip_power_off: + dprintk(VIDC_WARN, "Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n", + wfi_status, idle_status, pc_ready, ctrl_status); + return -EAGAIN; +} + +static int __power_collapse(struct venus_hfi_device *device, bool force) +{ + int rc = 0; + u32 flags = 0; + if (!device) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; @@ -3128,45 +3157,9 @@ static int __power_collapse(struct venus_hfi_device *device, bool force) else if (rc) goto skip_power_off; - ctrl_status = __read_register(device, VIDC_CTRL_STATUS); - pc_ready = ctrl_status & VIDC_CTRL_STATUS_PC_READY; - idle_status = ctrl_status & BIT(30); - - if (!pc_ready) { - wfi_status = BIT(0) & - __read_register(device, - VIDC_WRAPPER_TZ_CPU_STATUS); - if (!wfi_status || !idle_status) { - dprintk(VIDC_WARN, - "Skipping PC, wfi or idle status not set.\n"); - goto skip_power_off; - } - - rc = __prepare_pc(device); - if (rc) { - dprintk(VIDC_WARN, "Failed __prepare_pc %d\n", rc); - goto skip_power_off; - } - - while (count < max_tries) { - wfi_status = BIT(0) & - __read_register(device, - VIDC_WRAPPER_TZ_CPU_STATUS); - ctrl_status = __read_register(device, - VIDC_CTRL_STATUS); - if (wfi_status && - (ctrl_status & VIDC_CTRL_STATUS_PC_READY)) - break; - usleep_range(150, 250); - count++; - } - - if (count == max_tries) { - dprintk(VIDC_ERR, - "Skip PC. Core is not in right state.\n"); - goto skip_power_off; - } - } + rc = call_venus_op(device, prepare_pc, device); + if (rc) + goto skip_power_off; __flush_debug_queue(device, device->raw_packet); @@ -3178,9 +3171,6 @@ static int __power_collapse(struct venus_hfi_device *device, bool force) return rc; skip_power_off: - dprintk(VIDC_WARN, "Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n", - wfi_status, idle_status, pc_ready, ctrl_status); - return -EAGAIN; } @@ -3294,6 +3284,16 @@ static struct hal_session *__get_session(struct venus_hfi_device *device, return NULL; } +static bool __watchdog_common(u32 intr_status) +{ + bool rc = false; + + if (intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK) + rc = true; + + return rc; +} + static int __response_handler(struct venus_hfi_device *device) { struct msm_vidc_cb_info *packets; @@ -3310,12 +3310,12 @@ static int __response_handler(struct venus_hfi_device *device) if (!raw_packet || !packets) { dprintk(VIDC_ERR, - "%s: Invalid args : Res packet = %p, Raw packet = %p\n", + "%s: Invalid args : Res packet = %pK, Raw packet = %pK\n", __func__, packets, raw_packet); return 0; } - if (device->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK) { + if (call_venus_op(device, watchdog, device->intr_status)) { struct hfi_sfr_struct *vsfr = (struct hfi_sfr_struct *) device->sfr.align_virtual_addr; struct msm_vidc_cb_info info = { @@ -3361,14 +3361,6 @@ static int __response_handler(struct venus_hfi_device *device) dprintk(VIDC_DBG, "Received SYS_INIT_DONE\n"); break; case HAL_SESSION_LOAD_RESOURCE_DONE: - /* - * Work around for H/W bug, need to re-program these - * registers as part of a handshake agreement with the - * firmware. This strictly only needs to be done for - * decoder secure sessions, but there's no harm in doing - * so for all sessions as it's at worst a NO-OP. - */ - __set_threshold_registers(device); break; default: break; @@ -3491,7 +3483,7 @@ static void venus_hfi_core_work_handler(struct work_struct *work) goto err_no_work; } - __core_clear_interrupt(device); + call_venus_op(device, core_clear_interrupt, device); num_responses = __response_handler(device); err_no_work: @@ -3521,7 +3513,7 @@ static void venus_hfi_core_work_handler(struct work_struct *work) } /* We need re-enable the irq which was disabled in ISR handler */ - if (!(intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK)) + if (!call_venus_op(device, watchdog, intr_status)) enable_irq(device->hal_data->irq); /* @@ -3703,7 +3695,7 @@ static int __handle_reset_clk(struct msm_vidc_platform_resources *res, return rc; } -static inline void __disable_unprepare_clks(struct venus_hfi_device *device) +void __disable_unprepare_clks(struct venus_hfi_device *device) { struct clock_info *cl; int rc = 0; @@ -3732,7 +3724,7 @@ static inline void __disable_unprepare_clks(struct venus_hfi_device *device) } } -static int reset_ahb2axi_bridge(struct venus_hfi_device *device) +int __reset_ahb2axi_bridge_common(struct venus_hfi_device *device) { int rc, i; @@ -4179,7 +4171,7 @@ static int __enable_regulators(struct venus_hfi_device *device) return rc; } -static int __disable_regulators(struct venus_hfi_device *device) +int __disable_regulators(struct venus_hfi_device *device) { struct regulator_info *rinfo; @@ -4355,50 +4347,6 @@ static int __disable_subcaches(struct venus_hfi_device *device) return 0; } -static void interrupt_init_iris1(struct venus_hfi_device *device) -{ - u32 mask_val = 0; - - /* All interrupts should be disabled initially 0x1F6 : Reset value */ - mask_val = __read_register(device, VIDC_WRAPPER_INTR_MASK); - - /* Write 0 to unmask CPU and WD interrupts */ - mask_val &= ~(VIDC_WRAPPER_INTR_MASK_A2HWD_BMSK | - VIDC_WRAPPER_INTR_MASK_A2HCPU_BMSK); - __write_register(device, VIDC_WRAPPER_INTR_MASK, mask_val); -} - -static void interrupt_init_vpu4(struct venus_hfi_device *device) -{ - __write_register(device, VIDC_WRAPPER_INTR_MASK, - VIDC_WRAPPER_INTR_MASK_A2HVCODEC_BMSK); -} - -static void setup_dsp_uc_memmap_iris1(struct venus_hfi_device *device) -{ - /* initialize DSP QTBL & UCREGION with CPU queues */ - __write_register(device, HFI_DSP_QTBL_ADDR, - (u32)device->iface_q_table.align_device_addr); - __write_register(device, HFI_DSP_UC_REGION_ADDR, - (u32)device->iface_q_table.align_device_addr); - __write_register(device, HFI_DSP_UC_REGION_SIZE, SHARED_QSIZE); - if (device->res->domain_cvp) { - __write_register(device, HFI_DSP_QTBL_ADDR, - (u32)device->dsp_iface_q_table.align_device_addr); - __write_register(device, HFI_DSP_UC_REGION_ADDR, - (u32)device->dsp_iface_q_table.align_device_addr); - __write_register(device, HFI_DSP_UC_REGION_SIZE, - device->dsp_iface_q_table.mem_data.size); - } -} - -static void clock_config_on_enable_iris1(struct venus_hfi_device *device) -{ - __write_register(device, VIDC_WRAPPER_CPU_CGC_DIS, 0); - __write_register(device, VIDC_WRAPPER_CPU_CLOCK_CONFIG, 0); -} - - static int __set_ubwc_config(struct venus_hfi_device *device) { u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE]; @@ -4503,12 +4451,12 @@ static int __venus_power_on(struct venus_hfi_device *device) return rc; } -static void power_off_common(struct venus_hfi_device *device) +static void __power_off_common(struct venus_hfi_device *device) { if (!device->power_enabled) return; - if (!(device->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK)) + if (!(device->intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK)) disable_irq_nosync(device->hal_data->irq); device->intr_status = 0; @@ -4524,93 +4472,6 @@ static void power_off_common(struct venus_hfi_device *device) device->power_enabled = false; } -static void power_off_iris2(struct venus_hfi_device *device) -{ - u32 lpi_status, reg_status = 0, count = 0, max_count = 10; - - if (!device->power_enabled) - return; - - if (!(device->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK)) - disable_irq_nosync(device->hal_data->irq); - device->intr_status = 0; - - /* HPG 6.1.2 Step 1 */ - __write_register(device, VIDC_CPU_CS_X2RPMh, 0x3); - - /* HPG 6.1.2 Step 2, noc to low power */ - __write_register(device, VIDC_AON_WRAPPER_MVP_NOC_LPI_CONTROL, 0x1); - while (!reg_status && count < max_count) { - lpi_status = - __read_register(device, - VIDC_AON_WRAPPER_MVP_NOC_LPI_STATUS); - reg_status = lpi_status & BIT(0); - dprintk(VIDC_DBG, - "Noc: lpi_status %d noc_status %d (count %d)\n", - lpi_status, reg_status, count); - usleep_range(50, 100); - count++; - } - if (count == max_count) { - dprintk(VIDC_ERR, - "NOC not in qaccept status %d\n", reg_status); - } - - /* HPG 6.1.2 Step 3, debug bridge to low power */ - __write_register(device, - VIDC_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL, 0x7); - reg_status = 0; - count = 0; - while ((reg_status != 0x7) && count < max_count) { - lpi_status = __read_register(device, - VIDC_WRAPPER_DEBUG_BRIDGE_LPI_STATUS); - reg_status = lpi_status & 0x7; - dprintk(VIDC_DBG, - "DBLP Set : lpi_status %d reg_status %d (count %d)\n", - lpi_status, reg_status, count); - usleep_range(50, 100); - count++; - } - if (count == max_count) { - dprintk(VIDC_ERR, - "DBLP Set: status %d\n", reg_status); - } - - /* HPG 6.1.2 Step 4, debug bridge to lpi release */ - __write_register(device, - VIDC_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL, 0x0); - lpi_status = 0x1; - count = 0; - while (lpi_status && count < max_count) { - lpi_status = __read_register(device, - VIDC_WRAPPER_DEBUG_BRIDGE_LPI_STATUS); - dprintk(VIDC_DBG, - "DBLP Release: lpi_status %d(count %d)\n", - lpi_status, count); - usleep_range(50, 100); - count++; - } - if (count == max_count) { - dprintk(VIDC_ERR, - "DBLP Release: lpi_status %d\n", lpi_status); - } - - /* HPG 6.1.2 Step 6 */ - __disable_unprepare_clks(device); - - /* HPG 6.1.2 Step 7 & 8 */ - if (call_venus_op(device, reset_ahb2axi_bridge, device)) - dprintk(VIDC_ERR, "Failed to reset ahb2axi\n"); - - /* HPG 6.1.2 Step 5 */ - if (__disable_regulators(device)) - dprintk(VIDC_WARN, "Failed to disable regulators\n"); - - if (__unvote_buses(device)) - dprintk(VIDC_WARN, "Failed to unvote for buses\n"); - device->power_enabled = false; -} - static inline int __suspend(struct venus_hfi_device *device) { int rc = 0; @@ -4674,20 +4535,15 @@ static inline int __resume(struct venus_hfi_device *device) goto err_set_video_state; } - __setup_ucregion_memory_map(device); + call_venus_op(device, setup_ucregion_memmap, device); + /* Wait for boot completion */ - rc = __boot_firmware(device); + rc = call_venus_op(device, boot_firmware, device); if (rc) { dprintk(VIDC_ERR, "Failed to reset venus core\n"); goto err_reset_core; } - /* - * Work around for H/W bug, need to reprogram these registers once - * firmware is out reset - */ - __set_threshold_registers(device); - if (device->res->pm_qos_latency_us) { #ifdef CONFIG_SMP device->qos.type = PM_QOS_REQ_AFFINE_IRQ; @@ -4926,7 +4782,7 @@ static void __noc_error_info(struct venus_hfi_device *device, u32 core_num) dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG3_HIGH: %#x\n", core_num, val); } -static void noc_error_info_common(struct venus_hfi_device *device) +static void __noc_error_info_common(struct venus_hfi_device *device) { const u32 core0 = 0, core1 = 1; @@ -4939,38 +4795,6 @@ static void noc_error_info_common(struct venus_hfi_device *device) __noc_error_info(device, core1); } -static void noc_error_info_iris2(struct venus_hfi_device *device) -{ - u32 val = 0; - - val = __read_register(device, VCODEC_NOC_ERL_MAIN_SWID_LOW); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_SWID_LOW: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_SWID_HIGH); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_SWID_HIGH: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_MAINCTL_LOW); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_MAINCTL_LOW: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRVLD_LOW); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRVLD_LOW: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRCLR_LOW); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRCLR_LOW: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val); -} - static int venus_hfi_noc_error_info(void *dev) { struct venus_hfi_device *device; diff --git a/msm/vidc/venus_hfi.h b/msm/vidc/hfi_common.h similarity index 81% rename from msm/vidc/venus_hfi.h rename to msm/vidc/hfi_common.h index 2bc1890c8a34..c519f2f41f96 100644 --- a/msm/vidc/venus_hfi.h +++ b/msm/vidc/hfi_common.h @@ -3,8 +3,8 @@ * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ -#ifndef __H_VENUS_HFI_H__ -#define __H_VENUS_HFI_H__ +#ifndef __HFI_COMMON_H__ +#define __HFI_COMMON_H__ #include #include @@ -234,12 +234,17 @@ enum reset_state { struct venus_hfi_device; struct venus_hfi_vpu_ops { - void (*interrupt_init)(struct venus_hfi_device *ptr); - void (*setup_dsp_uc_memmap)(struct venus_hfi_device *device); + void (*interrupt_init)(struct venus_hfi_device *device); + void (*setup_ucregion_memmap)(struct venus_hfi_device *device); void (*clock_config_on_enable)(struct venus_hfi_device *device); int (*reset_ahb2axi_bridge)(struct venus_hfi_device *device); void (*power_off)(struct venus_hfi_device *device); + int (*prepare_pc)(struct venus_hfi_device *device); + void (*raise_interrupt)(struct venus_hfi_device *device); + bool (*watchdog)(u32 intr_status); void (*noc_error_info)(struct venus_hfi_device *device); + void (*core_clear_interrupt)(struct venus_hfi_device *device); + int (*boot_firmware)(struct venus_hfi_device *device); }; struct venus_hfi_device { @@ -286,4 +291,30 @@ int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id, struct msm_vidc_platform_resources *res, hfi_cmd_response_callback callback); +void __write_register(struct venus_hfi_device *device, u32 reg, u32 value); +int __read_register(struct venus_hfi_device *device, u32 reg); +void __disable_unprepare_clks(struct venus_hfi_device *device); +int __disable_regulators(struct venus_hfi_device *device); +int __unvote_buses(struct venus_hfi_device *device); +int __reset_ahb2axi_bridge_common(struct venus_hfi_device *device); +int __prepare_pc(struct venus_hfi_device *device); + +/* AR50 specific */ +void __interrupt_init_ar50(struct venus_hfi_device *device); +/* IRIS1 specific */ +void __interrupt_init_iris1(struct venus_hfi_device *device); +void __setup_dsp_uc_memmap_iris1(struct venus_hfi_device *device); +void __clock_config_on_enable_iris1(struct venus_hfi_device *device); +void __setup_ucregion_memory_map_iris1(struct venus_hfi_device *device); +/* IRIS2 specific */ +void __interrupt_init_iris2(struct venus_hfi_device *device); +void __setup_ucregion_memory_map_iris2(struct venus_hfi_device *device); +void __power_off_iris2(struct venus_hfi_device *device); +int __prepare_pc_iris2(struct venus_hfi_device *device); +void __raise_interrupt_iris2(struct venus_hfi_device *device); +bool __watchdog_iris2(u32 intr_status); +void __noc_error_info_iris2(struct venus_hfi_device *device); +void __core_clear_interrupt_iris2(struct venus_hfi_device *device); +int __boot_firmware_iris2(struct venus_hfi_device *device); + #endif diff --git a/msm/vidc/hfi_io_common.h b/msm/vidc/hfi_io_common.h new file mode 100644 index 000000000000..2d42fdaa381e --- /dev/null +++ b/msm/vidc/hfi_io_common.h @@ -0,0 +1,139 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#ifndef __HFI_IO_COMMON_H__ +#define __HFI_IO_COMMON_H__ + +#include + +#define VBIF_BASE_OFFS 0x00080000 + +#define CPU_BASE_OFFS 0x000C0000 +#define CPU_CS_BASE_OFFS (CPU_BASE_OFFS + 0x00012000) +#define CPU_IC_BASE_OFFS (CPU_BASE_OFFS + 0x0001F000) + +#define CPU_CS_A2HSOFTINT (CPU_CS_BASE_OFFS + 0x18) +#define CPU_CS_A2HSOFTINTCLR (CPU_CS_BASE_OFFS + 0x1C) +#define CPU_CS_VMIMSG (CPU_CS_BASE_OFFS + 0x34) +#define CPU_CS_VMIMSGAG0 (CPU_CS_BASE_OFFS + 0x38) +#define CPU_CS_VMIMSGAG1 (CPU_CS_BASE_OFFS + 0x3C) +#define CPU_CS_SCIACMD (CPU_CS_BASE_OFFS + 0x48) + +/* HFI_CTRL_STATUS */ +#define CPU_CS_SCIACMDARG0 (CPU_CS_BASE_OFFS + 0x4C) +#define CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK 0xfe +#define CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY 0x100 +#define CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK 0x40000000 + +/* HFI_QTBL_INFO */ +#define CPU_CS_SCIACMDARG1 (CPU_CS_BASE_OFFS + 0x50) + +/* HFI_QTBL_ADDR */ +#define CPU_CS_SCIACMDARG2 (CPU_CS_BASE_OFFS + 0x54) + +/* HFI_VERSION_INFO */ +#define CPU_CS_SCIACMDARG3 (CPU_CS_BASE_OFFS + 0x58) + +/* SFR_ADDR */ +#define CPU_CS_SCIBCMD (CPU_CS_BASE_OFFS + 0x5C) + +/* MMAP_ADDR */ +#define CPU_CS_SCIBCMDARG0 (CPU_CS_BASE_OFFS + 0x60) + +/* UC_REGION_ADDR */ +#define CPU_CS_SCIBARG1 (CPU_CS_BASE_OFFS + 0x64) + +/* UC_REGION_ADDR */ +#define CPU_CS_SCIBARG2 (CPU_CS_BASE_OFFS + 0x68) + +#define CPU_IC_SOFTINT (CPU_IC_BASE_OFFS + 0x18) +#define CPU_IC_SOFTINT_H2A_SHFT 0xF + +/* + * -------------------------------------------------------------------------- + * MODULE: wrapper + * -------------------------------------------------------------------------- + */ +#define WRAPPER_BASE_OFFS 0x000E0000 +#define WRAPPER_INTR_STATUS (WRAPPER_BASE_OFFS + 0x0C) +#define WRAPPER_INTR_STATUS_A2HWD_BMSK 0x10 +#define WRAPPER_INTR_STATUS_A2H_BMSK 0x4 + +#define WRAPPER_INTR_MASK (WRAPPER_BASE_OFFS + 0x10) +#define WRAPPER_INTR_MASK_A2HWD_BMSK 0x10 +#define WRAPPER_INTR_MASK_A2HVCODEC_BMSK 0x8 +#define WRAPPER_INTR_MASK_A2HCPU_BMSK 0x4 +#define WRAPPER_INTR_CLEAR (WRAPPER_BASE_OFFS + 0x14) + +#define WRAPPER_CPU_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x2000) +#define WRAPPER_CPU_CGC_DIS (WRAPPER_BASE_OFFS + 0x2010) +#define WRAPPER_CPU_STATUS (WRAPPER_BASE_OFFS + 0x2014) + +#define CTRL_INIT CPU_CS_SCIACMD + +#define CTRL_STATUS CPU_CS_SCIACMDARG0 +#define CTRL_ERROR_STATUS__M \ + CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK +#define CTRL_INIT_IDLE_MSG_BMSK \ + CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK +#define CTRL_STATUS_PC_READY \ + CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY + + +#define QTBL_INFO CPU_CS_SCIACMDARG1 + +#define QTBL_ADDR CPU_CS_SCIACMDARG2 + +#define VERSION_INFO CPU_CS_SCIACMDARG3 + +#define SFR_ADDR CPU_CS_SCIBCMD +#define MMAP_ADDR CPU_CS_SCIBCMDARG0 +#define UC_REGION_ADDR CPU_CS_SCIBARG1 +#define UC_REGION_SIZE CPU_CS_SCIBARG2 + +/* HFI_DSP_QTBL_ADDR + * 31:3 - HFI_DSP_QTBL_ADDR + * 4-byte aligned Address + */ +#define HFI_DSP_QTBL_ADDR CPU_CS_VMIMSG + +/* HFI_DSP_UC_REGION_ADDR + * 31:20 - HFI_DSP_UC_REGION_ADDR + * 1MB aligned address. + * Uncached Region start Address. This region covers + * HFI DSP QTable, + * HFI DSP Queue Headers, + * HFI DSP Queues, + */ +#define HFI_DSP_UC_REGION_ADDR CPU_CS_VMIMSGAG0 + +/* HFI_DSP_UC_REGION_SIZE + * 31:20 - HFI_DSP_UC_REGION_SIZE + * Multiples of 1MB. + * Size of the DSP_UC_REGION Uncached Region + */ +#define HFI_DSP_UC_REGION_SIZE CPU_CS_VMIMSGAG1 + +/* + * -------------------------------------------------------------------------- + * MODULE: vcodec noc error log registers + * -------------------------------------------------------------------------- + */ +#define VCODEC_CORE0_VIDEO_NOC_BASE_OFFS 0x00004000 +#define VCODEC_CORE1_VIDEO_NOC_BASE_OFFS 0x0000C000 +#define VCODEC_COREX_VIDEO_NOC_ERR_SWID_LOW_OFFS 0x0500 +#define VCODEC_COREX_VIDEO_NOC_ERR_SWID_HIGH_OFFS 0x0504 +#define VCODEC_COREX_VIDEO_NOC_ERR_MAINCTL_LOW_OFFS 0x0508 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS 0x0510 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRCLR_LOW_OFFS 0x0518 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_LOW_OFFS 0x0520 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_HIGH_OFFS 0x0524 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_LOW_OFFS 0x0528 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_HIGH_OFFS 0x052C +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_LOW_OFFS 0x0530 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_HIGH_OFFS 0x0534 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_LOW_OFFS 0x0538 +#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_HIGH_OFFS 0x053C +#endif diff --git a/msm/vidc/hfi_iris1.c b/msm/vidc/hfi_iris1.c new file mode 100644 index 000000000000..faf1e075691b --- /dev/null +++ b/msm/vidc/hfi_iris1.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include "hfi_common.h" +#include "hfi_io_common.h" + +void __interrupt_init_iris1(struct venus_hfi_device *device) +{ + u32 mask_val = 0; + + /* All interrupts should be disabled initially 0x1F6 : Reset value */ + mask_val = __read_register(device, WRAPPER_INTR_MASK); + + /* Write 0 to unmask CPU and WD interrupts */ + mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BMSK | + WRAPPER_INTR_MASK_A2HCPU_BMSK); + __write_register(device, WRAPPER_INTR_MASK, mask_val); +} + +void __setup_ucregion_memory_map_iris1(struct venus_hfi_device *device) +{ + /* initialize CPU QTBL & UCREGION */ + __write_register(device, UC_REGION_ADDR, + (u32)device->iface_q_table.align_device_addr); + __write_register(device, UC_REGION_SIZE, SHARED_QSIZE); + __write_register(device, QTBL_ADDR, + (u32)device->iface_q_table.align_device_addr); + __write_register(device, QTBL_INFO, 0x01); + if (device->sfr.align_device_addr) + __write_register(device, SFR_ADDR, + (u32)device->sfr.align_device_addr); + if (device->qdss.align_device_addr) + __write_register(device, MMAP_ADDR, + (u32)device->qdss.align_device_addr); + + /* initialize DSP QTBL & UCREGION with CPU queues by default */ + __write_register(device, HFI_DSP_QTBL_ADDR, + (u32)device->iface_q_table.align_device_addr); + __write_register(device, HFI_DSP_UC_REGION_ADDR, + (u32)device->iface_q_table.align_device_addr); + __write_register(device, HFI_DSP_UC_REGION_SIZE, SHARED_QSIZE); + if (device->res->domain_cvp) { + /* initialize DSP QTBL & UCREGION with DSP queues */ + __write_register(device, HFI_DSP_QTBL_ADDR, + (u32)device->dsp_iface_q_table.align_device_addr); + __write_register(device, HFI_DSP_UC_REGION_ADDR, + (u32)device->dsp_iface_q_table.align_device_addr); + __write_register(device, HFI_DSP_UC_REGION_SIZE, + device->dsp_iface_q_table.mem_data.size); + } +} + +void __clock_config_on_enable_iris1(struct venus_hfi_device *device) +{ + __write_register(device, WRAPPER_CPU_CGC_DIS, 0); + __write_register(device, WRAPPER_CPU_CLOCK_CONFIG, 0); +} + diff --git a/msm/vidc/hfi_iris2.c b/msm/vidc/hfi_iris2.c new file mode 100644 index 000000000000..4fd4dc415289 --- /dev/null +++ b/msm/vidc/hfi_iris2.c @@ -0,0 +1,411 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include "msm_vidc_debug.h" +#include "hfi_common.h" + +#define VBIF_BASE_OFFS_IRIS2 0x00080000 + +#define CPU_BASE_OFFS_IRIS2 0x000A0000 +#define AON_BASE_OFFS 0x000E0000 +#define CPU_CS_BASE_OFFS_IRIS2 (CPU_BASE_OFFS_IRIS2) +#define CPU_IC_BASE_OFFS_IRIS2 (CPU_BASE_OFFS_IRIS2) + +#define CPU_CS_A2HSOFTINTCLR_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x1C) +#define CPU_CS_VMIMSG_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x34) +#define CPU_CS_VMIMSGAG0_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x38) +#define CPU_CS_VMIMSGAG1_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x3C) +#define CPU_CS_SCIACMD_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x48) +#define CPU_CS_H2XSOFTINTEN_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x148) + +/* HFI_CTRL_STATUS */ +#define CPU_CS_SCIACMDARG0_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x4C) +#define CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_IRIS2 0xfe +#define CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY_IRIS2 0x100 +#define CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK_IRIS2 0x40000000 + +/* HFI_QTBL_INFO */ +#define CPU_CS_SCIACMDARG1_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x50) + +/* HFI_QTBL_ADDR */ +#define CPU_CS_SCIACMDARG2_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x54) + +/* HFI_VERSION_INFO */ +#define CPU_CS_SCIACMDARG3_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x58) + +/* SFR_ADDR */ +#define CPU_CS_SCIBCMD_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x5C) + +/* MMAP_ADDR */ +#define CPU_CS_SCIBCMDARG0_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x60) + +/* UC_REGION_ADDR */ +#define CPU_CS_SCIBARG1_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x64) + +/* UC_REGION_ADDR */ +#define CPU_CS_SCIBARG2_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x68) + +/* FAL10 Feature Control */ +#define CPU_CS_X2RPMh_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x168) +#define CPU_CS_X2RPMh_MASK0_BMSK_IRIS2 0x1 +#define CPU_CS_X2RPMh_MASK0_SHFT_IRIS2 0x0 +#define CPU_CS_X2RPMh_MASK1_BMSK_IRIS2 0x2 +#define CPU_CS_X2RPMh_MASK1_SHFT_IRIS2 0x1 +#define CPU_CS_X2RPMh_SWOVERRIDE_BMSK_IRIS2 0x4 +#define CPU_CS_X2RPMh_SWOVERRIDE_SHFT_IRIS2 0x3 + +#define CPU_IC_SOFTINT_IRIS2 (CPU_IC_BASE_OFFS_IRIS2 + 0x150) +#define CPU_IC_SOFTINT_H2A_SHFT_IRIS2 0x0 + +/* + * -------------------------------------------------------------------------- + * MODULE: wrapper + * -------------------------------------------------------------------------- + */ +#define WRAPPER_BASE_OFFS_IRIS2 0x000B0000 +#define WRAPPER_INTR_STATUS_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x0C) +#define WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2 0x8 +#define WRAPPER_INTR_STATUS_A2H_BMSK_IRIS2 0x4 + +#define WRAPPER_INTR_MASK_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x10) +#define WRAPPER_INTR_MASK_A2HWD_BMSK_IRIS2 0x8 +#define WRAPPER_INTR_MASK_A2HCPU_BMSK_IRIS2 0x4 + +#define WRAPPER_CPU_CLOCK_CONFIG_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x2000) +#define WRAPPER_CPU_CGC_DIS_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x2010) +#define WRAPPER_CPU_STATUS_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x2014) + +#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x54) +#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x58) +/* + * -------------------------------------------------------------------------- + * MODULE: tz_wrapper + * -------------------------------------------------------------------------- + */ +#define WRAPPER_TZ_BASE_OFFS 0x000C0000 +#define WRAPPER_TZ_CPU_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS) +#define WRAPPER_TZ_CPU_STATUS (WRAPPER_TZ_BASE_OFFS + 0x10) + +#define CTRL_INIT_IRIS2 CPU_CS_SCIACMD_IRIS2 + +#define CTRL_STATUS_IRIS2 CPU_CS_SCIACMDARG0_IRIS2 +#define CTRL_ERROR_STATUS__M_IRIS2 \ + CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_IRIS2 +#define CTRL_INIT_IDLE_MSG_BMSK_IRIS2 \ + CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK_IRIS2 +#define CTRL_STATUS_PC_READY_IRIS2 \ + CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY_IRIS2 + + +#define QTBL_INFO_IRIS2 CPU_CS_SCIACMDARG1_IRIS2 + +#define QTBL_ADDR_IRIS2 CPU_CS_SCIACMDARG2_IRIS2 + +#define VERSION_INFO_IRIS2 CPU_CS_SCIACMDARG3_IRIS2 + +#define SFR_ADDR_IRIS2 CPU_CS_SCIBCMD_IRIS2 +#define MMAP_ADDR_IRIS2 CPU_CS_SCIBCMDARG0_IRIS2 +#define UC_REGION_ADDR_IRIS2 CPU_CS_SCIBARG1_IRIS2 +#define UC_REGION_SIZE_IRIS2 CPU_CS_SCIBARG2_IRIS2 + +#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS) +#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4) + +/* + * -------------------------------------------------------------------------- + * MODULE: vcodec noc error log registers (iris2) + * -------------------------------------------------------------------------- + */ +#define VCODEC_NOC_VIDEO_A_NOC_BASE_OFFS 0x00010000 +#define VCODEC_NOC_ERL_MAIN_SWID_LOW 0x00011200 +#define VCODEC_NOC_ERL_MAIN_SWID_HIGH 0x00011204 +#define VCODEC_NOC_ERL_MAIN_MAINCTL_LOW 0x00011208 +#define VCODEC_NOC_ERL_MAIN_ERRVLD_LOW 0x00011210 +#define VCODEC_NOC_ERL_MAIN_ERRCLR_LOW 0x00011218 +#define VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW 0x00011220 +#define VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH 0x00011224 +#define VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW 0x00011228 +#define VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH 0x0001122C +#define VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW 0x00011230 +#define VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH 0x00011234 +#define VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW 0x00011238 +#define VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH 0x0001123C + +void __interrupt_init_iris2(struct venus_hfi_device *device) +{ + u32 mask_val = 0; + + /* All interrupts should be disabled initially 0x1F6 : Reset value */ + mask_val = __read_register(device, WRAPPER_INTR_MASK_IRIS2); + + /* Write 0 to unmask CPU and WD interrupts */ + mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BMSK_IRIS2| + WRAPPER_INTR_MASK_A2HCPU_BMSK_IRIS2); + __write_register(device, WRAPPER_INTR_MASK_IRIS2, mask_val); +} + +void __setup_ucregion_memory_map_iris2(struct venus_hfi_device *device) +{ + __write_register(device, UC_REGION_ADDR_IRIS2, + (u32)device->iface_q_table.align_device_addr); + __write_register(device, UC_REGION_SIZE_IRIS2, SHARED_QSIZE); + __write_register(device, QTBL_ADDR_IRIS2, + (u32)device->iface_q_table.align_device_addr); + __write_register(device, QTBL_INFO_IRIS2, 0x01); + if (device->sfr.align_device_addr) + __write_register(device, SFR_ADDR_IRIS2, + (u32)device->sfr.align_device_addr); + if (device->qdss.align_device_addr) + __write_register(device, MMAP_ADDR_IRIS2, + (u32)device->qdss.align_device_addr); +} + +void __power_off_iris2(struct venus_hfi_device *device) +{ + u32 lpi_status, reg_status = 0, count = 0, max_count = 10; + + if (!device->power_enabled) + return; + + if (!(device->intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2)) + disable_irq_nosync(device->hal_data->irq); + device->intr_status = 0; + + /* HPG 6.1.2 Step 1 */ + __write_register(device, CPU_CS_X2RPMh_IRIS2, 0x3); + + /* HPG 6.1.2 Step 2, noc to low power */ + __write_register(device, AON_WRAPPER_MVP_NOC_LPI_CONTROL, 0x1); + while (!reg_status && count < max_count) { + lpi_status = + __read_register(device, + AON_WRAPPER_MVP_NOC_LPI_STATUS); + reg_status = lpi_status & BIT(0); + dprintk(VIDC_DBG, + "Noc: lpi_status %d noc_status %d (count %d)\n", + lpi_status, reg_status, count); + usleep_range(50, 100); + count++; + } + if (count == max_count) { + dprintk(VIDC_ERR, + "NOC not in qaccept status %d\n", reg_status); + } + + /* HPG 6.1.2 Step 3, debug bridge to low power */ + __write_register(device, + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2, 0x7); + reg_status = 0; + count = 0; + while ((reg_status != 0x7) && count < max_count) { + lpi_status = __read_register(device, + WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2); + reg_status = lpi_status & 0x7; + dprintk(VIDC_DBG, + "DBLP Set : lpi_status %d reg_status %d (count %d)\n", + lpi_status, reg_status, count); + usleep_range(50, 100); + count++; + } + if (count == max_count) { + dprintk(VIDC_ERR, + "DBLP Set: status %d\n", reg_status); + } + + /* HPG 6.1.2 Step 4, debug bridge to lpi release */ + __write_register(device, + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2, 0x0); + lpi_status = 0x1; + count = 0; + while (lpi_status && count < max_count) { + lpi_status = __read_register(device, + WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2); + dprintk(VIDC_DBG, + "DBLP Release: lpi_status %d(count %d)\n", + lpi_status, count); + usleep_range(50, 100); + count++; + } + if (count == max_count) { + dprintk(VIDC_ERR, + "DBLP Release: lpi_status %d\n", lpi_status); + } + + /* HPG 6.1.2 Step 6 */ + __disable_unprepare_clks(device); + + /* HPG 6.1.2 Step 7 & 8 */ + if (call_venus_op(device, reset_ahb2axi_bridge, device)) + dprintk(VIDC_ERR, "Failed to reset ahb2axi\n"); + + /* HPG 6.1.2 Step 5 */ + if (__disable_regulators(device)) + dprintk(VIDC_WARN, "Failed to disable regulators\n"); + + if (__unvote_buses(device)) + dprintk(VIDC_WARN, "Failed to unvote for buses\n"); + device->power_enabled = false; +} + +int __prepare_pc_iris2(struct venus_hfi_device *device) +{ + int rc = 0; + u32 wfi_status = 0, idle_status = 0, pc_ready = 0; + u32 ctrl_status = 0; + int count = 0; + const int max_tries = 10; + + ctrl_status = __read_register(device, CTRL_STATUS_IRIS2); + pc_ready = ctrl_status & CTRL_STATUS_PC_READY_IRIS2; + idle_status = ctrl_status & BIT(30); + + if (pc_ready) { + dprintk(VIDC_DBG, "Already in pc_ready state\n"); + return 0; + } + + wfi_status = BIT(0) & __read_register(device, + WRAPPER_TZ_CPU_STATUS); + if (!wfi_status || !idle_status) { + dprintk(VIDC_WARN, "Skipping PC, wfi status not set\n"); + goto skip_power_off; + } + + rc = __prepare_pc(device); + if (rc) { + dprintk(VIDC_WARN, "Failed __prepare_pc %d\n", rc); + goto skip_power_off; + } + + while (count < max_tries) { + wfi_status = BIT(0) & __read_register(device, + WRAPPER_TZ_CPU_STATUS); + ctrl_status = __read_register(device, CTRL_STATUS_IRIS2); + if (wfi_status && (ctrl_status & CTRL_STATUS_PC_READY_IRIS2)) + break; + usleep_range(150, 250); + count++; + } + + if (count == max_tries) { + dprintk(VIDC_ERR, "Skip PC. Core is not in right state\n"); + goto skip_power_off; + } + + return rc; + +skip_power_off: + dprintk(VIDC_WARN, "Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n", + wfi_status, idle_status, pc_ready, ctrl_status); + return -EAGAIN; +} + +void __raise_interrupt_iris2(struct venus_hfi_device *device) +{ + __write_register(device, CPU_IC_SOFTINT_IRIS2, + 1 << CPU_IC_SOFTINT_H2A_SHFT_IRIS2); +} + +bool __watchdog_iris2(u32 intr_status) +{ + bool rc = false; + + if (intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2) + rc = true; + + return rc; +} + +void __noc_error_info_iris2(struct venus_hfi_device *device) +{ + u32 val = 0; + + val = __read_register(device, VCODEC_NOC_ERL_MAIN_SWID_LOW); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_SWID_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_SWID_HIGH); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_SWID_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_MAINCTL_LOW); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_MAINCTL_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRVLD_LOW); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRVLD_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRCLR_LOW); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRCLR_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH); + dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val); +} + +void __core_clear_interrupt_iris2(struct venus_hfi_device *device) +{ + u32 intr_status = 0, mask = 0; + + if (!device) { + dprintk(VIDC_ERR, "%s: NULL device\n", __func__); + return; + } + + intr_status = __read_register(device, WRAPPER_INTR_STATUS_IRIS2); + mask = (WRAPPER_INTR_STATUS_A2H_BMSK_IRIS2| + WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2| + CTRL_INIT_IDLE_MSG_BMSK_IRIS2); + + if (intr_status & mask) { + device->intr_status |= intr_status; + device->reg_count++; + dprintk(VIDC_DBG, + "INTERRUPT for device: %pK: times: %d interrupt_status: %d\n", + device, device->reg_count, intr_status); + } else { + device->spur_count++; + } + + __write_register(device, CPU_CS_A2HSOFTINTCLR_IRIS2, 1); +} + +int __boot_firmware_iris2(struct venus_hfi_device *device) +{ + int rc = 0; + u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 10000; + + ctrl_init_val = BIT(0); + if (device->res->domain_cvp) + ctrl_init_val |= BIT(1); + + __write_register(device, CTRL_INIT_IRIS2, ctrl_init_val); + while (!ctrl_status && count < max_tries) { + ctrl_status = __read_register(device, CTRL_STATUS_IRIS2); + if ((ctrl_status & CTRL_ERROR_STATUS__M_IRIS2) == 0x4) { + dprintk(VIDC_ERR, "invalid setting for UC_REGION\n"); + break; + } + + usleep_range(50, 100); + count++; + } + + if (count >= max_tries) { + dprintk(VIDC_ERR, "Error booting up vidc firmware\n"); + rc = -ETIME; + } + + /* Enable interrupt before sending commands to venus */ + __write_register(device, CPU_CS_H2XSOFTINTEN_IRIS2, 0x1); + __write_register(device, CPU_CS_X2RPMh_IRIS2, 0x0); + + return rc; +} diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index ef55a3a3f28a..a97d95cb3627 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -11,7 +11,6 @@ #include #include #include "vidc_hfi_helper.h" -#include "vidc_hfi_io.h" #include "msm_vidc_debug.h" #include "vidc_hfi.h" diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 8d1256cdf1ce..a42802d5267b 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1391,16 +1391,13 @@ static int msm_venc_resolve_rc_enable(struct msm_vidc_inst *inst, static int msm_venc_resolve_rate_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) { - struct v4l2_ctrl *rc_enable; - if (inst->rc_type == RATE_CONTROL_LOSSLESS) { dprintk(VIDC_DBG, "Skip RC mode when enabling lossless encoding\n"); return 0; } - rc_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE); - if (!rc_enable->val) { + if (inst->rc_type == RATE_CONTROL_OFF) { dprintk(VIDC_ERR, "RC is not enabled.\n"); return -EINVAL; @@ -2617,7 +2614,6 @@ int msm_venc_set_frame_qp(struct msm_vidc_inst *inst) struct v4l2_ctrl *i_qp = NULL; struct v4l2_ctrl *p_qp = NULL; struct v4l2_ctrl *b_qp = NULL; - struct v4l2_ctrl *rc_enable = NULL; struct hfi_quantization qp; if (!inst || !inst->core) { @@ -2633,7 +2629,6 @@ int msm_venc_set_frame_qp(struct msm_vidc_inst *inst) i_qp = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP); p_qp = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP); b_qp = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP); - rc_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE); /* * When RC is ON: @@ -2642,7 +2637,7 @@ int msm_venc_set_frame_qp(struct msm_vidc_inst *inst) * I_QP value must be set by client. * If other QP value is invalid, then, assign I_QP value to it. */ - if (rc_enable->val) { + if (inst->rc_type != RATE_CONTROL_OFF) { if (!(inst->client_set_ctrls & CLIENT_SET_I_QP)) qp.enable &= ~QP_ENABLE_I; if (!(inst->client_set_ctrls & CLIENT_SET_P_QP)) @@ -2829,7 +2824,6 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst) u32 mb_per_frame, fps, mbps, bitrate, max_slices; u32 slice_val, slice_mode, max_avg_slicesize; u32 rc_mode, output_width, output_height; - struct v4l2_ctrl *rc_enable; u32 codec; if (!inst || !inst->core) { @@ -2845,13 +2839,11 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst) slice_val = 0; bitrate = inst->clk_data.bitrate; - fps = inst->clk_data.frame_rate; + fps = inst->clk_data.frame_rate >> 16; rc_mode = inst->rc_type; - rc_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE); - if (fps > 60 || - (rc_enable->val && - rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR && - rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)) { + if (fps > 60 || (!(rc_mode == RATE_CONTROL_OFF || + rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR || + rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR))) { goto set_and_exit; } @@ -2896,8 +2888,11 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst) mbps <= NUM_MBS_PER_SEC(1088, 1920, 60)) { max_slices = inst->capability.cap[CAP_SLICE_BYTE].max ? inst->capability.cap[CAP_SLICE_BYTE].max : 1; - max_avg_slicesize = ((bitrate / fps) / 8) / max_slices; - slice_val = max(slice_val, max_avg_slicesize); + if (rc_mode != RATE_CONTROL_OFF) { + max_avg_slicesize = + ((bitrate / fps) / 8) / max_slices; + slice_val = max(slice_val, max_avg_slicesize); + } } } @@ -2928,7 +2923,6 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst) int rc = 0; struct hfi_device *hdev; struct v4l2_ctrl *ctrl = NULL; - struct v4l2_ctrl *rc_mode = NULL; struct hfi_intra_refresh intra_refresh; struct v4l2_format *f; @@ -2938,9 +2932,8 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst) } hdev = inst->core->device; - rc_mode = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE_MODE); - if (!(rc_mode->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR || - rc_mode->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)) + if (!(inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR || + inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)) return 0; /* Firmware supports only random mode */ @@ -3616,6 +3609,11 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) if (!(codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264)) return 0; + if (!(inst->rc_type == RATE_CONTROL_OFF || + inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR || + inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR)) + return 0; + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); if (!ctrl->val) return 0; @@ -3706,7 +3704,6 @@ int msm_venc_set_dyn_qp(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) int rc = 0; struct hfi_device *hdev; struct hfi_quantization qp; - struct v4l2_ctrl *rc_enable; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); @@ -3714,8 +3711,7 @@ int msm_venc_set_dyn_qp(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } hdev = inst->core->device; - rc_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE); - if (rc_enable->val) { + if (inst->rc_type != RATE_CONTROL_OFF) { dprintk(VIDC_ERR, "%s: Dyn qp is set only when RC is OFF\n", __func__); return -EINVAL; @@ -3958,6 +3954,9 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) if (rc) goto exit; rc = msm_venc_set_rate_control(inst); + if (rc) + goto exit; + rc = msm_venc_set_vbv_delay(inst); if (rc) goto exit; rc = msm_venc_set_bitrate_savings_mode(inst); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 72e4a0cb310f..5a633cd0f5df 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1432,12 +1432,6 @@ static void msm_vidc_comm_update_ctrl_limits(struct msm_vidc_inst *inst) return; msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE, &inst->capability.cap[CAP_BITRATE]); - msm_vidc_comm_update_ctrl(inst, - V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES, - &inst->capability.cap[CAP_SLICE_BYTE]); - msm_vidc_comm_update_ctrl(inst, - V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB, - &inst->capability.cap[CAP_SLICE_MB]); msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT, &inst->capability.cap[CAP_LTR_COUNT]); diff --git a/msm/vidc/vidc_hfi.c b/msm/vidc/vidc_hfi.c index cedf0c1dea00..11ea53019f63 100644 --- a/msm/vidc/vidc_hfi.c +++ b/msm/vidc/vidc_hfi.c @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include #include "msm_vidc_debug.h" #include "vidc_hfi_api.h" -#include "venus_hfi.h" +#include "hfi_common.h" struct hfi_device *vidc_hfi_initialize(enum msm_vidc_hfi_type hfi_type, u32 device_id, struct msm_vidc_platform_resources *res, diff --git a/msm/vidc/vidc_hfi_io.h b/msm/vidc/vidc_hfi_io.h deleted file mode 100644 index 388d1ac1cc98..000000000000 --- a/msm/vidc/vidc_hfi_io.h +++ /dev/null @@ -1,220 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. - */ - -#ifndef __VIDC_HFI_IO_H__ -#define __VIDC_HFI_IO_H__ - -#include - -#define VIDC_VBIF_BASE_OFFS 0x00080000 - -#define VIDC_CPU_BASE_OFFS 0x000A0000 -#define VIDEO_CC_BASE_OFFS 0x000F0000 -#define VIDC_AON_BASE_OFFS 0x000E0000 -#define VIDC_CPU_CS_BASE_OFFS (VIDC_CPU_BASE_OFFS) -#define VIDC_CPU_IC_BASE_OFFS (VIDC_CPU_BASE_OFFS) - -#define VIDC_CPU_CS_A2HSOFTINTEN (VIDC_CPU_CS_BASE_OFFS + 0x10) -#define VIDC_CPU_CS_A2HSOFTINTENCLR (VIDC_CPU_CS_BASE_OFFS + 0x14) -#define VIDC_CPU_CS_A2HSOFTINT (VIDC_CPU_CS_BASE_OFFS + 0x18) -#define VIDC_CPU_CS_A2HSOFTINTCLR (VIDC_CPU_CS_BASE_OFFS + 0x1C) -#define VIDC_CPU_CS_VMIMSG (VIDC_CPU_CS_BASE_OFFS + 0x34) -#define VIDC_CPU_CS_VMIMSGAG0 (VIDC_CPU_CS_BASE_OFFS + 0x38) -#define VIDC_CPU_CS_VMIMSGAG1 (VIDC_CPU_CS_BASE_OFFS + 0x3C) -#define VIDC_CPU_CS_VMIMSGAG2 (VIDC_CPU_CS_BASE_OFFS + 0x40) -#define VIDC_CPU_CS_VMIMSGAG3 (VIDC_CPU_CS_BASE_OFFS + 0x44) -#define VIDC_CPU_CS_SCIACMD (VIDC_CPU_CS_BASE_OFFS + 0x48) -#define VIDC_CPU_CS_H2XSOFTINTEN (VIDC_CPU_CS_BASE_OFFS + 0x148) - -/* HFI_CTRL_STATUS */ -#define VIDC_CPU_CS_SCIACMDARG0 (VIDC_CPU_CS_BASE_OFFS + 0x4C) -#define VIDC_CPU_CS_SCIACMDARG0_BMSK 0xff -#define VIDC_CPU_CS_SCIACMDARG0_SHFT 0x0 -#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK 0xfe -#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_SHFT 0x1 -#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_BMSK 0x1 -#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_SHFT 0x0 -#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY 0x100 -#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK 0x40000000 - -/* HFI_QTBL_INFO */ -#define VIDC_CPU_CS_SCIACMDARG1 (VIDC_CPU_CS_BASE_OFFS + 0x50) - -/* HFI_QTBL_ADDR */ -#define VIDC_CPU_CS_SCIACMDARG2 (VIDC_CPU_CS_BASE_OFFS + 0x54) - -/* HFI_VERSION_INFO */ -#define VIDC_CPU_CS_SCIACMDARG3 (VIDC_CPU_CS_BASE_OFFS + 0x58) - -/* VIDC_SFR_ADDR */ -#define VIDC_CPU_CS_SCIBCMD (VIDC_CPU_CS_BASE_OFFS + 0x5C) - -/* VIDC_MMAP_ADDR */ -#define VIDC_CPU_CS_SCIBCMDARG0 (VIDC_CPU_CS_BASE_OFFS + 0x60) - -/* VIDC_UC_REGION_ADDR */ -#define VIDC_CPU_CS_SCIBARG1 (VIDC_CPU_CS_BASE_OFFS + 0x64) - -/* VIDC_UC_REGION_ADDR */ -#define VIDC_CPU_CS_SCIBARG2 (VIDC_CPU_CS_BASE_OFFS + 0x68) - -#define VIDC_CPU_CS_SCIBARG3 (VIDC_CPU_CS_BASE_OFFS + 0x6C) - -/* FAL10 Feature Control */ -#define VIDC_CPU_CS_X2RPMh (VIDC_CPU_CS_BASE_OFFS + 0x168) -#define VIDC_CPU_CS_X2RPMh_MASK0_BMSK 0x1 -#define VIDC_CPU_CS_X2RPMh_MASK0_SHFT 0x0 -#define VIDC_CPU_CS_X2RPMh_MASK1_BMSK 0x2 -#define VIDC_CPU_CS_X2RPMh_MASK1_SHFT 0x1 -#define VIDC_CPU_CS_X2RPMh_SWOVERRIDE_BMSK 0x4 -#define VIDC_CPU_CS_X2RPMh_SWOVERRIDE_SHFT 0x3 - -#define VIDC_CPU_IC_SOFTINT (VIDC_CPU_IC_BASE_OFFS + 0x150) -#define VIDC_CPU_IC_SOFTINT_H2A_BMSK 0x1 -#define VIDC_CPU_IC_SOFTINT_H2A_SHFT 0x0 -#define VIDC_CPU_IC_SOFTINTCLEAR (VIDC_CPU_IC_BASE_OFFS + 0x154) - -/* - * -------------------------------------------------------------------------- - * MODULE: vidc_wrapper - * -------------------------------------------------------------------------- - */ -#define VIDC_WRAPPER_BASE_OFFS 0x000B0000 - -#define VIDC_WRAPPER_HW_VERSION (VIDC_WRAPPER_BASE_OFFS + 0x00) -#define VIDC_WRAPPER_HW_VERSION_MAJOR_VERSION_MASK 0x78000000 -#define VIDC_WRAPPER_HW_VERSION_MAJOR_VERSION_SHIFT 28 -#define VIDC_WRAPPER_HW_VERSION_MINOR_VERSION_MASK 0xFFF0000 -#define VIDC_WRAPPER_HW_VERSION_MINOR_VERSION_SHIFT 16 -#define VIDC_WRAPPER_HW_VERSION_STEP_VERSION_MASK 0xFFFF -#define VIDC_WRAPPER_CLOCK_CONFIG (VIDC_WRAPPER_BASE_OFFS + 0x04) - -#define VIDC_WRAPPER_INTR_STATUS (VIDC_WRAPPER_BASE_OFFS + 0x0C) -#define VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK 0x8 -#define VIDC_WRAPPER_INTR_STATUS_A2HWD_SHFT 0x3 -#define VIDC_WRAPPER_INTR_STATUS_A2H_BMSK 0x4 -#define VIDC_WRAPPER_INTR_STATUS_A2H_SHFT 0x2 - -#define VIDC_WRAPPER_INTR_MASK (VIDC_WRAPPER_BASE_OFFS + 0x10) -#define VIDC_WRAPPER_INTR_MASK_A2HWD_BMSK 0x8 -#define VIDC_WRAPPER_INTR_MASK_A2HWD_SHFT 0x3 -#define VIDC_WRAPPER_INTR_MASK_A2HVCODEC_BMSK 0x8 -#define VIDC_WRAPPER_INTR_MASK_A2HCPU_BMSK 0x4 -#define VIDC_WRAPPER_INTR_MASK_A2HCPU_SHFT 0x2 - -#define VIDC_WRAPPER_CPU_CLOCK_CONFIG (VIDC_WRAPPER_BASE_OFFS + 0x2000) -#define VIDC_WRAPPER_CPU_CGC_DIS (VIDC_WRAPPER_BASE_OFFS + 0x2010) -#define VIDC_WRAPPER_CPU_STATUS (VIDC_WRAPPER_BASE_OFFS + 0x2014) - -#define VIDC_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (VIDC_WRAPPER_BASE_OFFS + 0x54) -#define VIDC_WRAPPER_DEBUG_BRIDGE_LPI_STATUS (VIDC_WRAPPER_BASE_OFFS + 0x58) -/* - * -------------------------------------------------------------------------- - * MODULE: vidc_tz_wrapper - * -------------------------------------------------------------------------- - */ -#define VIDC_WRAPPER_TZ_BASE_OFFS 0x000C0000 -#define VIDC_WRAPPER_TZ_CPU_CLOCK_CONFIG (VIDC_WRAPPER_TZ_BASE_OFFS) -#define VIDC_WRAPPER_TZ_CPU_STATUS (VIDC_WRAPPER_TZ_BASE_OFFS + 0x10) - -#define VIDC_VENUS_VBIF_CLK_ON (VIDC_VBIF_BASE_OFFS + 0x4) -#define VENUS_VBIF_AXI_HALT_CTRL0 (VIDC_VBIF_BASE_OFFS + 0x208) -#define VENUS_VBIF_AXI_HALT_CTRL1 (VIDC_VBIF_BASE_OFFS + 0x20C) - -#define VENUS_VBIF_AXI_HALT_CTRL0_HALT_REQ BIT(0) -#define VENUS_VBIF_AXI_HALT_CTRL1_HALT_ACK BIT(0) -#define VENUS_VBIF_AXI_HALT_ACK_TIMEOUT_US 500000 - - -#define VIDC_CTRL_INIT VIDC_CPU_CS_SCIACMD - -#define VIDC_CTRL_STATUS VIDC_CPU_CS_SCIACMDARG0 -#define VIDC_CTRL_ERROR_STATUS__M \ - VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK -#define VIDC_CTRL_INIT_IDLE_MSG_BMSK \ - VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK -#define VIDC_CTRL_STATUS_PC_READY \ - VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY - - -#define VIDC_QTBL_INFO VIDC_CPU_CS_SCIACMDARG1 - -#define VIDC_QTBL_ADDR VIDC_CPU_CS_SCIACMDARG2 - -#define VIDC_VERSION_INFO VIDC_CPU_CS_SCIACMDARG3 - -#define VIDC_SFR_ADDR VIDC_CPU_CS_SCIBCMD -#define VIDC_MMAP_ADDR VIDC_CPU_CS_SCIBCMDARG0 -#define VIDC_UC_REGION_ADDR VIDC_CPU_CS_SCIBARG1 -#define VIDC_UC_REGION_SIZE VIDC_CPU_CS_SCIBARG2 - -/* HFI_DSP_QTBL_ADDR - * 31:3 - HFI_DSP_QTBL_ADDR - * 4-byte aligned Address - */ -#define HFI_DSP_QTBL_ADDR VIDC_CPU_CS_VMIMSG - -/* HFI_DSP_UC_REGION_ADDR - * 31:20 - HFI_DSP_UC_REGION_ADDR - * 1MB aligned address. - * Uncached Region start Address. This region covers - * HFI DSP QTable, - * HFI DSP Queue Headers, - * HFI DSP Queues, - */ -#define HFI_DSP_UC_REGION_ADDR VIDC_CPU_CS_VMIMSGAG0 - -/* HFI_DSP_UC_REGION_SIZE - * 31:20 - HFI_DSP_UC_REGION_SIZE - * Multiples of 1MB. - * Size of the DSP_UC_REGION Uncached Region - */ -#define HFI_DSP_UC_REGION_SIZE VIDC_CPU_CS_VMIMSGAG1 - -/* - * -------------------------------------------------------------------------- - * MODULE: vcodec noc error log registers (iris1) - * -------------------------------------------------------------------------- - */ -#define VCODEC_CORE0_VIDEO_NOC_BASE_OFFS 0x00004000 -#define VCODEC_CORE1_VIDEO_NOC_BASE_OFFS 0x0000C000 -#define VCODEC_COREX_VIDEO_NOC_ERR_SWID_LOW_OFFS 0x0500 -#define VCODEC_COREX_VIDEO_NOC_ERR_SWID_HIGH_OFFS 0x0504 -#define VCODEC_COREX_VIDEO_NOC_ERR_MAINCTL_LOW_OFFS 0x0508 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS 0x0510 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRCLR_LOW_OFFS 0x0518 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_LOW_OFFS 0x0520 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_HIGH_OFFS 0x0524 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_LOW_OFFS 0x0528 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_HIGH_OFFS 0x052C -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_LOW_OFFS 0x0530 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_HIGH_OFFS 0x0534 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_LOW_OFFS 0x0538 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_HIGH_OFFS 0x053C - -#define VIDC_AON_WRAPPER_MVP_NOC_LPI_CONTROL (VIDC_AON_BASE_OFFS) -#define VIDC_AON_WRAPPER_MVP_NOC_LPI_STATUS (VIDC_AON_BASE_OFFS + 0x4) - -/* - * -------------------------------------------------------------------------- - * MODULE: vcodec noc error log registers (iris2) - * -------------------------------------------------------------------------- - */ -#define VCODEC_NOC_VIDEO_A_NOC_BASE_OFFS 0x00010000 -#define VCODEC_NOC_ERL_MAIN_SWID_LOW 0x00011200 -#define VCODEC_NOC_ERL_MAIN_SWID_HIGH 0x00011204 -#define VCODEC_NOC_ERL_MAIN_MAINCTL_LOW 0x00011208 -#define VCODEC_NOC_ERL_MAIN_ERRVLD_LOW 0x00011210 -#define VCODEC_NOC_ERL_MAIN_ERRCLR_LOW 0x00011218 -#define VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW 0x00011220 -#define VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH 0x00011224 -#define VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW 0x00011228 -#define VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH 0x0001122C -#define VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW 0x00011230 -#define VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH 0x00011234 -#define VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW 0x00011238 -#define VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH 0x0001123C -# -#endif From dd4fe4d8279b3f15a393c907f54bc90242df2b38 Mon Sep 17 00:00:00 2001 From: Shivendra Kakrania Date: Mon, 6 May 2019 18:36:27 -0700 Subject: [PATCH 005/452] msm: vidc: Remove dummy file created for techpack Removing dummy video file, created for techpack/video. Change-Id: I714f9241c43e875ff5caba037af82db85baf76df Signed-off-by: Shivendra Kakrania --- vid.c | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 vid.c diff --git a/vid.c b/vid.c deleted file mode 100644 index 4d2ba3b0a42c..000000000000 --- a/vid.c +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. - */ - -static void _vid_techpack_stub(void) -{ -} From 35da0d64cfba7e9fdbbdeb067ab756adc5d44470 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Mon, 6 May 2019 23:26:15 -0700 Subject: [PATCH 006/452] msm: vidc: enhance CVP usage functionality Amend below CVP functionalities - enable logic - start sequence - frame skip logic - downscale resolution logic - debugfs support. Change-Id: I21ad934526c338916d130aaf3401bd89b574b4c1 Signed-off-by: Maheshwar Ajja --- msm/vidc/hfi_common.c | 14 +-- msm/vidc/hfi_iris1.c | 2 +- msm/vidc/hfi_iris2.c | 2 +- msm/vidc/msm_cvp_external.c | 207 +++++++++++++++++++++++----------- msm/vidc/msm_cvp_external.h | 10 +- msm/vidc/msm_v4l2_vidc.c | 6 +- msm/vidc/msm_venc.c | 23 +--- msm/vidc/msm_vidc.c | 183 +++++++++++++++--------------- msm/vidc/msm_vidc_common.c | 78 ++++++++++--- msm/vidc/msm_vidc_debug.c | 2 + msm/vidc/msm_vidc_debug.h | 1 + msm/vidc/msm_vidc_platform.c | 10 +- msm/vidc/msm_vidc_res_parse.c | 6 +- msm/vidc/msm_vidc_resources.h | 3 +- 14 files changed, 333 insertions(+), 214 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 430d07c82330..1fe54d83381a 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -299,7 +299,7 @@ static int __dsp_send_hfi_queue(struct venus_hfi_device *device) { int rc; - if (!device->res->domain_cvp) + if (!device->res->cvp_internal) return 0; if (!device->dsp_iface_q_table.mem_data.dma_handle) { @@ -333,7 +333,7 @@ static int __dsp_suspend(struct venus_hfi_device *device, bool force, u32 flags) int rc; struct hal_session *temp; - if (!device->res->domain_cvp) + if (!device->res->cvp_internal) return 0; if (!(device->dsp_flags & DSP_INIT)) @@ -374,7 +374,7 @@ static int __dsp_resume(struct venus_hfi_device *device, u32 flags) { int rc; - if (!device->res->domain_cvp) + if (!device->res->cvp_internal) return 0; if (!(device->dsp_flags & DSP_SUSPEND)) { @@ -400,7 +400,7 @@ static int __dsp_shutdown(struct venus_hfi_device *device, u32 flags) { int rc; - if (!device->res->domain_cvp) + if (!device->res->cvp_internal) return 0; if (!(device->dsp_flags & DSP_INIT)) { @@ -1171,7 +1171,7 @@ static inline int __boot_firmware_common(struct venus_hfi_device *device) u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 10000; ctrl_init_val = BIT(0); - if (device->res->domain_cvp) + if (device->res->cvp_internal) ctrl_init_val |= BIT(1); __write_register(device, CTRL_INIT, ctrl_init_val); @@ -1688,7 +1688,7 @@ static void __interface_queues_release(struct venus_hfi_device *device) device->mem_addr.align_virtual_addr = NULL; device->mem_addr.align_device_addr = 0; - if (device->res->domain_cvp) + if (device->res->cvp_internal) __interface_dsp_queues_release(device); } @@ -1901,7 +1901,7 @@ static int __interface_queues_init(struct venus_hfi_device *dev) } - if (dev->res->domain_cvp) { + if (dev->res->cvp_internal) { rc = __interface_dsp_queues_init(dev); if (rc) { dprintk(VIDC_ERR, "dsp_queues_init failed\n"); diff --git a/msm/vidc/hfi_iris1.c b/msm/vidc/hfi_iris1.c index faf1e075691b..5789bd856394 100644 --- a/msm/vidc/hfi_iris1.c +++ b/msm/vidc/hfi_iris1.c @@ -41,7 +41,7 @@ void __setup_ucregion_memory_map_iris1(struct venus_hfi_device *device) __write_register(device, HFI_DSP_UC_REGION_ADDR, (u32)device->iface_q_table.align_device_addr); __write_register(device, HFI_DSP_UC_REGION_SIZE, SHARED_QSIZE); - if (device->res->domain_cvp) { + if (device->res->cvp_internal) { /* initialize DSP QTBL & UCREGION with DSP queues */ __write_register(device, HFI_DSP_QTBL_ADDR, (u32)device->dsp_iface_q_table.align_device_addr); diff --git a/msm/vidc/hfi_iris2.c b/msm/vidc/hfi_iris2.c index 4fd4dc415289..d01ceef45aa7 100644 --- a/msm/vidc/hfi_iris2.c +++ b/msm/vidc/hfi_iris2.c @@ -383,7 +383,7 @@ int __boot_firmware_iris2(struct venus_hfi_device *device) u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 10000; ctrl_init_val = BIT(0); - if (device->res->domain_cvp) + if (device->res->cvp_internal) ctrl_init_val |= BIT(1); __write_register(device, CTRL_INIT_IRIS2, ctrl_init_val); diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index 717f0bf7efad..1ccb9368aa53 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -171,6 +171,66 @@ static int msm_cvp_allocate_buffer(struct msm_vidc_inst *inst, return rc; } +static int msm_cvp_init_downscale_resolution(struct msm_vidc_inst *inst) +{ + struct msm_cvp_external *cvp; + const u32 width_max = 1920; + u32 width, height, ds_width, ds_height, temp; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; + + ds_width = cvp->width; + ds_height = cvp->height; + + if (!cvp->downscale) { + dprintk(VIDC_DBG, "%s: downscaling not enabled\n", __func__); + goto exit; + } + + /* Step 1) make width always the larger number */ + if (cvp->height > cvp->width) { + width = cvp->height; + height = cvp->width; + } else { + width = cvp->width; + height = cvp->height; + } + /* + * Step 2) Downscale width by 4 and round + * make sure width stays between 480 and 1920 + */ + ds_width = (width + 2) >> 2; + if (ds_width < 480) + ds_width = 480; + if (ds_width > width_max) + ds_width = width_max; + ds_height = (height * ds_width) / width; + if (ds_height < 128) + ds_height = 128; + + /* Step 3) do not downscale if width is less than 480 */ + if (width <= 480) + ds_width = width; + if (ds_width == width) + ds_height = height; + + /* Step 4) switch width and height if already switched */ + if (height > width) { + temp = ds_height; + ds_height = ds_width; + ds_width = temp; + } + +exit: + cvp->ds_width = ds_width; + cvp->ds_height = ds_height; + return 0; +} + static void msm_cvp_deinit_downscale_buffers(struct msm_vidc_inst *inst) { struct msm_cvp_external *cvp; @@ -389,15 +449,12 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst) struct cvp_kmd_arg *arg; struct msm_cvp_session_set_persist_buffers_packet persist2_packet; - if (!inst || !inst->cvp) { + if (!inst || !inst->cvp || !inst->cvp->arg) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; } - arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL); - if (!arg) - return -ENOMEM; - cvp = inst->cvp; + arg = cvp->arg; dprintk(VIDC_DBG, "%s:\n", __func__); cvp->persist2_buffer.size = HFI_DME_INTERNAL_PERSIST_2_BUFFER_SIZE; @@ -451,35 +508,36 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst) print_cvp_buffer(VIDC_DBG, "alloc: output_buffer", inst, &cvp->output_buffer); - kfree(arg); return rc; error: msm_cvp_deinit_internal_buffers(inst); - kfree(arg); return rc; } static int msm_cvp_prepare_extradata(struct msm_vidc_inst *inst, - struct vb2_buffer *vb) + struct msm_vidc_buffer *mbuf) { int rc = 0; struct msm_cvp_external *cvp; - struct dma_buf *dbuf = NULL; - char *kvaddr = NULL; + struct vb2_buffer *vb; + struct dma_buf *dbuf; + char *kvaddr; struct msm_vidc_extradata_header *e_hdr; bool input_extradata, found_end; - if (!inst || !inst->cvp || !vb) { + if (!inst || !inst->cvp || !mbuf) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; } + cvp = inst->cvp; + + vb = &mbuf->vvb.vb2_buf; if (vb->num_planes <= 1) { dprintk(VIDC_ERR, "%s: extradata plane not enabled\n", __func__); return -EINVAL; } - cvp = inst->cvp; dbuf = dma_buf_get(vb->planes[1].m.fd); if (!dbuf) { @@ -539,17 +597,24 @@ static int msm_cvp_prepare_extradata(struct msm_vidc_inst *inst, dbuf->size); goto error; } - /* copy payload */ - e_hdr->version = 0x00000001; - e_hdr->port_index = 1; - e_hdr->type = MSM_VIDC_EXTRADATA_CVP_METADATA; - e_hdr->data_size = sizeof(struct msm_vidc_enc_cvp_metadata_payload); - e_hdr->size = sizeof(struct msm_vidc_extradata_header) + + if (cvp->metadata_available) { + cvp->metadata_available = false; + + /* copy payload */ + e_hdr->version = 0x00000001; + e_hdr->port_index = 1; + e_hdr->type = MSM_VIDC_EXTRADATA_CVP_METADATA; + e_hdr->data_size = + sizeof(struct msm_vidc_enc_cvp_metadata_payload); + e_hdr->size = sizeof(struct msm_vidc_extradata_header) + e_hdr->data_size; - dma_buf_begin_cpu_access(cvp->output_buffer.dbuf, DMA_BIDIRECTIONAL); - memcpy(e_hdr->data, cvp->output_buffer.kvaddr, + dma_buf_begin_cpu_access(cvp->output_buffer.dbuf, + DMA_BIDIRECTIONAL); + memcpy(e_hdr->data, cvp->output_buffer.kvaddr, sizeof(struct msm_vidc_enc_cvp_metadata_payload)); - dma_buf_end_cpu_access(cvp->output_buffer.dbuf, DMA_BIDIRECTIONAL); + dma_buf_end_cpu_access(cvp->output_buffer.dbuf, + DMA_BIDIRECTIONAL); + } /* fill extradata none */ e_hdr = (struct msm_vidc_extradata_header *) ((char *)e_hdr + e_hdr->size); @@ -607,27 +672,52 @@ static int msm_cvp_reference_management(struct msm_vidc_inst *inst) } static int msm_cvp_frame_process(struct msm_vidc_inst *inst, - struct vb2_buffer *vb) + struct msm_vidc_buffer *mbuf) { int rc = 0; struct msm_cvp_external *cvp; + struct vb2_buffer *vb; struct cvp_kmd_arg *arg; struct msm_cvp_dme_frame_packet *frame; + const u32 fps_max = 60; + u32 fps, skip_framecount; + bool skipframe = false; - if (!inst || !inst->cvp) { + if (!inst || !inst->cvp || !inst->cvp->arg || !mbuf) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; } - arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL); - if (!arg) - return -ENOMEM; - cvp = inst->cvp; + arg = cvp->arg; + + vb = &mbuf->vvb.vb2_buf; cvp->fullres_buffer.index = vb->index; cvp->fullres_buffer.fd = vb->planes[0].m.fd; cvp->fullres_buffer.size = vb->planes[0].length; cvp->fullres_buffer.offset = vb->planes[0].data_offset; + /* frame skip logic */ + fps = max(inst->clk_data.operating_rate, + inst->clk_data.frame_rate) >> 16; + if (fps > fps_max) { + /* + * fps <= 120: 0, 2, 4, 6 .. are not skipped + * fps <= 180: 0, 3, 6, 9 .. are not skipped + * fps <= 240: 0, 4, 8, 12 .. are not skipped + * fps <= 960: 0, 16, 32, 48 .. are not skipped + */ + fps = ALIGN(fps, fps_max); + skip_framecount = fps / fps_max; + skipframe = !(cvp->framecount % skip_framecount); + } + if (skipframe) { + print_cvp_buffer(VIDC_DBG, "input frame skipped", + inst, &cvp->fullres_buffer); + cvp->framecount++; + cvp->metadata_available = false; + return 0; + } + arg->type = CVP_KMD_SEND_CMD_PKT; frame = (struct msm_cvp_dme_frame_packet *)&arg->data.hfi_pkt.pkt_data; @@ -680,18 +770,19 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, goto error; } cvp->framecount++; + cvp->metadata_available = true; error: - kfree(arg); return rc; } -int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst, struct vb2_buffer *vb) +int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf) { int rc = 0; struct msm_cvp_external *cvp; - if (!inst || !inst->cvp || !vb) { + if (!inst || !inst->cvp || !mbuf) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; } @@ -702,13 +793,13 @@ int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst, struct vb2_buffer *vb) } cvp = inst->cvp; - rc = msm_cvp_frame_process(inst, vb); + rc = msm_cvp_frame_process(inst, mbuf); if (rc) { dprintk(VIDC_ERR, "%s: cvp process failed\n", __func__); return rc; } - rc = msm_cvp_prepare_extradata(inst, vb); + rc = msm_cvp_prepare_extradata(inst, mbuf); if (rc) { dprintk(VIDC_ERR, "%s: prepare extradata failed\n", __func__); return rc; @@ -760,6 +851,8 @@ static int msm_vidc_cvp_close(struct msm_vidc_inst *inst) "%s: cvp close failed with error %d\n", __func__, rc); cvp->priv = NULL; + kfree(cvp->arg); + cvp->arg = NULL; kfree(inst->cvp); inst->cvp = NULL; @@ -792,39 +885,25 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst) struct msm_cvp_dme_basic_config_packet *dmecfg; u32 color_fmt; - if (!inst || !inst->cvp) { + if (!inst || !inst->cvp || !inst->cvp->arg) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; } - arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL); - if (!arg) - return -ENOMEM; - - f = &inst->fmts[INPUT_PORT].v4l2_fmt; cvp = inst->cvp; - + arg = cvp->arg; cvp->framecount = 0; + cvp->metadata_available = false; + f = &inst->fmts[INPUT_PORT].v4l2_fmt; cvp->width = f->fmt.pix_mp.width; cvp->height = f->fmt.pix_mp.height; color_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat); /* enable downscale always */ cvp->downscale = true; - if (cvp->width * cvp->height < 640 * 480) { - cvp->ds_width = cvp->width; - cvp->ds_height = cvp->height; - } else if (cvp->width * cvp->height < 1920 * 1080) { - if (cvp->ds_width >= cvp->ds_height) { - cvp->ds_width = 480; - cvp->ds_height = 270; - } else { - cvp->ds_width = 270; - cvp->ds_height = 480; - } - } else { - cvp->ds_width = cvp->width / 4; - cvp->ds_height = cvp->height / 4; - } + rc = msm_cvp_init_downscale_resolution(inst); + if (rc) + goto error; + dprintk(VIDC_DBG, "%s: pixelformat %#x, wxh %dx%d downscale %d ds_wxh %dx%d\n", __func__, f->fmt.pix_mp.pixelformat, @@ -873,12 +952,10 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst) if (rc) goto error; - kfree(arg); return rc; error: msm_vidc_cvp_deinit(inst); - kfree(arg); return rc; } @@ -892,18 +969,22 @@ static int msm_vidc_cvp_open(struct msm_vidc_inst *inst) dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; } - arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL); - if (!arg) - return -ENOMEM; inst->cvp = kzalloc(sizeof(struct msm_cvp_external), GFP_KERNEL); if (!inst->cvp) { dprintk(VIDC_ERR, "%s: failed to allocate\n", __func__); - rc = -ENOMEM; - goto error; + return -ENOMEM; } cvp = inst->cvp; + cvp->arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL); + if (!cvp->arg) { + kfree(inst->cvp); + inst->cvp = NULL; + return -ENOMEM; + } + arg = cvp->arg; + dprintk(VIDC_DBG, "%s: opening cvp\n", __func__); cvp->priv = msm_cvp_open(0, MSM_VIDC_CVP); if (!cvp->priv) { @@ -923,14 +1004,10 @@ static int msm_vidc_cvp_open(struct msm_vidc_inst *inst) dprintk(VIDC_DBG, "%s: cvp session id %#x\n", __func__, cvp->session_id); - kfree(arg); return 0; error: msm_vidc_cvp_close(inst); - kfree(inst->cvp); - inst->cvp = NULL; - kfree(arg); return rc; } diff --git a/msm/vidc/msm_cvp_external.h b/msm/vidc/msm_cvp_external.h index ed98428f78c3..522bf938452d 100644 --- a/msm/vidc/msm_cvp_external.h +++ b/msm/vidc/msm_cvp_external.h @@ -50,11 +50,6 @@ static inline bool is_vidc_cvp_enabled(struct msm_vidc_inst *inst) return !!inst->cvp; } -static inline bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst) -{ - return false; -} - struct msm_cvp_buffer_type { u32 buffer_addr; u32 size; @@ -143,6 +138,7 @@ struct msm_cvp_buf { struct msm_cvp_external { void *priv; + void *arg; u32 session_id; u32 width; u32 height; @@ -151,6 +147,7 @@ struct msm_cvp_external { bool downscale; u32 framecount; u32 buffer_idx; + bool metadata_available; struct msm_cvp_buf fullres_buffer; struct msm_cvp_buf src_buffer; struct msm_cvp_buf ref_buffer; @@ -161,8 +158,7 @@ struct msm_cvp_external { }; int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst, - struct vb2_buffer *vb); + struct msm_vidc_buffer *mbuf); int msm_vidc_cvp_prepare_preprocess(struct msm_vidc_inst *inst); int msm_vidc_cvp_unprepare_preprocess(struct msm_vidc_inst *inst); - #endif diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index 1eb74547a8d3..24aaf7c2476f 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -519,7 +519,7 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) } /* setup the cvp device */ - if (core->resources.domain_cvp) { + if (core->resources.cvp_internal) { rc = msm_vidc_register_video_device(MSM_VIDC_CVP, nr + 2, core, dev); if (rc) { @@ -583,7 +583,7 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) err_fail_sub_device_probe: vidc_hfi_deinitialize(core->hfi_type, core->device); err_cores_exceeded: - if (core->resources.domain_cvp) { + if (core->resources.cvp_internal) { device_remove_file(&core->vdev[MSM_VIDC_CVP].vdev.dev, &dev_attr_link_name); video_unregister_device(&core->vdev[MSM_VIDC_CVP].vdev); @@ -663,7 +663,7 @@ static int msm_vidc_remove(struct platform_device *pdev) } vidc_hfi_deinitialize(core->hfi_type, core->device); - if (core->resources.domain_cvp) { + if (core->resources.cvp_internal) { device_remove_file(&core->vdev[MSM_VIDC_CVP].vdev.dev, &dev_attr_link_name); video_unregister_device(&core->vdev[MSM_VIDC_CVP].vdev); diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index a42802d5267b..df32fa8efe8f 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3833,7 +3833,6 @@ int msm_venc_set_hdr_info(struct msm_vidc_inst *inst) int msm_venc_set_extradata(struct msm_vidc_inst *inst) { int rc = 0; - struct v4l2_ctrl *cvp_ctrl; u32 value = 0x0; u32 codec; @@ -3872,25 +3871,13 @@ int msm_venc_set_extradata(struct msm_vidc_inst *inst) } } - cvp_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE); - if (cvp_ctrl->val == V4L2_MPEG_MSM_VIDC_ENABLE) { - if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) { - dprintk(VIDC_ERR, - "%s: invalid params\n", __func__); - return -EINVAL; - } - } else { - /* - * For now, enable CVP metadata only if client provides it. - * Once the kernel-mode CVP metadata implementation - * is completed, this condition should be removed. - */ - if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) - value = 0x1; - - } + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) + value = 0x1; + dprintk(VIDC_DBG, "%s: CVP extradata %d\n", __func__, value); rc = msm_comm_set_extradata(inst, HFI_PROPERTY_PARAM_VENC_CVP_METADATA_EXTRADATA, value); + if (rc) + dprintk(VIDC_ERR, "%s: set CVP extradata failed\n", __func__); return rc; } diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 15954723facb..e0a88fbe9f5b 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -325,46 +325,6 @@ int msm_vidc_release_buffer(void *instance, int type, unsigned int index) } EXPORT_SYMBOL(msm_vidc_release_buffer); -static int msm_vidc_preprocess(struct msm_vidc_inst *inst, - struct vb2_buffer *vb) -{ - int rc = 0; - struct buf_queue *q; - - if (!inst || !vb) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); - return -EINVAL; - } - - if (!is_encode_session(inst) || vb->type != - V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) - return 0; - - if (!is_vidc_cvp_enabled(inst)) - return 0; - - q = msm_comm_get_vb2q(inst, vb->type); - if (!q) { - dprintk(VIDC_ERR, "%s: queue not found for type %d\n", - __func__, vb->type); - return -EINVAL; - } - if (!q->vb2_bufq.streaming) { - dprintk(VIDC_ERR, - "%s: enable input port streaming before queuing input buffers\n", - __func__); - return -EINVAL; - } - rc = msm_vidc_cvp_preprocess(inst, vb); - if (rc) { - dprintk(VIDC_ERR, "%s: cvp preprocess failed\n", - __func__); - return rc; - } - - return rc; -} - int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) { struct msm_vidc_inst *inst = instance; @@ -739,6 +699,51 @@ static int msm_vidc_set_properties(struct msm_vidc_inst *inst) return rc; } +bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst) +{ + bool allowed = false; + struct msm_vidc_core *core; + struct v4l2_ctrl *cvp_disable; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + goto exit; + } + core = inst->core; + + /* + * CVP enable if + * - platform support CVP external + * - client did not disable CVP forcefully + * - client may disable forcefully to save power + * - client did not enable CVP extradata + * - if enabled, client will give CVP extradata + * - rate control is not one of below modes + * - RATE_CONTROL_OFF + * - V4L2_MPEG_VIDEO_BITRATE_MODE_CQ + * - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_PLUS + */ + cvp_disable = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE); + + if (core->resources.cvp_external && !cvp_disable->val && + !(inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) && + inst->rc_type != RATE_CONTROL_OFF && + inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ && + !inst->clk_data.is_cbr_plus) { + dprintk(VIDC_DBG, "%s: cvp allowed\n", __func__); + allowed = true; + } else { + dprintk(VIDC_DBG, + "%s: cvp not allowed, cvp_external %d cvp_disable %d extradata %#x rc_type %d\n", + __func__, core->resources.cvp_external, + cvp_disable->val, inst->prop.extradata_ctrls, + inst->rc_type); + allowed = false; + } +exit: + return allowed; +} + static int msm_vidc_prepare_preprocess(struct msm_vidc_inst *inst) { int rc = 0; @@ -748,6 +753,11 @@ static int msm_vidc_prepare_preprocess(struct msm_vidc_inst *inst) return -EINVAL; } + if (!msm_vidc_cvp_usage) { + dprintk(VIDC_DBG, "%s: cvp usage disabled\n", __func__); + return 0; + } + if (!is_vidc_cvp_allowed(inst)) { dprintk(VIDC_DBG, "%s: cvp not allowed\n", __func__); return 0; @@ -756,12 +766,21 @@ static int msm_vidc_prepare_preprocess(struct msm_vidc_inst *inst) rc = msm_vidc_cvp_prepare_preprocess(inst); if (rc) { dprintk(VIDC_WARN, "%s: no cvp preprocessing\n", __func__); - msm_vidc_cvp_unprepare_preprocess(inst); goto exit; } dprintk(VIDC_DBG, "%s: cvp enabled\n", __func__); + dprintk(VIDC_DBG, "%s: set CVP extradata\n", __func__); + rc = msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VENC_CVP_METADATA_EXTRADATA, 1); + if (rc) { + dprintk(VIDC_WARN, "%s: set CVP extradata failed\n", __func__); + goto exit; + } + exit: + if (rc) + msm_vidc_cvp_unprepare_preprocess(inst); return rc; } @@ -783,6 +802,15 @@ static inline int start_streaming(struct msm_vidc_inst *inst) goto fail_start; } + if (is_encode_session(inst)) { + rc = msm_vidc_prepare_preprocess(inst); + if (rc) { + dprintk(VIDC_WARN, "%s: no preprocessing\n", __func__); + /* ignore error */ + rc = 0; + } + } + b.buffer_type = HFI_BUFFER_OUTPUT; if (inst->session_type == MSM_VIDC_DECODER && is_secondary_output_mode(inst)) @@ -968,16 +996,6 @@ static int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count) goto stream_start_failed; } - if (is_encode_session(inst) && q->type == - V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - rc = msm_vidc_prepare_preprocess(inst); - if (rc) { - dprintk(VIDC_WARN, "%s: no preprocessing\n", __func__); - /* ignore error */ - rc = 0; - } - } - rc = msm_comm_qbufs(inst); if (rc) { dprintk(VIDC_ERR, @@ -1027,24 +1045,6 @@ static int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count) return rc; } -static inline int stop_streaming(struct msm_vidc_inst *inst) -{ - int rc = 0; - - dprintk(VIDC_DBG, "%s: %x : inst %pK\n", __func__, - hash32_ptr(inst->session), inst); - - rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); - if (rc) - dprintk(VIDC_ERR, - "Failed to move inst: %pK to state %d\n", - inst, MSM_VIDC_RELEASE_RESOURCES_DONE); - - msm_clock_data_reset(inst); - - return rc; -} - static int msm_vidc_unprepare_preprocess(struct msm_vidc_inst *inst) { int rc = 0; @@ -1066,6 +1066,32 @@ static int msm_vidc_unprepare_preprocess(struct msm_vidc_inst *inst) return rc; } +static inline int stop_streaming(struct msm_vidc_inst *inst) +{ + int rc = 0; + + dprintk(VIDC_DBG, "%s: %x : inst %pK\n", __func__, + hash32_ptr(inst->session), inst); + + rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); + if (rc) + dprintk(VIDC_ERR, + "Failed to move inst: %pK to state %d\n", + inst, MSM_VIDC_RELEASE_RESOURCES_DONE); + + if (is_encode_session(inst)) { + rc = msm_vidc_unprepare_preprocess(inst); + if (rc) + dprintk(VIDC_ERR, + "%s: failed to unprepare preprocess\n", + __func__); + } + + msm_clock_data_reset(inst); + + return rc; +} + static void msm_vidc_stop_streaming(struct vb2_queue *q) { struct msm_vidc_inst *inst; @@ -1078,16 +1104,6 @@ static void msm_vidc_stop_streaming(struct vb2_queue *q) inst = q->drv_priv; dprintk(VIDC_DBG, "Streamoff called on: %d capability\n", q->type); - - if (is_encode_session(inst) && q->type == - V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - rc = msm_vidc_unprepare_preprocess(inst); - if (rc) - dprintk(VIDC_ERR, - "%s: failed to unprepare preprocess\n", - __func__); - } - switch (q->type) { case INPUT_MPLANE: if (!inst->bufq[OUTPUT_PORT].vb2_bufq.streaming) @@ -1209,20 +1225,11 @@ static void msm_vidc_buf_queue(struct vb2_buffer *vb2) return; } - /* do preprocessing if any */ - rc = msm_vidc_preprocess(inst, vb2); - if (rc) { - dprintk(VIDC_ERR, "%s: preprocess failed %x\n", - __func__, hash32_ptr(inst->session)); - goto exit; - } - if (inst->batch.enable) rc = msm_vidc_queue_buf_batch(inst, vb2); else rc = msm_vidc_queue_buf(inst, vb2); -exit: if (rc) { print_vb2_buffer(VIDC_ERR, "failed vb2-qbuf", inst, vb2); msm_comm_generate_session_error(inst); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 5a633cd0f5df..390f119f9611 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -15,6 +15,7 @@ #include "vidc_hfi.h" #include "msm_vidc_debug.h" #include "msm_vidc_clocks.h" +#include "msm_cvp_external.h" #include "msm_cvp_internal.h" #include "msm_vidc_buffer_calculations.h" @@ -4058,6 +4059,34 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd) return rc; } +static int msm_comm_preprocess(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf) +{ + int rc = 0; + + if (!inst || !mbuf) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + /* preprocessing is allowed for encoder input buffer only */ + if (!is_encode_session(inst) || mbuf->vvb.vb2_buf.type != INPUT_MPLANE) + return 0; + + /* preprocessing is done using CVP module only */ + if (!is_vidc_cvp_enabled(inst)) + return 0; + + rc = msm_vidc_cvp_preprocess(inst, mbuf); + if (rc) { + dprintk(VIDC_ERR, "%s: cvp preprocess failed\n", + __func__); + return rc; + } + + return rc; +} + static void populate_frame_data(struct vidc_frame_data *data, struct msm_vidc_buffer *mbuf, struct msm_vidc_inst *inst) { @@ -4264,6 +4293,10 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) return 0; } + rc = msm_comm_preprocess(inst, mbuf); + if (rc) + return rc; + rc = msm_comm_scale_clocks_and_bus(inst); if (rc) dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__); @@ -4280,6 +4313,7 @@ int msm_comm_qbufs(struct msm_vidc_inst *inst) { int rc = 0; struct msm_vidc_buffer *mbuf; + bool found; if (!inst) { dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); @@ -4292,24 +4326,36 @@ int msm_comm_qbufs(struct msm_vidc_inst *inst) return 0; } - rc = msm_comm_scale_clocks_and_bus(inst); - if (rc) - dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__); - - mutex_lock(&inst->registeredbufs.lock); - list_for_each_entry(mbuf, &inst->registeredbufs.list, list) { - /* Queue only deferred buffers */ - if (!(mbuf->flags & MSM_VIDC_FLAG_DEFERRED)) - continue; - print_vidc_buffer(VIDC_DBG, "qbufs", inst, mbuf); - rc = msm_comm_qbuf_to_hfi(inst, mbuf); - if (rc) { - dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", - __func__, rc); + do { + mutex_lock(&inst->registeredbufs.lock); + found = false; + list_for_each_entry(mbuf, &inst->registeredbufs.list, list) { + /* Queue only deferred buffers */ + if (mbuf->flags & MSM_VIDC_FLAG_DEFERRED) { + found = true; + break; + } + } + mutex_unlock(&inst->registeredbufs.lock); + if (!found) { + dprintk(VIDC_DBG, + "%s: no more deferred qbufs\n", __func__); break; } - } - mutex_unlock(&inst->registeredbufs.lock); + + /* do not call msm_comm_qbuf() under registerbufs lock */ + if (!kref_get_mbuf(inst, mbuf)) { + dprintk(VIDC_ERR, "%s: mbuf not found\n", __func__); + rc = -EINVAL; + break; + } + rc = msm_comm_qbuf(inst, mbuf); + kref_put_mbuf(mbuf); + if (rc) { + dprintk(VIDC_ERR, "%s: failed qbuf\n", __func__); + break; + } + } while (found); return rc; } diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index 17ff19228c83..abaf11ac117c 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -25,6 +25,7 @@ bool msm_vidc_fw_coverage = !true; bool msm_vidc_thermal_mitigation_disabled = !true; int msm_vidc_clock_voting = !1; bool msm_vidc_syscache_disable = !true; +bool msm_vidc_cvp_usage = !true; #define MAX_DBG_BUF_SIZE 4096 @@ -188,6 +189,7 @@ struct dentry *msm_vidc_debugfs_init_drv(void) &msm_vidc_clock_voting) && __debugfs_create(bool, "disable_video_syscache", &msm_vidc_syscache_disable) && + __debugfs_create(bool, "cvp_usage", &msm_vidc_cvp_usage) && __debugfs_create(bool, "lossless_encoding", &msm_vidc_lossless_encode); diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index a06bf2b2f844..58217d5c03d9 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -61,6 +61,7 @@ extern bool msm_vidc_thermal_mitigation_disabled; extern int msm_vidc_clock_voting; extern bool msm_vidc_syscache_disable; extern bool msm_vidc_lossless_encode; +extern bool msm_vidc_cvp_usage; #define dprintk(__level, __fmt, ...) \ do { \ diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 2f5b6a05dac6..6b25adff4afd 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -299,7 +299,7 @@ static struct msm_vidc_common_data lito_common_data_v0[] = { .value = 0, }, { - .key = "qcom,domain-cvp", + .key = "qcom,cvp-internal", .value = 1, }, { @@ -370,7 +370,7 @@ static struct msm_vidc_common_data lito_common_data_v1[] = { .value = 0, }, { - .key = "qcom,domain-cvp", + .key = "qcom,cvp-internal", .value = 1, }, { @@ -445,8 +445,8 @@ static struct msm_vidc_common_data kona_common_data[] = { .value = 0, }, { - .key = "qcom,domain-cvp", - .value = 0, + .key = "qcom,cvp-external", + .value = 1, }, { .key = "qcom,decode-batching", @@ -587,7 +587,7 @@ static struct msm_vidc_common_data sm8150_common_data[] = { .value = 0, }, { - .key = "qcom,domain-cvp", + .key = "qcom,cvp-internal", .value = 1, }, { diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 855078b9aaf2..de1d60a124b7 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -806,8 +806,10 @@ int read_platform_resources_from_drv_data( "qcom,fw-unload-delay"); res->msm_vidc_hw_rsp_timeout = find_key_value(platform_data, "qcom,hw-resp-timeout"); - res->domain_cvp = find_key_value(platform_data, - "qcom,domain-cvp"); + res->cvp_internal = find_key_value(platform_data, + "qcom,cvp-internal"); + res->cvp_external = find_key_value(platform_data, + "qcom,cvp-external"); res->non_fatal_pagefaults = find_key_value(platform_data, "qcom,domain-attr-non-fatal-faults"); res->cache_pagetables = find_key_value(platform_data, diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 7043b81d396b..c6ea445d14f3 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -188,7 +188,8 @@ struct msm_vidc_platform_resources { int msm_vidc_hw_rsp_timeout; int msm_vidc_firmware_unload_delay; uint32_t msm_vidc_pwr_collapse_delay; - bool domain_cvp; + bool cvp_internal; + bool cvp_external; bool non_fatal_pagefaults; bool cache_pagetables; bool decode_batching; From 954a066aacee7591843d6d941db83702d33d12c7 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Tue, 7 May 2019 15:28:17 -0700 Subject: [PATCH 007/452] msm: vidc: Fixed LTR count capability Kona target supports two LTR frames encoding. Fixing this capability in kona driver. Handle resolution check correctly while setting slice mode. Change-Id: Iea6a041ecafb24da014832ecf2146088d4569a6f CRs-Fixed: 2444064 Signed-off-by: Darshana Patil --- msm/vidc/msm_venc.c | 12 +++++++----- msm/vidc/msm_vidc_platform.c | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index df32fa8efe8f..81e13028fde0 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2374,7 +2374,7 @@ int msm_venc_set_vbv_delay(struct msm_vidc_inst *inst) height = f->fmt.pix_mp.height; width = f->fmt.pix_mp.width; mbpf = NUM_MBS_PER_FRAME(height, width); - fps = inst->clk_data.frame_rate; + fps = inst->clk_data.frame_rate >> 16; mbpf = NUM_MBS_PER_FRAME(height, width); mbps = NUM_MBS_PER_SEC(height, width, fps); @@ -2850,11 +2850,13 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst) f = &inst->fmts[INPUT_PORT].v4l2_fmt; output_width = f->fmt.pix_mp.width; output_height = f->fmt.pix_mp.height; - if (output_height < 128 || - (codec != V4L2_PIX_FMT_HEVC && output_width < 384) || - (codec != V4L2_PIX_FMT_H264 && output_width < 192)) { + if ((codec == V4L2_PIX_FMT_HEVC) && + (output_height < 128 || output_width < 384)) + goto set_and_exit; + + if ((codec == V4L2_PIX_FMT_H264) && + (output_height < 128 || output_width < 192)) goto set_and_exit; - } ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); if (ctrl->val == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) { diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 6b25adff4afd..12ae94da85f5 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -171,7 +171,7 @@ static struct msm_vidc_codec_capability kona_capabilities[] = { {CAP_SCALE_Y, DOMAINS_ALL, CODECS_ALL, 4096, 65536, 1, 4096}, {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, - {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 6, 1, 0}, + {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 2, 1, 0}, /* ((4096 * 2304) / 256) * 60 fps */ {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, 0, 2211840, 1, 2211840}, From da72739ed0ffc2c56dd8d11417f62d82b1e816f1 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Wed, 8 May 2019 15:19:34 -0700 Subject: [PATCH 008/452] msm: vidc: remove TME format from supported formats list video driver does not support TME format, so remove it. Change-Id: Ica7656fc1758a007f0d20d0351a4cedb82b9a0ee Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_venc.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 81e13028fde0..c019fc3c2baf 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -998,11 +998,6 @@ static struct msm_vidc_format_desc venc_output_formats[] = { .description = "HEVC compressed format", .fourcc = V4L2_PIX_FMT_HEVC, }, - { - .name = "TME", - .description = "TME MBI format", - .fourcc = V4L2_PIX_FMT_TME, - }, }; struct msm_vidc_format_constraint enc_pix_format_constraints[] = { From a571bf18b71c5fcb875fd26e3cd1749a06fd9894 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Thu, 9 May 2019 00:00:50 -0700 Subject: [PATCH 009/452] msm: vidc: fix in UBWC LP5 Configuration Default UBWC configuration for LPDDR5 is corrected. Highest Bank Bit is set to 16. Change-Id: I0fb18279ae32d34a7f3bada6d05a72c5935430dd Signed-off-by: Akshata Sahukar --- msm/vidc/msm_vidc_platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 12ae94da85f5..61ba6e5a4e2b 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -779,7 +779,7 @@ static struct msm_vidc_efuse_data sdm670_efuse_data[] = { /* Default UBWC config for LPDDR5 */ static struct msm_vidc_ubwc_config_data kona_ubwc_data[] = { - UBWC_CONFIG(1, 1, 1, 0, 0, 0, 8, 32, 15, 0, 0), + UBWC_CONFIG(1, 1, 1, 0, 0, 0, 8, 32, 16, 0, 0), }; static struct msm_vidc_platform_data default_data = { From 8a68da653dddd88ef7d02c2102717e252a77fefe Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Wed, 8 May 2019 10:45:28 -0700 Subject: [PATCH 010/452] msm: vidc: remove structure vidc_hal_session_init_done The structure vidc_hal_session_init_done is not being used, so remove it. Change-Id: Id4a577db117f98b18439245907765be5c9badc83 Signed-off-by: Maheshwar Ajja --- msm/vidc/hfi_response_handler.c | 9 ++------- msm/vidc/vidc_hfi_api.h | 5 ----- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index a97d95cb3627..b731ad2260cc 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -109,8 +109,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, struct hfi_colour_space *colour_info; if (sizeof(struct hfi_msg_event_notify_packet) > pkt->size) { - dprintk(VIDC_ERR, - "hal_process_session_init_done: bad_pkt_size\n"); + dprintk(VIDC_ERR, "%s: bad_pkt_size\n", __func__); return -E2BIG; } @@ -285,8 +284,7 @@ static int hfi_process_evt_release_buffer_ref(u32 device_id, "RECEIVED: EVENT_NOTIFY - release_buffer_reference\n"); if (sizeof(struct hfi_msg_event_notify_packet) > pkt->size) { - dprintk(VIDC_ERR, - "hal_process_session_init_done: bad_pkt_size\n"); + dprintk(VIDC_ERR, "%s: bad_pkt_size\n", __func__); return -E2BIG; } @@ -618,7 +616,6 @@ static int hfi_process_session_init_done(u32 device_id, { struct hfi_msg_sys_session_init_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - struct vidc_hal_session_init_done session_init_done = { {0} }; dprintk(VIDC_DBG, "RECEIVED: SESSION_INIT_DONE[%x]\n", pkt->session_id); @@ -631,8 +628,6 @@ static int hfi_process_session_init_done(u32 device_id, cmd_done.device_id = device_id; cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.status = hfi_map_err_status(pkt->error_type); - cmd_done.data.session_init_done = session_init_done; - cmd_done.size = sizeof(struct vidc_hal_session_init_done); info->response_type = HAL_SESSION_INIT_DONE; info->response.cmd = cmd_done; diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index eed788b7b270..37eba5880fbe 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -574,10 +574,6 @@ struct vidc_hal_sys_init_done { u32 max_sessions_supported; }; -struct vidc_hal_session_init_done { - struct msm_vidc_capability capability; -}; - struct msm_vidc_cb_cmd_done { u32 device_id; void *session_id; @@ -592,7 +588,6 @@ struct msm_vidc_cb_cmd_done { struct vidc_hal_ebd ebd; struct vidc_hal_fbd fbd; struct vidc_hal_sys_init_done sys_init_done; - struct vidc_hal_session_init_done session_init_done; struct hal_buffer_info buffer_info; struct vidc_register_buffer regbuf; struct vidc_unregister_buffer unregbuf; From 1277141e60f0529c24ff1fe6f06bdb3572e7532d Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Fri, 10 May 2019 12:27:11 -0700 Subject: [PATCH 011/452] msm: vidc: Handoff regulators after firmware loading is complete Regulator handoff causes the GDSC to turn off momentarily and resets internal registers. As a result, TZ is unable to program secure registers during Secure PIL load fails. Moving the handoff after PIL load allows proper secure register programming and enables secure sessions. CRs-Fixed: 2450296 Change-Id: I32c7bf8726b51fdfa73b40819e8fdccdbbc0abe3 Signed-off-by: Chinmay Sawarkar --- msm/vidc/hfi_common.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 1fe54d83381a..32bd91c9503f 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -4431,15 +4431,6 @@ static int __venus_power_on(struct venus_hfi_device *device) device->intr_status = 0; enable_irq(device->hal_data->irq); - /* - * Hand off control of regulators to h/w _after_ enabling clocks. - * Note that the GDSC will turn off when switching from normal - * (s/w triggered) to fast (HW triggered) unless the h/w vote is - * present. Since Venus isn't up yet, the GDSC will be off briefly. - */ - if (__enable_hw_power_collapse(device)) - dprintk(VIDC_ERR, "Failed to enabled inter-frame PC\n"); - return rc; fail_enable_clks: @@ -4535,6 +4526,15 @@ static inline int __resume(struct venus_hfi_device *device) goto err_set_video_state; } + /* + * Hand off control of regulators to h/w _after_ loading fw. + * Note that the GDSC will turn off when switching from normal + * (s/w triggered) to fast (HW triggered) unless the h/w vote is + * present. + */ + if (__enable_hw_power_collapse(device)) + dprintk(VIDC_ERR, "Failed to enabled inter-frame PC\n"); + call_venus_op(device, setup_ucregion_memmap, device); /* Wait for boot completion */ @@ -4621,6 +4621,15 @@ static int __load_fw(struct venus_hfi_device *device) goto fail_protect_mem; } } + /* + * Hand off control of regulators to h/w _after_ loading fw. + * Note that the GDSC will turn off when switching from normal + * (s/w triggered) to fast (HW triggered) unless the h/w vote is + * present. + */ + if (__enable_hw_power_collapse(device)) + dprintk(VIDC_ERR, "Failed to enabled inter-frame PC\n"); + trace_msm_v4l2_vidc_fw_load_end("msm_v4l2_vidc venus_fw load end"); return rc; fail_protect_mem: From 70e7d6b0ba7cf0f6ee0858f3d32cdc72295c4c34 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Wed, 8 May 2019 10:46:54 -0700 Subject: [PATCH 012/452] msm: vidc: move cbr plus variable to legacy cbr Move cbr plus variable to legacy cbr variable as it is interfering with CVP usage. Change-Id: If31f49858486e4295e7dfd9f47175e23c4078200 Signed-off-by: Darshana Patil Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_venc.c | 61 ++++++++++++++++++------------------ msm/vidc/msm_vidc.c | 2 +- msm/vidc/msm_vidc_clocks.c | 10 ++---- msm/vidc/msm_vidc_clocks.h | 2 ++ msm/vidc/msm_vidc_internal.h | 2 +- 5 files changed, 38 insertions(+), 39 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index c019fc3c2baf..d1c61f014bf7 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -39,6 +39,8 @@ #define MIN_CBRPLUS_H 480 #define MAX_CBR_W 1280 #define MAX_CBR_H 720 +#define LEGACY_CBR_BUF_SIZE 500 +#define CBR_PLUS_BUF_SIZE 1000 #define L_MODE V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY #define MIN_NUM_ENC_OUTPUT_BUFFERS 4 @@ -1095,6 +1097,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) inst->clk_data.frame_rate = (DEFAULT_FPS << 16); inst->clk_data.operating_rate = (DEFAULT_FPS << 16); + inst->clk_data.is_legacy_cbr = false; inst->buff_req.buffer[1].buffer_type = HAL_BUFFER_INPUT; inst->buff_req.buffer[1].buffer_count_min_host = @@ -2286,7 +2289,6 @@ int msm_venc_set_rate_control(struct msm_vidc_inst *inst) } hdev = inst->core->device; - inst->clk_data.is_cbr_plus = false; f = &inst->fmts[INPUT_PORT].v4l2_fmt; codec = get_v4l2_codec(inst); height = f->fmt.pix_mp.height; @@ -2344,15 +2346,11 @@ int msm_venc_set_rate_control(struct msm_vidc_inst *inst) int msm_venc_set_vbv_delay(struct msm_vidc_inst *inst) { - int rc = 0; - bool is_greater_or_equal_vga = false; - bool is_less_or_equal_720p = false; struct hfi_device *hdev; struct v4l2_ctrl *ctrl; u32 codec; u32 height, width, fps, mbpf, mbps; - u32 buf_size = 0; u32 max_fps = 15; struct hfi_vbv_hrd_buf_size hrd_buf_size; struct v4l2_format *f; @@ -2363,7 +2361,6 @@ int msm_venc_set_vbv_delay(struct msm_vidc_inst *inst) } hdev = inst->core->device; - inst->clk_data.is_cbr_plus = false; f = &inst->fmts[INPUT_PORT].v4l2_fmt; codec = get_v4l2_codec(inst); height = f->fmt.pix_mp.height; @@ -2373,38 +2370,43 @@ int msm_venc_set_vbv_delay(struct msm_vidc_inst *inst) mbpf = NUM_MBS_PER_FRAME(height, width); mbps = NUM_MBS_PER_SEC(height, width, fps); - if (!(inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR ^ - inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR)) + /* vbv delay is required for CBR_CFR and CBR_VFR only */ + if (inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR && + inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR) return 0; + /* vbv delay is not required for VP8 encoder */ if (codec == V4L2_PIX_FMT_VP8) return 0; - if (((width >= MIN_CBRPLUS_W && height >= MIN_CBRPLUS_H) || - (width >= MIN_CBRPLUS_H && height >= MIN_CBRPLUS_W) || - mbpf >= NUM_MBS_PER_FRAME(MIN_CBRPLUS_H, MIN_CBRPLUS_W)) && - mbps > NUM_MBS_PER_SEC(MIN_CBRPLUS_H, MIN_CBRPLUS_W, max_fps)) - is_greater_or_equal_vga = true; + /* default behavior */ + inst->clk_data.is_legacy_cbr = false; + hrd_buf_size.vbv_hrd_buf_size = CBR_PLUS_BUF_SIZE; - if ((width <= MAX_CBR_W && height <= MAX_CBR_H) || - (width <= MAX_CBR_H && height <= MAX_CBR_W) || - mbpf <= NUM_MBS_PER_FRAME(MAX_CBR_H, MAX_CBR_W)) - is_less_or_equal_720p = true; + /* if resolution greater than MAX_CBR (720p), default behavior */ + if (res_is_greater_than(width, height, MAX_CBR_W, MAX_CBR_H)) + goto set_vbv_delay; - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_VBV_DELAY); - - if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR && - is_greater_or_equal_vga && is_less_or_equal_720p) - buf_size = ctrl->val; - - if ((is_greater_or_equal_vga) && (buf_size != 500)) { - inst->clk_data.is_cbr_plus = true; - hrd_buf_size.vbv_hrd_buf_size = 1000; - } else { - inst->clk_data.is_cbr_plus = false; - hrd_buf_size.vbv_hrd_buf_size = 500; + /* enable legacy cbr if resolution less than MIN_CBRPLUS (VGA) */ + if (res_is_less_than(width, height, MIN_CBRPLUS_W, MIN_CBRPLUS_H) && + mbps <= NUM_MBS_PER_SEC(MIN_CBRPLUS_H, MIN_CBRPLUS_W, + max_fps)) { + inst->clk_data.is_legacy_cbr = true; + hrd_buf_size.vbv_hrd_buf_size = LEGACY_CBR_BUF_SIZE; + goto set_vbv_delay; } + /* enable legacy cbr if rate control is CBR_VFR and VBV delay is 500 */ + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR) { + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_VBV_DELAY); + if (ctrl->val == LEGACY_CBR_BUF_SIZE) { + inst->clk_data.is_legacy_cbr = true; + hrd_buf_size.vbv_hrd_buf_size = LEGACY_CBR_BUF_SIZE; + goto set_vbv_delay; + } + } + +set_vbv_delay: dprintk(VIDC_DBG, "Set hrd_buf_size %d", hrd_buf_size.vbv_hrd_buf_size); rc = call_hfi_op(hdev, session_set_property, @@ -2415,7 +2417,6 @@ int msm_venc_set_vbv_delay(struct msm_vidc_inst *inst) dprintk(VIDC_ERR, "%s: set HRD_BUF_SIZE %u failed\n", __func__, hrd_buf_size.vbv_hrd_buf_size); - inst->clk_data.is_cbr_plus = false; } return rc; } diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index e0a88fbe9f5b..7787157e090a 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -729,7 +729,7 @@ bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst) !(inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) && inst->rc_type != RATE_CONTROL_OFF && inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ && - !inst->clk_data.is_cbr_plus) { + !inst->clk_data.is_legacy_cbr) { dprintk(VIDC_DBG, "%s: cvp allowed\n", __func__); allowed = true; } else { diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index b85ce570be64..620812cbb621 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1242,7 +1242,7 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) int rc = 0; struct hfi_device *hdev; struct hfi_video_work_route pdata; - bool cbr_plus; + bool is_legacy_cbr; u32 codec; if (!inst || !inst->core || !inst->core->device) { @@ -1253,7 +1253,7 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) } hdev = inst->core->device; - cbr_plus = inst->clk_data.is_cbr_plus; + is_legacy_cbr = inst->clk_data.is_legacy_cbr; pdata.video_work_route = 4; codec = get_v4l2_codec(inst); @@ -1263,7 +1263,6 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) pdata.video_work_route = 1; } else if (inst->session_type == MSM_VIDC_ENCODER) { u32 slice_mode, width, height; - bool is_1080p_above; struct v4l2_format *f; slice_mode = msm_comm_g_ctrl_for_id(inst, @@ -1272,11 +1271,8 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) height = f->fmt.pix_mp.height; width = f->fmt.pix_mp.width; - is_1080p_above = res_is_greater_than(width, height, 1920, 1088); - if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES || - codec == V4L2_PIX_FMT_VP8 || - (!is_1080p_above && !cbr_plus)) { + codec == V4L2_PIX_FMT_VP8 || is_legacy_cbr) { pdata.video_work_route = 1; } } else { diff --git a/msm/vidc/msm_vidc_clocks.h b/msm/vidc/msm_vidc_clocks.h index ed0588fb6c4f..effbe7c75819 100644 --- a/msm/vidc/msm_vidc_clocks.h +++ b/msm/vidc/msm_vidc_clocks.h @@ -11,6 +11,8 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst); int msm_vidc_set_clocks(struct msm_vidc_core *core); int msm_comm_vote_bus(struct msm_vidc_core *core); int msm_dcvs_try_enable(struct msm_vidc_inst *inst); +bool res_is_less_than(u32 width, u32 height, u32 ref_width, u32 ref_height); +bool res_is_greater_than(u32 width, u32 height, u32 ref_width, u32 ref_height); int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst); int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst); int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst); diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index d9af3b29c574..0dd5b8fe1f70 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -384,7 +384,7 @@ struct clock_data { u32 opb_fourcc; u32 work_mode; bool low_latency_mode; - bool is_cbr_plus; + bool is_legacy_cbr; u32 work_route; u32 dcvs_flags; u32 frame_rate; From 05f2237d39a0d6255e53063e138cb763e9e0d9bb Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Fri, 10 May 2019 11:39:07 +0800 Subject: [PATCH 013/452] techpack: video: fix integer overflow issue for blur resolution Use S32_MAX instead of U32_MAX for maximum ctrl val for blur resolution, as ctrl val is s32. Change-Id: Ie92f6ba831ffead2d56c9eee24917b8a42cdd564 Signed-off-by: Qiwei Liu --- msm/vidc/msm_venc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index d1c61f014bf7..3c70ad3fca22 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -792,7 +792,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .name = "Set Blur width/height", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, - .maximum = 0xFFFFFFFF, + .maximum = S32_MAX, .default_value = 0, .step = 1, }, @@ -3788,7 +3788,9 @@ int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst) frame_sz.buffer_type = HFI_BUFFER_INPUT; frame_sz.height = ctrl->val & 0xFFFF; - frame_sz.width = (ctrl->val & 0xFFFF0000) >> 16; + frame_sz.width = (ctrl->val & 0x7FFF0000) >> 16; + dprintk(VIDC_DBG, "%s: type %u, height %u, width %u\n", __func__, + frame_sz.buffer_type, frame_sz.height, frame_sz.width); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_BLUR_FRAME_SIZE, &frame_sz, sizeof(frame_sz)); From d64baed296ec3ba5c712a23b7b78b3b391971dba Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Fri, 10 May 2019 14:00:13 -0700 Subject: [PATCH 014/452] msm: vidc: Use input bitrate to calculate decoder bus vote By calculating bitrate at each frame, we get a better estimate of the BW requirements of the decode session. Thus improving performance and power usage. CRs-Fixed: 2451137 Change-Id: I22f0029bbb7d501340469a317e89de7eb34717c4 Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc_bus_iris2.c | 2 +- msm/vidc/msm_vidc_clocks.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_bus_iris2.c b/msm/vidc/msm_vidc_bus_iris2.c index 400ca9991314..fc91088ef6d7 100644 --- a/msm/vidc/msm_vidc_bus_iris2.c +++ b/msm/vidc/msm_vidc_bus_iris2.c @@ -134,7 +134,7 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, lcu_per_frame = DIV_ROUND_UP(width, lcu_size) * DIV_ROUND_UP(height, lcu_size); - bitrate = __lut(width, height, fps)->bitrate; + bitrate = (d->bitrate + 1000000 - 1) / 1000000; bins_to_bit_factor = FP_INT(4); diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 620812cbb621..faea7f22f46b 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -344,6 +344,9 @@ int msm_comm_vote_bus(struct msm_vidc_core *core) (inst->clk_data.frame_rate >> 16) * vote_data[i].fps; } + } else if (inst->session_type == MSM_VIDC_DECODER) { + vote_data[i].bitrate = + filled_len * vote_data[i].fps * 8; } vote_data[i].power_mode = 0; From 706c47da7718ebf0e9af77ea555d427de3ecfc1e Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Tue, 14 May 2019 14:03:42 -0700 Subject: [PATCH 015/452] msm: vidc: Remove Picture Type Decode Driver Support Remove support for V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE. Cleared related code. Change-Id: I3b7100dfd08ee68a5033d8f6ec2cfdcfbbfbbe14 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_vdec.c | 44 -------------------------------------------- msm/vidc/vidc_hfi.h | 4 ---- 2 files changed, 48 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 45a4774ba6a7..b2b35cc202ac 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -82,20 +82,6 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, .step = 1, }, - { - .id = V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE, - .name = "Picture Type Decoding", - .type = V4L2_CTRL_TYPE_BITMASK, - .minimum = 0, - .maximum = (V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_I | - V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_P | - V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_B), - .default_value = (V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_I | - V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_P | - V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_B), - .step = 0, - .qmenu = NULL, - }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE, .name = "Sync Frame Decode", @@ -854,7 +840,6 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) (msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val) << 28); break; case V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER: - case V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE: case V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_8BIT: case V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_10BIT: break; @@ -1113,32 +1098,6 @@ int msm_vdec_set_output_order(struct msm_vidc_inst *inst) return rc; } -int msm_vdec_set_picture_type(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct hfi_device *hdev; - struct v4l2_ctrl *ctrl; - struct hfi_enable_picture enable_picture; - - if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); - return -EINVAL; - } - hdev = inst->core->device; - - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE); - enable_picture.picture_type = ctrl->val; - - dprintk(VIDC_DBG, "%s: %#x\n", __func__, enable_picture.picture_type); - rc = call_hfi_op(hdev, session_set_property, inst->session, - HFI_PROPERTY_PARAM_VDEC_PICTURE_TYPE_DECODE, &enable_picture, - sizeof(enable_picture)); - if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); - - return rc; -} - int msm_vdec_set_sync_frame_mode(struct msm_vidc_inst *inst) { int rc = 0; @@ -1462,9 +1421,6 @@ int msm_vdec_set_properties(struct msm_vidc_inst *inst) if (rc) goto exit; rc = msm_vdec_set_output_order(inst); - if (rc) - goto exit; - rc = msm_vdec_set_picture_type(inst); if (rc) goto exit; rc = msm_vdec_set_sync_frame_mode(inst); diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index d3ab844a2499..11b39cfb3430 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -257,10 +257,6 @@ struct hfi_data_payload { u8 rg_data[1]; }; -struct hfi_enable_picture { - u32 picture_type; -}; - struct hfi_mb_error_map { u32 error_map_size; u8 rg_error_map[1]; From 37915f19822c0a97309be8191f65945990ebd2e7 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Thu, 9 May 2019 16:03:39 +0800 Subject: [PATCH 016/452] msm: vidc: enable CSC for HEVC Allow to use CSC for HEVC encodings. Change-Id: I059db52215de56cc1dc38c13df5e0d188b4df5d0 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_venc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 3c70ad3fca22..707a97ef9e6a 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3432,7 +3432,8 @@ int msm_venc_set_video_csc(struct msm_vidc_inst *inst) } hdev = inst->core->device; - if (get_v4l2_codec(inst) != V4L2_PIX_FMT_H264) + if (get_v4l2_codec(inst) != V4L2_PIX_FMT_H264 && + get_v4l2_codec(inst) != V4L2_PIX_FMT_HEVC) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC); From 96cf4d94e438d355a4c3086fd3bd851eb6ff8e3a Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Tue, 14 May 2019 15:19:35 +0530 Subject: [PATCH 017/452] techpack: video: add support for lito in makefile This change adds support to compile video driver project for lito. Change-Id: I398fd8f37cb42bb20f849f17284c377001c14dde Signed-off-by: Govindaraj Rajagopal --- Makefile | 9 +++++++++ config/litovid.conf | 1 + config/litovidconf.h | 6 ++++++ 3 files changed, 16 insertions(+) create mode 100644 config/litovid.conf create mode 100644 config/litovidconf.h diff --git a/Makefile b/Makefile index d4981863d8de..0fcf3f6df3da 100644 --- a/Makefile +++ b/Makefile @@ -9,4 +9,13 @@ ifeq ($(CONFIG_ARCH_KONA), y) LINUXINCLUDE += -include $(srctree)/techpack/video/config/konavidconf.h endif +# auto-detect subdirs +ifeq ($(CONFIG_ARCH_LITO), y) +include $(srctree)/techpack/video/config/litovid.conf +endif + +ifeq ($(CONFIG_ARCH_LITO), y) +LINUXINCLUDE += -include $(srctree)/techpack/video/config/litovidconf.h +endif + obj-y +=msm/ diff --git a/config/litovid.conf b/config/litovid.conf new file mode 100644 index 000000000000..efb4eedfb73e --- /dev/null +++ b/config/litovid.conf @@ -0,0 +1 @@ +export CONFIG_MSM_VIDC_V4L2=y diff --git a/config/litovidconf.h b/config/litovidconf.h new file mode 100644 index 000000000000..78d6c57a6920 --- /dev/null +++ b/config/litovidconf.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#define CONFIG_MSM_VIDC_V4L2 1 From 16e94fc70e2594e886b7d84eaeb8d86b147e4cf3 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Wed, 8 May 2019 17:11:02 +0530 Subject: [PATCH 018/452] msm_vidc: Add support for Cx ipeak limitation Make a vote call whenever the clock frequency driver computes crosses a threshold mark. This vote call handles the situation when many subsystems are in turbo and where a need arises to throttle the CDSP current. CRs-Fixed: 2330072 Change-Id: Id10c02749b00fd5a1b1980923c5034648bd35985 Signed-off-by: shubham gupta Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/hfi_common.c | 57 ++++++++++++++++++++++++++++----- msm/vidc/msm_vidc_res_parse.c | 59 ++++++++++++++++++++++++++++++++++- msm/vidc/msm_vidc_resources.h | 3 ++ 3 files changed, 110 insertions(+), 9 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 32bd91c9503f..a7945cc563de 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -1263,6 +1264,51 @@ static enum hal_default_properties venus_hfi_get_default_properties(void *dev) return prop; } +static int __set_clk_rate(struct venus_hfi_device *device, + struct clock_info *cl, u64 rate) +{ + int rc = 0; + u64 threshold_freq = device->res->clk_freq_threshold; + struct cx_ipeak_client *ipeak = device->res->cx_ipeak_context; + struct clk *clk = cl->clk; + + if (ipeak && device->clk_freq < threshold_freq && rate >= threshold_freq) { + rc = cx_ipeak_update(ipeak, true); + if (rc) { + dprintk(VIDC_ERR, + "%s: cx_ipeak_update failed!\n", __func__); + return rc; + } + dprintk(VIDC_PROF, + "cx_ipeak_update: up, clk freq = %lu rate = %lu threshold_freq = %lu\n", + device->clk_freq, rate, threshold_freq); + } + + rc = clk_set_rate(clk, rate); + if (rc) { + dprintk(VIDC_ERR, + "%s: Failed to set clock rate %llu %s: %d\n", + __func__, rate, cl->name, rc); + return rc; + } + + device->clk_freq = rate; + + if (device->clk_freq >= threshold_freq && rate < threshold_freq) { + rc = cx_ipeak_update(ipeak, false); + if (rc) { + dprintk(VIDC_ERR, + "cx_ipeak_update failed! ipeak %pK\n", ipeak); + return rc; + } + dprintk(VIDC_PROF, + "cx_ipeak_update: up, clk freq = %lu rate = %lu threshold_freq = %lu\n", + device->clk_freq, rate, threshold_freq); + } + + return rc; +} + static int __set_clocks(struct venus_hfi_device *device, u32 freq) { struct clock_info *cl; @@ -1270,14 +1316,9 @@ static int __set_clocks(struct venus_hfi_device *device, u32 freq) venus_hfi_for_each_clock(device, cl) { if (cl->has_scaling) {/* has_scaling */ - device->clk_freq = freq; - rc = clk_set_rate(cl->clk, freq); - if (rc) { - dprintk(VIDC_ERR, - "Failed to set clock rate %u %s: %d %s\n", - freq, cl->name, rc, __func__); + rc = __set_clk_rate(device, cl, freq); + if (rc) return rc; - } trace_msm_vidc_perf_clock_scale(cl->name, freq); dprintk(VIDC_PROF, "Scaling clock %s to %u\n", @@ -3776,7 +3817,7 @@ static inline int __prepare_enable_clks(struct venus_hfi_device *device) * it to the lowest frequency possible */ if (cl->has_scaling) - clk_set_rate(cl->clk, clk_round_rate(cl->clk, 0)); + __set_clk_rate(device, cl, clk_round_rate(cl->clk, 0)); rc = clk_set_flags(cl->clk, CLKFLAG_RETAIN_PERIPH); if (rc) { diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index de1d60a124b7..b1e46a5db018 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -111,6 +111,13 @@ static inline void msm_vidc_free_clock_table( res->clock_set.count = 0; } +static inline void msm_vidc_free_cx_ipeak_context( + struct msm_vidc_platform_resources *res) +{ + cx_ipeak_unregister(res->cx_ipeak_context); + res->cx_ipeak_context = NULL; +} + void msm_vidc_free_platform_resources( struct msm_vidc_platform_resources *res) { @@ -121,6 +128,7 @@ void msm_vidc_free_platform_resources( msm_vidc_free_qdss_addr_table(res); msm_vidc_free_bus_vectors(res); msm_vidc_free_buffer_usage_table(res); + msm_vidc_free_cx_ipeak_context(res); } static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res) @@ -832,6 +840,46 @@ int read_platform_resources_from_drv_data( } +static int msm_vidc_populate_cx_ipeak_context( + struct msm_vidc_platform_resources *res) +{ + struct platform_device *pdev = res->pdev; + int rc = 0; + + if (of_find_property(pdev->dev.of_node, + "qcom,cx-ipeak-data", NULL)) + res->cx_ipeak_context = cx_ipeak_register( + pdev->dev.of_node, "qcom,cx-ipeak-data"); + else + return rc; + + if (IS_ERR(res->cx_ipeak_context)) { + rc = PTR_ERR(res->cx_ipeak_context); + if (rc == -EPROBE_DEFER) + dprintk(VIDC_INFO, + "cx-ipeak register failed. Deferring probe!"); + else + dprintk(VIDC_ERR, + "cx-ipeak register failed. rc: %d", rc); + + res->cx_ipeak_context = NULL; + return rc; + } + + if (res->cx_ipeak_context) + dprintk(VIDC_INFO, "cx-ipeak register successful"); + else + dprintk(VIDC_INFO, "cx-ipeak register not implemented"); + + of_property_read_u32(pdev->dev.of_node, + "qcom,clock-freq-threshold", + &res->clk_freq_threshold); + dprintk(VIDC_DBG, "cx ipeak threshold frequency = %u\n", + res->clk_freq_threshold); + + return rc; +} + int read_platform_resources_from_dt( struct msm_vidc_platform_resources *res) { @@ -916,10 +964,19 @@ int read_platform_resources_from_dt( goto err_setup_legacy_cb; } + rc = msm_vidc_populate_cx_ipeak_context(res); + if (rc) { + dprintk(VIDC_ERR, + "Failed to setup cx-ipeak %d\n", rc); + goto err_register_cx_ipeak; + } + return rc; -err_load_reset_table: +err_register_cx_ipeak: + msm_vidc_free_cx_ipeak_context(res); err_setup_legacy_cb: +err_load_reset_table: msm_vidc_free_allowed_clocks_table(res); err_load_allowed_clocks_table: msm_vidc_free_clock_table(res); diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index c6ea445d14f3..59847ea39a6b 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -9,6 +9,7 @@ #include #include "msm_vidc.h" #include +#include "soc/qcom/cx_ipeak.h" #define MAX_BUFFER_TYPES 32 @@ -206,6 +207,8 @@ struct msm_vidc_platform_resources { uint32_t fw_cycles; uint32_t fw_vpp_cycles; struct msm_vidc_ubwc_config_data *ubwc_config; + uint32_t clk_freq_threshold; + struct cx_ipeak_client *cx_ipeak_context; }; static inline bool is_iommu_present(struct msm_vidc_platform_resources *res) From 9aeda12e522134454843a8cad39c057d0a5d4ff9 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Wed, 8 May 2019 09:35:15 +0530 Subject: [PATCH 019/452] msm: vidc: update fuse map for lito read bit 21 of register FEATURE_CONFIG1(0x00786008) to check if fuse is blown to enable lower SKU spec. Change-Id: I63c5d764aed13c60c0d213aa0fc29dec9edfef3f Signed-off-by: Dikshita Agarwal --- msm/vidc/msm_vidc_platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 61ba6e5a4e2b..9ec9c5ca013a 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -770,7 +770,7 @@ static struct msm_vidc_common_data sdm670_common_data_v1[] = { }; static struct msm_vidc_efuse_data lito_efuse_data[] = { - EFUSE_ENTRY(0x00786018, 4, 0x00000400, 0x0a, SKU_VERSION), + EFUSE_ENTRY(0x00786008, 4, 0x00200000, 0x15, SKU_VERSION), }; static struct msm_vidc_efuse_data sdm670_efuse_data[] = { From 884bf7ef2170d392d092f167a5f05f5138a38e52 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Wed, 8 May 2019 09:58:25 +0530 Subject: [PATCH 020/452] msm: vidc: add platform specific capabilities for lito Add platform specific capabilities for lito and use them in place of firmware capabilities. Change-Id: I4aca463604444b7ec161f794aac5ddd334c14368 Signed-off-by: Dikshita Agarwal --- msm/vidc/msm_vidc_platform.c | 130 +++++++++++++++++++++++++++++++++-- 1 file changed, 126 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 9ec9c5ca013a..ca454c39bc88 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -157,6 +157,122 @@ static struct msm_vidc_codec default_codecs[] = { {ENC, H264}, {ENC, HEVC}, {ENC, VP8}, }; +static struct msm_vidc_codec_capability lito_capabilities_v0[] = { + /* {cap_type, domains, codecs, min, max, step_size, default_value} */ + {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 5760, 1, 1920}, + {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 5760, 1, 1080}, + /* ((5760 * 2880) / 256) */ + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 1, 64800, 1, 34560}, + /* ((4096x2160)/256)@90fps */ + {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 1, 3110400, 1, 2073600}, + {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 480, 1, 30}, + {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 200000000, 1, 20000000}, + {CAP_SCALE_X, DOMAINS_ALL, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_SCALE_Y, DOMAINS_ALL, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, + {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, + {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 4, 1, 0}, + /* ((1920 * 1088) / 256) * 30 fps */ + {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, + 0, 244800, 1, 244800}, + {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, + {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_I_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 20}, + {CAP_P_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 40}, + {CAP_B_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 40}, + /* 10 slices */ + {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_SLICE_MB, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, + + /* VP8 specific */ + {CAP_FRAME_WIDTH, ENC|DEC, VP8, 96, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 96, 1080, 1, 1080}, + /* (1920 * 1088) / 256 */ + {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 1, 8160, 1, 8160}, + /* ((1920 * 1088) / 256) * 120*/ + {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 1, 979200, 1, 244800}, + {CAP_FRAMERATE, ENC|DEC, VP8, 1, 120, 1, 30}, + {CAP_BITRATE, ENC, VP8, 1, 40000000, 1, 20000000}, + {CAP_BITRATE, DEC, VP8, 1, 100000000, 1, 20000000}, + + /* Mpeg2 decoder specific */ + {CAP_FRAME_WIDTH, DEC, MPEG2, 96, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, MPEG2, 96, 1920, 1, 1080}, + /* (1920 * 1088) / 256 */ + {CAP_MBS_PER_FRAME, DEC, MPEG2, 1, 8160, 1, 8160}, + /* ((1920 * 1088) / 256) * 30*/ + {CAP_MBS_PER_SECOND, DEC, MPEG2, 1, 244800, 1, 244800}, + {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, + {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, + + /* Secure usecase specific */ + {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1080}, + /* (4096 * 2160) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 1, 34560, 1, 34560}, + {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, +}; + +static struct msm_vidc_codec_capability lito_capabilities_v1[] = { + /* {cap_type, domains, codecs, min, max, step_size, default_value} */ + {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1080}, + /* ((4096 * 2160) / 256) */ + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 1, 34560, 1, 34560}, + /* 4K@30 decode + 1080@30 encode */ + {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 1, 1281600, 1, 2073600}, + {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 240, 1, 30}, + {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 100000000, 1, 20000000}, + {CAP_SCALE_X, DOMAINS_ALL, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_SCALE_Y, DOMAINS_ALL, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, + {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, + {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 4, 1, 0}, + /* ((1920 * 1088) / 256) * 30 fps */ + {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, + 0, 244800, 1, 244800}, + {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, + {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_I_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 20}, + {CAP_P_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 40}, + {CAP_B_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 40}, + /* 10 slices */ + {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_SLICE_MB, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, + + /* VP8 specific */ + {CAP_FRAME_WIDTH, ENC|DEC, VP8, 96, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 96, 1080, 1, 1080}, + /* (1920 * 1088) / 256 */ + {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 1, 8160, 1, 8160}, + /* ((1920 * 1088) / 256) * 120*/ + {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 1, 979200, 1, 244800}, + {CAP_FRAMERATE, ENC|DEC, VP8, 1, 120, 1, 30}, + {CAP_BITRATE, ENC, VP8, 1, 40000000, 1, 20000000}, + {CAP_BITRATE, DEC, VP8, 1, 100000000, 1, 20000000}, + + /* Mpeg2 decoder specific */ + {CAP_FRAME_WIDTH, DEC, MPEG2, 96, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, MPEG2, 96, 1920, 1, 1080}, + /* (1920 * 1088) / 256 */ + {CAP_MBS_PER_FRAME, DEC, MPEG2, 1, 8160, 1, 8160}, + /* ((1920 * 1088) / 256) * 30*/ + {CAP_MBS_PER_SECOND, DEC, MPEG2, 1, 244800, 1, 244800}, + {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, + {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, + + /* Secure usecase specific */ + {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1080}, + /* (4096 * 2160) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 1, 34560, 1, 34560}, + {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, +}; + static struct msm_vidc_codec_capability kona_capabilities[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 8192, 1, 1920}, @@ -263,7 +379,7 @@ static struct msm_vidc_common_data lito_common_data_v0[] = { }, { .key = "qcom,max-secure-instances", - .value = 5, + .value = 3, }, { .key = "qcom,max-hw-load", @@ -275,7 +391,7 @@ static struct msm_vidc_common_data lito_common_data_v0[] = { .value = 8160,/* ((1920x1088)/256) */ }, { - .key = "qcom,qcom,max-hq-mbs-per-sec", + .key = "qcom,max-hq-mbs-per-sec", .value = 244800,/* ((1920x1088)/256) MBs@30fps */ }, { @@ -335,7 +451,7 @@ static struct msm_vidc_common_data lito_common_data_v1[] = { }, { .key = "qcom,max-secure-instances", - .value = 5, + .value = 3, }, { .key = "qcom,max-hw-load", @@ -346,7 +462,7 @@ static struct msm_vidc_common_data lito_common_data_v1[] = { .value = 8160,/* ((1920x1088)/256) */ }, { - .key = "qcom,qcom,max-hq-mbs-per-sec", + .key = "qcom,max-hq-mbs-per-sec", .value = 244800,/* ((1920x1088)/256) MBs@30fps */ }, { @@ -810,6 +926,10 @@ static struct msm_vidc_platform_data lito_data = { .sku_version = 0, .vpu_ver = VPU_VERSION_IRIS1, .ubwc_config = 0x0, + .codecs = default_codecs, + .codecs_count = ARRAY_SIZE(default_codecs), + .codec_caps = lito_capabilities_v0, + .codec_caps_count = ARRAY_SIZE(lito_capabilities_v0), }; static struct msm_vidc_platform_data kona_data = { @@ -1016,6 +1136,8 @@ void *vidc_get_drv_data(struct device *dev) driver_data->common_data = lito_common_data_v1; driver_data->common_data_length = ARRAY_SIZE(lito_common_data_v1); + driver_data->codec_caps = lito_capabilities_v1; + driver_data->codec_caps_count = ARRAY_SIZE(lito_capabilities_v1); } } From 1a50269424c81bb9cbb591d7425bb5882618d7ea Mon Sep 17 00:00:00 2001 From: Aniket Masule Date: Fri, 10 May 2019 11:31:24 +0530 Subject: [PATCH 021/452] msm: vidc: Add state check to allow flush command Entry field from clock data structure gets initialized with codec data during state transition from MSM_VIDC_CORE_INIT_DONE to MSM_VIDC_OPEN. When flush is called before this transaction, it calls msm_clock_data_reset where mentioned field is getting accessed, which results in uninitialized data access. Add state check to ensure the command is handled in right sequence. Change-Id: Ic98221cbfe465415d89a0e2891f8af65f584f1dc Signed-off-by: Aniket Masule --- msm/vidc/msm_vidc_clocks.c | 2 +- msm/vidc/msm_vidc_common.c | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index faea7f22f46b..a1905a13246b 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1099,7 +1099,7 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) dprintk(VIDC_DBG, "Init DCVS Load\n"); - if (!inst || !inst->core) { + if (!inst || !inst->core || !inst->clk_data.entry) { dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n", __func__, inst); return; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 390f119f9611..24f04f5d0fb4 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5091,6 +5091,14 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) "Invalid params, inst %pK\n", inst); return -EINVAL; } + + if (inst->state < MSM_VIDC_OPEN_DONE) { + dprintk(VIDC_ERR, + "Invalid state to call flush, inst %pK, state %#x\n", + inst, inst->state); + return -EINVAL; + } + core = inst->core; hdev = core->device; From 218c9b688b53c541539a617c3c78b8ca1dc0f327 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Thu, 9 May 2019 11:20:22 -0700 Subject: [PATCH 022/452] msm: vidc: send queues virtual addr to video firmware Write queues virtual address to video firmware to use it for debug purpose to get more information. Change-Id: I9bf347c3ea279196e7ae40c936f6b3608c94b09b Signed-off-by: Maheshwar Ajja --- msm/vidc/hfi_iris2.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/msm/vidc/hfi_iris2.c b/msm/vidc/hfi_iris2.c index d01ceef45aa7..ecae4f752936 100644 --- a/msm/vidc/hfi_iris2.c +++ b/msm/vidc/hfi_iris2.c @@ -14,6 +14,11 @@ #define CPU_IC_BASE_OFFS_IRIS2 (CPU_BASE_OFFS_IRIS2) #define CPU_CS_A2HSOFTINTCLR_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x1C) +#define CPU_CS_VCICMD_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x20) +#define CPU_CS_VCICMDARG0_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x24) +#define CPU_CS_VCICMDARG1_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x28) +#define CPU_CS_VCICMDARG2_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x2C) +#define CPU_CS_VCICMDARG3_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x30) #define CPU_CS_VMIMSG_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x34) #define CPU_CS_VMIMSGAG0_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x38) #define CPU_CS_VMIMSGAG1_IRIS2 (CPU_CS_BASE_OFFS_IRIS2 + 0x3C) @@ -160,6 +165,11 @@ void __setup_ucregion_memory_map_iris2(struct venus_hfi_device *device) if (device->qdss.align_device_addr) __write_register(device, MMAP_ADDR_IRIS2, (u32)device->qdss.align_device_addr); + /* update queues vaddr for debug purpose */ + __write_register(device, CPU_CS_VCICMDARG0_IRIS2, + (u32)device->iface_q_table.align_virtual_addr); + __write_register(device, CPU_CS_VCICMDARG1_IRIS2, + (u32)((u64)device->iface_q_table.align_virtual_addr >> 32)); } void __power_off_iris2(struct venus_hfi_device *device) From 2922c259e175826de4c50b235834490d3ce4ae76 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Mon, 13 May 2019 12:28:25 -0700 Subject: [PATCH 023/452] msm: vidc: enable cvp usage Enable CVP usage to improve encoded video quality. Change-Id: Ice0b6590435c094fa52bedb89f65150ab0c9a378 Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_vidc_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index abaf11ac117c..5e2a76b81ee3 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -25,7 +25,7 @@ bool msm_vidc_fw_coverage = !true; bool msm_vidc_thermal_mitigation_disabled = !true; int msm_vidc_clock_voting = !1; bool msm_vidc_syscache_disable = !true; -bool msm_vidc_cvp_usage = !true; +bool msm_vidc_cvp_usage = true; #define MAX_DBG_BUF_SIZE 4096 From a4d013e724302a3ed7f9c63dcaa63bc5eace76ff Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Thu, 16 May 2019 16:44:50 +0800 Subject: [PATCH 024/452] msm: vidc: support dynamic blur info config Support dynamically config blur resolution to firmware. Remove unused code for encoder aspect_ratio extradata. Change-Id: Id2896ab943de4b676338b42bd4993d4057e960ac Signed-off-by: Qiwei Liu --- msm/vidc/msm_venc.c | 12 +++++++++--- msm/vidc/msm_venc.h | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 707a97ef9e6a..48991d3d4128 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1717,6 +1717,15 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) return -EINVAL; } break; + case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_DIMENSIONS: + if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_set_blur_resolution(inst); + if (rc) + dprintk(VIDC_ERR, + "%s: set blur resolution failed\n", + __func__); + } + break; case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER: case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: case V4L2_CID_ROTATE: @@ -1747,7 +1756,6 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH: case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT: - case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_DIMENSIONS: case V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY: case V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM: case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: @@ -3840,8 +3848,6 @@ int msm_venc_set_extradata(struct msm_vidc_inst *inst) codec = get_v4l2_codec(inst); if (inst->prop.extradata_ctrls == EXTRADATA_NONE) { // Disable all Extradata - msm_comm_set_index_extradata(inst, - MSM_VIDC_EXTRADATA_ASPECT_RATIO, 0x0); msm_comm_set_extradata(inst, HFI_PROPERTY_PARAM_VENC_LTR_INFO, 0x0); msm_comm_set_extradata(inst, diff --git a/msm/vidc/msm_venc.h b/msm/vidc/msm_venc.h index 4894e4013d43..f8c0b0a666a6 100644 --- a/msm/vidc/msm_venc.h +++ b/msm/vidc/msm_venc.h @@ -37,4 +37,5 @@ int msm_venc_set_hp_max_layer(struct msm_vidc_inst *inst); int msm_venc_set_hp_layer(struct msm_vidc_inst *inst); int msm_venc_set_base_layer_priority_id(struct msm_vidc_inst *inst); int msm_venc_set_lossless(struct msm_vidc_inst *inst); +int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst); #endif From 4eab7c9c7fee0c86eeda40b153333acef3de4fde Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Thu, 9 May 2019 13:24:45 +0800 Subject: [PATCH 025/452] msm: vidc: amend video driver and firmware logging Route all firmware logs to custom tracer by default custom tracer logs can be enabled using "echo msm_vidc_events:* >> /d/tracing/set_event" custom tracer logs can be collected using cat /d/tracing/trace_pipe > trace.txt New log masks: VIDC_ERR = 0x00000001, VIDC_WARN = 0x00000002, VIDC_INFO = 0x00000004, VIDC_DBG = 0x00000008, VIDC_PROF = 0x00000010, VIDC_PKT = 0x00000020, VIDC_PRINTK = 0x00001000, VIDC_FTRACE = 0x00002000, FW_LOW = 0x00010000, FW_MEDIUM = 0x00020000, FW_HIGH = 0x00040000, FW_ERROR = 0x00080000, FW_FATAL = 0x00100000, FW_PERF = 0x00200000, FW_PRINTK = 0x10000000, FW_FTRACE = 0x20000000, 12 bits [0 .. 11] are driver log level mask, 4 bits [12 .. 15] are driver log route, 12 bits [16 .. 27] are firmware log level, 4 bits [28 .. 31] are firmware log route. Change-Id: Ib65ac3bdd6ad535775aaed4adf1df3c7b03681a8 Signed-off-by: Shi Zhongbo --- msm/vidc/hfi_common.c | 16 +++++------ msm/vidc/msm_vidc_debug.c | 12 +++------ msm/vidc/msm_vidc_debug.h | 56 ++++++++++++++++++++++----------------- 3 files changed, 43 insertions(+), 41 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index a7945cc563de..f3c6c71b37d3 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -2094,7 +2094,7 @@ static int venus_hfi_core_init(void *device) if (rc || __iface_cmdq_write(dev, &version_pkt)) dprintk(VIDC_WARN, "Failed to send image version pkt to f/w\n"); - __sys_set_debug(device, msm_vidc_fw_debug); + __sys_set_debug(device, (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT); __enable_subcaches(device); __set_subcaches(device); @@ -2291,7 +2291,8 @@ static int venus_hfi_session_set_property(void *sess, static void __set_default_sys_properties(struct venus_hfi_device *device) { - if (__sys_set_debug(device, msm_vidc_fw_debug)) + if (__sys_set_debug(device, + (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT)) dprintk(VIDC_WARN, "Setting fw_debug msg ON failed\n"); if (__sys_set_power_control(device, true)) dprintk(VIDC_WARN, "Setting h/w power collapse ON failed\n"); @@ -3238,7 +3239,7 @@ static void __process_sys_error(struct venus_hfi_device *device) static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) { bool local_packet = false; - enum vidc_msg_prio log_level = VIDC_FW; + enum vidc_msg_prio log_level = msm_vidc_debug; if (!device) { dprintk(VIDC_ERR, "%s: Invalid params\n", __func__); @@ -3256,11 +3257,10 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) local_packet = true; /* - * Local packek is used when something FATAL occurred. - * It is good to print these logs by default. + * Local packek is used when error occurred. + * It is good to print these logs to printk as well. */ - - log_level = VIDC_ERR; + log_level |= VIDC_PRINTK; } while (!__iface_dbgq_read(device, packet)) { @@ -4594,7 +4594,7 @@ static inline int __resume(struct venus_hfi_device *device) device->res->pm_qos_latency_us); } - __sys_set_debug(device, msm_vidc_fw_debug); + __sys_set_debug(device, (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT); __enable_subcaches(device); __set_subcaches(device); diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index abaf11ac117c..2511d1a3ed8d 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -9,18 +9,14 @@ #include "vidc_hfi_api.h" #include -int msm_vidc_debug = VIDC_ERR | VIDC_WARN; +int msm_vidc_debug = VIDC_ERR | VIDC_WARN | VIDC_PRINTK | + FW_HIGH | FW_ERROR | FW_FATAL | FW_FTRACE; EXPORT_SYMBOL(msm_vidc_debug); -int msm_vidc_debug_out = VIDC_OUT_PRINTK; -EXPORT_SYMBOL(msm_vidc_debug_out); - bool msm_vidc_lossless_encode = !true; EXPORT_SYMBOL(msm_vidc_lossless_encode); -int msm_vidc_fw_debug = HFI_DEBUG_MSG_HIGH | - HFI_DEBUG_MSG_ERROR | HFI_DEBUG_MSG_FATAL; -int msm_vidc_fw_debug_mode = 1; +int msm_vidc_fw_debug_mode = HFI_DEBUG_MODE_QUEUE; bool msm_vidc_fw_coverage = !true; bool msm_vidc_thermal_mitigation_disabled = !true; int msm_vidc_clock_voting = !1; @@ -179,10 +175,8 @@ struct dentry *msm_vidc_debugfs_init_drv(void) ok = __debugfs_create(x32, "debug_level", &msm_vidc_debug) && - __debugfs_create(x32, "fw_level", &msm_vidc_fw_debug) && __debugfs_create(u32, "fw_debug_mode", &msm_vidc_fw_debug_mode) && __debugfs_create(bool, "fw_coverage", &msm_vidc_fw_coverage) && - __debugfs_create(u32, "debug_output", &msm_vidc_debug_out) && __debugfs_create(bool, "disable_thermal_mitigation", &msm_vidc_thermal_mitigation_disabled) && __debugfs_create(u32, "core_clock_voting", diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index 58217d5c03d9..f34978288c23 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -32,18 +32,25 @@ */ enum vidc_msg_prio { - VIDC_ERR = 0x0001, - VIDC_WARN = 0x0002, - VIDC_INFO = 0x0004, - VIDC_DBG = 0x0008, - VIDC_PROF = 0x0010, - VIDC_PKT = 0x0020, - VIDC_FW = 0x1000, -}; - -enum vidc_msg_out { - VIDC_OUT_PRINTK = 0, + VIDC_ERR = 0x00000001, + VIDC_WARN = 0x00000002, + VIDC_INFO = 0x00000004, + VIDC_DBG = 0x00000008, + VIDC_PROF = 0x00000010, + VIDC_PKT = 0x00000020, + VIDC_PRINTK = 0x00001000, + VIDC_FTRACE = 0x00002000, + FW_LOW = 0x00010000, + FW_MEDIUM = 0x00020000, + FW_HIGH = 0x00040000, + FW_ERROR = 0x00080000, + FW_FATAL = 0x00100000, + FW_PERF = 0x00200000, + FW_PRINTK = 0x10000000, + FW_FTRACE = 0x20000000, }; +#define FW_LOGSHIFT 16 +#define FW_LOGMASK 0x0FFF0000 enum msm_vidc_debugfs_event { MSM_VIDC_DEBUGFS_EVENT_ETB, @@ -53,8 +60,6 @@ enum msm_vidc_debugfs_event { }; extern int msm_vidc_debug; -extern int msm_vidc_debug_out; -extern int msm_vidc_fw_debug; extern int msm_vidc_fw_debug_mode; extern bool msm_vidc_fw_coverage; extern bool msm_vidc_thermal_mitigation_disabled; @@ -66,9 +71,19 @@ extern bool msm_vidc_cvp_usage; #define dprintk(__level, __fmt, ...) \ do { \ if (msm_vidc_debug & __level) { \ - if (msm_vidc_debug_out == VIDC_OUT_PRINTK) { \ + if (msm_vidc_debug & VIDC_FTRACE) { \ + char trace_logbuf[MAX_TRACER_LOG_LENGTH]; \ + int log_length = snprintf(trace_logbuf, \ + MAX_TRACER_LOG_LENGTH, \ + VIDC_DBG_TAG __fmt, \ + get_debug_level_str(__level), \ + ##__VA_ARGS__); \ + trace_msm_vidc_printf(trace_logbuf, \ + log_length); \ + } \ + if (msm_vidc_debug & VIDC_PRINTK) { \ pr_info(VIDC_DBG_TAG __fmt, \ - get_debug_level_str(__level), \ + get_debug_level_str(__level), \ ##__VA_ARGS__); \ } \ } \ @@ -76,13 +91,8 @@ extern bool msm_vidc_cvp_usage; #define dprintk_ratelimit(__level, __fmt, arg...) \ do { \ - if (msm_vidc_debug & __level) { \ - if (msm_vidc_debug_out == VIDC_OUT_PRINTK && \ - msm_vidc_check_ratelimit()) { \ - pr_info(VIDC_DBG_TAG __fmt, \ - get_debug_level_str(__level), \ - ## arg); \ - } \ + if (msm_vidc_check_ratelimit()) { \ + dprintk(__level, __fmt, arg); \ } \ } while (0) @@ -118,8 +128,6 @@ static inline char *get_debug_level_str(int level) return "prof"; case VIDC_PKT: return "pkt"; - case VIDC_FW: - return "fw"; default: return "???"; } From 8400f650f8ac77d7d011930de45708f49322c04f Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Wed, 15 May 2019 11:57:01 -0700 Subject: [PATCH 026/452] msm: vidc: New hfi macro for hdr10 histogram extradata HDR10 histogram extradata is applicable only for decode. Hence reclassifying the macro value. CRs-Fixed: 2453471 Change-Id: I0e3784ca4b2646838ab5a002c3263a66a1c60204 Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vdec.c | 2 +- msm/vidc/vidc_hfi.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index b2b35cc202ac..cc6dc12d9617 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -1366,7 +1366,7 @@ int msm_vdec_set_extradata(struct msm_vidc_inst *inst) if (codec == V4L2_PIX_FMT_VP9 || codec == V4L2_PIX_FMT_HEVC) { msm_comm_set_extradata(inst, - HFI_PROPERTY_PARAM_HDR10_HIST_EXTRADATA, 0x1); + HFI_PROPERTY_PARAM_VDEC_HDR10_HIST_EXTRADATA, 0x1); } msm_comm_set_extradata(inst, diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index 11b39cfb3430..8ae61b3dd638 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -186,8 +186,8 @@ struct hfi_extradata_header { (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x0021) #define HFI_PROPERTY_PARAM_VDEC_UBWC_CR_STAT_INFO_EXTRADATA \ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x0022) -#define HFI_PROPERTY_PARAM_HDR10_HIST_EXTRADATA \ - (HFI_PROPERTY_PARAM_OX_START + 0x0023) +#define HFI_PROPERTY_PARAM_VDEC_HDR10_HIST_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x0023) #define HFI_PROPERTY_CONFIG_VDEC_OX_START \ (HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x4000) From 52ed35827a06caaed366ba7b789f138310d960b4 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Thu, 16 May 2019 22:01:45 +0530 Subject: [PATCH 027/452] msm-vidc: decide num of extradata planes based on chipset Have a chipset specific check to decide the default value of num of extradata planes. Make num of planes as 2 if extradata is enabled. Change-Id: Ie61cac744b4277c024f36bebe795bea2eeced6ae Signed-off-by: Dikshita Agarwal --- msm/vidc/msm_venc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 48991d3d4128..595b714c784f 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1074,7 +1074,10 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) f->fmt.pix_mp.height = DEFAULT_HEIGHT; f->fmt.pix_mp.width = DEFAULT_WIDTH; f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12_UBWC; - f->fmt.pix_mp.num_planes = 2; + if(inst->core->platform_data->vpu_ver == VPU_VERSION_IRIS1) + f->fmt.pix_mp.num_planes = 1; + else + f->fmt.pix_mp.num_planes = 2; f->fmt.pix_mp.plane_fmt[0].sizeimage = msm_vidc_calculate_enc_input_frame_size(inst); f->fmt.pix_mp.plane_fmt[1].sizeimage = @@ -1589,6 +1592,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if ((inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_ROI) || (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_HDR10PLUS)) { f = &inst->fmts[INPUT_PORT].v4l2_fmt; + f->fmt.pix_mp.num_planes = 2; f->fmt.pix_mp.plane_fmt[1].sizeimage = msm_vidc_calculate_enc_input_extra_size(inst); } From 74650362eb46b7d932eae7d11c367d70893df606 Mon Sep 17 00:00:00 2001 From: Shivendra Kakrania Date: Wed, 22 May 2019 11:55:12 -0700 Subject: [PATCH 028/452] msm: vidc: Updating H264 decoder internal buffer size calculation For H264 decoder, resolutions with non-multiple of 16 were calculating less internal buffer size. Updated calculation to handle such scenarios. Change-Id: I3c07b843cc898a584aba4c9f26627898a7427fe8 Signed-off-by: Shivendra Kakrania --- msm/vidc/msm_vidc_buffer_calculations.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 116df605866b..da6fc6dba86c 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -110,7 +110,7 @@ ((((width + 15) >> 4) << 7)) #define SIZE_H264D_LB_RECON_DMA_METADATA_WR(width, height) \ - (ALIGN(height, 8) * 32) + (ALIGN(height, 16) * 32) #define SIZE_H264D_QP(width, height) \ (((width + 63) >> 6) * ((height + 63) >> 6) * 128) From 71ce4cbe76c622545ef41d82a38a3e549aa69d7a Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Thu, 9 May 2019 15:08:51 -0700 Subject: [PATCH 029/452] msm: vidc: reject sessions based on max mbpf Driver need not support sessions if cumulative mbpf (macroblocks per frame) is more than platform specified value. So reject such sessions. Change-Id: Id12eedfb97783b746c771066d6a556692be84c9f Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_vidc_common.c | 48 +++++++++++++++++++++++++++++++++-- msm/vidc/msm_vidc_platform.c | 4 +++ msm/vidc/msm_vidc_res_parse.c | 3 +++ msm/vidc/msm_vidc_resources.h | 1 + 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 24f04f5d0fb4..0b161029896c 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5261,7 +5261,47 @@ void msm_vidc_ssr_handler(struct work_struct *work) mutex_unlock(&core->lock); } -static int msm_vidc_load_supported(struct msm_vidc_inst *inst) +static int msm_vidc_check_mbpf_supported(struct msm_vidc_inst *inst) +{ + u32 mbpf = 0; + struct msm_vidc_core *core; + struct msm_vidc_inst *temp; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + core = inst->core; + + if (!core->resources.max_mbpf) { + dprintk(VIDC_DBG, "%s: max mbpf not available\n", + __func__); + return 0; + } + + mutex_lock(&core->lock); + list_for_each_entry(temp, &core->instances, list) { + /* ignore invalid session */ + if (temp->state == MSM_VIDC_CORE_INVALID) + continue; + /* ignore thumbnail session */ + if (is_thumbnail_session(temp)) + continue; + mbpf += NUM_MBS_PER_FRAME( + temp->fmts[INPUT_PORT].v4l2_fmt.fmt.pix_mp.height, + temp->fmts[INPUT_PORT].v4l2_fmt.fmt.pix_mp.width); + } + mutex_unlock(&core->lock); + + if (mbpf > core->resources.max_mbpf) { + msm_vidc_print_running_insts(inst->core); + return -EBUSY; + } + + return 0; +} + +static int msm_vidc_check_mbps_supported(struct msm_vidc_inst *inst) { int num_mbs_per_sec = 0, max_load_adj = 0; enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD | @@ -5389,13 +5429,17 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) capability = &inst->capability; hdev = inst->core->device; core = inst->core; - rc = msm_vidc_load_supported(inst); + rc = msm_vidc_check_mbps_supported(inst); if (rc) { dprintk(VIDC_WARN, "%s: Hardware is overloaded\n", __func__); return rc; } + rc = msm_vidc_check_mbpf_supported(inst); + if (rc) + return rc; + if (!is_thermal_permissible(core)) { dprintk(VIDC_WARN, "Thermal level critical, stop all active sessions!\n"); diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index ca454c39bc88..97a734ad5391 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -532,6 +532,10 @@ static struct msm_vidc_common_data kona_common_data[] = { * 8192x4320@48fps */ }, + { + .key = "qcom,max-mbpf", + .value = 138240, /* (8192x4320)/256 */ + }, { .key = "qcom,max-hq-mbs-per-frame", .value = 34560, /* 4096x2160 */ diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index b1e46a5db018..816a8a4eac14 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -777,6 +777,9 @@ int read_platform_resources_from_drv_data( res->max_load = find_key_value(platform_data, "qcom,max-hw-load"); + res->max_mbpf = find_key_value(platform_data, + "qcom,max-mbpf"); + res->max_hq_mbs_per_frame = find_key_value(platform_data, "qcom,max-hq-mbs-per-frame"); diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 59847ea39a6b..90d4d03d7df2 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -166,6 +166,7 @@ struct msm_vidc_platform_resources { struct addr_set qdss_addr_set; struct buffer_usage_set buffer_usage_set; uint32_t max_load; + uint32_t max_mbpf; uint32_t max_hq_mbs_per_frame; uint32_t max_hq_mbs_per_sec; uint32_t max_bframe_mbs_per_frame; From cc5f9c54092189af460883eef0579b3ed58879bc Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Wed, 22 May 2019 11:24:16 +0800 Subject: [PATCH 030/452] msm: vidc: fix f/w logging route Fix to independently control f/w logging route. Change-Id: I81b57995cb9619d2dee9c43547e86cc3f08d3778 Signed-off-by: Shi Zhongbo --- msm/vidc/hfi_common.c | 6 +++--- msm/vidc/msm_vidc_debug.h | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index f3c6c71b37d3..3763385fcffa 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -3239,7 +3239,7 @@ static void __process_sys_error(struct venus_hfi_device *device) static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) { bool local_packet = false; - enum vidc_msg_prio log_level = msm_vidc_debug; + enum vidc_msg_prio log_level = msm_vidc_debug & FW_LOGMASK; if (!device) { dprintk(VIDC_ERR, "%s: Invalid params\n", __func__); @@ -3260,7 +3260,7 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) * Local packek is used when error occurred. * It is good to print these logs to printk as well. */ - log_level |= VIDC_PRINTK; + log_level |= FW_PRINTK; } while (!__iface_dbgq_read(device, packet)) { @@ -3286,7 +3286,7 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) * from the message fixes this to print it in a single * line. */ - dprintk(log_level, "%s", &pkt->rg_msg_data[1]); + dprintk_firmware(log_level, "%s", &pkt->rg_msg_data[1]); } } diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index f34978288c23..181683965fbb 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -89,6 +89,27 @@ extern bool msm_vidc_cvp_usage; } \ } while (0) +#define dprintk_firmware(__level, __fmt, ...) \ + do { \ + if (msm_vidc_debug & __level) { \ + if (msm_vidc_debug & FW_FTRACE) { \ + char trace_logbuf[MAX_TRACER_LOG_LENGTH]; \ + int log_length = snprintf(trace_logbuf, \ + MAX_TRACER_LOG_LENGTH, \ + VIDC_DBG_TAG __fmt, \ + get_debug_level_str(__level), \ + ##__VA_ARGS__); \ + trace_msm_vidc_printf(trace_logbuf, \ + log_length); \ + } \ + if (msm_vidc_debug & FW_PRINTK) { \ + pr_info(VIDC_DBG_TAG __fmt, \ + get_debug_level_str(__level), \ + ##__VA_ARGS__); \ + } \ + } \ + } while (0) + #define dprintk_ratelimit(__level, __fmt, arg...) \ do { \ if (msm_vidc_check_ratelimit()) { \ From 60c3671f50257daa0787266aa80ee31a3c73caee Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Thu, 23 May 2019 14:55:14 -0700 Subject: [PATCH 031/452] msm: vidc: do not enable CVP usage for secure session CVP usage is not supported for secure session so do not enable CVP usage for secure session. Change-Id: Ifed6daaf706895ebbc56b246134d9775787c7b9d Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_vidc.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 7787157e090a..7c98269cf103 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -721,7 +721,8 @@ bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst) * - rate control is not one of below modes * - RATE_CONTROL_OFF * - V4L2_MPEG_VIDEO_BITRATE_MODE_CQ - * - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_PLUS + * - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR + * - not secure session */ cvp_disable = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE); @@ -729,15 +730,17 @@ bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst) !(inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) && inst->rc_type != RATE_CONTROL_OFF && inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ && - !inst->clk_data.is_legacy_cbr) { + !inst->clk_data.is_legacy_cbr && + !is_secure_session(inst)) { dprintk(VIDC_DBG, "%s: cvp allowed\n", __func__); allowed = true; } else { dprintk(VIDC_DBG, - "%s: cvp not allowed, cvp_external %d cvp_disable %d extradata %#x rc_type %d\n", + "%s: cvp not allowed, cvp_external %d cvp_disable %d extradata %#x rc_type %d legacy_cbr %d secure %d\n", __func__, core->resources.cvp_external, cvp_disable->val, inst->prop.extradata_ctrls, - inst->rc_type); + inst->rc_type, inst->clk_data.is_legacy_cbr, + is_secure_session(inst)); allowed = false; } exit: From 05d88704e824c5f8ec21937cd4b5e380a4c213fe Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 24 May 2019 16:26:09 +0530 Subject: [PATCH 032/452] msm: vidc: update video dimensions during port reconfiguration During a decode session, video output port can go through reconfiguration. As a result, update the reconfig dimension when client calls for g_fmt on output port. Change-Id: Ib5f5866acbdfe107ba4693b8b94498d42f74b312 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vdec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index cc6dc12d9617..cfe5f13784ce 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -662,6 +662,10 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) if (f->type == OUTPUT_MPLANE) { fmt = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + if (inst->in_reconfig) { + fmt->fmt.pix_mp.width = inst->reconfig_width; + fmt->fmt.pix_mp.height = inst->reconfig_height; + } fmt->fmt.pix_mp.plane_fmt[0].sizeimage = msm_vidc_calculate_dec_output_frame_size(inst); if (fmt->fmt.pix_mp.num_planes > 1) @@ -670,10 +674,6 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) memcpy(f, fmt, sizeof(struct v4l2_format)); } else if (f->type == INPUT_MPLANE) { fmt = &inst->fmts[INPUT_PORT].v4l2_fmt; - if (inst->in_reconfig) { - fmt->fmt.pix_mp.width = inst->reconfig_width; - fmt->fmt.pix_mp.height = inst->reconfig_height; - } fmt->fmt.pix_mp.plane_fmt[0].sizeimage = msm_vidc_calculate_dec_input_frame_size(inst); memcpy(f, fmt, sizeof(struct v4l2_format)); From d783a8038b476d6550fbf9f2b1ce57c1b2687e40 Mon Sep 17 00:00:00 2001 From: Shivendra Kakrania Date: Fri, 24 May 2019 22:12:37 -0700 Subject: [PATCH 033/452] msm: vidc: Revert of 2735098 Reverting 2735098 "update video dimensions during port reconfiguration". Change-Id: I2343cf77d23a564c3346d71dae9cd6377ae9d4e2 Signed-off-by: Shivendra Kakrania --- msm/vidc/msm_vdec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index cfe5f13784ce..cc6dc12d9617 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -662,10 +662,6 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) if (f->type == OUTPUT_MPLANE) { fmt = &inst->fmts[OUTPUT_PORT].v4l2_fmt; - if (inst->in_reconfig) { - fmt->fmt.pix_mp.width = inst->reconfig_width; - fmt->fmt.pix_mp.height = inst->reconfig_height; - } fmt->fmt.pix_mp.plane_fmt[0].sizeimage = msm_vidc_calculate_dec_output_frame_size(inst); if (fmt->fmt.pix_mp.num_planes > 1) @@ -674,6 +670,10 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) memcpy(f, fmt, sizeof(struct v4l2_format)); } else if (f->type == INPUT_MPLANE) { fmt = &inst->fmts[INPUT_PORT].v4l2_fmt; + if (inst->in_reconfig) { + fmt->fmt.pix_mp.width = inst->reconfig_width; + fmt->fmt.pix_mp.height = inst->reconfig_height; + } fmt->fmt.pix_mp.plane_fmt[0].sizeimage = msm_vidc_calculate_dec_input_frame_size(inst); memcpy(f, fmt, sizeof(struct v4l2_format)); From 967b2f6bcb6949b44ef41cb8872bd8c7bb277573 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Mon, 20 May 2019 19:59:38 +0530 Subject: [PATCH 034/452] msm: vidc: Decide DCVS after session configuration DCVS feature depends on multiple client configurations. Low latency, thumbnail mode, etc are few among them. DCVS is now decided before the session starts streaming i.e after all configuration are inplace. CRs-Fixed: 2457035 Change-Id: I4a42ae6bafdc852e81794b69d117f5821af4841f Signed-off-by: Vikash Garodia Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vdec.c | 1 - msm/vidc/msm_vidc.c | 3 ++- msm/vidc/msm_vidc_clocks.c | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index cc6dc12d9617..e4ef88c73457 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -848,7 +848,6 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (ctrl->val) inst->flags |= VIDC_THUMBNAIL; - msm_dcvs_try_enable(inst); rc = msm_vidc_set_buffer_count_for_thumbnail(inst); if (rc) { dprintk(VIDC_ERR, "Failed to set buffer count\n"); diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 7c98269cf103..28080d6d30c7 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -918,6 +918,8 @@ static inline int start_streaming(struct msm_vidc_inst *inst) __func__, inst->batch.enable ? "enabled" : "disabled", inst, hash32_ptr(inst->session)); + msm_dcvs_try_enable(inst); + /* * For seq_changed_insufficient, driver should set session_continue * to firmware after the following sequence @@ -1570,7 +1572,6 @@ void *msm_vidc_open(int core_id, int session_type) goto fail_init; } - msm_dcvs_try_enable(inst); if (msm_comm_check_for_inst_overload(core)) { dprintk(VIDC_ERR, "Instance count reached Max limit, rejecting session"); diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index a1905a13246b..0ce353c33547 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1030,15 +1030,18 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst) int msm_dcvs_try_enable(struct msm_vidc_inst *inst) { - if (!inst) { + if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s: Invalid args: %p\n", __func__, inst); return -EINVAL; } if (msm_vidc_clock_voting || + !inst->core->resources.dcvs || inst->flags & VIDC_THUMBNAIL || inst->clk_data.low_latency_mode || - inst->batch.enable) { + inst->batch.enable || + inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ || + inst->grid_enable) { dprintk(VIDC_PROF, "DCVS disabled: %pK\n", inst); inst->clk_data.dcvs_mode = false; return false; From 31bb5f19a06fa1b66adb233cec5929169cd11245 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 21 May 2019 15:08:13 -0700 Subject: [PATCH 035/452] msm: vidc: Disable batching for concurrent usecase Disable decode batching for concurrent decode session. CRs-Fixed: 2457122 Change-Id: I776e9d057ae0f1a9dc0fd565b061ae48b88435e1 Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vdec.c | 20 +++++++++++++++++++- msm/vidc/msm_vidc_buffer_calculations.c | 4 ++-- msm/vidc/msm_vidc_common.c | 2 +- msm/vidc/msm_vidc_internal.h | 1 + 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index e4ef88c73457..d95626e3ba64 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -776,8 +776,26 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) inst->clk_data.frame_rate = (DEFAULT_FPS << 16); inst->clk_data.operating_rate = (DEFAULT_FPS << 16); - if (core->resources.decode_batching) + if (core->resources.decode_batching) { + struct msm_vidc_inst *temp; + inst->batch.size = MAX_DEC_BATCH_SIZE; + inst->decode_batching = true; + + mutex_lock(&core->lock); + list_for_each_entry(temp, &core->instances, list) { + if (temp != inst && + temp->state != MSM_VIDC_CORE_INVALID && + is_decode_session(temp) && + !is_thumbnail_session(temp)) { + inst->decode_batching = false; + dprintk(VIDC_DBG, + "Disable decode-batching in multi sessions\n"); + break; + } + } + mutex_unlock(&core->lock); + } inst->buff_req.buffer[1].buffer_type = HAL_BUFFER_INPUT; inst->buff_req.buffer[1].buffer_count_min_host = diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index da6fc6dba86c..c000118ef4e2 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -610,7 +610,7 @@ int msm_vidc_init_buffer_count(struct msm_vidc_inst *inst) HAL_BUFFER_INPUT); fmt->count_min = input_min_count; /* batching needs minimum batch size count of input buffers */ - if (inst->core->resources.decode_batching && + if (inst->decode_batching && is_decode_session(inst) && fmt->count_min < inst->batch.size) fmt->count_min = inst->batch.size; @@ -711,7 +711,7 @@ int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, * batch size count of extra buffers added on output port */ if (buffer_type == HAL_BUFFER_OUTPUT) { - if (inst->core->resources.decode_batching && + if (inst->decode_batching && is_decode_session(inst) && count < inst->batch.size) count = inst->batch.size; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 0b161029896c..39e445312fa6 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2787,7 +2787,7 @@ bool is_batching_allowed(struct msm_vidc_inst *inst) maxmbs = inst->capability.cap[CAP_BATCH_MAX_MB_PER_FRAME].max; maxfps = inst->capability.cap[CAP_BATCH_MAX_FPS].max; - return (inst->core->resources.decode_batching && + return (inst->decode_batching && is_decode_session(inst) && !is_thumbnail_session(inst) && !inst->clk_data.low_latency_mode && diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 0dd5b8fe1f70..98707751c6d6 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -514,6 +514,7 @@ struct msm_vidc_inst { struct msm_vidc_codec_data *codec_data; struct hal_hdr10_pq_sei hdr10_sei_params; struct batch_mode batch; + bool decode_batching; struct msm_vidc_inst_smem_ops *smem_ops; int (*buffer_size_calculators)(struct msm_vidc_inst *inst); }; From 2f4c502bab571c8bbda09ff50b37505301d379b6 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Mon, 20 May 2019 17:21:49 +0800 Subject: [PATCH 036/452] msm: vidc: revise debug levels Clean up debug log levels as: 1. Revise VIDC_WARN to VIDC_ERR; 2. Revise VIDC_PROF as VIDC_PERF; 3. Mark some one-time logs, e.g most of logs in initialization and deinitialization as VIDC_HIGH; 4. Keep VIDC_PKT; 5. All other logs change to VIDC_LOW; Change-Id: I8fc30f97dc3424da8418aab00e8af074ec8d4ef9 Signed-off-by: Shi Zhongbo --- msm/vidc/hfi_common.c | 276 ++++++++++--------- msm/vidc/hfi_iris2.c | 20 +- msm/vidc/hfi_packetization.c | 16 +- msm/vidc/hfi_response_handler.c | 80 +++--- msm/vidc/msm_cvp_external.c | 56 ++-- msm/vidc/msm_cvp_internal.c | 16 +- msm/vidc/msm_smem.c | 16 +- msm/vidc/msm_v4l2_vidc.c | 12 +- msm/vidc/msm_vdec.c | 26 +- msm/vidc/msm_venc.c | 146 +++++----- msm/vidc/msm_vidc.c | 64 ++--- msm/vidc/msm_vidc_buffer_calculations.c | 8 +- msm/vidc/msm_vidc_bus_iris1.c | 6 +- msm/vidc/msm_vidc_bus_iris2.c | 4 +- msm/vidc/msm_vidc_clocks.c | 100 +++---- msm/vidc/msm_vidc_common.c | 350 ++++++++++++------------ msm/vidc/msm_vidc_debug.c | 22 +- msm/vidc/msm_vidc_debug.h | 35 ++- msm/vidc/msm_vidc_platform.c | 4 +- msm/vidc/msm_vidc_res_parse.c | 80 +++--- 20 files changed, 666 insertions(+), 671 deletions(-) mode change 100644 => 100755 msm/vidc/msm_vidc.c mode change 100644 => 100755 msm/vidc/msm_vidc_clocks.c diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 3763385fcffa..cea5b001be71 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -215,7 +215,7 @@ static void __sim_modify_cmd_packet(u8 *packet, struct venus_hfi_device *device) session = __get_session(device, sys_init->session_id); if (!session) { - dprintk(VIDC_DBG, "%s :Invalid session id: %x\n", + dprintk(VIDC_ERR, "%s :Invalid session id: %x\n", __func__, sys_init->session_id); return; } @@ -309,11 +309,11 @@ static int __dsp_send_hfi_queue(struct venus_hfi_device *device) } if (device->dsp_flags & DSP_INIT) { - dprintk(VIDC_DBG, "%s: dsp already inited\n", __func__); + dprintk(VIDC_HIGH, "%s: dsp already inited\n", __func__); return 0; } - dprintk(VIDC_DBG, "%s: hfi queue %#llx size %d\n", + dprintk(VIDC_HIGH, "%s: hfi queue %#llx size %d\n", __func__, device->dsp_iface_q_table.mem_data.dma_handle, device->dsp_iface_q_table.mem_data.size); rc = fastcvpd_video_send_cmd_hfi_queue( @@ -325,7 +325,7 @@ static int __dsp_send_hfi_queue(struct venus_hfi_device *device) } device->dsp_flags |= DSP_INIT; - dprintk(VIDC_DBG, "%s: dsp inited\n", __func__); + dprintk(VIDC_HIGH, "%s: dsp inited\n", __func__); return rc; } @@ -350,7 +350,7 @@ static int __dsp_suspend(struct venus_hfi_device *device, bool force, u32 flags) if (temp->domain == HAL_VIDEO_DOMAIN_CVP) { /* don't suspend if cvp session is not paused */ if (!(temp->flags & SESSION_PAUSE)) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: cvp session %x not paused\n", __func__, hash32_ptr(temp)); return -EBUSY; @@ -358,7 +358,7 @@ static int __dsp_suspend(struct venus_hfi_device *device, bool force, u32 flags) } } - dprintk(VIDC_DBG, "%s: suspend dsp\n", __func__); + dprintk(VIDC_HIGH, "%s: suspend dsp\n", __func__); rc = fastcvpd_video_suspend(flags); if (rc) { dprintk(VIDC_ERR, "%s: dsp suspend failed with error %d\n", @@ -367,7 +367,7 @@ static int __dsp_suspend(struct venus_hfi_device *device, bool force, u32 flags) } device->dsp_flags |= DSP_SUSPEND; - dprintk(VIDC_DBG, "%s: dsp suspended\n", __func__); + dprintk(VIDC_HIGH, "%s: dsp suspended\n", __func__); return 0; } @@ -379,11 +379,11 @@ static int __dsp_resume(struct venus_hfi_device *device, u32 flags) return 0; if (!(device->dsp_flags & DSP_SUSPEND)) { - dprintk(VIDC_DBG, "%s: dsp not suspended\n", __func__); + dprintk(VIDC_HIGH, "%s: dsp not suspended\n", __func__); return 0; } - dprintk(VIDC_DBG, "%s: resume dsp\n", __func__); + dprintk(VIDC_HIGH, "%s: resume dsp\n", __func__); rc = fastcvpd_video_resume(flags); if (rc) { dprintk(VIDC_ERR, @@ -393,7 +393,7 @@ static int __dsp_resume(struct venus_hfi_device *device, u32 flags) } device->dsp_flags &= ~DSP_SUSPEND; - dprintk(VIDC_DBG, "%s: dsp resumed\n", __func__); + dprintk(VIDC_HIGH, "%s: dsp resumed\n", __func__); return rc; } @@ -405,11 +405,11 @@ static int __dsp_shutdown(struct venus_hfi_device *device, u32 flags) return 0; if (!(device->dsp_flags & DSP_INIT)) { - dprintk(VIDC_DBG, "%s: dsp not inited\n", __func__); + dprintk(VIDC_HIGH, "%s: dsp not inited\n", __func__); return 0; } - dprintk(VIDC_DBG, "%s: shutdown dsp\n", __func__); + dprintk(VIDC_HIGH, "%s: shutdown dsp\n", __func__); rc = fastcvpd_video_shutdown(flags); if (rc) { dprintk(VIDC_ERR, @@ -419,7 +419,7 @@ static int __dsp_shutdown(struct venus_hfi_device *device, u32 flags) } device->dsp_flags &= ~DSP_INIT; - dprintk(VIDC_DBG, "%s: dsp shutdown successful\n", __func__); + dprintk(VIDC_HIGH, "%s: dsp shutdown successful\n", __func__); return rc; } @@ -433,7 +433,7 @@ static int __session_pause(struct venus_hfi_device *device, return 0; session->flags |= SESSION_PAUSE; - dprintk(VIDC_DBG, "%s: cvp session %x paused\n", __func__, + dprintk(VIDC_HIGH, "%s: cvp session %x paused\n", __func__, hash32_ptr(session)); return rc; @@ -449,7 +449,7 @@ static int __session_resume(struct venus_hfi_device *device, return 0; session->flags &= ~SESSION_PAUSE; - dprintk(VIDC_DBG, "%s: cvp session %x resumed\n", __func__, + dprintk(VIDC_HIGH, "%s: cvp session %x resumed\n", __func__, hash32_ptr(session)); rc = __resume(device); @@ -520,12 +520,12 @@ static int __acquire_regulator(struct regulator_info *rinfo, * about it. We can't disable the regulator w/o * getting it back under s/w control */ - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Failed to acquire regulator control: %s\n", rinfo->name); } else { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Acquire regulator control from HW: %s\n", rinfo->name); @@ -533,7 +533,7 @@ static int __acquire_regulator(struct regulator_info *rinfo, } if (!regulator_is_enabled(rinfo->regulator)) { - dprintk(VIDC_WARN, "Regulator is not enabled %s\n", + dprintk(VIDC_ERR, "Regulator is not enabled %s\n", rinfo->name); msm_vidc_res_handle_fatal_hw_error(device->res, true); } @@ -549,11 +549,11 @@ static int __hand_off_regulator(struct regulator_info *rinfo) rc = regulator_set_mode(rinfo->regulator, REGULATOR_MODE_FAST); if (rc) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Failed to hand off regulator control: %s\n", rinfo->name); } else { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Hand off regulator control to HW: %s\n", rinfo->name); } @@ -598,7 +598,7 @@ static int __write_queue(struct vidc_iface_q_info *qinfo, u8 *packet, dprintk(VIDC_ERR, "Invalid Params\n"); return -EINVAL; } else if (!qinfo->q_array.align_virtual_addr) { - dprintk(VIDC_WARN, "Queues have already been freed\n"); + dprintk(VIDC_ERR, "Queues have already been freed\n"); return -EINVAL; } @@ -692,7 +692,7 @@ static void __hal_sim_modify_msg_packet(u8 *packet, session = __get_session(device, init_done->session_id); if (!session) { - dprintk(VIDC_DBG, "%s: Invalid session id: %x\n", + dprintk(VIDC_ERR, "%s: Invalid session id: %x\n", __func__, init_done->session_id); return; } @@ -741,7 +741,7 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, dprintk(VIDC_ERR, "Invalid Params\n"); return -EINVAL; } else if (!qinfo->q_array.align_virtual_addr) { - dprintk(VIDC_WARN, "Queues have already been freed\n"); + dprintk(VIDC_ERR, "Queues have already been freed\n"); return -EINVAL; } @@ -779,7 +779,7 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, */ mb(); *pb_tx_req_is_set = 0; - dprintk(VIDC_DBG, + dprintk(VIDC_LOW, "%s queue is empty, rx_req = %u, tx_req = %u, read_idx = %u\n", receive_request ? "message" : "debug", queue->qhdr_rx_req, queue->qhdr_tx_req, @@ -818,10 +818,10 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, new_read_idx << 2); } } else { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "BAD packet received, read_idx: %#x, pkt_size: %d\n", read_idx, packet_size_in_words << 2); - dprintk(VIDC_WARN, "Dropping this packet\n"); + dprintk(VIDC_ERR, "Dropping this packet\n"); new_read_idx = write_idx; rc = -ENODATA; } @@ -861,7 +861,7 @@ static int __smem_alloc(struct venus_hfi_device *dev, return -EINVAL; } - dprintk(VIDC_INFO, "start to alloc size: %d, flags: %d\n", size, flags); + dprintk(VIDC_HIGH, "start to alloc size: %d, flags: %d\n", size, flags); rc = msm_smem_alloc( size, align, flags, usage, 1, (void *)dev->res, MSM_VIDC_UNKNOWN, alloc); @@ -871,7 +871,7 @@ static int __smem_alloc(struct venus_hfi_device *dev, goto fail_smem_alloc; } - dprintk(VIDC_DBG, "%s: ptr = %pK, size = %d\n", __func__, + dprintk(VIDC_HIGH, "%s: ptr = %pK, size = %d\n", __func__, alloc->kvaddr, size); mem->mem_size = alloc->size; @@ -907,14 +907,14 @@ void __write_register(struct venus_hfi_device *device, __strict_check(device); if (!device->power_enabled) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "HFI Write register failed : Power is OFF\n"); msm_vidc_res_handle_fatal_hw_error(device->res, true); return; } base_addr = device->hal_data->register_base; - dprintk(VIDC_DBG, "Base addr: %pK, writing to: %#x, Value: %#x...\n", + dprintk(VIDC_LOW, "Base addr: %pK, writing to: %#x, Value: %#x...\n", base_addr, hwiosymaddr, value); base_addr += hwiosymaddr; writel_relaxed(value, base_addr); @@ -938,7 +938,7 @@ int __read_register(struct venus_hfi_device *device, u32 reg) __strict_check(device); if (!device->power_enabled) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "HFI Read register failed : Power is OFF\n"); msm_vidc_res_handle_fatal_hw_error(device->res, true); return -EINVAL; @@ -952,7 +952,7 @@ int __read_register(struct venus_hfi_device *device, u32 reg) * register. */ rmb(); - dprintk(VIDC_DBG, "Base addr: %pK, read from: %#x, value: %#x...\n", + dprintk(VIDC_LOW, "Base addr: %pK, read from: %#x, value: %#x...\n", base_addr, reg, rc); return rc; @@ -983,7 +983,7 @@ static int __vote_bandwidth(struct bus_info *bus, unsigned long freq) /* Bus Driver expects values in Bps */ ab = freq * 1000; - dprintk(VIDC_PROF, "Voting bus %s to ab %llu\n", bus->name, ab); + dprintk(VIDC_PERF, "Voting bus %s to ab %llu\n", bus->name, ab); rc = msm_bus_scale_update_bw(bus->client, ab, 0); if (rc) dprintk(VIDC_ERR, "Failed voting bus %s to ab %llu, rc=%d\n", @@ -1020,7 +1020,7 @@ static int __vote_buses(struct venus_hfi_device *device, unsigned long freq = 0; if (!num_data) { - dprintk(VIDC_DBG, "No vote data available\n"); + dprintk(VIDC_LOW, "No vote data available\n"); goto no_data_count; } else if (!data) { dprintk(VIDC_ERR, "Invalid voting data\n"); @@ -1155,7 +1155,7 @@ static int __tzbsp_set_video_state(enum tzbsp_video_state state) return rc; } - dprintk(VIDC_DBG, "Set state %d, resp %d\n", state, tzbsp_rsp); + dprintk(VIDC_LOW, "Set state %d, resp %d\n", state, tzbsp_rsp); if (tzbsp_rsp) { dprintk(VIDC_ERR, "Failed to set video core state to suspend: %d\n", @@ -1207,11 +1207,11 @@ static int venus_hfi_suspend(void *dev) return -ENOTSUPP; } - dprintk(VIDC_DBG, "Suspending Venus\n"); + dprintk(VIDC_HIGH, "Suspending Venus\n"); mutex_lock(&device->lock); rc = __power_collapse(device, true); if (rc) { - dprintk(VIDC_WARN, "%s: Venus is busy\n", __func__); + dprintk(VIDC_ERR, "%s: Venus is busy\n", __func__); rc = -EBUSY; } mutex_unlock(&device->lock); @@ -1236,7 +1236,7 @@ static int venus_hfi_flush_debug_queue(void *dev) mutex_lock(&device->lock); if (!device->power_enabled) { - dprintk(VIDC_WARN, "%s: venus power off\n", __func__); + dprintk(VIDC_ERR, "%s: venus power off\n", __func__); rc = -EINVAL; goto exit; } @@ -1279,7 +1279,7 @@ static int __set_clk_rate(struct venus_hfi_device *device, "%s: cx_ipeak_update failed!\n", __func__); return rc; } - dprintk(VIDC_PROF, + dprintk(VIDC_PERF, "cx_ipeak_update: up, clk freq = %lu rate = %lu threshold_freq = %lu\n", device->clk_freq, rate, threshold_freq); } @@ -1301,7 +1301,7 @@ static int __set_clk_rate(struct venus_hfi_device *device, "cx_ipeak_update failed! ipeak %pK\n", ipeak); return rc; } - dprintk(VIDC_PROF, + dprintk(VIDC_PERF, "cx_ipeak_update: up, clk freq = %lu rate = %lu threshold_freq = %lu\n", device->clk_freq, rate, threshold_freq); } @@ -1321,7 +1321,7 @@ static int __set_clocks(struct venus_hfi_device *device, u32 freq) return rc; trace_msm_vidc_perf_clock_scale(cl->name, freq); - dprintk(VIDC_PROF, "Scaling clock %s to %u\n", + dprintk(VIDC_PERF, "Scaling clock %s to %u\n", cl->name, freq); } } @@ -1361,8 +1361,6 @@ static int __scale_clocks(struct venus_hfi_device *device) u32 rate = 0; allowed_clks_tbl = device->res->allowed_clks_tbl; - - dprintk(VIDC_DBG, "%s: NULL scale data\n", __func__); rate = device->clk_freq ? device->clk_freq : allowed_clks_tbl[0].clock_rate; @@ -1419,7 +1417,7 @@ static int __iface_cmdq_write_relaxed(struct venus_hfi_device *device, &venus_hfi_pm_work, msecs_to_jiffies( device->res->msm_vidc_pwr_collapse_delay))) { - dprintk(VIDC_DBG, + dprintk(VIDC_LOW, "PM work already scheduled\n"); } } @@ -1465,7 +1463,7 @@ static int __iface_msgq_read(struct venus_hfi_device *device, void *pkt) __strict_check(device); if (!__core_in_valid_state(device)) { - dprintk(VIDC_DBG, "%s - fw not in init state\n", __func__); + dprintk(VIDC_ERR, "%s - fw not in init state\n", __func__); rc = -EINVAL; goto read_error_null; } @@ -1600,7 +1598,7 @@ static int __interface_dsp_queues_init(struct venus_hfi_device *dev) dprintk(VIDC_ERR, "%s: failed dma mapping\n", __func__); goto fail_dma_map; } - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: kvaddr %pK dma_handle %#llx iova %#llx size %zd\n", __func__, kvaddr, dma_handle, iova, q_size); @@ -1855,7 +1853,7 @@ static int __interface_queues_init(struct venus_hfi_device *dev) ALIGNED_QDSS_SIZE, 1, SMEM_UNCACHED, HAL_BUFFER_INTERNAL_CMD_QUEUE); if (rc) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "qdss_alloc_fail: QDSS messages logging will not work\n"); dev->qdss.align_device_addr = 0; } else { @@ -1872,7 +1870,7 @@ static int __interface_queues_init(struct venus_hfi_device *dev) ALIGNED_SFR_SIZE, 1, SMEM_UNCACHED, HAL_BUFFER_INTERNAL_CMD_QUEUE); if (rc) { - dprintk(VIDC_WARN, "sfr_alloc_fail: SFR not will work\n"); + dprintk(VIDC_ERR, "sfr_alloc_fail: SFR not will work\n"); dev->sfr.align_device_addr = 0; } else { dev->sfr.align_device_addr = mem_addr->align_device_addr - @@ -1965,7 +1963,7 @@ static int __sys_set_debug(struct venus_hfi_device *device, u32 debug) rc = call_hfi_pkt_op(device, sys_debug_config, pkt, debug); if (rc) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Debug mode setting to FW failed\n"); return -ENOTEMPTY; } @@ -1985,13 +1983,13 @@ static int __sys_set_coverage(struct venus_hfi_device *device, u32 mode) rc = call_hfi_pkt_op(device, sys_coverage_config, pkt, mode); if (rc) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Coverage mode setting to FW failed\n"); return -ENOTEMPTY; } if (__iface_cmdq_write(device, pkt)) { - dprintk(VIDC_WARN, "Failed to send coverage pkt to f/w\n"); + dprintk(VIDC_ERR, "Failed to send coverage pkt to f/w\n"); return -ENOTEMPTY; } @@ -2037,7 +2035,7 @@ static int venus_hfi_core_init(void *device) dev = device; - dprintk(VIDC_DBG, "Core initializing\n"); + dprintk(VIDC_HIGH, "Core initializing\n"); mutex_lock(&dev->lock); @@ -2060,7 +2058,7 @@ static int venus_hfi_core_init(void *device) __set_state(dev, VENUS_STATE_INIT); - dprintk(VIDC_DBG, "Dev_Virt: %pa, Reg_Virt: %pK\n", + dprintk(VIDC_HIGH, "Dev_Virt: %pa, Reg_Virt: %pK\n", &dev->hal_data->firmware_base, dev->hal_data->register_base); @@ -2092,7 +2090,7 @@ static int venus_hfi_core_init(void *device) rc = call_hfi_pkt_op(dev, sys_image_version, &version_pkt); if (rc || __iface_cmdq_write(dev, &version_pkt)) - dprintk(VIDC_WARN, "Failed to send image version pkt to f/w\n"); + dprintk(VIDC_ERR, "Failed to send image version pkt to f/w\n"); __sys_set_debug(device, (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT); @@ -2110,7 +2108,7 @@ static int venus_hfi_core_init(void *device) pm_qos_add_request(&dev->qos, PM_QOS_CPU_DMA_LATENCY, dev->res->pm_qos_latency_us); } - dprintk(VIDC_DBG, "Core inited successfully\n"); + dprintk(VIDC_HIGH, "Core inited successfully\n"); mutex_unlock(&dev->lock); return rc; err_core_init: @@ -2135,7 +2133,7 @@ static int venus_hfi_core_release(void *dev) } mutex_lock(&device->lock); - dprintk(VIDC_DBG, "Core releasing\n"); + dprintk(VIDC_HIGH, "Core releasing\n"); if (device->res->pm_qos_latency_us && pm_qos_request_active(&device->qos)) pm_qos_remove_request(&device->qos); @@ -2150,7 +2148,7 @@ static int venus_hfi_core_release(void *dev) list_for_each_entry_safe(session, next, &device->sess_head, list) list_del(&session->list); - dprintk(VIDC_DBG, "Core released successfully\n"); + dprintk(VIDC_HIGH, "Core released successfully\n"); mutex_unlock(&device->lock); return rc; @@ -2201,7 +2199,7 @@ static void __core_clear_interrupt_common(struct venus_hfi_device *device) if (intr_status & mask) { device->intr_status |= intr_status; device->reg_count++; - dprintk(VIDC_DBG, + dprintk(VIDC_LOW, "INTERRUPT for device: %pK: times: %d interrupt_status: %d\n", device, device->reg_count, intr_status); } else { @@ -2259,7 +2257,7 @@ static int venus_hfi_session_set_property(void *sess, device = session->device; mutex_lock(&device->lock); - dprintk(VIDC_INFO, "in set_prop,with prop id: %#x\n", ptype); + dprintk(VIDC_HIGH, "in set_prop,with prop id: %#x\n", ptype); if (!__is_session_valid(device, session, __func__)) { rc = -EINVAL; goto err_set_prop; @@ -2269,7 +2267,7 @@ static int venus_hfi_session_set_property(void *sess, pkt, session, ptype, pdata, size); if (rc == -ENOTSUPP) { - dprintk(VIDC_DBG, + dprintk(VIDC_ERR, "set property: unsupported prop id: %#x\n", ptype); rc = 0; goto err_set_prop; @@ -2293,9 +2291,9 @@ static void __set_default_sys_properties(struct venus_hfi_device *device) { if (__sys_set_debug(device, (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT)) - dprintk(VIDC_WARN, "Setting fw_debug msg ON failed\n"); + dprintk(VIDC_ERR, "Setting fw_debug msg ON failed\n"); if (__sys_set_power_control(device, true)) - dprintk(VIDC_WARN, "Setting h/w power collapse ON failed\n"); + dprintk(VIDC_ERR, "Setting h/w power collapse ON failed\n"); } static void __session_clean(struct hal_session *session) @@ -2304,11 +2302,11 @@ static void __session_clean(struct hal_session *session) struct venus_hfi_device *device; if (!session || !session->device) { - dprintk(VIDC_WARN, "%s: invalid params\n", __func__); + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return; } device = session->device; - dprintk(VIDC_DBG, "deleted the session: %pK\n", session); + dprintk(VIDC_HIGH, "deleted the session: %pK\n", session); /* * session might have been removed from the device list in * core_release, so check and remove if it is in the list @@ -2377,7 +2375,7 @@ static int venus_hfi_session_init(void *device, void *session_id, s->device = dev; s->codec = codec_type; s->domain = session_type; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: inst %pK, session %pK, codec 0x%x, domain 0x%x\n", __func__, session_id, s, s->codec, s->domain); @@ -2450,7 +2448,7 @@ static int venus_hfi_session_end(void *session) if (msm_vidc_fw_coverage) { if (__sys_set_coverage(sess->device, msm_vidc_fw_coverage)) - dprintk(VIDC_WARN, "Fw_coverage msg ON failed\n"); + dprintk(VIDC_ERR, "Fw_coverage msg ON failed\n"); } rc = __send_session_cmd(session, HFI_CMD_SYS_SESSION_END); @@ -2522,7 +2520,7 @@ static int venus_hfi_session_set_buffers(void *sess, goto err_create_pkt; } - dprintk(VIDC_INFO, "set buffers: %#x\n", buffer_info->buffer_type); + dprintk(VIDC_HIGH, "set buffers: %#x\n", buffer_info->buffer_type); if (__iface_cmdq_write(session->device, pkt)) rc = -ENOTEMPTY; @@ -2566,7 +2564,7 @@ static int venus_hfi_session_release_buffers(void *sess, goto err_create_pkt; } - dprintk(VIDC_INFO, "Release buffers: %#x\n", buffer_info->buffer_type); + dprintk(VIDC_HIGH, "Release buffers: %#x\n", buffer_info->buffer_type); if (__iface_cmdq_write(session->device, pkt)) rc = -ENOTEMPTY; @@ -2998,7 +2996,7 @@ static int __check_core_registered(struct hal_device_data core, struct list_head *curr, *next; if (!core.dev_count) { - dprintk(VIDC_INFO, "no device Registered\n"); + dprintk(VIDC_ERR, "no device Registered\n"); return -EINVAL; } @@ -3029,7 +3027,7 @@ static int __check_core_registered(struct hal_device_data core, return 0; } - dprintk(VIDC_INFO, "Device not registered\n"); + dprintk(VIDC_ERR, "Device not registered\n"); return -EINVAL; } return -EINVAL; @@ -3074,14 +3072,13 @@ static void venus_hfi_pm_handler(struct work_struct *work) return; } - dprintk(VIDC_PROF, - "Entering %s\n", __func__); + dprintk(VIDC_HIGH, "Entering %s\n", __func__); /* * It is ok to check this variable outside the lock since * it is being updated in this context only */ if (device->skip_pc_count >= VIDC_MAX_PC_SKIP_COUNT) { - dprintk(VIDC_WARN, "Failed to PC for %d times\n", + dprintk(VIDC_ERR, "Failed to PC for %d times\n", device->skip_pc_count); device->skip_pc_count = 0; __process_fatal_error(device); @@ -3096,19 +3093,19 @@ static void venus_hfi_pm_handler(struct work_struct *work) device->skip_pc_count = 0; /* Cancel pending delayed works if any */ cancel_delayed_work(&venus_hfi_pm_work); - dprintk(VIDC_PROF, "%s: power collapse successful!\n", + dprintk(VIDC_HIGH, "%s: power collapse successful!\n", __func__); break; case -EBUSY: device->skip_pc_count = 0; - dprintk(VIDC_DBG, "%s: retry PC as dsp is busy\n", __func__); + dprintk(VIDC_HIGH, "%s: retry PC as dsp is busy\n", __func__); queue_delayed_work(device->venus_pm_workq, &venus_hfi_pm_work, msecs_to_jiffies( device->res->msm_vidc_pwr_collapse_delay)); break; case -EAGAIN: device->skip_pc_count++; - dprintk(VIDC_WARN, "%s: retry power collapse (count %d)\n", + dprintk(VIDC_ERR, "%s: retry power collapse (count %d)\n", __func__, device->skip_pc_count); queue_delayed_work(device->venus_pm_workq, &venus_hfi_pm_work, msecs_to_jiffies( @@ -3133,20 +3130,20 @@ static int __prepare_pc_common(struct venus_hfi_device *device) idle_status = ctrl_status & BIT(30); if (pc_ready) { - dprintk(VIDC_DBG, "Already in pc_ready state\n"); + dprintk(VIDC_HIGH, "Already in pc_ready state\n"); return 0; } wfi_status = BIT(0) & __read_register(device, WRAPPER_CPU_STATUS); if (!wfi_status || !idle_status) { - dprintk(VIDC_WARN, "Skipping PC, wfi status not set\n"); + dprintk(VIDC_ERR, "Skipping PC, wfi status not set\n"); goto skip_power_off; } rc = __prepare_pc(device); if (rc) { - dprintk(VIDC_WARN, "Failed __prepare_pc %d\n", rc); + dprintk(VIDC_ERR, "Failed __prepare_pc %d\n", rc); goto skip_power_off; } @@ -3168,7 +3165,7 @@ static int __prepare_pc_common(struct venus_hfi_device *device) return rc; skip_power_off: - dprintk(VIDC_WARN, "Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n", + dprintk(VIDC_ERR, "Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n", wfi_status, idle_status, pc_ready, ctrl_status); return -EAGAIN; } @@ -3183,13 +3180,13 @@ static int __power_collapse(struct venus_hfi_device *device, bool force) return -EINVAL; } if (!device->power_enabled) { - dprintk(VIDC_DBG, "%s: Power already disabled\n", + dprintk(VIDC_HIGH, "%s: Power already disabled\n", __func__); goto exit; } if (!__core_in_valid_state(device)) { - dprintk(VIDC_WARN, "%s - Core not in init state\n", __func__); + dprintk(VIDC_ERR, "%s - Core not in init state\n", __func__); return -EINVAL; } @@ -3307,7 +3304,7 @@ static bool __is_session_valid(struct venus_hfi_device *device, return true; invalid: - dprintk(VIDC_WARN, "%s: device %pK, invalid session %pK\n", + dprintk(VIDC_ERR, "%s: device %pK, invalid session %pK\n", func, device, session); return false; } @@ -3384,7 +3381,7 @@ static int __response_handler(struct venus_hfi_device *device) rc = hfi_process_msg_packet(device->device_id, (struct vidc_hal_msg_pkt_hdr *)raw_packet, info); if (rc) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Corrupt/unknown packet found, discarding\n"); --packet_count; continue; @@ -3396,10 +3393,10 @@ static int __response_handler(struct venus_hfi_device *device) __process_sys_error(device); break; case HAL_SYS_RELEASE_RESOURCE_DONE: - dprintk(VIDC_DBG, "Received SYS_RELEASE_RESOURCE\n"); + dprintk(VIDC_HIGH, "Received SYS_RELEASE_RESOURCE\n"); break; case HAL_SYS_INIT_DONE: - dprintk(VIDC_DBG, "Received SYS_INIT_DONE\n"); + dprintk(VIDC_HIGH, "Received SYS_INIT_DONE\n"); break; case HAL_SESSION_LOAD_RESOURCE_DONE: break; @@ -3472,7 +3469,7 @@ static int __response_handler(struct venus_hfi_device *device) if (packet_count >= max_packets && __get_q_size(device, VIDC_IFACEQ_MSGQ_IDX)) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Too many packets in message queue to handle at once, deferring read\n"); break; } @@ -3509,7 +3506,7 @@ static void venus_hfi_core_work_handler(struct work_struct *work) if (!__core_in_valid_state(device)) { - dprintk(VIDC_DBG, "%s - Core not in init state\n", __func__); + dprintk(VIDC_ERR, "%s - Core not in init state\n", __func__); goto err_no_work; } @@ -3548,7 +3545,7 @@ static void venus_hfi_core_work_handler(struct work_struct *work) (i + 1), num_responses); break; } - dprintk(VIDC_DBG, "Processing response %d of %d, type %d\n", + dprintk(VIDC_LOW, "Processing response %d of %d, type %d\n", (i + 1), num_responses, r->response_type); device->callback(r->response_type, &r->response); } @@ -3589,7 +3586,7 @@ static int __init_regs_and_interrupts(struct venus_hfi_device *device, goto err_core_init; } - dprintk(VIDC_DBG, "HAL_DATA will be assigned now\n"); + dprintk(VIDC_HIGH, "HAL_DATA will be assigned now\n"); hal = kzalloc(sizeof(struct hal_data), GFP_KERNEL); if (!hal) { dprintk(VIDC_ERR, "Failed to alloc\n"); @@ -3618,7 +3615,7 @@ static int __init_regs_and_interrupts(struct venus_hfi_device *device, } disable_irq_nosync(res->irq); - dprintk(VIDC_INFO, + dprintk(VIDC_HIGH, "firmware_base = %pa, register_base = %pa, register_size = %d\n", &res->firmware_base, &res->register_base, res->register_size); @@ -3657,7 +3654,7 @@ static inline int __init_clocks(struct venus_hfi_device *device) venus_hfi_for_each_clock(device, cl) { - dprintk(VIDC_DBG, "%s: scalable? %d, count %d\n", + dprintk(VIDC_HIGH, "%s: scalable? %d, count %d\n", cl->name, cl->has_scaling, cl->count); } @@ -3693,7 +3690,7 @@ static int __handle_reset_clk(struct msm_vidc_platform_resources *res, return 0; rst = rst_set->reset_tbl[reset_index].rst; - dprintk(VIDC_DBG, "reset_clk: name %s reset_state %d rst %pK\n", + dprintk(VIDC_HIGH, "reset_clk: name %s reset_state %d rst %pK\n", rst_set->reset_tbl[reset_index].name, state, rst); switch (state) { @@ -3747,17 +3744,17 @@ void __disable_unprepare_clks(struct venus_hfi_device *device) } venus_hfi_for_each_clock_reverse(device, cl) { - dprintk(VIDC_DBG, "Clock: %s disable and unprepare\n", + dprintk(VIDC_HIGH, "Clock: %s disable and unprepare\n", cl->name); rc = clk_set_flags(cl->clk, CLKFLAG_NORETAIN_PERIPH); if (rc) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Failed set flag NORETAIN_PERIPH %s\n", cl->name); } rc = clk_set_flags(cl->clk, CLKFLAG_NORETAIN_MEM); if (rc) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Failed set flag NORETAIN_MEM %s\n", cl->name); } @@ -3821,13 +3818,13 @@ static inline int __prepare_enable_clks(struct venus_hfi_device *device) rc = clk_set_flags(cl->clk, CLKFLAG_RETAIN_PERIPH); if (rc) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Failed set flag RETAIN_PERIPH %s\n", cl->name); } rc = clk_set_flags(cl->clk, CLKFLAG_RETAIN_MEM); if (rc) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Failed set flag RETAIN_MEM %s\n", cl->name); } @@ -3839,7 +3836,8 @@ static inline int __prepare_enable_clks(struct venus_hfi_device *device) } c++; - dprintk(VIDC_DBG, "Clock: %s prepared and enabled\n", cl->name); + dprintk(VIDC_HIGH, + "Clock: %s prepared and enabled\n", cl->name); } call_venus_op(device, clock_config_on_enable, device); @@ -3882,7 +3880,7 @@ static int __init_bus(struct venus_hfi_device *device) venus_hfi_for_each_bus(device, bus) { if (!strcmp(bus->mode, "msm-vidc-llcc")) { if (msm_vidc_syscache_disable) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Skipping LLC bus init %s: %s\n", bus->name, bus->mode); continue; @@ -3964,7 +3962,7 @@ static void __deinit_subcaches(struct venus_hfi_device *device) venus_hfi_for_each_subcache_reverse(device, sinfo) { if (sinfo->subcache) { - dprintk(VIDC_DBG, "deinit_subcaches: %s\n", + dprintk(VIDC_HIGH, "deinit_subcaches: %s\n", sinfo->name); llcc_slice_putd(sinfo->subcache); sinfo->subcache = NULL; @@ -4009,7 +4007,7 @@ static int __init_subcaches(struct venus_hfi_device *device) sinfo->subcache = NULL; goto err_subcache_get; } - dprintk(VIDC_DBG, "init_subcaches: %s\n", + dprintk(VIDC_HIGH, "init_subcaches: %s\n", sinfo->name); } @@ -4055,7 +4053,7 @@ static int __init_resources(struct venus_hfi_device *device, rc = __init_subcaches(device); if (rc) - dprintk(VIDC_WARN, "Failed to init subcaches: %d\n", rc); + dprintk(VIDC_ERR, "Failed to init subcaches: %d\n", rc); return rc; @@ -4095,7 +4093,7 @@ static int __protect_cp_mem(struct venus_hfi_device *device) if (!strcmp(cb->name, "venus_ns")) { desc.args[1] = memprot.cp_size = cb->addr_range.start; - dprintk(VIDC_DBG, "%s memprot.cp_size: %#x\n", + dprintk(VIDC_HIGH, "%s memprot.cp_size: %#x\n", __func__, memprot.cp_size); } @@ -4104,7 +4102,7 @@ static int __protect_cp_mem(struct venus_hfi_device *device) cb->addr_range.start; desc.args[3] = memprot.cp_nonpixel_size = cb->addr_range.size; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s memprot.cp_nonpixel_start: %#x size: %#x\n", __func__, memprot.cp_nonpixel_start, memprot.cp_nonpixel_size); @@ -4132,7 +4130,7 @@ static int __disable_regulator(struct regulator_info *rinfo, { int rc = 0; - dprintk(VIDC_DBG, "Disabling regulator %s\n", rinfo->name); + dprintk(VIDC_HIGH, "Disabling regulator %s\n", rinfo->name); /* * This call is needed. Driver needs to acquire the control back @@ -4147,7 +4145,7 @@ static int __disable_regulator(struct regulator_info *rinfo, * about it. We can't disable the regulator w/o * getting it back under s/w control */ - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Failed to acquire control on %s\n", rinfo->name); @@ -4156,7 +4154,7 @@ static int __disable_regulator(struct regulator_info *rinfo, rc = regulator_disable(rinfo->regulator); if (rc) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Failed to disable %s: %d\n", rinfo->name, rc); goto disable_regulator_failed; @@ -4176,7 +4174,7 @@ static int __enable_hw_power_collapse(struct venus_hfi_device *device) rc = __hand_off_regulators(device); if (rc) - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "%s : Failed to enable HW power collapse %d\n", __func__, rc); return rc; @@ -4187,7 +4185,7 @@ static int __enable_regulators(struct venus_hfi_device *device) int rc = 0, c = 0; struct regulator_info *rinfo; - dprintk(VIDC_DBG, "Enabling regulators\n"); + dprintk(VIDC_HIGH, "Enabling regulators\n"); venus_hfi_for_each_regulator(device, rinfo) { rc = regulator_enable(rinfo->regulator); @@ -4198,7 +4196,7 @@ static int __enable_regulators(struct venus_hfi_device *device) goto err_reg_enable_failed; } - dprintk(VIDC_DBG, "Enabled regulator %s\n", + dprintk(VIDC_HIGH, "Enabled regulator %s\n", rinfo->name); c++; } @@ -4216,7 +4214,7 @@ int __disable_regulators(struct venus_hfi_device *device) { struct regulator_info *rinfo; - dprintk(VIDC_DBG, "Disabling regulators\n"); + dprintk(VIDC_HIGH, "Disabling regulators\n"); venus_hfi_for_each_regulator_reverse(device, rinfo) __disable_regulator(rinfo, device); @@ -4237,17 +4235,17 @@ static int __enable_subcaches(struct venus_hfi_device *device) venus_hfi_for_each_subcache(device, sinfo) { rc = llcc_slice_activate(sinfo->subcache); if (rc) { - dprintk(VIDC_WARN, "Failed to activate %s: %d\n", + dprintk(VIDC_ERR, "Failed to activate %s: %d\n", sinfo->name, rc); msm_vidc_res_handle_fatal_hw_error(device->res, true); goto err_activate_fail; } sinfo->isactive = true; - dprintk(VIDC_DBG, "Activated subcache %s\n", sinfo->name); + dprintk(VIDC_HIGH, "Activated subcache %s\n", sinfo->name); c++; } - dprintk(VIDC_DBG, "Activated %d Subcaches to Venus\n", c); + dprintk(VIDC_HIGH, "Activated %d Subcaches to Venus\n", c); return 0; @@ -4268,7 +4266,7 @@ static int __set_subcaches(struct venus_hfi_device *device) struct vidc_resource_hdr rhdr; if (device->res->sys_cache_res_set) { - dprintk(VIDC_DBG, "Subcaches already set to Venus\n"); + dprintk(VIDC_HIGH, "Subcaches already set to Venus\n"); return 0; } @@ -4287,7 +4285,7 @@ static int __set_subcaches(struct venus_hfi_device *device) /* Set resource to Venus for activated subcaches */ if (c) { - dprintk(VIDC_DBG, "Setting %d Subcaches\n", c); + dprintk(VIDC_HIGH, "Setting %d Subcaches\n", c); rhdr.resource_handle = sc_res_info; /* cookie */ rhdr.resource_id = VIDC_RESOURCE_SYSCACHE; @@ -4296,7 +4294,7 @@ static int __set_subcaches(struct venus_hfi_device *device) rc = __core_set_resource(device, &rhdr, (void *)sc_res_info); if (rc) { - dprintk(VIDC_WARN, "Failed to set subcaches %d\n", rc); + dprintk(VIDC_ERR, "Failed to set subcaches %d\n", rc); goto err_fail_set_subacaches; } @@ -4305,7 +4303,7 @@ static int __set_subcaches(struct venus_hfi_device *device) sinfo->isset = true; } - dprintk(VIDC_DBG, "Set Subcaches done to Venus\n"); + dprintk(VIDC_HIGH, "Set Subcaches done to Venus\n"); device->res->sys_cache_res_set = true; } @@ -4347,13 +4345,13 @@ static int __release_subcaches(struct venus_hfi_device *device) } if (c > 0) { - dprintk(VIDC_DBG, "Releasing %d subcaches\n", c); + dprintk(VIDC_HIGH, "Releasing %d subcaches\n", c); rhdr.resource_handle = sc_res_info; /* cookie */ rhdr.resource_id = VIDC_RESOURCE_SYSCACHE; rc = __core_release_resource(device, &rhdr); if (rc) - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Failed to release %d subcaches\n", c); } @@ -4373,11 +4371,11 @@ static int __disable_subcaches(struct venus_hfi_device *device) /* De-activate subcaches */ venus_hfi_for_each_subcache_reverse(device, sinfo) { if (sinfo->isactive) { - dprintk(VIDC_DBG, "De-activate subcache %s\n", + dprintk(VIDC_HIGH, "De-activate subcache %s\n", sinfo->name); rc = llcc_slice_deactivate(sinfo->subcache); if (rc) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Failed to de-activate %s: %d\n", sinfo->name, rc); } @@ -4402,7 +4400,7 @@ static int __set_ubwc_config(struct venus_hfi_device *device) rc = call_hfi_pkt_op(device, sys_ubwc_config, pkt, device->res->ubwc_config); if (rc) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "ubwc config setting to FW failed\n"); rc = -ENOTEMPTY; goto fail_to_set_ubwc_config; @@ -4413,7 +4411,7 @@ static int __set_ubwc_config(struct venus_hfi_device *device) goto fail_to_set_ubwc_config; } - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Configured UBWC Config to Venus\n"); fail_to_set_ubwc_config: @@ -4457,7 +4455,7 @@ static int __venus_power_on(struct venus_hfi_device *device) rc = __scale_clocks(device); if (rc) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Failed to scale clocks, performance might be affected\n"); rc = 0; } @@ -4497,10 +4495,10 @@ static void __power_off_common(struct venus_hfi_device *device) dprintk(VIDC_ERR, "Failed to reset ahb2axi\n"); if (__disable_regulators(device)) - dprintk(VIDC_WARN, "Failed to disable regulators\n"); + dprintk(VIDC_ERR, "Failed to disable regulators\n"); if (__unvote_buses(device)) - dprintk(VIDC_WARN, "Failed to unvote for buses\n"); + dprintk(VIDC_ERR, "Failed to unvote for buses\n"); device->power_enabled = false; } @@ -4512,11 +4510,11 @@ static inline int __suspend(struct venus_hfi_device *device) dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } else if (!device->power_enabled) { - dprintk(VIDC_DBG, "Power already disabled\n"); + dprintk(VIDC_HIGH, "Power already disabled\n"); return 0; } - dprintk(VIDC_PROF, "Entering suspend\n"); + dprintk(VIDC_HIGH, "Entering suspend\n"); if (device->res->pm_qos_latency_us && pm_qos_request_active(&device->qos)) @@ -4524,14 +4522,14 @@ static inline int __suspend(struct venus_hfi_device *device) rc = __tzbsp_set_video_state(TZBSP_VIDEO_STATE_SUSPEND); if (rc) { - dprintk(VIDC_WARN, "Failed to suspend video core %d\n", rc); + dprintk(VIDC_ERR, "Failed to suspend video core %d\n", rc); goto err_tzbsp_suspend; } __disable_subcaches(device); call_venus_op(device, power_off, device); - dprintk(VIDC_PROF, "Venus power off\n"); + dprintk(VIDC_HIGH, "Venus power off\n"); return rc; err_tzbsp_suspend: @@ -4549,11 +4547,11 @@ static inline int __resume(struct venus_hfi_device *device) } else if (device->power_enabled) { goto exit; } else if (!__core_in_valid_state(device)) { - dprintk(VIDC_DBG, "venus_hfi_device in deinit state."); + dprintk(VIDC_ERR, "venus_hfi_device in deinit state."); return -EINVAL; } - dprintk(VIDC_PROF, "Resuming from power collapse\n"); + dprintk(VIDC_HIGH, "Resuming from power collapse\n"); rc = __venus_power_on(device); if (rc) { dprintk(VIDC_ERR, "Failed to power on venus\n"); @@ -4600,7 +4598,7 @@ static inline int __resume(struct venus_hfi_device *device) __set_subcaches(device); __dsp_resume(device, flags); - dprintk(VIDC_PROF, "Resumed from power collapse\n"); + dprintk(VIDC_HIGH, "Resumed from power collapse\n"); exit: /* Don't reset skip_pc_count for SYS_PC_PREP cmd */ if (device->last_packet_type != HFI_CMD_SYS_PC_PREP) @@ -4703,7 +4701,7 @@ static void __unload_fw(struct venus_hfi_device *device) device->resources.fw.cookie = NULL; __deinit_resources(device); - dprintk(VIDC_PROF, "Firmware unloaded successfully\n"); + dprintk(VIDC_HIGH, "Firmware unloaded successfully\n"); } static int venus_hfi_get_fw_info(void *dev, struct hal_fw_info *fw_info) @@ -4737,7 +4735,7 @@ static int venus_hfi_get_fw_info(void *dev, struct hal_fw_info *fw_info) ; if (i == VENUS_VERSION_LENGTH - 1) { - dprintk(VIDC_WARN, "Venus version string is not proper\n"); + dprintk(VIDC_ERR, "Venus version string is not proper\n"); fw_info->version[0] = '\0'; goto fail_version_string; } @@ -4747,7 +4745,7 @@ static int venus_hfi_get_fw_info(void *dev, struct hal_fw_info *fw_info) fw_info->version[j] = '\0'; fail_version_string: - dprintk(VIDC_DBG, "F/W version retrieved : %s\n", fw_info->version); + dprintk(VIDC_HIGH, "F/W version retrieved : %s\n", fw_info->version); fw_info->base_addr = device->hal_data->firmware_base; fw_info->register_base = device->res->register_base; fw_info->register_size = device->hal_data->register_size; @@ -4907,7 +4905,7 @@ static struct venus_hfi_device *__add_device(u32 device_id, return NULL; } - dprintk(VIDC_INFO, "entered , device_id: %d\n", device_id); + dprintk(VIDC_HIGH, "entered , device_id: %d\n", device_id); hdevice = kzalloc(sizeof(struct venus_hfi_device), GFP_KERNEL); if (!hdevice) { diff --git a/msm/vidc/hfi_iris2.c b/msm/vidc/hfi_iris2.c index ecae4f752936..12377281e5b3 100644 --- a/msm/vidc/hfi_iris2.c +++ b/msm/vidc/hfi_iris2.c @@ -193,7 +193,7 @@ void __power_off_iris2(struct venus_hfi_device *device) __read_register(device, AON_WRAPPER_MVP_NOC_LPI_STATUS); reg_status = lpi_status & BIT(0); - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Noc: lpi_status %d noc_status %d (count %d)\n", lpi_status, reg_status, count); usleep_range(50, 100); @@ -213,7 +213,7 @@ void __power_off_iris2(struct venus_hfi_device *device) lpi_status = __read_register(device, WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2); reg_status = lpi_status & 0x7; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "DBLP Set : lpi_status %d reg_status %d (count %d)\n", lpi_status, reg_status, count); usleep_range(50, 100); @@ -232,7 +232,7 @@ void __power_off_iris2(struct venus_hfi_device *device) while (lpi_status && count < max_count) { lpi_status = __read_register(device, WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2); - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "DBLP Release: lpi_status %d(count %d)\n", lpi_status, count); usleep_range(50, 100); @@ -252,10 +252,10 @@ void __power_off_iris2(struct venus_hfi_device *device) /* HPG 6.1.2 Step 5 */ if (__disable_regulators(device)) - dprintk(VIDC_WARN, "Failed to disable regulators\n"); + dprintk(VIDC_ERR, "Failed to disable regulators\n"); if (__unvote_buses(device)) - dprintk(VIDC_WARN, "Failed to unvote for buses\n"); + dprintk(VIDC_ERR, "Failed to unvote for buses\n"); device->power_enabled = false; } @@ -272,20 +272,20 @@ int __prepare_pc_iris2(struct venus_hfi_device *device) idle_status = ctrl_status & BIT(30); if (pc_ready) { - dprintk(VIDC_DBG, "Already in pc_ready state\n"); + dprintk(VIDC_HIGH, "Already in pc_ready state\n"); return 0; } wfi_status = BIT(0) & __read_register(device, WRAPPER_TZ_CPU_STATUS); if (!wfi_status || !idle_status) { - dprintk(VIDC_WARN, "Skipping PC, wfi status not set\n"); + dprintk(VIDC_ERR, "Skipping PC, wfi status not set\n"); goto skip_power_off; } rc = __prepare_pc(device); if (rc) { - dprintk(VIDC_WARN, "Failed __prepare_pc %d\n", rc); + dprintk(VIDC_ERR, "Failed __prepare_pc %d\n", rc); goto skip_power_off; } @@ -307,7 +307,7 @@ int __prepare_pc_iris2(struct venus_hfi_device *device) return rc; skip_power_off: - dprintk(VIDC_WARN, "Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n", + dprintk(VIDC_ERR, "Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n", wfi_status, idle_status, pc_ready, ctrl_status); return -EAGAIN; } @@ -377,7 +377,7 @@ void __core_clear_interrupt_iris2(struct venus_hfi_device *device) if (intr_status & mask) { device->intr_status |= intr_status; device->reg_count++; - dprintk(VIDC_DBG, + dprintk(VIDC_LOW, "INTERRUPT for device: %pK: times: %d interrupt_status: %d\n", device, device->reg_count, intr_status); } else { diff --git a/msm/vidc/hfi_packetization.c b/msm/vidc/hfi_packetization.c index aded2b398165..036a0c4c5d97 100644 --- a/msm/vidc/hfi_packetization.c +++ b/msm/vidc/hfi_packetization.c @@ -70,7 +70,7 @@ enum hal_video_codec vidc_get_hal_codec(u32 hfi_codec) hal_codec = HAL_VIDEO_CODEC_CVP; break; default: - dprintk(VIDC_INFO, "%s: invalid codec 0x%x\n", + dprintk(VIDC_HIGH, "%s: invalid codec 0x%x\n", __func__, hfi_codec); hal_codec = 0; break; @@ -135,7 +135,7 @@ u32 vidc_get_hfi_codec(enum hal_video_codec hal_codec) hfi_codec = HFI_VIDEO_CODEC_CVP; break; default: - dprintk(VIDC_INFO, "%s: invalid codec 0x%x\n", + dprintk(VIDC_HIGH, "%s: invalid codec 0x%x\n", __func__, hal_codec); hfi_codec = 0; break; @@ -207,7 +207,7 @@ int create_pkt_cmd_sys_coverage_config( pkt->num_properties = 1; pkt->rg_property_data[0] = HFI_PROPERTY_SYS_CONFIG_COVERAGE; pkt->rg_property_data[1] = mode; - dprintk(VIDC_DBG, "Firmware coverage mode %d\n", + dprintk(VIDC_HIGH, "Firmware coverage mode %d\n", pkt->rg_property_data[1]); return 0; } @@ -256,7 +256,7 @@ int create_pkt_cmd_sys_set_resource( for (i = 0; i < hfi_sc_info->num_entries; i++) { hfi_sc[i] = res_sc[i]; - dprintk(VIDC_DBG, "entry hfi#%d, sc_id %d, size %d\n", + dprintk(VIDC_HIGH, "entry hfi#%d, sc_id %d, size %d\n", i, hfi_sc[i].sc_id, hfi_sc[i].size); } break; @@ -297,7 +297,7 @@ int create_pkt_cmd_sys_release_resource( rc = -ENOTSUPP; } - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "rel_res: pkt_type 0x%x res_type 0x%x prepared\n", pkt->packet_type, pkt->resource_type); @@ -785,7 +785,7 @@ int create_pkt_cmd_session_set_property( if (size && pdata) memcpy(&pkt->rg_property_data[1], pdata, size); - dprintk(VIDC_DBG, "Setting HAL Property = 0x%x\n", ptype); + dprintk(VIDC_HIGH, "Setting HAL Property = 0x%x\n", ptype); return 0; } @@ -804,7 +804,7 @@ static int get_hfi_ssr_type(enum hal_ssr_trigger_type type) rc = HFI_TEST_SSR_HW_WDOG_IRQ; break; default: - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "SSR trigger type not recognized, using WDOG.\n"); } return rc; @@ -881,7 +881,7 @@ static struct hfi_packetization_ops hfi_default = { struct hfi_packetization_ops *hfi_get_pkt_ops_handle( enum hfi_packetization_type type) { - dprintk(VIDC_DBG, "%s selected\n", + dprintk(VIDC_HIGH, "%s selected\n", type == HFI_PACKETIZATION_4XX ? "4xx packetization" : "Unknown hfi"); diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index b731ad2260cc..5805b7ba195d 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -141,7 +141,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, (struct hfi_frame_size *) data_ptr; event_notify.width = frame_sz->width; event_notify.height = frame_sz->height; - dprintk(VIDC_DBG, "height: %d width: %d\n", + dprintk(VIDC_HIGH, "height: %d width: %d\n", frame_sz->height, frame_sz->width); data_ptr += sizeof(struct hfi_frame_size); @@ -152,7 +152,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, (struct hfi_profile_level *) data_ptr; event_notify.profile = profile_level->profile; event_notify.level = profile_level->level; - dprintk(VIDC_DBG, "profile: %d level: %d\n", + dprintk(VIDC_HIGH, "profile: %d level: %d\n", profile_level->profile, profile_level->level); data_ptr += @@ -184,7 +184,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, MSM_VIDC_BIT_DEPTH_10; else event_notify.bit_depth = luma_bit_depth; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "bitdepth(%d), luma_bit_depth(%d), chroma_bit_depth(%d)\n", event_notify.bit_depth, luma_bit_depth, chroma_bit_depth); @@ -195,7 +195,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, pic_struct = (struct hfi_pic_struct *) data_ptr; event_notify.pic_struct = pic_struct->progressive_only; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Progressive only flag: %d\n", pic_struct->progressive_only); data_ptr += @@ -207,7 +207,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, (struct hfi_colour_space *) data_ptr; event_notify.colour_space = colour_info->colour_space; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Colour space value is: %d\n", colour_info->colour_space); data_ptr += @@ -217,7 +217,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, data_ptr = data_ptr + sizeof(u32); entropy_mode = *(u32 *)data_ptr; event_notify.entropy_mode = entropy_mode; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Entropy Mode: 0x%x\n", entropy_mode); data_ptr += sizeof(u32); @@ -229,7 +229,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, data_ptr; event_notify.capture_buf_count = buf_req->buffer_count_min; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Capture Count : 0x%x\n", event_notify.capture_buf_count); data_ptr += @@ -245,11 +245,11 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, event_notify.crop_data.width = crop_info->width; event_notify.crop_data.height = crop_info->height; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "CROP info : Left = %d Top = %d\n", crop_info->left, crop_info->top); - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "CROP info : Width = %d Height = %d\n", crop_info->width, crop_info->height); @@ -280,7 +280,7 @@ static int hfi_process_evt_release_buffer_ref(u32 device_id, struct msm_vidc_cb_event event_notify = {0}; struct hfi_msg_release_buffer_ref_event_packet *data; - dprintk(VIDC_DBG, + dprintk(VIDC_LOW, "RECEIVED: EVENT_NOTIFY - release_buffer_reference\n"); if (sizeof(struct hfi_msg_event_notify_packet) > pkt->size) { @@ -329,13 +329,13 @@ static int hfi_process_session_error(u32 device_id, cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.status = hfi_map_err_status(pkt->event_data1); info->response.cmd = cmd_done; - dprintk(VIDC_INFO, "Received: SESSION_ERROR with event id : %#x %#x\n", + dprintk(VIDC_HIGH, "Received: SESSION_ERROR with event id : %#x %#x\n", pkt->event_data1, pkt->event_data2); switch (pkt->event_data1) { /* Ignore below errors */ case HFI_ERR_SESSION_INVALID_SCALE_FACTOR: case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED: - dprintk(VIDC_INFO, "Non Fatal: HFI_EVENT_SESSION_ERROR\n"); + dprintk(VIDC_HIGH, "Non Fatal: HFI_EVENT_SESSION_ERROR\n"); info->response_type = HAL_RESPONSE_UNUSED; break; default: @@ -354,7 +354,7 @@ static int hfi_process_event_notify(u32 device_id, struct msm_vidc_cb_info *info) { struct hfi_msg_event_notify_packet *pkt = _pkt; - dprintk(VIDC_DBG, "Received: EVENT_NOTIFY\n"); + dprintk(VIDC_LOW, "Received: EVENT_NOTIFY\n"); if (pkt->size < sizeof(struct hfi_msg_event_notify_packet)) { dprintk(VIDC_ERR, "Invalid Params\n"); @@ -367,17 +367,17 @@ static int hfi_process_event_notify(u32 device_id, pkt->event_data1, pkt->event_data2); return hfi_process_sys_error(device_id, pkt, info); case HFI_EVENT_SESSION_ERROR: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_ERROR[%#x]\n", + dprintk(VIDC_HIGH, "HFI_EVENT_SESSION_ERROR[%#x]\n", pkt->session_id); return hfi_process_session_error(device_id, pkt, info); case HFI_EVENT_SESSION_SEQUENCE_CHANGED: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED[%#x]\n", + dprintk(VIDC_HIGH, "HFI_EVENT_SESSION_SEQUENCE_CHANGED[%#x]\n", pkt->session_id); return hfi_process_sess_evt_seq_changed(device_id, pkt, info); case HFI_EVENT_RELEASE_BUFFER_REFERENCE: - dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE[%#x]\n", + dprintk(VIDC_LOW, "HFI_EVENT_RELEASE_BUFFER_REFERENCE[%#x]\n", pkt->session_id); return hfi_process_evt_release_buffer_ref(device_id, pkt, info); @@ -399,7 +399,7 @@ static int hfi_process_sys_init_done(u32 device_id, struct msm_vidc_cb_cmd_done cmd_done = {0}; enum vidc_status status = VIDC_ERR_NONE; - dprintk(VIDC_DBG, "RECEIVED: SYS_INIT_DONE\n"); + dprintk(VIDC_HIGH, "RECEIVED: SYS_INIT_DONE\n"); if (sizeof(struct hfi_msg_sys_init_done_packet) > pkt->size) { dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", __func__, pkt->size); @@ -430,7 +430,7 @@ static int hfi_process_sys_rel_resource_done(u32 device_id, enum vidc_status status = VIDC_ERR_NONE; u32 pkt_size; - dprintk(VIDC_DBG, "RECEIVED: SYS_RELEASE_RESOURCE_DONE\n"); + dprintk(VIDC_HIGH, "RECEIVED: SYS_RELEASE_RESOURCE_DONE\n"); pkt_size = sizeof(struct hfi_msg_sys_release_resource_done_packet); if (pkt_size > pkt->size) { dprintk(VIDC_ERR, @@ -485,7 +485,7 @@ static void hfi_process_sess_get_prop_buf_req( } while (req_bytes) { - dprintk(VIDC_DBG, "got buffer requirements for: %d\n", + dprintk(VIDC_HIGH, "got buffer requirements for: %d\n", hfi_buf_req->buffer_type); switch (hfi_buf_req->buffer_type) { case HFI_BUFFER_INPUT: @@ -576,7 +576,7 @@ static int hfi_process_session_prop_info(u32 device_id, struct msm_vidc_cb_cmd_done cmd_done = {0}; struct buffer_requirements buff_req = { { {0} } }; - dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO[%#x]\n", + dprintk(VIDC_HIGH, "Received SESSION_PROPERTY_INFO[%#x]\n", pkt->session_id); if (pkt->size < sizeof(struct hfi_msg_session_property_info_packet)) { @@ -603,7 +603,7 @@ static int hfi_process_session_prop_info(u32 device_id, return 0; default: - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "hal_process_session_prop_info: unknown_prop_id: %x\n", pkt->rg_property_data[0]); return -ENOTSUPP; @@ -617,7 +617,7 @@ static int hfi_process_session_init_done(u32 device_id, struct hfi_msg_sys_session_init_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_INIT_DONE[%x]\n", pkt->session_id); + dprintk(VIDC_HIGH, "RECEIVED: SESSION_INIT_DONE[%x]\n", pkt->session_id); if (sizeof(struct hfi_msg_sys_session_init_done_packet) > pkt->size) { dprintk(VIDC_ERR, @@ -642,7 +642,7 @@ static int hfi_process_session_load_res_done(u32 device_id, struct hfi_msg_session_load_resources_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%#x]\n", + dprintk(VIDC_HIGH, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%#x]\n", pkt->session_id); if (sizeof(struct hfi_msg_session_load_resources_done_packet) != @@ -671,7 +671,7 @@ static int hfi_process_session_flush_done(u32 device_id, struct hfi_msg_session_flush_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_FLUSH_DONE[%#x]\n", + dprintk(VIDC_HIGH, "RECEIVED: SESSION_FLUSH_DONE[%#x]\n", pkt->session_id); if (sizeof(struct hfi_msg_session_flush_done_packet) != pkt->size) { @@ -716,7 +716,7 @@ static int hfi_process_session_etb_done(u32 device_id, struct msm_vidc_cb_data_done data_done = {0}; struct hfi_picture_type *hfi_picture_type = NULL; - dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%#x]\n", pkt->session_id); + dprintk(VIDC_LOW, "RECEIVED: SESSION_ETB_DONE[%#x]\n", pkt->session_id); if (!pkt || pkt->size < sizeof(struct hfi_msg_session_empty_buffer_done_packet)) { @@ -749,7 +749,7 @@ static int hfi_process_session_etb_done(u32 device_id, data_done.input_done.flags = hfi_picture_type->picture_type; else - dprintk(VIDC_DBG, + dprintk(VIDC_LOW, "Non-Sync frame sent for H264/HEVC\n"); } @@ -791,7 +791,7 @@ static int hfi_process_session_ftb_done( struct hfi_msg_session_fill_buffer_done_compressed_packet *pkt = (struct hfi_msg_session_fill_buffer_done_compressed_packet *) msg_hdr; - dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%#x]\n", + dprintk(VIDC_LOW, "RECEIVED: SESSION_FTB_DONE[%#x]\n", pkt->session_id); if (sizeof(struct hfi_msg_session_fill_buffer_done_compressed_packet) @@ -831,7 +831,7 @@ static int hfi_process_session_ftb_done( (struct hfi_msg_session_fbd_uncompressed_plane0_packet *) msg_hdr; - dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%#x]\n", + dprintk(VIDC_LOW, "RECEIVED: SESSION_FTB_DONE[%#x]\n", pkt->session_id); if (sizeof( struct hfi_msg_session_fbd_uncompressed_plane0_packet) > @@ -895,7 +895,7 @@ static int hfi_process_session_start_done(u32 device_id, struct hfi_msg_session_start_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_START_DONE[%#x]\n", + dprintk(VIDC_HIGH, "RECEIVED: SESSION_START_DONE[%#x]\n", pkt->session_id); if (!pkt || pkt->size != @@ -922,7 +922,7 @@ static int hfi_process_session_stop_done(u32 device_id, struct hfi_msg_session_stop_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_STOP_DONE[%#x]\n", + dprintk(VIDC_HIGH, "RECEIVED: SESSION_STOP_DONE[%#x]\n", pkt->session_id); if (!pkt || pkt->size != @@ -950,7 +950,7 @@ static int hfi_process_session_rel_res_done(u32 device_id, struct hfi_msg_session_release_resources_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%#x]\n", + dprintk(VIDC_HIGH, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%#x]\n", pkt->session_id); if (!pkt || pkt->size != @@ -984,7 +984,7 @@ static int hfi_process_session_rel_buf_done(u32 device_id, pkt ? pkt->size : 0); return -E2BIG; } - dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_BUFFER_DONE[%#x]\n", + dprintk(VIDC_HIGH, "RECEIVED:SESSION_RELEASE_BUFFER_DONE[%#x]\n", pkt->session_id); cmd_done.device_id = device_id; @@ -1014,7 +1014,7 @@ static int hfi_process_session_register_buffer_done(u32 device_id, __func__, pkt ? pkt->size : 0); return -E2BIG; } - dprintk(VIDC_DBG, "RECEIVED: SESSION_REGISTER_BUFFERS_DONE[%#x]\n", + dprintk(VIDC_HIGH, "RECEIVED: SESSION_REGISTER_BUFFERS_DONE[%#x]\n", pkt->session_id); cmd_done.device_id = device_id; @@ -1042,7 +1042,7 @@ static int hfi_process_session_unregister_buffer_done(u32 device_id, __func__, pkt ? pkt->size : 0); return -E2BIG; } - dprintk(VIDC_DBG, "RECEIVED: SESSION_UNREGISTER_BUFFERS_DONE[%#x]\n", + dprintk(VIDC_HIGH, "RECEIVED: SESSION_UNREGISTER_BUFFERS_DONE[%#x]\n", pkt->session_id); cmd_done.device_id = device_id; @@ -1064,7 +1064,7 @@ static int hfi_process_session_end_done(u32 device_id, struct hfi_msg_sys_session_end_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_END_DONE[%#x]\n", pkt->session_id); + dprintk(VIDC_HIGH, "RECEIVED: SESSION_END_DONE[%#x]\n", pkt->session_id); if (!pkt || pkt->size != sizeof(struct hfi_msg_sys_session_end_done_packet)) { @@ -1090,7 +1090,7 @@ static int hfi_process_session_abort_done(u32 device_id, struct hfi_msg_sys_session_abort_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_ABORT_DONE[%#x]\n", + dprintk(VIDC_HIGH, "RECEIVED: SESSION_ABORT_DONE[%#x]\n", pkt->session_id); if (!pkt || pkt->size != @@ -1142,7 +1142,7 @@ static void hfi_process_sys_get_prop_image_version( version[i] = ' '; } version[i] = '\0'; - dprintk(VIDC_DBG, "F/W version: %s\n", version); + dprintk(VIDC_HIGH, "F/W version: %s\n", version); smem_table_ptr = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_IMAGE_VERSION_TABLE, &smem_block_size); @@ -1179,7 +1179,7 @@ static int hfi_process_sys_property_info(u32 device_id, }; return 0; default: - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: unknown_prop_id: %x\n", __func__, pkt->rg_property_data[0]); return -ENOTSUPP; @@ -1210,7 +1210,7 @@ int hfi_process_msg_packet(u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr, return -EINVAL; } - dprintk(VIDC_DBG, "Parse response %#x\n", msg_hdr->packet); + dprintk(VIDC_LOW, "Parse response %#x\n", msg_hdr->packet); switch (msg_hdr->packet) { case HFI_MSG_EVENT_NOTIFY: pkt_func = (pkt_func_def)hfi_process_event_notify; @@ -1272,7 +1272,7 @@ int hfi_process_msg_packet(u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr, pkt_func = (pkt_func_def)hfi_process_ignore; break; default: - dprintk(VIDC_DBG, "Unable to parse message: %#x\n", + dprintk(VIDC_LOW, "Unable to parse message: %#x\n", msg_hdr->packet); break; } diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index 1ccb9368aa53..10976ee06687 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -187,7 +187,7 @@ static int msm_cvp_init_downscale_resolution(struct msm_vidc_inst *inst) ds_height = cvp->height; if (!cvp->downscale) { - dprintk(VIDC_DBG, "%s: downscaling not enabled\n", __func__); + dprintk(VIDC_HIGH, "%s: downscaling not enabled\n", __func__); goto exit; } @@ -240,10 +240,10 @@ static void msm_cvp_deinit_downscale_buffers(struct msm_vidc_inst *inst) return; } cvp = inst->cvp; - dprintk(VIDC_DBG, "%s:\n", __func__); + dprintk(VIDC_HIGH, "%s:\n", __func__); if (cvp->src_buffer.dbuf) { - print_cvp_buffer(VIDC_DBG, "free: src_buffer", + print_cvp_buffer(VIDC_HIGH, "free: src_buffer", inst, &cvp->src_buffer); if (msm_cvp_free_buffer(inst, &cvp->src_buffer)) print_cvp_buffer(VIDC_ERR, @@ -251,7 +251,7 @@ static void msm_cvp_deinit_downscale_buffers(struct msm_vidc_inst *inst) inst, &cvp->src_buffer); } if (cvp->ref_buffer.dbuf) { - print_cvp_buffer(VIDC_DBG, "free: ref_buffer", + print_cvp_buffer(VIDC_HIGH, "free: ref_buffer", inst, &cvp->ref_buffer); if (msm_cvp_free_buffer(inst, &cvp->ref_buffer)) print_cvp_buffer(VIDC_ERR, @@ -272,10 +272,10 @@ static int msm_cvp_init_downscale_buffers(struct msm_vidc_inst *inst) cvp = inst->cvp; if (!cvp->downscale) { - dprintk(VIDC_DBG, "%s: downscaling not enabled\n", __func__); + dprintk(VIDC_HIGH, "%s: downscaling not enabled\n", __func__); return 0; } - dprintk(VIDC_DBG, "%s:\n", __func__); + dprintk(VIDC_HIGH, "%s:\n", __func__); cvp->src_buffer.size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, cvp->ds_width, cvp->ds_height); @@ -286,7 +286,7 @@ static int msm_cvp_init_downscale_buffers(struct msm_vidc_inst *inst) inst, &cvp->src_buffer); goto error; } - print_cvp_buffer(VIDC_DBG, "alloc: src_buffer", + print_cvp_buffer(VIDC_HIGH, "alloc: src_buffer", inst, &cvp->src_buffer); cvp->ref_buffer.size = cvp->src_buffer.size; @@ -297,7 +297,7 @@ static int msm_cvp_init_downscale_buffers(struct msm_vidc_inst *inst) inst, &cvp->ref_buffer); goto error; } - print_cvp_buffer(VIDC_DBG, "alloc: ref_buffer", + print_cvp_buffer(VIDC_HIGH, "alloc: ref_buffer", inst, &cvp->ref_buffer); return rc; @@ -316,10 +316,10 @@ static void msm_cvp_deinit_context_buffers(struct msm_vidc_inst *inst) return; } cvp = inst->cvp; - dprintk(VIDC_DBG, "%s:\n", __func__); + dprintk(VIDC_HIGH, "%s:\n", __func__); if (cvp->context_buffer.dbuf) { - print_cvp_buffer(VIDC_DBG, "free: context_buffer", + print_cvp_buffer(VIDC_HIGH, "free: context_buffer", inst, &cvp->context_buffer); if (msm_cvp_free_buffer(inst, &cvp->context_buffer)) print_cvp_buffer(VIDC_ERR, @@ -327,7 +327,7 @@ static void msm_cvp_deinit_context_buffers(struct msm_vidc_inst *inst) inst, &cvp->context_buffer); } if (cvp->refcontext_buffer.dbuf) { - print_cvp_buffer(VIDC_DBG, "free: refcontext_buffer", + print_cvp_buffer(VIDC_HIGH, "free: refcontext_buffer", inst, &cvp->refcontext_buffer); if (msm_cvp_free_buffer(inst, &cvp->refcontext_buffer)) print_cvp_buffer(VIDC_ERR, @@ -346,7 +346,7 @@ static int msm_cvp_init_context_buffers(struct msm_vidc_inst *inst) return -EINVAL; } cvp = inst->cvp; - dprintk(VIDC_DBG, "%s:\n", __func__); + dprintk(VIDC_HIGH, "%s:\n", __func__); cvp->context_buffer.size = HFI_DME_FRAME_CONTEXT_BUFFER_SIZE; rc = msm_cvp_allocate_buffer(inst, &cvp->context_buffer, false); @@ -356,7 +356,7 @@ static int msm_cvp_init_context_buffers(struct msm_vidc_inst *inst) inst, &cvp->context_buffer); goto error; } - print_cvp_buffer(VIDC_DBG, "alloc: context_buffer", + print_cvp_buffer(VIDC_HIGH, "alloc: context_buffer", inst, &cvp->context_buffer); cvp->refcontext_buffer.size = cvp->context_buffer.size; @@ -367,7 +367,7 @@ static int msm_cvp_init_context_buffers(struct msm_vidc_inst *inst) inst, &cvp->refcontext_buffer); goto error; } - print_cvp_buffer(VIDC_DBG, "alloc: refcontext_buffer", + print_cvp_buffer(VIDC_HIGH, "alloc: refcontext_buffer", inst, &cvp->refcontext_buffer); return rc; @@ -390,10 +390,10 @@ static void msm_cvp_deinit_internal_buffers(struct msm_vidc_inst *inst) } cvp = inst->cvp; - dprintk(VIDC_DBG, "%s:\n", __func__); + dprintk(VIDC_HIGH, "%s:\n", __func__); if (cvp->output_buffer.dbuf) { - print_cvp_buffer(VIDC_DBG, "free: output_buffer", + print_cvp_buffer(VIDC_HIGH, "free: output_buffer", inst, &cvp->output_buffer); rc = msm_cvp_free_buffer(inst, &cvp->output_buffer); if (rc) @@ -403,7 +403,7 @@ static void msm_cvp_deinit_internal_buffers(struct msm_vidc_inst *inst) } if (cvp->persist2_buffer.dbuf) { - print_cvp_buffer(VIDC_DBG, "free: persist2_buffer", + print_cvp_buffer(VIDC_HIGH, "free: persist2_buffer", inst, &cvp->persist2_buffer); memset(&persist2_packet, 0, sizeof(struct msm_cvp_session_release_persist_buffers_packet)); @@ -455,7 +455,7 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst) } cvp = inst->cvp; arg = cvp->arg; - dprintk(VIDC_DBG, "%s:\n", __func__); + dprintk(VIDC_HIGH, "%s:\n", __func__); cvp->persist2_buffer.size = HFI_DME_INTERNAL_PERSIST_2_BUFFER_SIZE; rc = msm_cvp_allocate_buffer(inst, &cvp->persist2_buffer, false); @@ -465,7 +465,7 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst) inst, &cvp->persist2_buffer); goto error; } - print_cvp_buffer(VIDC_DBG, "alloc: persist2_buffer", + print_cvp_buffer(VIDC_HIGH, "alloc: persist2_buffer", inst, &cvp->persist2_buffer); /* set buffer */ @@ -505,7 +505,7 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst) inst, &cvp->output_buffer); goto error; } - print_cvp_buffer(VIDC_DBG, "alloc: output_buffer", + print_cvp_buffer(VIDC_HIGH, "alloc: output_buffer", inst, &cvp->output_buffer); return rc; @@ -711,7 +711,7 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, skipframe = !(cvp->framecount % skip_framecount); } if (skipframe) { - print_cvp_buffer(VIDC_DBG, "input frame skipped", + print_cvp_buffer(VIDC_LOW, "input frame skipped", inst, &cvp->fullres_buffer); cvp->framecount++; cvp->metadata_available = false; @@ -754,7 +754,7 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, frame->refframe_contextbuffer.buffer_addr = cvp->refcontext_buffer.fd; frame->refframe_contextbuffer.size = cvp->refcontext_buffer.size; - print_cvp_buffer(VIDC_DBG, "input frame", inst, &cvp->fullres_buffer); + print_cvp_buffer(VIDC_LOW, "input frame", inst, &cvp->fullres_buffer); rc = msm_cvp_private(cvp->priv, CVP_KMD_SEND_CMD_PKT, arg); if (rc) { print_cvp_buffer(VIDC_ERR, "send failed: input frame", @@ -825,7 +825,7 @@ static int msm_vidc_cvp_deinit(struct msm_vidc_inst *inst) } cvp = inst->cvp; - dprintk(VIDC_DBG, "%s: cvp session %#x\n", __func__, cvp->session_id); + dprintk(VIDC_HIGH, "%s: cvp session %#x\n", __func__, cvp->session_id); msm_cvp_deinit_internal_buffers(inst); msm_cvp_deinit_context_buffers(inst); msm_cvp_deinit_downscale_buffers(inst); @@ -844,7 +844,7 @@ static int msm_vidc_cvp_close(struct msm_vidc_inst *inst) } cvp = inst->cvp; - dprintk(VIDC_DBG, "%s: cvp session %#x\n", __func__, cvp->session_id); + dprintk(VIDC_HIGH, "%s: cvp session %#x\n", __func__, cvp->session_id); rc = msm_cvp_close(cvp->priv); if (rc) dprintk(VIDC_ERR, @@ -866,7 +866,7 @@ int msm_vidc_cvp_unprepare_preprocess(struct msm_vidc_inst *inst) return -EINVAL; } if (!inst->cvp) { - dprintk(VIDC_DBG, "%s: cvp not enabled or closed\n", __func__); + dprintk(VIDC_HIGH, "%s: cvp not enabled or closed\n", __func__); return 0; } @@ -904,7 +904,7 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst) if (rc) goto error; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: pixelformat %#x, wxh %dx%d downscale %d ds_wxh %dx%d\n", __func__, f->fmt.pix_mp.pixelformat, cvp->width, cvp->height, cvp->downscale, @@ -985,7 +985,7 @@ static int msm_vidc_cvp_open(struct msm_vidc_inst *inst) } arg = cvp->arg; - dprintk(VIDC_DBG, "%s: opening cvp\n", __func__); + dprintk(VIDC_HIGH, "%s: opening cvp\n", __func__); cvp->priv = msm_cvp_open(0, MSM_VIDC_CVP); if (!cvp->priv) { dprintk(VIDC_ERR, "%s: failed to open cvp session\n", __func__); @@ -1001,7 +1001,7 @@ static int msm_vidc_cvp_open(struct msm_vidc_inst *inst) goto error; } cvp->session_id = arg->data.session.session_id; - dprintk(VIDC_DBG, "%s: cvp session id %#x\n", + dprintk(VIDC_HIGH, "%s: cvp session id %#x\n", __func__, cvp->session_id); return 0; diff --git a/msm/vidc/msm_cvp_internal.c b/msm/vidc/msm_cvp_internal.c index 60eda88e254e..e5ae10750404 100644 --- a/msm/vidc/msm_cvp_internal.c +++ b/msm/vidc/msm_cvp_internal.c @@ -94,7 +94,7 @@ void handle_session_register_buffer_done(enum hal_command_response cmd, __func__, response->data.regbuf.client_data); goto exit; } - print_cvp_buffer(VIDC_DBG, "register_done", inst, cbuf); + print_cvp_buffer(VIDC_HIGH, "register_done", inst, cbuf); event.type = V4L2_EVENT_MSM_VIDC_REGISTER_BUFFER_DONE; data = (u32 *)event.u.data; @@ -146,7 +146,7 @@ void handle_session_unregister_buffer_done(enum hal_command_response cmd, __func__, response->data.unregbuf.client_data); goto exit; } - print_cvp_buffer(VIDC_DBG, "unregister_done", inst, cbuf); + print_cvp_buffer(VIDC_HIGH, "unregister_done", inst, cbuf); rc = inst->smem_ops->smem_unmap_dma_buf(inst, &cbuf->smem); if (rc) { @@ -262,7 +262,7 @@ static int msm_cvp_get_session_info(struct msm_vidc_inst *inst, } session->session_id = hash32_ptr(inst->session); - dprintk(VIDC_DBG, "%s: id 0x%x\n", __func__, session->session_id); + dprintk(VIDC_HIGH, "%s: id 0x%x\n", __func__, session->session_id); return rc; } @@ -277,7 +277,7 @@ static int msm_cvp_request_power(struct msm_vidc_inst *inst, return -EINVAL; } - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: clock_cycles_a %d, clock_cycles_b %d, ddr_bw %d sys_cache_bw %d\n", __func__, power->clock_cycles_a, power->clock_cycles_b, power->ddr_bw, power->sys_cache_bw); @@ -344,7 +344,7 @@ static int msm_cvp_register_buffer(struct msm_vidc_inst *inst, return -EINVAL; } hdev = inst->core->device; - print_client_buffer(VIDC_DBG, "register", inst, buf); + print_client_buffer(VIDC_HIGH, "register", inst, buf); mutex_lock(&inst->cvpbufs.lock); found = false; @@ -423,7 +423,7 @@ static int msm_cvp_unregister_buffer(struct msm_vidc_inst *inst, return -EINVAL; } hdev = inst->core->device; - print_client_buffer(VIDC_DBG, "unregister", inst, buf); + print_client_buffer(VIDC_HIGH, "unregister", inst, buf); mutex_lock(&inst->cvpbufs.lock); found = false; @@ -576,7 +576,7 @@ int msm_cvp_inst_deinit(struct msm_vidc_inst *inst) dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; } - dprintk(VIDC_DBG, "%s: inst %pK (%#x)\n", __func__, + dprintk(VIDC_HIGH, "%s: inst %pK (%#x)\n", __func__, inst, hash32_ptr(inst->session)); rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE); @@ -614,7 +614,7 @@ int msm_cvp_inst_init(struct msm_vidc_inst *inst) return -EINVAL; } - dprintk(VIDC_DBG, "%s: inst %pK (%#x)\n", __func__, + dprintk(VIDC_HIGH, "%s: inst %pK (%#x)\n", __func__, inst, hash32_ptr(inst->session)); /* set default frequency */ diff --git a/msm/vidc/msm_smem.c b/msm/vidc/msm_smem.c index f9336347f99d..6a748bf09647 100644 --- a/msm/vidc/msm_smem.c +++ b/msm/vidc/msm_smem.c @@ -111,7 +111,7 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, unsigned long align, trace_msm_smem_buffer_iommu_op_end("MAP", 0, 0, align, *iova, *buffer_size); } else { - dprintk(VIDC_DBG, "iommu not present, use phys mem addr\n"); + dprintk(VIDC_HIGH, "iommu not present, use phys mem addr\n"); } return 0; @@ -132,14 +132,14 @@ static int msm_dma_put_device_address(u32 flags, int rc = 0; if (!mapping_info) { - dprintk(VIDC_WARN, "Invalid mapping_info\n"); + dprintk(VIDC_ERR, "Invalid mapping_info\n"); return -EINVAL; } if (!mapping_info->dev || !mapping_info->table || !mapping_info->buf || !mapping_info->attach || !mapping_info->cb_info) { - dprintk(VIDC_WARN, "Invalid params\n"); + dprintk(VIDC_ERR, "Invalid params\n"); return -EINVAL; } @@ -263,7 +263,7 @@ int msm_smem_unmap_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) if (smem->refcount) { smem->refcount--; } else { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "unmap called while refcount is zero already\n"); return -EINVAL; } @@ -344,13 +344,13 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, if (is_iommu_present(res)) { if (flags & SMEM_ADSP) { - dprintk(VIDC_DBG, "Allocating from ADSP heap\n"); + dprintk(VIDC_HIGH, "Allocating from ADSP heap\n"); heap_mask = ION_HEAP(ION_ADSP_HEAP_ID); } else { heap_mask = ION_HEAP(ION_SYSTEM_HEAP_ID); } } else { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "allocate shared memory from adsp heap size %zx align %d\n", size, align); heap_mask = ION_HEAP(ION_ADSP_HEAP_ID); @@ -427,7 +427,7 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, } } - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, buffer_type = %#x, flags = %#lx\n", __func__, mem->dma_buf, mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type, mem->flags); @@ -444,7 +444,7 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, static int free_dma_mem(struct msm_smem *mem) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, buffer_type = %#x\n", __func__, mem->dma_buf, mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type); diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index 24aaf7c2476f..fd64cee4d061 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -391,11 +391,11 @@ static ssize_t thermal_level_store(struct device *dev, rc = kstrtoint(buf, 0, &val); if (rc || val < 0) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Invalid thermal level value: %s\n", buf); return -EINVAL; } - dprintk(VIDC_DBG, "Thermal level old %d new %d\n", + dprintk(VIDC_HIGH, "Thermal level old %d new %d\n", vidc_driver->thermal_level, val); if (val == vidc_driver->thermal_level) @@ -551,7 +551,7 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) if (rc != -EPROBE_DEFER) dprintk(VIDC_ERR, "Failed to create HFI device\n"); else - dprintk(VIDC_DBG, "msm_vidc: request probe defer\n"); + dprintk(VIDC_HIGH, "msm_vidc: request probe defer\n"); goto err_cores_exceeded; } @@ -564,7 +564,7 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) vidc_driver->sku_version = core->resources.sku_version; - dprintk(VIDC_DBG, "populating sub devices\n"); + dprintk(VIDC_HIGH, "populating sub devices\n"); /* * Trigger probe for each sub-device i.e. qcom,msm-vidc,context-bank. * When msm_vidc_probe is called for each sub-device, parse the @@ -709,7 +709,7 @@ static int msm_vidc_pm_suspend(struct device *dev) if (rc == -ENOTSUPP) rc = 0; else if (rc) - dprintk(VIDC_WARN, "Failed to suspend: %d\n", rc); + dprintk(VIDC_ERR, "Failed to suspend: %d\n", rc); return rc; @@ -717,7 +717,7 @@ static int msm_vidc_pm_suspend(struct device *dev) static int msm_vidc_pm_resume(struct device *dev) { - dprintk(VIDC_INFO, "%s\n", __func__); + dprintk(VIDC_HIGH, "%s\n", __func__); return 0; } diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index d95626e3ba64..19b741c3f659 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -711,7 +711,7 @@ int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) sizeof(f->description)); f->pixelformat = fmt_desc->fourcc; } else { - dprintk(VIDC_DBG, "No more formats found\n"); + dprintk(VIDC_HIGH, "No more formats found\n"); rc = -EINVAL; } return rc; @@ -789,7 +789,7 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) is_decode_session(temp) && !is_thumbnail_session(temp)) { inst->decode_batching = false; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Disable decode-batching in multi sessions\n"); break; } @@ -833,7 +833,7 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) return -EINVAL; } - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: %x : control name = %s, id = 0x%x value = %d\n", __func__, hash32_ptr(inst->session), ctrl->name, ctrl->id, ctrl->val); @@ -937,7 +937,7 @@ int msm_vdec_set_frame_size(struct msm_vidc_inst *inst) frame_size.buffer_type = HFI_BUFFER_INPUT; frame_size.width = f->fmt.pix_mp.width; frame_size.height = f->fmt.pix_mp.height; - dprintk(VIDC_DBG, "%s: input wxh %dx%d\n", __func__, + dprintk(VIDC_HIGH, "%s: input wxh %dx%d\n", __func__, frame_size.width, frame_size.height); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_FRAME_SIZE, &frame_size, sizeof(frame_size)); @@ -1075,7 +1075,7 @@ int msm_vdec_set_profile_level(struct msm_vidc_inst *inst) profile_level.profile = inst->profile; profile_level.level = inst->level; - dprintk(VIDC_DBG, "%s: %#x %#x\n", __func__, + dprintk(VIDC_HIGH, "%s: %#x %#x\n", __func__, profile_level.profile, profile_level.level); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT, &profile_level, @@ -1100,7 +1100,7 @@ int msm_vdec_set_output_order(struct msm_vidc_inst *inst) hdev = inst->core->device; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER); - dprintk(VIDC_DBG, "%s: %d\n", __func__, ctrl->val); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, ctrl->val); if (ctrl->val == V4L2_MPEG_MSM_VIDC_ENABLE) output_order = HFI_OUTPUT_ORDER_DECODE; else @@ -1131,7 +1131,7 @@ int msm_vdec_set_sync_frame_mode(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE); hfi_property.enable = (bool)ctrl->val; - dprintk(VIDC_DBG, "%s: %#x\n", __func__, hfi_property.enable); + dprintk(VIDC_HIGH, "%s: %#x\n", __func__, hfi_property.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VDEC_THUMBNAIL_MODE, &hfi_property, sizeof(hfi_property)); @@ -1169,7 +1169,7 @@ int msm_vdec_set_secure_mode(struct msm_vidc_inst *inst) } } - dprintk(VIDC_DBG, "%s: %#x\n", __func__, ctrl->val); + dprintk(VIDC_HIGH, "%s: %#x\n", __func__, ctrl->val); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_SECURE_SESSION, &ctrl->val, sizeof(u32)); if (rc) @@ -1247,7 +1247,7 @@ int msm_vdec_set_output_stream_mode(struct msm_vidc_inst *inst) f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; frame_sz.width = f->fmt.pix_mp.width; frame_sz.height = f->fmt.pix_mp.height; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "frame_size: hal buffer type %d, width %d, height %d\n", frame_sz.buffer_type, frame_sz.width, frame_sz.height); rc = call_hfi_op(hdev, session_set_property, inst->session, @@ -1280,7 +1280,7 @@ int msm_vdec_set_priority(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY); hfi_property.enable = (bool)ctrl->val; - dprintk(VIDC_DBG, "%s: %#x\n", __func__, hfi_property.enable); + dprintk(VIDC_HIGH, "%s: %#x\n", __func__, hfi_property.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_REALTIME, &hfi_property, sizeof(hfi_property)); @@ -1309,7 +1309,7 @@ int msm_vdec_set_operating_rate(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE); operating_rate.operating_rate = ctrl->val; - dprintk(VIDC_DBG, "%s: %#x\n", __func__, + dprintk(VIDC_HIGH, "%s: %#x\n", __func__, operating_rate.operating_rate); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_OPERATING_RATE, &operating_rate, @@ -1339,7 +1339,7 @@ int msm_vdec_set_conceal_color(struct msm_vidc_inst *inst) conceal_color.conceal_color_8bit = ctrl_8b->val; conceal_color.conceal_color_10bit = ctrl_10b->val; - dprintk(VIDC_DBG, "%s: %#x %#x\n", __func__, + dprintk(VIDC_HIGH, "%s: %#x %#x\n", __func__, conceal_color.conceal_color_8bit, conceal_color.conceal_color_10bit); rc = call_hfi_op(hdev, session_set_property, inst->session, @@ -1474,7 +1474,7 @@ int msm_vdec_set_properties(struct msm_vidc_inst *inst) if (rc) dprintk(VIDC_ERR, "%s: failed with %d\n", __func__, rc); else - dprintk(VIDC_DBG, "%s: set properties successful\n", __func__); + dprintk(VIDC_HIGH, "%s: set properties successful\n", __func__); return rc; } diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 595b714c784f..93fac1508e73 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1154,7 +1154,7 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) sizeof(f->description)); f->pixelformat = fmt_desc->fourcc; } else { - dprintk(VIDC_DBG, "No more formats found\n"); + dprintk(VIDC_HIGH, "No more formats found\n"); rc = -EINVAL; } return rc; @@ -1370,7 +1370,7 @@ static int msm_venc_resolve_rc_enable(struct msm_vidc_inst *inst, u32 codec; if (!ctrl->val) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "RC is not enabled. Setting RC OFF\n"); inst->rc_type = RATE_CONTROL_OFF; } else { @@ -1382,7 +1382,7 @@ static int msm_venc_resolve_rc_enable(struct msm_vidc_inst *inst, if (msm_vidc_lossless_encode && (codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264)) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Reset RC mode to RC_LOSSLESS for HEVC lossless encoding\n"); inst->rc_type = RATE_CONTROL_LOSSLESS; } @@ -1393,7 +1393,7 @@ static int msm_venc_resolve_rate_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) { if (inst->rc_type == RATE_CONTROL_LOSSLESS) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Skip RC mode when enabling lossless encoding\n"); return 0; } @@ -1431,7 +1431,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) cll_sei = &(inst->hdr10_sei_params.cll_sei); codec = get_v4l2_codec(inst); - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: %x : name %s, id 0x%x value %d\n", __func__, hash32_ptr(inst->session), ctrl->name, ctrl->id, ctrl->val); @@ -1537,7 +1537,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) u32 info_type = ((u32)ctrl->val >> 28) & 0xF; u32 val = (ctrl->val & 0xFFFFFFF); - dprintk(VIDC_DBG, "Ctrl:%d, HDR Info with value %u (%#X)", + dprintk(VIDC_HIGH, "Ctrl:%d, HDR Info with value %u (%#X)", info_type, val, ctrl->val); switch (info_type) { case MSM_VIDC_RGB_PRIMARY_00: @@ -1767,7 +1767,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER: case V4L2_CID_MPEG_VIDC_VENC_RC_TIMESTAMP_DISABLE: case V4L2_CID_MPEG_VIDEO_VBV_DELAY: - dprintk(VIDC_DBG, "Control set: ID : %x Val : %d\n", + dprintk(VIDC_HIGH, "Control set: ID : %x Val : %d\n", ctrl->id, ctrl->val); break; default: @@ -1796,7 +1796,7 @@ int msm_venc_set_frame_size(struct msm_vidc_inst *inst) frame_sz.buffer_type = HFI_BUFFER_INPUT; frame_sz.width = f->fmt.pix_mp.width; frame_sz.height = f->fmt.pix_mp.height; - dprintk(VIDC_DBG, "%s: input %d %d\n", __func__, + dprintk(VIDC_HIGH, "%s: input %d %d\n", __func__, frame_sz.width, frame_sz.height); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_FRAME_SIZE, &frame_sz, sizeof(frame_sz)); @@ -1810,7 +1810,7 @@ int msm_venc_set_frame_size(struct msm_vidc_inst *inst) frame_sz.buffer_type = HFI_BUFFER_OUTPUT; frame_sz.width = f->fmt.pix_mp.width; frame_sz.height = f->fmt.pix_mp.height; - dprintk(VIDC_DBG, "%s: output %d %d\n", __func__, + dprintk(VIDC_HIGH, "%s: output %d %d\n", __func__, frame_sz.width, frame_sz.height); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_FRAME_SIZE, &frame_sz, sizeof(frame_sz)); @@ -1839,7 +1839,7 @@ int msm_venc_set_frame_rate(struct msm_vidc_inst *inst) frame_rate.buffer_type = HFI_BUFFER_OUTPUT; frame_rate.frame_rate = inst->clk_data.frame_rate; - dprintk(VIDC_DBG, "%s: %#x\n", __func__, frame_rate.frame_rate); + dprintk(VIDC_HIGH, "%s: %#x\n", __func__, frame_rate.frame_rate); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_FRAME_RATE, @@ -1946,7 +1946,7 @@ int msm_venc_set_secure_mode(struct msm_vidc_inst *inst) } } - dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_SECURE_SESSION, &enable, sizeof(enable)); if (rc) @@ -1971,7 +1971,7 @@ int msm_venc_set_priority(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY); enable.enable = !!ctrl->val; - dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_REALTIME, &enable, sizeof(enable)); if (rc) @@ -1996,7 +1996,7 @@ int msm_venc_set_operating_rate(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE); op_rate.operating_rate = ctrl->val; - dprintk(VIDC_DBG, "%s: %d\n", __func__, op_rate.operating_rate >> 16); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, op_rate.operating_rate >> 16); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_OPERATING_RATE, &op_rate, sizeof(op_rate)); if (rc) { @@ -2028,7 +2028,7 @@ int msm_venc_set_profile_level(struct msm_vidc_inst *inst) profile_level.profile = inst->profile; profile_level.level = inst->level; - dprintk(VIDC_DBG, "%s: %#x %#x\n", __func__, + dprintk(VIDC_HIGH, "%s: %#x %#x\n", __func__, profile_level.profile, profile_level.level); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT, &profile_level, @@ -2058,7 +2058,7 @@ int msm_venc_set_idr_period(struct msm_vidc_inst *inst) idr_period.idr_period = 1; - dprintk(VIDC_DBG, "%s: %d\n", __func__, idr_period.idr_period); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, idr_period.idr_period); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD, &idr_period, sizeof(idr_period)); @@ -2126,7 +2126,7 @@ void msm_venc_decide_bframe(struct msm_vidc_inst *inst) */ inst->prop.bframe_changed = true; bframe_ctrl->val = MAX_NUM_B_FRAMES; - dprintk(VIDC_DBG, "Bframe is forcefully enabled\n"); + dprintk(VIDC_HIGH, "Bframe is forcefully enabled\n"); } else { /* * Native recorder is not enabled @@ -2135,7 +2135,7 @@ void msm_venc_decide_bframe(struct msm_vidc_inst *inst) goto disable_bframe; } } - dprintk(VIDC_DBG, "Bframe can be enabled!\n"); + dprintk(VIDC_HIGH, "Bframe can be enabled!\n"); return; disable_bframe: @@ -2147,9 +2147,9 @@ void msm_venc_decide_bframe(struct msm_vidc_inst *inst) */ inst->prop.bframe_changed = true; bframe_ctrl->val = 0; - dprintk(VIDC_DBG, "Bframe is forcefully disabled!\n"); + dprintk(VIDC_HIGH, "Bframe is forcefully disabled!\n"); } else { - dprintk(VIDC_DBG, "Bframe is disabled\n"); + dprintk(VIDC_HIGH, "Bframe is disabled\n"); } } @@ -2167,7 +2167,7 @@ int msm_venc_set_adaptive_bframes(struct msm_vidc_inst *inst) enable.enable = true; - dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_ADAPTIVE_B, &enable, sizeof(enable)); if (rc) @@ -2243,7 +2243,7 @@ int msm_venc_set_intra_period(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); intra_period.bframes = ctrl->val; - dprintk(VIDC_DBG, "%s: %d %d\n", __func__, intra_period.pframes, + dprintk(VIDC_HIGH, "%s: %d %d\n", __func__, intra_period.pframes, intra_period.bframes); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD, &intra_period, @@ -2276,7 +2276,7 @@ int msm_venc_set_request_keyframe(struct msm_vidc_inst *inst) } hdev = inst->core->device; - dprintk(VIDC_DBG, "%s\n", __func__); + dprintk(VIDC_HIGH, "%s\n", __func__); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME, NULL, 0); if (rc) { @@ -2344,7 +2344,7 @@ int msm_venc_set_rate_control(struct msm_vidc_inst *inst) inst->rc_type); break; } - dprintk(VIDC_DBG, "%s: %d\n", __func__, inst->rc_type); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, inst->rc_type); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_RATE_CONTROL, &hfi_rc, sizeof(u32)); @@ -2419,7 +2419,7 @@ int msm_venc_set_vbv_delay(struct msm_vidc_inst *inst) } set_vbv_delay: - dprintk(VIDC_DBG, "Set hrd_buf_size %d", + dprintk(VIDC_HIGH, "Set hrd_buf_size %d", hrd_buf_size.vbv_hrd_buf_size); rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, @@ -2456,7 +2456,7 @@ int msm_venc_set_input_timestamp_rc(struct msm_vidc_inst *inst) */ enable.enable = !!ctrl->val; - dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_DISABLE_RC_TIMESTAMP, &enable, sizeof(enable)); @@ -2481,12 +2481,12 @@ int msm_venc_set_bitrate(struct msm_vidc_inst *inst) hdev = inst->core->device; if (inst->layer_bitrate) { - dprintk(VIDC_DBG, "%s: Layer bitrate is enabled\n", __func__); + dprintk(VIDC_HIGH, "%s: Layer bitrate is enabled\n", __func__); return 0; } enable.enable = 0; - dprintk(VIDC_DBG, "%s: bitrate type: %d\n", + dprintk(VIDC_HIGH, "%s: bitrate type: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_BITRATE_TYPE, &enable, @@ -2499,7 +2499,7 @@ int msm_venc_set_bitrate(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE); bitrate.bit_rate = ctrl->val; bitrate.layer_id = MSM_VIDC_ALL_LAYER_ID; - dprintk(VIDC_DBG, "%s: %d\n", __func__, bitrate.bit_rate); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, bitrate.bit_rate); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE, &bitrate, sizeof(bitrate)); @@ -2532,14 +2532,14 @@ int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst) V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); if (!max_layer->val || !layer->val) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: Hierp layer not set. Ignore layer bitrate\n", __func__); goto error; } if (max_layer->val < layer->val) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: Hierp layer greater than max isn't allowed\n", __func__); goto error; @@ -2561,7 +2561,7 @@ int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst) /* Set layer bitrates only when highest layer br ratio is 100. */ if (layer_br_ratios[layer->val-1]->val != MAX_BIT_RATE_RATIO || layer_br_ratios[0]->val == 0) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: Improper layer bitrate ratio\n", __func__); goto error; @@ -2569,7 +2569,7 @@ int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst) for (i = layer->val - 1; i > 0; --i) { if (layer_br_ratios[i]->val == 0) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: Layer ratio must be non-zero\n", __func__); goto error; @@ -2578,7 +2578,7 @@ int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst) } enable.enable = 1; - dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_BITRATE_TYPE, &enable, sizeof(enable)); @@ -2592,7 +2592,7 @@ int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst) layer_br.bit_rate = bitrate->val * layer_br_ratios[i]->val / 100; layer_br.layer_id = i; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: Bitrate for Layer[%u]: [%u]\n", __func__, layer_br.layer_id, layer_br.bit_rate); @@ -2657,7 +2657,7 @@ int msm_venc_set_frame_qp(struct msm_vidc_inst *inst) return 0; } else { if (!(inst->client_set_ctrls & CLIENT_SET_I_QP)) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "%s: Client value is not valid\n", __func__); return -EINVAL; } @@ -2673,7 +2673,7 @@ int msm_venc_set_frame_qp(struct msm_vidc_inst *inst) qp.qp_packed = i_qp->val | p_qp->val << 8 | b_qp->val << 16; - dprintk(VIDC_DBG, "%s: layers %#x frames %#x qp_packed %#x\n", + dprintk(VIDC_HIGH, "%s: layers %#x frames %#x qp_packed %#x\n", __func__, qp.layer_id, qp.enable, qp.qp_packed); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_FRAME_QP, &qp, sizeof(qp)); @@ -2698,7 +2698,7 @@ int msm_venc_set_qp_range(struct msm_vidc_inst *inst) if (!(inst->client_set_ctrls & CLIENT_SET_MIN_QP) && !(inst->client_set_ctrls & CLIENT_SET_MAX_QP)) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: Client didn't set QP range.\n", __func__); return 0; } @@ -2712,7 +2712,7 @@ int msm_venc_set_qp_range(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP); qp_range.max_qp.qp_packed = ctrl->val; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: layers %#x qp_min %#x qp_max %#x\n", __func__, qp_range.min_qp.layer_id, qp_range.min_qp.qp_packed, qp_range.max_qp.qp_packed); @@ -2744,7 +2744,7 @@ int msm_venc_set_frame_quality(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY); frame_quality.frame_quality = ctrl->val; - dprintk(VIDC_DBG, "%s: %d\n", __func__, frame_quality.frame_quality); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, frame_quality.frame_quality); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_HEIC_FRAME_QUALITY, &frame_quality, sizeof(frame_quality)); @@ -2778,7 +2778,7 @@ int msm_venc_set_grid(struct msm_vidc_inst *inst) else grid_enable.grid_enable = true; - dprintk(VIDC_DBG, "%s: %d\n", __func__, grid_enable.grid_enable); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, grid_enable.grid_enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_HEIC_GRID_ENABLE, &grid_enable, sizeof(grid_enable)); @@ -2810,7 +2810,7 @@ int msm_venc_set_entropy_mode(struct msm_vidc_inst *inst) ctrl->val); entropy.cabac_model = HFI_H264_CABAC_MODEL_2; - dprintk(VIDC_DBG, "%s: %d\n", __func__, entropy.entropy_mode); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, entropy.entropy_mode); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL, &entropy, sizeof(entropy)); @@ -2916,7 +2916,7 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst) multi_slice_control.slice_size = slice_val; hdev = inst->core->device; - dprintk(VIDC_DBG, "%s: %d %d\n", __func__, + dprintk(VIDC_HIGH, "%s: %d %d\n", __func__, multi_slice_control.multi_slice, multi_slice_control.slice_size); rc = call_hfi_op(hdev, session_set_property, inst->session, @@ -2972,7 +2972,7 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst) intra_refresh.mbs = 0; } - dprintk(VIDC_DBG, "%s: %d %d\n", __func__, + dprintk(VIDC_HIGH, "%s: %d %d\n", __func__, intra_refresh.mode, intra_refresh.mbs); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH, &intra_refresh, @@ -2999,12 +2999,12 @@ int msm_venc_set_bitrate_savings_mode(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS); enable.enable = !!ctrl->val; if (!ctrl->val && inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Can't disable bitrate savings for non-VBR_CFR\n"); enable.enable = 1; } - dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_BITRATE_SAVINGS, &enable, sizeof(enable)); @@ -3041,7 +3041,7 @@ int msm_venc_set_loop_filter_mode(struct msm_vidc_inst *inst) h264_db_control.slice_alpha_offset = ctrl_a->val; h264_db_control.slice_beta_offset = ctrl_b->val; - dprintk(VIDC_DBG, "%s: %d %d %d\n", __func__, + dprintk(VIDC_HIGH, "%s: %d %d %d\n", __func__, h264_db_control.mode, h264_db_control.slice_alpha_offset, h264_db_control.slice_beta_offset); rc = call_hfi_op(hdev, session_set_property, inst->session, @@ -3077,7 +3077,7 @@ int msm_venc_set_sequence_header_mode(struct msm_vidc_inst *inst) else enable.enable = false; - dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER, &enable, sizeof(enable)); @@ -3108,7 +3108,7 @@ int msm_venc_set_au_delimiter_mode(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_AU_DELIMITER); enable.enable = !!ctrl->val; - dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_GENERATE_AUDNAL, &enable, sizeof(enable)); @@ -3175,7 +3175,7 @@ int msm_venc_set_base_layer_priority_id(struct msm_vidc_inst *inst) max_layer = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); if (max_layer->val <= 0) { - dprintk(VIDC_DBG, "%s: Layer id can only be set with Hierp\n", + dprintk(VIDC_HIGH, "%s: Layer id can only be set with Hierp\n", __func__); return 0; } @@ -3183,7 +3183,7 @@ int msm_venc_set_base_layer_priority_id(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID); baselayerid = ctrl->val; - dprintk(VIDC_DBG, "%s: %d\n", __func__, baselayerid); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, baselayerid); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_BASELAYER_PRIORITYID, &baselayerid, sizeof(baselayerid)); @@ -3229,13 +3229,13 @@ int msm_venc_set_hp_max_layer(struct msm_vidc_inst *inst) hp_layer = ctrl->val - 1; if (inst->hybrid_hp) { - dprintk(VIDC_DBG, "%s: Hybrid hierp layer: %d\n", + dprintk(VIDC_HIGH, "%s: Hybrid hierp layer: %d\n", __func__, hp_layer); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_HIER_P_HYBRID_MODE, &hp_layer, sizeof(hp_layer)); } else { - dprintk(VIDC_DBG, "%s: Hierp max layer: %d\n", + dprintk(VIDC_HIGH, "%s: Hierp max layer: %d\n", __func__, hp_layer); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER, @@ -3267,7 +3267,7 @@ int msm_venc_set_hp_layer(struct msm_vidc_inst *inst) return 0; if (inst->hybrid_hp) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "%s: Setting layer isn't allowed with hybrid hp\n", __func__); return 0; @@ -3279,7 +3279,7 @@ int msm_venc_set_hp_layer(struct msm_vidc_inst *inst) V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); if (max_layer->val < ctrl->val) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "%s: HP layer count greater than max isn't allowed\n", __func__); return 0; @@ -3292,7 +3292,7 @@ int msm_venc_set_hp_layer(struct msm_vidc_inst *inst) if (ctrl->val) hp_layer = ctrl->val - 1; - dprintk(VIDC_DBG, "%s: Hierp enhancement layer: %d\n", + dprintk(VIDC_HIGH, "%s: Hierp enhancement layer: %d\n", __func__, hp_layer); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER, @@ -3323,7 +3323,7 @@ int msm_venc_set_vpx_error_resilience(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE); enable.enable = !!ctrl->val; - dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_VPX_ERROR_RESILIENCE_MODE, &enable, sizeof(enable)); @@ -3369,7 +3369,7 @@ int msm_venc_set_video_signal_info(struct msm_vidc_inst *inst) signal_info.transfer_characteristics = ctrl_tr->val; signal_info.matrix_coeffs = ctrl_mc->val; - dprintk(VIDC_DBG, "%s: %d %d %d %d\n", __func__, + dprintk(VIDC_HIGH, "%s: %d %d %d %d\n", __func__, signal_info.color_primaries, signal_info.video_full_range, signal_info.transfer_characteristics, signal_info.matrix_coeffs); @@ -3415,7 +3415,7 @@ int msm_venc_set_rotation(struct msm_vidc_inst *inst) else if (vflip->val == V4L2_MPEG_MSM_VIDC_ENABLE) vpe_rotation.flip = HFI_FLIP_VERTICAL; - dprintk(VIDC_DBG, "Set rotation = %d, flip = %d\n", + dprintk(VIDC_HIGH, "Set rotation = %d, flip = %d\n", vpe_rotation.rotation, vpe_rotation.flip); rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, @@ -3479,14 +3479,14 @@ int msm_venc_set_8x8_transform(struct msm_vidc_inst *inst) hdev = inst->core->device; if (get_v4l2_codec(inst) != V4L2_PIX_FMT_H264) { - dprintk(VIDC_DBG, "%s: skip as codec is not H264\n", + dprintk(VIDC_HIGH, "%s: skip as codec is not H264\n", __func__); return 0; } if (inst->profile != HFI_H264_PROFILE_HIGH && inst->profile != HFI_H264_PROFILE_CONSTRAINED_HIGH) { - dprintk(VIDC_DBG, "%s: skip due to %#x\n", + dprintk(VIDC_HIGH, "%s: skip due to %#x\n", __func__, inst->profile); return 0; } @@ -3494,7 +3494,7 @@ int msm_venc_set_8x8_transform(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM); enable.enable = !!ctrl->val; - dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_H264_8X8_TRANSFORM, &enable, sizeof(enable)); @@ -3542,7 +3542,7 @@ int msm_venc_set_vui_timing_info(struct msm_vidc_inst *inst) timing_info.fixed_frame_rate = cfr; timing_info.time_scale = NSEC_PER_SEC; - dprintk(VIDC_DBG, "%s: %d %d\n", __func__, timing_info.enable, + dprintk(VIDC_HIGH, "%s: %d %d\n", __func__, timing_info.enable, timing_info.fixed_frame_rate); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_VUI_TIMING_INFO, &timing_info, @@ -3591,7 +3591,7 @@ int msm_venc_set_nal_stream_format(struct msm_vidc_inst *inst) break; } - dprintk(VIDC_DBG, "%s: %#x\n", __func__, + dprintk(VIDC_HIGH, "%s: %#x\n", __func__, stream_format.nal_stream_format_select); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT, &stream_format, @@ -3637,7 +3637,7 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) ltr.ltr_count = ctrl->val; ltr.ltr_mode = HFI_LTR_MODE_MANUAL; ltr.trust_mode = 1; - dprintk(VIDC_DBG, "%s: %d %d\n", __func__, + dprintk(VIDC_HIGH, "%s: %d %d\n", __func__, ltr.ltr_mode, ltr.ltr_count); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_LTRMODE, <r, sizeof(ltr)); @@ -3669,7 +3669,7 @@ int msm_venc_set_ltr_useframe(struct msm_vidc_inst *inst) use_ltr.ref_ltr = ctrl->val; use_ltr.use_constrnt = false; use_ltr.frames = 0; - dprintk(VIDC_DBG, "%s: %d\n", __func__, use_ltr.ref_ltr); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, use_ltr.ref_ltr); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_USELTRFRAME, &use_ltr, sizeof(use_ltr)); @@ -3700,7 +3700,7 @@ int msm_venc_set_ltr_markframe(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME); mark_ltr.mark_frame = ctrl->val; - dprintk(VIDC_DBG, "%s: %d\n", __func__, mark_ltr.mark_frame); + dprintk(VIDC_HIGH, "%s: %d\n", __func__, mark_ltr.mark_frame); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME, &mark_ltr, sizeof(mark_ltr)); @@ -3736,7 +3736,7 @@ int msm_venc_set_dyn_qp(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (get_v4l2_codec(inst) == V4L2_PIX_FMT_VP8) qp.enable &= ~QP_ENABLE_B; - dprintk(VIDC_DBG, "%s: %#x\n", __func__, + dprintk(VIDC_HIGH, "%s: %#x\n", __func__, ctrl->val); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_FRAME_QP, &qp, sizeof(qp)); @@ -3774,7 +3774,7 @@ int msm_venc_set_aspect_ratio(struct msm_vidc_inst *inst) return 0; sar.aspect_height = ctrl->val; - dprintk(VIDC_DBG, "%s: %d %d\n", __func__, + dprintk(VIDC_HIGH, "%s: %d %d\n", __func__, sar.aspect_width, sar.aspect_height); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_ASPECT_RATIO, &sar, sizeof(sar)); @@ -3802,7 +3802,7 @@ int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst) frame_sz.buffer_type = HFI_BUFFER_INPUT; frame_sz.height = ctrl->val & 0xFFFF; frame_sz.width = (ctrl->val & 0x7FFF0000) >> 16; - dprintk(VIDC_DBG, "%s: type %u, height %u, width %u\n", __func__, + dprintk(VIDC_HIGH, "%s: type %u, height %u, width %u\n", __func__, frame_sz.buffer_type, frame_sz.height, frame_sz.width); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_BLUR_FRAME_SIZE, &frame_sz, @@ -3833,7 +3833,7 @@ int msm_venc_set_hdr_info(struct msm_vidc_inst *inst) return 0; /* No conversion to HFI needed as both structures are same */ - dprintk(VIDC_DBG, "%s: setting hdr info\n", __func__); + dprintk(VIDC_HIGH, "%s: setting hdr info\n", __func__); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_HDR10_PQ_SEI, &inst->hdr10_sei_params, sizeof(inst->hdr10_sei_params)); @@ -3884,7 +3884,7 @@ int msm_venc_set_extradata(struct msm_vidc_inst *inst) if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) value = 0x1; - dprintk(VIDC_DBG, "%s: CVP extradata %d\n", __func__, value); + dprintk(VIDC_HIGH, "%s: CVP extradata %d\n", __func__, value); rc = msm_comm_set_extradata(inst, HFI_PROPERTY_PARAM_VENC_CVP_METADATA_EXTRADATA, value); if (rc) @@ -3904,7 +3904,7 @@ int msm_venc_set_lossless(struct msm_vidc_inst *inst) if (inst->rc_type != RATE_CONTROL_LOSSLESS) return 0; - dprintk(VIDC_DBG, "%s: enable lossless encoding\n", __func__); + dprintk(VIDC_HIGH, "%s: enable lossless encoding\n", __func__); enable.enable = 1; rc = call_hfi_op(hdev, session_set_property, inst->session, @@ -4060,7 +4060,7 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) if (rc) dprintk(VIDC_ERR, "%s: failed with %d\n", __func__, rc); else - dprintk(VIDC_DBG, "%s: set properties successful\n", __func__); + dprintk(VIDC_HIGH, "%s: set properties successful\n", __func__); return rc; } diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c old mode 100644 new mode 100755 index 28080d6d30c7..3fc9233a6db5 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -152,7 +152,7 @@ int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *q_ctrl) else q_ctrl->flags = 0; - dprintk(VIDC_DBG, "query ctrl: %s: min %d, max %d, flags %#x\n", + dprintk(VIDC_HIGH, "query ctrl: %s: min %d, max %d, flags %#x\n", ctrl->name, q_ctrl->minimum, q_ctrl->maximum, q_ctrl->flags); return rc; } @@ -171,7 +171,7 @@ int msm_vidc_s_fmt(void *instance, struct v4l2_format *f) if (inst->session_type == MSM_VIDC_ENCODER) rc = msm_venc_s_fmt(instance, f); - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "s_fmt: %x : type %d wxh %dx%d pixelfmt %#x num_planes %d size[0] %d size[1] %d in_reconfig %d\n", hash32_ptr(inst->session), f->type, f->fmt.pix_mp.width, f->fmt.pix_mp.height, @@ -195,7 +195,7 @@ int msm_vidc_g_fmt(void *instance, struct v4l2_format *f) if (inst->session_type == MSM_VIDC_ENCODER) rc = msm_venc_g_fmt(instance, f); - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "g_fmt: %x : type %d wxh %dx%d pixelfmt %#x num_planes %d size[0] %d size[1] %d in_reconfig %d\n", hash32_ptr(inst->session), f->type, f->fmt.pix_mp.width, f->fmt.pix_mp.height, @@ -309,12 +309,12 @@ int msm_vidc_release_buffer(void *instance, int type, unsigned int index) continue; if (mbuf->flags & MSM_VIDC_FLAG_RBR_PENDING) { - print_vidc_buffer(VIDC_DBG, + print_vidc_buffer(VIDC_HIGH, "skip rel buf (rbr pending)", inst, mbuf); continue; } - print_vidc_buffer(VIDC_DBG, "release buf", inst, mbuf); + print_vidc_buffer(VIDC_HIGH, "release buf", inst, mbuf); msm_comm_unmap_vidc_buffer(inst, mbuf); list_del(&mbuf->list); kref_put_mbuf(mbuf); @@ -435,7 +435,7 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type i) "Failed to find buffer queue for type = %d\n", i); return -EINVAL; } - dprintk(VIDC_DBG, "Calling streamon\n"); + dprintk(VIDC_HIGH, "Calling streamon\n"); mutex_lock(&q->lock); rc = vb2_streamon(&q->vb2_bufq, i); mutex_unlock(&q->lock); @@ -464,7 +464,7 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i) } if (!inst->in_reconfig) { - dprintk(VIDC_DBG, "%s: inst %pK release resources\n", + dprintk(VIDC_HIGH, "%s: inst %pK release resources\n", __func__, inst); rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) @@ -473,7 +473,7 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i) __func__, inst); } - dprintk(VIDC_DBG, "Calling streamoff\n"); + dprintk(VIDC_HIGH, "Calling streamoff\n"); mutex_lock(&q->lock); rc = vb2_streamoff(&q->vb2_bufq, i); mutex_unlock(&q->lock); @@ -553,7 +553,7 @@ static void msm_vidc_cleanup_buffer(struct vb2_buffer *vb) } if (q->vb2_bufq.streaming) { - dprintk(VIDC_DBG, "%d PORT is streaming\n", + dprintk(VIDC_HIGH, "%d PORT is streaming\n", vb->type); return; } @@ -591,7 +591,7 @@ static int msm_vidc_queue_setup(struct vb2_queue *q, case INPUT_MPLANE: { fmt = &inst->fmts[INPUT_PORT]; if (*num_buffers < fmt->count_min_host) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Client passed num buffers %d less than the min_host count %d\n", *num_buffers, fmt->count_min_host); } @@ -612,7 +612,7 @@ static int msm_vidc_queue_setup(struct vb2_queue *q, if (inst->session_type != MSM_VIDC_DECODER && inst->state > MSM_VIDC_LOAD_RESOURCES_DONE) { if (*num_buffers < fmt->count_min_host) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Client passed num buffers %d less than the min_host count %d\n", *num_buffers, fmt->count_min_host); @@ -637,7 +637,7 @@ static int msm_vidc_queue_setup(struct vb2_queue *q, break; } - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "queue_setup: %x : type %d num_buffers %d num_planes %d sizes[0] %d sizes[1] %d\n", hash32_ptr(inst->session), q->type, *num_buffers, *num_planes, sizes[0], sizes[1]); @@ -652,7 +652,7 @@ static inline int msm_vidc_verify_buffer_counts(struct msm_vidc_inst *inst) if (inst->session_type == MSM_VIDC_DECODER && (inst->state < MSM_VIDC_LOAD_RESOURCES_DONE || inst->state >= MSM_VIDC_RELEASE_RESOURCES_DONE)) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "No need to verify buffer counts : %pK\n", inst); return 0; } @@ -661,7 +661,7 @@ static inline int msm_vidc_verify_buffer_counts(struct msm_vidc_inst *inst) struct hal_buffer_requirements *req = &inst->buff_req.buffer[i]; if (req && (req->buffer_type == HAL_BUFFER_OUTPUT)) { - dprintk(VIDC_DBG, "Verifying Buffer : %d\n", + dprintk(VIDC_HIGH, "Verifying Buffer : %d\n", req->buffer_type); if (req->buffer_count_actual < req->buffer_count_min_host || @@ -732,10 +732,10 @@ bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst) inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ && !inst->clk_data.is_legacy_cbr && !is_secure_session(inst)) { - dprintk(VIDC_DBG, "%s: cvp allowed\n", __func__); + dprintk(VIDC_HIGH, "%s: cvp allowed\n", __func__); allowed = true; } else { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: cvp not allowed, cvp_external %d cvp_disable %d extradata %#x rc_type %d legacy_cbr %d secure %d\n", __func__, core->resources.cvp_external, cvp_disable->val, inst->prop.extradata_ctrls, @@ -757,27 +757,27 @@ static int msm_vidc_prepare_preprocess(struct msm_vidc_inst *inst) } if (!msm_vidc_cvp_usage) { - dprintk(VIDC_DBG, "%s: cvp usage disabled\n", __func__); + dprintk(VIDC_HIGH, "%s: cvp usage disabled\n", __func__); return 0; } if (!is_vidc_cvp_allowed(inst)) { - dprintk(VIDC_DBG, "%s: cvp not allowed\n", __func__); + dprintk(VIDC_HIGH, "%s: cvp not allowed\n", __func__); return 0; } rc = msm_vidc_cvp_prepare_preprocess(inst); if (rc) { - dprintk(VIDC_WARN, "%s: no cvp preprocessing\n", __func__); + dprintk(VIDC_ERR, "%s: no cvp preprocessing\n", __func__); goto exit; } - dprintk(VIDC_DBG, "%s: cvp enabled\n", __func__); + dprintk(VIDC_HIGH, "%s: cvp enabled\n", __func__); - dprintk(VIDC_DBG, "%s: set CVP extradata\n", __func__); + dprintk(VIDC_HIGH, "%s: set CVP extradata\n", __func__); rc = msm_comm_set_extradata(inst, HFI_PROPERTY_PARAM_VENC_CVP_METADATA_EXTRADATA, 1); if (rc) { - dprintk(VIDC_WARN, "%s: set CVP extradata failed\n", __func__); + dprintk(VIDC_ERR, "%s: set CVP extradata failed\n", __func__); goto exit; } @@ -794,7 +794,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) struct hfi_buffer_size_minimum b; struct v4l2_format *f; - dprintk(VIDC_DBG, "%s: %x : inst %pK\n", __func__, + dprintk(VIDC_HIGH, "%s: %x : inst %pK\n", __func__, hash32_ptr(inst->session), inst); hdev = inst->core->device; @@ -808,7 +808,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) if (is_encode_session(inst)) { rc = msm_vidc_prepare_preprocess(inst); if (rc) { - dprintk(VIDC_WARN, "%s: no preprocessing\n", __func__); + dprintk(VIDC_ERR, "%s: no preprocessing\n", __func__); /* ignore error */ rc = 0; } @@ -914,7 +914,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) } inst->batch.enable = is_batching_allowed(inst); - dprintk(VIDC_DBG, "%s: batching %s for inst %pK (%#x)\n", + dprintk(VIDC_HIGH, "%s: batching %s for inst %pK (%#x)\n", __func__, inst->batch.enable ? "enabled" : "disabled", inst, hash32_ptr(inst->session)); @@ -978,7 +978,7 @@ static int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count) return -EINVAL; } hdev = inst->core->device; - dprintk(VIDC_DBG, "Streamon called on: %d capability for inst: %pK\n", + dprintk(VIDC_HIGH, "Streamon called on: %d capability for inst: %pK\n", q->type, inst); switch (q->type) { case INPUT_MPLANE: @@ -1075,7 +1075,7 @@ static inline int stop_streaming(struct msm_vidc_inst *inst) { int rc = 0; - dprintk(VIDC_DBG, "%s: %x : inst %pK\n", __func__, + dprintk(VIDC_HIGH, "%s: %x : inst %pK\n", __func__, hash32_ptr(inst->session), inst); rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); @@ -1108,7 +1108,7 @@ static void msm_vidc_stop_streaming(struct vb2_queue *q) } inst = q->drv_priv; - dprintk(VIDC_DBG, "Streamoff called on: %d capability\n", q->type); + dprintk(VIDC_HIGH, "Streamoff called on: %d capability\n", q->type); switch (q->type) { case INPUT_MPLANE: if (!inst->bufq[OUTPUT_PORT].vb2_bufq.streaming) @@ -1434,13 +1434,13 @@ static int try_get_ctrl_for_instance(struct msm_vidc_inst *inst, break; case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: ctrl->val = inst->fmts[OUTPUT_PORT].count_min_host; - dprintk(VIDC_DBG, "g_min: %x : hal_buffer %d min buffers %d\n", + dprintk(VIDC_HIGH, "g_min: %x : hal_buffer %d min buffers %d\n", hash32_ptr(inst->session), HAL_BUFFER_OUTPUT, ctrl->val); break; case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: ctrl->val = inst->fmts[INPUT_PORT].count_min_host; - dprintk(VIDC_DBG, "g_min: %x : hal_buffer %d min buffers %d\n", + dprintk(VIDC_HIGH, "g_min: %x : hal_buffer %d min buffers %d\n", hash32_ptr(inst->session), HAL_BUFFER_INPUT, ctrl->val); break; case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA: @@ -1491,7 +1491,7 @@ void *msm_vidc_open(int core_id, int session_type) } pr_info(VIDC_DBG_TAG "Opening video instance: %pK, %d\n", - "info", inst, session_type); + "high", inst, session_type); mutex_init(&inst->sync_lock); mutex_init(&inst->bufq[OUTPUT_PORT].lock); mutex_init(&inst->bufq[INPUT_PORT].lock); @@ -1761,7 +1761,7 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) msm_vidc_debugfs_deinit_inst(inst); pr_info(VIDC_DBG_TAG "Closed video instance: %pK\n", - "info", inst); + "high", inst); kfree(inst); return 0; } diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index c000118ef4e2..281d49eb9ba6 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -617,7 +617,7 @@ int msm_vidc_init_buffer_count(struct msm_vidc_inst *inst) fmt->count_min_host = fmt->count_actual = fmt->count_min + extra_buff_count; - dprintk(VIDC_DBG, "%s: %x : input min %d min_host %d actual %d\n", + dprintk(VIDC_HIGH, "%s: %x : input min %d min_host %d actual %d\n", __func__, hash32_ptr(inst->session), fmt->count_min, fmt->count_min_host, fmt->count_actual); @@ -648,7 +648,7 @@ int msm_vidc_init_buffer_count(struct msm_vidc_inst *inst) fmt->count_min_host = fmt->count_actual = fmt->count_min + extra_buff_count; - dprintk(VIDC_DBG, "%s: %x : output min %d min_host %d actual %d\n", + dprintk(VIDC_HIGH, "%s: %x : output min %d min_host %d actual %d\n", __func__, hash32_ptr(inst->session), fmt->count_min, fmt->count_min_host, fmt->count_actual); @@ -768,10 +768,10 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) if (inst->buffer_size_limit && (inst->buffer_size_limit < frame_size)) { frame_size = inst->buffer_size_limit; - dprintk(VIDC_DBG, "input buffer size limited to %d\n", + dprintk(VIDC_HIGH, "input buffer size limited to %d\n", frame_size); } else { - dprintk(VIDC_DBG, "set input buffer size to %d\n", + dprintk(VIDC_HIGH, "set input buffer size to %d\n", frame_size); } diff --git a/msm/vidc/msm_vidc_bus_iris1.c b/msm/vidc/msm_vidc_bus_iris1.c index 3512f4d11032..90fdb821babc 100644 --- a/msm/vidc/msm_vidc_bus_iris1.c +++ b/msm/vidc/msm_vidc_bus_iris1.c @@ -64,7 +64,7 @@ void __dump(struct dump dump[], int len) } } - dprintk(VIDC_DBG, "%s", formatted_line); + dprintk(VIDC_LOW, "%s", formatted_line); } } @@ -275,7 +275,7 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, llc.line_buffer_write + ddr.total; /* Dump all the variables for easier debugging */ - if (msm_vidc_debug & VIDC_PROF) { + if (msm_vidc_debug & VIDC_PERF) { struct dump dump[] = { {"DECODER PARAMETERS", "", DUMP_HEADER_MAGIC}, {"lcu size", "%d", lcu_size}, @@ -569,7 +569,7 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, ddr.total = fp_mult(ddr.total, qsmmu_bw_overhead_factor); llc.total = llc.ref_read_crcb + llc.line_buffer + ddr.total; - if (msm_vidc_debug & VIDC_PROF) { + if (msm_vidc_debug & VIDC_PERF) { struct dump dump[] = { {"ENCODER PARAMETERS", "", DUMP_HEADER_MAGIC}, {"width", "%d", width}, diff --git a/msm/vidc/msm_vidc_bus_iris2.c b/msm/vidc/msm_vidc_bus_iris2.c index fc91088ef6d7..21703d3e3992 100644 --- a/msm/vidc/msm_vidc_bus_iris2.c +++ b/msm/vidc/msm_vidc_bus_iris2.c @@ -214,7 +214,7 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, llc.line_buffer_write + ddr.total; /* Dump all the variables for easier debugging */ - if (msm_vidc_debug & VIDC_PROF) { + if (msm_vidc_debug & VIDC_PERF) { struct dump dump[] = { {"DECODER PARAMETERS", "", DUMP_HEADER_MAGIC}, {"lcu size", "%d", lcu_size}, @@ -508,7 +508,7 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, ddr.total = fp_mult(ddr.total, qsmmu_bw_overhead_factor); llc.total = llc.ref_read_crcb + llc.line_buffer + ddr.total; - if (msm_vidc_debug & VIDC_PROF) { + if (msm_vidc_debug & VIDC_PERF) { struct dump dump[] = { {"ENCODER PARAMETERS", "", DUMP_HEADER_MAGIC}, {"width", "%d", width}, diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c old mode 100644 new mode 100755 index 0ce353c33547..44c38920537a --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -47,13 +47,13 @@ struct msm_vidc_core_ops core_ops_iris2 = { static inline void msm_dcvs_print_dcvs_stats(struct clock_data *dcvs) { - dprintk(VIDC_PROF, + dprintk(VIDC_PERF, "DCVS: Load_Low %lld, Load Norm %lld, Load High %lld\n", dcvs->load_low, dcvs->load_norm, dcvs->load_high); - dprintk(VIDC_PROF, + dprintk(VIDC_PERF, "DCVS: min_threshold %d, max_threshold %d\n", dcvs->min_threshold, dcvs->max_threshold); } @@ -230,7 +230,7 @@ static int fill_dynamic_stats(struct msm_vidc_inst *inst, vote_data->use_dpb_read = true; } - dprintk(VIDC_PROF, + dprintk(VIDC_PERF, "Input CR = %d Recon CR = %d Complexity Factor = %d\n", vote_data->input_cr, vote_data->compression_ratio, vote_data->complexity_factor); @@ -257,12 +257,12 @@ int msm_comm_vote_bus(struct msm_vidc_core *core) vote_data = kzalloc(sizeof(struct vidc_bus_vote_data) * MAX_SUPPORTED_INSTANCES, GFP_ATOMIC); if (!vote_data) { - dprintk(VIDC_DBG, + dprintk(VIDC_LOW, "vote_data allocation with GFP_ATOMIC failed\n"); vote_data = kzalloc(sizeof(struct vidc_bus_vote_data) * MAX_SUPPORTED_INSTANCES, GFP_KERNEL); if (!vote_data) { - dprintk(VIDC_DBG, + dprintk(VIDC_ERR, "vote_data allocation failed\n"); return -EINVAL; } @@ -293,7 +293,7 @@ int msm_comm_vote_bus(struct msm_vidc_core *core) if ((!filled_len || !device_addr) && (inst->session_type != MSM_VIDC_CVP)) { - dprintk(VIDC_DBG, "%s: no input for session %x\n", + dprintk(VIDC_LOW, "%s: no input for session %x\n", __func__, hash32_ptr(inst->session)); continue; } @@ -414,7 +414,7 @@ static int msm_dcvs_scale_clocks(struct msm_vidc_inst *inst, inst->clk_data.dcvs_flags = 0; if (!inst->clk_data.dcvs_mode || inst->batch.enable) { - dprintk(VIDC_DBG, "Skip DCVS (dcvs %d, batching %d)\n", + dprintk(VIDC_LOW, "Skip DCVS (dcvs %d, batching %d)\n", inst->clk_data.dcvs_mode, inst->batch.enable); /* update load (freq) with normal value */ inst->clk_data.load = inst->clk_data.load_norm; @@ -463,7 +463,7 @@ static int msm_dcvs_scale_clocks(struct msm_vidc_inst *inst, dcvs->dcvs_flags = 0; } - dprintk(VIDC_PROF, + dprintk(VIDC_PERF, "DCVS: %x : total bufs %d outside fw %d max threshold %d with fw %d min bufs %d flags %#x\n", hash32_ptr(inst->session), fmt->count_actual, bufs_with_client, dcvs->max_threshold, bufs_with_fw, @@ -489,7 +489,7 @@ static void msm_vidc_update_freq_entry(struct msm_vidc_inst *inst, if (!found) { temp = kzalloc(sizeof(*temp), GFP_KERNEL); if (!temp) { - dprintk(VIDC_WARN, "%s: malloc failure.\n", __func__); + dprintk(VIDC_ERR, "%s: malloc failure.\n", __func__); goto exit; } temp->freq = freq; @@ -523,7 +523,7 @@ static unsigned long msm_vidc_max_freq(struct msm_vidc_core *core) allowed_clks_tbl = core->resources.allowed_clks_tbl; freq = allowed_clks_tbl[0].clock_rate; - dprintk(VIDC_PROF, "Max rate = %lu\n", freq); + dprintk(VIDC_PERF, "Max rate = %lu\n", freq); return freq; } @@ -571,7 +571,7 @@ void msm_comm_update_input_cr(struct msm_vidc_inst *inst, if (!found) { temp = kzalloc(sizeof(*temp), GFP_KERNEL); if (!temp) { - dprintk(VIDC_WARN, "%s: malloc failure.\n", __func__); + dprintk(VIDC_ERR, "%s: malloc failure.\n", __func__); goto exit; } temp->index = index; @@ -642,7 +642,7 @@ static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, freq = max(vpp_cycles, vsp_cycles); freq = max(freq, fw_cycles); - dprintk(VIDC_DBG, "Update DCVS Load\n"); + dprintk(VIDC_LOW, "Update DCVS Load\n"); allowed_clks_tbl = core->resources.allowed_clks_tbl; for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) { rate = allowed_clks_tbl[i].clock_rate; @@ -658,7 +658,7 @@ static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, msm_dcvs_print_dcvs_stats(dcvs); - dprintk(VIDC_PROF, "%s Inst %pK : Filled Len = %d Freq = %llu\n", + dprintk(VIDC_PERF, "%s Inst %pK : Filled Len = %d Freq = %llu\n", __func__, inst, filled_len, freq); return (unsigned long) freq; @@ -749,7 +749,7 @@ static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst, dcvs->load_high = i > 0 ? allowed_clks_tbl[i-1].clock_rate : dcvs->load_norm; - dprintk(VIDC_PROF, + dprintk(VIDC_PERF, "%s: inst %pK: %x : filled len %d required freq %llu load_norm %llu\n", __func__, inst, hash32_ptr(inst->session), filled_len, freq, dcvs->load_norm); @@ -842,7 +842,7 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, dcvs->load_high = i > 0 ? allowed_clks_tbl[i-1].clock_rate : dcvs->load_norm; - dprintk(VIDC_PROF, + dprintk(VIDC_PERF, "%s: inst %pK: %x : filled len %d required freq %llu load_norm %llu\n", __func__, inst, hash32_ptr(inst->session), filled_len, freq, dcvs->load_norm); @@ -888,7 +888,7 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core) mutex_unlock(&inst->registeredbufs.lock); if (!filled_len || !device_addr) { - dprintk(VIDC_DBG, "%s no input for session %x\n", + dprintk(VIDC_LOW, "%s no input for session %x\n", __func__, hash32_ptr(inst->session)); continue; } @@ -905,7 +905,7 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core) freq_core_max = max_t(unsigned long, freq_core_1, freq_core_2); if (msm_vidc_clock_voting) { - dprintk(VIDC_PROF, + dprintk(VIDC_PERF, "msm_vidc_clock_voting %d\n", msm_vidc_clock_voting); freq_core_max = msm_vidc_clock_voting; @@ -942,7 +942,7 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core) core->curr_freq = rate; mutex_unlock(&core->lock); - dprintk(VIDC_PROF, + dprintk(VIDC_PERF, "%s: clock rate %lu requested %lu increment %d decrement %d\n", __func__, core->curr_freq, core->min_freq, increment, decrement); @@ -982,7 +982,7 @@ int msm_comm_scale_clocks(struct msm_vidc_inst *inst) mutex_unlock(&inst->registeredbufs.lock); if (!filled_len || !device_addr) { - dprintk(VIDC_DBG, "%s no input for session %x\n", + dprintk(VIDC_LOW, "%s no input for session %x\n", __func__, hash32_ptr(inst->session)); return 0; } @@ -1018,11 +1018,11 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst) hdev = core->device; if (msm_comm_scale_clocks(inst)) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Failed to scale clocks. Performance might be impacted\n"); } if (msm_comm_vote_bus(core)) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Failed to scale DDR bus. Performance might be impacted\n"); } return 0; @@ -1042,12 +1042,12 @@ int msm_dcvs_try_enable(struct msm_vidc_inst *inst) inst->batch.enable || inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ || inst->grid_enable) { - dprintk(VIDC_PROF, "DCVS disabled: %pK\n", inst); + dprintk(VIDC_HIGH, "DCVS disabled: %pK\n", inst); inst->clk_data.dcvs_mode = false; return false; } inst->clk_data.dcvs_mode = true; - dprintk(VIDC_PROF, "DCVS enabled: %pK\n", inst); + dprintk(VIDC_HIGH, "DCVS enabled: %pK\n", inst); return true; } @@ -1064,7 +1064,7 @@ int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst) } if (inst->session_type == MSM_VIDC_CVP) { - dprintk(VIDC_DBG, "%s: cvp session\n", __func__); + dprintk(VIDC_LOW, "%s: cvp session\n", __func__); return 0; } @@ -1100,7 +1100,7 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) struct clock_data *dcvs; struct msm_vidc_format *fmt; - dprintk(VIDC_DBG, "Init DCVS Load\n"); + dprintk(VIDC_HIGH, "Init DCVS Load\n"); if (!inst || !inst->core || !inst->clk_data.entry) { dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n", @@ -1224,7 +1224,7 @@ int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst) V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR && mbps <= CBR_VFR_MB_LIMIT)) { pdata.video_work_route = 1; - dprintk(VIDC_DBG, "Configured work route = 1"); + dprintk(VIDC_HIGH, "Configured work route = 1"); } } else { return -EINVAL; @@ -1237,7 +1237,7 @@ int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst) (void *)inst->session, HFI_PROPERTY_PARAM_WORK_ROUTE, (void *)&pdata, sizeof(pdata)); if (rc) - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, " Failed to configure work route %pK\n", inst); return rc; @@ -1285,14 +1285,14 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) return -EINVAL; } - dprintk(VIDC_DBG, "Configurng work route = %u", + dprintk(VIDC_HIGH, "Configurng work route = %u", pdata.video_work_route); rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_PARAM_WORK_ROUTE, (void *)&pdata, sizeof(pdata)); if (rc) - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, " Failed to configure work route %pK\n", inst); else inst->clk_data.work_route = pdata.video_work_route; @@ -1348,7 +1348,7 @@ static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst) (void *)inst->session, HFI_PROPERTY_PARAM_WORK_MODE, (void *)&pdata, sizeof(pdata)); if (rc) - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, " Failed to configure Work Mode %pK\n", inst); /* For WORK_MODE_1, set Low Latency mode by default to HW. */ @@ -1388,7 +1388,7 @@ int msm_vidc_decide_work_mode_iris1(struct msm_vidc_inst *inst) if (inst->clk_data.low_latency_mode) { pdata.video_work_mode = HFI_WORKMODE_1; - dprintk(VIDC_DBG, "Configured work mode = 1"); + dprintk(VIDC_HIGH, "Configured work mode = 1"); goto decision_done; } @@ -1432,7 +1432,7 @@ int msm_vidc_decide_work_mode_iris1(struct msm_vidc_inst *inst) (void *)inst->session, HFI_PROPERTY_PARAM_WORK_MODE, (void *)&pdata, sizeof(pdata)); if (rc) - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, " Failed to configure Work Mode %pK\n", inst); /* For WORK_MODE_1, set Low Latency mode by default to HW. */ @@ -1494,7 +1494,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) } if (inst->rc_type == RATE_CONTROL_LOSSLESS && out_f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_H264) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Set work mode to low latency for AVC lossless encoding."); latency.enable = true; } @@ -1502,7 +1502,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) return -EINVAL; } - dprintk(VIDC_DBG, "Configuring work mode = %u low latency = %u", + dprintk(VIDC_HIGH, "Configuring work mode = %u low latency = %u", pdata.video_work_mode, latency.enable); @@ -1512,7 +1512,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE, (void *)&latency, sizeof(latency)); if (rc) - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, " Failed to configure low latency %pK\n", inst); else inst->clk_data.low_latency_mode = latency.enable; @@ -1522,7 +1522,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) (void *)inst->session, HFI_PROPERTY_PARAM_WORK_MODE, (void *)&pdata, sizeof(pdata)); if (rc) - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, " Failed to configure Work Mode %pK\n", inst); else inst->clk_data.work_mode = pdata.video_work_mode; @@ -1541,7 +1541,7 @@ static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, hdev = inst->core->device; if (inst->session_type != MSM_VIDC_ENCODER) { - dprintk(VIDC_DBG, + dprintk(VIDC_LOW, "%s : Not an encoder session. Nothing to do\n", __func__); return 0; @@ -1576,7 +1576,7 @@ static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, inst->flags | VIDC_LOW_POWER : inst->flags & ~VIDC_LOW_POWER; - dprintk(VIDC_PROF, + dprintk(VIDC_HIGH, "Power Save Mode for inst: %pK Enable = %d\n", inst, enable); fail_power_mode_set: return rc; @@ -1587,7 +1587,7 @@ static int msm_vidc_move_core_to_power_save_mode(struct msm_vidc_core *core, { struct msm_vidc_inst *inst = NULL; - dprintk(VIDC_PROF, "Core %d : Moving all inst to LP mode\n", core_id); + dprintk(VIDC_HIGH, "Core %d : Moving all inst to LP mode\n", core_id); mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { if (inst->clk_data.core_id == core_id && @@ -1692,12 +1692,12 @@ int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) cur_inst_lp_load = (msm_comm_get_inst_load(inst, LOAD_CALC_NO_QUIRKS) * lp_cycles)/inst->clk_data.work_route; - dprintk(VIDC_DBG, "Core 0 RT Load = %d Core 1 RT Load = %d\n", + dprintk(VIDC_HIGH, "Core 0 RT Load = %d Core 1 RT Load = %d\n", core0_load, core1_load); - dprintk(VIDC_DBG, "Core 0 RT LP Load = %d Core 1 RT LP Load = %d\n", + dprintk(VIDC_HIGH, "Core 0 RT LP Load = %d Core 1 RT LP Load = %d\n", core0_lp_load, core1_lp_load); - dprintk(VIDC_DBG, "Max Load = %lu\n", max_freq); - dprintk(VIDC_DBG, "Current Load = %d Current LP Load = %d\n", + dprintk(VIDC_HIGH, "Max Load = %lu\n", max_freq); + dprintk(VIDC_HIGH, "Current Load = %d Current LP Load = %d\n", current_inst_load, cur_inst_lp_load); if (inst->session_type == MSM_VIDC_ENCODER) { @@ -1728,14 +1728,14 @@ int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) if (current_inst_load + min_load < max_freq) { inst->clk_data.core_id = min_core_id; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Selected normally : Core ID = %d\n", inst->clk_data.core_id); msm_vidc_power_save_mode_enable(inst, false); } else if (cur_inst_lp_load + min_load < max_freq) { /* Move current instance to LP and return */ inst->clk_data.core_id = min_core_id; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Selected by moving current to LP : Core ID = %d\n", inst->clk_data.core_id); msm_vidc_power_save_mode_enable(inst, true); @@ -1743,7 +1743,7 @@ int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) } else if (cur_inst_lp_load + min_lp_load < max_freq) { /* Move all instances to LP mode and return */ inst->clk_data.core_id = min_lp_core_id; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Moved all inst's to LP: Core ID = %d\n", inst->clk_data.core_id); msm_vidc_move_core_to_power_save_mode(core, min_lp_core_id); @@ -1756,7 +1756,7 @@ int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) decision_done: core_info.video_core_enable_mask = inst->clk_data.core_id; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Core Enable Mask %d\n", core_info.video_core_enable_mask); rc = call_hfi_op(hdev, session_set_property, @@ -1764,7 +1764,7 @@ int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE, &core_info, sizeof(core_info)); if (rc) - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, " Failed to configure CORE ID %pK\n", inst); rc = msm_comm_scale_clocks_and_bus(inst); @@ -1802,7 +1802,7 @@ void msm_print_core_status(struct msm_vidc_core *core, u32 core_id) struct v4l2_format *out_f; struct v4l2_format *inp_f; - dprintk(VIDC_PROF, "Instances running on core %u", core_id); + dprintk(VIDC_PERF, "Instances running on core %u", core_id); mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { @@ -1811,7 +1811,7 @@ void msm_print_core_status(struct msm_vidc_core *core, u32 core_id) continue; out_f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; inp_f = &inst->fmts[INPUT_PORT].v4l2_fmt; - dprintk(VIDC_PROF, + dprintk(VIDC_PERF, "inst %pK (%4ux%4u) to (%4ux%4u) %3u %s %s %s %s %lu\n", inst, inp_f->fmt.pix_mp.width, diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 39e445312fa6..4a7d60ba5e88 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -264,7 +264,7 @@ int msm_comm_hfi_to_v4l2(int id, int value) } unknown_value: - dprintk(VIDC_WARN, "Unknown control (%x, %d)\n", id, value); + dprintk(VIDC_ERR, "Unknown control (%x, %d)\n", id, value); return -EINVAL; } @@ -318,7 +318,7 @@ static int h264_level_v4l2_to_hfi(int value) } unknown_value: - dprintk(VIDC_WARN, "Unknown level (%d)\n", value); + dprintk(VIDC_ERR, "Unknown level (%d)\n", value); return -EINVAL; } @@ -358,7 +358,7 @@ static int hevc_level_v4l2_to_hfi(int value) } unknown_value: - dprintk(VIDC_WARN, "Unknown level (%d)\n", value); + dprintk(VIDC_ERR, "Unknown level (%d)\n", value); return -EINVAL; } @@ -396,7 +396,7 @@ static int vp9_level_v4l2_to_hfi(int value) } unknown_value: - dprintk(VIDC_WARN, "Unknown level (%d)\n", value); + dprintk(VIDC_ERR, "Unknown level (%d)\n", value); return -EINVAL; } @@ -522,7 +522,7 @@ int msm_comm_v4l2_to_hfi(int id, int value) return HFI_H264_DB_MODE_ALL_BOUNDARY; } } - dprintk(VIDC_WARN, "Unknown control (%x, %d)\n", id, value); + dprintk(VIDC_ERR, "Unknown control (%x, %d)\n", id, value); return -EINVAL; } @@ -542,7 +542,7 @@ int msm_comm_get_v4l2_profile(int fourcc, int profile) case V4L2_PIX_FMT_MPEG2: return 0; default: - dprintk(VIDC_WARN, "Unknown codec id %x\n", fourcc); + dprintk(VIDC_ERR, "Unknown codec id %x\n", fourcc); return 0; } } @@ -567,7 +567,7 @@ int msm_comm_get_v4l2_level(int fourcc, int level) case V4L2_PIX_FMT_MPEG2: return 0; default: - dprintk(VIDC_WARN, "Unknown codec id %x\n", fourcc); + dprintk(VIDC_ERR, "Unknown codec id %x\n", fourcc); return 0; } } @@ -662,7 +662,7 @@ int msm_comm_ctrl_init(struct msm_vidc_inst *inst, /* Construct a super cluster of all controls */ inst->cluster = get_super_cluster(inst, num_ctrls); if (!inst->cluster) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Failed to setup super cluster\n"); return -EINVAL; } @@ -695,7 +695,7 @@ int msm_comm_set_stream_output_mode(struct msm_vidc_inst *inst, } if (!is_decode_session(inst)) { - dprintk(VIDC_DBG, "%s: not a decode session %x\n", + dprintk(VIDC_HIGH, "%s: not a decode session %x\n", __func__, hash32_ptr(inst->session)); return -EINVAL; } @@ -790,7 +790,7 @@ int msm_comm_get_inst_load(struct msm_vidc_inst *inst, if (!is_realtime_session(inst) && (quirks & LOAD_CALC_IGNORE_NON_REALTIME_LOAD)) { if (!(inst->clk_data.frame_rate >> 16)) { - dprintk(VIDC_INFO, "instance:%pK fps = 0\n", inst); + dprintk(VIDC_LOW, "instance:%pK fps = 0\n", inst); load = 0; } else { load = msm_comm_get_mbs_per_sec(inst) / @@ -1003,7 +1003,7 @@ const struct msm_vidc_format_desc *msm_comm_get_pixel_fmt_index( k++; } if (i == size) { - dprintk(VIDC_INFO, "Format not found\n"); + dprintk(VIDC_HIGH, "Format not found\n"); return NULL; } return &fmt[i]; @@ -1022,7 +1022,7 @@ struct msm_vidc_format_desc *msm_comm_get_pixel_fmt_fourcc( break; } if (i == size) { - dprintk(VIDC_INFO, "Format not found\n"); + dprintk(VIDC_HIGH, "Format not found\n"); return NULL; } return &fmt[i]; @@ -1042,7 +1042,7 @@ struct msm_vidc_format_constraint *msm_comm_get_pixel_fmt_constraints( break; } if (i == size) { - dprintk(VIDC_INFO, "Format constraint not found.\n"); + dprintk(VIDC_HIGH, "Format constraint not found.\n"); return NULL; } return &fmt[i]; @@ -1093,7 +1093,7 @@ static int msm_vidc_capabilities(struct msm_vidc_core *core) platform_caps = core->resources.codec_caps; num_platform_caps = core->resources.codec_caps_count; - dprintk(VIDC_DBG, "%s: num caps %d\n", __func__, num_platform_caps); + dprintk(VIDC_HIGH, "%s: num caps %d\n", __func__, num_platform_caps); /* loop over each platform capability */ for (i = 0; i < num_platform_caps; i++) { /* select matching core codec and update it */ @@ -1131,7 +1131,7 @@ static void handle_sys_init_done(enum hal_command_response cmd, void *data) dprintk(VIDC_ERR, "Wrong device_id received\n"); return; } - dprintk(VIDC_DBG, "%s: core %pK\n", __func__, core); + dprintk(VIDC_HIGH, "%s: core %pK\n", __func__, core); complete(&(core->completions[SYS_MSG_INDEX(cmd)])); } @@ -1209,7 +1209,7 @@ static void handle_session_release_buf_done(enum hal_command_response cmd, inst = get_inst(get_vidc_core(response->device_id), response->session_id); if (!inst) { - dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + dprintk(VIDC_ERR, "Got a response for an inactive session\n"); return; } @@ -1220,7 +1220,7 @@ static void handle_session_release_buf_done(enum hal_command_response cmd, list_for_each_safe(ptr, next, &inst->scratchbufs.list) { buf = list_entry(ptr, struct internal_buf, list); if (address == buf->smem.device_addr) { - dprintk(VIDC_DBG, "releasing scratch: %x\n", + dprintk(VIDC_HIGH, "releasing scratch: %x\n", buf->smem.device_addr); buf_found = true; } @@ -1231,7 +1231,7 @@ static void handle_session_release_buf_done(enum hal_command_response cmd, list_for_each_safe(ptr, next, &inst->persistbufs.list) { buf = list_entry(ptr, struct internal_buf, list); if (address == buf->smem.device_addr) { - dprintk(VIDC_DBG, "releasing persist: %x\n", + dprintk(VIDC_HIGH, "releasing persist: %x\n", buf->smem.device_addr); buf_found = true; } @@ -1276,12 +1276,12 @@ void change_inst_state(struct msm_vidc_inst *inst, enum instance_state state) } mutex_lock(&inst->lock); if (inst->state == MSM_VIDC_CORE_INVALID) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Inst: %pK is in bad state can't change state to %d\n", inst, state); goto exit; } - dprintk(VIDC_DBG, "Moved inst: %pK from state: %d to state: %d\n", + dprintk(VIDC_HIGH, "Moved inst: %pK from state: %d to state: %d\n", inst, inst->state, state); inst->state = state; exit: @@ -1338,11 +1338,11 @@ static int wait_for_state(struct msm_vidc_inst *inst, int rc = 0; if (IS_ALREADY_IN_STATE(flipped_state, desired_state)) { - dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", + dprintk(VIDC_HIGH, "inst: %pK is already in state: %d\n", inst, inst->state); goto err_same_state; } - dprintk(VIDC_DBG, "Waiting for hal_cmd: %d\n", hal_cmd); + dprintk(VIDC_HIGH, "Waiting for hal_cmd: %d\n", hal_cmd); rc = wait_for_sess_signal_receipt(inst, hal_cmd); if (!rc) change_inst_state(inst, desired_state); @@ -1375,7 +1375,7 @@ static void msm_comm_generate_max_clients_error(struct msm_vidc_inst *inst) static void print_cap(const char *type, struct hal_capability_supported *cap) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%-24s: %-10d %-10d %-10d %-10d\n", type, cap->min, cap->max, cap->step_size, cap->default_value); } @@ -1413,7 +1413,7 @@ static int msm_vidc_comm_update_ctrl(struct msm_vidc_inst *inst, __func__, ctrl->name, cap->default_value); goto error; } - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Updated control: %s: min %lld, max %lld, step %lld, default value = %lld\n", ctrl->name, ctrl->minimum, ctrl->maximum, ctrl->step, ctrl->default_value); @@ -1460,7 +1460,7 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data) response->session_id); if (!inst) { - dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + dprintk(VIDC_ERR, "Got a response for an inactive session\n"); return; } @@ -1472,7 +1472,7 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data) } if (inst->session_type == MSM_VIDC_CVP) { - dprintk(VIDC_DBG, "%s: cvp session %#x\n", + dprintk(VIDC_HIGH, "%s: cvp session %#x\n", __func__, hash32_ptr(inst->session)); signal_session_msg_receipt(cmd, inst); put_inst(inst); @@ -1499,13 +1499,13 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data) goto error; } - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: capabilities for domain %#x codec %#x\n", __func__, capability->domain, capability->codec); memcpy(&inst->capability, capability, sizeof(struct msm_vidc_capability)); - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Capability type : min max step_size default_value\n"); print_cap("width", &inst->capability.cap[CAP_FRAME_WIDTH]); print_cap("height", &inst->capability.cap[CAP_FRAME_HEIGHT]); @@ -1571,14 +1571,14 @@ static void handle_event_change(enum hal_command_response cmd, void *data) u32 codec; if (!event_notify) { - dprintk(VIDC_WARN, "Got an empty event from hfi\n"); + dprintk(VIDC_ERR, "Got an empty event from hfi\n"); return; } inst = get_inst(get_vidc_core(event_notify->device_id), event_notify->session_id); if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + dprintk(VIDC_ERR, "Got a response for an inactive session\n"); goto err_bad_event; } hdev = inst->core->device; @@ -1593,8 +1593,8 @@ static void handle_event_change(enum hal_command_response cmd, void *data) */ bool event_fields_changed = false; - dprintk(VIDC_DBG, "V4L2_EVENT_SEQ_CHANGED_SUFFICIENT\n"); - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "V4L2_EVENT_SEQ_CHANGED_SUFFICIENT\n"); + dprintk(VIDC_HIGH, "event_notify->height = %d event_notify->width = %d\n", event_notify->height, event_notify->width); @@ -1616,7 +1616,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data) if (event_fields_changed) { event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT; } else { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "No parameter change continue session\n"); rc = call_hfi_op(hdev, session_continue, (void *)inst->session); @@ -1636,7 +1636,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data) struct msm_vidc_buffer *mbuf; u32 planes[VIDEO_MAX_PLANES] = {0}; - dprintk(VIDC_DBG, + dprintk(VIDC_LOW, "%s: inst: %pK data_buffer: %x extradata_buffer: %x\n", __func__, inst, event_notify->packet_buffer, event_notify->extra_data_buffer); @@ -1711,17 +1711,17 @@ static void handle_event_change(enum hal_command_response cmd, void *data) ptr[10] = msm_comm_get_v4l2_level(codec, event_notify->level); - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Event payload: height = %u width = %u profile = %u level = %u\n", event_notify->height, event_notify->width, ptr[9], ptr[10]); - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Event payload: bit_depth = %u pic_struct = %u colour_space = %u\n", event_notify->bit_depth, event_notify->pic_struct, event_notify->colour_space); - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Event payload: CROP top = %u left = %u Height = %u Width = %u\n", event_notify->crop_data.top, event_notify->crop_data.left, @@ -1740,14 +1740,14 @@ static void handle_event_change(enum hal_command_response cmd, void *data) fmt->count_min = event_notify->capture_buf_count; fmt->count_min_host = fmt->count_min + extra_buff_count; - dprintk(VIDC_DBG, "%s: buffer[%d] count: min %d min_host %d\n", + dprintk(VIDC_HIGH, "%s: buffer[%d] count: min %d min_host %d\n", __func__, HAL_BUFFER_OUTPUT, fmt->count_min, fmt->count_min_host); mutex_unlock(&inst->lock); if (event == V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT) { - dprintk(VIDC_DBG, "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT\n"); + dprintk(VIDC_HIGH, "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT\n"); } rc = msm_vidc_check_session_supported(inst); @@ -1781,7 +1781,7 @@ static void handle_session_prop_info(enum hal_command_response cmd, void *data) inst = get_inst(get_vidc_core(response->device_id), response->session_id); if (!inst) { - dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + dprintk(VIDC_ERR, "Got a response for an inactive session\n"); return; } @@ -1822,7 +1822,7 @@ static void handle_load_resource_done(enum hal_command_response cmd, void *data) inst = get_inst(get_vidc_core(response->device_id), response->session_id); if (!inst) { - dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + dprintk(VIDC_ERR, "Got a response for an inactive session\n"); return; } @@ -1849,7 +1849,7 @@ static void handle_start_done(enum hal_command_response cmd, void *data) inst = get_inst(get_vidc_core(response->device_id), response->session_id); if (!inst) { - dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + dprintk(VIDC_ERR, "Got a response for an inactive session\n"); return; } @@ -1870,7 +1870,7 @@ static void handle_stop_done(enum hal_command_response cmd, void *data) inst = get_inst(get_vidc_core(response->device_id), response->session_id); if (!inst) { - dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + dprintk(VIDC_ERR, "Got a response for an inactive session\n"); return; } @@ -1892,7 +1892,7 @@ static void handle_release_res_done(enum hal_command_response cmd, void *data) inst = get_inst(get_vidc_core(response->device_id), response->session_id); if (!inst) { - dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + dprintk(VIDC_ERR, "Got a response for an inactive session\n"); return; } @@ -1910,14 +1910,14 @@ void msm_comm_validate_output_buffers(struct msm_vidc_inst *inst) mutex_lock(&inst->outputbufs.lock); if (list_empty(&inst->outputbufs.list)) { - dprintk(VIDC_DBG, "%s: no OUTPUT buffers allocated\n", + dprintk(VIDC_HIGH, "%s: no OUTPUT buffers allocated\n", __func__); mutex_unlock(&inst->outputbufs.lock); return; } list_for_each_entry(binfo, &inst->outputbufs.list, list) { if (binfo->buffer_ownership != DRIVER) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "This buffer is with FW %x\n", binfo->smem.device_addr); continue; @@ -1928,7 +1928,7 @@ void msm_comm_validate_output_buffers(struct msm_vidc_inst *inst) /* Only minimum number of DPBs are allocated */ if (buffers_owned_by_driver != fmt->count_min) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "OUTPUT Buffer count mismatch %d of %d\n", buffers_owned_by_driver, fmt->count_min); @@ -1993,7 +1993,7 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) inst = get_inst(get_vidc_core(response->device_id), response->session_id); if (!inst) { - dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + dprintk(VIDC_ERR, "Got a response for an inactive session\n"); return; } @@ -2035,7 +2035,7 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) goto exit; } - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Notify flush complete, flush_type: %x\n", flush_type); v4l2_event_queue_fh(&inst->event_handler, &flush_event); @@ -2060,7 +2060,7 @@ static void handle_session_error(enum hal_command_response cmd, void *data) inst = get_inst(get_vidc_core(response->device_id), response->session_id); if (!inst) { - dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + dprintk(VIDC_ERR, "Got a response for an inactive session\n"); return; } @@ -2069,7 +2069,7 @@ static void handle_session_error(enum hal_command_response cmd, void *data) inst, hash32_ptr(inst->session)); if (response->status == VIDC_ERR_MAX_CLIENTS) { - dprintk(VIDC_WARN, "Too many clients, rejecting %pK", inst); + dprintk(VIDC_ERR, "Too many clients, rejecting %pK", inst); event = V4L2_EVENT_MSM_VIDC_MAX_CLIENTS; /* @@ -2081,10 +2081,10 @@ static void handle_session_error(enum hal_command_response cmd, void *data) msm_comm_session_clean(inst); } else if (response->status == VIDC_ERR_NOT_SUPPORTED) { - dprintk(VIDC_WARN, "Unsupported bitstream in %pK", inst); + dprintk(VIDC_ERR, "Unsupported bitstream in %pK", inst); event = V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED; } else { - dprintk(VIDC_WARN, "Unknown session error (%d) for %pK\n", + dprintk(VIDC_ERR, "Unknown session error (%d) for %pK\n", response->status, inst); event = V4L2_EVENT_MSM_VIDC_SYS_ERROR; } @@ -2104,14 +2104,14 @@ static void msm_comm_clean_notify_client(struct msm_vidc_core *core) return; } - dprintk(VIDC_WARN, "%s: Core %pK\n", __func__, core); + dprintk(VIDC_ERR, "%s: Core %pK\n", __func__, core); mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { mutex_lock(&inst->lock); inst->state = MSM_VIDC_CORE_INVALID; mutex_unlock(&inst->lock); - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "%s Send sys error for inst %pK\n", __func__, inst); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); @@ -2151,11 +2151,11 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) return; } - dprintk(VIDC_WARN, "SYS_ERROR received for core %pK\n", core); + dprintk(VIDC_ERR, "SYS_ERROR received for core %pK\n", core); msm_vidc_noc_error_info(core); call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); list_for_each_entry(inst, &core->instances, list) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "%s: Send sys error for inst %pK\n", __func__, inst); change_inst_state(inst, MSM_VIDC_CORE_INVALID); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); @@ -2166,11 +2166,11 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) /* handle the hw error before core released to get full debug info */ msm_vidc_handle_hw_error(core); if (response->status == VIDC_ERR_NOC_ERROR) { - dprintk(VIDC_WARN, "Got NOC error"); + dprintk(VIDC_ERR, "Got NOC error"); MSM_VIDC_ERROR(true); } - dprintk(VIDC_DBG, "Calling core_release\n"); + dprintk(VIDC_ERR, "Calling core_release\n"); rc = call_hfi_op(hdev, core_release, hdev->hfi_device_data); if (rc) { dprintk(VIDC_ERR, "core_release failed\n"); @@ -2180,7 +2180,7 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) core->state = VIDC_CORE_UNINIT; mutex_unlock(&core->lock); - dprintk(VIDC_WARN, "SYS_ERROR handled.\n"); + dprintk(VIDC_ERR, "SYS_ERROR handled.\n"); } void msm_comm_session_clean(struct msm_vidc_inst *inst) @@ -2193,14 +2193,14 @@ void msm_comm_session_clean(struct msm_vidc_inst *inst) return; } if (!inst->session) { - dprintk(VIDC_DBG, "%s: inst %pK session already cleaned\n", + dprintk(VIDC_HIGH, "%s: inst %pK session already cleaned\n", __func__, inst); return; } hdev = inst->core->device; mutex_lock(&inst->lock); - dprintk(VIDC_DBG, "%s: inst %pK\n", __func__, inst); + dprintk(VIDC_HIGH, "%s: inst %pK\n", __func__, inst); rc = call_hfi_op(hdev, session_clean, (void *)inst->session); if (rc) { @@ -2225,7 +2225,7 @@ static void handle_session_close(enum hal_command_response cmd, void *data) inst = get_inst(get_vidc_core(response->device_id), response->session_id); if (!inst) { - dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + dprintk(VIDC_ERR, "Got a response for an inactive session\n"); return; } @@ -2407,14 +2407,14 @@ static void handle_ebd(enum hal_command_response cmd, void *data) inst = get_inst(get_vidc_core(response->device_id), response->session_id); if (!inst) { - dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + dprintk(VIDC_ERR, "Got a response for an inactive session\n"); return; } empty_buf_done = (struct vidc_hal_ebd *)&response->input_done; /* If this is internal EOS buffer, handle it in driver */ if (is_eos_buffer(inst, empty_buf_done->packet_buffer)) { - dprintk(VIDC_DBG, "Received EOS buffer 0x%x\n", + dprintk(VIDC_HIGH, "Received EOS buffer 0x%x\n", empty_buf_done->packet_buffer); goto exit; } @@ -2435,18 +2435,18 @@ static void handle_ebd(enum hal_command_response cmd, void *data) vb->planes[0].bytesused = response->input_done.filled_len; if (vb->planes[0].bytesused > vb->planes[0].length) - dprintk(VIDC_INFO, "bytesused overflow length\n"); + dprintk(VIDC_LOW, "bytesused overflow length\n"); vb->planes[0].data_offset = response->input_done.offset; if (vb->planes[0].data_offset > vb->planes[0].length) - dprintk(VIDC_INFO, "data_offset overflow length\n"); + dprintk(VIDC_LOW, "data_offset overflow length\n"); if (empty_buf_done->status == VIDC_ERR_NOT_SUPPORTED) { - dprintk(VIDC_INFO, "Failed : Unsupported input stream\n"); + dprintk(VIDC_LOW, "Failed : Unsupported input stream\n"); mbuf->vvb.flags |= V4L2_BUF_INPUT_UNSUPPORTED; } if (empty_buf_done->status == VIDC_ERR_BITSTREAM_ERR) { - dprintk(VIDC_INFO, "Failed : Corrupted input stream\n"); + dprintk(VIDC_LOW, "Failed : Corrupted input stream\n"); mbuf->vvb.flags |= V4L2_BUF_FLAG_DATA_CORRUPT; } if (empty_buf_done->flags & HAL_BUFFERFLAG_SYNCFRAME) @@ -2538,7 +2538,7 @@ static void handle_fbd(enum hal_command_response cmd, void *data) inst = get_inst(get_vidc_core(response->device_id), response->session_id); if (!inst) { - dprintk(VIDC_WARN, "Got a response for an inactive session\n"); + dprintk(VIDC_ERR, "Got a response for an inactive session\n"); return; } @@ -2571,13 +2571,13 @@ static void handle_fbd(enum hal_command_response cmd, void *data) fill_buf_done->filled_len1 = 0; vb->planes[0].bytesused = fill_buf_done->filled_len1; if (vb->planes[0].bytesused > vb->planes[0].length) - dprintk(VIDC_INFO, + dprintk(VIDC_LOW, "fbd:Overflow bytesused = %d; length = %d\n", vb->planes[0].bytesused, vb->planes[0].length); vb->planes[0].data_offset = fill_buf_done->offset1; if (vb->planes[0].data_offset > vb->planes[0].length) - dprintk(VIDC_INFO, + dprintk(VIDC_LOW, "fbd:Overflow data_offset = %d; length = %d\n", vb->planes[0].data_offset, vb->planes[0].length); @@ -2648,7 +2648,7 @@ static void handle_fbd(enum hal_command_response cmd, void *data) void handle_cmd_response(enum hal_command_response cmd, void *data) { - dprintk(VIDC_DBG, "Command response = %d\n", cmd); + dprintk(VIDC_LOW, "Command response = %d\n", cmd); switch (cmd) { case HAL_SYS_INIT_DONE: handle_sys_init_done(cmd, data); @@ -2707,7 +2707,7 @@ void handle_cmd_response(enum hal_command_response cmd, void *data) handle_session_unregister_buffer_done(cmd, data); break; default: - dprintk(VIDC_DBG, "response unhandled: %d\n", cmd); + dprintk(VIDC_LOW, "response unhandled: %d\n", cmd); break; } } @@ -2750,7 +2750,7 @@ static bool is_thermal_permissible(struct msm_vidc_core *core) return true; if (msm_vidc_thermal_mitigation_disabled) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Thermal mitigation not enabled. debugfs %d\n", msm_vidc_thermal_mitigation_disabled); return true; @@ -2760,7 +2760,7 @@ static bool is_thermal_permissible(struct msm_vidc_core *core) freq = core->curr_freq; is_turbo = is_core_turbo(core, freq); - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Core freq %ld Thermal level %d Turbo mode %d\n", freq, tl, is_turbo); @@ -2809,7 +2809,7 @@ static int msm_comm_session_abort(struct msm_vidc_inst *inst) hdev = inst->core->device; abort_completion = SESSION_MSG_INDEX(HAL_SESSION_ABORT_DONE); - dprintk(VIDC_WARN, "%s: inst %pK session %x\n", __func__, + dprintk(VIDC_ERR, "%s: inst %pK session %x\n", __func__, inst, hash32_ptr(inst->session)); rc = call_hfi_op(hdev, session_abort, (void *)inst->session); if (rc) { @@ -2850,7 +2850,7 @@ static void handle_thermal_event(struct msm_vidc_core *core) mutex_unlock(&core->lock); if (inst->state >= MSM_VIDC_OPEN_DONE && inst->state < MSM_VIDC_CLOSE_DONE) { - dprintk(VIDC_WARN, "%s: abort inst %pK\n", + dprintk(VIDC_ERR, "%s: abort inst %pK\n", __func__, inst); rc = msm_comm_session_abort(inst); if (rc) { @@ -2860,7 +2860,7 @@ static void handle_thermal_event(struct msm_vidc_core *core) goto err_sess_abort; } change_inst_state(inst, MSM_VIDC_CORE_INVALID); - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "%s Send sys error for inst %pK\n", __func__, inst); msm_vidc_queue_v4l2_event(inst, @@ -2883,7 +2883,7 @@ void msm_comm_handle_thermal_event(void) list_for_each_entry(core, &vidc_driver->cores, list) { if (!is_thermal_permissible(core)) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Thermal level critical, stop all active sessions!\n"); handle_thermal_event(core); } @@ -2896,11 +2896,11 @@ int msm_comm_check_core_init(struct msm_vidc_core *core) mutex_lock(&core->lock); if (core->state >= VIDC_CORE_INIT_DONE) { - dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n", + dprintk(VIDC_HIGH, "Video core: %d is already in state: %d\n", core->id, core->state); goto exit; } - dprintk(VIDC_DBG, "Waiting for SYS_INIT_DONE\n"); + dprintk(VIDC_HIGH, "Waiting for SYS_INIT_DONE\n"); rc = wait_for_completion_timeout( &core->completions[SYS_MSG_INDEX(HAL_SYS_INIT_DONE)], msecs_to_jiffies(core->resources.msm_vidc_hw_rsp_timeout)); @@ -2913,7 +2913,7 @@ int msm_comm_check_core_init(struct msm_vidc_core *core) core->state = VIDC_CORE_INIT_DONE; rc = 0; } - dprintk(VIDC_DBG, "SYS_INIT_DONE!!!\n"); + dprintk(VIDC_HIGH, "SYS_INIT_DONE!!!\n"); exit: mutex_unlock(&core->lock); return rc; @@ -2946,11 +2946,11 @@ static int msm_comm_init_core(struct msm_vidc_inst *inst) hdev = core->device; mutex_lock(&core->lock); if (core->state >= VIDC_CORE_INIT) { - dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n", + dprintk(VIDC_HIGH, "Video core: %d is already in state: %d\n", core->id, core->state); goto core_already_inited; } - dprintk(VIDC_DBG, "%s: core %pK\n", __func__, core); + dprintk(VIDC_HIGH, "%s: core %pK\n", __func__, core); rc = call_hfi_op(hdev, core_init, hdev->hfi_device_data); if (rc) { dprintk(VIDC_ERR, "Failed to init core, id = %d\n", @@ -2967,7 +2967,7 @@ static int msm_comm_init_core(struct msm_vidc_inst *inst) core->resources.max_secure_inst_count ? core->resources.max_secure_inst_count : core->resources.max_inst_count; - dprintk(VIDC_DBG, "%s: codecs count %d, max inst count %d\n", + dprintk(VIDC_HIGH, "%s: codecs count %d, max inst count %d\n", __func__, core->resources.codecs_count, core->resources.max_inst_count); if (!core->resources.codecs || !core->resources.codecs_count) { @@ -2986,7 +2986,7 @@ static int msm_comm_init_core(struct msm_vidc_inst *inst) goto fail_core_init; } } else { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "%s: capabilities memory is expected to be freed\n", __func__); } @@ -3004,7 +3004,7 @@ static int msm_comm_init_core(struct msm_vidc_inst *inst) core->capabilities = NULL; goto fail_core_init; } - dprintk(VIDC_DBG, "%s: done\n", __func__); + dprintk(VIDC_HIGH, "%s: done\n", __func__); core_already_inited: change_inst_state(inst, MSM_VIDC_CORE_INIT); mutex_unlock(&core->lock); @@ -3033,7 +3033,7 @@ static int msm_vidc_deinit_core(struct msm_vidc_inst *inst) mutex_lock(&core->lock); if (core->state == VIDC_CORE_UNINIT) { - dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n", + dprintk(VIDC_HIGH, "Video core: %d is already in state: %d\n", core->id, core->state); goto core_already_uninited; } @@ -3056,7 +3056,7 @@ static int msm_vidc_deinit_core(struct msm_vidc_inst *inst) msecs_to_jiffies(core->state == VIDC_CORE_INIT_DONE ? core->resources.msm_vidc_firmware_unload_delay : 0)); - dprintk(VIDC_DBG, "firmware unload delayed by %u ms\n", + dprintk(VIDC_HIGH, "firmware unload delayed by %u ms\n", core->state == VIDC_CORE_INIT_DONE ? core->resources.msm_vidc_firmware_unload_delay : 0); } @@ -3078,7 +3078,7 @@ static int msm_comm_session_init_done(int flipped_state, { int rc; - dprintk(VIDC_DBG, "inst %pK: waiting for session init done\n", inst); + dprintk(VIDC_HIGH, "inst %pK: waiting for session init done\n", inst); rc = wait_for_state(inst, flipped_state, MSM_VIDC_OPEN_DONE, HAL_SESSION_INIT_DONE); if (rc) { @@ -3105,7 +3105,7 @@ static int msm_comm_session_init(int flipped_state, hdev = inst->core->device; if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_OPEN)) { - dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", + dprintk(VIDC_HIGH, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -3128,7 +3128,7 @@ static int msm_comm_session_init(int flipped_state, goto exit; } - dprintk(VIDC_DBG, "%s: inst %pK\n", __func__, inst); + dprintk(VIDC_HIGH, "%s: inst %pK\n", __func__, inst); rc = call_hfi_op(hdev, session_init, hdev->hfi_device_data, inst, get_hal_domain(inst->session_type), get_hal_codec(fourcc), @@ -3221,7 +3221,7 @@ static int msm_vidc_load_resources(int flipped_state, return -EINVAL; } if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_LOAD_RESOURCES)) { - dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", + dprintk(VIDC_HIGH, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -3243,7 +3243,7 @@ static int msm_vidc_load_resources(int flipped_state, } hdev = core->device; - dprintk(VIDC_DBG, "%s: inst %pK\n", __func__, inst); + dprintk(VIDC_HIGH, "%s: inst %pK\n", __func__, inst); rc = call_hfi_op(hdev, session_load_res, (void *) inst->session); if (rc) { dprintk(VIDC_ERR, @@ -3270,13 +3270,13 @@ static int msm_vidc_start(int flipped_state, struct msm_vidc_inst *inst) return -EINVAL; } if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_START)) { - dprintk(VIDC_INFO, + dprintk(VIDC_HIGH, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } hdev = inst->core->device; - dprintk(VIDC_DBG, "%s: inst %pK\n", __func__, inst); + dprintk(VIDC_HIGH, "%s: inst %pK\n", __func__, inst); rc = call_hfi_op(hdev, session_start, (void *) inst->session); if (rc) { dprintk(VIDC_ERR, @@ -3303,13 +3303,13 @@ static int msm_vidc_stop(int flipped_state, struct msm_vidc_inst *inst) return -EINVAL; } if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_STOP)) { - dprintk(VIDC_INFO, + dprintk(VIDC_HIGH, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } hdev = inst->core->device; - dprintk(VIDC_DBG, "%s: inst %pK\n", __func__, inst); + dprintk(VIDC_HIGH, "%s: inst %pK\n", __func__, inst); rc = call_hfi_op(hdev, session_stop, (void *) inst->session); if (rc) { dprintk(VIDC_ERR, "%s: inst %pK session_stop failed\n", @@ -3336,13 +3336,13 @@ static int msm_vidc_release_res(int flipped_state, struct msm_vidc_inst *inst) return -EINVAL; } if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_RELEASE_RESOURCES)) { - dprintk(VIDC_INFO, + dprintk(VIDC_HIGH, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } hdev = inst->core->device; - dprintk(VIDC_DBG, "%s: inst %pK\n", __func__, inst); + dprintk(VIDC_HIGH, "%s: inst %pK\n", __func__, inst); rc = call_hfi_op(hdev, session_release_res, (void *) inst->session); if (rc) { dprintk(VIDC_ERR, @@ -3365,13 +3365,13 @@ static int msm_comm_session_close(int flipped_state, return -EINVAL; } if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_CLOSE)) { - dprintk(VIDC_INFO, + dprintk(VIDC_HIGH, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } hdev = inst->core->device; - dprintk(VIDC_DBG, "%s: inst %pK\n", __func__, inst); + dprintk(VIDC_HIGH, "%s: inst %pK\n", __func__, inst); rc = call_hfi_op(hdev, session_end, (void *) inst->session); if (rc) { dprintk(VIDC_ERR, @@ -3405,7 +3405,7 @@ int msm_comm_suspend(int core_id) rc = call_hfi_op(hdev, suspend, hdev->hfi_device_data); if (rc) - dprintk(VIDC_WARN, "Failed to suspend\n"); + dprintk(VIDC_ERR, "Failed to suspend\n"); return rc; } @@ -3457,7 +3457,7 @@ u32 msm_comm_convert_color_fmt(u32 v4l2_fmt) case V4L2_PIX_FMT_NV12_TP10_UBWC: return COLOR_FMT_NV12_BPP10_UBWC; default: - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Invalid v4l2 color fmt FMT : %x, Set default(NV12)", v4l2_fmt); return COLOR_FMT_NV12; @@ -3533,7 +3533,7 @@ static int set_dpb_only_buffers(struct msm_vidc_inst *inst, f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; buffer_size = VENUS_BUFFER_SIZE(hfi_fmt, f->fmt.pix_mp.width, f->fmt.pix_mp.height); - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "output: num = %d, size = %d\n", num_buffers, buffer_size); @@ -3548,11 +3548,11 @@ static int set_dpb_only_buffers(struct msm_vidc_inst *inst, if (f->fmt.pix_mp.num_planes == 1 || !f->fmt.pix_mp.plane_fmt[1].sizeimage) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "This extradata buffer not required, buffer_type: %x\n", buffer_type); } else { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "extradata: num = 1, size = %d\n", f->fmt.pix_mp.plane_fmt[1].sizeimage); inst->dpb_extra_binfo = NULL; @@ -3593,7 +3593,7 @@ static int set_dpb_only_buffers(struct msm_vidc_inst *inst, } binfo->buffer_type = buffer_type; binfo->buffer_ownership = DRIVER; - dprintk(VIDC_DBG, "Output buffer address: %#x\n", + dprintk(VIDC_HIGH, "Output buffer address: %#x\n", binfo->smem.device_addr); if (inst->buffer_mode_set[OUTPUT_PORT] == @@ -3670,7 +3670,7 @@ static int set_internal_buf_on_fw(struct msm_vidc_inst *inst, buffer_info.buffer_type = buffer_type; buffer_info.num_buffers = 1; buffer_info.align_device_addr = handle->device_addr; - dprintk(VIDC_DBG, "%s %s buffer : %x\n", + dprintk(VIDC_HIGH, "%s %s buffer : %x\n", reuse ? "Reusing" : "Allocated", get_buffer_name(buffer_type), buffer_info.align_device_addr); @@ -3724,7 +3724,7 @@ static bool reuse_internal_buffers(struct msm_vidc_inst *inst, } } reused = true; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Re-using internal buffer type : %d\n", buffer_type); } mutex_unlock(&buf_list->lock); @@ -3794,13 +3794,13 @@ static int set_internal_buffers(struct msm_vidc_inst *inst, internal_buf = get_buff_req_buffer(inst, buffer_type); if (!internal_buf) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "This internal buffer not required, buffer_type: %x\n", buffer_type); return 0; } - dprintk(VIDC_DBG, "Buffer type %s: num = %d, size = %d\n", + dprintk(VIDC_HIGH, "Buffer type %s: num = %d, size = %d\n", get_buffer_name(buffer_type), internal_buf->buffer_count_actual, internal_buf->buffer_size); @@ -3824,7 +3824,7 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state) dprintk(VIDC_ERR, "%s: invalid params %pK", __func__, inst); return -EINVAL; } - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Trying to move inst: %pK (%#x) from: %#x to %#x\n", inst, hash32_ptr(inst->session), inst->state, state); @@ -3837,7 +3837,7 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state) } flipped_state = get_flipped_state(inst->state, state); - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "inst: %pK (%#x) flipped_state = %#x\n", inst, hash32_ptr(inst->session), flipped_state); switch (flipped_state) { @@ -3881,7 +3881,7 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state) HAL_SESSION_STOP_DONE); if (rc || state <= get_flipped_state(inst->state, state)) break; - dprintk(VIDC_DBG, "Moving to Stop Done state\n"); + dprintk(VIDC_HIGH, "Moving to Stop Done state\n"); case MSM_VIDC_RELEASE_RESOURCES: rc = msm_vidc_release_res(flipped_state, inst); if (rc || state <= get_flipped_state(inst->state, state)) @@ -3892,7 +3892,7 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state) HAL_SESSION_RELEASE_RESOURCE_DONE); if (rc || state <= get_flipped_state(inst->state, state)) break; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Moving to release resources done state\n"); case MSM_VIDC_CLOSE: rc = msm_comm_session_close(flipped_state, inst); @@ -3906,7 +3906,7 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state) msm_comm_session_clean(inst); case MSM_VIDC_CORE_UNINIT: case MSM_VIDC_CORE_INVALID: - dprintk(VIDC_DBG, "Sending core uninit\n"); + dprintk(VIDC_HIGH, "Sending core uninit\n"); rc = msm_vidc_deinit_core(inst); if (rc || state == get_flipped_state(inst->state, state)) break; @@ -3955,7 +3955,7 @@ int msm_vidc_send_pending_eos_buffers(struct msm_vidc_inst *inst) data.timestamp = 0; data.extradata_addr = data.device_addr; data.extradata_size = 0; - dprintk(VIDC_DBG, "Queueing EOS buffer 0x%x\n", + dprintk(VIDC_HIGH, "Queueing EOS buffer 0x%x\n", data.device_addr); hdev = inst->core->device; @@ -4011,7 +4011,7 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd) u32 smem_flags = SMEM_UNCACHED; if (inst->state != MSM_VIDC_START_DONE) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Inst = %pK is not ready for EOS\n", inst); break; } @@ -4265,7 +4265,7 @@ static int msm_comm_qbuf_in_rbr(struct msm_vidc_inst *inst, if (rc) dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__); - print_vidc_buffer(VIDC_DBG, "qbuf in rbr", inst, mbuf); + print_vidc_buffer(VIDC_HIGH, "qbuf in rbr", inst, mbuf); rc = msm_comm_qbuf_to_hfi(inst, mbuf); if (rc) dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", __func__, rc); @@ -4289,7 +4289,7 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) if (inst->state != MSM_VIDC_START_DONE) { mbuf->flags |= MSM_VIDC_FLAG_DEFERRED; - print_vidc_buffer(VIDC_DBG, "qbuf deferred", inst, mbuf); + print_vidc_buffer(VIDC_HIGH, "qbuf deferred", inst, mbuf); return 0; } @@ -4301,7 +4301,7 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) if (rc) dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__); - print_vidc_buffer(VIDC_DBG, "qbuf", inst, mbuf); + print_vidc_buffer(VIDC_HIGH, "qbuf", inst, mbuf); rc = msm_comm_qbuf_to_hfi(inst, mbuf); if (rc) dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", __func__, rc); @@ -4321,7 +4321,7 @@ int msm_comm_qbufs(struct msm_vidc_inst *inst) } if (inst->state != MSM_VIDC_START_DONE) { - dprintk(VIDC_DBG, "%s: inst not in start state: %d\n", + dprintk(VIDC_HIGH, "%s: inst not in start state: %d\n", __func__, inst->state); return 0; } @@ -4338,7 +4338,7 @@ int msm_comm_qbufs(struct msm_vidc_inst *inst) } mutex_unlock(&inst->registeredbufs.lock); if (!found) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: no more deferred qbufs\n", __func__); break; } @@ -4386,7 +4386,7 @@ int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst, if (inst->state != MSM_VIDC_START_DONE) { mbuf->flags |= MSM_VIDC_FLAG_DEFERRED; - print_vidc_buffer(VIDC_DBG, "qbuf deferred", inst, mbuf); + print_vidc_buffer(VIDC_HIGH, "qbuf deferred", inst, mbuf); return 0; } @@ -4397,7 +4397,7 @@ int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst, if (inst->clk_data.buffer_counter > SKIP_BATCH_WINDOW) { count = num_pending_qbufs(inst, OUTPUT_MPLANE); if (count < inst->batch.size) { - print_vidc_buffer(VIDC_DBG, + print_vidc_buffer(VIDC_HIGH, "batch-qbuf deferred", inst, mbuf); return 0; } @@ -4419,7 +4419,7 @@ int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst, if (buf->flags & MSM_VIDC_FLAG_RBR_PENDING) goto loop_end; - print_vidc_buffer(VIDC_DBG, "batch-qbuf", inst, buf); + print_vidc_buffer(VIDC_HIGH, "batch-qbuf", inst, buf); rc = msm_comm_qbuf_to_hfi(inst, buf); if (rc) { dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", @@ -4496,15 +4496,15 @@ int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst) } } - dprintk(VIDC_DBG, "Buffer requirements :\n"); - dprintk(VIDC_DBG, "%15s %8s %8s %8s %8s %8s\n", + dprintk(VIDC_HIGH, "Buffer requirements :\n"); + dprintk(VIDC_HIGH, "%15s %8s %8s %8s %8s %8s\n", "buffer type", "count", "mincount_host", "mincount_fw", "size", "alignment"); for (i = 0; i < HAL_BUFFER_MAX; i++) { struct hal_buffer_requirements req = inst->buff_req.buffer[i]; if (req.buffer_type != HAL_BUFFER_NONE) { - dprintk(VIDC_DBG, "%15s %8d %8d %8d %8d %8d\n", + dprintk(VIDC_HIGH, "%15s %8d %8d %8d %8d %8d\n", get_buffer_name(req.buffer_type), req.buffer_count_actual, req.buffer_count_min_host, @@ -4605,7 +4605,7 @@ int msm_comm_release_dpb_only_buffers(struct msm_vidc_inst *inst, } mutex_lock(&inst->outputbufs.lock); if (list_empty(&inst->outputbufs.list)) { - dprintk(VIDC_DBG, "%s - No OUTPUT buffers allocated\n", + dprintk(VIDC_HIGH, "%s - No OUTPUT buffers allocated\n", __func__); mutex_unlock(&inst->outputbufs.lock); return 0; @@ -4628,7 +4628,7 @@ int msm_comm_release_dpb_only_buffers(struct msm_vidc_inst *inst, handle = &buf->smem; if ((buf->buffer_ownership == FIRMWARE) && !force_release) { - dprintk(VIDC_INFO, "DPB is with f/w. Can't free it\n"); + dprintk(VIDC_HIGH, "DPB is with f/w. Can't free it\n"); /* * mark this buffer to avoid sending it to video h/w * again, this buffer belongs to old resolution and @@ -4648,7 +4648,7 @@ int msm_comm_release_dpb_only_buffers(struct msm_vidc_inst *inst, rc = call_hfi_op(hdev, session_release_buffers, (void *)inst->session, &buffer_info); if (rc) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Rel output buf fail:%x, %d\n", buffer_info.align_device_addr, buffer_info.buffer_size); @@ -4699,7 +4699,7 @@ static enum hal_buffer scratch_buf_sufficient(struct msm_vidc_inst *inst, if (count != bufreq->buffer_count_actual) goto not_sufficient; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Existing scratch buffer is sufficient for buffer type %#x\n", buffer_type); @@ -4763,12 +4763,12 @@ int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst, rc = wait_for_sess_signal_receipt(inst, HAL_SESSION_RELEASE_BUFFER_DONE); if (rc) - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "%s: wait for signal failed, rc %d\n", __func__, rc); mutex_lock(&inst->scratchbufs.lock); } else { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Rel scrtch buf fail:%x, %d\n", buffer_info.align_device_addr, buffer_info.buffer_size); @@ -4872,12 +4872,12 @@ int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst) rc = wait_for_sess_signal_receipt(inst, HAL_SESSION_RELEASE_BUFFER_DONE); if (rc) - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "%s: wait for signal failed, rc %d\n", __func__, rc); mutex_lock(&inst->persistbufs.lock); } else { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Rel prst buf fail:%x, %d\n", buffer_info.align_device_addr, buffer_info.buffer_size); @@ -4902,7 +4902,7 @@ int msm_comm_set_buffer_count(struct msm_vidc_inst *inst, buf_count.buffer_type = get_hfi_buffer(type); buf_count.buffer_count_actual = act_count; buf_count.buffer_count_min_host = host_count; - dprintk(VIDC_DBG, "%s: %x : hal_buffer %d min_host %d actual %d\n", + dprintk(VIDC_HIGH, "%s: %x : hal_buffer %d min_host %d actual %d\n", __func__, hash32_ptr(inst->session), type, host_count, act_count); rc = call_hfi_op(hdev, session_set_property, @@ -4929,7 +4929,7 @@ int msm_comm_set_dpb_only_buffers(struct msm_vidc_inst *inst) force_release = false; if (msm_comm_release_dpb_only_buffers(inst, force_release)) - dprintk(VIDC_WARN, "Failed to release output buffers\n"); + dprintk(VIDC_ERR, "Failed to release output buffers\n"); rc = set_dpb_only_buffers(inst, HAL_BUFFER_OUTPUT); if (rc) @@ -4950,7 +4950,7 @@ int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst) } if (msm_comm_release_scratch_buffers(inst, true)) - dprintk(VIDC_WARN, "Failed to release scratch buffers\n"); + dprintk(VIDC_ERR, "Failed to release scratch buffers\n"); rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH, &inst->scratchbufs); @@ -4987,14 +4987,14 @@ int msm_comm_set_recon_buffers(struct msm_vidc_inst *inst) } if (inst->session_type != MSM_VIDC_ENCODER) { - dprintk(VIDC_DBG, "Recon buffs not req for decoder/cvp\n"); + dprintk(VIDC_HIGH, "Recon buffs not req for decoder/cvp\n"); return 0; } internal_buf = get_buff_req_buffer(inst, HAL_BUFFER_INTERNAL_RECON); if (!internal_buf || !internal_buf->buffer_count_actual) { - dprintk(VIDC_DBG, "Inst : %pK Recon buffers not required\n", + dprintk(VIDC_HIGH, "Inst : %pK Recon buffers not required\n", inst); return 0; } @@ -5066,7 +5066,7 @@ static void msm_comm_flush_in_invalid_state(struct msm_vidc_inst *inst) inst, vb); vb2_buffer_done(vb, VB2_BUF_STATE_DONE); } else { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "%s VB is in state %d not in ACTIVE state\n" , __func__, vb->state); } @@ -5106,7 +5106,7 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) op_flush = flags & V4L2_CMD_FLUSH_CAPTURE; if (ip_flush && !op_flush) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Input only flush not supported, making it flush all\n"); op_flush = true; return 0; @@ -5144,7 +5144,7 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) if (!(mbuf->smem[0].refcount >= 2)) continue; - print_vidc_buffer(VIDC_DBG, "flush buf", inst, mbuf); + print_vidc_buffer(VIDC_HIGH, "flush buf", inst, mbuf); msm_comm_flush_vidc_buffer(inst, mbuf); for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) { @@ -5169,11 +5169,11 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) hdev = inst->core->device; if (ip_flush) { - dprintk(VIDC_DBG, "Send flush on all ports to firmware\n"); + dprintk(VIDC_HIGH, "Send flush on all ports to firmware\n"); rc = call_hfi_op(hdev, session_flush, inst->session, HAL_FLUSH_ALL); } else { - dprintk(VIDC_DBG, "Send flush on output port to firmware\n"); + dprintk(VIDC_HIGH, "Send flush on output port to firmware\n"); rc = call_hfi_op(hdev, session_flush, inst->session, HAL_FLUSH_OUTPUT); } @@ -5194,7 +5194,7 @@ int msm_vidc_noc_error_info(struct msm_vidc_core *core) struct hfi_device *hdev; if (!core || !core->device) { - dprintk(VIDC_WARN, "%s: Invalid parameters: %pK\n", + dprintk(VIDC_ERR, "%s: Invalid parameters: %pK\n", __func__, core); return -EINVAL; } @@ -5215,7 +5215,7 @@ int msm_vidc_trigger_ssr(struct msm_vidc_core *core, enum hal_ssr_trigger_type type) { if (!core) { - dprintk(VIDC_WARN, "%s: Invalid parameters\n", __func__); + dprintk(VIDC_ERR, "%s: Invalid parameters\n", __func__); return -EINVAL; } core->ssr_type = type; @@ -5238,7 +5238,7 @@ void msm_vidc_ssr_handler(struct work_struct *work) mutex_lock(&core->lock); if (core->state == VIDC_CORE_INIT_DONE) { - dprintk(VIDC_WARN, "%s: ssr type %d\n", __func__, + dprintk(VIDC_ERR, "%s: ssr type %d\n", __func__, core->ssr_type); /* * In current implementation user-initiated SSR triggers @@ -5255,7 +5255,7 @@ void msm_vidc_ssr_handler(struct work_struct *work) core->trigger_ssr = false; } } else { - dprintk(VIDC_WARN, "%s: video core %pK not initialized\n", + dprintk(VIDC_ERR, "%s: video core %pK not initialized\n", __func__, core); } mutex_unlock(&core->lock); @@ -5274,7 +5274,7 @@ static int msm_vidc_check_mbpf_supported(struct msm_vidc_inst *inst) core = inst->core; if (!core->resources.max_mbpf) { - dprintk(VIDC_DBG, "%s: max mbpf not available\n", + dprintk(VIDC_HIGH, "%s: max mbpf not available\n", __func__); return 0; } @@ -5333,7 +5333,7 @@ int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst) struct v4l2_format *f; if (inst->grid_enable > 0) { - dprintk(VIDC_DBG, "Skip scaling check for HEIC\n"); + dprintk(VIDC_HIGH, "Skip scaling check for HEIC\n"); return 0; } @@ -5368,7 +5368,7 @@ int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst) return -ENOTSUPP; } - dprintk(VIDC_DBG, "%s: supported WxH = %dx%d\n", + dprintk(VIDC_HIGH, "%s: supported WxH = %dx%d\n", __func__, input_width, input_height); return 0; } @@ -5423,7 +5423,7 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) struct v4l2_format *f; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_WARN, "%s: Invalid parameter\n", __func__); + dprintk(VIDC_ERR, "%s: Invalid parameter\n", __func__); return -EINVAL; } capability = &inst->capability; @@ -5431,7 +5431,7 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) core = inst->core; rc = msm_vidc_check_mbps_supported(inst); if (rc) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "%s: Hardware is overloaded\n", __func__); return rc; } @@ -5441,7 +5441,7 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) return rc; if (!is_thermal_permissible(core)) { - dprintk(VIDC_WARN, + dprintk(VIDC_ERR, "Thermal level critical, stop all active sessions!\n"); return -ENOTSUPP; } @@ -5530,7 +5530,7 @@ void msm_comm_generate_session_error(struct msm_vidc_inst *inst) dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); return; } - dprintk(VIDC_WARN, "%s: inst %pK\n", __func__, inst); + dprintk(VIDC_ERR, "%s: inst %pK\n", __func__, inst); response.session_id = inst; response.status = VIDC_ERR_FAIL; handle_session_error(cmd, (void *)&response); @@ -5546,7 +5546,7 @@ void msm_comm_generate_sys_error(struct msm_vidc_inst *inst) dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); return; } - dprintk(VIDC_WARN, "%s: inst %pK\n", __func__, inst); + dprintk(VIDC_ERR, "%s: inst %pK\n", __func__, inst); core = inst->core; response.device_id = (u32) core->id; handle_sys_error(cmd, (void *) &response); @@ -5588,7 +5588,7 @@ int msm_comm_kill_session(struct msm_vidc_inst *inst) change_inst_state(inst, MSM_VIDC_CLOSE_DONE); msm_comm_session_clean(inst); - dprintk(VIDC_WARN, "%s: inst %pK session %x handled\n", __func__, + dprintk(VIDC_ERR, "%s: inst %pK session %x handled\n", __func__, inst, hash32_ptr(inst->session)); return rc; } @@ -5638,7 +5638,7 @@ void msm_vidc_fw_unload_handler(struct work_struct *work) if (list_empty(&core->instances) && core->state != VIDC_CORE_UNINIT) { if (core->state > VIDC_CORE_INIT) { - dprintk(VIDC_DBG, "Calling vidc_hal_core_release\n"); + dprintk(VIDC_HIGH, "Calling vidc_hal_core_release\n"); rc = call_hfi_op(hdev, core_release, hdev->hfi_device_data); if (rc) { @@ -5682,7 +5682,7 @@ int msm_comm_set_color_format(struct msm_vidc_inst *inst, dprintk(VIDC_ERR, "Failed to set input color format\n"); else - dprintk(VIDC_DBG, "Setting uncompressed colorformat to %#x\n", + dprintk(VIDC_HIGH, "Setting uncompressed colorformat to %#x\n", format); return rc; @@ -5763,13 +5763,13 @@ int msm_comm_session_continue(void *instance) mutex_lock(&inst->lock); if (inst->state >= MSM_VIDC_RELEASE_RESOURCES_DONE || inst->state < MSM_VIDC_START_DONE) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Inst %pK : Not in valid state to call %s\n", inst, __func__); goto sess_continue_fail; } if (inst->session_type == MSM_VIDC_DECODER && inst->in_reconfig) { - dprintk(VIDC_DBG, "send session_continue\n"); + dprintk(VIDC_HIGH, "send session_continue\n"); rc = call_hfi_op(hdev, session_continue, (void *)inst->session); if (rc) { @@ -5796,7 +5796,7 @@ int msm_comm_session_continue(void *instance) } } } else if (inst->session_type == MSM_VIDC_ENCODER) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "session_continue not supported for encoder"); } else { dprintk(VIDC_ERR, @@ -6327,7 +6327,7 @@ struct msm_vidc_buffer *msm_comm_get_vidc_buffer(struct msm_vidc_inst *inst, rc = -EEXIST; } if (rc == -EEXIST) { - print_vidc_buffer(VIDC_DBG, + print_vidc_buffer(VIDC_HIGH, "existing qbuf", inst, mbuf); /* enable RBR pending */ mbuf->flags |= MSM_VIDC_FLAG_RBR_PENDING; @@ -6388,7 +6388,7 @@ void msm_comm_put_vidc_buffer(struct msm_vidc_inst *inst, goto unlock; } - print_vidc_buffer(VIDC_DBG, "dqbuf", inst, mbuf); + print_vidc_buffer(VIDC_HIGH, "dqbuf", inst, mbuf); for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) { if (inst->smem_ops->smem_unmap_dma_buf(inst, &mbuf->smem[i])) print_vidc_buffer(VIDC_ERR, @@ -6491,7 +6491,7 @@ void handle_release_buffer_reference(struct msm_vidc_inst *inst, /* buffer found means client queued the buffer already */ if (inst->in_reconfig || inst->in_flush) { - print_vidc_buffer(VIDC_DBG, "rbr flush buf", inst, mbuf); + print_vidc_buffer(VIDC_HIGH, "rbr flush buf", inst, mbuf); msm_comm_flush_vidc_buffer(inst, mbuf); msm_comm_unmap_vidc_buffer(inst, mbuf); /* remove from list */ @@ -6613,7 +6613,7 @@ void msm_comm_store_filled_length(struct msm_vidc_list *data_list, if (!found) { pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) { - dprintk(VIDC_WARN, "%s: malloc failure.\n", __func__); + dprintk(VIDC_ERR, "%s: malloc failure.\n", __func__); goto exit; } pdata->index = index; @@ -6671,7 +6671,7 @@ void msm_comm_store_mark_data(struct msm_vidc_list *data_list, if (!found) { pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) { - dprintk(VIDC_WARN, "%s: malloc failure.\n", __func__); + dprintk(VIDC_ERR, "%s: malloc failure.\n", __func__); goto exit; } pdata->index = index; @@ -6770,7 +6770,7 @@ int msm_comm_set_color_format_constraints(struct msm_vidc_inst *inst, pconstraint->buffer_type = get_hfi_buffer(buffer_type); pconstraint->num_planes = pix_constraint->num_planes; //set Y plan constraints - dprintk(VIDC_INFO, "Set Y plan constraints.\n"); + dprintk(VIDC_HIGH, "Set Y plan constraints.\n"); pconstraint->rg_plane_format[0].stride_multiples = VENUS_Y_STRIDE(hfi_fmt, 1); pconstraint->rg_plane_format[0].max_stride = @@ -6781,7 +6781,7 @@ int msm_comm_set_color_format_constraints(struct msm_vidc_inst *inst, pix_constraint->y_buffer_alignment; //set UV plan constraints - dprintk(VIDC_INFO, "Set UV plan constraints.\n"); + dprintk(VIDC_HIGH, "Set UV plan constraints.\n"); pconstraint->rg_plane_format[1].stride_multiples = VENUS_UV_STRIDE(hfi_fmt, 1); pconstraint->rg_plane_format[1].max_stride = @@ -6801,7 +6801,7 @@ int msm_comm_set_color_format_constraints(struct msm_vidc_inst *inst, dprintk(VIDC_ERR, "Failed to set input color format constraint\n"); else - dprintk(VIDC_DBG, "Set color format constraint success\n"); + dprintk(VIDC_HIGH, "Set color format constraint success\n"); exit: if (!pconstraint) diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index 2511d1a3ed8d..018db00d2d60 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -9,7 +9,7 @@ #include "vidc_hfi_api.h" #include -int msm_vidc_debug = VIDC_ERR | VIDC_WARN | VIDC_PRINTK | +int msm_vidc_debug = VIDC_ERR | VIDC_PRINTK | FW_HIGH | FW_ERROR | FW_FATAL | FW_FTRACE; EXPORT_SYMBOL(msm_vidc_debug); @@ -76,7 +76,7 @@ static ssize_t core_info_read(struct file *file, char __user *buf, cur += write_str(cur, end - cur, "Core state: %d\n", core->state); rc = call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data, &fw_info); if (rc) { - dprintk(VIDC_WARN, "Failed to read FW info\n"); + dprintk(VIDC_ERR, "Failed to read FW info\n"); goto err_fw_info; } @@ -129,14 +129,14 @@ static ssize_t trigger_ssr_write(struct file *filp, const char __user *buf, size = count; if (copy_from_user(kbuf, buf, size)) { - dprintk(VIDC_WARN, "%s User memory fault\n", __func__); + dprintk(VIDC_ERR, "%s User memory fault\n", __func__); rc = -EFAULT; goto exit; } rc = kstrtoul(kbuf, 0, &ssr_trigger_val); if (rc) { - dprintk(VIDC_WARN, "returning error err %d\n", rc); + dprintk(VIDC_ERR, "returning error err %d\n", rc); rc = -EINVAL; } else { msm_vidc_trigger_ssr(core, ssr_trigger_val); @@ -233,7 +233,7 @@ struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core, static int inst_info_open(struct inode *inode, struct file *file) { - dprintk(VIDC_INFO, "Open inode ptr: %pK\n", inode->i_private); + dprintk(VIDC_LOW, "Open inode ptr: %pK\n", inode->i_private); file->private_data = inode->i_private; return 0; } @@ -395,7 +395,7 @@ static ssize_t inst_info_read(struct file *file, char __user *buf, static int inst_info_release(struct inode *inode, struct file *file) { - dprintk(VIDC_INFO, "Release inode ptr: %pK\n", inode->i_private); + dprintk(VIDC_LOW, "Release inode ptr: %pK\n", inode->i_private); file->private_data = NULL; return 0; } @@ -463,7 +463,7 @@ void msm_vidc_debugfs_deinit_inst(struct msm_vidc_inst *inst) dentry = inst->debugfs_root; if (dentry->d_inode) { - dprintk(VIDC_INFO, "Destroy %pK\n", dentry->d_inode->i_private); + dprintk(VIDC_LOW, "Destroy %pK\n", dentry->d_inode->i_private); kfree(dentry->d_inode->i_private); dentry->d_inode->i_private = NULL; } @@ -489,10 +489,10 @@ void msm_vidc_debugfs_update(struct msm_vidc_inst *inst, inst->count.ebd++; if (inst->count.ebd && inst->count.ebd == inst->count.etb) { toc(inst, FRAME_PROCESSING); - dprintk(VIDC_PROF, "EBD: FW needs input buffers\n"); + dprintk(VIDC_PERF, "EBD: FW needs input buffers\n"); } if (inst->count.ftb == inst->count.fbd) - dprintk(VIDC_PROF, "EBD: FW needs output buffers\n"); + dprintk(VIDC_PERF, "EBD: FW needs output buffers\n"); break; case MSM_VIDC_DEBUGFS_EVENT_FTB: { inst->count.ftb++; @@ -508,10 +508,10 @@ void msm_vidc_debugfs_update(struct msm_vidc_inst *inst, if (inst->count.fbd && inst->count.fbd == inst->count.ftb) { toc(inst, FRAME_PROCESSING); - dprintk(VIDC_PROF, "FBD: FW needs output buffers\n"); + dprintk(VIDC_PERF, "FBD: FW needs output buffers\n"); } if (inst->count.etb == inst->count.ebd) - dprintk(VIDC_PROF, "FBD: FW needs input buffers\n"); + dprintk(VIDC_PERF, "FBD: FW needs input buffers\n"); break; default: dprintk(VIDC_ERR, "Invalid state in debugfs: %d\n", e); diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index 181683965fbb..e16376611f6d 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -33,11 +33,10 @@ enum vidc_msg_prio { VIDC_ERR = 0x00000001, - VIDC_WARN = 0x00000002, - VIDC_INFO = 0x00000004, - VIDC_DBG = 0x00000008, - VIDC_PROF = 0x00000010, - VIDC_PKT = 0x00000020, + VIDC_HIGH = 0x00000002, + VIDC_LOW = 0x00000004, + VIDC_PERF = 0x00000008, + VIDC_PKT = 0x00000010, VIDC_PRINTK = 0x00001000, VIDC_FTRACE = 0x00002000, FW_LOW = 0x00010000, @@ -119,7 +118,7 @@ extern bool msm_vidc_cvp_usage; #define MSM_VIDC_ERROR(value) \ do { if (value) \ - dprintk(VIDC_DBG, "BugOn"); \ + dprintk(VIDC_ERR, "BugOn"); \ BUG_ON(value); \ } while (0) @@ -139,14 +138,12 @@ static inline char *get_debug_level_str(int level) switch (level) { case VIDC_ERR: return "err"; - case VIDC_WARN: - return "warn"; - case VIDC_INFO: - return "info"; - case VIDC_DBG: - return "dbg"; - case VIDC_PROF: - return "prof"; + case VIDC_HIGH: + return "high"; + case VIDC_LOW: + return "low"; + case VIDC_PERF: + return "perf"; case VIDC_PKT: return "pkt"; default: @@ -161,7 +158,7 @@ static inline void tic(struct msm_vidc_inst *i, enum profiling_points p, if (!i->debug.pdata[p].name[0]) memcpy(i->debug.pdata[p].name, b, 64); - if ((msm_vidc_debug & VIDC_PROF) && + if ((msm_vidc_debug & VIDC_PERF) && i->debug.pdata[p].sampling) { do_gettimeofday(&__ddl_tv); i->debug.pdata[p].start = @@ -174,7 +171,7 @@ static inline void toc(struct msm_vidc_inst *i, enum profiling_points p) { struct timeval __ddl_tv; - if ((msm_vidc_debug & VIDC_PROF) && + if ((msm_vidc_debug & VIDC_PERF) && !i->debug.pdata[p].sampling) { do_gettimeofday(&__ddl_tv); i->debug.pdata[p].stop = (__ddl_tv.tv_sec * 1000) @@ -191,15 +188,15 @@ static inline void show_stats(struct msm_vidc_inst *i) for (x = 0; x < MAX_PROFILING_POINTS; x++) { if (i->debug.pdata[x].name[0] && - (msm_vidc_debug & VIDC_PROF)) { + (msm_vidc_debug & VIDC_PERF)) { if (i->debug.samples) { - dprintk(VIDC_PROF, "%s averaged %d ms/sample\n", + dprintk(VIDC_PERF, "%s averaged %d ms/sample\n", i->debug.pdata[x].name, i->debug.pdata[x].cumulative / i->debug.samples); } - dprintk(VIDC_PROF, "%s Samples: %d\n", + dprintk(VIDC_PERF, "%s Samples: %d\n", i->debug.pdata[x].name, i->debug.samples); } diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 97a734ad5391..6c0e40519bfa 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1073,7 +1073,7 @@ static int msm_vidc_read_efuse( data->sku_version = (efuse & (efuse_data[i]).mask) >> (efuse_data[i]).shift; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "efuse 0x%x, platform version 0x%x\n", efuse, data->sku_version); @@ -1124,7 +1124,7 @@ void *vidc_get_drv_data(struct device *dev) dprintk(VIDC_ERR, "Failed to get ddr type, use LPDDR5\n"); } - dprintk(VIDC_DBG, "DDR Type %x\n", ddr_type); + dprintk(VIDC_HIGH, "DDR Type %x\n", ddr_type); if (driver_data->ubwc_config && (ddr_type == DDR_TYPE_LPDDR4 || diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 816a8a4eac14..b0a95ce4724d 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -143,7 +143,7 @@ static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res) * qcom,reg-presets is an optional property. It likely won't be * present if we don't have any register settings to program */ - dprintk(VIDC_DBG, "qcom,reg-presets not found\n"); + dprintk(VIDC_HIGH, "qcom,reg-presets not found\n"); return 0; } @@ -153,7 +153,7 @@ static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res) reg_set->count /= sizeof(*reg_set->reg_tbl) / sizeof(u32); if (!reg_set->count) { - dprintk(VIDC_DBG, "no elements in reg set\n"); + dprintk(VIDC_HIGH, "no elements in reg set\n"); return rc; } @@ -172,7 +172,7 @@ static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res) return -EINVAL; } for (i = 0; i < reg_set->count; i++) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "reg = %x, value = %x\n", reg_set->reg_tbl[i].reg, reg_set->reg_tbl[i].value @@ -192,7 +192,7 @@ static int msm_vidc_load_qdss_table(struct msm_vidc_platform_resources *res) * qcom,qdss-presets is an optional property. It likely won't be * present if we don't have any register settings to program */ - dprintk(VIDC_DBG, "qcom,qdss-presets not found\n"); + dprintk(VIDC_HIGH, "qcom,qdss-presets not found\n"); return rc; } @@ -202,7 +202,7 @@ static int msm_vidc_load_qdss_table(struct msm_vidc_platform_resources *res) qdss_addr_set->count /= sizeof(*qdss_addr_set->addr_tbl) / sizeof(u32); if (!qdss_addr_set->count) { - dprintk(VIDC_DBG, "no elements in qdss reg set\n"); + dprintk(VIDC_HIGH, "no elements in qdss reg set\n"); return rc; } @@ -226,7 +226,7 @@ static int msm_vidc_load_qdss_table(struct msm_vidc_platform_resources *res) } for (i = 0; i < qdss_addr_set->count; i++) { - dprintk(VIDC_DBG, "qdss addr = %x, value = %x\n", + dprintk(VIDC_HIGH, "qdss addr = %x, value = %x\n", qdss_addr_set->addr_tbl[i].start, qdss_addr_set->addr_tbl[i].size); } @@ -243,7 +243,7 @@ static int msm_vidc_load_subcache_info(struct msm_vidc_platform_resources *res) num_subcaches = of_property_count_strings(pdev->dev.of_node, "cache-slice-names"); if (num_subcaches <= 0) { - dprintk(VIDC_DBG, "No subcaches found\n"); + dprintk(VIDC_HIGH, "No subcaches found\n"); goto err_load_subcache_table_fail; } @@ -257,7 +257,7 @@ static int msm_vidc_load_subcache_info(struct msm_vidc_platform_resources *res) } subcaches->count = num_subcaches; - dprintk(VIDC_DBG, "Found %d subcaches\n", num_subcaches); + dprintk(VIDC_HIGH, "Found %d subcaches\n", num_subcaches); for (c = 0; c < num_subcaches; ++c) { struct subcache_info *vsc = &res->subcache_set.subcache_tbl[c]; @@ -303,7 +303,7 @@ int msm_vidc_load_u32_table(struct platform_device *pdev, u32 *ptbl = NULL; if (!of_find_property(of_node, table_name, NULL)) { - dprintk(VIDC_DBG, "%s not found\n", table_name); + dprintk(VIDC_HIGH, "%s not found\n", table_name); return 0; } @@ -350,7 +350,7 @@ static int msm_vidc_load_allowed_clocks_table( if (!of_find_property(pdev->dev.of_node, "qcom,allowed-clock-rates", NULL)) { - dprintk(VIDC_DBG, "qcom,allowed-clock-rates not found\n"); + dprintk(VIDC_HIGH, "qcom,allowed-clock-rates not found\n"); return 0; } @@ -436,7 +436,7 @@ static int msm_vidc_populate_bus(struct device *dev, range, ARRAY_SIZE(range)); if (rc) { rc = 0; - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "'qcom,range' not found defaulting to <0 INT_MAX>\n"); range[0] = 0; range[1] = INT_MAX; @@ -447,7 +447,7 @@ static int msm_vidc_populate_bus(struct device *dev, buses->count++; bus->dev = dev; - dprintk(VIDC_DBG, "Found bus %s [%d->%d] with mode %s\n", + dprintk(VIDC_HIGH, "Found bus %s [%d->%d] with mode %s\n", bus->name, bus->master, bus->slave, bus->mode); err_bus: return rc; @@ -467,7 +467,7 @@ static int msm_vidc_load_buffer_usage_table( * likely won't be present if the core doesn't support content * protection */ - dprintk(VIDC_DBG, "buffer-type-tz-usage-table not found\n"); + dprintk(VIDC_HIGH, "buffer-type-tz-usage-table not found\n"); return 0; } @@ -476,7 +476,7 @@ static int msm_vidc_load_buffer_usage_table( buffer_usage_set->count /= sizeof(*buffer_usage_set->buffer_usage_tbl) / sizeof(u32); if (!buffer_usage_set->count) { - dprintk(VIDC_DBG, "no elements in buffer usage set\n"); + dprintk(VIDC_HIGH, "no elements in buffer usage set\n"); return 0; } @@ -565,7 +565,7 @@ static int msm_vidc_load_regulator_table( regulator_node = of_parse_phandle(domains_parent_node, domains_property->name, 0); if (IS_ERR(regulator_node)) { - dprintk(VIDC_WARN, "%s is not a phandle\n", + dprintk(VIDC_ERR, "%s is not a phandle\n", domains_property->name); continue; } @@ -587,13 +587,13 @@ static int msm_vidc_load_regulator_table( rinfo->has_hw_power_collapse = of_property_read_bool( regulator_node, "qcom,support-hw-trigger"); - dprintk(VIDC_DBG, "Found regulator %s: h/w collapse = %s\n", + dprintk(VIDC_HIGH, "Found regulator %s: h/w collapse = %s\n", rinfo->name, rinfo->has_hw_power_collapse ? "yes" : "no"); } if (!regulators->count) - dprintk(VIDC_DBG, "No regulators found"); + dprintk(VIDC_HIGH, "No regulators found"); return 0; @@ -614,7 +614,7 @@ static int msm_vidc_load_clock_table( num_clocks = of_property_count_strings(pdev->dev.of_node, "clock-names"); if (num_clocks <= 0) { - dprintk(VIDC_DBG, "No clocks found\n"); + dprintk(VIDC_HIGH, "No clocks found\n"); clocks->count = 0; rc = 0; goto err_load_clk_table_fail; @@ -645,7 +645,7 @@ static int msm_vidc_load_clock_table( } clocks->count = num_clocks; - dprintk(VIDC_DBG, "Found %d clocks\n", num_clocks); + dprintk(VIDC_HIGH, "Found %d clocks\n", num_clocks); for (c = 0; c < num_clocks; ++c) { struct clock_info *vc = &res->clock_set.clock_tbl[c]; @@ -664,7 +664,7 @@ static int msm_vidc_load_clock_table( else vc->has_mem_retention = false; - dprintk(VIDC_DBG, "Found clock %s: scale-able = %s\n", vc->name, + dprintk(VIDC_HIGH, "Found clock %s: scale-able = %s\n", vc->name, vc->has_scaling ? "yes" : "no"); } @@ -686,7 +686,7 @@ static int msm_vidc_load_reset_table( num_clocks = of_property_count_strings(pdev->dev.of_node, "reset-names"); if (num_clocks <= 0) { - dprintk(VIDC_DBG, "No reset clocks found\n"); + dprintk(VIDC_HIGH, "No reset clocks found\n"); rst->count = 0; return 0; } @@ -697,7 +697,7 @@ static int msm_vidc_load_reset_table( return -ENOMEM; rst->count = num_clocks; - dprintk(VIDC_DBG, "Found %d reset clocks\n", num_clocks); + dprintk(VIDC_HIGH, "Found %d reset clocks\n", num_clocks); for (c = 0; c < num_clocks; ++c) { struct reset_info *rc = &res->reset_set.reset_tbl[c]; @@ -719,12 +719,12 @@ static int msm_decide_dt_node( rc = of_property_read_u32(pdev->dev.of_node, "sku-index", &sku_index); if (rc) { - dprintk(VIDC_DBG, "'sku_index' not found in node\n"); + dprintk(VIDC_HIGH, "'sku_index' not found in node\n"); return 0; } if (sku_index != res->sku_version) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Failed to parser dt: sku_index %d res->sku_version - %d\n", sku_index, res->sku_version); return -EINVAL; @@ -772,7 +772,7 @@ int read_platform_resources_from_drv_data( res->fw_name = "venus"; - dprintk(VIDC_DBG, "Firmware filename: %s\n", res->fw_name); + dprintk(VIDC_HIGH, "Firmware filename: %s\n", res->fw_name); res->max_load = find_key_value(platform_data, "qcom,max-hw-load"); @@ -859,7 +859,7 @@ static int msm_vidc_populate_cx_ipeak_context( if (IS_ERR(res->cx_ipeak_context)) { rc = PTR_ERR(res->cx_ipeak_context); if (rc == -EPROBE_DEFER) - dprintk(VIDC_INFO, + dprintk(VIDC_HIGH, "cx-ipeak register failed. Deferring probe!"); else dprintk(VIDC_ERR, @@ -870,14 +870,14 @@ static int msm_vidc_populate_cx_ipeak_context( } if (res->cx_ipeak_context) - dprintk(VIDC_INFO, "cx-ipeak register successful"); + dprintk(VIDC_HIGH, "cx-ipeak register successful"); else - dprintk(VIDC_INFO, "cx-ipeak register not implemented"); + dprintk(VIDC_HIGH, "cx-ipeak register not implemented"); of_property_read_u32(pdev->dev.of_node, "qcom,clock-freq-threshold", &res->clk_freq_threshold); - dprintk(VIDC_DBG, "cx ipeak threshold frequency = %u\n", + dprintk(VIDC_HIGH, "cx ipeak threshold frequency = %u\n", res->clk_freq_threshold); return rc; @@ -914,11 +914,11 @@ int read_platform_resources_from_dt( rc = msm_vidc_load_subcache_info(res); if (rc) - dprintk(VIDC_WARN, "Failed to load subcache info: %d\n", rc); + dprintk(VIDC_ERR, "Failed to load subcache info: %d\n", rc); rc = msm_vidc_load_qdss_table(res); if (rc) - dprintk(VIDC_WARN, "Failed to load qdss reg table: %d\n", rc); + dprintk(VIDC_ERR, "Failed to load qdss reg table: %d\n", rc); rc = msm_vidc_load_reg_table(res); if (rc) { @@ -1026,8 +1026,8 @@ static int msm_vidc_setup_context_bank(struct msm_vidc_platform_resources *res, dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); dma_set_seg_boundary(dev, DMA_BIT_MASK(64)); - dprintk(VIDC_DBG, "Attached %s and created mapping\n", dev_name(dev)); - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Attached %s and created mapping\n", dev_name(dev)); + dprintk(VIDC_HIGH, "Context bank name:%s, buffer_type: %#x, is_secure: %d, address range start: %#x, size: %#x, dev: %pK, domain: %pK", cb->name, cb->buffer_type, cb->is_secure, cb->addr_range.start, cb->addr_range.size, cb->dev, cb->domain); @@ -1098,12 +1098,12 @@ static int msm_vidc_populate_context_bank(struct device *dev, rc = of_property_read_string(np, "label", &cb->name); if (rc) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "Failed to read cb label from device tree\n"); rc = 0; } - dprintk(VIDC_DBG, "%s: context bank has name %s\n", __func__, cb->name); + dprintk(VIDC_HIGH, "%s: context bank has name %s\n", __func__, cb->name); rc = of_property_read_u32_array(np, "virtual-addr-pool", (u32 *)&cb->addr_range, 2); if (rc) { @@ -1114,7 +1114,7 @@ static int msm_vidc_populate_context_bank(struct device *dev, } cb->is_secure = of_property_read_bool(np, "qcom,secure-context-bank"); - dprintk(VIDC_DBG, "context bank %s : secure = %d\n", + dprintk(VIDC_HIGH, "context bank %s : secure = %d\n", cb->name, cb->is_secure); /* setup buffer type for each sub device*/ @@ -1124,7 +1124,7 @@ static int msm_vidc_populate_context_bank(struct device *dev, rc = -ENOENT; goto err_setup_cb; } - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "context bank %s address start = %x address size = %x buffer_type = %x\n", cb->name, cb->addr_range.start, cb->addr_range.size, cb->buffer_type); @@ -1164,7 +1164,7 @@ static int msm_vidc_populate_legacy_context_bank( domains_parent_node = of_find_node_by_name(pdev->dev.of_node, "qcom,vidc-iommu-domains"); if (!domains_parent_node) { - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s legacy iommu domains not present\n", __func__); return 0; } @@ -1231,7 +1231,7 @@ static int msm_vidc_populate_legacy_context_bank( dprintk(VIDC_ERR, "Cannot setup context bank %d\n", rc); goto err_setup_cb; } - dprintk(VIDC_DBG, + dprintk(VIDC_HIGH, "%s: context bank %s secure %d addr start = %#x addr size = %#x buffer_type = %#x\n", __func__, cb->name, cb->is_secure, cb->addr_range.start, cb->addr_range.size, cb->buffer_type); @@ -1268,7 +1268,7 @@ int read_context_bank_resources_from_dt(struct platform_device *pdev) if (rc) dprintk(VIDC_ERR, "Failed to probe context bank\n"); else - dprintk(VIDC_DBG, "Successfully probed context bank\n"); + dprintk(VIDC_HIGH, "Successfully probed context bank\n"); return rc; } From 0c95602a7bdb6c125d39fd8e5d2dd8077436a30e Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Wed, 29 May 2019 19:49:43 +0530 Subject: [PATCH 037/452] msm-vidc: update supported resolution for VP8 decoder/encoder. Update max supported height to 1920 for Vp8. Change-Id: Ic8013967b73ea538045bdb89dabe34bdc6559359 --- msm/vidc/msm_vidc_platform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 6c0e40519bfa..0ab19939dfb9 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -188,7 +188,7 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { /* VP8 specific */ {CAP_FRAME_WIDTH, ENC|DEC, VP8, 96, 1920, 1, 1920}, - {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 96, 1080, 1, 1080}, + {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 96, 1920, 1, 1080}, /* (1920 * 1088) / 256 */ {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 1, 8160, 1, 8160}, /* ((1920 * 1088) / 256) * 120*/ @@ -246,7 +246,7 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { /* VP8 specific */ {CAP_FRAME_WIDTH, ENC|DEC, VP8, 96, 1920, 1, 1920}, - {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 96, 1080, 1, 1080}, + {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 96, 1920, 1, 1080}, /* (1920 * 1088) / 256 */ {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 1, 8160, 1, 8160}, /* ((1920 * 1088) / 256) * 120*/ From e8ea75982225742c45f85196d3f06d4ce3cde71a Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Fri, 31 May 2019 11:51:52 -0700 Subject: [PATCH 038/452] msm: vidc: amend cvp module structures Align strctures as expected by CVP firmware. Change-Id: Ib0a379d8dbcf0c65a8eef1561778f2fa972b517c Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_cvp_external.c | 73 ++++++++++++++++++++++++++++++++----- msm/vidc/msm_cvp_external.h | 46 ++++++++++++++++++----- 2 files changed, 100 insertions(+), 19 deletions(-) diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index 10976ee06687..fe470d7d7951 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -22,7 +22,41 @@ static void print_cvp_buffer(u32 tag, const char *str, cbuf->offset, cbuf->dbuf, cbuf->kvaddr); } -static int msm_cvp_fill_planeinfo(struct cvp_kmd_color_plane_info *plane_info, +static int msm_cvp_get_version_info(struct msm_vidc_inst *inst) +{ + int rc; + struct msm_cvp_external *cvp; + struct cvp_kmd_arg *arg; + struct cvp_kmd_sys_properties *sys_prop; + struct cvp_kmd_sys_property *prop_data; + u32 version; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; + arg = cvp->arg; + + memset(arg, 0, sizeof(struct cvp_kmd_arg)); + arg->type = CVP_KMD_GET_SYS_PROPERTY; + sys_prop = (struct cvp_kmd_sys_properties *)&arg->data.sys_properties; + sys_prop->prop_num = CVP_KMD_HFI_VERSION_PROP_NUMBER; + prop_data = (struct cvp_kmd_sys_property *) + &arg->data.sys_properties.prop_data; + prop_data->prop_type = CVP_KMD_HFI_VERSION_PROP_TYPE; + rc = msm_cvp_private(cvp->priv, CVP_KMD_GET_SYS_PROPERTY, arg); + if (rc) { + dprintk(VIDC_ERR, "%s: failed, rc %d\n", __func__, rc); + return rc; + } + version = prop_data->data; + dprintk(VIDC_HIGH, "%s: version %#x\n", __func__, version); + + return 0; +} + +static int msm_cvp_fill_planeinfo(struct msm_cvp_color_plane_info *plane_info, u32 color_fmt, u32 width, u32 height) { int rc = 0; @@ -420,8 +454,14 @@ static void msm_cvp_deinit_internal_buffers(struct msm_vidc_inst *inst) arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL); if (arg) { - memset(arg, 0, sizeof(struct cvp_kmd_arg)); arg->type = CVP_KMD_HFI_PERSIST_CMD; + arg->buf_offset = offsetof(struct + msm_cvp_session_release_persist_buffers_packet, + persist1_buffer) / sizeof(u32); + arg->buf_num = (sizeof(struct + msm_cvp_session_release_persist_buffers_packet) - + (arg->buf_offset * sizeof(u32))) / + sizeof(struct msm_cvp_buffer_type); memcpy(&(arg->data.pbuf_cmd), &persist2_packet, sizeof(struct msm_cvp_session_release_persist_buffers_packet)); @@ -432,6 +472,8 @@ static void msm_cvp_deinit_internal_buffers(struct msm_vidc_inst *inst) "release failed: persist2_buffer", inst, &cvp->persist2_buffer); kfree(arg); + } else { + dprintk(VIDC_ERR, "%s: alloc failed\n", __func__); } rc = msm_cvp_free_buffer(inst, &cvp->persist2_buffer); @@ -481,11 +523,13 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst) memset(arg, 0, sizeof(struct cvp_kmd_arg)); arg->type = CVP_KMD_HFI_PERSIST_CMD; - if (sizeof(struct cvp_kmd_persist_buf) < - sizeof(struct msm_cvp_session_set_persist_buffers_packet)) { - dprintk(VIDC_ERR, "%s: insufficient size\n", __func__); - goto error; - } + arg->buf_offset = offsetof( + struct msm_cvp_session_set_persist_buffers_packet, + persist1_buffer) / sizeof(u32); + arg->buf_num = (sizeof( + struct msm_cvp_session_set_persist_buffers_packet) - + (arg->buf_offset * sizeof(u32))) / + sizeof(struct msm_cvp_buffer_type); memcpy(&(arg->data.pbuf_cmd), &persist2_packet, sizeof(struct msm_cvp_session_set_persist_buffers_packet)); rc = msm_cvp_private(cvp->priv, CVP_KMD_HFI_PERSIST_CMD, arg); @@ -522,7 +566,7 @@ static int msm_cvp_prepare_extradata(struct msm_vidc_inst *inst, struct msm_cvp_external *cvp; struct vb2_buffer *vb; struct dma_buf *dbuf; - char *kvaddr; + char *kvaddr = NULL; struct msm_vidc_extradata_header *e_hdr; bool input_extradata, found_end; @@ -718,9 +762,14 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, return 0; } + memset(arg, 0, sizeof(struct cvp_kmd_arg)); arg->type = CVP_KMD_SEND_CMD_PKT; + arg->buf_offset = offsetof(struct msm_cvp_dme_frame_packet, + fullres_srcbuffer) / sizeof(u32); + arg->buf_num = (sizeof(struct msm_cvp_dme_frame_packet) - + (arg->buf_offset * sizeof(u32))) / + sizeof(struct msm_cvp_buffer_type); frame = (struct msm_cvp_dme_frame_packet *)&arg->data.hfi_pkt.pkt_data; - frame->size = sizeof(struct msm_cvp_dme_frame_packet); frame->packet_type = HFI_CMD_SESSION_CVP_DME_FRAME; frame->session_id = cvp->session_id; @@ -1004,6 +1053,12 @@ static int msm_vidc_cvp_open(struct msm_vidc_inst *inst) dprintk(VIDC_HIGH, "%s: cvp session id %#x\n", __func__, cvp->session_id); + rc = msm_cvp_get_version_info(inst); + if (rc) { + dprintk(VIDC_ERR, "%s: get_version_info failed\n", __func__); + goto error; + } + return 0; error: diff --git a/msm/vidc/msm_cvp_external.h b/msm/vidc/msm_cvp_external.h index 522bf938452d..5983e7e71f3b 100644 --- a/msm/vidc/msm_cvp_external.h +++ b/msm/vidc/msm_cvp_external.h @@ -37,6 +37,14 @@ #define HFI_DME_INTERNAL_PERSIST_2_BUFFER_SIZE (512 * 1024) #define HFI_DME_FRAME_CONTEXT_BUFFER_SIZE (64 * 1024) +#define CVP_KMD_HFI_VERSION_PROP_TYPE (1) +#define CVP_KMD_HFI_VERSION_PROP_NUMBER (1) + +static inline bool is_vidc_cvp_enabled(struct msm_vidc_inst *inst) +{ + return !!inst->cvp; +} + enum HFI_COLOR_PLANE_TYPE { HFI_COLOR_PLANE_METADATA, HFI_COLOR_PLANE_PICDATA, @@ -45,21 +53,35 @@ enum HFI_COLOR_PLANE_TYPE { HFI_MAX_COLOR_PLANES }; -static inline bool is_vidc_cvp_enabled(struct msm_vidc_inst *inst) -{ - return !!inst->cvp; -} +struct msm_cvp_color_plane_info { + u32 stride[HFI_MAX_COLOR_PLANES]; + u32 buf_size[HFI_MAX_COLOR_PLANES]; +}; + +struct msm_cvp_client_data { + u32 transactionid; + u32 client_data1; + u32 client_data2; + u32 kernel_data1; + u32 kernel_data2; + u32 reserved1; + u32 reserved2; +}; struct msm_cvp_buffer_type { u32 buffer_addr; u32 size; + u32 offset; + u32 flags; + u32 reserved1; + u32 reserved2; }; struct msm_cvp_session_release_persist_buffers_packet { u32 size; u32 packet_type; u32 session_id; - struct cvp_kmd_client_data client_data; + struct msm_cvp_client_data client_data; u32 cvp_op; struct msm_cvp_buffer_type persist1_buffer; struct msm_cvp_buffer_type persist2_buffer; @@ -69,7 +91,7 @@ struct msm_cvp_session_set_persist_buffers_packet { u32 size; u32 packet_type; u32 session_id; - struct cvp_kmd_client_data client_data; + struct msm_cvp_client_data client_data; u32 cvp_op; struct msm_cvp_buffer_type persist1_buffer; struct msm_cvp_buffer_type persist2_buffer; @@ -79,13 +101,16 @@ struct msm_cvp_dme_frame_packet { u32 size; u32 packet_type; u32 session_id; - struct cvp_kmd_client_data client_data; + struct msm_cvp_client_data client_data; + u32 stream_idx; u32 skip_mv_calc; u32 min_fpx_threshold; u32 enable_descriptor_lpf; u32 enable_ncc_subpel; u32 descmatch_threshold; int ncc_robustness_threshold; + u32 reserved[8]; + u32 buf_marker; struct msm_cvp_buffer_type fullres_srcbuffer; struct msm_cvp_buffer_type src_buffer; struct msm_cvp_buffer_type srcframe_contextbuffer; @@ -100,15 +125,16 @@ struct msm_cvp_dme_basic_config_packet { u32 size; u32 packet_type; u32 session_id; - struct cvp_kmd_client_data client_data; + struct msm_cvp_client_data client_data; + u32 stream_idx; u32 srcbuffer_format; - struct cvp_kmd_color_plane_info srcbuffer_planeinfo; + struct msm_cvp_color_plane_info srcbuffer_planeinfo; u32 src_width; u32 src_height; u32 fullres_width; u32 fullres_height; u32 fullresbuffer_format; - struct cvp_kmd_color_plane_info fullresbuffer_planeinfo; + struct msm_cvp_color_plane_info fullresbuffer_planeinfo; u32 ds_enable; u32 enable_lrme_robustness; u32 enable_inlier_tracking; From 4fc4b562fbcbc71b4c22d21d75b4288c7d3b7d46 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 24 May 2019 16:57:47 +0530 Subject: [PATCH 039/452] msm-vidc: reduce max_tries count to 1000 Cleaning up the debug change - reset max_tries count from 10000 to 1000. Change-Id: Id0b142f92b8f45eaa73ab256b7b07bb10f382b80 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_common.c | 2 +- msm/vidc/hfi_iris2.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index cea5b001be71..8dd590f97606 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -1169,7 +1169,7 @@ static int __tzbsp_set_video_state(enum tzbsp_video_state state) static inline int __boot_firmware_common(struct venus_hfi_device *device) { int rc = 0; - u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 10000; + u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 1000; ctrl_init_val = BIT(0); if (device->res->cvp_internal) diff --git a/msm/vidc/hfi_iris2.c b/msm/vidc/hfi_iris2.c index 12377281e5b3..a352fbd4625c 100644 --- a/msm/vidc/hfi_iris2.c +++ b/msm/vidc/hfi_iris2.c @@ -390,7 +390,7 @@ void __core_clear_interrupt_iris2(struct venus_hfi_device *device) int __boot_firmware_iris2(struct venus_hfi_device *device) { int rc = 0; - u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 10000; + u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 1000; ctrl_init_val = BIT(0); if (device->res->cvp_internal) From 046ec851a6fef7a889be934054498f4bb0c02916 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Tue, 28 May 2019 18:43:44 -0700 Subject: [PATCH 040/452] msm: vidc: Update VP9 minimum buffer count Update VP9 output_min_count to 9. Change-Id: I920e534882846ec5e9a5b287e95c2290222fc40f Signed-off-by: Akshata Sahukar --- msm/vidc/msm_vidc_buffer_calculations.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 281d49eb9ba6..7c5836cca0ac 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -637,7 +637,7 @@ int msm_vidc_init_buffer_count(struct msm_vidc_inst *inst) output_min_count = 6; break; case V4L2_PIX_FMT_VP9: - output_min_count = 11; + output_min_count = 9; break; } } From a7517a214f2af5e3af4567f444dfcfda0489b381 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Tue, 4 Jun 2019 18:13:14 -0700 Subject: [PATCH 041/452] msm: vidc: Add support to BRS feature Include BRS control id in msm_venc_s_ctrl to add support to BRS feature. Change-Id: I05b23e7960128a7b19c582caa5123849ba0cb2b0 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_venc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 93fac1508e73..0835f54c7bd6 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1767,6 +1767,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER: case V4L2_CID_MPEG_VIDC_VENC_RC_TIMESTAMP_DISABLE: case V4L2_CID_MPEG_VIDEO_VBV_DELAY: + case V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS: dprintk(VIDC_HIGH, "Control set: ID : %x Val : %d\n", ctrl->id, ctrl->val); break; From 6c943a05840c3ffc309345944a74f8f5d14c3ee1 Mon Sep 17 00:00:00 2001 From: Amit Shekhar Date: Wed, 22 May 2019 16:09:58 -0700 Subject: [PATCH 042/452] msm: vidc: Reject read only OPB buffer in split mode Requirement stipulates OPB to be writable buffer in split mode. Erring out in case of read only buffer will help debugging quickly. Change-Id: I529a97b3d0aa5f82e7cf7d024475338a9d24d1dd Signed-off-by: Amit Shekhar --- msm/vidc/msm_vidc_common.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 4a7d60ba5e88..0e03d13c126e 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2567,6 +2567,13 @@ static void handle_fbd(enum hal_command_response cmd, void *data) mbuf->flags &= ~MSM_VIDC_FLAG_QUEUED; vb = &mbuf->vvb.vb2_buf; + if (fill_buf_done->buffer_type == HAL_BUFFER_OUTPUT2 && + fill_buf_done->flags1 & HAL_BUFFERFLAG_READONLY) { + dprintk(VIDC_ERR, + "%s: Read only buffer not allowed for OPB\n", __func__); + goto exit; + } + if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DROP_FRAME) fill_buf_done->filled_len1 = 0; vb->planes[0].bytesused = fill_buf_done->filled_len1; From f1863f28aafe49214e6ecd98761fad34e3c51e09 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Thu, 6 Jun 2019 10:29:43 -0700 Subject: [PATCH 043/452] msm: vidc: Update in VP9 decoder height alignment Updated SIZE_VPXD_LB_RECON_DMA_METADATA_WR macro to align height to 16 from 8. Change-Id: Icf8dd8494df49251979557af890d91f6aaf5b5d0 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_vidc_buffer_calculations.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 7c5836cca0ac..1dee2750eabc 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -203,7 +203,7 @@ max(((height + 31) >> 5) * MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE, \ ((height + 63) >> 6) * MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE)) #define SIZE_VPXD_LB_RECON_DMA_METADATA_WR(width, height) \ - ALIGN((ALIGN(height, 8) / (4 / 2)) * 64, BUFFER_ALIGNMENT_SIZE(32)) + ALIGN((ALIGN(height, 16) / (4 / 2)) * 64, BUFFER_ALIGNMENT_SIZE(32)) #define SIZE_VP8D_LB_FE_TOP_DATA(width, height) \ ((ALIGN(width, 16) + 8) * 10 * 2) #define SIZE_VP9D_LB_FE_TOP_DATA(width, height) \ From b0cae0e82567fc3bd076ac393e4bee8391d867fb Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Thu, 6 Jun 2019 10:33:28 +0800 Subject: [PATCH 044/452] msm: vidc: fix f/w logging route checking Fix to check f/w logging route based on local flag variant instead of the global one. Because route maybe updated when error occurred. Change-Id: Ia67e138a2b494da465f4868553d33509e70020eb Signed-off-by: Shi Zhongbo --- msm/vidc/hfi_common.c | 2 +- msm/vidc/msm_vidc_debug.h | 30 ++++++++++++++---------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 8dd590f97606..4364e8e54308 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -3236,7 +3236,7 @@ static void __process_sys_error(struct venus_hfi_device *device) static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) { bool local_packet = false; - enum vidc_msg_prio log_level = msm_vidc_debug & FW_LOGMASK; + enum vidc_msg_prio log_level = msm_vidc_debug; if (!device) { dprintk(VIDC_ERR, "%s: Invalid params\n", __func__); diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index e16376611f6d..bfa337b4f1b2 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -90,22 +90,20 @@ extern bool msm_vidc_cvp_usage; #define dprintk_firmware(__level, __fmt, ...) \ do { \ - if (msm_vidc_debug & __level) { \ - if (msm_vidc_debug & FW_FTRACE) { \ - char trace_logbuf[MAX_TRACER_LOG_LENGTH]; \ - int log_length = snprintf(trace_logbuf, \ - MAX_TRACER_LOG_LENGTH, \ - VIDC_DBG_TAG __fmt, \ - get_debug_level_str(__level), \ - ##__VA_ARGS__); \ - trace_msm_vidc_printf(trace_logbuf, \ - log_length); \ - } \ - if (msm_vidc_debug & FW_PRINTK) { \ - pr_info(VIDC_DBG_TAG __fmt, \ - get_debug_level_str(__level), \ - ##__VA_ARGS__); \ - } \ + if (__level & FW_FTRACE) { \ + char trace_logbuf[MAX_TRACER_LOG_LENGTH]; \ + int log_length = snprintf(trace_logbuf, \ + MAX_TRACER_LOG_LENGTH, \ + VIDC_DBG_TAG __fmt, \ + "fw", \ + ##__VA_ARGS__); \ + trace_msm_vidc_printf(trace_logbuf, \ + log_length); \ + } \ + if (__level & FW_PRINTK) { \ + pr_info(VIDC_DBG_TAG __fmt, \ + "fw", \ + ##__VA_ARGS__); \ } \ } while (0) From 612a31d1ace597c7d3ef5b4821a924db180c8107 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 29 May 2019 14:08:02 +0530 Subject: [PATCH 045/452] msm: vidc: update video resolution during reconfig event Video port resolution can be updated during reconfig event itself. With this, reconfig height and width was removed. Also relevant code cleanup was made accordingly. Change-Id: I4fb38563b4c747eb356f28b7df7e99bd397ff8d1 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vdec.c | 4 ---- msm/vidc/msm_vidc_clocks.c | 9 ++------- msm/vidc/msm_vidc_common.c | 22 ++++++++-------------- msm/vidc/msm_vidc_internal.h | 2 -- 4 files changed, 10 insertions(+), 27 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 19b741c3f659..4c09e686cf30 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -670,10 +670,6 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) memcpy(f, fmt, sizeof(struct v4l2_format)); } else if (f->type == INPUT_MPLANE) { fmt = &inst->fmts[INPUT_PORT].v4l2_fmt; - if (inst->in_reconfig) { - fmt->fmt.pix_mp.width = inst->reconfig_width; - fmt->fmt.pix_mp.height = inst->reconfig_height; - } fmt->fmt.pix_mp.plane_fmt[0].sizeimage = msm_vidc_calculate_dec_input_frame_size(inst); memcpy(f, fmt, sizeof(struct v4l2_format)); diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 44c38920537a..46e28f7d0103 100755 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -124,15 +124,10 @@ int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst) out_f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; inp_f = &inst->fmts[INPUT_PORT].v4l2_fmt; - if (!inst->in_reconfig) { - height = max(out_f->fmt.pix_mp.height, + height = max(out_f->fmt.pix_mp.height, inp_f->fmt.pix_mp.height); - width = max(out_f->fmt.pix_mp.width, + width = max(out_f->fmt.pix_mp.width, inp_f->fmt.pix_mp.width); - } else { - height = inst->reconfig_height; - width = inst->reconfig_width; - } return NUM_MBS_PER_FRAME(height, width); } diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 0e03d13c126e..9dce5919f84a 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -732,11 +732,8 @@ static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst) struct v4l2_format *f; f = &inst->fmts[INPUT_PORT].v4l2_fmt; - input_port_mbs = inst->in_reconfig ? - NUM_MBS_PER_FRAME(inst->reconfig_width, - inst->reconfig_height) : - NUM_MBS_PER_FRAME(f->fmt.pix_mp.width, - f->fmt.pix_mp.height); + input_port_mbs = NUM_MBS_PER_FRAME(f->fmt.pix_mp.width, + f->fmt.pix_mp.height); f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; output_port_mbs = NUM_MBS_PER_FRAME(f->fmt.pix_mp.width, @@ -1730,11 +1727,14 @@ static void handle_event_change(enum hal_command_response cmd, void *data) mutex_lock(&inst->lock); inst->in_reconfig = true; - inst->reconfig_height = event_notify->height; - inst->reconfig_width = event_notify->width; + fmt = &inst->fmts[INPUT_PORT]; + fmt->v4l2_fmt.fmt.pix_mp.height = event_notify->height; + fmt->v4l2_fmt.fmt.pix_mp.width = event_notify->width; inst->bit_depth = event_notify->bit_depth; fmt = &inst->fmts[OUTPUT_PORT]; + fmt->v4l2_fmt.fmt.pix_mp.height = event_notify->height; + fmt->v4l2_fmt.fmt.pix_mp.width = event_notify->width; extra_buff_count = msm_vidc_get_extra_buff_count(inst, HAL_BUFFER_OUTPUT); fmt->count_min = event_notify->capture_buf_count; @@ -5762,7 +5762,6 @@ int msm_comm_session_continue(void *instance) struct msm_vidc_inst *inst = instance; int rc = 0; struct hfi_device *hdev; - struct v4l2_format *f; if (!inst || !inst->core || !inst->core->device) return -EINVAL; @@ -5786,12 +5785,7 @@ int msm_comm_session_continue(void *instance) goto sess_continue_fail; } inst->in_reconfig = false; - f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; - f->fmt.pix_mp.height = inst->reconfig_height; - f->fmt.pix_mp.width = inst->reconfig_width; - f = &inst->fmts[INPUT_PORT].v4l2_fmt; - f->fmt.pix_mp.height = inst->reconfig_height; - f->fmt.pix_mp.width = inst->reconfig_width; + if (msm_comm_get_stream_output_mode(inst) == HAL_VIDEO_DECODER_SECONDARY) { rc = msm_comm_queue_dpb_only_buffers(inst); diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 98707751c6d6..65b20b41cf45 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -483,8 +483,6 @@ struct msm_vidc_inst { struct v4l2_fh event_handler; struct msm_smem *extradata_handle; bool in_reconfig; - u32 reconfig_width; - u32 reconfig_height; struct dentry *debugfs_root; void *priv; struct msm_vidc_debug debug; From 762f815ddc62b8e29a966408f8410b6f289138cb Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 24 May 2019 20:37:13 +0530 Subject: [PATCH 046/452] msm: vidc: remove decoder operating rate setting to firmware operating rate setting to firmware is not required for decoder. Change-Id: I271a42822f4a00e95d875400e5ad273697c94ab1 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vdec.c | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 4c09e686cf30..905efd756e5a 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -1286,36 +1286,6 @@ int msm_vdec_set_priority(struct msm_vidc_inst *inst) return rc; } -int msm_vdec_set_operating_rate(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct hfi_device *hdev; - struct v4l2_ctrl *ctrl; - struct hfi_operating_rate operating_rate; - - if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); - return -EINVAL; - } - hdev = inst->core->device; - - if (is_decode_session(inst)) - return 0; - - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE); - operating_rate.operating_rate = ctrl->val; - - dprintk(VIDC_HIGH, "%s: %#x\n", __func__, - operating_rate.operating_rate); - rc = call_hfi_op(hdev, session_set_property, inst->session, - HFI_PROPERTY_CONFIG_OPERATING_RATE, &operating_rate, - sizeof(operating_rate)); - if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); - - return rc; -} - int msm_vdec_set_conceal_color(struct msm_vidc_inst *inst) { int rc = 0; @@ -1462,9 +1432,6 @@ int msm_vdec_set_properties(struct msm_vidc_inst *inst) rc = msm_vdec_set_output_buffer_counts(inst); if (rc) goto exit; - rc = msm_vdec_set_operating_rate(inst); - if (rc) - goto exit; exit: if (rc) From 31021fce6a4b643eab9809fb63a6ff863d059352 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 22 May 2019 18:00:24 +0530 Subject: [PATCH 047/452] msm: vidc: Update perf mode for different video hardwares Perf mode can be either predefined or can be decided dynamically. It is configured differently for different video hardware versions. Perf mode is now updated with below 1. Remove multicore calculation as it is not applicable for single core hardware. 2. Rate control type CQ is considered during load calculation 3. If the clocks are available, keep higher perf mode, unless restricted by the hardware specification. CRs-Fixed: 2462264 Change-Id: I9328e07ea3d1667b15a431c624112f1e8f8c92e0 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_clocks.c | 171 ++++++++++++------------------------- 1 file changed, 54 insertions(+), 117 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 46e28f7d0103..cfbaddff1f62 100755 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1528,7 +1528,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, bool enable) { - u32 rc = 0, mbs_per_frame, mbs_per_sec; + u32 rc = 0; u32 prop_id = 0; void *pdata = NULL; struct hfi_device *hdev = NULL; @@ -1542,18 +1542,6 @@ static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, return 0; } - /* Power saving always disabled for CQ and LOSSLESS RC modes. */ - mbs_per_frame = msm_vidc_get_mbs_per_frame(inst); - mbs_per_sec = mbs_per_frame * msm_vidc_get_fps(inst); - if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ || - inst->rc_type == RATE_CONTROL_LOSSLESS || - (mbs_per_frame <= - inst->core->resources.max_hq_mbs_per_frame && - mbs_per_sec <= - inst->core->resources.max_hq_mbs_per_sec)) { - enable = false; - } - prop_id = HFI_PROPERTY_CONFIG_VENC_PERF_MODE; hfi_perf_mode = enable ? HFI_VENC_PERFMODE_POWER_SAVE : HFI_VENC_PERFMODE_MAX_QUALITY; @@ -1565,7 +1553,7 @@ static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, dprintk(VIDC_ERR, "%s: Failed to set power save mode for inst: %pK\n", __func__, inst); - goto fail_power_mode_set; + return rc; } inst->flags = enable ? inst->flags | VIDC_LOW_POWER : @@ -1573,7 +1561,7 @@ static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, dprintk(VIDC_HIGH, "Power Save Mode for inst: %pK Enable = %d\n", inst, enable); -fail_power_mode_set: + return rc; } @@ -1614,6 +1602,9 @@ static u32 get_core_load(struct msm_vidc_core *core, cycles = lp_cycles = inst->clk_data.entry->vpp_cycles; } else if (inst->session_type == MSM_VIDC_ENCODER) { lp_mode |= inst->flags & VIDC_LOW_POWER; + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) + lp_mode = false; + cycles = lp_mode ? inst->clk_data.entry->low_power_cycles : inst->clk_data.entry->vpp_cycles; @@ -1632,16 +1623,13 @@ static u32 get_core_load(struct msm_vidc_core *core, int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) { - int rc = 0, hier_mode = 0; - struct hfi_device *hdev; - struct msm_vidc_core *core; + bool enable = false; + int rc = 0; + u32 core_load = 0, core_lp_load = 0; + u32 cur_inst_load = 0, cur_inst_lp_load = 0; + u32 mbpf, mbps, max_hq_mbpf, max_hq_mbps; unsigned long max_freq, lp_cycles = 0; - struct hfi_videocores_usage_type core_info; - u32 core0_load = 0, core1_load = 0, core0_lp_load = 0, - core1_lp_load = 0; - u32 current_inst_load = 0, cur_inst_lp_load = 0, - min_load = 0, min_lp_load = 0; - u32 min_core_id, min_lp_core_id; + struct msm_vidc_core *core; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, @@ -1651,131 +1639,80 @@ int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) } core = inst->core; - hdev = core->device; max_freq = msm_vidc_max_freq(inst->core); inst->clk_data.core_id = 0; - core0_load = get_core_load(core, VIDC_CORE_ID_1, false, true); - core1_load = get_core_load(core, VIDC_CORE_ID_2, false, true); - core0_lp_load = get_core_load(core, VIDC_CORE_ID_1, true, true); - core1_lp_load = get_core_load(core, VIDC_CORE_ID_2, true, true); - - min_load = min(core0_load, core1_load); - min_core_id = core0_load < core1_load ? - VIDC_CORE_ID_1 : VIDC_CORE_ID_2; - min_lp_load = min(core0_lp_load, core1_lp_load); - min_lp_core_id = core0_lp_load < core1_lp_load ? - VIDC_CORE_ID_1 : VIDC_CORE_ID_2; + core_load = get_core_load(core, VIDC_CORE_ID_1, false, true); + core_lp_load = get_core_load(core, VIDC_CORE_ID_1, true, true); lp_cycles = inst->session_type == MSM_VIDC_ENCODER ? inst->clk_data.entry->low_power_cycles : inst->clk_data.entry->vpp_cycles; - /* - * Incase there is only 1 core enabled, mark it as the core - * with min load. This ensures that this core is selected and - * video session is set to run on the enabled core. - */ - if (inst->capability.cap[CAP_MAX_VIDEOCORES].max <= VIDC_CORE_ID_1) { - min_core_id = min_lp_core_id = VIDC_CORE_ID_1; - min_load = core0_load; - min_lp_load = core0_lp_load; - } - current_inst_load = (msm_comm_get_inst_load(inst, LOAD_CALC_NO_QUIRKS) * + cur_inst_load = (msm_comm_get_inst_load(inst, LOAD_CALC_NO_QUIRKS) * inst->clk_data.entry->vpp_cycles)/inst->clk_data.work_route; cur_inst_lp_load = (msm_comm_get_inst_load(inst, LOAD_CALC_NO_QUIRKS) * lp_cycles)/inst->clk_data.work_route; - dprintk(VIDC_HIGH, "Core 0 RT Load = %d Core 1 RT Load = %d\n", - core0_load, core1_load); - dprintk(VIDC_HIGH, "Core 0 RT LP Load = %d Core 1 RT LP Load = %d\n", - core0_lp_load, core1_lp_load); + mbpf = msm_vidc_get_mbs_per_frame(inst); + mbps = mbpf * msm_vidc_get_fps(inst); + max_hq_mbpf = core->resources.max_hq_mbs_per_frame; + max_hq_mbps = core->resources.max_hq_mbs_per_sec; + + dprintk(VIDC_HIGH, "Core RT Load = %d LP Load = %d\n", + core_load, core_lp_load); dprintk(VIDC_HIGH, "Max Load = %lu\n", max_freq); dprintk(VIDC_HIGH, "Current Load = %d Current LP Load = %d\n", - current_inst_load, cur_inst_lp_load); - - if (inst->session_type == MSM_VIDC_ENCODER) { - /* Hier mode can be normal HP or Hybrid HP. */ - u32 max_cores, work_mode; - - hier_mode = msm_comm_g_ctrl_for_id(inst, - V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); - max_cores = inst->capability.cap[CAP_MAX_VIDEOCORES].max; - work_mode = inst->clk_data.work_mode; - if (hier_mode && max_cores >= VIDC_CORE_ID_3 && - work_mode == HFI_WORKMODE_2) { - if (current_inst_load / 2 + core0_load <= max_freq && - current_inst_load / 2 + core1_load <= max_freq) { - inst->clk_data.core_id = VIDC_CORE_ID_3; - msm_vidc_power_save_mode_enable(inst, false); - goto decision_done; - } - if (cur_inst_lp_load / 2 + core0_lp_load <= max_freq && - cur_inst_lp_load / 2 + core1_lp_load <= max_freq) { - inst->clk_data.core_id = VIDC_CORE_ID_3; - msm_vidc_power_save_mode_enable(inst, true); - goto decision_done; - } - } + cur_inst_load, cur_inst_lp_load); + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ && + (core_load > max_freq || core_lp_load > max_freq)) { + dprintk(VIDC_ERR, + "CQ session - Core cannot support this load\n"); + return -EINVAL; } - if (current_inst_load + min_load < max_freq) { - inst->clk_data.core_id = min_core_id; - dprintk(VIDC_HIGH, - "Selected normally : Core ID = %d\n", - inst->clk_data.core_id); - msm_vidc_power_save_mode_enable(inst, false); - } else if (cur_inst_lp_load + min_load < max_freq) { - /* Move current instance to LP and return */ - inst->clk_data.core_id = min_core_id; - dprintk(VIDC_HIGH, - "Selected by moving current to LP : Core ID = %d\n", - inst->clk_data.core_id); + if (cur_inst_load + core_load <= max_freq) { + if (mbpf > max_hq_mbpf || mbps > max_hq_mbps) + enable = true; + msm_vidc_power_save_mode_enable(inst, enable); + } else if (cur_inst_lp_load + core_load <= max_freq) { msm_vidc_power_save_mode_enable(inst, true); - - } else if (cur_inst_lp_load + min_lp_load < max_freq) { - /* Move all instances to LP mode and return */ - inst->clk_data.core_id = min_lp_core_id; - dprintk(VIDC_HIGH, - "Moved all inst's to LP: Core ID = %d\n", - inst->clk_data.core_id); - msm_vidc_move_core_to_power_save_mode(core, min_lp_core_id); + } else if (cur_inst_lp_load + core_lp_load <= max_freq) { + dprintk(VIDC_HIGH, "Moved all inst's to LP"); + msm_vidc_move_core_to_power_save_mode(core, VIDC_CORE_ID_1); } else { - rc = -EINVAL; - dprintk(VIDC_ERR, - "Sorry ... Core Can't support this load\n"); - return rc; + dprintk(VIDC_ERR, "Core cannot support this load\n"); + return -EINVAL; } -decision_done: - core_info.video_core_enable_mask = inst->clk_data.core_id; - dprintk(VIDC_HIGH, - "Core Enable Mask %d\n", core_info.video_core_enable_mask); - - rc = call_hfi_op(hdev, session_set_property, - (void *)inst->session, - HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE, &core_info, - sizeof(core_info)); - if (rc) - dprintk(VIDC_ERR, - " Failed to configure CORE ID %pK\n", inst); - + inst->clk_data.core_id = VIDC_CORE_ID_1; rc = msm_comm_scale_clocks_and_bus(inst); - msm_print_core_status(core, VIDC_CORE_ID_1); - msm_print_core_status(core, VIDC_CORE_ID_2); - return rc; } int msm_vidc_decide_core_and_power_mode_iris2(struct msm_vidc_inst *inst) { + u32 mbpf, mbps, max_hq_mbpf, max_hq_mbps; + bool enable = true; + inst->clk_data.core_id = VIDC_CORE_ID_1; msm_print_core_status(inst->core, VIDC_CORE_ID_1); - return msm_vidc_power_save_mode_enable(inst, true); + /* Power saving always disabled for CQ and LOSSLESS RC modes. */ + mbpf = msm_vidc_get_mbs_per_frame(inst); + mbps = mbpf * msm_vidc_get_fps(inst); + max_hq_mbpf = inst->core->resources.max_hq_mbs_per_frame; + max_hq_mbps = inst->core->resources.max_hq_mbs_per_sec; + + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ || + inst->rc_type == RATE_CONTROL_LOSSLESS || + (mbpf <= max_hq_mbpf && mbps <= max_hq_mbps)) + enable = false; + + return msm_vidc_power_save_mode_enable(inst, enable); } void msm_vidc_init_core_clk_ops(struct msm_vidc_core *core) From 3418f42be463cfa096525fcacfc5c499f2ddb3d4 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Wed, 8 May 2019 17:26:43 +0530 Subject: [PATCH 048/452] msm: vidc: Update device clock after cx ipeak logic Existing code updates the device clock before cx ipeak logic. As a result, the cx ipeak takes a decision based on updated clock rather than the clock at which the device was running. With the change, device clock is updated after the cx ipeak is decided. Change-Id: Icfde29176f8adb3a12c68a611f47b83ca7a8e4a9 Signed-off-by: Vikash Garodia Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/hfi_common.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 4364e8e54308..4fbbda3a8c15 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -1292,13 +1292,12 @@ static int __set_clk_rate(struct venus_hfi_device *device, return rc; } - device->clk_freq = rate; - - if (device->clk_freq >= threshold_freq && rate < threshold_freq) { + if (ipeak && device->clk_freq >= threshold_freq && rate < threshold_freq) { rc = cx_ipeak_update(ipeak, false); if (rc) { dprintk(VIDC_ERR, "cx_ipeak_update failed! ipeak %pK\n", ipeak); + device->clk_freq = rate; return rc; } dprintk(VIDC_PERF, @@ -1306,6 +1305,8 @@ static int __set_clk_rate(struct venus_hfi_device *device, device->clk_freq, rate, threshold_freq); } + device->clk_freq = rate; + return rc; } From 12ac83a8c55841b8ccc61089e4d7126fbd930556 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 24 May 2019 19:31:54 +0530 Subject: [PATCH 049/452] msm: vidc: Release non-requested internal buffers during load resource firmware will check input buffer type against requested buffer type. If there a mismatch it will throw an error. So cleared non-requested buffer from the scratch buffer list Change-Id: Ifabf532982a393d4fc356ff3cad0ca3fd715fce0 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_common.c | 35 +++++++++++++++++++++++++++++++++++ msm/vidc/msm_vidc_common.h | 2 ++ 2 files changed, 37 insertions(+) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 9dce5919f84a..fe9c75deaf8b 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -3437,6 +3437,29 @@ static int get_flipped_state(int present_state, return flipped_state; } +int msm_comm_reset_bufreqs(struct msm_vidc_inst *inst, enum hal_buffer buf_type) +{ + struct hal_buffer_requirements *bufreqs; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + bufreqs = get_buff_req_buffer(inst, buf_type); + if (!bufreqs) { + dprintk(VIDC_ERR, "%s: invalid buf type %d\n", + __func__, buf_type); + return -EINVAL; + } + bufreqs->buffer_size = bufreqs->buffer_region_size = + bufreqs->buffer_count_min = bufreqs->buffer_count_min_host = + bufreqs->buffer_count_actual = bufreqs->contiguous = + bufreqs->buffer_alignment = 0; + + return 0; +} + struct hal_buffer_requirements *get_buff_req_buffer( struct msm_vidc_inst *inst, enum hal_buffer buffer_type) { @@ -4447,6 +4470,14 @@ int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst) { int rc = -EINVAL, i = 0; union hal_get_property hprop; + enum hal_buffer int_buf[] = { + HAL_BUFFER_INTERNAL_SCRATCH, + HAL_BUFFER_INTERNAL_SCRATCH_1, + HAL_BUFFER_INTERNAL_SCRATCH_2, + HAL_BUFFER_INTERNAL_PERSIST, + HAL_BUFFER_INTERNAL_PERSIST_1, + HAL_BUFFER_INTERNAL_RECON, + }; memset(&hprop, 0x0, sizeof(hprop)); /* @@ -4473,6 +4504,10 @@ int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst) return rc; } + /* reset internal buffers */ + for (i = 0; i < ARRAY_SIZE(int_buf); i++) + msm_comm_reset_bufreqs(inst, int_buf[i]); + for (i = 0; i < HAL_BUFFER_MAX; i++) { struct hal_buffer_requirements req; struct hal_buffer_requirements *curr_req; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index a71dabc61bde..7135d20436ef 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -174,6 +174,8 @@ int msm_comm_release_dpb_only_buffers(struct msm_vidc_inst *inst, void msm_comm_validate_output_buffers(struct msm_vidc_inst *inst); int msm_comm_force_cleanup(struct msm_vidc_inst *inst); int msm_comm_suspend(int core_id); +int msm_comm_reset_bufreqs(struct msm_vidc_inst *inst, + enum hal_buffer buf_type); struct hal_buffer_requirements *get_buff_req_buffer( struct msm_vidc_inst *inst, u32 buffer_type); #define IS_PRIV_CTRL(idx) (\ From 52ae7a5f1bb90cae2ee5a44f071721adeab033ca Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Fri, 7 Jun 2019 11:00:25 -0700 Subject: [PATCH 050/452] msm: vidc: Enable ubwc cr stat by default Decode session needs UBWC CR statistics for BW calculations. Hence need to enable this exetradata by default. CRs-Fixed: 2467542 Change-Id: I3955a0b09cf82f97478c31704be6b16f297b011b Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vdec.c | 2 ++ msm/vidc/msm_vidc_clocks.c | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 905efd756e5a..9f4bfc08e7cd 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -1346,6 +1346,8 @@ int msm_vdec_set_extradata(struct msm_vidc_inst *inst) msm_comm_set_extradata(inst, HFI_PROPERTY_PARAM_VDEC_INTERLACE_VIDEO_EXTRADATA, 0x1); msm_comm_set_extradata(inst, display_info, 0x1); + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VDEC_UBWC_CR_STAT_INFO_EXTRADATA, 0x1); if (codec == V4L2_PIX_FMT_VP9 || codec == V4L2_PIX_FMT_HEVC) { msm_comm_set_extradata(inst, diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index cfbaddff1f62..8480686a4236 100755 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -177,10 +177,12 @@ static int fill_dynamic_stats(struct msm_vidc_inst *inst, { struct recon_buf *binfo, *nextb; struct vidc_input_cr_data *temp, *next; - u32 min_cf = MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR, max_cf = 0; - u32 min_input_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO, - max_input_cr = 0; - u32 min_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO, max_cr = 0; + u32 max_cr = MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO; + u32 max_cf = MSM_VIDC_MIN_UBWC_COMPLEXITY_FACTOR; + u32 max_input_cr = MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO; + u32 min_cf = MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR; + u32 min_input_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO; + u32 min_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO; mutex_lock(&inst->reconbufs.lock); list_for_each_entry_safe(binfo, nextb, &inst->reconbufs.list, list) { From 994366e08273d4107d19dcf668c3828232331f36 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Thu, 6 Jun 2019 15:46:27 -0700 Subject: [PATCH 051/452] msm: vidc: use batch enable instead of decode_batching Use the existing batch enable variable instead of extra variable decode_batching. Change-Id: Ic7875caf2b0d2c47d77b0c0c0ce9b5792920cafc Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_vdec.c | 4 ++-- msm/vidc/msm_vidc_buffer_calculations.c | 4 ++-- msm/vidc/msm_vidc_common.c | 2 +- msm/vidc/msm_vidc_internal.h | 1 - 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 9f4bfc08e7cd..6a7aa8051469 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -776,7 +776,7 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) struct msm_vidc_inst *temp; inst->batch.size = MAX_DEC_BATCH_SIZE; - inst->decode_batching = true; + inst->batch.enable = true; mutex_lock(&core->lock); list_for_each_entry(temp, &core->instances, list) { @@ -784,7 +784,7 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) temp->state != MSM_VIDC_CORE_INVALID && is_decode_session(temp) && !is_thumbnail_session(temp)) { - inst->decode_batching = false; + inst->batch.enable = false; dprintk(VIDC_HIGH, "Disable decode-batching in multi sessions\n"); break; diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 1dee2750eabc..231e9ec82a9f 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -610,7 +610,7 @@ int msm_vidc_init_buffer_count(struct msm_vidc_inst *inst) HAL_BUFFER_INPUT); fmt->count_min = input_min_count; /* batching needs minimum batch size count of input buffers */ - if (inst->decode_batching && + if (inst->batch.enable && is_decode_session(inst) && fmt->count_min < inst->batch.size) fmt->count_min = inst->batch.size; @@ -711,7 +711,7 @@ int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, * batch size count of extra buffers added on output port */ if (buffer_type == HAL_BUFFER_OUTPUT) { - if (inst->decode_batching && + if (inst->batch.enable && is_decode_session(inst) && count < inst->batch.size) count = inst->batch.size; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index fe9c75deaf8b..01335cdaba45 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2794,7 +2794,7 @@ bool is_batching_allowed(struct msm_vidc_inst *inst) maxmbs = inst->capability.cap[CAP_BATCH_MAX_MB_PER_FRAME].max; maxfps = inst->capability.cap[CAP_BATCH_MAX_FPS].max; - return (inst->decode_batching && + return (inst->batch.enable && is_decode_session(inst) && !is_thumbnail_session(inst) && !inst->clk_data.low_latency_mode && diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 65b20b41cf45..453451851a55 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -512,7 +512,6 @@ struct msm_vidc_inst { struct msm_vidc_codec_data *codec_data; struct hal_hdr10_pq_sei hdr10_sei_params; struct batch_mode batch; - bool decode_batching; struct msm_vidc_inst_smem_ops *smem_ops; int (*buffer_size_calculators)(struct msm_vidc_inst *inst); }; From 48e20d6e8f017df7c7b8697b32af12664c19017e Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Fri, 31 May 2019 21:23:38 +0800 Subject: [PATCH 052/452] msm: vidc: support disable all blur feature Add support to disable both auto blur and external blur. Change-Id: I5200f738ffa5849a3e840f90f0da66c38607ceae Signed-off-by: Qiwei Liu --- msm/vidc/msm_venc.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 0835f54c7bd6..c4f7db5b5add 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3791,6 +3791,7 @@ int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst) struct hfi_device *hdev; struct v4l2_ctrl *ctrl; struct hfi_frame_size frame_sz; + struct v4l2_format *f; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); @@ -3803,6 +3804,29 @@ int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst) frame_sz.buffer_type = HFI_BUFFER_INPUT; frame_sz.height = ctrl->val & 0xFFFF; frame_sz.width = (ctrl->val & 0x7FFF0000) >> 16; + + /* + * 0x0 is default value, internal blur enabled, external blur disabled + * 0x1 means dynamic external blur, blur resolution will be set + * after start, internal blur disabled + * 0x2 means disable both internal and external blur + */ + if (ctrl->val == 0x2) { + if (inst->state == MSM_VIDC_START_DONE) { + dprintk(VIDC_ERR, + "Dynamic disable all blur not supported\n"); + return -EINVAL; + } + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + /* + * Use original input width/height (before VPSS) to inform FW + * to disable all blur. + */ + frame_sz.width = f->fmt.pix_mp.width; + frame_sz.height = f->fmt.pix_mp.height; + dprintk(VIDC_HIGH, "Disable both auto and external blur\n"); + } + dprintk(VIDC_HIGH, "%s: type %u, height %u, width %u\n", __func__, frame_sz.buffer_type, frame_sz.height, frame_sz.width); rc = call_hfi_op(hdev, session_set_property, inst->session, From fe44bca0c047d3ac1279a76a1a93fa0a697e89fc Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Mon, 10 Jun 2019 13:15:54 -0700 Subject: [PATCH 053/452] Revert "msm: vidc: Enable ubwc cr stat by default" This reverts commit 52ae7a5f1bb90cae2ee5a44f071721adeab033ca. --- msm/vidc/msm_vdec.c | 2 -- msm/vidc/msm_vidc_clocks.c | 10 ++++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 6a7aa8051469..2819203d6289 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -1346,8 +1346,6 @@ int msm_vdec_set_extradata(struct msm_vidc_inst *inst) msm_comm_set_extradata(inst, HFI_PROPERTY_PARAM_VDEC_INTERLACE_VIDEO_EXTRADATA, 0x1); msm_comm_set_extradata(inst, display_info, 0x1); - msm_comm_set_extradata(inst, - HFI_PROPERTY_PARAM_VDEC_UBWC_CR_STAT_INFO_EXTRADATA, 0x1); if (codec == V4L2_PIX_FMT_VP9 || codec == V4L2_PIX_FMT_HEVC) { msm_comm_set_extradata(inst, diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 8480686a4236..cfbaddff1f62 100755 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -177,12 +177,10 @@ static int fill_dynamic_stats(struct msm_vidc_inst *inst, { struct recon_buf *binfo, *nextb; struct vidc_input_cr_data *temp, *next; - u32 max_cr = MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO; - u32 max_cf = MSM_VIDC_MIN_UBWC_COMPLEXITY_FACTOR; - u32 max_input_cr = MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO; - u32 min_cf = MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR; - u32 min_input_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO; - u32 min_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO; + u32 min_cf = MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR, max_cf = 0; + u32 min_input_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO, + max_input_cr = 0; + u32 min_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO, max_cr = 0; mutex_lock(&inst->reconbufs.lock); list_for_each_entry_safe(binfo, nextb, &inst->reconbufs.list, list) { From fc8664564a301389a877b09e2854c29d322c79ca Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 7 Jun 2019 18:21:54 +0530 Subject: [PATCH 054/452] msm: vidc: add additional check to avoid out of bound access pkt->msg_size can be corrupted, that leads to OOB access. So added additional conditional check to avoid OOB access in debug queue packet handling. Change-Id: I360812c40369ecef2dd99464d400661bc785074b Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_common.c | 37 ++++++++++++++++++++++++++++++++++--- msm/vidc/vidc_hfi_helper.h | 5 +++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 4fbbda3a8c15..4da528e36802 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -36,6 +36,7 @@ #define FIRMWARE_SIZE 0X00A00000 #define REG_ADDR_OFFSET_BITMASK 0x000FFFFF #define QDSS_IOVA_START 0x80001000 +#define MIN_PAYLOAD_SIZE 3 static struct hal_device_data hal_ctxt; @@ -3261,22 +3262,50 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) log_level |= FW_PRINTK; } +#define SKIP_INVALID_PKT(pkt_size, payload_size, pkt_hdr_size) ({ \ + if (pkt_size < pkt_hdr_size || \ + payload_size < MIN_PAYLOAD_SIZE || \ + payload_size > \ + (pkt_size - pkt_hdr_size + sizeof(u8))) { \ + dprintk(VIDC_ERR, \ + "%s: invalid msg size - %d\n", \ + __func__, pkt->msg_size); \ + continue; \ + } \ + }) + while (!__iface_dbgq_read(device, packet)) { - struct hfi_msg_sys_coverage_packet *pkt = - (struct hfi_msg_sys_coverage_packet *) packet; + struct hfi_packet_header *pkt = + (struct hfi_packet_header *) packet; + + if (pkt->size < sizeof(struct hfi_packet_header)) { + dprintk(VIDC_ERR, "Invalid pkt size - %s\n", + __func__); + continue; + } if (pkt->packet_type == HFI_MSG_SYS_COV) { + struct hfi_msg_sys_coverage_packet *pkt = + (struct hfi_msg_sys_coverage_packet *) packet; int stm_size = 0; + SKIP_INVALID_PKT(pkt->size, + pkt->msg_size, sizeof(*pkt)); + stm_size = stm_log_inv_ts(0, 0, pkt->rg_msg_data, pkt->msg_size); if (stm_size == 0) dprintk(VIDC_ERR, "In %s, stm_log returned size of 0\n", __func__); - } else { + + } else if (pkt->packet_type == HFI_MSG_SYS_DEBUG) { struct hfi_msg_sys_debug_packet *pkt = (struct hfi_msg_sys_debug_packet *) packet; + + SKIP_INVALID_PKT(pkt->size, + pkt->msg_size, sizeof(*pkt)); + /* * All fw messages starts with new line character. This * causes dprintk to print this message in two lines @@ -3284,9 +3313,11 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) * from the message fixes this to print it in a single * line. */ + pkt->rg_msg_data[pkt->msg_size-1] = '\0'; dprintk_firmware(log_level, "%s", &pkt->rg_msg_data[1]); } } +#undef SKIP_INVALID_PKT if (local_packet) kfree(packet); diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index c7c0aa1f68eb..ba01cd7e2156 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -839,6 +839,11 @@ struct vidc_hal_session_cmd_pkt { u32 session_id; }; +struct hfi_packet_header { + u32 size; + u32 packet_type; +}; + struct hfi_cmd_sys_init_packet { u32 size; u32 packet_type; From 2a820b1c52851b788c1f9ed14e34c7d146b3bfad Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Tue, 11 Jun 2019 13:39:46 +0800 Subject: [PATCH 055/452] msm: vidc: add VIDC_BUS log mask Add new VIDC_BUS log mask for bus parameters related logs. Change-Id: If933c8c88ec2e0ccb283606da7f46a3c3c49756a Signed-off-by: Shi Zhongbo --- msm/vidc/msm_vidc_bus_iris1.c | 6 +++--- msm/vidc/msm_vidc_bus_iris2.c | 4 ++-- msm/vidc/msm_vidc_debug.h | 3 +++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/msm/vidc/msm_vidc_bus_iris1.c b/msm/vidc/msm_vidc_bus_iris1.c index 90fdb821babc..5e30046bcf50 100644 --- a/msm/vidc/msm_vidc_bus_iris1.c +++ b/msm/vidc/msm_vidc_bus_iris1.c @@ -64,7 +64,7 @@ void __dump(struct dump dump[], int len) } } - dprintk(VIDC_LOW, "%s", formatted_line); + dprintk(VIDC_BUS, "%s", formatted_line); } } @@ -275,7 +275,7 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, llc.line_buffer_write + ddr.total; /* Dump all the variables for easier debugging */ - if (msm_vidc_debug & VIDC_PERF) { + if (msm_vidc_debug & VIDC_BUS) { struct dump dump[] = { {"DECODER PARAMETERS", "", DUMP_HEADER_MAGIC}, {"lcu size", "%d", lcu_size}, @@ -569,7 +569,7 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, ddr.total = fp_mult(ddr.total, qsmmu_bw_overhead_factor); llc.total = llc.ref_read_crcb + llc.line_buffer + ddr.total; - if (msm_vidc_debug & VIDC_PERF) { + if (msm_vidc_debug & VIDC_BUS) { struct dump dump[] = { {"ENCODER PARAMETERS", "", DUMP_HEADER_MAGIC}, {"width", "%d", width}, diff --git a/msm/vidc/msm_vidc_bus_iris2.c b/msm/vidc/msm_vidc_bus_iris2.c index 21703d3e3992..bbb640fc46b9 100644 --- a/msm/vidc/msm_vidc_bus_iris2.c +++ b/msm/vidc/msm_vidc_bus_iris2.c @@ -214,7 +214,7 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, llc.line_buffer_write + ddr.total; /* Dump all the variables for easier debugging */ - if (msm_vidc_debug & VIDC_PERF) { + if (msm_vidc_debug & VIDC_BUS) { struct dump dump[] = { {"DECODER PARAMETERS", "", DUMP_HEADER_MAGIC}, {"lcu size", "%d", lcu_size}, @@ -508,7 +508,7 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, ddr.total = fp_mult(ddr.total, qsmmu_bw_overhead_factor); llc.total = llc.ref_read_crcb + llc.line_buffer + ddr.total; - if (msm_vidc_debug & VIDC_PERF) { + if (msm_vidc_debug & VIDC_BUS) { struct dump dump[] = { {"ENCODER PARAMETERS", "", DUMP_HEADER_MAGIC}, {"width", "%d", width}, diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index e16376611f6d..72a79b48544f 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -37,6 +37,7 @@ enum vidc_msg_prio { VIDC_LOW = 0x00000004, VIDC_PERF = 0x00000008, VIDC_PKT = 0x00000010, + VIDC_BUS = 0x00000020, VIDC_PRINTK = 0x00001000, VIDC_FTRACE = 0x00002000, FW_LOW = 0x00010000, @@ -146,6 +147,8 @@ static inline char *get_debug_level_str(int level) return "perf"; case VIDC_PKT: return "pkt"; + case VIDC_BUS: + return "bus"; default: return "???"; } From 1dcfc5752d5acaa5f07c0ec51649c92d835bfc7a Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Thu, 6 Jun 2019 17:19:57 -0700 Subject: [PATCH 056/452] msm: vidc: decide batching while configuration driver returns min buffer count to client which includes extra buffers count which is required for batching even though batching may be disabled in start_streaming() later. So decide batching in set format (configuration) to avoid adding extra buffers count to reduce memory usage in non-batching cases. Change-Id: I147f7aaf928074a23c9dcda2dbf69a744cec382d Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_vdec.c | 28 ++++++++------------ msm/vidc/msm_vidc.c | 21 ++++++++++++++- msm/vidc/msm_vidc_buffer_calculations.c | 33 ++++++++++++++++++++--- msm/vidc/msm_vidc_buffer_calculations.h | 4 ++- msm/vidc/msm_vidc_common.c | 35 +++++++++++++++++++++++-- msm/vidc/msm_vidc_common.h | 2 ++ 6 files changed, 99 insertions(+), 24 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 2819203d6289..34a1e235fc9b 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -652,6 +652,16 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) memcpy(f, &fmt->v4l2_fmt, sizeof(struct v4l2_format)); } + /* + * if batching enabled previously then you may chose + * to disable it based on recent configuration changes. + * if batching already disabled do not enable it again + * as sufficient extra buffers (required for batch mode + * on both ports) may not have been updated to client. + */ + if (inst->batch.enable) + inst->batch.enable = is_batching_allowed(inst); + err_invalid_fmt: return rc; } @@ -773,24 +783,8 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) inst->clk_data.frame_rate = (DEFAULT_FPS << 16); inst->clk_data.operating_rate = (DEFAULT_FPS << 16); if (core->resources.decode_batching) { - struct msm_vidc_inst *temp; - - inst->batch.size = MAX_DEC_BATCH_SIZE; inst->batch.enable = true; - - mutex_lock(&core->lock); - list_for_each_entry(temp, &core->instances, list) { - if (temp != inst && - temp->state != MSM_VIDC_CORE_INVALID && - is_decode_session(temp) && - !is_thumbnail_session(temp)) { - inst->batch.enable = false; - dprintk(VIDC_HIGH, - "Disable decode-batching in multi sessions\n"); - break; - } - } - mutex_unlock(&core->lock); + inst->batch.size = MAX_DEC_BATCH_SIZE; } inst->buff_req.buffer[1].buffer_type = HAL_BUFFER_INPUT; diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 3fc9233a6db5..9264190be82e 100755 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -19,6 +19,7 @@ #include "vidc_hfi_helper.h" #include "vidc_hfi_api.h" #include "msm_vidc_clocks.h" +#include "msm_vidc_buffer_calculations.h" #include #define MAX_EVENTS 30 @@ -913,7 +914,15 @@ static inline int start_streaming(struct msm_vidc_inst *inst) } } - inst->batch.enable = is_batching_allowed(inst); + /* + * if batching enabled previously then you may chose + * to disable it based on recent configuration changes. + * if batching already disabled do not enable it again + * as sufficient extra buffers (required for batch mode + * on both ports) may not have been updated to client. + */ + if (inst->batch.enable) + inst->batch.enable = is_batching_allowed(inst); dprintk(VIDC_HIGH, "%s: batching %s for inst %pK (%#x)\n", __func__, inst->batch.enable ? "enabled" : "disabled", inst, hash32_ptr(inst->session)); @@ -1433,12 +1442,22 @@ static int try_get_ctrl_for_instance(struct msm_vidc_inst *inst, inst->level); break; case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: + rc = msm_vidc_calculate_output_buffer_count(inst); + if (rc) { + dprintk(VIDC_ERR, "g_min: input failed\n", __func__); + break; + } ctrl->val = inst->fmts[OUTPUT_PORT].count_min_host; dprintk(VIDC_HIGH, "g_min: %x : hal_buffer %d min buffers %d\n", hash32_ptr(inst->session), HAL_BUFFER_OUTPUT, ctrl->val); break; case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: + rc = msm_vidc_calculate_input_buffer_count(inst); + if (rc) { + dprintk(VIDC_ERR, "g_min: output failed\n", __func__); + break; + } ctrl->val = inst->fmts[INPUT_PORT].count_min_host; dprintk(VIDC_HIGH, "g_min: %x : hal_buffer %d min buffers %d\n", hash32_ptr(inst->session), HAL_BUFFER_INPUT, ctrl->val); diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 231e9ec82a9f..29a3e4aa4d3b 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -591,16 +591,15 @@ void msm_vidc_init_buffer_size_calculators(struct msm_vidc_inst *inst) msm_vidc_calculate_internal_buffer_sizes; } -int msm_vidc_init_buffer_count(struct msm_vidc_inst *inst) +int msm_vidc_calculate_input_buffer_count(struct msm_vidc_inst *inst) { struct msm_vidc_format *fmt; int extra_buff_count = 0; - u32 codec, input_min_count = 4, output_min_count = 4; + u32 input_min_count = 4; if (!is_decode_session(inst) && !is_encode_session(inst)) return 0; - codec = get_v4l2_codec(inst); /* * Update input buff counts * Extradata uses same count as input port @@ -621,6 +620,19 @@ int msm_vidc_init_buffer_count(struct msm_vidc_inst *inst) __func__, hash32_ptr(inst->session), fmt->count_min, fmt->count_min_host, fmt->count_actual); + return 0; +} + +int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst) +{ + struct msm_vidc_format *fmt; + int extra_buff_count = 0; + u32 codec, output_min_count = 4; + + if (!is_decode_session(inst) && !is_encode_session(inst)) + return 0; + + codec = get_v4l2_codec(inst); /* Update output buff count: Changes for decoder based on codec */ if (is_decode_session(inst)) { switch (codec) { @@ -654,6 +666,21 @@ int msm_vidc_init_buffer_count(struct msm_vidc_inst *inst) return 0; } + +int msm_vidc_calculate_buffer_counts(struct msm_vidc_inst *inst) +{ + int rc; + + rc = msm_vidc_calculate_input_buffer_count(inst); + if (rc) + return rc; + rc = msm_vidc_calculate_output_buffer_count(inst); + if (rc) + return rc; + + return rc; +} + u32 msm_vidc_set_buffer_count_for_thumbnail(struct msm_vidc_inst *inst) { struct msm_vidc_format *fmt; diff --git a/msm/vidc/msm_vidc_buffer_calculations.h b/msm/vidc/msm_vidc_buffer_calculations.h index 29fe98c606f5..5ba979b7937d 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.h +++ b/msm/vidc/msm_vidc_buffer_calculations.h @@ -25,7 +25,9 @@ struct msm_vidc_enc_buff_size_calculators { }; void msm_vidc_init_buffer_size_calculators(struct msm_vidc_inst *inst); -int msm_vidc_init_buffer_count(struct msm_vidc_inst *inst); +int msm_vidc_calculate_input_buffer_count(struct msm_vidc_inst *inst); +int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst); +int msm_vidc_calculate_buffer_counts(struct msm_vidc_inst *inst); int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, enum hal_buffer buffer_type); u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 01335cdaba45..6cb6736dee66 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -725,6 +725,36 @@ enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst) return HAL_VIDEO_DECODER_PRIMARY; } +bool is_single_session(struct msm_vidc_inst *inst, u32 ignore_flags) +{ + bool single = true; + struct msm_vidc_core *core; + struct msm_vidc_inst *temp; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return false; + } + core = inst->core; + + mutex_lock(&core->lock); + list_for_each_entry(temp, &core->instances, list) { + /* ignore invalid session */ + if (temp->state == MSM_VIDC_CORE_INVALID) + continue; + if ((ignore_flags & VIDC_THUMBNAIL) && + is_thumbnail_session(temp)) + continue; + if (temp != inst) { + single = false; + break; + } + } + mutex_unlock(&core->lock); + + return single; +} + static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst) { int input_port_mbs, output_port_mbs; @@ -2783,6 +2813,7 @@ static bool is_thermal_permissible(struct msm_vidc_core *core) bool is_batching_allowed(struct msm_vidc_inst *inst) { u32 op_pixelformat, fps, maxmbs, maxfps; + u32 ignore_flags = VIDC_THUMBNAIL; if (!inst || !inst->core) return false; @@ -2794,7 +2825,7 @@ bool is_batching_allowed(struct msm_vidc_inst *inst) maxmbs = inst->capability.cap[CAP_BATCH_MAX_MB_PER_FRAME].max; maxfps = inst->capability.cap[CAP_BATCH_MAX_FPS].max; - return (inst->batch.enable && + return (is_single_session(inst, ignore_flags) && is_decode_session(inst) && !is_thumbnail_session(inst) && !inst->clk_data.low_latency_mode && @@ -3150,7 +3181,7 @@ static int msm_comm_session_init(int flipped_state, goto exit; } - rc = msm_vidc_init_buffer_count(inst); + rc = msm_vidc_calculate_buffer_counts(inst); if (rc) { dprintk(VIDC_ERR, "Failed to initialize buff counts\n"); goto exit; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 7135d20436ef..7e18a095936c 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -130,6 +130,8 @@ static inline int msm_comm_s_ctrl(struct msm_vidc_inst *inst, { return v4l2_s_ctrl(NULL, &inst->ctrl_handler, ctrl); } + +bool is_single_session(struct msm_vidc_inst *inst, u32 ignore_flags); bool is_batching_allowed(struct msm_vidc_inst *inst); enum hal_buffer get_hal_buffer_type(unsigned int type, unsigned int plane_num); From 1f3b5821fe8929d93ef6098b0a57b5be60f04ac7 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Mon, 10 Jun 2019 14:15:28 -0700 Subject: [PATCH 057/452] msm: vidc: Provide default profile type in s_fmt Set default profile type to avoid error when client has not set any profile type. Change-Id: I89b81f5167f65685e47073b5e73d3bd7c4fe81d6 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_venc.c | 29 +++++++++++++++++++++++++++++ msm/vidc/msm_venc.h | 1 + 2 files changed, 30 insertions(+) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index c4f7db5b5add..49d03ffcf0f5 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1248,6 +1248,15 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) mplane->width = f->fmt.pix_mp.width; mplane->height = f->fmt.pix_mp.height; mplane->pixelformat = f->fmt.pix_mp.pixelformat; + + if (!inst->profile) { + rc = msm_venc_set_default_profile(inst); + if (rc) { + dprintk(VIDC_ERR, "%s: Failed to set default profile type\n", __func__); + goto exit; + } + } + rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE); if (rc) { dprintk(VIDC_ERR, "Failed to open instance\n"); @@ -1326,6 +1335,26 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) return rc; } +int msm_venc_set_default_profile(struct msm_vidc_inst *inst) +{ + if (!inst) { + dprintk(VIDC_ERR, + "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (get_v4l2_codec(inst) == V4L2_PIX_FMT_HEVC) + inst->profile = HFI_HEVC_PROFILE_MAIN; + else if (get_v4l2_codec(inst) == V4L2_PIX_FMT_VP8) + inst->profile = HFI_VP8_PROFILE_MAIN; + else if (get_v4l2_codec(inst) == V4L2_PIX_FMT_H264) + inst->profile = HFI_H264_PROFILE_HIGH; + else + dprintk(VIDC_ERR, + "%s: Invalid codec type %#x\n", __func__, get_v4l2_codec(inst)); + return 0; +} + int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) { struct v4l2_format *fmt; diff --git a/msm/vidc/msm_venc.h b/msm/vidc/msm_venc.h index f8c0b0a666a6..dd17266814f6 100644 --- a/msm/vidc/msm_venc.h +++ b/msm/vidc/msm_venc.h @@ -18,6 +18,7 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f); int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f); +int msm_venc_set_default_profile(struct msm_vidc_inst *inst); int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl); int msm_venc_set_properties(struct msm_vidc_inst *inst); From cb789feb4e9f4e57e9597d7fd7348e5f1f772c18 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 7 Jun 2019 17:52:22 +0530 Subject: [PATCH 058/452] msm: vidc: limit gop size to firmware max supported value Change gop size to firmware max supported range. Change-Id: Ic84dc498b9399b8cc453127c42acf42d31c0f3d4 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_venc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index c4f7db5b5add..1688cbd897fa 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -41,6 +41,7 @@ #define MAX_CBR_H 720 #define LEGACY_CBR_BUF_SIZE 500 #define CBR_PLUS_BUF_SIZE 1000 +#define MAX_GOP 0xFFFFFFF #define L_MODE V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY #define MIN_NUM_ENC_OUTPUT_BUFFERS 4 @@ -91,7 +92,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .name = "Intra Period for P frames", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, - .maximum = INT_MAX, + .maximum = MAX_GOP, .default_value = 2*DEFAULT_FPS-1, .step = 1, .qmenu = NULL, From d4b95d4a4e565989d75743b7c1c09d97579eb9dd Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Tue, 11 Jun 2019 16:41:38 -0700 Subject: [PATCH 059/452] msm: vidc: add sanity checks for clocks and regulators Add sanity checks before and after clocks and regulator operations to get more information if these operations not functional as expected. Change-Id: Ib4985113200ed065e6acf6cb7ae406b88cc7f432 Signed-off-by: Maheshwar Ajja --- msm/vidc/hfi_common.c | 34 ++++++++++++++++++++++++++++++++++ msm/vidc/hfi_common.h | 1 + 2 files changed, 35 insertions(+) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 4fbbda3a8c15..0efab74faf33 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -3759,7 +3759,16 @@ void __disable_unprepare_clks(struct venus_hfi_device *device) "Failed set flag NORETAIN_MEM %s\n", cl->name); } + + if (!__clk_is_enabled(cl->clk)) + dprintk(VIDC_ERR, "%s: clock %s already disabled\n", + __func__, cl->name); + clk_disable_unprepare(cl->clk); + + if (__clk_is_enabled(cl->clk)) + dprintk(VIDC_ERR, "%s: clock %s not disabled\n", + __func__, cl->name); } } @@ -3829,6 +3838,11 @@ static inline int __prepare_enable_clks(struct venus_hfi_device *device) "Failed set flag RETAIN_MEM %s\n", cl->name); } + + if (__clk_is_enabled(cl->clk)) + dprintk(VIDC_ERR, "%s: clock %s already enabled\n", + __func__, cl->name); + rc = clk_prepare_enable(cl->clk); if (rc) { dprintk(VIDC_ERR, "Failed to enable clocks\n"); @@ -3836,6 +3850,10 @@ static inline int __prepare_enable_clks(struct venus_hfi_device *device) goto fail_clk_enable; } + if (!__clk_is_enabled(cl->clk)) + dprintk(VIDC_ERR, "%s: clock %s not enabled\n", + __func__, cl->name); + c++; dprintk(VIDC_HIGH, "Clock: %s prepared and enabled\n", cl->name); @@ -4153,6 +4171,10 @@ static int __disable_regulator(struct regulator_info *rinfo, goto disable_regulator_failed; } + if (!regulator_is_enabled(rinfo->regulator)) + dprintk(VIDC_ERR, "%s: regulator %s already disabled\n", + __func__, rinfo->name); + rc = regulator_disable(rinfo->regulator); if (rc) { dprintk(VIDC_ERR, @@ -4161,6 +4183,10 @@ static int __disable_regulator(struct regulator_info *rinfo, goto disable_regulator_failed; } + if (regulator_is_enabled(rinfo->regulator)) + dprintk(VIDC_ERR, "%s: regulator %s not disabled\n", + __func__, rinfo->name); + return 0; disable_regulator_failed: @@ -4189,6 +4215,10 @@ static int __enable_regulators(struct venus_hfi_device *device) dprintk(VIDC_HIGH, "Enabling regulators\n"); venus_hfi_for_each_regulator(device, rinfo) { + if (regulator_is_enabled(rinfo->regulator)) + dprintk(VIDC_ERR, "%s: regulator %s already enabled\n", + __func__, rinfo->name); + rc = regulator_enable(rinfo->regulator); if (rc) { dprintk(VIDC_ERR, @@ -4197,6 +4227,10 @@ static int __enable_regulators(struct venus_hfi_device *device) goto err_reg_enable_failed; } + if (!regulator_is_enabled(rinfo->regulator)) + dprintk(VIDC_ERR, "%s: regulator %s not enabled\n", + __func__, rinfo->name); + dprintk(VIDC_HIGH, "Enabled regulator %s\n", rinfo->name); c++; diff --git a/msm/vidc/hfi_common.h b/msm/vidc/hfi_common.h index c519f2f41f96..acbbe3b3d191 100644 --- a/msm/vidc/hfi_common.h +++ b/msm/vidc/hfi_common.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "vidc_hfi_api.h" #include "vidc_hfi_helper.h" #include "vidc_hfi_api.h" From 56010535ad69b357fbe1ba2482ac16af4a807373 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Wed, 12 Jun 2019 16:29:57 +0530 Subject: [PATCH 060/452] msm: vidc: add caps for batch mode decode - Add caps for batch mode decode for lito. - fix min value for few caps. Change-Id: I24ae2baf506f885398ef9f121e6a25a141078db8 --- msm/vidc/msm_vidc_platform.c | 54 +++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 0ab19939dfb9..ff57dd450778 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -162,9 +162,9 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 5760, 1, 1920}, {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 5760, 1, 1080}, /* ((5760 * 2880) / 256) */ - {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 1, 64800, 1, 34560}, + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 64800, 1, 34560}, /* ((4096x2160)/256)@90fps */ - {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 1, 3110400, 1, 2073600}, + {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 3110400, 1, 2073600}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 480, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 200000000, 1, 20000000}, {CAP_SCALE_X, DOMAINS_ALL, CODECS_ALL, 4096, 65536, 1, 4096}, @@ -190,9 +190,9 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {CAP_FRAME_WIDTH, ENC|DEC, VP8, 96, 1920, 1, 1920}, {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 96, 1920, 1, 1080}, /* (1920 * 1088) / 256 */ - {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 1, 8160, 1, 8160}, + {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 36, 8160, 1, 8160}, /* ((1920 * 1088) / 256) * 120*/ - {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 1, 979200, 1, 244800}, + {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 36, 979200, 1, 244800}, {CAP_FRAMERATE, ENC|DEC, VP8, 1, 120, 1, 30}, {CAP_BITRATE, ENC, VP8, 1, 40000000, 1, 20000000}, {CAP_BITRATE, DEC, VP8, 1, 100000000, 1, 20000000}, @@ -201,9 +201,9 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {CAP_FRAME_WIDTH, DEC, MPEG2, 96, 1920, 1, 1920}, {CAP_FRAME_HEIGHT, DEC, MPEG2, 96, 1920, 1, 1080}, /* (1920 * 1088) / 256 */ - {CAP_MBS_PER_FRAME, DEC, MPEG2, 1, 8160, 1, 8160}, + {CAP_MBS_PER_FRAME, DEC, MPEG2, 36, 8160, 1, 8160}, /* ((1920 * 1088) / 256) * 30*/ - {CAP_MBS_PER_SECOND, DEC, MPEG2, 1, 244800, 1, 244800}, + {CAP_MBS_PER_SECOND, DEC, MPEG2, 36, 244800, 1, 244800}, {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, @@ -211,8 +211,13 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1080}, /* (4096 * 2160) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 1, 34560, 1, 34560}, + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 34560, 1, 34560}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, + + /* Batch Mode Decode */ + {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 36, 8160, 1, 8160}, + /* (1920 * 1080) / 256 */ + {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, }; static struct msm_vidc_codec_capability lito_capabilities_v1[] = { @@ -220,9 +225,9 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1080}, /* ((4096 * 2160) / 256) */ - {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 1, 34560, 1, 34560}, + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 34560, 1, 34560}, /* 4K@30 decode + 1080@30 encode */ - {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 1, 1281600, 1, 2073600}, + {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 1281600, 1, 2073600}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 240, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 100000000, 1, 20000000}, {CAP_SCALE_X, DOMAINS_ALL, CODECS_ALL, 4096, 65536, 1, 4096}, @@ -248,9 +253,9 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {CAP_FRAME_WIDTH, ENC|DEC, VP8, 96, 1920, 1, 1920}, {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 96, 1920, 1, 1080}, /* (1920 * 1088) / 256 */ - {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 1, 8160, 1, 8160}, + {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 36, 8160, 1, 8160}, /* ((1920 * 1088) / 256) * 120*/ - {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 1, 979200, 1, 244800}, + {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 36, 979200, 1, 244800}, {CAP_FRAMERATE, ENC|DEC, VP8, 1, 120, 1, 30}, {CAP_BITRATE, ENC, VP8, 1, 40000000, 1, 20000000}, {CAP_BITRATE, DEC, VP8, 1, 100000000, 1, 20000000}, @@ -259,9 +264,9 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {CAP_FRAME_WIDTH, DEC, MPEG2, 96, 1920, 1, 1920}, {CAP_FRAME_HEIGHT, DEC, MPEG2, 96, 1920, 1, 1080}, /* (1920 * 1088) / 256 */ - {CAP_MBS_PER_FRAME, DEC, MPEG2, 1, 8160, 1, 8160}, + {CAP_MBS_PER_FRAME, DEC, MPEG2, 36, 8160, 1, 8160}, /* ((1920 * 1088) / 256) * 30*/ - {CAP_MBS_PER_SECOND, DEC, MPEG2, 1, 244800, 1, 244800}, + {CAP_MBS_PER_SECOND, DEC, MPEG2, 36, 244800, 1, 244800}, {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, @@ -269,8 +274,13 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1080}, /* (4096 * 2160) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 1, 34560, 1, 34560}, + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 34560, 1, 34560}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, + + /* Batch Mode Decode */ + {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 36, 8160, 1, 8160}, + /* (1920 * 1080) / 256 */ + {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, }; static struct msm_vidc_codec_capability kona_capabilities[] = { @@ -278,9 +288,9 @@ static struct msm_vidc_codec_capability kona_capabilities[] = { {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 8192, 1, 1920}, {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 8192, 1, 1080}, /* (8192 * 4320) / 256 */ - {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 1, 138240, 1, 138240}, + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 138240, 1, 138240}, /* ((1920 * 1088) / 256) * 960 fps */ - {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 1, 7833600, 1, 7833600}, + {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 64, 7833600, 1, 7833600}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 960, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 220000000, 1, 20000000}, {CAP_SCALE_X, DOMAINS_ALL, CODECS_ALL, 4096, 65536, 1, 4096}, @@ -306,9 +316,9 @@ static struct msm_vidc_codec_capability kona_capabilities[] = { {CAP_FRAME_WIDTH, ENC|DEC, VP8, 128, 4096, 1, 1920}, {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 128, 4096, 1, 1080}, /* (4096 * 2304) / 256 */ - {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 1, 36864, 1, 8160}, + {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 64, 36864, 1, 8160}, /* ((4096 * 2304) / 256) * 120 */ - {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 1, 4423680, 1, 244800}, + {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 64, 4423680, 1, 244800}, {CAP_FRAMERATE, ENC|DEC, VP8, 1, 120, 1, 30}, {CAP_BITRATE, ENC, VP8, 1, 74000000, 1, 20000000}, {CAP_BITRATE, DEC, VP8, 1, 220000000, 1, 20000000}, @@ -317,9 +327,9 @@ static struct msm_vidc_codec_capability kona_capabilities[] = { {CAP_FRAME_WIDTH, DEC, MPEG2, 128, 1920, 1, 1920}, {CAP_FRAME_HEIGHT, DEC, MPEG2, 128, 1920, 1, 1080}, /* (1920 * 1088) / 256 */ - {CAP_MBS_PER_FRAME, DEC, MPEG2, 1, 8160, 1, 8160}, + {CAP_MBS_PER_FRAME, DEC, MPEG2, 64, 8160, 1, 8160}, /* ((1920 * 1088) / 256) * 30*/ - {CAP_MBS_PER_SECOND, DEC, MPEG2, 1, 244800, 1, 244800}, + {CAP_MBS_PER_SECOND, DEC, MPEG2, 64, 244800, 1, 244800}, {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, @@ -327,11 +337,11 @@ static struct msm_vidc_codec_capability kona_capabilities[] = { {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1080}, /* (4096 * 2304) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 1, 36864, 1, 36864}, + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 36864, 1, 36864}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, /* Batch Mode Decode */ - {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 128, 34560, 1, 34560}, + {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 64, 34560, 1, 34560}, /* (4096 * 2160) / 256 */ {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 120, 1, 120}, }; From 7e866a6a3c62c37ab4cff0447b0d3bf6596f859c Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 11 Jun 2019 10:46:04 -0700 Subject: [PATCH 061/452] msm: vidc: Initialize max cf and max cr values CF and CR cannot be zero. Initialization of Min/Max values keeps the values within limits, when FW does not provide them. Also, do not modify CF, CR value based on DCVS. Always use worst case values. CRs-Fixed: 2467542 Change-Id: I91ed83cb5c9e1a8cda5775c491d99b97c4043a12 Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc_bus.h | 1 - msm/vidc/msm_vidc_clocks.c | 22 ++++++++-------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/msm/vidc/msm_vidc_bus.h b/msm/vidc/msm_vidc_bus.h index 66d65d4b5ebd..919ee1cd3587 100644 --- a/msm/vidc/msm_vidc_bus.h +++ b/msm/vidc/msm_vidc_bus.h @@ -226,7 +226,6 @@ struct vidc_bus_vote_data { int input_cr; u32 ddr_bw; u32 sys_cache_bw; - bool use_dpb_read; unsigned int lcu_size; unsigned int fps; enum msm_vidc_power_mode power_mode; diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index cfbaddff1f62..1151b0be8a89 100755 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -14,7 +14,7 @@ #define MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR (4 << 16) #define MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO (1 << 16) -#define MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO (5 << 16) +#define MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO (3 << 16) static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst); static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, @@ -167,6 +167,7 @@ void update_recon_stats(struct msm_vidc_inst *inst, recon_stats->buffer_index) { binfo->CR = CR; binfo->CF = CF; + break; } } mutex_unlock(&inst->reconbufs.lock); @@ -177,10 +178,12 @@ static int fill_dynamic_stats(struct msm_vidc_inst *inst, { struct recon_buf *binfo, *nextb; struct vidc_input_cr_data *temp, *next; - u32 min_cf = MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR, max_cf = 0; - u32 min_input_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO, - max_input_cr = 0; - u32 min_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO, max_cr = 0; + u32 max_cr = MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO; + u32 max_cf = MSM_VIDC_MIN_UBWC_COMPLEXITY_FACTOR; + u32 max_input_cr = MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO; + u32 min_cf = MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR; + u32 min_input_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO; + u32 min_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO; mutex_lock(&inst->reconbufs.lock); list_for_each_entry_safe(binfo, nextb, &inst->reconbufs.list, list) { @@ -215,15 +218,6 @@ static int fill_dynamic_stats(struct msm_vidc_inst *inst, vote_data->compression_ratio = min_cr; vote_data->complexity_factor = max_cf; vote_data->input_cr = min_input_cr; - vote_data->use_dpb_read = false; - - /* Check if driver can vote for lower bus BW */ - if (inst->clk_data.load < inst->clk_data.load_norm) { - vote_data->compression_ratio = max_cr; - vote_data->complexity_factor = min_cf; - vote_data->input_cr = max_input_cr; - vote_data->use_dpb_read = true; - } dprintk(VIDC_PERF, "Input CR = %d Recon CR = %d Complexity Factor = %d\n", From d6ab63aafe6e3d5f44723b23ea9c7c20c7bf7131 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 11 Jun 2019 12:22:09 -0700 Subject: [PATCH 062/452] msm: vidc: Use frame statistics for decode bw calculations FW provides UBWC_CR_STATS_INFO with every EBD which can be used to accurately calculate BW requirements. Also renamed reconbufs to refbufs, which is common to encode and decode. CRs-Fixed: 2467542 Change-Id: I29afdcd466bd61f455507d30ab7ca951d0e9911c Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc.c | 2 +- msm/vidc/msm_vidc_clocks.c | 13 ++++++------- msm/vidc/msm_vidc_common.c | 28 +++++++++++----------------- msm/vidc/msm_vidc_internal.h | 2 +- 4 files changed, 19 insertions(+), 26 deletions(-) mode change 100755 => 100644 msm/vidc/msm_vidc.c mode change 100755 => 100644 msm/vidc/msm_vidc_clocks.c diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c old mode 100755 new mode 100644 index 9264190be82e..079b73d54f71 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1525,7 +1525,7 @@ void *msm_vidc_open(int core_id, int session_type) INIT_MSM_VIDC_LIST(&inst->outputbufs); INIT_MSM_VIDC_LIST(&inst->registeredbufs); INIT_MSM_VIDC_LIST(&inst->cvpbufs); - INIT_MSM_VIDC_LIST(&inst->reconbufs); + INIT_MSM_VIDC_LIST(&inst->refbufs); INIT_MSM_VIDC_LIST(&inst->eosbufs); INIT_MSM_VIDC_LIST(&inst->etb_data); INIT_MSM_VIDC_LIST(&inst->fbd_data); diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c old mode 100755 new mode 100644 index 1151b0be8a89..08328f16ff87 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -160,9 +160,8 @@ void update_recon_stats(struct msm_vidc_inst *inst, CF = recon_stats->complexity_number / frame_size; else CF = MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR; - - mutex_lock(&inst->reconbufs.lock); - list_for_each_entry(binfo, &inst->reconbufs.list, list) { + mutex_lock(&inst->refbufs.lock); + list_for_each_entry(binfo, &inst->refbufs.list, list) { if (binfo->buffer_index == recon_stats->buffer_index) { binfo->CR = CR; @@ -170,7 +169,7 @@ void update_recon_stats(struct msm_vidc_inst *inst, break; } } - mutex_unlock(&inst->reconbufs.lock); + mutex_unlock(&inst->refbufs.lock); } static int fill_dynamic_stats(struct msm_vidc_inst *inst, @@ -185,8 +184,8 @@ static int fill_dynamic_stats(struct msm_vidc_inst *inst, u32 min_input_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO; u32 min_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO; - mutex_lock(&inst->reconbufs.lock); - list_for_each_entry_safe(binfo, nextb, &inst->reconbufs.list, list) { + mutex_lock(&inst->refbufs.lock); + list_for_each_entry_safe(binfo, nextb, &inst->refbufs.list, list) { if (binfo->CR) { min_cr = min(min_cr, binfo->CR); max_cr = max(max_cr, binfo->CR); @@ -196,7 +195,7 @@ static int fill_dynamic_stats(struct msm_vidc_inst *inst, max_cf = max(max_cf, binfo->CF); } } - mutex_unlock(&inst->reconbufs.lock); + mutex_unlock(&inst->refbufs.lock); mutex_lock(&inst->input_crs.lock); list_for_each_entry_safe(temp, next, &inst->input_crs.list, list) { diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 6cb6736dee66..d285cd713f7c 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -4891,13 +4891,13 @@ int msm_comm_release_recon_buffers(struct msm_vidc_inst *inst) return -EINVAL; } - mutex_lock(&inst->reconbufs.lock); - list_for_each_entry_safe(buf, next, &inst->reconbufs.list, list) { + mutex_lock(&inst->refbufs.lock); + list_for_each_entry_safe(buf, next, &inst->refbufs.list, list) { list_del(&buf->list); kfree(buf); } - INIT_LIST_HEAD(&inst->reconbufs.list); - mutex_unlock(&inst->reconbufs.lock); + INIT_LIST_HEAD(&inst->refbufs.list); + mutex_unlock(&inst->refbufs.lock); return 0; } @@ -5049,32 +5049,26 @@ int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst) int msm_comm_set_recon_buffers(struct msm_vidc_inst *inst) { int rc = 0; - unsigned int i = 0; - struct hal_buffer_requirements *internal_buf; + unsigned int i = 0, bufcount = 0; struct recon_buf *binfo; - struct msm_vidc_list *buf_list = &inst->reconbufs; + struct msm_vidc_list *buf_list = &inst->refbufs; if (!inst) { dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); return -EINVAL; } - if (inst->session_type != MSM_VIDC_ENCODER) { - dprintk(VIDC_HIGH, "Recon buffs not req for decoder/cvp\n"); + if (inst->session_type != MSM_VIDC_ENCODER && + inst->session_type != MSM_VIDC_DECODER) { + dprintk(VIDC_HIGH, "Recon buffs not req for cvp\n"); return 0; } - internal_buf = get_buff_req_buffer(inst, - HAL_BUFFER_INTERNAL_RECON); - if (!internal_buf || !internal_buf->buffer_count_actual) { - dprintk(VIDC_HIGH, "Inst : %pK Recon buffers not required\n", - inst); - return 0; - } + bufcount = inst->fmts[OUTPUT_PORT].count_actual; msm_comm_release_recon_buffers(inst); - for (i = 0; i < internal_buf->buffer_count_actual; i++) { + for (i = 0; i < bufcount; i++) { binfo = kzalloc(sizeof(*binfo), GFP_KERNEL); if (!binfo) { dprintk(VIDC_ERR, "Out of memory\n"); diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 453451851a55..6565760a4c12 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -470,7 +470,7 @@ struct msm_vidc_inst { struct msm_vidc_list persistbufs; struct msm_vidc_list pending_getpropq; struct msm_vidc_list outputbufs; - struct msm_vidc_list reconbufs; + struct msm_vidc_list refbufs; struct msm_vidc_list eosbufs; struct msm_vidc_list registeredbufs; struct msm_vidc_list cvpbufs; From fb9ec98d7081c6f57caa6ec41c1a69791d9d7ce4 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 11 Jun 2019 10:49:27 -0700 Subject: [PATCH 063/452] msm: vidc: Add bw for cbcr dbp read and write As per system requirements this additional bw is needed for decode session. Change-Id: Ia435aadcf78e4e2fd7b01ed00633fa2f38729bc6 Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc_bus_iris2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/msm/vidc/msm_vidc_bus_iris2.c b/msm/vidc/msm_vidc_bus_iris2.c index bbb640fc46b9..1a9f92529438 100644 --- a/msm/vidc/msm_vidc_bus_iris2.c +++ b/msm/vidc/msm_vidc_bus_iris2.c @@ -171,11 +171,13 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, ddr.dpb_read = fp_div(fp_mult(ddr.dpb_read, fp_mult(dpb_factor, motion_vector_complexity)), dpb_read_compression_factor); + ddr.dpb_read += fp_div(ddr.dpb_read, FP_INT(2)); ddr.dpb_write = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; ddr.dpb_write = fp_div(fp_mult(ddr.dpb_write, fp_mult(dpb_factor, dpb_write_factor)), dpb_write_compression_factor); + ddr.dpb_write += fp_div(ddr.dpb_write, FP_INT(2)); dpb_total = ddr.dpb_read + ddr.dpb_write; From 82b121236b57bd8842828e916e55b5e1709c6215 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Thu, 13 Jun 2019 15:49:56 -0700 Subject: [PATCH 064/452] msm: vidc: amend buffer counts calculation - Consider thumbnail mode while calculating buffer counts - decide batching in reconfiguration event so that driver returns proper min buffer count when client query for it Change-Id: I4d5373e78d43592caf0cef59f2f8801d20014efd Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_vdec.c | 6 ++- msm/vidc/msm_vidc_buffer_calculations.c | 62 ++++++++++++++----------- msm/vidc/msm_vidc_buffer_calculations.h | 1 - msm/vidc/msm_vidc_common.c | 7 +++ 4 files changed, 45 insertions(+), 31 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 34a1e235fc9b..eba234ec1462 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -856,9 +856,11 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (ctrl->val) inst->flags |= VIDC_THUMBNAIL; - rc = msm_vidc_set_buffer_count_for_thumbnail(inst); + rc = msm_vidc_calculate_buffer_counts(inst); if (rc) { - dprintk(VIDC_ERR, "Failed to set buffer count\n"); + dprintk(VIDC_ERR, + "%s: %x : failed to calculate thumbnail buffer count\n", + __func__, hash32_ptr(inst->session)); return rc; } break; diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 29a3e4aa4d3b..c119cf6ba1ac 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -597,14 +597,25 @@ int msm_vidc_calculate_input_buffer_count(struct msm_vidc_inst *inst) int extra_buff_count = 0; u32 input_min_count = 4; + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + fmt = &inst->fmts[INPUT_PORT]; + if (!is_decode_session(inst) && !is_encode_session(inst)) return 0; + if (is_thumbnail_session(inst)) { + fmt->count_min = fmt->count_min_host = fmt->count_actual = + MIN_NUM_THUMBNAIL_MODE_INPUT_BUFFERS; + return 0; + } + /* * Update input buff counts * Extradata uses same count as input port */ - fmt = &inst->fmts[INPUT_PORT]; extra_buff_count = msm_vidc_get_extra_buff_count(inst, HAL_BUFFER_INPUT); fmt->count_min = input_min_count; @@ -629,10 +640,31 @@ int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst) int extra_buff_count = 0; u32 codec, output_min_count = 4; + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + fmt = &inst->fmts[OUTPUT_PORT]; + codec = get_v4l2_codec(inst); + if (!is_decode_session(inst) && !is_encode_session(inst)) return 0; - codec = get_v4l2_codec(inst); + if (is_thumbnail_session(inst)) { + if (codec == V4L2_PIX_FMT_VP9) { + fmt->count_min = + MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS_VP9; + fmt->count_min_host = fmt->count_min; + fmt->count_actual = fmt->count_min_host; + } else { + fmt->count_min = + MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS; + fmt->count_min_host = fmt->count_min; + fmt->count_actual = fmt->count_min_host; + } + return 0; + } + /* Update output buff count: Changes for decoder based on codec */ if (is_decode_session(inst)) { switch (codec) { @@ -653,7 +685,6 @@ int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst) break; } } - fmt = &inst->fmts[OUTPUT_PORT]; extra_buff_count = msm_vidc_get_extra_buff_count(inst, HAL_BUFFER_OUTPUT); fmt->count_min = output_min_count; @@ -681,31 +712,6 @@ int msm_vidc_calculate_buffer_counts(struct msm_vidc_inst *inst) return rc; } -u32 msm_vidc_set_buffer_count_for_thumbnail(struct msm_vidc_inst *inst) -{ - struct msm_vidc_format *fmt; - - fmt = &inst->fmts[INPUT_PORT]; - fmt->count_min = MIN_NUM_THUMBNAIL_MODE_INPUT_BUFFERS; - fmt->count_min_host = MIN_NUM_THUMBNAIL_MODE_INPUT_BUFFERS; - fmt->count_actual = MIN_NUM_THUMBNAIL_MODE_INPUT_BUFFERS; - - fmt = &inst->fmts[OUTPUT_PORT]; - /* VP9 super frame requires multiple frames decoding */ - if (get_v4l2_codec(inst) == V4L2_PIX_FMT_VP9) { - fmt->count_min = MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS_VP9; - fmt->count_min_host = - MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS_VP9; - fmt->count_actual = - MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS_VP9; - } else { - fmt->count_min = MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS; - fmt->count_min_host = MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS; - fmt->count_actual = MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS; - } - return 0; -} - int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, enum hal_buffer buffer_type) { diff --git a/msm/vidc/msm_vidc_buffer_calculations.h b/msm/vidc/msm_vidc_buffer_calculations.h index 5ba979b7937d..7e4575ad6e56 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.h +++ b/msm/vidc/msm_vidc_buffer_calculations.h @@ -37,6 +37,5 @@ u32 msm_vidc_calculate_enc_input_frame_size(struct msm_vidc_inst *inst); u32 msm_vidc_calculate_enc_output_frame_size(struct msm_vidc_inst *inst); u32 msm_vidc_calculate_enc_input_extra_size(struct msm_vidc_inst *inst); u32 msm_vidc_calculate_enc_output_extra_size(struct msm_vidc_inst *inst); -u32 msm_vidc_set_buffer_count_for_thumbnail(struct msm_vidc_inst *inst); #endif // __H_MSM_VIDC_BUFFER_MEM_DEFS_H__ diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 6cb6736dee66..f0dc78fbe060 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1778,6 +1778,13 @@ static void handle_event_change(enum hal_command_response cmd, void *data) if (event == V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT) { dprintk(VIDC_HIGH, "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT\n"); + + /* decide batching as configuration changed */ + if (inst->batch.enable) + inst->batch.enable = is_batching_allowed(inst); + dprintk(VIDC_HIGH, "%s: %x : batching %s\n", + __func__, hash32_ptr(inst->session), + inst->batch.enable ? "enabled" : "disabled"); } rc = msm_vidc_check_session_supported(inst); From ac11cf2022b44e99ea856b6d6689167684a2a6ba Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 12 Jun 2019 18:53:40 +0530 Subject: [PATCH 065/452] msm: vidc: Update bitstream buffer size for secure case Existing logic to calculate buffer size is based on the max bitrate supported during a secure session. Even the peak bitrate calculation is not sufficient to arrive at the required frame size. Going back to earlier logic based on macroblocks per frame. CRs-Fixed: 2467242 Change-Id: I0fe1768036f19ad2f1d08222e3ed239be7a2e27c Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_buffer_calculations.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index c119cf6ba1ac..a94be0a9e2b6 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -782,22 +782,14 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) frame_size = base_res_mbs * MB_SIZE_IN_PIXEL * 3 / 2 / div_factor; - if (is_secure_session(inst)) { - u32 max_bitrate = inst->capability.cap[CAP_SECURE_BITRATE].max; - - /* - * for secure, calc frame_size based on max bitrate, - * peak bitrate can be 10 times more and - * frame rate assumed to be 30 fps at least - */ - frame_size = (max_bitrate * 10 / 8) / 30; - } - /* multiply by 10/8 (1.25) to get size for 10 bit case */ if ((f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_VP9) || (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_HEVC)) frame_size = frame_size + (frame_size >> 2); + if (is_secure_session(inst)) + frame_size /= 2; + if (inst->buffer_size_limit && (inst->buffer_size_limit < frame_size)) { frame_size = inst->buffer_size_limit; From eb66c84844710c7375555d42b2df47c714afa996 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Fri, 14 Jun 2019 08:01:56 -0700 Subject: [PATCH 066/452] msm: vidc: amend reconfiguration buffer requirements Do not reset buffer counts while session is running and modify in case of insufficient event processing. Change-Id: I5425e54702339e768f3c3a6182fa62dd7a8b484a Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_vidc_buffer_calculations.c | 8 ++++++++ msm/vidc/msm_vidc_common.c | 19 ++++++++++--------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index c119cf6ba1ac..7812fa17d9e6 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -606,6 +606,10 @@ int msm_vidc_calculate_input_buffer_count(struct msm_vidc_inst *inst) if (!is_decode_session(inst) && !is_encode_session(inst)) return 0; + /* do not change buffer count while session is running */ + if (inst->state == MSM_VIDC_START_DONE) + return 0; + if (is_thumbnail_session(inst)) { fmt->count_min = fmt->count_min_host = fmt->count_actual = MIN_NUM_THUMBNAIL_MODE_INPUT_BUFFERS; @@ -650,6 +654,10 @@ int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst) if (!is_decode_session(inst) && !is_encode_session(inst)) return 0; + /* do not change buffer count while session is running */ + if (inst->state == MSM_VIDC_START_DONE) + return 0; + if (is_thumbnail_session(inst)) { if (codec == V4L2_PIX_FMT_VP9) { fmt->count_min = diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index f0dc78fbe060..f28c849e3027 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1765,15 +1765,6 @@ static void handle_event_change(enum hal_command_response cmd, void *data) fmt = &inst->fmts[OUTPUT_PORT]; fmt->v4l2_fmt.fmt.pix_mp.height = event_notify->height; fmt->v4l2_fmt.fmt.pix_mp.width = event_notify->width; - extra_buff_count = msm_vidc_get_extra_buff_count(inst, - HAL_BUFFER_OUTPUT); - fmt->count_min = event_notify->capture_buf_count; - fmt->count_min_host = fmt->count_min + extra_buff_count; - - dprintk(VIDC_HIGH, "%s: buffer[%d] count: min %d min_host %d\n", - __func__, HAL_BUFFER_OUTPUT, fmt->count_min, - fmt->count_min_host); - mutex_unlock(&inst->lock); if (event == V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT) { @@ -1785,6 +1776,16 @@ static void handle_event_change(enum hal_command_response cmd, void *data) dprintk(VIDC_HIGH, "%s: %x : batching %s\n", __func__, hash32_ptr(inst->session), inst->batch.enable ? "enabled" : "disabled"); + + extra_buff_count = msm_vidc_get_extra_buff_count(inst, + HAL_BUFFER_OUTPUT); + fmt->count_min = event_notify->capture_buf_count; + fmt->count_min_host = fmt->count_min + extra_buff_count; + dprintk(VIDC_HIGH, + "%s: %x : hal buffer[%d] count: min %d min_host %d\n", + __func__, hash32_ptr(inst->session), + HAL_BUFFER_OUTPUT, fmt->count_min, + fmt->count_min_host); } rc = msm_vidc_check_session_supported(inst); From 82b6884d196e1335d03ea6e798c73cd8fe7649c5 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Thu, 13 Jun 2019 18:49:57 -0700 Subject: [PATCH 067/452] msm: vidc: Update all height and width alignment to 16 Updated corresponding variables of size_vpss_lb to align height to 16. This is needed to fix internal buffer mismatch of H264 decoder with firmware which was caused due to height alignment to 8. Also updated SIZE_VP9D_LB_FE_TOP_DATA, SIZE_VP9D_LB_PE_TOP_DATA and SIZE_VP9D_LB_VSP_TOP macros width alignment to 16 from 8. Change-Id: I308a64ec69ac2a63fae9a9481652119f55834cae Signed-off-by: Akshata Sahukar --- msm/vidc/msm_vidc_buffer_calculations.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index c119cf6ba1ac..74407ba5aa47 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -207,15 +207,15 @@ #define SIZE_VP8D_LB_FE_TOP_DATA(width, height) \ ((ALIGN(width, 16) + 8) * 10 * 2) #define SIZE_VP9D_LB_FE_TOP_DATA(width, height) \ - ((ALIGN(ALIGN(width, 8), 64) + 8) * 10 * 2) + ((ALIGN(ALIGN(width, 16), 64) + 8) * 10 * 2) #define SIZE_VP8D_LB_PE_TOP_DATA(width, height) \ ((ALIGN(width, 16) >> 4) * 64) #define SIZE_VP9D_LB_PE_TOP_DATA(width, height) \ - ((ALIGN(ALIGN(width, 8), 64) >> 6) * 176) + ((ALIGN(ALIGN(width, 16), 64) >> 6) * 176) #define SIZE_VP8D_LB_VSP_TOP(width, height) \ (((ALIGN(width, 16) >> 4) * 64 / 2) + 256) #define SIZE_VP9D_LB_VSP_TOP(width, height) \ - (((ALIGN(ALIGN(width, 8), 64) >> 6) * 64 * 8) + 256) + (((ALIGN(ALIGN(width, 16), 64) >> 6) * 64 * 8) + 256) #define HFI_IRIS2_VP9D_COMV_SIZE \ @@ -967,10 +967,10 @@ static inline u32 size_vpss_lb(u32 width, u32 height) opb_wr_top_line_luma_buf_size = ALIGN(opb_wr_top_line_luma_buf_size, VENUS_DMA_ALIGNMENT) + (MAX_TILE_COLUMNS - 1) * 256; opb_wr_top_line_luma_buf_size = max(opb_wr_top_line_luma_buf_size, - (32 * ALIGN(height, 8))); + (32 * ALIGN(height, 16))); opb_wr_top_line_chroma_buf_size = opb_wr_top_line_luma_buf_size; opb_lb_wr_llb_uv_buffer_size = opb_lb_wr_llb_y_buffer_size = - ALIGN((ALIGN(height, 8) / 2) * + ALIGN((ALIGN(height, 16) / 2) * 64, BUFFER_ALIGNMENT_SIZE(32)); size = NUM_OF_VPP_PIPES * 2 * (vpss_4tap_top_buffer_size + vpss_div2_top_buffer_size) + From 185d24cdddf9aedc7c40d966dc05a52d9d2b9c03 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Mon, 17 Jun 2019 12:40:53 +0530 Subject: [PATCH 068/452] msm-vidc: calculate encode output buffer size considering 10-bit In case of opaque color format the bit depth will be known with first ETB. Existing logic calculates output buffer size based on 8-bit which won't be sufficient for 10-bit. So consider 10-bit by default while calculating encoder output buffer size. Change-Id: I51eee2fcb0dc137c596babd04659cd1fc087ebd6 --- msm/vidc/msm_vidc_buffer_calculations.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 29a3e4aa4d3b..0e94ab178db3 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -869,11 +869,15 @@ u32 msm_vidc_calculate_enc_output_frame_size(struct msm_vidc_inst *inst) if (inst->rc_type == RATE_CONTROL_LOSSLESS) frame_size = (width * height * 6); - /* For 10-bit cases size = size * 1.25 */ - if (inst->bit_depth == MSM_VIDC_BIT_DEPTH_10) { + /* + * In case of opaque color format bitdepth will be known + * with first ETB, buffers allocated already with 8 bit + * won't be sufficient for 10 bit + * calculate size considering 10-bit by default + * For 10-bit cases size = size * 1.25 + */ frame_size *= 5; frame_size /= 4; - } return ALIGN(frame_size, SZ_4K); } From 307e05c5f81d3efe34fe067f4ec82fc68c0f38cb Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Fri, 14 Jun 2019 09:39:34 -0700 Subject: [PATCH 069/452] msm: venc: Modify vbvdelay logic Modified vbvdelay logic with default behavior as CBR+. Enable legacy CBR if resolution is < 720p. Client can overwrite default behavior if resolution is between VGA & 720p. Change-Id: I9bd5ede782959780e5a5cb56eda0ae5e344e66aa Signed-off-by: Darshana Patil --- msm/vidc/msm_venc.c | 56 +++++++++++++++++++------------------- msm/vidc/msm_vidc_clocks.c | 28 +++++++++++++++++++ msm/vidc/msm_vidc_clocks.h | 4 +++ 3 files changed, 60 insertions(+), 28 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 6b3e29f16859..2cebe0a4723d 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2390,11 +2390,10 @@ int msm_venc_set_rate_control(struct msm_vidc_inst *inst) int msm_venc_set_vbv_delay(struct msm_vidc_inst *inst) { int rc = 0; + bool is_legacy_cbr; struct hfi_device *hdev; struct v4l2_ctrl *ctrl; - u32 codec; - u32 height, width, fps, mbpf, mbps; - u32 max_fps = 15; + u32 codec, height, width, buf_size; struct hfi_vbv_hrd_buf_size hrd_buf_size; struct v4l2_format *f; @@ -2408,10 +2407,6 @@ int msm_venc_set_vbv_delay(struct msm_vidc_inst *inst) codec = get_v4l2_codec(inst); height = f->fmt.pix_mp.height; width = f->fmt.pix_mp.width; - mbpf = NUM_MBS_PER_FRAME(height, width); - fps = inst->clk_data.frame_rate >> 16; - mbpf = NUM_MBS_PER_FRAME(height, width); - mbps = NUM_MBS_PER_SEC(height, width, fps); /* vbv delay is required for CBR_CFR and CBR_VFR only */ if (inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR && @@ -2422,34 +2417,39 @@ int msm_venc_set_vbv_delay(struct msm_vidc_inst *inst) if (codec == V4L2_PIX_FMT_VP8) return 0; - /* default behavior */ - inst->clk_data.is_legacy_cbr = false; - hrd_buf_size.vbv_hrd_buf_size = CBR_PLUS_BUF_SIZE; + /* Default behavior */ + is_legacy_cbr = false; + buf_size = CBR_PLUS_BUF_SIZE; - /* if resolution greater than MAX_CBR (720p), default behavior */ - if (res_is_greater_than(width, height, MAX_CBR_W, MAX_CBR_H)) - goto set_vbv_delay; - - /* enable legacy cbr if resolution less than MIN_CBRPLUS (VGA) */ - if (res_is_less_than(width, height, MIN_CBRPLUS_W, MIN_CBRPLUS_H) && - mbps <= NUM_MBS_PER_SEC(MIN_CBRPLUS_H, MIN_CBRPLUS_W, - max_fps)) { - inst->clk_data.is_legacy_cbr = true; - hrd_buf_size.vbv_hrd_buf_size = LEGACY_CBR_BUF_SIZE; - goto set_vbv_delay; - } - - /* enable legacy cbr if rate control is CBR_VFR and VBV delay is 500 */ - if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR) { + /* + * Client can set vbv delay only when + * resolution is between VGA and 720p + */ + if (res_is_greater_than_or_equal_to(width, height, MIN_CBRPLUS_W, + MIN_CBRPLUS_H) && res_is_less_than_or_equal_to(width, height, + MAX_CBR_W, MAX_CBR_H)) { ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_VBV_DELAY); if (ctrl->val == LEGACY_CBR_BUF_SIZE) { - inst->clk_data.is_legacy_cbr = true; - hrd_buf_size.vbv_hrd_buf_size = LEGACY_CBR_BUF_SIZE; - goto set_vbv_delay; + is_legacy_cbr = true; + buf_size = LEGACY_CBR_BUF_SIZE; + goto set_vbv_delay; + } else if (ctrl->val == CBR_PLUS_BUF_SIZE) { + is_legacy_cbr = false; + buf_size = CBR_PLUS_BUF_SIZE; + goto set_vbv_delay; } } + /* Enable legacy cbr if resolution < MIN_CBRPLUS (720p) */ + if (res_is_less_than(width, height, MAX_CBR_W, MAX_CBR_H)) { + is_legacy_cbr = true; + buf_size = LEGACY_CBR_BUF_SIZE; + goto set_vbv_delay; + } + set_vbv_delay: + inst->clk_data.is_legacy_cbr = is_legacy_cbr; + hrd_buf_size.vbv_hrd_buf_size = buf_size; dprintk(VIDC_HIGH, "Set hrd_buf_size %d", hrd_buf_size.vbv_hrd_buf_size); rc = call_hfi_op(hdev, session_set_property, diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 08328f16ff87..eefe15131a4d 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -116,6 +116,34 @@ bool res_is_greater_than(u32 width, u32 height, return false; } +bool res_is_greater_than_or_equal_to(u32 width, u32 height, + u32 ref_width, u32 ref_height) +{ + u32 num_mbs = NUM_MBS_PER_FRAME(height, width); + u32 max_side = max(ref_width, ref_height); + + if (num_mbs >= NUM_MBS_PER_FRAME(ref_height, ref_width) || + width >= max_side || + height >= max_side) + return true; + else + return false; +} + +bool res_is_less_than_or_equal_to(u32 width, u32 height, + u32 ref_width, u32 ref_height) +{ + u32 num_mbs = NUM_MBS_PER_FRAME(height, width); + u32 max_side = max(ref_width, ref_height); + + if (num_mbs <= NUM_MBS_PER_FRAME(ref_height, ref_width) || + width <= max_side || + height <= max_side) + return true; + else + return false; +} + int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst) { int height, width; diff --git a/msm/vidc/msm_vidc_clocks.h b/msm/vidc/msm_vidc_clocks.h index effbe7c75819..816b42ec9490 100644 --- a/msm/vidc/msm_vidc_clocks.h +++ b/msm/vidc/msm_vidc_clocks.h @@ -13,6 +13,10 @@ int msm_comm_vote_bus(struct msm_vidc_core *core); int msm_dcvs_try_enable(struct msm_vidc_inst *inst); bool res_is_less_than(u32 width, u32 height, u32 ref_width, u32 ref_height); bool res_is_greater_than(u32 width, u32 height, u32 ref_width, u32 ref_height); +bool res_is_less_than_or_equal_to(u32 width, u32 height, + u32 ref_width, u32 ref_height); +bool res_is_greater_than_or_equal_to(u32 width, u32 height, + u32 ref_width, u32 ref_height); int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst); int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst); int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst); From b491becf08c665a97341b3348e229a6d3bac1ea8 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Tue, 18 Jun 2019 15:11:00 -0700 Subject: [PATCH 070/452] msm: vidc: Update Max Allowed MB per frame Updated maximun allowed mdbf to support one 8K session and one 4K session at a time. Change-Id: I64ad3820aaddf5a3f89f97fe34c158b30f1e3675 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_vidc_platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index ff57dd450778..9ec8041205fc 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -544,7 +544,7 @@ static struct msm_vidc_common_data kona_common_data[] = { }, { .key = "qcom,max-mbpf", - .value = 138240, /* (8192x4320)/256 */ + .value = 172800, /* (8192x4320)/256 + (4096x2160)/256*/ }, { .key = "qcom,max-hq-mbs-per-frame", From 979119ba674b6be33afc2f1ecdc608f62ab8bffc Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Tue, 18 Jun 2019 15:02:27 -0700 Subject: [PATCH 071/452] msm: vidc: fix encoder reference buffer count Fixed encoder reference buffer count to use maximum number of hier players set by client. Change-Id: I7fe55aff9ee3ac5065e6cab4af37013577e3c4c0 Signed-off-by: Darshana Patil --- msm/vidc/msm_vidc_buffer_calculations.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index c75a52291fe7..89d9e1ac9804 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -456,7 +456,7 @@ int msm_vidc_get_num_ref_frames(struct msm_vidc_inst *inst) num_ref = num_ref + ltr_count; layer_ctrl = get_ctrl(inst, - V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); + V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); num_hp_layers = layer_ctrl->val; codec = get_v4l2_codec(inst); if (num_hp_layers > 0) { From 2d58b33183884aa8e613bb1eb376a204412e5819 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Tue, 18 Jun 2019 18:24:26 -0700 Subject: [PATCH 072/452] msm: vidc: fix to pass correct buffer count to fw Remove msm_vidc_calculate_output_buffer_count function calls while g_ctrl event to avoid overwriting of buffer count to old buffer count value that is set by client. Change-Id: I76135a88948ad7e2845c054a48e9f148bf367abb Signed-off-by: Akshata Sahukar --- msm/vidc/msm_vidc.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 079b73d54f71..01912b2ab77f 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1442,22 +1442,12 @@ static int try_get_ctrl_for_instance(struct msm_vidc_inst *inst, inst->level); break; case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: - rc = msm_vidc_calculate_output_buffer_count(inst); - if (rc) { - dprintk(VIDC_ERR, "g_min: input failed\n", __func__); - break; - } ctrl->val = inst->fmts[OUTPUT_PORT].count_min_host; dprintk(VIDC_HIGH, "g_min: %x : hal_buffer %d min buffers %d\n", hash32_ptr(inst->session), HAL_BUFFER_OUTPUT, ctrl->val); break; case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: - rc = msm_vidc_calculate_input_buffer_count(inst); - if (rc) { - dprintk(VIDC_ERR, "g_min: output failed\n", __func__); - break; - } ctrl->val = inst->fmts[INPUT_PORT].count_min_host; dprintk(VIDC_HIGH, "g_min: %x : hal_buffer %d min buffers %d\n", hash32_ptr(inst->session), HAL_BUFFER_INPUT, ctrl->val); From 5e31da536d759ae38d592edc7ee452d162e8a8df Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Mon, 13 May 2019 13:04:13 -0700 Subject: [PATCH 073/452] msm: vidc: add superframe encode support In HFR (High Frame Rate) encoding usecases client sends superframe (single input multiple frames). So add support for encoding superframes. Change-Id: I6f726d0ccf5b4b831e517efd3587d822da7eaae5 Signed-off-by: Maheshwar Ajja --- msm/vidc/hfi_packetization.c | 1 + msm/vidc/msm_vdec.c | 9 ++ msm/vidc/msm_venc.c | 16 +++ msm/vidc/msm_vidc_buffer_calculations.c | 18 ++++ msm/vidc/msm_vidc_clocks.c | 8 +- msm/vidc/msm_vidc_clocks.h | 5 + msm/vidc/msm_vidc_common.c | 125 +++++++++++++++++++++++- msm/vidc/msm_vidc_common.h | 10 ++ msm/vidc/msm_vidc_internal.h | 3 + 9 files changed, 192 insertions(+), 3 deletions(-) diff --git a/msm/vidc/hfi_packetization.c b/msm/vidc/hfi_packetization.c index 036a0c4c5d97..71efb4c7412c 100644 --- a/msm/vidc/hfi_packetization.c +++ b/msm/vidc/hfi_packetization.c @@ -876,6 +876,7 @@ static struct hfi_packetization_ops hfi_default = { .session_get_buf_req = create_pkt_cmd_session_get_buf_req, .session_flush = create_pkt_cmd_session_flush, .session_set_property = create_pkt_cmd_session_set_property, + .session_sync_process = create_pkt_cmd_session_sync_process, }; struct hfi_packetization_ops *hfi_get_pkt_ops_handle( diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index eba234ec1462..aad7adcba35a 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -397,6 +397,15 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, .step = 1, }, + { + .id = V4L2_CID_MPEG_VIDC_SUPERFRAME, + .name = "Superframe", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 0, + .default_value = 0, + .step = 1, + }, }; #define NUM_CTRLS ARRAY_SIZE(msm_vdec_ctrls) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 6b3e29f16859..10952e4db38b 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -948,6 +948,15 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = 0, .step = 500, }, + { + .id = V4L2_CID_MPEG_VIDC_SUPERFRAME, + .name = "Superframe", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = VIDC_SUPERFRAME_MAX, + .default_value = 0, + .step = 1, + }, }; #define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls) @@ -1798,6 +1807,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VENC_RC_TIMESTAMP_DISABLE: case V4L2_CID_MPEG_VIDEO_VBV_DELAY: case V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS: + case V4L2_CID_MPEG_VIDC_SUPERFRAME: dprintk(VIDC_HIGH, "Control set: ID : %x Val : %d\n", ctrl->id, ctrl->val); break; @@ -2166,6 +2176,12 @@ void msm_venc_decide_bframe(struct msm_vidc_inst *inst) goto disable_bframe; } } + + /* do not enable bframe if superframe is enabled */ + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); + if (ctrl->val) + goto disable_bframe; + dprintk(VIDC_HIGH, "Bframe can be enabled!\n"); return; diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index c75a52291fe7..5a9e9f605c03 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -18,6 +18,10 @@ /* extra o/p buffers in case of decoder dcvs */ #define DCVS_DEC_EXTRA_OUTPUT_BUFFERS 4 +/* extra buffers for encoder HFR usecase */ +#define HFR_EXTRA_INPUT_BUFFERS 4 +#define HFR_EXTRA_OUTPUT_BUFFERS 12 + #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_WIDTH 32 #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_HEIGHT 8 #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_UV_TILE_WIDTH 16 @@ -724,6 +728,7 @@ int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, enum hal_buffer buffer_type) { unsigned int count = 0; + struct v4l2_format *f; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s Invalid args\n", __func__); @@ -758,6 +763,19 @@ int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, count = inst->batch.size; } + /* increase both input and output counts for HFR/HSR encode case */ + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + if (is_encode_session(inst) && msm_vidc_get_fps(inst) >= 120 && + !res_is_greater_than(f->fmt.pix_mp.width, + f->fmt.pix_mp.height, 1920, 1088)) { + if (buffer_type == HAL_BUFFER_INPUT && + count < HFR_EXTRA_INPUT_BUFFERS) + count = HFR_EXTRA_INPUT_BUFFERS; + if (buffer_type == HAL_BUFFER_OUTPUT && + count < HFR_EXTRA_OUTPUT_BUFFERS) + count = HFR_EXTRA_OUTPUT_BUFFERS; + } + return count; } diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 08328f16ff87..cfb6e886906c 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -132,7 +132,7 @@ int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst) return NUM_MBS_PER_FRAME(height, width); } -static int msm_vidc_get_fps(struct msm_vidc_inst *inst) +int msm_vidc_get_fps(struct msm_vidc_inst *inst) { int fps; @@ -148,10 +148,16 @@ static int msm_vidc_get_fps(struct msm_vidc_inst *inst) void update_recon_stats(struct msm_vidc_inst *inst, struct recon_stats_type *recon_stats) { + struct v4l2_ctrl *ctrl; struct recon_buf *binfo; u32 CR = 0, CF = 0; u32 frame_size; + /* do not consider recon stats in case of superframe */ + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); + if (ctrl->val) + return; + CR = get_ubwc_compression_ratio(recon_stats->ubwc_stats_info); frame_size = (msm_vidc_get_mbs_per_frame(inst) / (32 * 8) * 3) / 2; diff --git a/msm/vidc/msm_vidc_clocks.h b/msm/vidc/msm_vidc_clocks.h index effbe7c75819..b5e5a92c7dd3 100644 --- a/msm/vidc/msm_vidc_clocks.h +++ b/msm/vidc/msm_vidc_clocks.h @@ -14,6 +14,7 @@ int msm_dcvs_try_enable(struct msm_vidc_inst *inst); bool res_is_less_than(u32 width, u32 height, u32 ref_width, u32 ref_height); bool res_is_greater_than(u32 width, u32 height, u32 ref_width, u32 ref_height); int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst); +int msm_vidc_get_fps(struct msm_vidc_inst *inst); int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst); int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst); void msm_comm_free_freq_table(struct msm_vidc_inst *inst); @@ -32,4 +33,8 @@ void msm_comm_update_input_cr(struct msm_vidc_inst *inst, u32 index, void update_recon_stats(struct msm_vidc_inst *inst, struct recon_stats_type *recon_stats); void msm_vidc_init_core_clk_ops(struct msm_vidc_core *core); +bool res_is_greater_than(u32 width, u32 height, + u32 ref_width, u32 ref_height); +bool res_is_less_than(u32 width, u32 height, + u32 ref_width, u32 ref_height); #endif diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 2f30bd36485f..2ed844988048 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2436,6 +2436,7 @@ static void handle_ebd(enum hal_command_response cmd, void *data) struct vidc_hal_ebd *empty_buf_done; u32 planes[VIDEO_MAX_PLANES] = {0}; struct v4l2_format *f; + struct v4l2_ctrl *ctrl; if (!response) { dprintk(VIDC_ERR, "Invalid response from vidc_hal\n"); @@ -2468,9 +2469,23 @@ static void handle_ebd(enum hal_command_response cmd, void *data) __func__, planes[0], planes[1]); goto exit; } - mbuf->flags &= ~MSM_VIDC_FLAG_QUEUED; vb = &mbuf->vvb.vb2_buf; + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); + if (ctrl->val && empty_buf_done->offset + + empty_buf_done->filled_len < vb->planes[0].length) { + dprintk(VIDC_HIGH, + "%s: %x : addr (%#x): offset (%d) + filled_len (%d) < length (%d)\n", + __func__, hash32_ptr(inst->session), + empty_buf_done->packet_buffer, + empty_buf_done->offset, + empty_buf_done->filled_len, + vb->planes[0].length); + kref_put_mbuf(mbuf); + goto exit; + } + + mbuf->flags &= ~MSM_VIDC_FLAG_QUEUED; vb->planes[0].bytesused = response->input_done.filled_len; if (vb->planes[0].bytesused > vb->planes[0].length) dprintk(VIDC_LOW, "bytesused overflow length\n"); @@ -4315,6 +4330,98 @@ static int msm_comm_qbuf_to_hfi(struct msm_vidc_inst *inst, return rc; } +static int msm_comm_qbuf_superframe_to_hfi(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf) +{ + int rc, i; + struct hfi_device *hdev; + struct v4l2_format *f; + struct v4l2_ctrl *ctrl; + u64 ts_delta_us; + struct vidc_frame_data *frames; + u32 num_etbs, superframe_count, frame_size, hfi_fmt; + + if (!inst || !inst->core || !inst->core->device || !mbuf) { + dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + frames = inst->superframe_data; + + if (!is_input_buffer(mbuf)) + return msm_comm_qbuf_to_hfi(inst, mbuf); + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); + superframe_count = ctrl->val; + if (superframe_count > VIDC_SUPERFRAME_MAX) { + dprintk(VIDC_ERR, "%s: wrong superframe count %d, max %d\n", + __func__, superframe_count, VIDC_SUPERFRAME_MAX); + return -EINVAL; + } + + ts_delta_us = 1000000 / (inst->clk_data.frame_rate >> 16); + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + hfi_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat); + frame_size = VENUS_BUFFER_SIZE(hfi_fmt, f->fmt.pix_mp.width, + f->fmt.pix_mp.height); + if (frame_size * superframe_count != + mbuf->vvb.vb2_buf.planes[0].length) { + dprintk(VIDC_ERR, + "%s: %#x : invalid superframe length, pxlfmt %#x wxh %dx%d framesize %d count %d length %d\n", + __func__, hash32_ptr(inst->session), + f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, + f->fmt.pix_mp.height, frame_size, superframe_count, + mbuf->vvb.vb2_buf.planes[0].length); + return -EINVAL; + } + + num_etbs = 0; + populate_frame_data(&frames[0], mbuf, inst); + /* prepare superframe buffers */ + frames[0].filled_len = frame_size; + /* + * superframe logic updates extradata and eos flags only, so + * ensure no other flags are populated in populate_frame_data() + */ + frames[0].flags &= ~HAL_BUFFERFLAG_EXTRADATA; + frames[0].flags &= ~HAL_BUFFERFLAG_EOS; + if (frames[0].flags) + dprintk(VIDC_ERR, "%s: invalid flags %#x\n", + __func__, frames[0].flags); + frames[0].flags = 0; + + for (i = 0; i < superframe_count; i++) { + if (i) + memcpy(&frames[i], &frames[0], + sizeof(struct vidc_frame_data)); + frames[i].offset += i * frame_size; + frames[i].timestamp += i * ts_delta_us; + if (!i) { + /* first frame */ + if (frames[i].extradata_addr) + frames[i].flags |= HAL_BUFFERFLAG_EXTRADATA; + } else if (i == superframe_count - 1) { + /* last frame */ + if (mbuf->vvb.flags & V4L2_BUF_FLAG_EOS) + frames[i].flags |= HAL_BUFFERFLAG_EOS; + } + num_etbs++; + } + + rc = call_hfi_op(hdev, session_process_batch, inst->session, + num_etbs, frames, 0, NULL); + if (rc) { + dprintk(VIDC_ERR, "%s: Failed to qbuf: %d\n", __func__, rc); + return rc; + } + /* update mbuf flags */ + mbuf->flags |= MSM_VIDC_FLAG_QUEUED; + mbuf->flags &= ~MSM_VIDC_FLAG_DEFERRED; + msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_ETB); + + return 0; +} + static int msm_comm_qbuf_in_rbr(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) { @@ -4345,6 +4452,7 @@ static int msm_comm_qbuf_in_rbr(struct msm_vidc_inst *inst, int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) { int rc = 0; + struct v4l2_ctrl *ctrl; if (!inst || !mbuf) { dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); @@ -4371,7 +4479,11 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__); print_vidc_buffer(VIDC_HIGH, "qbuf", inst, mbuf); - rc = msm_comm_qbuf_to_hfi(inst, mbuf); + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); + if (ctrl->val) + rc = msm_comm_qbuf_superframe_to_hfi(inst, mbuf); + else + rc = msm_comm_qbuf_to_hfi(inst, mbuf); if (rc) dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", __func__, rc); @@ -4975,14 +5087,23 @@ int msm_comm_set_buffer_count(struct msm_vidc_inst *inst, int host_count, int act_count, enum hal_buffer type) { int rc = 0; + struct v4l2_ctrl *ctrl; struct hfi_device *hdev; struct hfi_buffer_count_actual buf_count; + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } hdev = inst->core->device; buf_count.buffer_type = get_hfi_buffer(type); buf_count.buffer_count_actual = act_count; buf_count.buffer_count_min_host = host_count; + /* set total superframe buffers count */ + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); + if (ctrl->val) + buf_count.buffer_count_actual = act_count * ctrl->val; dprintk(VIDC_HIGH, "%s: %x : hal_buffer %d min_host %d actual %d\n", __func__, hash32_ptr(inst->session), type, host_count, act_count); diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 7e18a095936c..7d20fd15ae91 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -119,6 +119,16 @@ static inline bool in_port_reconfig(struct msm_vidc_inst *inst) return inst->in_reconfig && inst->bufq[INPUT_PORT].vb2_bufq.streaming; } +static inline bool is_input_buffer(struct msm_vidc_buffer *mbuf) +{ + return mbuf->vvb.vb2_buf.type == INPUT_MPLANE; +} + +static inline bool is_output_buffer(struct msm_vidc_buffer *mbuf) +{ + return mbuf->vvb.vb2_buf.type == OUTPUT_MPLANE; +} + static inline int msm_comm_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl) { diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 6565760a4c12..1258b4c999e6 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -51,6 +51,8 @@ /* Maintains the number of FTB's between each FBD over a window */ #define DCVS_FTB_WINDOW 16 +/* Superframe can have maximum of 32 frames */ +#define VIDC_SUPERFRAME_MAX 32 #define V4L2_EVENT_VIDC_BASE 10 #define INPUT_MPLANE V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE @@ -477,6 +479,7 @@ struct msm_vidc_inst { struct msm_vidc_list etb_data; struct msm_vidc_list fbd_data; struct buffer_requirements buff_req; + struct vidc_frame_data superframe_data[VIDC_SUPERFRAME_MAX]; struct v4l2_ctrl_handler ctrl_handler; struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1]; struct v4l2_ctrl **cluster; From aeee6b18dfe7f03c6d9b3352ecde9ad054019d9d Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 14 Jun 2019 12:42:57 +0530 Subject: [PATCH 074/452] msm-vidc: restrict interlace clip resolution [1] Some unsupported clip resolution like 1600x1200, firmware rejects the session during load resources. [2] Allow interlaced clip playback only if below conditions were met - resolution <= 1920x1920 - max_mbs_per_frame <= (1920x1088)/256 Change-Id: I67fd5377603c9c9ca577369c18ca6133190dc386 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_common.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 2f30bd36485f..81992279be32 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5588,6 +5588,18 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) mbpf_max); rc = -ENOTSUPP; } + if (!rc && inst->pic_struct != + MSM_VIDC_PIC_STRUCT_PROGRESSIVE && + (output_width > INTERLACE_WIDTH_MAX || + output_height > INTERLACE_HEIGHT_MAX || + (NUM_MBS_PER_FRAME(output_height, output_width) > + INTERLACE_MB_PER_FRAME_MAX))) { + dprintk(VIDC_ERR, + "Unsupported interlace WxH = (%u)x(%u), max supported is - (%u)x(%u)\n", + output_width, output_height, + INTERLACE_WIDTH_MAX, INTERLACE_HEIGHT_MAX); + rc = -ENOTSUPP; + } } if (rc) { dprintk(VIDC_ERR, From cfa9b00d0c8a29439101a36c0977224f8cfc0631 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Mon, 17 Jun 2019 11:44:18 +0530 Subject: [PATCH 075/452] msm-vidc: Update capabilities for VP8 codec - Higher SKU supports 4k@30. - Lower SKU supports 1080p@60. Change-Id: I2581e9061eedb680e49d1b040a7291211417c31a --- msm/vidc/msm_vidc_platform.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index ff57dd450778..0b8db56e4e9e 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -187,14 +187,14 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, /* VP8 specific */ - {CAP_FRAME_WIDTH, ENC|DEC, VP8, 96, 1920, 1, 1920}, - {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 96, 1920, 1, 1080}, - /* (1920 * 1088) / 256 */ - {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 36, 8160, 1, 8160}, - /* ((1920 * 1088) / 256) * 120*/ - {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 36, 979200, 1, 244800}, - {CAP_FRAMERATE, ENC|DEC, VP8, 1, 120, 1, 30}, - {CAP_BITRATE, ENC, VP8, 1, 40000000, 1, 20000000}, + {CAP_FRAME_WIDTH, ENC|DEC, VP8, 96, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 96, 4096, 1, 1080}, + /* (4096 * 2160) / 256 */ + {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 36, 34560, 1, 8160}, + /* (4096 * 2160) / 256) * 30*/ + {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 36, 1036800, 1, 244800}, + {CAP_FRAMERATE, ENC|DEC, VP8, 1, 30, 1, 30}, + {CAP_BITRATE, ENC, VP8, 1, 100000000, 1, 20000000}, {CAP_BITRATE, DEC, VP8, 1, 100000000, 1, 20000000}, /* Mpeg2 decoder specific */ @@ -254,9 +254,9 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 96, 1920, 1, 1080}, /* (1920 * 1088) / 256 */ {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 36, 8160, 1, 8160}, - /* ((1920 * 1088) / 256) * 120*/ - {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 36, 979200, 1, 244800}, - {CAP_FRAMERATE, ENC|DEC, VP8, 1, 120, 1, 30}, + /* ((1920 * 1088) / 256) * 60*/ + {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 36, 489600, 1, 244800}, + {CAP_FRAMERATE, ENC|DEC, VP8, 1, 60, 1, 30}, {CAP_BITRATE, ENC, VP8, 1, 40000000, 1, 20000000}, {CAP_BITRATE, DEC, VP8, 1, 100000000, 1, 20000000}, From 935b2ecc229a4de22fc6cbafe7ddf1703be49c20 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Wed, 19 Jun 2019 22:44:58 -0700 Subject: [PATCH 076/452] msm: vidc: cvp session clock rate and bus bandwidth Based on session configuration parameters estimate required cycles and set clock rate and bus bandwidth to cvp session. Change-Id: Iba07b304b4258e817d2404e272eb2b52891f9994 Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_cvp_external.c | 65 +++++++++++++++++++++++++++++++++++-- msm/vidc/msm_cvp_external.h | 2 ++ 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index fe470d7d7951..9742350ca8d0 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -205,6 +205,59 @@ static int msm_cvp_allocate_buffer(struct msm_vidc_inst *inst, return rc; } +static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp; + struct cvp_kmd_arg *arg; + struct cvp_kmd_usecase_desc desc; + struct cvp_kmd_request_power power; + const u32 fps_max = CVP_FRAME_RATE_MAX; + u32 fps; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; + arg = cvp->arg; + memset(&desc, 0, sizeof(struct cvp_kmd_usecase_desc)); + memset(&power, 0, sizeof(struct cvp_kmd_request_power)); + + fps = max(inst->clk_data.operating_rate, + inst->clk_data.frame_rate) >> 16; + + desc.fullres_width = cvp->width; + desc.fullres_height = cvp->height; + desc.downscale_width = cvp->ds_width; + desc.downscale_height = cvp->ds_height; + desc.is_downscale = cvp->downscale; + desc.fps = min(fps, fps_max); + desc.op_rate = min(fps, fps_max); + rc = msm_cvp_est_cycles(&desc, &power); + if (rc) { + dprintk(VIDC_ERR, "%s: estimate failed\n", __func__); + return rc; + } + dprintk(VIDC_HIGH, + "%s: core %d controller %d ddr bw %d\n", + __func__, power.clock_cycles_a, power.clock_cycles_b, + power.ddr_bw); + + memset(arg, 0, sizeof(struct cvp_kmd_arg)); + arg->type = CVP_KMD_REQUEST_POWER; + memcpy(&arg->data.req_power, &power, + sizeof(struct cvp_kmd_request_power)); + rc = msm_cvp_private(cvp->priv, CVP_KMD_REQUEST_POWER, arg); + if (rc) { + dprintk(VIDC_ERR, + "%s: request_power failed with %d\n", __func__, rc); + return rc; + } + + return rc; +} + static int msm_cvp_init_downscale_resolution(struct msm_vidc_inst *inst) { struct msm_cvp_external *cvp; @@ -723,7 +776,7 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, struct vb2_buffer *vb; struct cvp_kmd_arg *arg; struct msm_cvp_dme_frame_packet *frame; - const u32 fps_max = 60; + const u32 fps_max = CVP_FRAME_RATE_MAX; u32 fps, skip_framecount; bool skipframe = false; @@ -954,10 +1007,16 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst) goto error; dprintk(VIDC_HIGH, - "%s: pixelformat %#x, wxh %dx%d downscale %d ds_wxh %dx%d\n", + "%s: pixelformat %#x, wxh %dx%d downscale %d ds_wxh %dx%d fps %d op_rate %d\n", __func__, f->fmt.pix_mp.pixelformat, cvp->width, cvp->height, cvp->downscale, - cvp->ds_width, cvp->ds_height); + cvp->ds_width, cvp->ds_height, + inst->clk_data.frame_rate >> 16, + inst->clk_data.operating_rate >> 16); + + rc = msm_cvp_set_clocks_and_bus(inst); + if (rc) + goto error; memset(arg, 0, sizeof(struct cvp_kmd_arg)); arg->type = CVP_KMD_SEND_CMD_PKT; diff --git a/msm/vidc/msm_cvp_external.h b/msm/vidc/msm_cvp_external.h index 5983e7e71f3b..fd8b739af2b1 100644 --- a/msm/vidc/msm_cvp_external.h +++ b/msm/vidc/msm_cvp_external.h @@ -40,6 +40,8 @@ #define CVP_KMD_HFI_VERSION_PROP_TYPE (1) #define CVP_KMD_HFI_VERSION_PROP_NUMBER (1) +#define CVP_FRAME_RATE_MAX (60) + static inline bool is_vidc_cvp_enabled(struct msm_vidc_inst *inst) { return !!inst->cvp; From 836b73ab5f777640b393923fdf29063130bf8b2b Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Fri, 21 Jun 2019 18:09:00 -0700 Subject: [PATCH 077/452] msm: vidc: fix slice command buffer sizes Fix HEVC slice command buffer sizes. Change-Id: I87138c75e7476e6da6c16cefed00d9a3f405b90e Signed-off-by: Darshana Patil --- msm/vidc/msm_vidc_buffer_calculations.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index abe4a8ebb4d7..212f4a5d7bbf 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1109,11 +1109,13 @@ static inline u32 size_h265d_bse_cmd_buf(u32 width, u32 height) { u32 size; - size = ALIGN(((ALIGN(width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) + - (ALIGN(height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) * - NUM_HW_PIC_BUF, VENUS_DMA_ALIGNMENT); + size = (ALIGN(width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) + + (ALIGN(height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) * + NUM_HW_PIC_BUF; size = min_t(u32, size, H265D_MAX_SLICE + 1); size = 2 * size * SIZE_H265D_BSE_CMD_PER_BUF; + size = ALIGN(size, VENUS_DMA_ALIGNMENT); + return size; } @@ -1121,13 +1123,13 @@ static inline u32 size_h265d_vpp_cmd_buf(u32 width, u32 height) { u32 size = 0; - size = ALIGN(( - (ALIGN(width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) + - (ALIGN(height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) * - NUM_HW_PIC_BUF, VENUS_DMA_ALIGNMENT); + size = (ALIGN(width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) + + (ALIGN(height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) * + NUM_HW_PIC_BUF; size = min_t(u32, size, H265D_MAX_SLICE + 1); size = ALIGN(size, 4); size = 2 * size * SIZE_H265D_VPP_CMD_PER_BUF; + size = ALIGN(size, VENUS_DMA_ALIGNMENT); return size; } From 9fed96ca68a91407bd5cd1a84684bb124c1ef9ed Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Sun, 23 Jun 2019 13:12:13 +0530 Subject: [PATCH 078/452] msm: vidc: add check to avoid out-of-buffer write Possibility of dereferencing userspace ptr in kernel for invalid cmd. So added check to return error if unsupported cmd is given as input to ioctl. Change-Id: I3466fbd06e5b600f748824b9e16bcfdb4438bdef Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 01912b2ab77f..842252c797fd 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1343,6 +1343,12 @@ int msm_vidc_private(void *vidc_inst, unsigned int cmd, int rc = 0; struct msm_vidc_inst *inst = (struct msm_vidc_inst *)vidc_inst; + if (cmd != VIDIOC_VIDEO_CMD) { + dprintk(VIDC_ERR, + "%s: invalid private cmd %#x\n", __func__, cmd); + return -ENOIOCTLCMD; + } + if (!inst || !arg) { dprintk(VIDC_ERR, "%s: invalid args\n", __func__); return -EINVAL; From 254903a695b331cd7076fa8ce4b180071654457b Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Tue, 25 Jun 2019 17:59:38 +0800 Subject: [PATCH 079/452] msm: vidc: fix slice mbs setting When MB_MODE slice is enabled, should use output width/height to calculate the allowed slice size. Fix warning log for NV21 format. Change-Id: I97441cef36484ac6e82ba78b816f96d4b5bf2ab4 Signed-off-by: Qiwei Liu --- msm/vidc/msm_venc.c | 2 +- msm/vidc/msm_vidc_common.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index c3bf12ed8ded..03ca6978b325 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2902,7 +2902,7 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst) goto set_and_exit; } - f = &inst->fmts[INPUT_PORT].v4l2_fmt; + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; output_width = f->fmt.pix_mp.width; output_height = f->fmt.pix_mp.height; if ((codec == V4L2_PIX_FMT_HEVC) && diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 2ed844988048..6bf2aabd4831 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -3532,6 +3532,8 @@ u32 msm_comm_convert_color_fmt(u32 v4l2_fmt) switch (v4l2_fmt) { case V4L2_PIX_FMT_NV12: return COLOR_FMT_NV12; + case V4L2_PIX_FMT_NV21: + return COLOR_FMT_NV21; case V4L2_PIX_FMT_NV12_512: return COLOR_FMT_NV12_512; case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS: From 7a43aa6b189668e2706480be19ab24311b21dd4a Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Tue, 25 Jun 2019 11:28:27 -0700 Subject: [PATCH 080/452] msm: vidc: fix encoder internal buffer size Fixed all encoder internal buffer size calculation based on bitstream buffer size. Change-Id: Ib4bdf89f356877acd151d2d0a5a7ca8901421a84 Signed-off-by: Darshana Patil --- msm/vidc/msm_vidc_buffer_calculations.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 1e0fed51998c..9735d44c5004 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -509,7 +509,7 @@ int msm_vidc_get_encoder_internal_buffer_sizes(struct msm_vidc_inst *inst) return -EINVAL; } - f = &inst->fmts[INPUT_PORT].v4l2_fmt; + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; width = f->fmt.pix_mp.width; height = f->fmt.pix_mp.height; bframe = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); @@ -1512,10 +1512,10 @@ static inline u32 calculate_enc_scratch1_size(struct msm_vidc_inst *inst, (VENUS_DMA_ALIGNMENT + 16 * (width_coded >> 4)); topline_buf_ctrl_size_FE = ALIGN(topline_buf_ctrl_size_FE, VENUS_DMA_ALIGNMENT); - leftline_buf_ctrl_size_FE = ((VENUS_DMA_ALIGNMENT + 64 * + leftline_buf_ctrl_size_FE = (((VENUS_DMA_ALIGNMENT + 64 * (height_coded >> 4)) + (VENUS_DMA_ALIGNMENT << (num_vpp_pipes - 1)) - 1) & - (~((VENUS_DMA_ALIGNMENT << (num_vpp_pipes - 1)) - 1)) * + (~((VENUS_DMA_ALIGNMENT << (num_vpp_pipes - 1)) - 1)) * 1) * num_vpp_pipes; leftline_buf_meta_recony = ((VENUS_DMA_ALIGNMENT + 64 * ((height_coded) / (8 * (ten_bit ? 4 : 8)))) * num_vpp_pipes); From 04f6c63d2de9e27ba6778bdb910615f969c8e538 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 25 Jun 2019 15:27:27 -0700 Subject: [PATCH 081/452] msm: vidc: Add trace for every buffer transaction Tracing all the buffer transactions give clear picture of session behaviour and is helpful in performance analysis. CRs-Fixed: 2478892 Change-Id: Ibab23a187af77434e20ce0b1c51de29b9d1731f9 Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc_debug.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index 47f0cfc61741..1455f3faee88 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -480,6 +480,9 @@ void msm_vidc_debugfs_update(struct msm_vidc_inst *inst, switch (e) { case MSM_VIDC_DEBUGFS_EVENT_ETB: inst->count.etb++; + trace_msm_v4l2_vidc_buffer_counter("ETB", + inst->count.etb, inst->count.ebd, + inst->count.ftb, inst->count.fbd); if (inst->count.ebd && inst->count.ftb > inst->count.fbd) { d->pdata[FRAME_PROCESSING].name[0] = '\0'; tic(inst, FRAME_PROCESSING, a); @@ -487,6 +490,9 @@ void msm_vidc_debugfs_update(struct msm_vidc_inst *inst, break; case MSM_VIDC_DEBUGFS_EVENT_EBD: inst->count.ebd++; + trace_msm_v4l2_vidc_buffer_counter("EBD", + inst->count.etb, inst->count.ebd, + inst->count.ftb, inst->count.fbd); if (inst->count.ebd && inst->count.ebd == inst->count.etb) { toc(inst, FRAME_PROCESSING); dprintk(VIDC_PERF, "EBD: FW needs input buffers\n"); @@ -496,6 +502,9 @@ void msm_vidc_debugfs_update(struct msm_vidc_inst *inst, break; case MSM_VIDC_DEBUGFS_EVENT_FTB: { inst->count.ftb++; + trace_msm_v4l2_vidc_buffer_counter("FTB", + inst->count.etb, inst->count.ebd, + inst->count.ftb, inst->count.fbd); if (inst->count.ebd && inst->count.etb > inst->count.ebd) { d->pdata[FRAME_PROCESSING].name[0] = '\0'; tic(inst, FRAME_PROCESSING, a); @@ -505,6 +514,9 @@ void msm_vidc_debugfs_update(struct msm_vidc_inst *inst, case MSM_VIDC_DEBUGFS_EVENT_FBD: inst->count.fbd++; inst->debug.samples++; + trace_msm_v4l2_vidc_buffer_counter("FBD", + inst->count.etb, inst->count.ebd, + inst->count.ftb, inst->count.fbd); if (inst->count.fbd && inst->count.fbd == inst->count.ftb) { toc(inst, FRAME_PROCESSING); From 8bfbae799db34ff1bc640b1b0256571cf0cfeaae Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Wed, 26 Jun 2019 13:25:23 -0700 Subject: [PATCH 082/452] msm: vidc: fix slice command buffer sizes Fix HEVC slice command buffer sizes. Change-Id: I8db40a80561eebb15fba9345d37b51bd42380c4f --- msm/vidc/msm_vidc_buffer_calculations.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 9735d44c5004..bc5e7e9d864e 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1127,7 +1127,7 @@ static inline u32 size_h265d_bse_cmd_buf(u32 width, u32 height) { u32 size; - size = (ALIGN(width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) + + size = (ALIGN(width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) * (ALIGN(height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) * NUM_HW_PIC_BUF; size = min_t(u32, size, H265D_MAX_SLICE + 1); @@ -1141,7 +1141,7 @@ static inline u32 size_h265d_vpp_cmd_buf(u32 width, u32 height) { u32 size = 0; - size = (ALIGN(width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) + + size = (ALIGN(width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) * (ALIGN(height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) * NUM_HW_PIC_BUF; size = min_t(u32, size, H265D_MAX_SLICE + 1); From 14f8f69554186ca8598be28a7e429eaf7b1cd7ae Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 25 Jun 2019 17:56:24 -0700 Subject: [PATCH 083/452] msm: vidc: Increase min input buffer count by 2 This smoothens the buffer flow and takes care of random frame drops due to jitter. CRs-Fixed: 2478892 Change-Id: I27ecb686e3982152b18f3a2fc207ecf59f928dff Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc_buffer_calculations.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 9735d44c5004..50913d9e9ee7 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -624,6 +624,9 @@ int msm_vidc_calculate_input_buffer_count(struct msm_vidc_inst *inst) * Update input buff counts * Extradata uses same count as input port */ + if (is_decode_session(inst) && !is_secure_session(inst)) + input_min_count += 2; + extra_buff_count = msm_vidc_get_extra_buff_count(inst, HAL_BUFFER_INPUT); fmt->count_min = input_min_count; From 1332222345609d8fd8cbf05beb36fe3a97f0f226 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Wed, 26 Jun 2019 17:08:51 +0800 Subject: [PATCH 084/452] msm: vidc: add lossless encoding capability 1. Define lossless capability upto 4096x2304@60fps; 2. Check capability when starting the streaming; Change-Id: Iaa737aca6132b27a22a4e80a7d8eddfd83360b23 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_vidc_common.c | 29 +++++++++++++++++++++++++++++ msm/vidc/msm_vidc_platform.c | 6 ++++++ msm/vidc/vidc_hfi_api.h | 3 +++ 3 files changed, 38 insertions(+) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 2ed844988048..f5f2778d2bc7 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1552,6 +1552,26 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data) print_cap("b_qp", &inst->capability.cap[CAP_B_FRAME_QP]); print_cap("slice_bytes", &inst->capability.cap[CAP_SLICE_BYTE]); print_cap("slice_mbs", &inst->capability.cap[CAP_SLICE_MB]); + print_cap("max_videocores", &inst->capability.cap[CAP_MAX_VIDEOCORES]); + /* Secure usecase specific */ + print_cap("secure_width", + &inst->capability.cap[CAP_SECURE_FRAME_WIDTH]); + print_cap("secure_height", + &inst->capability.cap[CAP_SECURE_FRAME_HEIGHT]); + print_cap("secure_mbs_per_frame", + &inst->capability.cap[CAP_SECURE_MBS_PER_FRAME]); + print_cap("secure_bitrate", &inst->capability.cap[CAP_SECURE_BITRATE]); + /* Batch Mode Decode */ + print_cap("batch_mbs_per_frame", + &inst->capability.cap[CAP_BATCH_MAX_MB_PER_FRAME]); + print_cap("batch_frame_rate", &inst->capability.cap[CAP_BATCH_MAX_FPS]); + /* Lossless encoding usecase specific */ + print_cap("lossless_width", + &inst->capability.cap[CAP_LOSSLESS_FRAME_WIDTH]); + print_cap("lossless_height", + &inst->capability.cap[CAP_LOSSLESS_FRAME_HEIGHT]); + print_cap("lossless_mbs_per_frame", + &inst->capability.cap[CAP_LOSSLESS_MBS_PER_FRAME]); msm_vidc_comm_update_ctrl_limits(inst); @@ -5656,6 +5676,15 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) mbpf_max = capability->cap[CAP_MBS_PER_FRAME].max; } + if (inst->session_type == MSM_VIDC_ENCODER && + inst->rc_type == RATE_CONTROL_LOSSLESS) { + width_min = capability->cap[CAP_LOSSLESS_FRAME_WIDTH].min; + width_max = capability->cap[CAP_LOSSLESS_FRAME_WIDTH].max; + height_min = capability->cap[CAP_LOSSLESS_FRAME_HEIGHT].min; + height_max = capability->cap[CAP_LOSSLESS_FRAME_HEIGHT].max; + mbpf_max = capability->cap[CAP_LOSSLESS_MBS_PER_FRAME].max; + } + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; output_height = f->fmt.pix_mp.height; output_width = f->fmt.pix_mp.width; diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 109506bffaa4..a9531c916e6f 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -344,6 +344,12 @@ static struct msm_vidc_codec_capability kona_capabilities[] = { {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 64, 34560, 1, 34560}, /* (4096 * 2160) / 256 */ {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 120, 1, 120}, + + /* Lossless encoding usecase specific */ + {CAP_LOSSLESS_FRAME_WIDTH, ENC, H264|HEVC, 128, 4096, 1, 1920}, + {CAP_LOSSLESS_FRAME_HEIGHT, ENC, H264|HEVC, 128, 4096, 1, 1080}, + /* (4096 * 2304) / 256 */ + {CAP_LOSSLESS_MBS_PER_FRAME, ENC, H264|HEVC, 64, 36864, 1, 36864}, }; /* diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 37eba5880fbe..48097a046509 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -280,6 +280,9 @@ enum hal_capability { CAP_SECURE_BITRATE, CAP_BATCH_MAX_MB_PER_FRAME, CAP_BATCH_MAX_FPS, + CAP_LOSSLESS_FRAME_WIDTH, + CAP_LOSSLESS_FRAME_HEIGHT, + CAP_LOSSLESS_MBS_PER_FRAME, CAP_MAX, }; From d9ceba876f5f9e6de84274f4bf8d9570552e66b6 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Thu, 27 Jun 2019 16:20:36 +0800 Subject: [PATCH 085/452] msm: vidc: refinements for lossless encoding 1. Refine work mode to 2 and disable low latency by default; 2. Refine output buffer size to (width * height) * 9 / 4; 3. Double scratch buffer size for lossless encoding; Change-Id: If298b9fc63fc2329f02dcfcef5e4fd0667d3e8e6 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_vidc_buffer_calculations.c | 4 +++- msm/vidc/msm_vidc_clocks.c | 8 +++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 1e0fed51998c..ec524b6bc804 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -891,7 +891,7 @@ u32 msm_vidc_calculate_enc_output_frame_size(struct msm_vidc_inst *inst) frame_size = frame_size << 1; if (inst->rc_type == RATE_CONTROL_LOSSLESS) - frame_size = (width * height * 6); + frame_size = (width * height * 9) >> 2; /* * In case of opaque color format bitdepth will be known @@ -1300,6 +1300,8 @@ static inline u32 calculate_enc_scratch_size(struct msm_vidc_inst *inst, bitbin_size = ALIGN(bitstream_size, VENUS_DMA_ALIGNMENT); } size_singlePipe = bitbin_size / 2; + if (inst->rc_type == RATE_CONTROL_LOSSLESS) + size_singlePipe <<= 1; size_singlePipe = ALIGN(size_singlePipe, VENUS_DMA_ALIGNMENT); sao_bin_buffer_size = (64 * (((width + BUFFER_ALIGNMENT_SIZE(32)) * (height + BUFFER_ALIGNMENT_SIZE(32))) >> 10)) + 384; diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 809acafadf5d..76ab755bacb8 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1514,11 +1514,9 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) /* For WORK_MODE_1, set Low Latency mode by default */ latency.enable = true; } - if (inst->rc_type == RATE_CONTROL_LOSSLESS && - out_f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_H264) { - dprintk(VIDC_HIGH, - "Set work mode to low latency for AVC lossless encoding."); - latency.enable = true; + if (inst->rc_type == RATE_CONTROL_LOSSLESS) { + pdata.video_work_mode = HFI_WORKMODE_2; + latency.enable = false; } } else { return -EINVAL; From d5074f0078f68c113769e90db9a74258b52f21ec Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Mon, 17 Jun 2019 19:53:50 -0700 Subject: [PATCH 086/452] msm: vidc: do not allow queue buffer in flush Client is not supposed to queue buffer while driver is in flush. Return error if client queue buffer in flush to avoid possible deadlock issues in driver due to release buffer reference event processing. Change-Id: Ica2ff40e428f82b9f6d3aa1314f7bf7d322375bd Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_vidc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 842252c797fd..14fa7975ac7c 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -340,6 +340,12 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) return -EINVAL; } + if (inst->in_flush && is_decode_session(inst) && + b->type == OUTPUT_MPLANE) { + dprintk(VIDC_ERR, "%s: in flush, discarding qbuf\n", __func__); + return -EINVAL; + } + for (i = 0; i < b->length; i++) { b->m.planes[i].m.fd = b->m.planes[i].reserved[0]; b->m.planes[i].data_offset = b->m.planes[i].reserved[1]; From a705e592b98e9de39e62d16e34bd12c3385251a6 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Fri, 28 Jun 2019 11:39:07 -0700 Subject: [PATCH 087/452] msm: vidc: update encoder scratch1 size Updated encoder scratch1 buffer size macro to match HFICCB changes. This fixes mismatch in driver and HFI macro scratch1 buffer sizes. Change-Id: Ie61058f243dc1895e0af00b78118bbe9dbc54a98 --- msm/vidc/msm_vidc_buffer_calculations.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index ef049d19e815..5c47c79fd613 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1480,13 +1480,14 @@ static inline u32 calculate_enc_scratch1_size(struct msm_vidc_inst *inst, u32 width_lcu_num, height_lcu_num, width_coded, height_coded; u32 frame_num_lcu, linebuf_meta_recon_uv, topline_bufsize_fe_1stg_sao; u32 output_mv_bufsize = 0, temp_scratch_mv_bufsize = 0; - u32 size, bit_depth; + u32 size, bit_depth, num_LCUMB; width_lcu_num = ((width)+(lcu_size)-1) / (lcu_size); height_lcu_num = ((height)+(lcu_size)-1) / (lcu_size); frame_num_lcu = width_lcu_num * height_lcu_num; width_coded = width_lcu_num * (lcu_size); height_coded = height_lcu_num * (lcu_size); + num_LCUMB = (height_coded / lcu_size) * ((width_coded + lcu_size * 8) / lcu_size); slice_info_bufsize = (256 + (frame_num_lcu << 4)); slice_info_bufsize = ALIGN(slice_info_bufsize, VENUS_DMA_ALIGNMENT); line_buf_ctrl_size = ALIGN(width_coded, VENUS_DMA_ALIGNMENT); @@ -1522,14 +1523,18 @@ static inline u32 calculate_enc_scratch1_size(struct msm_vidc_inst *inst, (VENUS_DMA_ALIGNMENT << (num_vpp_pipes - 1)) - 1) & (~((VENUS_DMA_ALIGNMENT << (num_vpp_pipes - 1)) - 1)) * 1) * num_vpp_pipes; - leftline_buf_meta_recony = ((VENUS_DMA_ALIGNMENT + 64 * - ((height_coded) / (8 * (ten_bit ? 4 : 8)))) * num_vpp_pipes); + leftline_buf_meta_recony = (VENUS_DMA_ALIGNMENT + 64 * + ((height_coded) / (8 * (ten_bit ? 4 : 8)))); leftline_buf_meta_recony = ALIGN(leftline_buf_meta_recony, VENUS_DMA_ALIGNMENT); - linebuf_meta_recon_uv = ((VENUS_DMA_ALIGNMENT + 64 * - ((height_coded) / (4 * (ten_bit ? 4 : 8)))) * num_vpp_pipes); + leftline_buf_meta_recony = leftline_buf_meta_recony * + num_vpp_pipes; + linebuf_meta_recon_uv = (VENUS_DMA_ALIGNMENT + 64 * + ((height_coded) / (4 * (ten_bit ? 4 : 8)))); linebuf_meta_recon_uv = ALIGN(linebuf_meta_recon_uv, VENUS_DMA_ALIGNMENT); + linebuf_meta_recon_uv = linebuf_meta_recon_uv * + num_vpp_pipes; line_buf_recon_pix_size = ((ten_bit ? 3 : 2) * width_coded); line_buf_recon_pix_size = ALIGN(line_buf_recon_pix_size, VENUS_DMA_ALIGNMENT); @@ -1578,8 +1583,8 @@ static inline u32 calculate_enc_scratch1_size(struct msm_vidc_inst *inst, bse_reg_buffer_size = ((((512 << 3) + 7) & (~7)) * 4); vpp_reg_buffer_size = ((((HFI_VENUS_VPPSG_MAX_REGISTERS << 3) + 31) & (~31)) * 10); - lambda_lut_size = ((((52 << 1) + 7) & (~7)) * 11); - override_buffer_size = 16 * ((frame_num_lcu + 7) >> 3); + lambda_lut_size = (256 * 11); + override_buffer_size = 16 * ((num_LCUMB + 7) >> 3); override_buffer_size = ALIGN(override_buffer_size, VENUS_DMA_ALIGNMENT) * 2; ir_buffer_size = (((frame_num_lcu << 1) + 7) & (~7)) * 3; From 9734cff1ca072634255185b0dc4d3316d906c8cd Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Mon, 1 Jul 2019 16:39:27 +0530 Subject: [PATCH 088/452] msm-vidc: update decoder scaling capability Update scaling capability for decoder to reject the usecase where o/p resolution is less than i/p resolution. Change-Id: I7cf85db78d51f8dd43da8d4312c92ea982054cb1 --- msm/vidc/msm_vidc_platform.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index a9531c916e6f..c98973d52173 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -167,8 +167,10 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 3110400, 1, 2073600}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 480, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 200000000, 1, 20000000}, - {CAP_SCALE_X, DOMAINS_ALL, CODECS_ALL, 4096, 65536, 1, 4096}, - {CAP_SCALE_Y, DOMAINS_ALL, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_SCALE_X, ENC, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_SCALE_Y, ENC, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_SCALE_X, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, + {CAP_SCALE_Y, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 4, 1, 0}, @@ -230,8 +232,10 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 1281600, 1, 2073600}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 240, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 100000000, 1, 20000000}, - {CAP_SCALE_X, DOMAINS_ALL, CODECS_ALL, 4096, 65536, 1, 4096}, - {CAP_SCALE_Y, DOMAINS_ALL, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_SCALE_X, ENC, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_SCALE_Y, ENC, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_SCALE_X, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, + {CAP_SCALE_Y, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 4, 1, 0}, @@ -293,8 +297,10 @@ static struct msm_vidc_codec_capability kona_capabilities[] = { {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 64, 7833600, 1, 7833600}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 960, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 220000000, 1, 20000000}, - {CAP_SCALE_X, DOMAINS_ALL, CODECS_ALL, 4096, 65536, 1, 4096}, - {CAP_SCALE_Y, DOMAINS_ALL, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_SCALE_X, ENC, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_SCALE_Y, ENC, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_SCALE_X, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, + {CAP_SCALE_Y, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 2, 1, 0}, From a57153a3f9e3ec1fc5344ecf1f2400168aec2126 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Tue, 2 Jul 2019 11:33:25 +0530 Subject: [PATCH 089/452] msm: vidc: Add check to avoid NULL ptr dereference v4l2_ctrl_get_name may return NULL that leads to NULL ptr dereference. So added necessay check to avoid ptr dereferencing if it is NULL. Change-Id: If1a4ee8fe22e240b278f31888637d22b81b334e1 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 14fa7975ac7c..10d84555ad21 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1390,6 +1390,7 @@ static int msm_vidc_op_s_ctrl(struct v4l2_ctrl *ctrl) int rc = 0; unsigned int c = 0; struct msm_vidc_inst *inst; + const char *ctrl_name = NULL; if (!ctrl) { dprintk(VIDC_ERR, "%s invalid parameters for ctrl\n", __func__); @@ -1413,9 +1414,12 @@ static int msm_vidc_op_s_ctrl(struct v4l2_ctrl *ctrl) } } } - if (rc) + if (rc) { + ctrl_name = v4l2_ctrl_get_name(ctrl->id); dprintk(VIDC_ERR, "Failed setting control: Inst = %pK (%s)\n", - inst, v4l2_ctrl_get_name(ctrl->id)); + inst, ctrl_name ? ctrl_name : "Invalid ctrl"); + } + return rc; } From 9ce9c42bbbce06b16675de033151b4bf88bac570 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 3 Jul 2019 18:15:06 +0530 Subject: [PATCH 090/452] msm: vidc: Avoid information leak while accessing the packet Use trusted packet size on the received packet and check for the size of the data received against the expected size before accessing the packet. Change-Id: I1bd6008249a0bf4edeec711ec8d23cf7b8dac1f1 Signed-off-by: Priyanka Gujjula --- msm/vidc/hfi_response_handler.c | 56 ++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index 5805b7ba195d..115f544b53a4 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -95,23 +95,30 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, struct msm_vidc_cb_info *info) { struct msm_vidc_cb_event event_notify = {0}; - int num_properties_changed; + u32 num_properties_changed; struct hfi_frame_size *frame_sz; struct hfi_profile_level *profile_level; struct hfi_bit_depth *pixel_depth; struct hfi_pic_struct *pic_struct; struct hfi_buffer_requirements *buf_req; struct hfi_index_extradata_input_crop_payload *crop_info; - u32 entropy_mode = 0; + u32 rem_size,entropy_mode = 0; u8 *data_ptr; int prop_id; int luma_bit_depth, chroma_bit_depth; struct hfi_colour_space *colour_info; - if (sizeof(struct hfi_msg_event_notify_packet) > pkt->size) { - dprintk(VIDC_ERR, "%s: bad_pkt_size\n", __func__); +#define VALIDATE_PKT_SIZE(__rem_size, __msg_size) ({ \ + if (__rem_size < __msg_size) { \ + dprintk(VIDC_ERR, \ + "hal_process_session_init_done: bad_pkt_size\n"); \ + false; \ + } \ + true; \ + }) + if (!VALIDATE_PKT_SIZE(pkt->size, + sizeof(struct hfi_msg_event_notify_packet))) return -E2BIG; - } event_notify.device_id = device_id; event_notify.session_id = (void *)(uintptr_t)pkt->session_id; @@ -132,10 +139,18 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, if (num_properties_changed) { data_ptr = (u8 *) &pkt->rg_ext_event_data[0]; + rem_size = pkt->size - sizeof(struct + hfi_msg_event_notify_packet) + sizeof(u32); do { + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(u32))) + return -E2BIG; prop_id = (int) *((u32 *)data_ptr); + rem_size -= sizeof(u32); switch (prop_id) { case HFI_PROPERTY_PARAM_FRAME_SIZE: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + hfi_frame_size))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); frame_sz = (struct hfi_frame_size *) data_ptr; @@ -145,8 +160,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, frame_sz->height, frame_sz->width); data_ptr += sizeof(struct hfi_frame_size); + rem_size -= sizeof(struct hfi_frame_size); break; case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + hfi_profile_level))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); profile_level = (struct hfi_profile_level *) data_ptr; @@ -157,8 +176,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, profile_level->level); data_ptr += sizeof(struct hfi_profile_level); + rem_size -= sizeof(struct hfi_profile_level); break; case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + hfi_bit_depth))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); pixel_depth = (struct hfi_bit_depth *) data_ptr; /* @@ -189,8 +212,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, event_notify.bit_depth, luma_bit_depth, chroma_bit_depth); data_ptr += sizeof(struct hfi_bit_depth); + rem_size -= sizeof(struct hfi_bit_depth); break; case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + hfi_pic_struct))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); pic_struct = (struct hfi_pic_struct *) data_ptr; event_notify.pic_struct = @@ -200,8 +227,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, pic_struct->progressive_only); data_ptr += sizeof(struct hfi_pic_struct); + rem_size -= sizeof(struct hfi_pic_struct); break; case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + hfi_colour_space))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); colour_info = (struct hfi_colour_space *) data_ptr; @@ -212,8 +243,11 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, colour_info->colour_space); data_ptr += sizeof(struct hfi_colour_space); + rem_size -= sizeof(struct hfi_colour_space); break; case HFI_PROPERTY_CONFIG_VDEC_ENTROPY: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(u32))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); entropy_mode = *(u32 *)data_ptr; event_notify.entropy_mode = entropy_mode; @@ -221,8 +255,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, "Entropy Mode: 0x%x\n", entropy_mode); data_ptr += sizeof(u32); + rem_size -= sizeof(u32); break; case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + hfi_buffer_requirements))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); buf_req = (struct hfi_buffer_requirements *) @@ -234,8 +272,13 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, event_notify.capture_buf_count); data_ptr += sizeof(struct hfi_buffer_requirements); + rem_size -= + sizeof(struct hfi_buffer_requirements); break; case HFI_INDEX_EXTRADATA_INPUT_CROP: + if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + hfi_index_extradata_input_crop_payload))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); crop_info = (struct hfi_index_extradata_input_crop_payload *) @@ -256,6 +299,8 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, data_ptr += sizeof(struct hfi_index_extradata_input_crop_payload); + rem_size -= sizeof(struct + hfi_index_extradata_input_crop_payload); break; default: dprintk(VIDC_ERR, @@ -266,6 +311,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, num_properties_changed--; } while (num_properties_changed > 0); } +#undef VALIDATE_PKT_SIZE info->response_type = HAL_SESSION_EVENT_CHANGE; info->response.event = event_notify; From 86aaa6523453d9da2baa061257722bc910fa917a Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Mon, 1 Jul 2019 22:11:39 -0700 Subject: [PATCH 091/452] msm: vidc: add cvp session priority Set CVP session priority and colorformat. Change-Id: Ifba0734fa0d38ec47c2aa947bee815ae7c377589 Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_cvp_external.c | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index 9742350ca8d0..5991ed26e14e 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -56,6 +56,42 @@ static int msm_cvp_get_version_info(struct msm_vidc_inst *inst) return 0; } +static int msm_cvp_set_priority(struct msm_vidc_inst *inst) +{ + int rc; + struct msm_cvp_external *cvp; + struct cvp_kmd_arg *arg; + struct cvp_kmd_sys_properties *props; + struct cvp_kmd_sys_property *prop_array; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; + arg = cvp->arg; + props = (struct cvp_kmd_sys_properties *)&arg->data.sys_properties; + prop_array = (struct cvp_kmd_sys_property *) + &arg->data.sys_properties.prop_data; + + memset(arg, 0, sizeof(struct cvp_kmd_arg)); + arg->type = CVP_KMD_SET_SYS_PROPERTY; + props->prop_num = 1; + prop_array[0].prop_type = CVP_KMD_PROP_SESSION_PRIORITY; + if (is_realtime_session(inst)) + prop_array[0].data = VIDEO_REALTIME; + else + prop_array[0].data = VIDEO_NONREALTIME; + dprintk(VIDC_HIGH, "%s: %d\n", __func__, prop_array[0].data); + rc = msm_cvp_private(cvp->priv, CVP_KMD_SET_SYS_PROPERTY, arg); + if (rc) { + dprintk(VIDC_ERR, "%s: failed, rc %d\n", __func__, rc); + return rc; + } + + return 0; +} + static int msm_cvp_fill_planeinfo(struct msm_cvp_color_plane_info *plane_info, u32 color_fmt, u32 width, u32 height) { @@ -210,6 +246,7 @@ static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst) int rc = 0; struct msm_cvp_external *cvp; struct cvp_kmd_arg *arg; + struct v4l2_format *f; struct cvp_kmd_usecase_desc desc; struct cvp_kmd_request_power power; const u32 fps_max = CVP_FRAME_RATE_MAX; @@ -224,6 +261,7 @@ static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst) memset(&desc, 0, sizeof(struct cvp_kmd_usecase_desc)); memset(&power, 0, sizeof(struct cvp_kmd_request_power)); + f = &inst->fmts[INPUT_PORT].v4l2_fmt; fps = max(inst->clk_data.operating_rate, inst->clk_data.frame_rate) >> 16; @@ -234,6 +272,7 @@ static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst) desc.is_downscale = cvp->downscale; desc.fps = min(fps, fps_max); desc.op_rate = min(fps, fps_max); + desc.colorfmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat); rc = msm_cvp_est_cycles(&desc, &power); if (rc) { dprintk(VIDC_ERR, "%s: estimate failed\n", __func__); @@ -1014,6 +1053,10 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst) inst->clk_data.frame_rate >> 16, inst->clk_data.operating_rate >> 16); + rc = msm_cvp_set_priority(inst); + if (rc) + goto error; + rc = msm_cvp_set_clocks_and_bus(inst); if (rc) goto error; From 154af16cfc5e8f34326bc6323d4851539af184db Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Fri, 5 Jul 2019 16:33:36 -0700 Subject: [PATCH 092/452] msm: venc: enable encoder deblocking by default Enable encoder deblocking by default. Change-Id: I27af7bb60ed3baac061d481ba6181eb7c2e10a7c Signed-off-by: Darshana Patil --- msm/vidc/msm_venc.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 03ca6978b325..8395b9a03184 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -43,7 +43,8 @@ #define CBR_PLUS_BUF_SIZE 1000 #define MAX_GOP 0xFFFFFFF -#define L_MODE V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY +#define DB_DISABLE_SLICE_BOUNDARY \ + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY #define MIN_NUM_ENC_OUTPUT_BUFFERS 4 #define MIN_NUM_ENC_CAPTURE_BUFFERS 5 @@ -471,12 +472,12 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .name = "H.264 Loop Filter Mode", .type = V4L2_CTRL_TYPE_MENU, .minimum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED, - .maximum = L_MODE, - .default_value = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED, + .maximum = DB_DISABLE_SLICE_BOUNDARY, + .default_value = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED, .menu_skip_mask = ~( (1 << V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED) | (1 << V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED) | - (1 << L_MODE) + (1 << DB_DISABLE_SLICE_BOUNDARY) ), }, { @@ -3069,6 +3070,7 @@ int msm_venc_set_loop_filter_mode(struct msm_vidc_inst *inst) struct v4l2_ctrl *ctrl_a; struct v4l2_ctrl *ctrl_b; struct hfi_h264_db_control h264_db_control; + u32 codec; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); @@ -3076,7 +3078,8 @@ int msm_venc_set_loop_filter_mode(struct msm_vidc_inst *inst) } hdev = inst->core->device; - if (get_v4l2_codec(inst) != V4L2_PIX_FMT_H264) + codec = get_v4l2_codec(inst); + if (codec != V4L2_PIX_FMT_H264 && codec != V4L2_PIX_FMT_HEVC) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE); From 7db4d9a42454b5ac2ac05d7c28e2ce7f8aee654c Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Mon, 8 Jul 2019 13:23:17 -0700 Subject: [PATCH 093/452] msm: vidc: define common macro for DB disable slice boundary Defined a common macro for disable slice boundary deblocking mode. Change-Id: Ie163b1268a91f278e8ed6821c88ebff32e80d9cd Signed-off-by: Darshana Patil --- msm/vidc/msm_venc.c | 2 -- msm/vidc/msm_vidc_common.c | 3 +-- msm/vidc/msm_vidc_internal.h | 3 +++ 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 8395b9a03184..867656023a99 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -43,8 +43,6 @@ #define CBR_PLUS_BUF_SIZE 1000 #define MAX_GOP 0xFFFFFFF -#define DB_DISABLE_SLICE_BOUNDARY \ - V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY #define MIN_NUM_ENC_OUTPUT_BUFFERS 4 #define MIN_NUM_ENC_CAPTURE_BUFFERS 5 diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 6e54952878df..daf52123aad7 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -27,7 +27,6 @@ V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT #define V4L2_EVENT_RELEASE_BUFFER_REFERENCE \ V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE -#define L_MODE V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY static void handle_session_error(enum hal_command_response cmd, void *data); static void msm_vidc_print_running_insts(struct msm_vidc_core *core); @@ -516,7 +515,7 @@ int msm_comm_v4l2_to_hfi(int id, int value) return HFI_H264_DB_MODE_DISABLE; case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED: return HFI_H264_DB_MODE_ALL_BOUNDARY; - case L_MODE: + case DB_DISABLE_SLICE_BOUNDARY: return HFI_H264_DB_MODE_SKIP_SLICE_BOUNDARY; default: return HFI_H264_DB_MODE_ALL_BOUNDARY; diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 1258b4c999e6..5d8d165b82eb 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -69,6 +69,9 @@ #define MAX_NAME_LENGTH 64 +#define DB_DISABLE_SLICE_BOUNDARY \ + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY + #define NUM_MBS_PER_SEC(__height, __width, __fps) \ (NUM_MBS_PER_FRAME(__height, __width) * __fps) From 7b837fbb71a0865b8b7815b098b6faedc1a9d37d Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Thu, 11 Jul 2019 16:48:39 +0530 Subject: [PATCH 094/452] msm: vidc: Fix validate_pkt_size macro definition Convert validate_pkt_size macro to an inline function as this macro definition always returns true. Change-Id: I9e7eadfe82c041721565c880eca3a46e4e3e98d9 Signed-off-by: Priyanka Gujjula --- msm/vidc/hfi_response_handler.c | 39 +++++++++++++++++---------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index 115f544b53a4..5d755d118c02 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -90,6 +90,16 @@ static int get_hal_pixel_depth(u32 hfi_bit_depth) return MSM_VIDC_BIT_DEPTH_UNSUPPORTED; } +static inline int validate_pkt_size(u32 rem_size, u32 msg_size) +{ + if (rem_size < msg_size) { + dprintk(VIDC_ERR, "%s: bad_packet_size: %d\n", + __func__, rem_size); + return false; + } + return true; +} + static int hfi_process_sess_evt_seq_changed(u32 device_id, struct hfi_msg_event_notify_packet *pkt, struct msm_vidc_cb_info *info) @@ -108,15 +118,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, int luma_bit_depth, chroma_bit_depth; struct hfi_colour_space *colour_info; -#define VALIDATE_PKT_SIZE(__rem_size, __msg_size) ({ \ - if (__rem_size < __msg_size) { \ - dprintk(VIDC_ERR, \ - "hal_process_session_init_done: bad_pkt_size\n"); \ - false; \ - } \ - true; \ - }) - if (!VALIDATE_PKT_SIZE(pkt->size, + if (!validate_pkt_size(pkt->size, sizeof(struct hfi_msg_event_notify_packet))) return -E2BIG; @@ -142,13 +144,13 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, rem_size = pkt->size - sizeof(struct hfi_msg_event_notify_packet) + sizeof(u32); do { - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(u32))) + if (!validate_pkt_size(rem_size, sizeof(u32))) return -E2BIG; prop_id = (int) *((u32 *)data_ptr); rem_size -= sizeof(u32); switch (prop_id) { case HFI_PROPERTY_PARAM_FRAME_SIZE: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + if (!validate_pkt_size(rem_size, sizeof(struct hfi_frame_size))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); @@ -163,7 +165,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, rem_size -= sizeof(struct hfi_frame_size); break; case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + if (!validate_pkt_size(rem_size, sizeof(struct hfi_profile_level))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); @@ -179,7 +181,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, rem_size -= sizeof(struct hfi_profile_level); break; case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + if (!validate_pkt_size(rem_size, sizeof(struct hfi_bit_depth))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); @@ -215,7 +217,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, rem_size -= sizeof(struct hfi_bit_depth); break; case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + if (!validate_pkt_size(rem_size, sizeof(struct hfi_pic_struct))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); @@ -230,7 +232,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, rem_size -= sizeof(struct hfi_pic_struct); break; case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + if (!validate_pkt_size(rem_size, sizeof(struct hfi_colour_space))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); @@ -246,7 +248,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, rem_size -= sizeof(struct hfi_colour_space); break; case HFI_PROPERTY_CONFIG_VDEC_ENTROPY: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(u32))) + if (!validate_pkt_size(rem_size, sizeof(u32))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); entropy_mode = *(u32 *)data_ptr; @@ -258,7 +260,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, rem_size -= sizeof(u32); break; case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + if (!validate_pkt_size(rem_size, sizeof(struct hfi_buffer_requirements))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); @@ -276,7 +278,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, sizeof(struct hfi_buffer_requirements); break; case HFI_INDEX_EXTRADATA_INPUT_CROP: - if (!VALIDATE_PKT_SIZE(rem_size, sizeof(struct + if (!validate_pkt_size(rem_size, sizeof(struct hfi_index_extradata_input_crop_payload))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); @@ -311,7 +313,6 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, num_properties_changed--; } while (num_properties_changed > 0); } -#undef VALIDATE_PKT_SIZE info->response_type = HAL_SESSION_EVENT_CHANGE; info->response.event = event_notify; From b77f91e4fbdb84500f1123200b733d99a7f95643 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Mon, 8 Jul 2019 13:33:47 +0530 Subject: [PATCH 095/452] msm: vidc: Fix scaling capability for encoders Scaling capability are defined in Q16 format. Existing capability indicates that the capability is 16 times i.e output dimension can be scaled to 1/16th of input dimension. As per specification, the achievable ratio is 8. Change-Id: Ib9e005a055e604d3173dd8cd376d3b6666f2c12c Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_platform.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index c98973d52173..eaf20bb9fe4a 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -167,8 +167,8 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 3110400, 1, 2073600}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 480, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 200000000, 1, 20000000}, - {CAP_SCALE_X, ENC, CODECS_ALL, 4096, 65536, 1, 4096}, - {CAP_SCALE_Y, ENC, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_SCALE_X, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, + {CAP_SCALE_Y, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, {CAP_SCALE_X, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, {CAP_SCALE_Y, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, @@ -232,8 +232,8 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 1281600, 1, 2073600}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 240, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 100000000, 1, 20000000}, - {CAP_SCALE_X, ENC, CODECS_ALL, 4096, 65536, 1, 4096}, - {CAP_SCALE_Y, ENC, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_SCALE_X, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, + {CAP_SCALE_Y, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, {CAP_SCALE_X, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, {CAP_SCALE_Y, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, @@ -297,8 +297,8 @@ static struct msm_vidc_codec_capability kona_capabilities[] = { {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 64, 7833600, 1, 7833600}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 960, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 220000000, 1, 20000000}, - {CAP_SCALE_X, ENC, CODECS_ALL, 4096, 65536, 1, 4096}, - {CAP_SCALE_Y, ENC, CODECS_ALL, 4096, 65536, 1, 4096}, + {CAP_SCALE_X, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, + {CAP_SCALE_Y, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, {CAP_SCALE_X, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, {CAP_SCALE_Y, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, From 10eb14941d00201d8c88b85e5148550b604a14f8 Mon Sep 17 00:00:00 2001 From: Amit Shekhar Date: Thu, 11 Jul 2019 12:18:35 -0700 Subject: [PATCH 096/452] msm: vidc: Fix work mode for rate control CQ Set single stage work mode for HEIC sessions. Currently, with two stages, encoded tiles are missing at random. Change-Id: Iadb59102447e1873e99ae1fd03a1d7b6ce3cba1a Signed-off-by: Amit Shekhar --- msm/vidc/msm_vidc_clocks.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 76ab755bacb8..cab3cbd62487 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1514,6 +1514,10 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) /* For WORK_MODE_1, set Low Latency mode by default */ latency.enable = true; } + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) { + pdata.video_work_mode = HFI_WORKMODE_1; + latency.enable = true; + } if (inst->rc_type == RATE_CONTROL_LOSSLESS) { pdata.video_work_mode = HFI_WORKMODE_2; latency.enable = false; From 99aa37e4ae3d3c978aa05cc394243b01b0c1f0c0 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Thu, 11 Jul 2019 17:03:15 -0700 Subject: [PATCH 097/452] msm: vidc: fix downscale resolution calculation Compare unmodified width and height instead of modified values to resolve downscale resolution calculation issue. Change-Id: I06e753e416c356ca0e97a6ad53dc12fe04c5cfa3 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_cvp_external.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index fe470d7d7951..c3811f89cbf0 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -253,7 +253,7 @@ static int msm_cvp_init_downscale_resolution(struct msm_vidc_inst *inst) ds_height = height; /* Step 4) switch width and height if already switched */ - if (height > width) { + if (cvp->height > cvp->width) { temp = ds_height; ds_height = ds_width; ds_width = temp; From c97d00e59f625a8009e6a53c04908c9a52fe38ee Mon Sep 17 00:00:00 2001 From: Amit Shekhar Date: Fri, 12 Jul 2019 15:31:23 -0700 Subject: [PATCH 098/452] msm: vidc: Fix criteria for hybrid hierp enablement If client doesn't request hybrid hierp or sets zero as max enhancement layer count, then, hybrid hierp is not enabled. Change-Id: I4284fd5c25d4dc812dac3e134ab5dfc53833bfbf Signed-off-by: Amit Shekhar --- msm/vidc/msm_venc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 867656023a99..f3f4801a95b6 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3189,7 +3189,7 @@ int msm_venc_enable_hybrid_hp(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); layer = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); - if (ctrl->val != layer->val) + if (ctrl->val == 0 || ctrl->val != layer->val) return 0; /* From 3be0ff39108aefd14be2711b4d4dbc6bab0f1da4 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 3 Jul 2019 18:29:44 +0530 Subject: [PATCH 099/452] msm: vidc: Ensure size of the data available before typecasting Ensure the available data size with in the packet before type casting from a smaller data type to larger data type in order to avoid information leak or packet out of boundary access. Change-Id: I8614a8b3f930c87af8aa49f77ea9d768a73ea203 Signed-off-by: Priyanka Gujjula --- msm/vidc/hfi_response_handler.c | 30 +++++++++++++++++++++--------- msm/vidc/vidc_hfi.h | 2 +- msm/vidc/vidc_hfi_helper.h | 1 - 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index 5d755d118c02..5c376a4cfa69 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -334,6 +334,12 @@ static int hfi_process_evt_release_buffer_ref(u32 device_id, dprintk(VIDC_ERR, "%s: bad_pkt_size\n", __func__); return -E2BIG; } + if (pkt->size < sizeof(struct hfi_msg_event_notify_packet) - sizeof(u32) + + sizeof(struct hfi_msg_release_buffer_ref_event_packet)) { + dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", + __func__, pkt->size); + return -E2BIG; + } data = (struct hfi_msg_release_buffer_ref_event_packet *) pkt->rg_ext_event_data; @@ -762,15 +768,13 @@ static int hfi_process_session_etb_done(u32 device_id, struct hfi_msg_session_empty_buffer_done_packet *pkt = _pkt; struct msm_vidc_cb_data_done data_done = {0}; struct hfi_picture_type *hfi_picture_type = NULL; + u32 is_sync_frame; dprintk(VIDC_LOW, "RECEIVED: SESSION_ETB_DONE[%#x]\n", pkt->session_id); if (!pkt || pkt->size < - sizeof(struct hfi_msg_session_empty_buffer_done_packet)) { - dprintk(VIDC_ERR, - "hal_process_session_etb_done: bad_pkt_size\n"); - return -E2BIG; - } + sizeof(struct hfi_msg_session_empty_buffer_done_packet)) + goto bad_packet_size; data_done.device_id = device_id; data_done.session_id = (void *)(uintptr_t)pkt->session_id; @@ -790,8 +794,13 @@ static int hfi_process_session_etb_done(u32 device_id, data_done.input_done.extra_data_buffer = pkt->extra_data_buffer; data_done.input_done.status = hfi_map_err_status(pkt->error_type); - hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[0]; - if (hfi_picture_type->is_sync_frame) { + is_sync_frame = pkt->rgData[0]; + if (is_sync_frame) { + if (pkt->size < + sizeof(struct hfi_msg_session_empty_buffer_done_packet) + + sizeof(struct hfi_picture_type)) + goto bad_packet_size; + hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[1]; if (hfi_picture_type->picture_type) data_done.input_done.flags = hfi_picture_type->picture_type; @@ -808,6 +817,10 @@ static int hfi_process_session_etb_done(u32 device_id, info->response.data = data_done; return 0; +bad_packet_size: + dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", + __func__, pkt ? pkt->size : 0); + return -E2BIG; } static int hfi_process_session_ftb_done( @@ -1038,8 +1051,7 @@ static int hfi_process_session_rel_buf_done(u32 device_id, cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done); cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.status = hfi_map_err_status(pkt->error_type); - cmd_done.data.buffer_info = - *(struct hal_buffer_info *)pkt->rg_buffer_info; + cmd_done.data.buffer_info.buffer_addr = *pkt->rg_buffer_info; cmd_done.size = sizeof(struct hal_buffer_info); info->response_type = HAL_SESSION_RELEASE_BUFFER_DONE; diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index 8ae61b3dd638..bd26af04cf1a 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -589,7 +589,7 @@ struct hfi_msg_session_empty_buffer_done_packet { u32 extra_data_buffer; u32 flags; struct hfi_frame_cr_stats_type ubwc_cr_stats; - u32 rgData[0]; + u32 rgData[1]; }; struct hfi_msg_session_fill_buffer_done_compressed_packet { diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index ba01cd7e2156..859ab24a9c7e 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -659,7 +659,6 @@ struct hfi_bit_depth { }; struct hfi_picture_type { - u32 is_sync_frame; u32 picture_type; }; From fcc05b6aacd54cd9f17826032b9dfa63af9cf034 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Fri, 10 May 2019 12:27:11 -0700 Subject: [PATCH 100/452] msm: vidc: Remove mese bw vote for video encoder MESE BW vote is not applicable for Kona. We can reduce overall BW requirement by removing this vote. CRs-Fixed: 2487664 Change-Id: I7cd6e3937e8884a2e4790a49713bd33aaab9c4bf Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc_bus_iris2.c | 136 ++++++++++++---------------------- msm/vidc/msm_vidc_internal.h | 11 +++ 2 files changed, 58 insertions(+), 89 deletions(-) diff --git a/msm/vidc/msm_vidc_bus_iris2.c b/msm/vidc/msm_vidc_bus_iris2.c index 1a9f92529438..4b5c4bdbfdc2 100644 --- a/msm/vidc/msm_vidc_bus_iris2.c +++ b/msm/vidc/msm_vidc_bus_iris2.c @@ -83,7 +83,7 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, lcu_size = d->lcu_size; - dpb_bpp = d->num_formats >= 1 ? __bpp(d->color_formats[0]) : INT_MAX; + dpb_bpp = __bpp(d->color_formats[0]); unified_dpb_opb = d->num_formats == 1; @@ -93,25 +93,12 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, opb_compression_enabled = d->num_formats >= 2 && __ubwc(d->color_formats[1]); - /* - * convert q16 number into integer and fractional part upto 2 places. - * ex : 105752 / 65536 = 1.61; 1.61 in q16 = 105752; - * integer part = 105752 / 65536 = 1; - * reminder = 105752 - 1 * 65536 = 40216; - * fractional part = 40216 * 100 / 65536 = 61; - * now converto to fp(1, 61, 100) for below code. - */ - - integer_part = d->compression_ratio >> 16; - frac_part = - ((d->compression_ratio - (integer_part << 16)) * 100) >> 16; - + integer_part = Q16_INT(d->compression_ratio); + frac_part = Q16_FRAC(d->compression_ratio); dpb_read_compression_factor = FP(integer_part, frac_part, 100); - integer_part = d->complexity_factor >> 16; - frac_part = - ((d->complexity_factor - (integer_part << 16)) * 100) >> 16; - + integer_part = Q16_INT(d->complexity_factor); + frac_part = Q16_FRAC(d->complexity_factor); motion_vector_complexity = FP(integer_part, frac_part, 100); dpb_write_compression_factor = dpb_read_compression_factor; @@ -134,7 +121,7 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, lcu_per_frame = DIV_ROUND_UP(width, lcu_size) * DIV_ROUND_UP(height, lcu_size); - bitrate = (d->bitrate + 1000000 - 1) / 1000000; + bitrate = DIV_ROUND_UP(d->bitrate, 1000000); bins_to_bit_factor = FP_INT(4); @@ -160,12 +147,15 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, collocated_bytes_per_lcu * fps), FP_INT(bps(1))); ddr.collocated_write = ddr.collocated_read; - y_bw_no_ubwc_8bpp = fp_div(fp_mult( - FP_INT((int)(width * height)), FP_INT((int)fps)), + y_bw_no_ubwc_8bpp = fp_div(FP_INT(width * height * fps), FP_INT(1000 * 1000)); - y_bw_no_ubwc_10bpp = fp_div(fp_mult(y_bw_no_ubwc_8bpp, FP_INT(256)), + + if (dpb_bpp != 8) { + y_bw_no_ubwc_10bpp = + fp_div(fp_mult(y_bw_no_ubwc_8bpp, FP_INT(256)), FP_INT(192)); - y_bw_10bpp_p010 = y_bw_no_ubwc_8bpp * 2; + y_bw_10bpp_p010 = y_bw_no_ubwc_8bpp * 2; + } ddr.dpb_read = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; ddr.dpb_read = fp_div(fp_mult(ddr.dpb_read, @@ -194,8 +184,9 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, ddr.opb_write = fp_div(fp_mult(dpb_factor, ddr.opb_write), fp_mult(dpb_opb_scaling_ratio, opb_write_compression_factor)); - ddr.line_buffer_read = FP_INT(tnbr_per_lcu * - lcu_per_frame * fps / bps(1)); + ddr.line_buffer_read = + fp_div(FP_INT(tnbr_per_lcu * lcu_per_frame * fps), + FP_INT(bps(1))); ddr.line_buffer_write = ddr.line_buffer_read; if (llc_top_line_buf_enabled) { llc.line_buffer_read = ddr.line_buffer_read; @@ -309,14 +300,15 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, llc_top_line_buf_enabled = false, llc_vpss_rot_line_buf_enabled = false; - fp_t bins_to_bit_factor, dpb_compression_factor, + unsigned int bins_to_bit_factor; + fp_t dpb_compression_factor, original_compression_factor, original_compression_factor_y, y_bw_no_ubwc_8bpp, y_bw_no_ubwc_10bpp, y_bw_10bpp_p010, input_compression_factor, downscaling_ratio, ref_y_read_bw_factor, ref_cbcr_read_bw_factor, - recon_write_bw_factor, mese_read_factor, + recon_write_bw_factor, total_ref_read_crcb, qsmmu_bw_overhead_factor; fp_t integer_part, frac_part; @@ -328,7 +320,6 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, ref_read_y, ref_read_crcb, ref_write, ref_write_overlap, orig_read, line_buffer_read, line_buffer_write, - mese_read, mese_write, total; } ddr = {0}; @@ -352,31 +343,33 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, downscaling_ratio = fp_div(FP_INT(d->input_width * d->input_height), FP_INT(d->output_width * d->output_height)); downscaling_ratio = max(downscaling_ratio, FP_ONE); - bitrate = d->bitrate > 0 ? d->bitrate / 1000000 : + bitrate = d->bitrate > 0 ? DIV_ROUND_UP(d->bitrate, 1000000) : __lut(width, height, fps)->bitrate; lcu_size = d->lcu_size; lcu_per_frame = DIV_ROUND_UP(width, lcu_size) * DIV_ROUND_UP(height, lcu_size); tnbr_per_lcu = 16; - y_bw_no_ubwc_8bpp = fp_div(fp_mult( - FP_INT((int)(width * height)), FP_INT(fps)), + dpb_bpp = __bpp(d->color_formats[0]); + + y_bw_no_ubwc_8bpp = fp_div(FP_INT(width * height * fps), FP_INT(1000 * 1000)); - y_bw_no_ubwc_10bpp = fp_div(fp_mult(y_bw_no_ubwc_8bpp, - FP_INT(256)), FP_INT(192)); - y_bw_10bpp_p010 = y_bw_no_ubwc_8bpp * 2; + + if (dpb_bpp != 8) { + y_bw_no_ubwc_10bpp = fp_div(fp_mult(y_bw_no_ubwc_8bpp, + FP_INT(256)), FP_INT(192)); + y_bw_10bpp_p010 = y_bw_no_ubwc_8bpp * 2; + } b_frames_enabled = d->b_frames_enabled; original_color_format = d->num_formats >= 1 ? d->color_formats[0] : HAL_UNUSED_COLOR; - dpb_bpp = d->num_formats >= 1 ? __bpp(d->color_formats[0]) : INT_MAX; - original_compression_enabled = __ubwc(original_color_format); work_mode_1 = d->work_mode == HFI_WORKMODE_1; low_power = d->power_mode == VIDC_POWER_LOW; - bins_to_bit_factor = FP_INT(4); + bins_to_bit_factor = 4; if (d->use_sys_cache) { llc_ref_chroma_cache_enabled = true; @@ -384,25 +377,12 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, llc_vpss_rot_line_buf_enabled = true; } - /* - * Convert Q16 number into Integer and Fractional part upto 2 places. - * Ex : 105752 / 65536 = 1.61; 1.61 in Q16 = 105752; - * Integer part = 105752 / 65536 = 1; - * Reminder = 105752 - 1 * 65536 = 40216; - * Fractional part = 40216 * 100 / 65536 = 61; - * Now converto to FP(1, 61, 100) for below code. - */ - - integer_part = d->compression_ratio >> 16; - frac_part = - ((d->compression_ratio - (integer_part * 65536)) * 100) >> 16; - + integer_part = Q16_INT(d->compression_ratio); + frac_part = Q16_FRAC(d->compression_ratio); dpb_compression_factor = FP(integer_part, frac_part, 100); - integer_part = d->input_cr >> 16; - frac_part = - ((d->input_cr - (integer_part * 65536)) * 100) >> 16; - + integer_part = Q16_INT(d->input_cr); + frac_part = Q16_FRAC(d->input_cr); input_compression_factor = FP(integer_part, frac_part, 100); original_compression_factor = original_compression_factor_y = @@ -421,13 +401,7 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, input_compression_factor; } - mese_read_factor = fp_div(FP_INT((width * height * fps)/4), - original_compression_factor_y); - mese_read_factor = fp_div(fp_mult(mese_read_factor, FP(2, 53, 100)), - FP_INT(1000 * 1000)); - - ddr.vsp_read = fp_div(fp_mult(FP_INT(bitrate), bins_to_bit_factor), - FP_INT(8)); + ddr.vsp_read = fp_div(FP_INT(bitrate * bins_to_bit_factor), FP_INT(8)); ddr.vsp_write = ddr.vsp_read + fp_div(FP_INT(bitrate), FP_INT(8)); collocated_bytes_per_lcu = lcu_size == 16 ? 16 : @@ -438,22 +412,21 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, ddr.collocated_write = ddr.collocated_read; - ddr.ref_read_y = ddr.ref_read_crcb = dpb_bpp == 8 ? + ddr.ref_read_y = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; + if (b_frames_enabled) + ddr.ref_read_y = ddr.ref_read_y * 2; + ddr.ref_read_y = fp_div(ddr.ref_read_y, dpb_compression_factor); + + ddr.ref_read_crcb = ddr.ref_read_y; + if (width != vertical_tile_width) { ddr.ref_read_y = fp_mult(ddr.ref_read_y, ref_y_read_bw_factor); } - ddr.ref_read_y = fp_div(ddr.ref_read_y, dpb_compression_factor); - if (b_frames_enabled) - ddr.ref_read_y = fp_mult(ddr.ref_read_y, FP_INT(2)); - ddr.ref_read_crcb = fp_mult(ddr.ref_read_crcb, FP(0, 50, 100)); - ddr.ref_read_crcb = fp_div(ddr.ref_read_crcb, dpb_compression_factor); - if (b_frames_enabled) - ddr.ref_read_crcb = fp_mult(ddr.ref_read_crcb, FP_INT(2)); if (llc_ref_chroma_cache_enabled) { total_ref_read_crcb = ddr.ref_read_crcb; @@ -478,8 +451,9 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, if (rotation == 90 || rotation == 270) ddr.orig_read *= lcu_size == 32 ? (dpb_bpp == 8 ? 1 : 3) : 2; - ddr.line_buffer_read = FP_INT(tnbr_per_lcu * lcu_per_frame * - fps / bps(1)); + ddr.line_buffer_read = + fp_div(FP_INT(tnbr_per_lcu * lcu_per_frame * fps), + FP_INT(bps(1))); ddr.line_buffer_write = ddr.line_buffer_read; if (llc_top_line_buf_enabled) { @@ -487,24 +461,12 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, ddr.line_buffer_read = ddr.line_buffer_write = FP_ZERO; } - ddr.mese_read = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; - ddr.mese_read = fp_div(fp_mult(ddr.mese_read, FP(1, 37, 100)), - original_compression_factor_y) + mese_read_factor; - - ddr.mese_write = FP_INT((width * height)/512) + - fp_div(FP_INT((width * height)/4), - original_compression_factor_y) + - FP_INT((width * height)/128); - ddr.mese_write = fp_div(fp_mult(ddr.mese_write, FP_INT(fps)), - FP_INT(1000 * 1000)); - ddr.total = ddr.vsp_read + ddr.vsp_write + ddr.collocated_read + ddr.collocated_write + ddr.ref_read_y + ddr.ref_read_crcb + ddr.ref_write + ddr.ref_write_overlap + ddr.orig_read + - ddr.line_buffer_read + ddr.line_buffer_write + - ddr.mese_read + ddr.mese_write; + ddr.line_buffer_read + ddr.line_buffer_write; qsmmu_bw_overhead_factor = FP(1, 3, 100); ddr.total = fp_mult(ddr.total, qsmmu_bw_overhead_factor); @@ -540,13 +502,11 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, {"DERIVED PARAMETERS", "", DUMP_HEADER_MAGIC}, {"lcu size", "%d", lcu_size}, {"bitrate (Mbit/sec)", "%lu", bitrate}, - {"bins to bit factor", DUMP_FP_FMT, bins_to_bit_factor}, + {"bins to bit factor", "%u", bins_to_bit_factor}, {"original compression factor", DUMP_FP_FMT, original_compression_factor}, {"original compression factor y", DUMP_FP_FMT, original_compression_factor_y}, - {"mese read factor", DUMP_FP_FMT, - mese_read_factor}, {"qsmmu_bw_overhead_factor", DUMP_FP_FMT, qsmmu_bw_overhead_factor}, {"bw for NV12 8bpc)", DUMP_FP_FMT, y_bw_no_ubwc_8bpp}, @@ -564,8 +524,6 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, {"original read", DUMP_FP_FMT, ddr.orig_read}, {"line buffer read", DUMP_FP_FMT, ddr.line_buffer_read}, {"line buffer write", DUMP_FP_FMT, ddr.line_buffer_write}, - {"mese read", DUMP_FP_FMT, ddr.mese_read}, - {"mese write", DUMP_FP_FMT, ddr.mese_write}, {"INTERMEDIATE LLC B/W", "", DUMP_HEADER_MAGIC}, {"llc ref read crcb", DUMP_FP_FMT, llc.ref_read_crcb}, {"llc line buffer", DUMP_FP_FMT, llc.line_buffer}, diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 5d8d165b82eb..795e52a96838 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -82,6 +82,17 @@ (((c) && (c)->core_ops && (c)->core_ops->op) ? \ ((c)->core_ops->op(__VA_ARGS__)) : 0) +/* + * Convert Q16 number into Integer and Fractional part upto 2 places. + * Ex : 105752 / 65536 = 1.61; 1.61 in Q16 = 105752; + * Integer part = 105752 / 65536 = 1; + * Reminder = 105752 * 0xFFFF = 40216; Last 16 bits. + * Fractional part = 40216 * 100 / 65536 = 61; + * Now convert to FP(1, 61, 100). + */ +#define Q16_INT(q) ((q) >> 16) +#define Q16_FRAC(q) ((((q) & 0xFFFF) * 100) >> 16) + struct msm_vidc_inst; enum vidc_ports { From c5b079d20136a1688165ec98eb55b45905df387e Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Fri, 5 Jul 2019 15:26:09 -0700 Subject: [PATCH 101/452] msm: vidc: Optimize bw calculations Calculate DDR and LLCC bw simulteneously to avoid redundant calculations. This reduces number of calculations required by 50% and hence reduces cpu load. CRs-Fixed: 2487664 Change-Id: I6e1768cd63d9b6651fbaf4a8ed8d5706929d7743 Signed-off-by: Chinmay Sawarkar --- msm/vidc/hfi_common.c | 26 ++++++----- msm/vidc/msm_vidc_bus.h | 13 +++--- msm/vidc/msm_vidc_bus_iris1.c | 84 ++++++++++++----------------------- msm/vidc/msm_vidc_bus_iris2.c | 84 ++++++++++++----------------------- 4 files changed, 79 insertions(+), 128 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index cf8e3a7836af..cc78065accfa 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -977,14 +977,14 @@ static void __set_registers(struct venus_hfi_device *device) } } -static int __vote_bandwidth(struct bus_info *bus, unsigned long freq) +static int __vote_bandwidth(struct bus_info *bus, unsigned long bw_kbps) { int rc = 0; uint64_t ab = 0; /* Bus Driver expects values in Bps */ - ab = freq * 1000; - dprintk(VIDC_PERF, "Voting bus %s to ab %llu\n", bus->name, ab); + ab = bw_kbps * 1000; + dprintk(VIDC_PERF, "Voting bus %s to ab %llu bps\n", bus->name, ab); rc = msm_bus_scale_update_bw(bus->client, ab, 0); if (rc) dprintk(VIDC_ERR, "Failed voting bus %s to ab %llu, rc=%d\n", @@ -1018,7 +1018,8 @@ static int __vote_buses(struct venus_hfi_device *device, int rc = 0; struct bus_info *bus = NULL; struct vidc_bus_vote_data *new_data = NULL; - unsigned long freq = 0; + unsigned long bw_kbps = 0; + enum vidc_bus_type type; if (!num_data) { dprintk(VIDC_LOW, "No vote data available\n"); @@ -1040,19 +1041,24 @@ static int __vote_buses(struct venus_hfi_device *device, device->bus_vote.data = new_data; device->bus_vote.data_count = num_data; + device->bus_vote.calc_bw(&device->bus_vote); + venus_hfi_for_each_bus(device, bus) { if (bus && bus->client) { - if (!bus->is_prfm_mode) - freq = device->bus_vote.calc_bw - (bus, &device->bus_vote); + type = get_type_frm_name(bus->name); + + if (type == DDR) + bw_kbps = device->bus_vote.total_bw_ddr; + else if (type == LLCC) + bw_kbps = device->bus_vote.total_bw_llcc; else - freq = bus->range[1]; + bw_kbps = bus->range[1]; /* ensure freq is within limits */ - freq = clamp_t(typeof(freq), freq, + bw_kbps = clamp_t(typeof(bw_kbps), bw_kbps, bus->range[0], bus->range[1]); - rc = __vote_bandwidth(bus, freq); + rc = __vote_bandwidth(bus, bw_kbps); } else { dprintk(VIDC_ERR, "No BUS to Vote\n"); } diff --git a/msm/vidc/msm_vidc_bus.h b/msm/vidc/msm_vidc_bus.h index 919ee1cd3587..bc2c5f17fab4 100644 --- a/msm/vidc/msm_vidc_bus.h +++ b/msm/vidc/msm_vidc_bus.h @@ -232,20 +232,21 @@ struct vidc_bus_vote_data { u32 work_mode; bool use_sys_cache; bool b_frames_enabled; + unsigned long calc_bw_ddr; + unsigned long calc_bw_llcc; }; struct msm_vidc_bus_data { struct vidc_bus_vote_data *data; u32 data_count; - unsigned long (*calc_bw)(struct bus_info *bus, - struct msm_vidc_bus_data *data); + unsigned long total_bw_ddr; + unsigned long total_bw_llcc; + int (*calc_bw)(struct msm_vidc_bus_data *data); }; -unsigned long calc_bw_iris1(struct bus_info *bus, - struct msm_vidc_bus_data *vidc_data); +int calc_bw_iris1(struct msm_vidc_bus_data *vidc_data); -unsigned long calc_bw_iris2(struct bus_info *bus, - struct msm_vidc_bus_data *vidc_data); +int calc_bw_iris2(struct msm_vidc_bus_data *vidc_data); struct lut const *__lut(int width, int height, int fps); fp_t __compression_ratio(struct lut const *entry, int bpp); diff --git a/msm/vidc/msm_vidc_bus_iris1.c b/msm/vidc/msm_vidc_bus_iris1.c index 5e30046bcf50..da35f8f02893 100644 --- a/msm/vidc/msm_vidc_bus_iris1.c +++ b/msm/vidc/msm_vidc_bus_iris1.c @@ -68,34 +68,22 @@ void __dump(struct dump dump[], int len) } } -static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d, - enum vidc_bus_type type) +static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d) { return 0; } -static unsigned long __calculate_cvp(struct vidc_bus_vote_data *d, - enum vidc_bus_type type) +static unsigned long __calculate_cvp(struct vidc_bus_vote_data *d) { unsigned long ret = 0; - switch (type) { - case DDR: - ret = d->ddr_bw; - break; - case LLCC: - ret = d->sys_cache_bw; - break; - default: - dprintk(VIDC_ERR, "%s - Unknown type\n", __func__); - break; - } + d->calc_bw_ddr = d->ddr_bw; + d->calc_bw_llcc = d->sys_cache_bw; return ret; } -static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, - enum vidc_bus_type type) +static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) { /* * XXX: Don't fool around with any of the hardcoded numbers unless you @@ -335,22 +323,13 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, __dump(dump, ARRAY_SIZE(dump)); } - switch (type) { - case DDR: - ret = kbps(fp_round(ddr.total)); - break; - case LLCC: - ret = kbps(fp_round(llc.total)); - break; - default: - dprintk(VIDC_ERR, "%s - Unknown type\n", __func__); - } + d->calc_bw_ddr = kbps(fp_round(ddr.total)); + d->calc_bw_llcc = kbps(fp_round(llc.total)); return ret; } -static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, - enum vidc_bus_type type) +static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) { /* * XXX: Don't fool around with any of the hardcoded numbers unless you @@ -632,37 +611,28 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, __dump(dump, ARRAY_SIZE(dump)); } - switch (type) { - case DDR: - ret = kbps(fp_round(ddr.total)); - break; - case LLCC: - ret = kbps(fp_round(llc.total)); - break; - default: - dprintk(VIDC_ERR, "%s - Unknown type\n", __func__); - } + d->calc_bw_ddr = kbps(fp_round(ddr.total)); + d->calc_bw_llcc = kbps(fp_round(llc.total)); return ret; } -static unsigned long __calculate(struct vidc_bus_vote_data *d, - enum vidc_bus_type type) +static unsigned long __calculate(struct vidc_bus_vote_data *d) { unsigned long value = 0; switch (d->domain) { case HAL_VIDEO_DOMAIN_VPE: - value = __calculate_vpe(d, type); + value = __calculate_vpe(d); break; case HAL_VIDEO_DOMAIN_ENCODER: - value = __calculate_encoder(d, type); + value = __calculate_encoder(d); break; case HAL_VIDEO_DOMAIN_DECODER: - value = __calculate_decoder(d, type); + value = __calculate_decoder(d); break; case HAL_VIDEO_DOMAIN_CVP: - value = __calculate_cvp(d, type); + value = __calculate_cvp(d); break; default: dprintk(VIDC_ERR, "Unknown Domain"); @@ -671,29 +641,31 @@ static unsigned long __calculate(struct vidc_bus_vote_data *d, return value; } -unsigned long calc_bw_iris1(struct bus_info *bus, - struct msm_vidc_bus_data *vidc_data) +int calc_bw_iris1(struct msm_vidc_bus_data *vidc_data) { - unsigned long ab_kbps = 0, c = 0; - enum vidc_bus_type type; + int ret = 0, c = 0; if (!vidc_data || !vidc_data->data_count || !vidc_data->data) goto exit; + vidc_data->total_bw_ddr = 0; + vidc_data->total_bw_llcc = 0; + for (c = 0; c < vidc_data->data_count; ++c) { if (vidc_data->data->power_mode == VIDC_POWER_TURBO) { - ab_kbps = INT_MAX; + vidc_data->total_bw_ddr = INT_MAX; + vidc_data->total_bw_llcc = INT_MAX; goto exit; } } - type = get_type_frm_name(bus->name); - - for (c = 0; c < vidc_data->data_count; ++c) - ab_kbps += __calculate(&vidc_data->data[c], type); + for (c = 0; c < vidc_data->data_count; ++c) { + __calculate(&vidc_data->data[c]); + vidc_data->total_bw_ddr += vidc_data->data[c].calc_bw_ddr; + vidc_data->total_bw_llcc += vidc_data->data[c].calc_bw_llcc; + } exit: - trace_msm_vidc_perf_bus_vote(bus->name, ab_kbps); - return ab_kbps; + return ret; } diff --git a/msm/vidc/msm_vidc_bus_iris2.c b/msm/vidc/msm_vidc_bus_iris2.c index 1a9f92529438..270517d92ea3 100644 --- a/msm/vidc/msm_vidc_bus_iris2.c +++ b/msm/vidc/msm_vidc_bus_iris2.c @@ -6,34 +6,22 @@ #include "msm_vidc_bus.h" #include "msm_vidc_internal.h" -static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d, - enum vidc_bus_type type) +static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d) { return 0; } -static unsigned long __calculate_cvp(struct vidc_bus_vote_data *d, - enum vidc_bus_type type) +static unsigned long __calculate_cvp(struct vidc_bus_vote_data *d) { unsigned long ret = 0; - switch (type) { - case DDR: - ret = d->ddr_bw; - break; - case LLCC: - ret = d->sys_cache_bw; - break; - default: - dprintk(VIDC_ERR, "%s - Unknown type\n", __func__); - break; - } + d->calc_bw_ddr = d->ddr_bw; + d->calc_bw_llcc = d->sys_cache_bw; return ret; } -static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, - enum vidc_bus_type type) +static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) { /* * XXX: Don't fool around with any of the hardcoded numbers unless you @@ -276,22 +264,13 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, __dump(dump, ARRAY_SIZE(dump)); } - switch (type) { - case DDR: - ret = kbps(fp_round(ddr.total)); - break; - case LLCC: - ret = kbps(fp_round(llc.total)); - break; - default: - dprintk(VIDC_ERR, "%s - Unknown type\n", __func__); - } + d->calc_bw_ddr = kbps(fp_round(ddr.total)); + d->calc_bw_llcc = kbps(fp_round(llc.total)); return ret; } -static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, - enum vidc_bus_type type) +static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) { /* * XXX: Don't fool around with any of the hardcoded numbers unless you @@ -573,37 +552,28 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, __dump(dump, ARRAY_SIZE(dump)); } - switch (type) { - case DDR: - ret = kbps(fp_round(ddr.total)); - break; - case LLCC: - ret = kbps(fp_round(llc.total)); - break; - default: - dprintk(VIDC_ERR, "%s - Unknown governor\n", __func__); - } + d->calc_bw_ddr = kbps(fp_round(ddr.total)); + d->calc_bw_llcc = kbps(fp_round(llc.total)); return ret; } -static unsigned long __calculate(struct vidc_bus_vote_data *d, - enum vidc_bus_type type) +static unsigned long __calculate(struct vidc_bus_vote_data *d) { unsigned long value = 0; switch (d->domain) { case HAL_VIDEO_DOMAIN_VPE: - value = __calculate_vpe(d, type); + value = __calculate_vpe(d); break; case HAL_VIDEO_DOMAIN_ENCODER: - value = __calculate_encoder(d, type); + value = __calculate_encoder(d); break; case HAL_VIDEO_DOMAIN_DECODER: - value = __calculate_decoder(d, type); + value = __calculate_decoder(d); break; case HAL_VIDEO_DOMAIN_CVP: - value = __calculate_cvp(d, type); + value = __calculate_cvp(d); break; default: dprintk(VIDC_ERR, "Unknown Domain"); @@ -612,28 +582,30 @@ static unsigned long __calculate(struct vidc_bus_vote_data *d, return value; } -unsigned long calc_bw_iris2(struct bus_info *bus, - struct msm_vidc_bus_data *vidc_data) +int calc_bw_iris2(struct msm_vidc_bus_data *vidc_data) { - unsigned long ab_kbps = 0, c = 0; - enum vidc_bus_type type; + int ret = 0, c = 0; if (!vidc_data || !vidc_data->data_count || !vidc_data->data) goto exit; + vidc_data->total_bw_ddr = 0; + vidc_data->total_bw_llcc = 0; + for (c = 0; c < vidc_data->data_count; ++c) { if (vidc_data->data->power_mode == VIDC_POWER_TURBO) { - ab_kbps = INT_MAX; + vidc_data->total_bw_ddr = INT_MAX; + vidc_data->total_bw_llcc = INT_MAX; goto exit; } } - type = get_type_frm_name(bus->name); - - for (c = 0; c < vidc_data->data_count; ++c) - ab_kbps += __calculate(&vidc_data->data[c], type); + for (c = 0; c < vidc_data->data_count; ++c) { + __calculate(&vidc_data->data[c]); + vidc_data->total_bw_ddr += vidc_data->data[c].calc_bw_ddr; + vidc_data->total_bw_llcc += vidc_data->data[c].calc_bw_llcc; + } exit: - trace_msm_vidc_perf_bus_vote(bus->name, ab_kbps); - return ab_kbps; + return ret; } From 38b1e119c82d52d498896a74f474483880d86d59 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 22 May 2019 11:47:36 -0700 Subject: [PATCH 102/452] msm: vidc: queue batched buffers upon timeout Client expects all the buffers to be returned in certain scenarios but driver does not return due to decode batching feature. Add delayed_work functionality to queue batched buffers to video hardware upon timeout, so that all the buffers will be returned to client. Change-Id: I926de1da93d941ff2a64bfec1bbd351de2f3a601 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_v4l2_vidc.c | 11 +++ msm/vidc/msm_vidc.c | 3 + msm/vidc/msm_vidc_common.c | 140 ++++++++++++++++++++++++++-------- msm/vidc/msm_vidc_common.h | 5 ++ msm/vidc/msm_vidc_internal.h | 2 + msm/vidc/msm_vidc_platform.c | 16 ++++ msm/vidc/msm_vidc_res_parse.c | 2 + msm/vidc/msm_vidc_resources.h | 1 + 8 files changed, 150 insertions(+), 30 deletions(-) diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index fd64cee4d061..804c9b124f96 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -555,6 +555,12 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) goto err_cores_exceeded; } + core->vidc_core_workq = create_singlethread_workqueue( + "vidc_core_workq"); + if (!core->vidc_core_workq) { + dprintk(VIDC_ERR, "%s: create core workq failed\n", __func__); + goto err_core_workq; + } mutex_lock(&vidc_driver->lock); list_add_tail(&core->list, &vidc_driver->cores); mutex_unlock(&vidc_driver->lock); @@ -581,6 +587,9 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) return rc; err_fail_sub_device_probe: + if (core->vidc_core_workq) + destroy_workqueue(core->vidc_core_workq); +err_core_workq: vidc_hfi_deinitialize(core->hfi_type, core->device); err_cores_exceeded: if (core->resources.cvp_internal) { @@ -662,6 +671,8 @@ static int msm_vidc_remove(struct platform_device *pdev) return -EINVAL; } + if (core->vidc_core_workq) + destroy_workqueue(core->vidc_core_workq); vidc_hfi_deinitialize(core->hfi_type, core->device); if (core->resources.cvp_internal) { device_remove_file(&core->vdev[MSM_VIDC_CVP].vdev.dev, diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 10d84555ad21..39935643c43a 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1536,6 +1536,7 @@ void *msm_vidc_open(int core_id, int session_type) INIT_MSM_VIDC_LIST(&inst->etb_data); INIT_MSM_VIDC_LIST(&inst->fbd_data); + INIT_DELAYED_WORK(&inst->batch_work, msm_vidc_batch_handler); kref_init(&inst->kref); inst->session_type = session_type; @@ -1696,6 +1697,8 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst) } mutex_unlock(&inst->registeredbufs.lock); + cancel_batch_work(inst); + msm_comm_free_freq_table(inst); msm_comm_free_input_cr_table(inst); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index daf52123aad7..0ced7f4cfb48 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -4351,6 +4351,35 @@ static int msm_comm_qbuf_to_hfi(struct msm_vidc_inst *inst, return rc; } +void msm_vidc_batch_handler(struct work_struct *work) +{ + int rc = 0; + struct msm_vidc_inst *inst; + + inst = container_of(work, struct msm_vidc_inst, batch_work.work); + + inst = get_inst(get_vidc_core(MSM_VIDC_CORE_VENUS), inst); + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return; + } + + if (inst->state == MSM_VIDC_CORE_INVALID) { + dprintk(VIDC_ERR, "%s: invalid state\n", __func__); + goto exit; + } + + dprintk(VIDC_HIGH, "%s: %x: queue pending batch buffers\n", + __func__, hash32_ptr(inst->session)); + + rc = msm_comm_qbufs_batch(inst, NULL); + if (rc) + dprintk(VIDC_ERR, "%s: batch qbufs failed\n", __func__); + +exit: + put_inst(inst); +} + static int msm_comm_qbuf_superframe_to_hfi(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) { @@ -4562,6 +4591,45 @@ int msm_comm_qbufs(struct msm_vidc_inst *inst) return rc; } +int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf) +{ + int rc = 0; + struct msm_vidc_buffer *buf; + + rc = msm_comm_scale_clocks_and_bus(inst); + if (rc) + dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__); + + mutex_lock(&inst->registeredbufs.lock); + list_for_each_entry(buf, &inst->registeredbufs.list, list) { + /* Don't queue if buffer is not OUTPUT_MPLANE */ + if (buf->vvb.vb2_buf.type != OUTPUT_MPLANE) + goto loop_end; + /* Don't queue if buffer is not a deferred buffer */ + if (!(buf->flags & MSM_VIDC_FLAG_DEFERRED)) + goto loop_end; + /* Don't queue if RBR event is pending on this buffer */ + if (buf->flags & MSM_VIDC_FLAG_RBR_PENDING) + goto loop_end; + + print_vidc_buffer(VIDC_HIGH, "batch-qbuf", inst, buf); + rc = msm_comm_qbuf_to_hfi(inst, buf); + if (rc) { + dprintk(VIDC_ERR, "%s: Failed batch qbuf to hfi: %d\n", + __func__, rc); + break; + } +loop_end: + /* Queue pending buffers till the current buffer only */ + if (buf == mbuf) + break; + } + mutex_unlock(&inst->registeredbufs.lock); + + return rc; +} + /* * msm_comm_qbuf_decode_batch - count the buffers which are not queued to * firmware yet (count includes rbr pending buffers too) and @@ -4574,9 +4642,8 @@ int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst, { int rc = 0; u32 count = 0; - struct msm_vidc_buffer *buf; - if (!inst || !mbuf) { + if (!inst || !inst->core || !mbuf) { dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); return -EINVAL; } @@ -4601,43 +4668,55 @@ int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst, if (count < inst->batch.size) { print_vidc_buffer(VIDC_HIGH, "batch-qbuf deferred", inst, mbuf); + schedule_batch_work(inst); return 0; } + + /* + * Batch completed - queing bufs to firmware. + * so cancel pending work if any. + */ + cancel_batch_work(inst); } - rc = msm_comm_scale_clocks_and_bus(inst); + rc = msm_comm_qbufs_batch(inst, mbuf); if (rc) - dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__); - - mutex_lock(&inst->registeredbufs.lock); - list_for_each_entry(buf, &inst->registeredbufs.list, list) { - /* Don't queue if buffer is not CAPTURE_MPLANE */ - if (buf->vvb.vb2_buf.type != OUTPUT_MPLANE) - goto loop_end; - /* Don't queue if buffer is not a deferred buffer */ - if (!(buf->flags & MSM_VIDC_FLAG_DEFERRED)) - goto loop_end; - /* Don't queue if RBR event is pending on this buffer */ - if (buf->flags & MSM_VIDC_FLAG_RBR_PENDING) - goto loop_end; - - print_vidc_buffer(VIDC_HIGH, "batch-qbuf", inst, buf); - rc = msm_comm_qbuf_to_hfi(inst, buf); - if (rc) { - dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", - __func__, rc); - break; - } -loop_end: - /* Queue pending buffers till the current buffer only */ - if (buf == mbuf) - break; - } - mutex_unlock(&inst->registeredbufs.lock); + dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", + __func__, rc); return rc; } +int schedule_batch_work(struct msm_vidc_inst *inst) +{ + struct msm_vidc_core *core; + struct msm_vidc_platform_resources *res; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + return -EINVAL; + } + core = inst->core; + res = &core->resources; + + cancel_delayed_work(&inst->batch_work); + queue_delayed_work(core->vidc_core_workq, &inst->batch_work, + msecs_to_jiffies(res->batch_timeout)); + + return 0; +} + +int cancel_batch_work(struct msm_vidc_inst *inst) +{ + if (!inst) { + dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + return -EINVAL; + } + cancel_delayed_work(&inst->batch_work); + + return 0; +} + int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst) { int rc = -EINVAL, i = 0; @@ -5331,6 +5410,7 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) msm_clock_data_reset(inst); + cancel_batch_work(inst); if (inst->state == MSM_VIDC_CORE_INVALID) { dprintk(VIDC_ERR, "Core %pK and inst %pK are in bad state\n", diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 7d20fd15ae91..a91208c1ed42 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -286,12 +286,17 @@ void msm_comm_store_mark_data(struct msm_vidc_list *data_list, void msm_comm_fetch_mark_data(struct msm_vidc_list *data_list, u32 index, u32 *mark_data, u32 *mark_target); int msm_comm_release_mark_data(struct msm_vidc_inst *inst); +int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, + struct msm_vidc_buffer *mbuf); int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); +int schedule_batch_work(struct msm_vidc_inst *inst); +int cancel_batch_work(struct msm_vidc_inst *inst); int msm_comm_num_queued_bufs(struct msm_vidc_inst *inst, u32 type); int msm_comm_set_index_extradata(struct msm_vidc_inst *inst, uint32_t extradata_id, uint32_t value); int msm_comm_set_extradata(struct msm_vidc_inst *inst, uint32_t extradata_id, uint32_t value); bool msm_comm_check_for_inst_overload(struct msm_vidc_core *core); +void msm_vidc_batch_handler(struct work_struct *work); #endif diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 5d8d165b82eb..2162909fe33e 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -442,6 +442,7 @@ struct msm_vidc_core { struct msm_vidc_capability *capabilities; struct delayed_work fw_unload_work; struct work_struct ssr_work; + struct workqueue_struct *vidc_core_workq; enum hal_ssr_trigger_type ssr_type; bool smmu_fault_handled; bool trigger_ssr; @@ -518,6 +519,7 @@ struct msm_vidc_inst { struct msm_vidc_codec_data *codec_data; struct hal_hdr10_pq_sei hdr10_sei_params; struct batch_mode batch; + struct delayed_work batch_work; struct msm_vidc_inst_smem_ops *smem_ops; int (*buffer_size_calculators)(struct msm_vidc_inst *inst); }; diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index eaf20bb9fe4a..d9c4804f8faf 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -444,6 +444,10 @@ static struct msm_vidc_common_data lito_common_data_v0[] = { .key = "qcom,decode-batching", .value = 1, }, + { + .key = "qcom,batch-timeout", + .value = 200, + }, { .key = "qcom,dcvs", .value = 1, @@ -515,6 +519,10 @@ static struct msm_vidc_common_data lito_common_data_v1[] = { .key = "qcom,decode-batching", .value = 1, }, + { + .key = "qcom,batch-timeout", + .value = 200, + }, { .key = "qcom,dcvs", .value = 1, @@ -594,6 +602,10 @@ static struct msm_vidc_common_data kona_common_data[] = { .key = "qcom,decode-batching", .value = 1, }, + { + .key = "qcom,batch-timeout", + .value = 200, + }, { .key = "qcom,dcvs", .value = 1, @@ -736,6 +748,10 @@ static struct msm_vidc_common_data sm8150_common_data[] = { .key = "qcom,decode-batching", .value = 1, }, + { + .key = "qcom,batch-timeout", + .value = 200, + }, { .key = "qcom,dcvs", .value = 1, diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index b0a95ce4724d..d2d66bb60291 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -827,6 +827,8 @@ int read_platform_resources_from_drv_data( "qcom,domain-attr-cache-pagetables"); res->decode_batching = find_key_value(platform_data, "qcom,decode-batching"); + res->batch_timeout = find_key_value(platform_data, + "qcom,batch-timeout"); res->dcvs = find_key_value(platform_data, "qcom,dcvs"); res->fw_cycles = find_key_value(platform_data, diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 90d4d03d7df2..76b5b8d206bd 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -195,6 +195,7 @@ struct msm_vidc_platform_resources { bool non_fatal_pagefaults; bool cache_pagetables; bool decode_batching; + uint32_t batch_timeout; bool dcvs; struct msm_vidc_codec_data *codec_data; int codec_data_count; From 9e0c71bb6e64af5d5e6ae864e666a867d1e57c2e Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Tue, 16 Jul 2019 11:09:31 -0700 Subject: [PATCH 103/452] msm: vidc: Update minimum GOP size calculation Use max layers allowed in a session to calculate min GOP size instead of variable number of layers enabled during each frame encode to avoid GOP size not being multiple of sub-GOP size issue. Change-Id: I3bb6e5320385acea9cb892c04b586ac3ca8c753f Signed-off-by: Akshata Sahukar --- msm/vidc/msm_venc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index f3f4801a95b6..1fe2079ac714 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2249,7 +2249,7 @@ void msm_venc_adjust_gop_size(struct msm_vidc_inst *inst) * Layer encoding needs GOP size to be multiple of subgop size * And subgop size is 2 ^ number of enhancement layers */ - hier_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); + hier_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); if (hier_ctrl->val > 1) { u32 min_gop_size; u32 num_subgops; From 1fc298872a243ed19d817d8da7b8a8b312bf038d Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 16 Jul 2019 15:51:24 -0700 Subject: [PATCH 104/452] msm: vidc: Initialize 10bit bw variable In certain scenarios, y_bw_no_ubwc_10bpp and y_bw_10bpp_p010 will be used with unitialized and incorrect values. CRs-Fixed: 2487664 Change-Id: I292ed33b60c3994886bb3756babc8ab706ceab8b Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc_bus_iris2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vidc_bus_iris2.c b/msm/vidc/msm_vidc_bus_iris2.c index 4b5c4bdbfdc2..a4ea814f55d5 100644 --- a/msm/vidc/msm_vidc_bus_iris2.c +++ b/msm/vidc/msm_vidc_bus_iris2.c @@ -56,9 +56,9 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d, unsigned long bitrate; fp_t bins_to_bit_factor, vsp_read_factor, vsp_write_factor, - dpb_factor, dpb_write_factor, - y_bw_no_ubwc_8bpp, y_bw_no_ubwc_10bpp, y_bw_10bpp_p010, - motion_vector_complexity = 0; + dpb_factor, dpb_write_factor, y_bw_no_ubwc_8bpp; + fp_t y_bw_no_ubwc_10bpp = 0, y_bw_10bpp_p010 = 0, + motion_vector_complexity = 0; fp_t dpb_total = 0; /* Output parameters */ @@ -304,7 +304,7 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d, fp_t dpb_compression_factor, original_compression_factor, original_compression_factor_y, - y_bw_no_ubwc_8bpp, y_bw_no_ubwc_10bpp, y_bw_10bpp_p010, + y_bw_no_ubwc_8bpp, y_bw_no_ubwc_10bpp = 0, y_bw_10bpp_p010 = 0, input_compression_factor, downscaling_ratio, ref_y_read_bw_factor, ref_cbcr_read_bw_factor, From 4c65367a077f02d0797fd63d3d82b81aae3d1335 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Wed, 17 Jul 2019 13:05:19 -0700 Subject: [PATCH 105/452] msm: vidc: Enable LTR use contraint by default Encoder shall encode subsequent frames in encoding order subject to the following constraints: - It shall not use short-term reference frames in display/input order older than the current frame with the LTR command applied for future encoding in encoding order. - It shall not use LTR frames not described by the most recent USELTRFRAME. - It may use LTR frames updated after the current frame in encoding order. Change-Id: I167bb0e211c46f892fedb88f8054bc98543ebe8a Signed-off-by: Akshata Sahukar --- msm/vidc/msm_venc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 1fe2079ac714..7abbad7e76be 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3715,7 +3715,7 @@ int msm_venc_set_ltr_useframe(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME); use_ltr.ref_ltr = ctrl->val; - use_ltr.use_constrnt = false; + use_ltr.use_constrnt = true; use_ltr.frames = 0; dprintk(VIDC_HIGH, "%s: %d\n", __func__, use_ltr.ref_ltr); rc = call_hfi_op(hdev, session_set_property, inst->session, From 9abcce52a62ed28c3e3a5b7c05565383c1f4fa39 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 17 Jul 2019 15:32:03 +0530 Subject: [PATCH 106/452] msm: vidc: remove key frame flag usage from ebd Remove HAL_BUFFERFLAG_SYNCFRAME flag usage support from hfi_msg_session_empty_buffer_done_packet and its corresponding usage in handle_ebd. Change-Id: I2dafd35a462a443e6efa165cbf46d4b78833c765 Signed-off-by: Priyanka Gujjula --- msm/vidc/hfi_response_handler.c | 17 +---------------- msm/vidc/msm_vidc_common.c | 2 -- msm/vidc/vidc_hfi.h | 1 + msm/vidc/vidc_hfi_helper.h | 4 ---- 4 files changed, 2 insertions(+), 22 deletions(-) diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index 5c376a4cfa69..b6bef94a5e11 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -767,8 +767,6 @@ static int hfi_process_session_etb_done(u32 device_id, { struct hfi_msg_session_empty_buffer_done_packet *pkt = _pkt; struct msm_vidc_cb_data_done data_done = {0}; - struct hfi_picture_type *hfi_picture_type = NULL; - u32 is_sync_frame; dprintk(VIDC_LOW, "RECEIVED: SESSION_ETB_DONE[%#x]\n", pkt->session_id); @@ -790,24 +788,11 @@ static int hfi_process_session_etb_done(u32 device_id, pkt->ubwc_cr_stats.complexity_number; data_done.input_done.offset = pkt->offset; data_done.input_done.filled_len = pkt->filled_len; + data_done.input_done.flags = pkt->flags; data_done.input_done.packet_buffer = pkt->packet_buffer; data_done.input_done.extra_data_buffer = pkt->extra_data_buffer; data_done.input_done.status = hfi_map_err_status(pkt->error_type); - is_sync_frame = pkt->rgData[0]; - if (is_sync_frame) { - if (pkt->size < - sizeof(struct hfi_msg_session_empty_buffer_done_packet) - + sizeof(struct hfi_picture_type)) - goto bad_packet_size; - hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[1]; - if (hfi_picture_type->picture_type) - data_done.input_done.flags = - hfi_picture_type->picture_type; - else - dprintk(VIDC_LOW, - "Non-Sync frame sent for H264/HEVC\n"); - } trace_msm_v4l2_vidc_buffer_event_end("ETB", (u32)pkt->packet_buffer, -1, -1, diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 0ced7f4cfb48..d5fd1c6e1b66 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2521,8 +2521,6 @@ static void handle_ebd(enum hal_command_response cmd, void *data) dprintk(VIDC_LOW, "Failed : Corrupted input stream\n"); mbuf->vvb.flags |= V4L2_BUF_FLAG_DATA_CORRUPT; } - if (empty_buf_done->flags & HAL_BUFFERFLAG_SYNCFRAME) - mbuf->vvb.flags |= V4L2_BUF_FLAG_KEYFRAME; f = &inst->fmts[INPUT_PORT].v4l2_fmt; if (f->fmt.pix_mp.num_planes > 1) diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index bd26af04cf1a..24be24e061c3 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -589,6 +589,7 @@ struct hfi_msg_session_empty_buffer_done_packet { u32 extra_data_buffer; u32 flags; struct hfi_frame_cr_stats_type ubwc_cr_stats; + /* no usage of sync_frame flag in EBD, rgData[1] is not used */ u32 rgData[1]; }; diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index 859ab24a9c7e..05f00250726b 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -658,10 +658,6 @@ struct hfi_bit_depth { u32 bit_depth; }; -struct hfi_picture_type { - u32 picture_type; -}; - /* Base Offset for UBWC color formats */ #define HFI_COLOR_FORMAT_UBWC_BASE (0x8000) /* Base Offset for 10-bit color formats */ From 8daa8ee72fa0ac103d092f6fcd1bf07f48348e3b Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Wed, 17 Jul 2019 22:26:34 +0800 Subject: [PATCH 107/452] msm: vidc: fix some BW and freq calculation issues - Modify max UBWC_CR from 3 to 5, as this value can exceed 4 in real usecases. - Decoder dpb read/write has already added cbcr by dpb_factor, no need to add again. - Decoder dpb_read BW saving factor for LLC should be 1.3 for H264 and 1.14 for HEVC. - VSP base cycle should be 0 for Iris/Iris2. - Encoder ref_read_cbcr should multiply by ref_cbcr_read_bw_factor. - Encoder ref_write should multiply by recon_write_bw_factor when tile enabled. - Add fw_vpp_cycles when calculating vpp_cycles. - Add multi-pipe factor for vpp_cycles. - Add B-frame factor for encoder vpp_cycles. Change-Id: I9e40203c5c89d8abdc77787a752ca240e11791f6 Signed-off-by: Qiwei Liu --- msm/vidc/msm_vidc_bus_iris1.c | 2 +- msm/vidc/msm_vidc_bus_iris2.c | 31 ++++++++++++---------- msm/vidc/msm_vidc_clocks.c | 37 ++++++++++++++++----------- msm/vidc/msm_vidc_platform.c | 48 +++++++++++++++++------------------ 4 files changed, 65 insertions(+), 53 deletions(-) diff --git a/msm/vidc/msm_vidc_bus_iris1.c b/msm/vidc/msm_vidc_bus_iris1.c index da35f8f02893..45879927a7ec 100644 --- a/msm/vidc/msm_vidc_bus_iris1.c +++ b/msm/vidc/msm_vidc_bus_iris1.c @@ -230,7 +230,7 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) if (llc_ref_read_l2_cache_enabled) { ddr.dpb_read = fp_div(ddr.dpb_read, is_h264_category ? - FP(1, 15, 100) : FP(1, 30, 100)); + FP(1, 30, 100) : FP(1, 15, 100)); llc.dpb_read = dpb_total - ddr.dpb_write - ddr.dpb_read; } diff --git a/msm/vidc/msm_vidc_bus_iris2.c b/msm/vidc/msm_vidc_bus_iris2.c index dd7209e459e7..620411ead52b 100644 --- a/msm/vidc/msm_vidc_bus_iris2.c +++ b/msm/vidc/msm_vidc_bus_iris2.c @@ -149,19 +149,17 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) ddr.dpb_read = fp_div(fp_mult(ddr.dpb_read, fp_mult(dpb_factor, motion_vector_complexity)), dpb_read_compression_factor); - ddr.dpb_read += fp_div(ddr.dpb_read, FP_INT(2)); ddr.dpb_write = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; ddr.dpb_write = fp_div(fp_mult(ddr.dpb_write, fp_mult(dpb_factor, dpb_write_factor)), dpb_write_compression_factor); - ddr.dpb_write += fp_div(ddr.dpb_write, FP_INT(2)); dpb_total = ddr.dpb_read + ddr.dpb_write; if (llc_ref_read_l2_cache_enabled) { ddr.dpb_read = fp_div(ddr.dpb_read, is_h264_category ? - FP(1, 15, 100) : FP(1, 30, 100)); + FP(1, 30, 100) : FP(1, 14, 100)); llc.dpb_read = dpb_total - ddr.dpb_write - ddr.dpb_read; } @@ -310,6 +308,13 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) rotation = d->rotation; cropping_or_scaling = false; vertical_tile_width = 960; + /* + * recon_write_bw_factor varies according to resolution and bit-depth, + * here use 1.08(1.075) for worst case. + * Similar for ref_y_read_bw_factor, it can reach 1.375 for worst case, + * here use 1.3 for average case, and can somewhat balance the + * worst case assumption for UBWC CR factors. + */ recon_write_bw_factor = FP(1, 8, 100); ref_y_read_bw_factor = FP(1, 30, 100); ref_cbcr_read_bw_factor = FP(1, 50, 100); @@ -393,20 +398,18 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) ddr.ref_read_y = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; - if (b_frames_enabled) ddr.ref_read_y = ddr.ref_read_y * 2; ddr.ref_read_y = fp_div(ddr.ref_read_y, dpb_compression_factor); - ddr.ref_read_crcb = ddr.ref_read_y; + ddr.ref_read_crcb = fp_mult((ddr.ref_read_y / 2), + ref_cbcr_read_bw_factor); - if (width != vertical_tile_width) { + if (width > vertical_tile_width) { ddr.ref_read_y = fp_mult(ddr.ref_read_y, ref_y_read_bw_factor); } - ddr.ref_read_crcb = fp_mult(ddr.ref_read_crcb, FP(0, 50, 100)); - if (llc_ref_chroma_cache_enabled) { total_ref_read_crcb = ddr.ref_read_crcb; ddr.ref_read_crcb = fp_div(ddr.ref_read_crcb, @@ -415,12 +418,14 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) } ddr.ref_write = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; - ddr.ref_write = fp_mult(ddr.ref_write, - (fp_div(FP(1, 50, 100), dpb_compression_factor))); + ddr.ref_write = fp_div(fp_mult(ddr.ref_write, FP(1, 50, 100)), + dpb_compression_factor); - ddr.ref_write_overlap = fp_div(fp_mult(ddr.ref_write, - (recon_write_bw_factor - FP_ONE)), - recon_write_bw_factor); + if (width > vertical_tile_width) { + ddr.ref_write_overlap = fp_mult(ddr.ref_write, + (recon_write_bw_factor - FP_ONE)); + ddr.ref_write = fp_mult(ddr.ref_write, recon_write_bw_factor); + } ddr.orig_read = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : (original_compression_enabled ? y_bw_no_ubwc_10bpp : diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index cab3cbd62487..5c4816f7b5de 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -14,7 +14,7 @@ #define MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR (4 << 16) #define MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO (1 << 16) -#define MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO (3 << 16) +#define MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO (5 << 16) static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst); static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, @@ -783,6 +783,7 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, u32 filled_len) { u64 vsp_cycles = 0, vpp_cycles = 0, fw_cycles = 0, freq = 0; + u64 fw_vpp_cycles = 0; u32 vpp_cycles_per_mb; u32 mbs_per_second; struct msm_vidc_core *core = NULL; @@ -806,15 +807,24 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, * between them. */ + fw_cycles = fps * inst->core->resources.fw_cycles; + fw_vpp_cycles = fps * inst->core->resources.fw_vpp_cycles; + if (inst->session_type == MSM_VIDC_ENCODER) { vpp_cycles_per_mb = inst->flags & VIDC_LOW_POWER ? inst->clk_data.entry->low_power_cycles : inst->clk_data.entry->vpp_cycles; - vpp_cycles = mbs_per_second * vpp_cycles_per_mb; - /* 21 / 20 is overhead factor */ - vpp_cycles = (vpp_cycles * 21)/ - (inst->clk_data.work_route * 20); + vpp_cycles = mbs_per_second * vpp_cycles_per_mb / + inst->clk_data.work_route; + /* 1.25 factor for IbP GOP structure */ + if (msm_comm_g_ctrl_for_id(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES)) + vpp_cycles += vpp_cycles / 4; + /* 21 / 20 is minimum overhead factor */ + vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles); + /* 1.01 is multi-pipe overhead */ + if (inst->clk_data.work_route > 1) + vpp_cycles += vpp_cycles / 100; vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; @@ -827,22 +837,19 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, } vsp_cycles += ((u64)inst->clk_data.bitrate * vsp_factor_num) / vsp_factor_den; - - fw_cycles = fps * inst->core->resources.fw_cycles; - } else if (inst->session_type == MSM_VIDC_DECODER) { - vpp_cycles = mbs_per_second * inst->clk_data.entry->vpp_cycles; - /* 21 / 20 is overhead factor */ - vpp_cycles = (vpp_cycles * 21)/ - (inst->clk_data.work_route * 20); + vpp_cycles = mbs_per_second * inst->clk_data.entry->vpp_cycles / + inst->clk_data.work_route; + /* 21 / 20 is minimum overhead factor */ + vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles); + /* 1.059 is multi-pipe overhead */ + if (inst->clk_data.work_route > 1) + vpp_cycles += vpp_cycles * 59 / 1000; vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; /* vsp perf is about 0.5 bits/cycle */ vsp_cycles += ((fps * filled_len * 8) * 10) / 5; - - fw_cycles = fps * inst->core->resources.fw_cycles; - } else { dprintk(VIDC_ERR, "Unknown session type = %s\n", __func__); return msm_vidc_max_freq(inst->core); diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index d9c4804f8faf..4a9e953813a7 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -65,28 +65,28 @@ static struct msm_vidc_codec_data default_codec_data[] = { /* Update with lito data */ static struct msm_vidc_codec_data lito_codec_data[] = { - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 10, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 10, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 10, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 0, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 0, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 0, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), - CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 10, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 10, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 10, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 10, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 10, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 0, 200, 200), }; /* Update with Kona data */ static struct msm_vidc_codec_data kona_codec_data[] = { - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 10, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 10, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 10, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 0, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 0, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 0, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), - CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 10, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 10, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 10, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 10, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 10, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 0, 200, 200), }; /* Update with SM6150 data */ @@ -104,15 +104,15 @@ static struct msm_vidc_codec_data sm6150_codec_data[] = { /* Update with 855 data */ static struct msm_vidc_codec_data sm8150_codec_data[] = { - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 10, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 10, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 10, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 0, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 0, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 0, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), - CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 10, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 10, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 10, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 10, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 10, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 0, 200, 200), }; static struct msm_vidc_codec_data sdm845_codec_data[] = { From ba78735a86b379c33ecfc59aaae8d1b035f8f7a0 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Wed, 17 Jul 2019 12:40:43 -0700 Subject: [PATCH 108/452] msm: vidc: send dmabuf pointer instead of fd Send dmabuf pointer in reserved fields instead of fd to CVP driver for internal CVP usage buffers as fd is not available for these buffers. Change-Id: Ic25a445253b4ae05748d47b7caf0b88e909aad7e Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_cvp_external.c | 68 ++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index c65d28eef24e..41cc3a0aeb3b 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -7,6 +7,9 @@ #include "msm_cvp_external.h" #include "msm_vidc_common.h" +#define LOWER32(a) ((u32)((u64)a)) +#define UPPER32(a) ((u32)((u64)a >> 32)) + static void print_cvp_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, struct msm_cvp_buf *cbuf) { @@ -22,6 +25,22 @@ static void print_cvp_buffer(u32 tag, const char *str, cbuf->offset, cbuf->dbuf, cbuf->kvaddr); } +static int fill_cvp_buffer(struct msm_cvp_buffer_type *dst, + struct msm_cvp_buf *src) +{ + if (!dst || !src) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + dst->buffer_addr = -1; + dst->reserved1 = LOWER32(src->dbuf); + dst->reserved2 = UPPER32(src->dbuf); + dst->size = src->size; + + return 0; +} + static int msm_cvp_get_version_info(struct msm_vidc_inst *inst) { int rc; @@ -189,7 +208,6 @@ static int msm_cvp_allocate_buffer(struct msm_vidc_inst *inst, int ion_flags = 0; unsigned long heap_mask = 0; struct dma_buf *dbuf; - int fd; if (!inst || !inst->cvp || !buffer) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); @@ -212,14 +230,7 @@ static int msm_cvp_allocate_buffer(struct msm_vidc_inst *inst, goto error; } buffer->dbuf = dbuf; - - fd = dma_buf_fd(dbuf, O_CLOEXEC); - if (fd < 0) { - dprintk(VIDC_ERR, "%s: failed to get fd\n", __func__); - rc = -ENOMEM; - goto error; - } - buffer->fd = fd; + buffer->fd = -1; if (kernel_map) { buffer->kvaddr = dma_buf_vmap(dbuf); @@ -539,10 +550,8 @@ static void msm_cvp_deinit_internal_buffers(struct msm_vidc_inst *inst) HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS; persist2_packet.session_id = cvp->session_id; persist2_packet.cvp_op = CVP_DME; - persist2_packet.persist2_buffer.buffer_addr = - cvp->persist2_buffer.fd; - persist2_packet.persist2_buffer.size = - cvp->persist2_buffer.size; + fill_cvp_buffer(&persist2_packet.persist2_buffer, + &cvp->persist2_buffer); arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL); if (arg) { @@ -610,8 +619,8 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst) persist2_packet.packet_type = HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS; persist2_packet.session_id = cvp->session_id; persist2_packet.cvp_op = CVP_DME; - persist2_packet.persist2_buffer.buffer_addr = cvp->persist2_buffer.fd; - persist2_packet.persist2_buffer.size = cvp->persist2_buffer.size; + fill_cvp_buffer(&persist2_packet.persist2_buffer, + &cvp->persist2_buffer); memset(arg, 0, sizeof(struct cvp_kmd_arg)); arg->type = CVP_KMD_HFI_PERSIST_CMD; @@ -831,6 +840,7 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, cvp->fullres_buffer.fd = vb->planes[0].m.fd; cvp->fullres_buffer.size = vb->planes[0].length; cvp->fullres_buffer.offset = vb->planes[0].data_offset; + cvp->fullres_buffer.dbuf = mbuf->smem[0].dma_buf; /* frame skip logic */ fps = max(inst->clk_data.operating_rate, @@ -875,25 +885,19 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, frame->descmatch_threshold = 52; frame->ncc_robustness_threshold = 0; - frame->fullres_srcbuffer.buffer_addr = cvp->fullres_buffer.fd; - frame->fullres_srcbuffer.size = cvp->fullres_buffer.size; - frame->videospatialtemporal_statsbuffer.buffer_addr = - cvp->output_buffer.fd; - frame->videospatialtemporal_statsbuffer.size = - cvp->output_buffer.size; - - frame->src_buffer.buffer_addr = cvp->fullres_buffer.fd; - frame->src_buffer.size = cvp->fullres_buffer.size; + fill_cvp_buffer(&frame->fullres_srcbuffer, + &cvp->fullres_buffer); + fill_cvp_buffer(&frame->videospatialtemporal_statsbuffer, + &cvp->output_buffer); + fill_cvp_buffer(&frame->src_buffer, &cvp->fullres_buffer); if (cvp->downscale) { - frame->src_buffer.buffer_addr = cvp->src_buffer.fd; - frame->src_buffer.size = cvp->src_buffer.size; - frame->ref_buffer.buffer_addr = cvp->ref_buffer.fd; - frame->ref_buffer.size = cvp->ref_buffer.size; + fill_cvp_buffer(&frame->src_buffer, &cvp->src_buffer); + fill_cvp_buffer(&frame->ref_buffer, &cvp->ref_buffer); } - frame->srcframe_contextbuffer.buffer_addr = cvp->context_buffer.fd; - frame->srcframe_contextbuffer.size = cvp->context_buffer.size; - frame->refframe_contextbuffer.buffer_addr = cvp->refcontext_buffer.fd; - frame->refframe_contextbuffer.size = cvp->refcontext_buffer.size; + fill_cvp_buffer(&frame->srcframe_contextbuffer, + &cvp->context_buffer); + fill_cvp_buffer(&frame->refframe_contextbuffer, + &cvp->refcontext_buffer); print_cvp_buffer(VIDC_LOW, "input frame", inst, &cvp->fullres_buffer); rc = msm_cvp_private(cvp->priv, CVP_KMD_SEND_CMD_PKT, arg); From c074c474fbe8f8000683b4555dbc76cad4fe1f8d Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Fri, 19 Jul 2019 10:03:29 +0800 Subject: [PATCH 109/452] msm: venc: add all intra encoding supports 1. Add all intra encoding capability; 2. Disable LTR, HP, Slice mode and IR settings; 3. Use WorkMode2, HQ and Pipeline 4 by force; 4. Ignore dynamic switch between IPPP and all intra; 5. Reject sessions if static/dynamic frame rate larger than 240; 6. Reject any non HEVC or AVC sessions; 7. Reject any HEVC Main10 profile sessions; 8. Reset all intra flag to false when stream off; Change-Id: I9f405a7712c84bc6f8319025a7fb2a0a7f9064df Signed-off-by: Shi Zhongbo --- msm/vidc/msm_venc.c | 121 +++++++++++++++++++++++++++++++++++ msm/vidc/msm_venc.h | 1 + msm/vidc/msm_vidc.c | 2 + msm/vidc/msm_vidc_clocks.c | 3 +- msm/vidc/msm_vidc_common.c | 3 + msm/vidc/msm_vidc_internal.h | 1 + msm/vidc/msm_vidc_platform.c | 3 + msm/vidc/vidc_hfi_api.h | 1 + 8 files changed, 134 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 7abbad7e76be..0eb3b1671076 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1477,6 +1477,12 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_MPEG_VIDEO_GOP_SIZE: if (inst->state == MSM_VIDC_START_DONE) { + if (inst->all_intra) { + dprintk(VIDC_HIGH, + "%s: ignore dynamic gop size for all intra\n", + __func__); + break; + } rc = msm_venc_set_intra_period(inst); if (rc) dprintk(VIDC_ERR, @@ -1869,12 +1875,27 @@ int msm_venc_set_frame_rate(struct msm_vidc_inst *inst) int rc = 0; struct hfi_device *hdev; struct hfi_frame_rate frame_rate; + struct msm_vidc_capability *capability; + u32 fps_max; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; } hdev = inst->core->device; + capability = &inst->capability; + + /* Check frame rate */ + if (inst->all_intra) + fps_max = capability->cap[CAP_ALLINTRA_MAX_FPS].max; + else + fps_max = capability->cap[CAP_FRAMERATE].max; + + if (inst->clk_data.frame_rate >> 16 > fps_max) { + dprintk(VIDC_ERR, "%s: Unsupported frame rate\n", + __func__); + return -ENOTSUPP; + } frame_rate.buffer_type = HFI_BUFFER_OUTPUT; frame_rate.frame_rate = inst->clk_data.frame_rate; @@ -2289,6 +2310,14 @@ int msm_venc_set_intra_period(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); intra_period.bframes = ctrl->val; + if (inst->state == MSM_VIDC_START_DONE && + !intra_period.pframes && !intra_period.bframes) { + dprintk(VIDC_HIGH, + "%s: Switch from IPPP to All Intra is not allowed\n", + __func__); + return rc; + } + dprintk(VIDC_HIGH, "%s: %d %d\n", __func__, intra_period.pframes, intra_period.bframes); rc = call_hfi_op(hdev, session_set_property, inst->session, @@ -3989,10 +4018,102 @@ int msm_venc_set_lossless(struct msm_vidc_inst *inst) return rc; } +int handle_all_intra_restrictions(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *ctrl, *ctrl_t; + u32 n_fps, fps_max; + struct msm_vidc_capability *capability; + struct v4l2_format *f; + enum hal_video_codec codec; + struct hfi_intra_period intra_period; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) + return 0; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_GOP_SIZE); + intra_period.pframes = ctrl->val; + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); + intra_period.bframes = ctrl->val; + + if (!intra_period.pframes && !intra_period.bframes) + inst->all_intra = true; + else + return 0; + + dprintk(VIDC_HIGH, "All Intra(IDRs) Encoding\n"); + /* check codec and profile */ + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + codec = get_hal_codec(f->fmt.pix_mp.pixelformat); + if (codec != HAL_VIDEO_CODEC_HEVC && codec != HAL_VIDEO_CODEC_H264) { + dprintk(VIDC_ERR, "Unsupported codec for all intra\n"); + return -ENOTSUPP; + } + if (codec == HAL_VIDEO_CODEC_HEVC && + inst->profile == HFI_HEVC_PROFILE_MAIN10) { + dprintk(VIDC_ERR, "Unsupported HEVC profile for all intra\n"); + return -ENOTSUPP; + } + + /* check supported bit rate mode and frame rate */ + capability = &inst->capability; + n_fps = inst->clk_data.frame_rate >> 16; + fps_max = capability->cap[CAP_ALLINTRA_MAX_FPS].max; + if ((inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR && + inst->rc_type != RATE_CONTROL_OFF && + inst->rc_type != RATE_CONTROL_LOSSLESS) || + n_fps > fps_max) { + dprintk(VIDC_ERR, "Unsupported bitrate mode or frame rate\n"); + return -ENOTSUPP; + } + + /* Disable multi slice */ + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); + if (ctrl->val) { + dprintk(VIDC_HIGH, "Disable multi slice for all intra\n"); + ctrl->val = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; + } + + /* Disable LTR */ + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); + if (ctrl->val) { + dprintk(VIDC_HIGH, "Disable LTR for all intra\n"); + ctrl->val = 0; + } + + /* Disable Layer encoding */ + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); + ctrl_t = get_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); + if (ctrl->val || ctrl_t->val) { + dprintk(VIDC_HIGH, "Disable layer encoding for all intra\n"); + ctrl->val = 0; + ctrl_t->val = 0; + } + + /* Disable IR */ + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM); + ctrl_t = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB); + if (ctrl->val || ctrl_t->val) { + dprintk(VIDC_HIGH, "Disable IR for all intra\n"); + ctrl->val = 0; + ctrl_t->val = 0; + } + + return 0; +} + int msm_venc_set_properties(struct msm_vidc_inst *inst) { int rc = 0; + rc = handle_all_intra_restrictions(inst); + if (rc) + goto exit; rc = msm_venc_set_frame_size(inst); if (rc) goto exit; diff --git a/msm/vidc/msm_venc.h b/msm/vidc/msm_venc.h index dd17266814f6..455bc70805b6 100644 --- a/msm/vidc/msm_venc.h +++ b/msm/vidc/msm_venc.h @@ -39,4 +39,5 @@ int msm_venc_set_hp_layer(struct msm_vidc_inst *inst); int msm_venc_set_base_layer_priority_id(struct msm_vidc_inst *inst); int msm_venc_set_lossless(struct msm_vidc_inst *inst); int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst); +int handle_all_intra_restrictions(struct msm_vidc_inst *inst); #endif diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 39935643c43a..99105eb9fc5f 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1105,6 +1105,7 @@ static inline int stop_streaming(struct msm_vidc_inst *inst) dprintk(VIDC_ERR, "%s: failed to unprepare preprocess\n", __func__); + inst->all_intra = false; } msm_clock_data_reset(inst); @@ -1551,6 +1552,7 @@ void *msm_vidc_open(int core_id, int session_type) inst->smem_ops = &msm_vidc_smem_ops; inst->rc_type = RATE_CONTROL_OFF; inst->dpb_extra_binfo = NULL; + inst->all_intra = false; for (i = SESSION_MSG_INDEX(SESSION_MSG_START); i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) { diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index cab3cbd62487..d1f3bec83b44 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1518,7 +1518,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) pdata.video_work_mode = HFI_WORKMODE_1; latency.enable = true; } - if (inst->rc_type == RATE_CONTROL_LOSSLESS) { + if (inst->rc_type == RATE_CONTROL_LOSSLESS || inst->all_intra) { pdata.video_work_mode = HFI_WORKMODE_2; latency.enable = false; } @@ -1738,6 +1738,7 @@ int msm_vidc_decide_core_and_power_mode_iris2(struct msm_vidc_inst *inst) if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ || inst->rc_type == RATE_CONTROL_LOSSLESS || + inst->all_intra || (mbpf <= max_hq_mbpf && mbps <= max_hq_mbps)) enable = false; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 0ced7f4cfb48..95b5d4870694 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1571,6 +1571,9 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data) &inst->capability.cap[CAP_LOSSLESS_FRAME_HEIGHT]); print_cap("lossless_mbs_per_frame", &inst->capability.cap[CAP_LOSSLESS_MBS_PER_FRAME]); + /* All intra encoding usecase specific */ + print_cap("all_intra_frame_rate", + &inst->capability.cap[CAP_ALLINTRA_MAX_FPS]); msm_vidc_comm_update_ctrl_limits(inst); diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index fec213496dff..668eec7531a8 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -533,6 +533,7 @@ struct msm_vidc_inst { struct delayed_work batch_work; struct msm_vidc_inst_smem_ops *smem_ops; int (*buffer_size_calculators)(struct msm_vidc_inst *inst); + bool all_intra; }; extern struct msm_vidc_drv *vidc_driver; diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index d9c4804f8faf..5964efac5aaf 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -356,6 +356,9 @@ static struct msm_vidc_codec_capability kona_capabilities[] = { {CAP_LOSSLESS_FRAME_HEIGHT, ENC, H264|HEVC, 128, 4096, 1, 1080}, /* (4096 * 2304) / 256 */ {CAP_LOSSLESS_MBS_PER_FRAME, ENC, H264|HEVC, 64, 36864, 1, 36864}, + + /* All intra encoding usecase specific */ + {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 240, 1, 30}, }; /* diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 48097a046509..950439c026ee 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -283,6 +283,7 @@ enum hal_capability { CAP_LOSSLESS_FRAME_WIDTH, CAP_LOSSLESS_FRAME_HEIGHT, CAP_LOSSLESS_MBS_PER_FRAME, + CAP_ALLINTRA_MAX_FPS, CAP_MAX, }; From f9c4430e8b5ee5d1900e1ebd83fed3ba664189e6 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Fri, 19 Jul 2019 11:03:00 -0700 Subject: [PATCH 110/452] msm: vidc: handle dynamic framerate or operating rate changes Update CVP driver clocks, buses and preprocess frame skip logic if framerate or operating rate changed dynamically. Change-Id: Iebed437a1d7e0e136ebf703db76528cbd102363c Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_cvp_external.c | 48 +++++++++++++++++++++++++++---------- msm/vidc/msm_cvp_external.h | 2 ++ 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index c65d28eef24e..c490c8604c83 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -250,7 +250,6 @@ static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst) struct cvp_kmd_usecase_desc desc; struct cvp_kmd_request_power power; const u32 fps_max = CVP_FRAME_RATE_MAX; - u32 fps; if (!inst || !inst->cvp) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); @@ -262,16 +261,13 @@ static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst) memset(&power, 0, sizeof(struct cvp_kmd_request_power)); f = &inst->fmts[INPUT_PORT].v4l2_fmt; - fps = max(inst->clk_data.operating_rate, - inst->clk_data.frame_rate) >> 16; - desc.fullres_width = cvp->width; desc.fullres_height = cvp->height; desc.downscale_width = cvp->ds_width; desc.downscale_height = cvp->ds_height; desc.is_downscale = cvp->downscale; - desc.fps = min(fps, fps_max); - desc.op_rate = min(fps, fps_max); + desc.fps = min(cvp->frame_rate >> 16, fps_max); + desc.op_rate = cvp->operating_rate >> 16; desc.colorfmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat); rc = msm_cvp_est_cycles(&desc, &power); if (rc) { @@ -816,7 +812,7 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, struct cvp_kmd_arg *arg; struct msm_cvp_dme_frame_packet *frame; const u32 fps_max = CVP_FRAME_RATE_MAX; - u32 fps, skip_framecount; + u32 fps, operating_rate, skip_framecount; bool skipframe = false; if (!inst || !inst->cvp || !inst->cvp->arg || !mbuf) { @@ -832,9 +828,34 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, cvp->fullres_buffer.size = vb->planes[0].length; cvp->fullres_buffer.offset = vb->planes[0].data_offset; + /* handle framerate or operarating rate changes dynamically */ + if (cvp->frame_rate != inst->clk_data.frame_rate || + cvp->operating_rate != inst->clk_data.operating_rate) { + /* update cvp parameters */ + cvp->frame_rate = inst->clk_data.frame_rate; + cvp->operating_rate = inst->clk_data.operating_rate; + rc = msm_cvp_set_clocks_and_bus(inst); + if (rc) { + dprintk(VIDC_ERR, + "%s: unsupported dynamic changes %#x %#x\n", + __func__, cvp->frame_rate, cvp->operating_rate); + goto error; + } + } + + /* + * Special handling for operating rate 0xFFFFFFFF, + * client's intention is not to skip cvp preprocess + * based on operating rate, skip logic can still be + * executed based on framerate though. + */ + if (cvp->operating_rate == 0xFFFFFFFF) + operating_rate = fps_max << 16; + else + operating_rate = cvp->operating_rate; + /* frame skip logic */ - fps = max(inst->clk_data.operating_rate, - inst->clk_data.frame_rate) >> 16; + fps = max(cvp->frame_rate, operating_rate) >> 16; if (fps > fps_max) { /* * fps <= 120: 0, 2, 4, 6 .. are not skipped @@ -842,9 +863,9 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, * fps <= 240: 0, 4, 8, 12 .. are not skipped * fps <= 960: 0, 16, 32, 48 .. are not skipped */ - fps = ALIGN(fps, fps_max); + fps = roundup(fps, fps_max); skip_framecount = fps / fps_max; - skipframe = !(cvp->framecount % skip_framecount); + skipframe = cvp->framecount % skip_framecount; } if (skipframe) { print_cvp_buffer(VIDC_LOW, "input frame skipped", @@ -1037,6 +1058,8 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst) f = &inst->fmts[INPUT_PORT].v4l2_fmt; cvp->width = f->fmt.pix_mp.width; cvp->height = f->fmt.pix_mp.height; + cvp->frame_rate = inst->clk_data.frame_rate; + cvp->operating_rate = inst->clk_data.operating_rate; color_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat); /* enable downscale always */ @@ -1050,8 +1073,7 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst) __func__, f->fmt.pix_mp.pixelformat, cvp->width, cvp->height, cvp->downscale, cvp->ds_width, cvp->ds_height, - inst->clk_data.frame_rate >> 16, - inst->clk_data.operating_rate >> 16); + cvp->frame_rate >> 16, cvp->operating_rate >> 16); rc = msm_cvp_set_priority(inst); if (rc) diff --git a/msm/vidc/msm_cvp_external.h b/msm/vidc/msm_cvp_external.h index fd8b739af2b1..90b3e7722ced 100644 --- a/msm/vidc/msm_cvp_external.h +++ b/msm/vidc/msm_cvp_external.h @@ -172,6 +172,8 @@ struct msm_cvp_external { u32 height; u32 ds_width; u32 ds_height; + u32 frame_rate; + u32 operating_rate; bool downscale; u32 framecount; u32 buffer_idx; From b00fc8327b202a7cf5b3523440aa15714892d79d Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Mon, 22 Jul 2019 14:56:39 -0700 Subject: [PATCH 111/452] msm: vidc: Fix default_bus_vote Update all struct values in default_bus_vote. Calculate bw only when function available. CRs-Fixed: 2494775 Change-Id: I70a137494c4469f928efe3ddf1f0297e2281c689 Signed-off-by: Chinmay Sawarkar --- msm/vidc/hfi_common.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index cc78065accfa..b9548a914f6c 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -71,6 +71,9 @@ struct tzbsp_video_set_state_req { const struct msm_vidc_bus_data DEFAULT_BUS_VOTE = { .data = NULL, .data_count = 0, + .total_bw_ddr = 0, + .total_bw_llcc = 0, + .calc_bw = NULL, }; const int max_packets = 1000; @@ -1041,7 +1044,8 @@ static int __vote_buses(struct venus_hfi_device *device, device->bus_vote.data = new_data; device->bus_vote.data_count = num_data; - device->bus_vote.calc_bw(&device->bus_vote); + if (device->bus_vote.calc_bw) + device->bus_vote.calc_bw(&device->bus_vote); venus_hfi_for_each_bus(device, bus) { if (bus && bus->client) { From bc901062aa6c255f5bb7e736168480082a793b00 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Wed, 24 Jul 2019 15:10:07 +0800 Subject: [PATCH 112/452] msm: venc: add blur constraints Add blur constraints to reject external blur when rotation/flip/scalar enabled. Change-Id: Ia3fd1240a7788b89736889751f8a905e06e30f12 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_venc.c | 48 +++++++++++++++++++++++++++++++++++++++++++++ msm/vidc/msm_venc.h | 1 + 2 files changed, 49 insertions(+) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 0eb3b1671076..add57304f6da 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3901,6 +3901,13 @@ int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst) frame_sz.width = f->fmt.pix_mp.width; frame_sz.height = f->fmt.pix_mp.height; dprintk(VIDC_HIGH, "Disable both auto and external blur\n"); + } else if (ctrl->val != 0){ + if (check_blur_restrictions(inst)) { + /* reject external blur */ + dprintk(VIDC_ERR, + "External blur is unsupported with rotation/flip/scalar\n"); + return -EINVAL; + } } dprintk(VIDC_HIGH, "%s: type %u, height %u, width %u\n", __func__, @@ -4107,6 +4114,47 @@ int handle_all_intra_restrictions(struct msm_vidc_inst *inst) return 0; } +int check_blur_restrictions(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *rotation = NULL; + struct v4l2_ctrl *hflip = NULL; + struct v4l2_ctrl *vflip = NULL; + struct v4l2_format *f; + u32 output_height, output_width, input_height, input_width; + bool scalar_enable = false; + bool rotation_enable = false; + bool flip_enable = false; + + /* Only need to check static VPSS conditions */ + if (inst->state == MSM_VIDC_START_DONE) + return 0; + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + output_height = f->fmt.pix_mp.height; + output_width = f->fmt.pix_mp.width; + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + input_height = f->fmt.pix_mp.height; + input_width = f->fmt.pix_mp.width; + + if (output_height != input_height || output_width != input_width) + scalar_enable = true; + + rotation = get_ctrl(inst, V4L2_CID_ROTATE); + if (rotation->val != 0) + rotation_enable = true; + + hflip = get_ctrl(inst, V4L2_CID_HFLIP); + vflip = get_ctrl(inst, V4L2_CID_VFLIP); + if ((hflip->val == V4L2_MPEG_MSM_VIDC_ENABLE) || + (vflip->val == V4L2_MPEG_MSM_VIDC_ENABLE)) + flip_enable = true; + + if (scalar_enable || rotation_enable || flip_enable) + return -ENOTSUPP; + else + return 0; +} + int msm_venc_set_properties(struct msm_vidc_inst *inst) { int rc = 0; diff --git a/msm/vidc/msm_venc.h b/msm/vidc/msm_venc.h index 455bc70805b6..532505f87e2c 100644 --- a/msm/vidc/msm_venc.h +++ b/msm/vidc/msm_venc.h @@ -40,4 +40,5 @@ int msm_venc_set_base_layer_priority_id(struct msm_vidc_inst *inst); int msm_venc_set_lossless(struct msm_vidc_inst *inst); int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst); int handle_all_intra_restrictions(struct msm_vidc_inst *inst); +int check_blur_restrictions(struct msm_vidc_inst *inst); #endif From 61344c1970fc87448f563213e081fb28fce14758 Mon Sep 17 00:00:00 2001 From: Amit Shekhar Date: Tue, 16 Jul 2019 11:33:44 -0700 Subject: [PATCH 113/452] msm: vidc: Check image encode capabilities For heic/hevc image session, check respective capabilities to allow or reject. Change-Id: I4e565e6614a7863f75ecd4719480b850e1af43ae Signed-off-by: Amit Shekhar --- msm/vidc/msm_venc.c | 144 +++++++++++++++++++---------------- msm/vidc/msm_vidc.c | 12 --- msm/vidc/msm_vidc_clocks.c | 3 +- msm/vidc/msm_vidc_common.c | 99 +++++++++++++----------- msm/vidc/msm_vidc_common.h | 8 ++ msm/vidc/msm_vidc_internal.h | 3 - msm/vidc/msm_vidc_platform.c | 6 ++ msm/vidc/vidc_hfi_api.h | 4 + 8 files changed, 150 insertions(+), 129 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 0eb3b1671076..9359d2f20ae8 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1506,12 +1506,6 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) "%s: set bitrate mode failed\n", __func__); break; } - case V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY: - inst->frame_quality = ctrl->val; - break; - case V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE: - inst->grid_enable = ctrl->val; - break; case V4L2_CID_MPEG_VIDEO_BITRATE: inst->clk_data.bitrate = ctrl->val; if (inst->state == MSM_VIDC_START_DONE) { @@ -1774,6 +1768,8 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) __func__); } break; + case V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY: + case V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE: case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER: case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: case V4L2_CID_ROTATE: @@ -2800,12 +2796,74 @@ int msm_venc_set_qp_range(struct msm_vidc_inst *inst) return rc; } -int msm_venc_set_frame_quality(struct msm_vidc_inst *inst) +static void set_all_intra_preconditions(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *ctrl = NULL, *ctrl_t = NULL; + + /* Disable multi slice */ + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); + if (ctrl->val) { + dprintk(VIDC_HIGH, "Disable multi slice for all intra\n"); + ctrl->val = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; + } + + /* Disable LTR */ + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); + if (ctrl->val) { + dprintk(VIDC_HIGH, "Disable LTR for all intra\n"); + ctrl->val = 0; + } + + /* Disable Layer encoding */ + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); + ctrl_t = get_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); + if (ctrl->val || ctrl_t->val) { + dprintk(VIDC_HIGH, "Disable layer encoding for all intra\n"); + ctrl->val = 0; + ctrl_t->val = 0; + } + + /* Disable IR */ + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM); + ctrl_t = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB); + if (ctrl->val || ctrl_t->val) { + dprintk(VIDC_HIGH, "Disable IR for all intra\n"); + ctrl->val = 0; + ctrl_t->val = 0; + } + + return; +} + +static void set_heif_preconditions(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *ctrl = NULL; + + /* Reset PFrames */ + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_GOP_SIZE); + if (ctrl->val) { + dprintk(VIDC_HIGH, "Reset P-frame count for HEIF\n"); + ctrl->val = 0; + } + + /* Reset BFrames */ + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); + if (ctrl->val) { + dprintk(VIDC_HIGH, "Reset B-frame count for HEIF\n"); + ctrl->val = 0; + } + + return; +} + +int msm_venc_set_image_properties(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; struct v4l2_ctrl *ctrl; struct hfi_heic_frame_quality frame_quality; + struct hfi_heic_grid_enable grid_enable; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); @@ -2819,31 +2877,13 @@ int msm_venc_set_frame_quality(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY); frame_quality.frame_quality = ctrl->val; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, frame_quality.frame_quality); + dprintk(VIDC_HIGH, "%s: frame quality: %d\n", __func__, + frame_quality.frame_quality); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_HEIC_FRAME_QUALITY, &frame_quality, sizeof(frame_quality)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); - - return rc; -} - -int msm_venc_set_grid(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct hfi_device *hdev; - struct v4l2_ctrl *ctrl; - struct hfi_heic_grid_enable grid_enable; - - if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); - return -EINVAL; - } - hdev = inst->core->device; - - if (inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) - return 0; + dprintk(VIDC_ERR, "%s: set frame quality failed\n", __func__); ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE); @@ -2853,12 +2893,16 @@ int msm_venc_set_grid(struct msm_vidc_inst *inst) else grid_enable.grid_enable = true; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, grid_enable.grid_enable); + dprintk(VIDC_HIGH, "%s: grid enable: %d\n", __func__, + grid_enable.grid_enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_HEIC_GRID_ENABLE, &grid_enable, sizeof(grid_enable)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + dprintk(VIDC_ERR, "%s: set grid enable failed\n", __func__); + + set_all_intra_preconditions(inst); + set_heif_preconditions(inst); return rc; } @@ -4020,7 +4064,7 @@ int msm_venc_set_lossless(struct msm_vidc_inst *inst) int handle_all_intra_restrictions(struct msm_vidc_inst *inst) { - struct v4l2_ctrl *ctrl, *ctrl_t; + struct v4l2_ctrl *ctrl = NULL; u32 n_fps, fps_max; struct msm_vidc_capability *capability; struct v4l2_format *f; @@ -4071,38 +4115,7 @@ int handle_all_intra_restrictions(struct msm_vidc_inst *inst) return -ENOTSUPP; } - /* Disable multi slice */ - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); - if (ctrl->val) { - dprintk(VIDC_HIGH, "Disable multi slice for all intra\n"); - ctrl->val = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; - } - - /* Disable LTR */ - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); - if (ctrl->val) { - dprintk(VIDC_HIGH, "Disable LTR for all intra\n"); - ctrl->val = 0; - } - - /* Disable Layer encoding */ - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); - ctrl_t = get_ctrl(inst, - V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); - if (ctrl->val || ctrl_t->val) { - dprintk(VIDC_HIGH, "Disable layer encoding for all intra\n"); - ctrl->val = 0; - ctrl_t->val = 0; - } - - /* Disable IR */ - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM); - ctrl_t = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB); - if (ctrl->val || ctrl_t->val) { - dprintk(VIDC_HIGH, "Disable IR for all intra\n"); - ctrl->val = 0; - ctrl_t->val = 0; - } + set_all_intra_preconditions(inst); return 0; } @@ -4162,10 +4175,7 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) rc = msm_venc_set_qp_range(inst); if (rc) goto exit; - rc = msm_venc_set_frame_quality(inst); - if (rc) - goto exit; - rc = msm_venc_set_grid(inst); + rc = msm_venc_set_image_properties(inst); if (rc) goto exit; rc = msm_venc_set_au_delimiter_mode(inst); diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 99105eb9fc5f..088894140e43 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -826,15 +826,6 @@ static inline int start_streaming(struct msm_vidc_inst *inst) is_secondary_output_mode(inst)) b.buffer_type = HFI_BUFFER_OUTPUT2; - /* HEIC HW/FWK tiling encode is supported only for CQ RC mode */ - if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) { - if (!heic_encode_session_supported(inst)) { - dprintk(VIDC_ERR, - "HEIC Encode session not supported\n"); - return -ENOTSUPP; - } - } - /* Check if current session is under HW capability */ rc = msm_vidc_check_session_supported(inst); if (rc) { @@ -1440,9 +1431,6 @@ static int try_get_ctrl_for_instance(struct msm_vidc_inst *inst, V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, inst->profile); break; - case V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE: - ctrl->val = inst->grid_enable; - break; case V4L2_CID_MPEG_VIDEO_H264_LEVEL: ctrl->val = msm_comm_hfi_to_v4l2( V4L2_CID_MPEG_VIDEO_H264_LEVEL, diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index ab6b96871e55..5b7a9688d102 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1069,8 +1069,7 @@ int msm_dcvs_try_enable(struct msm_vidc_inst *inst) inst->flags & VIDC_THUMBNAIL || inst->clk_data.low_latency_mode || inst->batch.enable || - inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ || - inst->grid_enable) { + inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) { dprintk(VIDC_HIGH, "DCVS disabled: %pK\n", inst); inst->clk_data.dcvs_mode = false; return false; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 307852e4327f..b9374abe24f6 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2387,48 +2387,6 @@ int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst, return 0; } -bool heic_encode_session_supported(struct msm_vidc_inst *inst) -{ - u32 slice_mode; - u32 idr_period = IDR_PERIOD; - u32 n_bframes; - u32 n_pframes; - struct v4l2_format *f; - - slice_mode = msm_comm_g_ctrl_for_id(inst, - V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); - n_bframes = msm_comm_g_ctrl_for_id(inst, - V4L2_CID_MPEG_VIDEO_B_FRAMES); - n_pframes = msm_comm_g_ctrl_for_id(inst, - V4L2_CID_MPEG_VIDEO_GOP_SIZE); - - /* - * HEIC Encode is supported for Constant Quality RC mode only. - * All configurations below except grid_enable are required for any - * HEIC session including FWK tiled HEIC encode. - * grid_enable flag along with dimension check enables HW tiling. - */ - f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; - if (inst->session_type == MSM_VIDC_ENCODER && - get_hal_codec(f->fmt.pix_mp.pixelformat) == - HAL_VIDEO_CODEC_HEVC && - inst->frame_quality >= MIN_FRAME_QUALITY && - inst->frame_quality <= MAX_FRAME_QUALITY && - slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE && - idr_period == 1 && - n_bframes == 0 && - n_pframes == 0) { - if (inst->grid_enable > 0) { - if (f->fmt.pix_mp.width < HEIC_GRID_DIMENSION || - f->fmt.pix_mp.height < HEIC_GRID_DIMENSION) - return false; - } - return true; - } else { - return false; - } -} - static bool is_eos_buffer(struct msm_vidc_inst *inst, u32 device_addr) { struct eos_buf *temp, *next; @@ -5585,6 +5543,9 @@ static int msm_vidc_check_mbpf_supported(struct msm_vidc_inst *inst) /* ignore thumbnail session */ if (is_thumbnail_session(temp)) continue; + /* ignore HEIF sessions */ + if (is_image_session(temp)) + continue; mbpf += NUM_MBS_PER_FRAME( temp->fmts[INPUT_PORT].v4l2_fmt.fmt.pix_mp.height, temp->fmts[INPUT_PORT].v4l2_fmt.fmt.pix_mp.width); @@ -5629,10 +5590,15 @@ int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst) u32 x_min, x_max, y_min, y_max; u32 input_height, input_width, output_height, output_width; struct v4l2_format *f; + struct v4l2_ctrl *ctrl = NULL; - if (inst->grid_enable > 0) { - dprintk(VIDC_HIGH, "Skip scaling check for HEIC\n"); - return 0; + /* Grid get_ctrl allowed for encode session only */ + if (is_image_session(inst)) { + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE); + if (ctrl->val > 0) { + dprintk(VIDC_HIGH, "Skip scaling check for HEIC\n"); + return 0; + } } f = &inst->fmts[INPUT_PORT].v4l2_fmt; @@ -5719,6 +5685,7 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) u32 width_min, width_max, height_min, height_max; u32 mbpf_max; struct v4l2_format *f; + struct v4l2_ctrl *ctrl = NULL; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, "%s: Invalid parameter\n", __func__); @@ -5774,6 +5741,48 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) input_height = f->fmt.pix_mp.height; input_width = f->fmt.pix_mp.width; + if (is_image_session(inst)) { + if (is_secure_session(inst)) { + dprintk(VIDC_ERR, + "Secure image encode isn't supported!\n"); + return -ENOTSUPP; + } + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE); + if (ctrl->val > 0) { + if (inst->fmts[INPUT_PORT].v4l2_fmt.fmt.pix_mp.pixelformat != + V4L2_PIX_FMT_NV12 && + inst->fmts[INPUT_PORT].v4l2_fmt.fmt.pix_mp.pixelformat != + V4L2_PIX_FMT_NV12_512) + return -ENOTSUPP; + + width_min = + capability->cap[CAP_HEIC_IMAGE_FRAME_WIDTH].min; + width_max = + capability->cap[CAP_HEIC_IMAGE_FRAME_WIDTH].max; + height_min = + capability->cap[CAP_HEIC_IMAGE_FRAME_HEIGHT].min; + height_max = + capability->cap[CAP_HEIC_IMAGE_FRAME_HEIGHT].max; + mbpf_max = capability->cap[CAP_MBS_PER_FRAME].max; + + input_height = ALIGN(input_height, 512); + input_width = ALIGN(input_width, 512); + output_height = input_height; + output_width = input_width; + } else { + width_min = + capability->cap[CAP_HEVC_IMAGE_FRAME_WIDTH].min; + width_max = + capability->cap[CAP_HEVC_IMAGE_FRAME_WIDTH].max; + height_min = + capability->cap[CAP_HEVC_IMAGE_FRAME_HEIGHT].min; + height_max = + capability->cap[CAP_HEVC_IMAGE_FRAME_HEIGHT].max; + mbpf_max = capability->cap[CAP_MBS_PER_FRAME].max; + } + } + if (inst->session_type == MSM_VIDC_ENCODER && (input_width % 2 != 0 || input_height % 2 != 0 || output_width % 2 != 0 || output_height % 2 != 0)) { diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index a91208c1ed42..29b2348563e0 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -84,6 +84,14 @@ static inline u32 get_v4l2_codec(struct msm_vidc_inst *inst) return f->fmt.pix_mp.pixelformat; } +static inline bool is_image_session(struct msm_vidc_inst *inst) +{ + /* Grid may or may not be enabled for an image encode session */ + return inst->session_type == MSM_VIDC_ENCODER && + get_v4l2_codec(inst) == V4L2_PIX_FMT_HEVC && + inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ; +} + static inline bool is_realtime_session(struct msm_vidc_inst *inst) { return !!(inst->flags & VIDC_REALTIME); diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 668eec7531a8..b0d9610849c7 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -520,8 +520,6 @@ struct msm_vidc_inst { u32 colour_space; u32 profile; u32 level; - u32 grid_enable; - u32 frame_quality; u32 rc_type; u32 hybrid_hp; u32 layer_bitrate; @@ -560,7 +558,6 @@ void handle_cmd_response(enum hal_command_response cmd, void *data); int msm_vidc_trigger_ssr(struct msm_vidc_core *core, enum hal_ssr_trigger_type type); int msm_vidc_noc_error_info(struct msm_vidc_core *core); -bool heic_encode_session_supported(struct msm_vidc_inst *inst); int msm_vidc_check_session_supported(struct msm_vidc_inst *inst); int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst); void msm_vidc_queue_v4l2_event(struct msm_vidc_inst *inst, int event_type); diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 316950a01e80..4dd91f205b5e 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -359,6 +359,12 @@ static struct msm_vidc_codec_capability kona_capabilities[] = { /* All intra encoding usecase specific */ {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 240, 1, 30}, + + /* Image specific */ + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 1, 8192}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192}, }; /* diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 950439c026ee..ba21bbdeecc0 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -284,6 +284,10 @@ enum hal_capability { CAP_LOSSLESS_FRAME_HEIGHT, CAP_LOSSLESS_MBS_PER_FRAME, CAP_ALLINTRA_MAX_FPS, + CAP_HEVC_IMAGE_FRAME_WIDTH, + CAP_HEVC_IMAGE_FRAME_HEIGHT, + CAP_HEIC_IMAGE_FRAME_WIDTH, + CAP_HEIC_IMAGE_FRAME_HEIGHT, CAP_MAX, }; From 1af4075b33f810851ba4b0f0505313af99eb4aa2 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Mon, 29 Jul 2019 12:45:50 -0700 Subject: [PATCH 114/452] msm: vidc: adding support of driver editable control values using volatile flags in v4l2 control Due to various feature constraint and best effort encode/decode, driver needs to update client updated or default control value.Later these driver updated values are used in programming video firmware. Hence, we need various controls as volatile Change-Id: Ied22665addda921b0ef4827fb7a2b1fd47be5bbb Signed-off-by: Darshana Patil --- msm/vidc/msm_venc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 31d22f164b9e..61d82f07860f 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -95,6 +95,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = 2*DEFAULT_FPS-1, .step = 1, .qmenu = NULL, + .flags = V4L2_CTRL_FLAG_VOLATILE, }, { .id = V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP, @@ -155,6 +156,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = 0, .step = 1, .qmenu = NULL, + .flags = V4L2_CTRL_FLAG_VOLATILE, }, { .id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, @@ -545,6 +547,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = 0, .step = 1, .qmenu = NULL, + .flags = V4L2_CTRL_FLAG_VOLATILE, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME, @@ -576,6 +579,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { V4L2_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER_0, .step = 1, .menu_skip_mask = 0, + .flags = V4L2_CTRL_FLAG_VOLATILE, }, { .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE, From a7967f7038381dc3355b44fd94a84be785231627 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Wed, 24 Jul 2019 12:04:20 -0700 Subject: [PATCH 115/452] msm: venc: Set LTR info only when LTR is enabled Set LTR use mask and mark index information to firmware only when LTR count is non zero. Change-Id: Icdcd0e8e29841e0cf4d2222ad3c2331aed2e3968 Signed-off-by: Darshana Patil --- msm/vidc/msm_venc.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 31d22f164b9e..ce1be2ceb161 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3726,6 +3726,7 @@ int msm_venc_set_nal_stream_format(struct msm_vidc_inst *inst) int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) { int rc = 0; + bool is_ltr = true; struct hfi_device *hdev; struct v4l2_ctrl *ctrl; struct hfi_ltr_mode ltr; @@ -3738,13 +3739,17 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) hdev = inst->core->device; codec = get_v4l2_codec(inst); - if (!(codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264)) - return 0; + if (!(codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264)) { + is_ltr = false; + goto disable_ltr; + } if (!(inst->rc_type == RATE_CONTROL_OFF || inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR || - inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR)) - return 0; + inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR)) { + is_ltr = false; + goto disable_ltr; + } ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); if (!ctrl->val) @@ -3765,6 +3770,15 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) if (rc) dprintk(VIDC_ERR, "%s: set property failed\n", __func__); +disable_ltr: + /* + * Forcefully setting LTR count to zero when + * client sets unsupported codec/rate control. + */ + if (!is_ltr) { + ctrl->val = 0; + dprintk(VIDC_HIGH, "LTR is forcefully disabled!\n"); + } return rc; } @@ -3782,6 +3796,10 @@ int msm_venc_set_ltr_useframe(struct msm_vidc_inst *inst) } hdev = inst->core->device; + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); + if (!ctrl->val) + return 0; + codec = get_v4l2_codec(inst); if (!(codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264)) return 0; @@ -3814,6 +3832,10 @@ int msm_venc_set_ltr_markframe(struct msm_vidc_inst *inst) } hdev = inst->core->device; + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); + if (!ctrl->val) + return 0; + codec = get_v4l2_codec(inst); if (!(codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264)) return 0; From 6d95875992904bb62b76c1910113f7d484993857 Mon Sep 17 00:00:00 2001 From: Amit Shekhar Date: Mon, 29 Jul 2019 16:10:14 -0700 Subject: [PATCH 116/452] Revert "msm: vidc: Fix work mode for rate control CQ" Set default double stage work-mode for HEIC sessions. This reverts commit 10eb14941d00201d8c88b85e5148550b604a14f8. Change-Id: I347e3af101ef236ba18687a5672f3bca6b49d257 Signed-off-by: Amit Shekhar --- msm/vidc/msm_vidc_clocks.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 5b7a9688d102..cd74adb7690f 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1520,10 +1520,6 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) /* For WORK_MODE_1, set Low Latency mode by default */ latency.enable = true; } - if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) { - pdata.video_work_mode = HFI_WORKMODE_1; - latency.enable = true; - } if (inst->rc_type == RATE_CONTROL_LOSSLESS || inst->all_intra) { pdata.video_work_mode = HFI_WORKMODE_2; latency.enable = false; From 15f3510a38ecef126e8fa81094887198350aeeb5 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Thu, 25 Jul 2019 23:49:12 +0800 Subject: [PATCH 117/452] msm: vidc: Add window based bitrate check in decoder In decoder, window based bitrate check will help identify usecases where, input bitrate exceeds hw capabilities. CRs-Fixed: 2497423 Change-Id: Ic68bd66584ed84382ba03777d39775d08278a8a0 Signed-off-by: Qiwei Liu Signed-off-by: Chinmay Sawarkar --- msm/vidc/hfi_common.c | 2 +- msm/vidc/hfi_response_handler.c | 14 +++-- msm/vidc/msm_vidc.c | 7 ++- msm/vidc/msm_vidc_clocks.c | 3 +- msm/vidc/msm_vidc_common.c | 100 ++++++++++++++++++++++++++++++-- msm/vidc/msm_vidc_common.h | 6 ++ msm/vidc/msm_vidc_debug.h | 1 + msm/vidc/msm_vidc_internal.h | 8 +++ msm/vidc/msm_vidc_platform.c | 4 ++ msm/vidc/msm_vidc_res_parse.c | 2 + msm/vidc/msm_vidc_resources.h | 1 + 11 files changed, 134 insertions(+), 14 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index b9548a914f6c..5b6beb3fe538 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -2387,7 +2387,7 @@ static int venus_hfi_session_init(void *device, void *session_id, s->device = dev; s->codec = codec_type; s->domain = session_type; - dprintk(VIDC_HIGH, + dprintk(VIDC_HIGH|VIDC_PERF, "%s: inst %pK, session %pK, codec 0x%x, domain 0x%x\n", __func__, session_id, s, s->codec, s->domain); diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index b6bef94a5e11..63c25b35d5ea 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -158,7 +158,8 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, (struct hfi_frame_size *) data_ptr; event_notify.width = frame_sz->width; event_notify.height = frame_sz->height; - dprintk(VIDC_HIGH, "height: %d width: %d\n", + dprintk(VIDC_HIGH|VIDC_PERF, + "height: %d width: %d\n", frame_sz->height, frame_sz->width); data_ptr += sizeof(struct hfi_frame_size); @@ -173,7 +174,8 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, (struct hfi_profile_level *) data_ptr; event_notify.profile = profile_level->profile; event_notify.level = profile_level->level; - dprintk(VIDC_HIGH, "profile: %d level: %d\n", + dprintk(VIDC_HIGH|VIDC_PERF, + "profile: %d level: %d\n", profile_level->profile, profile_level->level); data_ptr += @@ -209,7 +211,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, MSM_VIDC_BIT_DEPTH_10; else event_notify.bit_depth = luma_bit_depth; - dprintk(VIDC_HIGH, + dprintk(VIDC_HIGH|VIDC_PERF, "bitdepth(%d), luma_bit_depth(%d), chroma_bit_depth(%d)\n", event_notify.bit_depth, luma_bit_depth, chroma_bit_depth); @@ -224,7 +226,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, pic_struct = (struct hfi_pic_struct *) data_ptr; event_notify.pic_struct = pic_struct->progressive_only; - dprintk(VIDC_HIGH, + dprintk(VIDC_HIGH|VIDC_PERF, "Progressive only flag: %d\n", pic_struct->progressive_only); data_ptr += @@ -253,7 +255,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, data_ptr = data_ptr + sizeof(u32); entropy_mode = *(u32 *)data_ptr; event_notify.entropy_mode = entropy_mode; - dprintk(VIDC_HIGH, + dprintk(VIDC_HIGH|VIDC_PERF, "Entropy Mode: 0x%x\n", entropy_mode); data_ptr += sizeof(u32); @@ -269,7 +271,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, data_ptr; event_notify.capture_buf_count = buf_req->buffer_count_min; - dprintk(VIDC_HIGH, + dprintk(VIDC_HIGH|VIDC_PERF, "Capture Count : 0x%x\n", event_notify.capture_buf_count); data_ptr += diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 088894140e43..343d6c83db4c 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -920,7 +920,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) */ if (inst->batch.enable) inst->batch.enable = is_batching_allowed(inst); - dprintk(VIDC_HIGH, "%s: batching %s for inst %pK (%#x)\n", + dprintk(VIDC_HIGH|VIDC_PERF, "%s: batching %s for inst %pK (%#x)\n", __func__, inst->batch.enable ? "enabled" : "disabled", inst, hash32_ptr(inst->session)); @@ -1524,6 +1524,7 @@ void *msm_vidc_open(int core_id, int session_type) INIT_MSM_VIDC_LIST(&inst->eosbufs); INIT_MSM_VIDC_LIST(&inst->etb_data); INIT_MSM_VIDC_LIST(&inst->fbd_data); + INIT_MSM_VIDC_LIST(&inst->window_data); INIT_DELAYED_WORK(&inst->batch_work, msm_vidc_batch_handler); kref_init(&inst->kref); @@ -1638,6 +1639,7 @@ void *msm_vidc_open(int core_id, int session_type) DEINIT_MSM_VIDC_LIST(&inst->input_crs); DEINIT_MSM_VIDC_LIST(&inst->etb_data); DEINIT_MSM_VIDC_LIST(&inst->fbd_data); + DEINIT_MSM_VIDC_LIST(&inst->window_data); kfree(inst); inst = NULL; @@ -1709,6 +1711,8 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst) dprintk(VIDC_ERR, "Failed to release mark_data buffers\n"); + msm_comm_release_window_data(inst); + msm_comm_release_eos_buffers(inst); if (msm_comm_release_dpb_only_buffers(inst, true)) @@ -1769,6 +1773,7 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) DEINIT_MSM_VIDC_LIST(&inst->input_crs); DEINIT_MSM_VIDC_LIST(&inst->etb_data); DEINIT_MSM_VIDC_LIST(&inst->fbd_data); + DEINIT_MSM_VIDC_LIST(&inst->window_data); mutex_destroy(&inst->sync_lock); mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 5b7a9688d102..062116a1e039 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1780,7 +1780,7 @@ void msm_print_core_status(struct msm_vidc_core *core, u32 core_id) out_f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; inp_f = &inst->fmts[INPUT_PORT].v4l2_fmt; dprintk(VIDC_PERF, - "inst %pK (%4ux%4u) to (%4ux%4u) %3u %s %s %s %s %lu\n", + "inst %pK (%4ux%4u) to (%4ux%4u) %3u %s %s %u %s %s %lu\n", inst, inp_f->fmt.pix_mp.width, inp_f->fmt.pix_mp.height, @@ -1790,6 +1790,7 @@ void msm_print_core_status(struct msm_vidc_core *core, u32 core_id) inst->session_type == MSM_VIDC_ENCODER ? "ENC" : "DEC", inst->clk_data.work_mode == HFI_WORKMODE_1 ? "WORK_MODE_1" : "WORK_MODE_2", + inst->clk_data.work_route, inst->flags & VIDC_LOW_POWER ? "LP" : "HQ", inst->flags & VIDC_REALTIME ? "RealTime" : "NonRTime", inst->clk_data.min_freq); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index b9374abe24f6..56e56f1aff26 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1729,6 +1729,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data) inst->profile = event_notify->profile; inst->level = event_notify->level; + inst->entropy_mode = event_notify->entropy_mode; inst->prop.crop_info.left = event_notify->crop_data.left; inst->prop.crop_info.top = @@ -1795,7 +1796,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data) /* decide batching as configuration changed */ if (inst->batch.enable) inst->batch.enable = is_batching_allowed(inst); - dprintk(VIDC_HIGH, "%s: %x : batching %s\n", + dprintk(VIDC_HIGH|VIDC_PERF, "%s: %x : batching %s\n", __func__, hash32_ptr(inst->session), inst->batch.enable ? "enabled" : "disabled"); @@ -2095,6 +2096,9 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) goto exit; } + if (flush_type == HAL_FLUSH_ALL) + msm_comm_release_window_data(inst); + dprintk(VIDC_HIGH, "Notify flush complete, flush_type: %x\n", flush_type); v4l2_event_queue_fh(&inst->event_handler, &flush_event); @@ -4306,6 +4310,10 @@ static int msm_comm_qbuf_to_hfi(struct msm_vidc_inst *inst, mbuf->flags |= MSM_VIDC_FLAG_QUEUED; msm_vidc_debugfs_update(inst, e); + if (mbuf->vvb.vb2_buf.type == INPUT_MPLANE && + is_decode_session(inst)) + rc = msm_comm_check_window_bitrate(inst, &frame_data); + err_bad_input: return rc; } @@ -4450,7 +4458,7 @@ static int msm_comm_qbuf_in_rbr(struct msm_vidc_inst *inst, if (rc) dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__); - print_vidc_buffer(VIDC_HIGH, "qbuf in rbr", inst, mbuf); + print_vidc_buffer(VIDC_HIGH|VIDC_PERF, "qbuf in rbr", inst, mbuf); rc = msm_comm_qbuf_to_hfi(inst, mbuf); if (rc) dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", __func__, rc); @@ -4487,7 +4495,7 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) if (rc) dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__); - print_vidc_buffer(VIDC_HIGH, "qbuf", inst, mbuf); + print_vidc_buffer(VIDC_HIGH|VIDC_PERF, "qbuf", inst, mbuf); ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); if (ctrl->val) rc = msm_comm_qbuf_superframe_to_hfi(inst, mbuf); @@ -4572,7 +4580,7 @@ int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, if (buf->flags & MSM_VIDC_FLAG_RBR_PENDING) goto loop_end; - print_vidc_buffer(VIDC_HIGH, "batch-qbuf", inst, buf); + print_vidc_buffer(VIDC_HIGH|VIDC_PERF, "batch-qbuf", inst, buf); rc = msm_comm_qbuf_to_hfi(inst, buf); if (rc) { dprintk(VIDC_ERR, "%s: Failed batch qbuf to hfi: %d\n", @@ -4614,7 +4622,8 @@ int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst, if (inst->state != MSM_VIDC_START_DONE) { mbuf->flags |= MSM_VIDC_FLAG_DEFERRED; - print_vidc_buffer(VIDC_HIGH, "qbuf deferred", inst, mbuf); + print_vidc_buffer(VIDC_HIGH|VIDC_PERF, + "qbuf deferred", inst, mbuf); return 0; } @@ -6170,6 +6179,10 @@ void print_vb2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, { if (!(tag & msm_vidc_debug) || !inst || !vb2) return; + if ((tag & VIDC_PERF) && + !(tag & VIDC_HIGH) && + (inst->session_type != MSM_VIDC_DECODER)) + return; if (vb2->num_planes == 1) dprintk(tag, @@ -7195,3 +7208,80 @@ bool msm_comm_check_for_inst_overload(struct msm_vidc_core *core) } return overload; } + +int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, + struct vidc_frame_data *frame_data) +{ + struct msm_vidc_window_data *pdata, *next; + u32 bitrate, max_br, window_size; + int buf_cnt = 1, fps, window_start; + + if (!inst || !inst->core || !frame_data) { + dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + return -EINVAL; + } + + if (!inst->core->resources.avsync_window_size) + return 0; + + fps = inst->clk_data.frame_rate >> 16; + max_br = MAX_BITRATE_DECODER_CAVLC; + if (inst->entropy_mode == HFI_H264_ENTROPY_CABAC) + max_br = inst->clk_data.work_mode == HFI_WORKMODE_2 ? + MAX_BITRATE_DECODER_2STAGE_CABAC : + MAX_BITRATE_DECODER_1STAGE_CABAC; + window_size = inst->core->resources.avsync_window_size * fps; + window_size = DIV_ROUND_UP(window_size, 1000); + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + dprintk(VIDC_ERR, "%s: malloc failure.\n", __func__); + return -ENOMEM; + } + + bitrate = pdata->frame_size = frame_data->filled_len; + window_start = pdata->etb_count = inst->count.etb; + + mutex_lock(&inst->window_data.lock); + list_add(&pdata->list, &inst->window_data.list); + list_for_each_entry_safe_continue(pdata, next, + &inst->window_data.list, list) { + if (buf_cnt < window_size) { + bitrate += pdata->frame_size; + window_start = pdata->etb_count; + buf_cnt++; + } else { + list_del(&pdata->list); + kfree(pdata); + } + } + mutex_unlock(&inst->window_data.lock); + + bitrate = DIV_ROUND_UP(((u64)bitrate * 8 * fps), window_size); + if (bitrate > max_br) { + dprintk(VIDC_PERF, + "Unsupported bitrate %u max %u, window size %u [%u,%u]", + bitrate, max_br, window_size, + window_start, inst->count.etb); + } + + return 0; +} + +void msm_comm_release_window_data(struct msm_vidc_inst *inst) +{ + struct msm_vidc_window_data *pdata, *next; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params %pK\n", + __func__, inst); + return; + } + + mutex_lock(&inst->window_data.lock); + list_for_each_entry_safe(pdata, next, &inst->window_data.list, list) { + list_del(&pdata->list); + kfree(pdata); + } + mutex_unlock(&inst->window_data.lock); +} diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 29b2348563e0..f9c4b4a910b5 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -18,6 +18,9 @@ #define CBR_MB_LIMIT (((1280+15)/16)*((720+15)/16)*30) #define CBR_VFR_MB_LIMIT (((640+15)/16)*((480+15)/16)*30) #define V4L2_CID_MPEG_VIDEO_UNKNOWN (V4L2_CID_MPEG_MSM_VIDC_BASE + 0xFFF) +#define MAX_BITRATE_DECODER_CAVLC 220000000 +#define MAX_BITRATE_DECODER_2STAGE_CABAC 200000000 +#define MAX_BITRATE_DECODER_1STAGE_CABAC 70000000 struct vb2_buf_entry { struct list_head list; @@ -307,4 +310,7 @@ int msm_comm_set_extradata(struct msm_vidc_inst *inst, uint32_t extradata_id, uint32_t value); bool msm_comm_check_for_inst_overload(struct msm_vidc_core *core); void msm_vidc_batch_handler(struct work_struct *work); +int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, + struct vidc_frame_data *frame_data); +void msm_comm_release_window_data(struct msm_vidc_inst *inst); #endif diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index 976bc2056258..a28151c2c430 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -137,6 +137,7 @@ static inline char *get_debug_level_str(int level) switch (level) { case VIDC_ERR: return "err"; + case VIDC_HIGH|VIDC_PERF: case VIDC_HIGH: return "high"; case VIDC_LOW: diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index b0d9610849c7..d36af351b747 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -206,6 +206,12 @@ struct msm_vidc_buf_data { u32 filled_length; }; +struct msm_vidc_window_data { + struct list_head list; + u32 frame_size; + u32 etb_count; +}; + struct msm_vidc_common_data { char key[128]; int value; @@ -493,6 +499,7 @@ struct msm_vidc_inst { struct msm_vidc_list cvpbufs; struct msm_vidc_list etb_data; struct msm_vidc_list fbd_data; + struct msm_vidc_list window_data; struct buffer_requirements buff_req; struct vidc_frame_data superframe_data[VIDC_SUPERFRAME_MAX]; struct v4l2_ctrl_handler ctrl_handler; @@ -520,6 +527,7 @@ struct msm_vidc_inst { u32 colour_space; u32 profile; u32 level; + u32 entropy_mode; u32 rc_type; u32 hybrid_hp; u32 layer_bitrate; diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 4dd91f205b5e..a1ea7062e77e 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -627,6 +627,10 @@ static struct msm_vidc_common_data kona_common_data[] = { .key = "qcom,fw-vpp-cycles", .value = 44156, }, + { + .key = "qcom,avsync-window-size", + .value = 40, + }, }; static struct msm_vidc_common_data sm6150_common_data[] = { diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index d2d66bb60291..067637053422 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -835,6 +835,8 @@ int read_platform_resources_from_drv_data( "qcom,fw-cycles"); res->fw_vpp_cycles = find_key_value(platform_data, "qcom,fw-vpp-cycles"); + res->avsync_window_size = find_key_value(platform_data, + "qcom,avsync-window-size"); res->csc_coeff_data = &platform_data->csc_data; diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 76b5b8d206bd..7c5619de22dc 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -208,6 +208,7 @@ struct msm_vidc_platform_resources { uint32_t vpu_ver; uint32_t fw_cycles; uint32_t fw_vpp_cycles; + uint32_t avsync_window_size; struct msm_vidc_ubwc_config_data *ubwc_config; uint32_t clk_freq_threshold; struct cx_ipeak_client *cx_ipeak_context; From 353089d3bed58c0d54530295b0f200232bd32611 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Tue, 30 Jul 2019 17:07:24 -0700 Subject: [PATCH 118/452] msm: venc: fix ltrmode for unsupported codec/RC type Do a get control before accessing the control value to make sure right structure is accessed. Change-Id: Iabf2ca85c342fe46d2236232794bbe9b9981fb18 Signed-off-by: Darshana Patil --- msm/vidc/msm_venc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index f66fe9e60de4..3d70c18b8e71 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3741,6 +3741,7 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) return -EINVAL; } hdev = inst->core->device; + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); codec = get_v4l2_codec(inst); if (!(codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264)) { @@ -3755,7 +3756,6 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) goto disable_ltr; } - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); if (!ctrl->val) return 0; if (ctrl->val > inst->capability.cap[CAP_LTR_COUNT].max) { From bd8775b802c6080d3714b2f754ffb3de0d6b3865 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Tue, 30 Jul 2019 18:45:10 -0700 Subject: [PATCH 119/452] msm: vidc: remove volatile flag for certain controls Reverting the volatile flag added to GOP size, bframe and max hier layer controls. Change-Id: I3f74bc59e7a73882ff1ce95832b8f248a8ddb80e Signed-off-by: Darshana Patil --- msm/vidc/msm_venc.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index f66fe9e60de4..895ae01064f3 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -95,7 +95,6 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = 2*DEFAULT_FPS-1, .step = 1, .qmenu = NULL, - .flags = V4L2_CTRL_FLAG_VOLATILE, }, { .id = V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP, @@ -156,7 +155,6 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = 0, .step = 1, .qmenu = NULL, - .flags = V4L2_CTRL_FLAG_VOLATILE, }, { .id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, @@ -579,7 +577,6 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { V4L2_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER_0, .step = 1, .menu_skip_mask = 0, - .flags = V4L2_CTRL_FLAG_VOLATILE, }, { .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE, From e047e8e387f138a363d90860372dbf9983835e9b Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Wed, 31 Jul 2019 15:10:20 -0700 Subject: [PATCH 120/452] msm: venc: remove volatile flag from LTR control Remove volatile flag associated with LTR control. Change-Id: I86c7fdb8b50adecf84d97145fad406f0e23002df Signed-off-by: Darshana Patil --- msm/vidc/msm_venc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 47810d6a6216..c5c9cd4adc86 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -545,7 +545,6 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = 0, .step = 1, .qmenu = NULL, - .flags = V4L2_CTRL_FLAG_VOLATILE, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME, From a6e8541864a6b490fa69c3816a9813cd8aa9397f Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 31 Jul 2019 20:17:08 +0530 Subject: [PATCH 121/452] msm: vidc: add check to ensure buffer size is 4K aligned Input and output buffer size must be 4K aligned for both encoder and decoder session. So reject the session during msm_vidc_qbuf, if alloc_len is not 4K aligned. Change-Id: If555f26f1658ce50e12a8533cb9d59134da0aa81 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 343d6c83db4c..77eef75ef2ae 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -340,6 +340,12 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) return -EINVAL; } + if (!IS_ALIGNED(b->m.planes[0].length, SZ_4K)) { + dprintk(VIDC_ERR, "qbuf: %x: buffer size not 4K aligned - %u\n", + hash32_ptr(inst->session), b->m.planes[0].length); + return -EINVAL; + } + if (inst->in_flush && is_decode_session(inst) && b->type == OUTPUT_MPLANE) { dprintk(VIDC_ERR, "%s: in flush, discarding qbuf\n", __func__); From 37de0e68d4c8ecedb942d4f215a03fa76f4be930 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Fri, 2 Aug 2019 22:34:15 +0800 Subject: [PATCH 122/452] msm: vidc: avoid repeatedly set the same freq If requested clk_freq is not changed, don't call clk driver to the same value repeatedly. Change-Id: I7ff1d7faedb10b06c0371f66b4a6cf6592d165fe Signed-off-by: Qiwei Liu --- msm/vidc/hfi_common.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 5b6beb3fe538..429ea53534d5 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -1326,6 +1326,10 @@ static int __set_clocks(struct venus_hfi_device *device, u32 freq) struct clock_info *cl; int rc = 0; + /* bail early if requested clk_freq is not changed */ + if (freq == device->clk_freq) + return 0; + venus_hfi_for_each_clock(device, cl) { if (cl->has_scaling) {/* has_scaling */ rc = __set_clk_rate(device, cl, freq); From 02f5b95ce6ebfac7b0e8a9bfd7628de3c5b1f127 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 30 Jul 2019 22:03:26 -0700 Subject: [PATCH 123/452] msm: vidc: Do not vote bw on ftb Parameter that affect BW change during ETB and EBD. During FTB BW calculation and voting is redundant. Change-Id: I418d422f614670c2543a19709b36b3f39fd0d0e1 Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc.c | 6 +++--- msm/vidc/msm_vidc_clocks.c | 19 +++++++++++-------- msm/vidc/msm_vidc_clocks.h | 2 +- msm/vidc/msm_vidc_common.c | 20 ++++++++++++-------- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 343d6c83db4c..db2e2b98c74d 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -940,7 +940,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) if (rc) goto fail_start; - msm_comm_scale_clocks_and_bus(inst); + msm_comm_scale_clocks_and_bus(inst, 1); rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE); if (rc) { @@ -1132,7 +1132,7 @@ static void msm_vidc_stop_streaming(struct vb2_queue *q) break; } - msm_comm_scale_clocks_and_bus(inst); + msm_comm_scale_clocks_and_bus(inst, 1); if (rc) dprintk(VIDC_ERR, @@ -1595,7 +1595,7 @@ void *msm_vidc_open(int core_id, int session_type) goto fail_init; } - msm_comm_scale_clocks_and_bus(inst); + msm_comm_scale_clocks_and_bus(inst, 1); inst->debugfs_root = msm_vidc_debugfs_init_inst(inst, core->debugfs_root); diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 062116a1e039..2a8f1a2acfbf 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1034,7 +1034,7 @@ int msm_comm_scale_clocks(struct msm_vidc_inst *inst) return 0; } -int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst) +int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc) { struct msm_vidc_core *core; struct hfi_device *hdev; @@ -1048,11 +1048,14 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst) if (msm_comm_scale_clocks(inst)) { dprintk(VIDC_ERR, - "Failed to scale clocks. Performance might be impacted\n"); + "Failed to scale clocks. May impact performance\n"); } - if (msm_comm_vote_bus(core)) { - dprintk(VIDC_ERR, - "Failed to scale DDR bus. Performance might be impacted\n"); + + if (do_bw_calc) { + if (msm_comm_vote_bus(core)) { + dprintk(VIDC_ERR, + "Failed to scale DDR bus. May impact perf\n"); + } } return 0; } @@ -1185,7 +1188,7 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) msm_dcvs_print_dcvs_stats(dcvs); - rc = msm_comm_scale_clocks_and_bus(inst); + rc = msm_comm_scale_clocks_and_bus(inst, 1); if (rc) dprintk(VIDC_ERR, "%s Failed to scale Clocks and Bus\n", @@ -1390,7 +1393,7 @@ static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst) (void *)&latency, sizeof(latency)); } - rc = msm_comm_scale_clocks_and_bus(inst); + rc = msm_comm_scale_clocks_and_bus(inst, 1); return rc; } @@ -1723,7 +1726,7 @@ int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) } inst->clk_data.core_id = VIDC_CORE_ID_1; - rc = msm_comm_scale_clocks_and_bus(inst); + rc = msm_comm_scale_clocks_and_bus(inst, 1); msm_print_core_status(core, VIDC_CORE_ID_1); return rc; } diff --git a/msm/vidc/msm_vidc_clocks.h b/msm/vidc/msm_vidc_clocks.h index d3bc4ae9dc34..4872cdaa8754 100644 --- a/msm/vidc/msm_vidc_clocks.h +++ b/msm/vidc/msm_vidc_clocks.h @@ -19,7 +19,7 @@ bool res_is_greater_than_or_equal_to(u32 width, u32 height, u32 ref_width, u32 ref_height); int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst); int msm_vidc_get_fps(struct msm_vidc_inst *inst); -int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst); +int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc); int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst); void msm_comm_free_freq_table(struct msm_vidc_inst *inst); int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 56e56f1aff26..cee0f4c83d2b 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -3052,7 +3052,7 @@ static int msm_comm_init_core(struct msm_vidc_inst *inst) change_inst_state(inst, MSM_VIDC_CORE_INIT); mutex_unlock(&core->lock); - rc = msm_comm_scale_clocks_and_bus(inst); + rc = msm_comm_scale_clocks_and_bus(inst, 1); return rc; fail_core_init: @@ -3082,7 +3082,7 @@ static int msm_vidc_deinit_core(struct msm_vidc_inst *inst) } mutex_unlock(&core->lock); - msm_comm_scale_clocks_and_bus(inst); + msm_comm_scale_clocks_and_bus(inst, 1); mutex_lock(&core->lock); @@ -4454,9 +4454,9 @@ static int msm_comm_qbuf_in_rbr(struct msm_vidc_inst *inst, return -EINVAL; } - rc = msm_comm_scale_clocks_and_bus(inst); + rc = msm_comm_scale_clocks_and_bus(inst, 0); if (rc) - dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__); + dprintk(VIDC_ERR, "%s: scale clock failed\n", __func__); print_vidc_buffer(VIDC_HIGH|VIDC_PERF, "qbuf in rbr", inst, mbuf); rc = msm_comm_qbuf_to_hfi(inst, mbuf); @@ -4470,6 +4470,7 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) { int rc = 0; struct v4l2_ctrl *ctrl; + int do_bw_calc = 0; if (!inst || !mbuf) { dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); @@ -4491,9 +4492,10 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) if (rc) return rc; - rc = msm_comm_scale_clocks_and_bus(inst); + do_bw_calc = mbuf->vvb.vb2_buf.type == INPUT_MPLANE; + rc = msm_comm_scale_clocks_and_bus(inst, do_bw_calc); if (rc) - dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__); + dprintk(VIDC_ERR, "%s: scale clock & bw failed\n", __func__); print_vidc_buffer(VIDC_HIGH|VIDC_PERF, "qbuf", inst, mbuf); ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); @@ -4563,10 +4565,12 @@ int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, { int rc = 0; struct msm_vidc_buffer *buf; + int do_bw_calc = 0; - rc = msm_comm_scale_clocks_and_bus(inst); + do_bw_calc = mbuf->vvb.vb2_buf.type == INPUT_MPLANE; + rc = msm_comm_scale_clocks_and_bus(inst, do_bw_calc); if (rc) - dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__); + dprintk(VIDC_ERR, "%s: scale clock & bw failed\n", __func__); mutex_lock(&inst->registeredbufs.lock); list_for_each_entry(buf, &inst->registeredbufs.list, list) { From d1161f93dc11cc5888fe1eb54474b1376aabef2b Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 5 Aug 2019 11:09:28 +0530 Subject: [PATCH 124/452] msm: vidc: increase msm_vidc_hw_rsp_timeout to 1500 Increase msm_vidc_hw_rsp_timeout to 1500, if kerenl or firmware log_mask is set. Change-Id: Id12e05e78ac4b004e4ccef7ff48be4f8eca1242a Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_debug.c | 60 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index 1455f3faee88..7312b7dbb11f 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -5,6 +5,7 @@ #define CREATE_TRACE_POINTS #define MAX_SSR_STRING_LEN 10 +#define MAX_DEBUG_LEVEL_STRING_LEN 15 #include "msm_vidc_debug.h" #include "vidc_hfi_api.h" #include @@ -151,6 +152,59 @@ static const struct file_operations ssr_fops = { .write = trigger_ssr_write, }; +static ssize_t debug_level_write(struct file *filp, const char __user *buf, + size_t count, loff_t *ppos) +{ + int rc = 0; + struct msm_vidc_core *core = filp->private_data; + char kbuf[MAX_DEBUG_LEVEL_STRING_LEN] = {0}; + + /* filter partial writes and invalid commands */ + if (*ppos != 0 || count >= sizeof(kbuf) || count == 0) { + dprintk(VIDC_ERR, "returning error - pos %d, count %d\n", + *ppos, count); + rc = -EINVAL; + } + + rc = simple_write_to_buffer(kbuf, sizeof(kbuf) - 1, ppos, buf, count); + if (rc < 0) { + dprintk(VIDC_ERR, "%s User memory fault\n", __func__); + rc = -EFAULT; + goto exit; + } + + rc = kstrtoint(kbuf, 0, &msm_vidc_debug); + if (rc) { + dprintk(VIDC_ERR, "returning error err %d\n", rc); + rc = -EINVAL; + goto exit; + } + core->resources.msm_vidc_hw_rsp_timeout = + ((msm_vidc_debug & 0xFF) > (VIDC_ERR | VIDC_HIGH)) ? 1500 : 1000; + rc = count; + dprintk(VIDC_HIGH, "debug timeout updated to - %d\n", + core->resources.msm_vidc_hw_rsp_timeout); + +exit: + return rc; +} + +static ssize_t debug_level_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + size_t len; + char kbuf[MAX_DEBUG_LEVEL_STRING_LEN]; + + len = scnprintf(kbuf, sizeof(kbuf), "0x%08x\n", msm_vidc_debug); + return simple_read_from_buffer(buf, count, ppos, kbuf, len); +} + +static const struct file_operations debug_level_fops = { + .open = simple_open, + .write = debug_level_write, + .read = debug_level_read, +}; + struct dentry *msm_vidc_debugfs_init_drv(void) { bool ok = false; @@ -174,7 +228,6 @@ struct dentry *msm_vidc_debugfs_init_drv(void) }) ok = - __debugfs_create(x32, "debug_level", &msm_vidc_debug) && __debugfs_create(u32, "fw_debug_mode", &msm_vidc_fw_debug_mode) && __debugfs_create(bool, "fw_coverage", &msm_vidc_fw_coverage) && __debugfs_create(bool, "disable_thermal_mitigation", @@ -227,6 +280,11 @@ struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core, dprintk(VIDC_ERR, "debugfs_create_file: fail\n"); goto failed_create_dir; } + if (!debugfs_create_file("debug_level", 0644, + parent, core, &debug_level_fops)) { + dprintk(VIDC_ERR, "debugfs_create_file: fail\n"); + goto failed_create_dir; + } failed_create_dir: return dir; } From af0e01c3837b60f79e7a2820f04690b15a3e54b3 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Mon, 5 Aug 2019 10:51:50 -0700 Subject: [PATCH 125/452] msm: vidc: make realtime as default By default, a session is realtime. Client can overwrite as non-realtime.Fixed realtime value for decoder.Deprecated VIDC_REALTIME flag usage. Change-Id: I5a1d1c9bdab18d3dfb73f3b21a23054de07d77a1 Signed-off-by: Darshana Patil --- msm/vidc/msm_vdec.c | 9 ++------- msm/vidc/msm_venc.c | 6 ++---- msm/vidc/msm_vidc_clocks.c | 4 ++-- msm/vidc/msm_vidc_common.h | 4 +++- msm/vidc/msm_vidc_internal.h | 1 - 5 files changed, 9 insertions(+), 15 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index aad7adcba35a..e1733c13cf7c 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -375,7 +375,7 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .type = V4L2_CTRL_TYPE_BOOLEAN, .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, - .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .default_value = V4L2_MPEG_MSM_VIDC_ENABLE, .step = 1, }, { @@ -902,9 +902,6 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) inst->buffer_size_limit = ctrl->val; break; case V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY: - inst->flags &= ~VIDC_REALTIME; - if (ctrl->val) - inst->flags |= VIDC_REALTIME; break; case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: inst->clk_data.operating_rate = ctrl->val; @@ -1269,7 +1266,6 @@ int msm_vdec_set_priority(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; - struct v4l2_ctrl *ctrl; struct hfi_enable hfi_property; if (!inst || !inst->core) { @@ -1278,8 +1274,7 @@ int msm_vdec_set_priority(struct msm_vidc_inst *inst) } hdev = inst->core->device; - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY); - hfi_property.enable = (bool)ctrl->val; + hfi_property.enable = is_realtime_session(inst); dprintk(VIDC_HIGH, "%s: %#x\n", __func__, hfi_property.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index c5c9cd4adc86..e26cd93431ad 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -755,7 +755,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .type = V4L2_CTRL_TYPE_BOOLEAN, .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, - .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .default_value = V4L2_MPEG_MSM_VIDC_ENABLE, .step = 1, }, { @@ -2016,7 +2016,6 @@ int msm_venc_set_priority(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; - struct v4l2_ctrl *ctrl; struct hfi_enable enable; if (!inst || !inst->core) { @@ -2025,8 +2024,7 @@ int msm_venc_set_priority(struct msm_vidc_inst *inst) } hdev = inst->core->device; - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY); - enable.enable = !!ctrl->val; + enable.enable = is_realtime_session(inst); dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 062116a1e039..100e5fbfd7d4 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1628,7 +1628,7 @@ static u32 get_core_load(struct msm_vidc_core *core, list_for_each_entry(inst, &core->instances, list) { u32 cycles, lp_cycles; - real_time_mode = inst->flags & VIDC_REALTIME ? true : false; + real_time_mode = is_realtime_session(inst); if (!(inst->clk_data.core_id & core_id)) continue; if (real_time_mode != real_time) @@ -1792,7 +1792,7 @@ void msm_print_core_status(struct msm_vidc_core *core, u32 core_id) "WORK_MODE_1" : "WORK_MODE_2", inst->clk_data.work_route, inst->flags & VIDC_LOW_POWER ? "LP" : "HQ", - inst->flags & VIDC_REALTIME ? "RealTime" : "NonRTime", + is_realtime_session(inst) ? "RealTime" : "NonRTime", inst->clk_data.min_freq); } mutex_unlock(&core->lock); diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index f9c4b4a910b5..fa7c31fcafbd 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -97,7 +97,9 @@ static inline bool is_image_session(struct msm_vidc_inst *inst) static inline bool is_realtime_session(struct msm_vidc_inst *inst) { - return !!(inst->flags & VIDC_REALTIME); + struct v4l2_ctrl *ctrl; + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY); + return !!ctrl->val; } static inline bool is_secure_session(struct msm_vidc_inst *inst) diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index d36af351b747..d27a7f54c05a 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -432,7 +432,6 @@ enum msm_vidc_modes { VIDC_TURBO = BIT(1), VIDC_THUMBNAIL = BIT(2), VIDC_LOW_POWER = BIT(3), - VIDC_REALTIME = BIT(4), }; struct msm_vidc_core_ops { From f72fe0767dd33502cd4ec362a31912c638d1eb74 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Wed, 24 Jul 2019 17:17:11 +0800 Subject: [PATCH 126/452] msm: venc: add dynamic flip Add to support dynamic flip command. Change-Id: Ide3aba6185241214eb955861bf251efd51662f03 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_venc.c | 156 +++++++++++++++++++++++++++++++---- msm/vidc/msm_venc.h | 2 + msm/vidc/msm_vidc_internal.h | 1 + msm/vidc/vidc_hfi_helper.h | 3 + 4 files changed, 146 insertions(+), 16 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index c5c9cd4adc86..a997087bf24d 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1046,6 +1046,45 @@ struct msm_vidc_format_constraint enc_pix_format_constraints[] = { }, }; +u32 v4l2_to_hfi_flip(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *hflip = NULL; + struct v4l2_ctrl *vflip = NULL; + u32 flip = HFI_FLIP_NONE; + + hflip = get_ctrl(inst, V4L2_CID_HFLIP); + vflip = get_ctrl(inst, V4L2_CID_VFLIP); + + if ((hflip->val == V4L2_MPEG_MSM_VIDC_ENABLE) && + (vflip->val == V4L2_MPEG_MSM_VIDC_ENABLE)) + flip = HFI_FLIP_HORIZONTAL | HFI_FLIP_VERTICAL; + else if (hflip->val == V4L2_MPEG_MSM_VIDC_ENABLE) + flip = HFI_FLIP_HORIZONTAL; + else if (vflip->val == V4L2_MPEG_MSM_VIDC_ENABLE) + flip = HFI_FLIP_VERTICAL; + + return flip; +} + +inline bool vidc_scalar_enabled(struct msm_vidc_inst *inst) +{ + struct v4l2_format *f; + u32 output_height, output_width, input_height, input_width; + bool scalar_enable = false; + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + output_height = f->fmt.pix_mp.height; + output_width = f->fmt.pix_mp.width; + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + input_height = f->fmt.pix_mp.height; + input_width = f->fmt.pix_mp.width; + + if (output_height != input_height || output_width != input_width) + scalar_enable = true; + + return scalar_enable; +} + static int msm_venc_set_csc(struct msm_vidc_inst *inst, u32 color_primaries, u32 custom_matrix); @@ -1134,7 +1173,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) inst->buff_req.buffer[12].buffer_type = HAL_BUFFER_INTERNAL_CMD_QUEUE; inst->buff_req.buffer[13].buffer_type = HAL_BUFFER_INTERNAL_RECON; msm_vidc_init_buffer_size_calculators(inst); - + inst->static_rotation_flip_enabled = false; return rc; } @@ -1768,6 +1807,16 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) __func__); } break; + case V4L2_CID_HFLIP: + case V4L2_CID_VFLIP: + if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_set_dynamic_flip(inst); + if (rc) + dprintk(VIDC_ERR, + "%s: set flip failed\n", + __func__); + } + break; case V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY: case V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE: case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER: @@ -1775,8 +1824,6 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_ROTATE: case V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT: case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: - case V4L2_CID_HFLIP: - case V4L2_CID_VFLIP: case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: @@ -3507,8 +3554,6 @@ int msm_venc_set_rotation(struct msm_vidc_inst *inst) { int rc = 0; struct v4l2_ctrl *rotation = NULL; - struct v4l2_ctrl *hflip = NULL; - struct v4l2_ctrl *vflip = NULL; struct hfi_device *hdev; struct hfi_vpe_rotation_type vpe_rotation; @@ -3524,17 +3569,7 @@ int msm_venc_set_rotation(struct msm_vidc_inst *inst) else if (rotation->val == 270) vpe_rotation.rotation = HFI_ROTATE_270; - hflip = get_ctrl(inst, V4L2_CID_HFLIP); - vflip = get_ctrl(inst, V4L2_CID_VFLIP); - - vpe_rotation.flip = HFI_FLIP_NONE; - if ((hflip->val == V4L2_MPEG_MSM_VIDC_ENABLE) && - (vflip->val == V4L2_MPEG_MSM_VIDC_ENABLE)) - vpe_rotation.flip = HFI_FLIP_HORIZONTAL | HFI_FLIP_VERTICAL; - else if (hflip->val == V4L2_MPEG_MSM_VIDC_ENABLE) - vpe_rotation.flip = HFI_FLIP_HORIZONTAL; - else if (vflip->val == V4L2_MPEG_MSM_VIDC_ENABLE) - vpe_rotation.flip = HFI_FLIP_VERTICAL; + vpe_rotation.flip = v4l2_to_hfi_flip(inst); dprintk(VIDC_HIGH, "Set rotation = %d, flip = %d\n", vpe_rotation.rotation, vpe_rotation.flip); @@ -3547,6 +3582,95 @@ int msm_venc_set_rotation(struct msm_vidc_inst *inst) return rc; } + /* Mark static rotation/flip set */ + inst->static_rotation_flip_enabled = false; + if ((vpe_rotation.rotation != HFI_ROTATE_NONE || + vpe_rotation.flip != HFI_FLIP_NONE) && + inst->state < MSM_VIDC_START_DONE) + inst->static_rotation_flip_enabled = true; + + return rc; +} + +int msm_venc_check_dynamic_flip_constraints(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct v4l2_ctrl *blur = NULL; + struct v4l2_format *f = NULL; + bool scalar_enable = false; + bool blur_enable = false; + u32 input_height, input_width; + + /* Dynamic flip is not allowed with scalar when static + * rotation/flip is disabled + */ + scalar_enable = vidc_scalar_enabled(inst); + + /* Check blur configs + * blur value = 0 -> enable auto blur + * blur value = 2 or input resolution -> disable all blur + * For other values -> enable external blur + * Dynamic flip is not allowed with external blur enabled + */ + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + input_height = f->fmt.pix_mp.height; + input_width = f->fmt.pix_mp.width; + + blur = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_BLUR_DIMENSIONS); + if (blur->val != 0 && blur->val != 2 && + ((blur->val & 0xFFFF) != input_height || + (blur->val & 0x7FFF0000) >> 16 != input_width)) + blur_enable = true; + + if (blur_enable) { + /* Reject dynamic flip with external blur enabled */ + dprintk(VIDC_ERR, + "Unsupported dynamic flip with external blur\n"); + rc = -EINVAL; + } else if (scalar_enable && !inst->static_rotation_flip_enabled) { + /* Reject dynamic flip with scalar enabled */ + dprintk(VIDC_ERR, "Unsupported dynamic flip with scalar\n"); + rc = -EINVAL; + } + + return rc; +} + +int msm_venc_set_dynamic_flip(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + u32 dynamic_flip; + + hdev = inst->core->device; + + rc = msm_venc_check_dynamic_flip_constraints(inst); + if (rc) { + dprintk(VIDC_ERR, + "%s: Dynamic flip unsupported\n", __func__); + return rc; + } + + /* Require IDR frame first */ + dprintk(VIDC_HIGH, "Set dynamic IDR frame\n"); + rc = msm_venc_set_request_keyframe(inst); + if (rc) { + dprintk(VIDC_ERR, + "%s: Dynamic IDR failed\n", __func__); + return rc; + } + + dynamic_flip = v4l2_to_hfi_flip(inst); + dprintk(VIDC_HIGH, "Dynamic flip = %d\n", dynamic_flip); + rc = call_hfi_op(hdev, session_set_property, + (void *)inst->session, + HFI_PROPERTY_CONFIG_VPE_FLIP, + &dynamic_flip, sizeof(dynamic_flip)); + if (rc) { + dprintk(VIDC_ERR, "Set dynamic flip failed\n"); + return rc; + } + return rc; } diff --git a/msm/vidc/msm_venc.h b/msm/vidc/msm_venc.h index 532505f87e2c..f9e8d227b37a 100644 --- a/msm/vidc/msm_venc.h +++ b/msm/vidc/msm_venc.h @@ -37,6 +37,8 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst); int msm_venc_set_hp_max_layer(struct msm_vidc_inst *inst); int msm_venc_set_hp_layer(struct msm_vidc_inst *inst); int msm_venc_set_base_layer_priority_id(struct msm_vidc_inst *inst); +int msm_venc_check_dynamic_flip_constraints(struct msm_vidc_inst *inst); +int msm_venc_set_dynamic_flip(struct msm_vidc_inst *inst); int msm_venc_set_lossless(struct msm_vidc_inst *inst); int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst); int handle_all_intra_restrictions(struct msm_vidc_inst *inst); diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index d36af351b747..b830abaecd36 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -532,6 +532,7 @@ struct msm_vidc_inst { u32 hybrid_hp; u32 layer_bitrate; u32 client_set_ctrls; + bool static_rotation_flip_enabled; struct internal_buf *dpb_extra_binfo; struct msm_vidc_codec_data *codec_data; struct hal_hdr10_pq_sei hdr10_sei_params; diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index 05f00250726b..2b96d5645a5e 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -398,6 +398,9 @@ struct hfi_buffer_info { #define HFI_PROPERTY_CONFIG_VPE_COMMON_START \ (HFI_DOMAIN_BASE_VPE + HFI_ARCH_COMMON_OFFSET + 0x8000) +#define HFI_PROPERTY_CONFIG_VPE_FLIP \ + (HFI_PROPERTY_CONFIG_VPE_COMMON_START + 0x001) + struct hfi_pic_struct { u32 progressive_only; }; From efed87ec8d1eed6ce4632a86794fcd1fa268abaf Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Thu, 1 Aug 2019 12:22:15 -0700 Subject: [PATCH 127/452] msm: vidc: increase decode input buffer count Increase input buffers count for first four elgible sessions to avoid high memory usage. Also made changes to extra buffer calculations. Change-Id: Id50791f6800390ad27abc6f361e54dcc7b61a8c8 Signed-off-by: Darshana Patil --- msm/vidc/msm_vdec.c | 8 +- msm/vidc/msm_venc.c | 8 +- msm/vidc/msm_vidc.c | 8 +- msm/vidc/msm_vidc_buffer_calculations.c | 243 ++++++++++++++++-------- msm/vidc/msm_vidc_common.c | 21 ++ msm/vidc/msm_vidc_common.h | 1 + msm/vidc/msm_vidc_internal.h | 5 +- 7 files changed, 199 insertions(+), 95 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index aad7adcba35a..95aae665ef7b 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -343,9 +343,9 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, .name = "CAPTURE Count", .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = MIN_NUM_OUTPUT_BUFFERS, + .minimum = SINGLE_OUTPUT_BUFFER, .maximum = MAX_NUM_OUTPUT_BUFFERS, - .default_value = MIN_NUM_OUTPUT_BUFFERS, + .default_value = SINGLE_OUTPUT_BUFFER, .step = 1, .qmenu = NULL, }, @@ -353,9 +353,9 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, .name = "OUTPUT Count", .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = MIN_NUM_INPUT_BUFFERS, + .minimum = SINGLE_INPUT_BUFFER, .maximum = MAX_NUM_INPUT_BUFFERS, - .default_value = MIN_NUM_INPUT_BUFFERS, + .default_value = SINGLE_INPUT_BUFFER, .step = 1, .qmenu = NULL, }, diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index c5c9cd4adc86..28c928f5486b 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -160,9 +160,9 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, .name = "CAPTURE Count", .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = MIN_NUM_OUTPUT_BUFFERS, + .minimum = SINGLE_OUTPUT_BUFFER, .maximum = MAX_NUM_OUTPUT_BUFFERS, - .default_value = MIN_NUM_OUTPUT_BUFFERS, + .default_value = SINGLE_OUTPUT_BUFFER, .step = 1, .qmenu = NULL, }, @@ -170,9 +170,9 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, .name = "OUTPUT Count", .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = MIN_NUM_INPUT_BUFFERS, + .minimum = SINGLE_INPUT_BUFFER, .maximum = MAX_NUM_INPUT_BUFFERS, - .default_value = MIN_NUM_INPUT_BUFFERS, + .default_value = SINGLE_INPUT_BUFFER, .step = 1, .qmenu = NULL, }, diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 343d6c83db4c..f3285b33b04e 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -604,10 +604,10 @@ static int msm_vidc_queue_setup(struct vb2_queue *q, } f = &fmt->v4l2_fmt; *num_planes = f->fmt.pix_mp.num_planes; - if (*num_buffers < MIN_NUM_INPUT_BUFFERS || + if (*num_buffers < SINGLE_INPUT_BUFFER || *num_buffers > MAX_NUM_INPUT_BUFFERS) fmt->count_actual = *num_buffers = - MIN_NUM_INPUT_BUFFERS; + SINGLE_INPUT_BUFFER; for (i = 0; i < *num_planes; i++) sizes[i] = f->fmt.pix_mp.plane_fmt[i].sizeimage; @@ -627,10 +627,10 @@ static int msm_vidc_queue_setup(struct vb2_queue *q, } f = &fmt->v4l2_fmt; *num_planes = f->fmt.pix_mp.num_planes; - if (*num_buffers < MIN_NUM_OUTPUT_BUFFERS || + if (*num_buffers < SINGLE_OUTPUT_BUFFER || *num_buffers > MAX_NUM_OUTPUT_BUFFERS) fmt->count_actual = *num_buffers = - MIN_NUM_OUTPUT_BUFFERS; + SINGLE_OUTPUT_BUFFER; for (i = 0; i < *num_planes; i++) sizes[i] = f->fmt.pix_mp.plane_fmt[i].sizeimage; diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 5c47c79fd613..2a820415c1f5 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -8,19 +8,35 @@ #include "msm_vidc_buffer_calculations.h" #include "msm_vidc_clocks.h" -#define MIN_NUM_THUMBNAIL_MODE_INPUT_BUFFERS MIN_NUM_INPUT_BUFFERS -#define MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS MIN_NUM_OUTPUT_BUFFERS -#define MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS_VP9 8 +#define VP9_REFERENCE_COUNT 8 -/* extra o/p buffers in case of encoder dcvs */ -#define DCVS_ENC_EXTRA_INPUT_BUFFERS 4 +/* minimum number of input buffers */ +#define MIN_INPUT_BUFFERS 4 +/* Max number of PERF eligible sessions */ +#define MAX_PERF_ELIGIBLE_SESSIONS 4 + +/* Decoder buffer count macros */ +/* total input buffers in case of decoder batch */ +#define BATCH_DEC_TOTAL_INPUT_BUFFERS 6 + +/* total input buffers for decoder HFR usecase */ +#define HFR_DEC_TOTAL_INPUT_BUFFERS 12 + +/* extra output buffers in case of decoder batch */ +#define BATCH_DEC_EXTRA_OUTPUT_BUFFERS 6 /* extra o/p buffers in case of decoder dcvs */ #define DCVS_DEC_EXTRA_OUTPUT_BUFFERS 4 -/* extra buffers for encoder HFR usecase */ -#define HFR_EXTRA_INPUT_BUFFERS 4 -#define HFR_EXTRA_OUTPUT_BUFFERS 12 +/* Encoder buffer count macros */ +/* total input buffers for encoder HFR usecase */ +#define HFR_ENC_TOTAL_INPUT_BUFFERS 8 + +/* minimum number of output buffers */ +#define MIN_ENC_OUTPUT_BUFFERS 4 + +/* extra output buffers for encoder HFR usecase */ +#define HFR_ENC_TOTAL_OUTPUT_BUFFERS 12 #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_WIDTH 32 #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_HEIGHT 8 @@ -262,6 +278,9 @@ #define HDR10PLUS_PAYLOAD_SIZE 1024 #define HDR10_HIST_EXTRADATA_SIZE 4096 +static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst); +static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst); + static inline u32 calculate_h264d_scratch_size(struct msm_vidc_inst *inst, u32 width, u32 height, bool is_interlaced); static inline u32 calculate_h265d_scratch_size(struct msm_vidc_inst *inst, @@ -599,7 +618,6 @@ int msm_vidc_calculate_input_buffer_count(struct msm_vidc_inst *inst) { struct msm_vidc_format *fmt; int extra_buff_count = 0; - u32 input_min_count = 4; if (!inst) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); @@ -616,25 +634,13 @@ int msm_vidc_calculate_input_buffer_count(struct msm_vidc_inst *inst) if (is_thumbnail_session(inst)) { fmt->count_min = fmt->count_min_host = fmt->count_actual = - MIN_NUM_THUMBNAIL_MODE_INPUT_BUFFERS; + SINGLE_INPUT_BUFFER; return 0; } - /* - * Update input buff counts - * Extradata uses same count as input port - */ - if (is_decode_session(inst) && !is_secure_session(inst)) - input_min_count += 2; - extra_buff_count = msm_vidc_get_extra_buff_count(inst, HAL_BUFFER_INPUT); - fmt->count_min = input_min_count; - /* batching needs minimum batch size count of input buffers */ - if (inst->batch.enable && - is_decode_session(inst) && - fmt->count_min < inst->batch.size) - fmt->count_min = inst->batch.size; + fmt->count_min = MIN_INPUT_BUFFERS; fmt->count_min_host = fmt->count_actual = fmt->count_min + extra_buff_count; @@ -649,7 +655,7 @@ int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst) { struct msm_vidc_format *fmt; int extra_buff_count = 0; - u32 codec, output_min_count = 4; + u32 codec, output_min_count; if (!inst) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); @@ -666,17 +672,9 @@ int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst) return 0; if (is_thumbnail_session(inst)) { - if (codec == V4L2_PIX_FMT_VP9) { - fmt->count_min = - MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS_VP9; - fmt->count_min_host = fmt->count_min; - fmt->count_actual = fmt->count_min_host; - } else { - fmt->count_min = - MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS; - fmt->count_min_host = fmt->count_min; - fmt->count_actual = fmt->count_min_host; - } + fmt->count_min = (codec == V4L2_PIX_FMT_VP9) ? + VP9_REFERENCE_COUNT : SINGLE_OUTPUT_BUFFER; + fmt->count_min_host = fmt->count_actual = fmt->count_min; return 0; } @@ -684,21 +682,17 @@ int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst) if (is_decode_session(inst)) { switch (codec) { case V4L2_PIX_FMT_MPEG2: - output_min_count = 6; - break; - case V4L2_PIX_FMT_H264: - output_min_count = 8; - break; - case V4L2_PIX_FMT_HEVC: - output_min_count = 8; - break; case V4L2_PIX_FMT_VP8: output_min_count = 6; break; case V4L2_PIX_FMT_VP9: output_min_count = 9; break; + default: + output_min_count = 8; //H264, HEVC } + } else { + output_min_count = MIN_ENC_OUTPUT_BUFFERS; } extra_buff_count = msm_vidc_get_extra_buff_count(inst, HAL_BUFFER_OUTPUT); @@ -730,56 +724,143 @@ int msm_vidc_calculate_buffer_counts(struct msm_vidc_inst *inst) int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, enum hal_buffer buffer_type) { - unsigned int count = 0; - struct v4l2_format *f; - if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s Invalid args\n", __func__); return 0; } - /* - * no extra buffers for thumbnail session because - * neither dcvs nor batching will be enabled - */ - if (is_thumbnail_session(inst)) + + if (!is_decode_session(inst) && !is_encode_session(inst)) return 0; - /* Add DCVS extra buffer count */ - if (inst->core->resources.dcvs) { - if (is_decode_session(inst) && - buffer_type == HAL_BUFFER_OUTPUT) { - count += DCVS_DEC_EXTRA_OUTPUT_BUFFERS; - } else if ((is_encode_session(inst) && - buffer_type == HAL_BUFFER_INPUT)) { - count += DCVS_ENC_EXTRA_INPUT_BUFFERS; - } - } + if (buffer_type == HAL_BUFFER_OUTPUT) + return msm_vidc_get_extra_output_buff_count(inst); + else if (buffer_type == HAL_BUFFER_INPUT) + return msm_vidc_get_extra_input_buff_count(inst); + + return 0; +} + +static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst) +{ + unsigned int extra_input_count = 0; + struct msm_vidc_core *core; + struct v4l2_format *f; /* - * if platform supports decode batching ensure minimum - * batch size count of extra buffers added on output port + * For a non-realtime session, extra buffers are not required. + * For thumbnail session, extra buffers are not required as + * neither dcvs nor batching will be enabled. */ - if (buffer_type == HAL_BUFFER_OUTPUT) { - if (inst->batch.enable && - is_decode_session(inst) && - count < inst->batch.size) - count = inst->batch.size; - } + if (!is_realtime_session(inst) || is_thumbnail_session(inst)) + return extra_input_count; - /* increase both input and output counts for HFR/HSR encode case */ + /* + * Batch mode and HFR not supported for resolution greater than + * UHD. Hence extra buffers are not required. + */ f = &inst->fmts[INPUT_PORT].v4l2_fmt; - if (is_encode_session(inst) && msm_vidc_get_fps(inst) >= 120 && - !res_is_greater_than(f->fmt.pix_mp.width, - f->fmt.pix_mp.height, 1920, 1088)) { - if (buffer_type == HAL_BUFFER_INPUT && - count < HFR_EXTRA_INPUT_BUFFERS) - count = HFR_EXTRA_INPUT_BUFFERS; - if (buffer_type == HAL_BUFFER_OUTPUT && - count < HFR_EXTRA_OUTPUT_BUFFERS) - count = HFR_EXTRA_OUTPUT_BUFFERS; - } + if (res_is_greater_than(f->fmt.pix_mp.width, f->fmt.pix_mp.height, + 4096, 2160)) + return extra_input_count; - return count; + if (is_decode_session(inst)) { + + /* + * Allocating 2 extra buffers, assuming current session is + * always batch eligible. Cannot rely on inst->batch.enable + * as it can be enabled/disabled based on clip fps etc. But + * decoder input can not be reallocated at run time. + */ + if (core->resources.decode_batching) + extra_input_count = (BATCH_DEC_TOTAL_INPUT_BUFFERS - + MIN_INPUT_BUFFERS); + + /* + * HFR decode session needs more buffers and we do not know + * whether a decode session is HFR or not until input buffers + * queued but by then input buffers are already allocated and + * we do not have option to increase input buffer count then. + * So have more buffers for initial 4 elgible sessions (and + * not for all sessions to avoid over memory usage issues). + */ + if (!is_secure_session(inst) && + msm_comm_get_num_perf_sessions(inst) < + MAX_PERF_ELIGIBLE_SESSIONS) { + inst->is_perf_eligible_session = true; + extra_input_count = (HFR_DEC_TOTAL_INPUT_BUFFERS - + MIN_INPUT_BUFFERS); + } + } else if (is_encode_session(inst)) { + /* + * Both DCVS and HFR needs extra 4 buffers. Since all sessions + * are DCVS eligible, we do not need extra handling for HFR as + * we are making sure initial 4 sessions have extra 4 buffers. + * For the remaining non-perf sessions, no extra buffers are + * allocated and total number of buffers will be 4 with best + * effort performance. + */ + if (msm_comm_get_num_perf_sessions(inst) < + MAX_PERF_ELIGIBLE_SESSIONS) { + inst->is_perf_eligible_session = true; + extra_input_count = (HFR_ENC_TOTAL_INPUT_BUFFERS - + MIN_INPUT_BUFFERS); + } + } + return extra_input_count; +} + +static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) +{ + unsigned int extra_output_count = 0; + struct msm_vidc_core *core; + struct v4l2_format *f; + + /* + * For a non-realtime session, extra buffers are not required. + * For thumbnail session, extra buffers are not required as + * neither dcvs nor batching will be enabled. + */ + if (!is_realtime_session(inst) || is_thumbnail_session(inst)) + return extra_output_count; + + /* + * Batch mode and HFR not supported for resolution greater than + * UHD. Hence extra buffers are not required. + */ + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + if (res_is_greater_than(f->fmt.pix_mp.width, f->fmt.pix_mp.height, + 4096, 2160)) + return extra_output_count; + + if (is_decode_session(inst)) { + /* + * Minimum number of decoder output buffers is codec specific. + * If platform supports decode batching ensure minimum 6 extra + * output buffers. Else add 4 extra output buffers for DCVS. + */ + if (core->resources.decode_batching) + extra_output_count = BATCH_DEC_EXTRA_OUTPUT_BUFFERS; + else if (inst->core->resources.dcvs) + extra_output_count = DCVS_DEC_EXTRA_OUTPUT_BUFFERS; + } else if (is_encode_session(inst)) { + /* + * Batching and DCVS are based on input. We assume that encoder + * output buffers can be re-cycled quickly. Hence it is assumed + * that output buffer count does not impact for DCVS/batching. + * For HFR, we are increasing buffer count to avoid latency/perf + * issue to re-cycle buffers. + */ + if (msm_vidc_get_fps(inst) >= 120 && + !res_is_greater_than(f->fmt.pix_mp.width, + f->fmt.pix_mp.height, 1920, 1088) && + msm_comm_get_num_perf_sessions(inst) < + MAX_PERF_ELIGIBLE_SESSIONS) { + inst->is_perf_eligible_session = true; + extra_output_count = (HFR_ENC_TOTAL_OUTPUT_BUFFERS - + MIN_ENC_OUTPUT_BUFFERS); + } + } + return extra_output_count; } u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 56e56f1aff26..3bfb085748f9 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -754,6 +754,27 @@ bool is_single_session(struct msm_vidc_inst *inst, u32 ignore_flags) return single; } +int msm_comm_get_num_perf_sessions(struct msm_vidc_inst *inst) +{ + int count = 0; + struct msm_vidc_core *core; + struct msm_vidc_inst *temp; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + goto exit; + } + core = inst->core; + mutex_lock(&core->lock); + list_for_each_entry(temp, &core->instances, list) { + if (temp->is_perf_eligible_session) + count++; + } + mutex_unlock(&core->lock); +exit: + return count; +} + static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst) { int input_port_mbs, output_port_mbs; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index f9c4b4a910b5..66b14815f214 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -153,6 +153,7 @@ static inline int msm_comm_s_ctrl(struct msm_vidc_inst *inst, } bool is_single_session(struct msm_vidc_inst *inst, u32 ignore_flags); +int msm_comm_get_num_perf_sessions(struct msm_vidc_inst *inst); bool is_batching_allowed(struct msm_vidc_inst *inst); enum hal_buffer get_hal_buffer_type(unsigned int type, unsigned int plane_num); diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index d36af351b747..9213a57b8027 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -42,8 +42,8 @@ #define DEFAULT_FPS 30 #define MINIMUM_FPS 1 #define MAXIMUM_FPS 960 -#define MIN_NUM_INPUT_BUFFERS 1 -#define MIN_NUM_OUTPUT_BUFFERS 1 +#define SINGLE_INPUT_BUFFER 1 +#define SINGLE_OUTPUT_BUFFER 1 #define MAX_NUM_INPUT_BUFFERS VIDEO_MAX_FRAME // same as VB2_MAX_FRAME #define MAX_NUM_OUTPUT_BUFFERS VIDEO_MAX_FRAME // same as VB2_MAX_FRAME @@ -540,6 +540,7 @@ struct msm_vidc_inst { struct msm_vidc_inst_smem_ops *smem_ops; int (*buffer_size_calculators)(struct msm_vidc_inst *inst); bool all_intra; + bool is_perf_eligible_session; }; extern struct msm_vidc_drv *vidc_driver; From b273402361252153fd277e3c3ae2e1ae4f2a4c50 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Mon, 5 Aug 2019 15:48:13 -0700 Subject: [PATCH 128/452] msm: vidc: Update cvp extradata control settings If kernel to kernel CVP is enabled, initially driver disables CVP extradata to firmware and then later, re-enables it. Introduced a new flag to usage of CVP kernel to kernel metadata to save the usage. As part of start streaming, driver will send out CVP extradata enabled once based on overall usage. Also, disabled kernel to kernel CVP usage for superframe. Change-Id: I5590bd2274e27243da99f207d61fb00fc6fc82e0 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_venc.c | 10 ++------ msm/vidc/msm_vidc.c | 44 ++++++++++++++++++++++++++++-------- msm/vidc/msm_vidc_internal.h | 4 ++++ 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index c5c9cd4adc86..86929de9d29d 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -4020,7 +4020,6 @@ int msm_venc_set_hdr_info(struct msm_vidc_inst *inst) int msm_venc_set_extradata(struct msm_vidc_inst *inst) { int rc = 0; - u32 value = 0x0; u32 codec; codec = get_v4l2_codec(inst); @@ -4056,13 +4055,8 @@ int msm_venc_set_extradata(struct msm_vidc_inst *inst) } } - if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) - value = 0x1; - dprintk(VIDC_HIGH, "%s: CVP extradata %d\n", __func__, value); - rc = msm_comm_set_extradata(inst, - HFI_PROPERTY_PARAM_VENC_CVP_METADATA_EXTRADATA, value); - if (rc) - dprintk(VIDC_ERR, "%s: set CVP extradata failed\n", __func__); + /* CVP extradata is common between user space and external CVP kernel to kernel. + Hence, skipping here and will be set after msm_vidc_prepare_preprocess in start_streaming*/ return rc; } diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 343d6c83db4c..99fa05786ec0 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -711,6 +711,7 @@ bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst) bool allowed = false; struct msm_vidc_core *core; struct v4l2_ctrl *cvp_disable; + struct v4l2_ctrl *superframe_enable; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); @@ -730,15 +731,18 @@ bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst) * - V4L2_MPEG_VIDEO_BITRATE_MODE_CQ * - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR * - not secure session + * - not superframe enabled */ cvp_disable = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE); + superframe_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); if (core->resources.cvp_external && !cvp_disable->val && !(inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) && inst->rc_type != RATE_CONTROL_OFF && inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ && !inst->clk_data.is_legacy_cbr && - !is_secure_session(inst)) { + !is_secure_session(inst) && + !superframe_enable->val) { dprintk(VIDC_HIGH, "%s: cvp allowed\n", __func__); allowed = true; } else { @@ -778,15 +782,8 @@ static int msm_vidc_prepare_preprocess(struct msm_vidc_inst *inst) dprintk(VIDC_ERR, "%s: no cvp preprocessing\n", __func__); goto exit; } - dprintk(VIDC_HIGH, "%s: cvp enabled\n", __func__); - - dprintk(VIDC_HIGH, "%s: set CVP extradata\n", __func__); - rc = msm_comm_set_extradata(inst, - HFI_PROPERTY_PARAM_VENC_CVP_METADATA_EXTRADATA, 1); - if (rc) { - dprintk(VIDC_ERR, "%s: set CVP extradata failed\n", __func__); - goto exit; - } + dprintk(VIDC_HIGH, "%s: kernel to kernel cvp enabled\n", __func__); + inst->prop.extradata_ctrls |= EXTRADATA_ENC_INPUT_KK_CVP; exit: if (rc) @@ -794,6 +791,31 @@ static int msm_vidc_prepare_preprocess(struct msm_vidc_inst *inst) return rc; } +static bool msm_vidc_set_cvp_metadata(struct msm_vidc_inst *inst) { + + int rc = 0; + u32 value = 0x0; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return false; + } + + if ((inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) || + (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_KK_CVP)) + value = 0x1; + + dprintk(VIDC_HIGH, "%s: CVP extradata %d\n", __func__, value); + rc = msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VENC_CVP_METADATA_EXTRADATA, value); + if (rc) { + dprintk(VIDC_ERR, + "%s: set CVP extradata failed\n", __func__); + return false; + } + return true; +} + static inline int start_streaming(struct msm_vidc_inst *inst) { int rc = 0; @@ -819,6 +841,8 @@ static inline int start_streaming(struct msm_vidc_inst *inst) /* ignore error */ rc = 0; } + if (!(msm_vidc_set_cvp_metadata(inst))) + goto fail_start; } b.buffer_type = HFI_BUFFER_OUTPUT; diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index d36af351b747..7180aa4522e7 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -58,6 +58,10 @@ #define INPUT_MPLANE V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE #define OUTPUT_MPLANE V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE +/* EXTRADATA_ENC_INPUT_KK_CVP is an extension of + v4l2_mpeg_vidc_extradata for internal usage. + This is needed to indicate internal kernel to kernel CVP usage. */ +#define EXTRADATA_ENC_INPUT_KK_CVP (1UL << 31) #define RATE_CONTROL_OFF (V4L2_MPEG_VIDEO_BITRATE_MODE_CQ + 1) #define RATE_CONTROL_LOSSLESS (V4L2_MPEG_VIDEO_BITRATE_MODE_CQ + 2) #define SYS_MSG_START HAL_SYS_INIT_DONE From 34d3f0fe996f0a9293fa50528fbfc5f3d8b36865 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Wed, 26 Jun 2019 15:42:30 -0700 Subject: [PATCH 129/452] msm: vidc: recalculate buffer counts based on frame rate Encoder buffer requirement changes based on frame rate or operating rate (HFR/HSR usecase) and hence recalculate buffer counts when client set frame rate or operating rate. Change-Id: I7b421524f319a4fde8b153dcd5c3bde123c5ccf9 Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_venc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index c5c9cd4adc86..1feffb06620c 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1517,6 +1517,8 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE: inst->clk_data.frame_rate = ctrl->val; + if (inst->state < MSM_VIDC_LOAD_RESOURCES) + msm_vidc_calculate_buffer_counts(inst); if (inst->state == MSM_VIDC_START_DONE) { rc = msm_venc_set_frame_rate(inst); if (rc) @@ -1560,6 +1562,8 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: inst->clk_data.operating_rate = ctrl->val; + if (inst->state < MSM_VIDC_LOAD_RESOURCES) + msm_vidc_calculate_buffer_counts(inst); if (inst->state == MSM_VIDC_START_DONE) { rc = msm_venc_set_operating_rate(inst); if (rc) From 6854e171a54931f6497dfb87a57f181d9c30b3b4 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Thu, 8 Aug 2019 13:23:07 +0800 Subject: [PATCH 130/452] msm: vidc: fix kw issues Fix two kw issues on uninitialized pointer and possible NULL dereference. Change-Id: Ic87335d435ee84bef1c264d99e0d857d2932cbdc Signed-off-by: Shi Zhongbo --- msm/vidc/msm_vidc_buffer_calculations.c | 16 +++++++++++++++- msm/vidc/msm_vidc_common.c | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 2a820415c1f5..13200fc29a58 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -746,6 +746,13 @@ static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst) struct msm_vidc_core *core; struct v4l2_format *f; + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + core = inst->core; + /* * For a non-realtime session, extra buffers are not required. * For thumbnail session, extra buffers are not required as @@ -815,6 +822,13 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) struct msm_vidc_core *core; struct v4l2_format *f; + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + core = inst->core; + /* * For a non-realtime session, extra buffers are not required. * For thumbnail session, extra buffers are not required as @@ -840,7 +854,7 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) */ if (core->resources.decode_batching) extra_output_count = BATCH_DEC_EXTRA_OUTPUT_BUFFERS; - else if (inst->core->resources.dcvs) + else if (core->resources.dcvs) extra_output_count = DCVS_DEC_EXTRA_OUTPUT_BUFFERS; } else if (is_encode_session(inst)) { /* diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index be2b6d25485e..b9cc0dabc1bf 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -4588,7 +4588,7 @@ int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, struct msm_vidc_buffer *buf; int do_bw_calc = 0; - do_bw_calc = mbuf->vvb.vb2_buf.type == INPUT_MPLANE; + do_bw_calc = mbuf ? mbuf->vvb.vb2_buf.type == INPUT_MPLANE : 0; rc = msm_comm_scale_clocks_and_bus(inst, do_bw_calc); if (rc) dprintk(VIDC_ERR, "%s: scale clock & bw failed\n", __func__); From 226261607b61f03d2049579980448475593f94a8 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Thu, 8 Aug 2019 14:47:53 -0700 Subject: [PATCH 131/452] msm: vidc: Set VBR as default rate control mode Set VBR as default rate control instead of RC_OFF. Change-Id: Ie89f0109a9fe38a6c18b4713e8e8e905beb40b70 Signed-off-by: Mihir Ganu --- msm/vidc/msm_venc.c | 2 +- msm/vidc/msm_vidc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 185b6cc9472d..bd90dc5b305f 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -850,7 +850,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .type = V4L2_CTRL_TYPE_BOOLEAN, .minimum = 0, .maximum = 1, - .default_value = 0, + .default_value = 1, .step = 1, }, { diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 5032227a7f29..c0c3a9c7f1bc 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1569,7 +1569,7 @@ void *msm_vidc_open(int core_id, int session_type) inst->pic_struct = MSM_VIDC_PIC_STRUCT_PROGRESSIVE; inst->colour_space = MSM_VIDC_BT601_6_525; inst->smem_ops = &msm_vidc_smem_ops; - inst->rc_type = RATE_CONTROL_OFF; + inst->rc_type = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR; inst->dpb_extra_binfo = NULL; inst->all_intra = false; From d4e94261b5b564e6b2f1dcb0abba10fdf6cb82cb Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 2 Aug 2019 15:47:19 +0530 Subject: [PATCH 132/452] msm: vidc: do not allow qbuf during flush 1. Don't allow qbuf (etb & ftb), if flush is issued to (encoder & decoder) input port. 2. Don't allow qbuf (etb & ftb), if flush is issued to encoder output port 3. Don't qbuf (ftb), if flush is issued to decoder output port 4. Allow qbuf (etb), if flush is issued to decoder output port to handle decoder reconfig. Change-Id: I08a6a10612cc1a14ad164c55c5c8e54550c84845 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc.c | 7 ++++--- msm/vidc/msm_vidc_common.c | 28 ++++++++++++++++++++-------- msm/vidc/msm_vidc_internal.h | 1 + 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 5032227a7f29..99e8d1aa0ad7 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -346,9 +346,10 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) return -EINVAL; } - if (inst->in_flush && is_decode_session(inst) && - b->type == OUTPUT_MPLANE) { - dprintk(VIDC_ERR, "%s: in flush, discarding qbuf\n", __func__); + if ((inst->out_flush && b->type == OUTPUT_MPLANE) || inst->in_flush) { + dprintk(VIDC_ERR, + "%s: %x: in flush, discarding qbuf, type %u, index %u\n", + __func__, hash32_ptr(inst->session), b->type, b->index); return -EINVAL; } diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index b9cc0dabc1bf..d6cf64742cb4 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2096,19 +2096,22 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) } } } - inst->in_flush = false; flush_event.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE; ptr = (u32 *)flush_event.u.data; flush_type = response->data.flush_type; switch (flush_type) { case HAL_FLUSH_INPUT: + inst->in_flush = false; ptr[0] = V4L2_CMD_FLUSH_OUTPUT; break; case HAL_FLUSH_OUTPUT: + inst->out_flush = false; ptr[0] = V4L2_CMD_FLUSH_CAPTURE; break; case HAL_FLUSH_ALL: + inst->in_flush = false; + inst->out_flush = false; ptr[0] |= V4L2_CMD_FLUSH_CAPTURE; ptr[0] |= V4L2_CMD_FLUSH_OUTPUT; break; @@ -5391,14 +5394,20 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) core = inst->core; hdev = core->device; - ip_flush = flags & V4L2_CMD_FLUSH_OUTPUT; - op_flush = flags & V4L2_CMD_FLUSH_CAPTURE; + ip_flush = !!(flags & V4L2_CMD_FLUSH_OUTPUT); + op_flush = !!(flags & V4L2_CMD_FLUSH_CAPTURE); if (ip_flush && !op_flush) { dprintk(VIDC_ERR, "Input only flush not supported, making it flush all\n"); op_flush = true; - return 0; + goto exit; + } + + if ((inst->in_flush && ip_flush) || (inst->out_flush && op_flush)) { + dprintk(VIDC_ERR, "%s: %x : Already in flush\n", + __func__, hash32_ptr(inst->session)); + goto exit; } msm_clock_data_reset(inst); @@ -5409,12 +5418,13 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) "Core %pK and inst %pK are in bad state\n", core, inst); msm_comm_flush_in_invalid_state(inst); - return 0; + goto exit; } mutex_lock(&inst->flush_lock); /* enable in flush */ - inst->in_flush = true; + inst->in_flush = ip_flush; + inst->out_flush = op_flush; mutex_lock(&inst->registeredbufs.lock); list_for_each_entry_safe(mbuf, next, &inst->registeredbufs.list, list) { @@ -5472,10 +5482,12 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) dprintk(VIDC_ERR, "Sending flush to firmware failed, flush out all buffers\n"); msm_comm_flush_in_invalid_state(inst); - /* disable in_flush */ + /* disable in_flush & out_flush */ inst->in_flush = false; + inst->out_flush = false; } +exit: return rc; } @@ -6850,7 +6862,7 @@ void handle_release_buffer_reference(struct msm_vidc_inst *inst, goto unlock; /* buffer found means client queued the buffer already */ - if (inst->in_reconfig || inst->in_flush) { + if (inst->in_reconfig || inst->out_flush) { print_vidc_buffer(VIDC_HIGH, "rbr flush buf", inst, mbuf); msm_comm_flush_vidc_buffer(inst, mbuf); msm_comm_unmap_vidc_buffer(inst, mbuf); diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index af433a2a17eb..1474af4eea3a 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -526,6 +526,7 @@ struct msm_vidc_inst { int bit_depth; struct kref kref; bool in_flush; + bool out_flush; u32 pic_struct; u32 colour_space; u32 profile; From 09a93f806ba6d450629e91ff152cbe83c7d6ae96 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Sun, 21 Jul 2019 00:47:05 +0530 Subject: [PATCH 133/452] msm: vidc: add support for input_tag, input_tag2 and sub-frame info 1. Client needs input etb to output fbd association. Introducing input_tag and input_tag2 fields for this. Client will send input_tag via etb reserved fields and client will get back those as part of fbd reserved fields. 2. Convey sub-frame information to client from firmware. CRs-Fixed: 2494945 Change-Id: Ic64131c7f8f3e3035cd6ff3997fe483171d71fc4 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_packetization.c | 8 +- msm/vidc/hfi_response_handler.c | 12 +-- msm/vidc/msm_vidc.c | 61 +++++++++--- msm/vidc/msm_vidc_common.c | 165 ++++++++++++++++++++++++++------ msm/vidc/msm_vidc_common.h | 15 ++- msm/vidc/msm_vidc_internal.h | 12 ++- msm/vidc/vidc_hfi.h | 16 ++-- msm/vidc/vidc_hfi_api.h | 12 +-- 8 files changed, 224 insertions(+), 77 deletions(-) diff --git a/msm/vidc/hfi_packetization.c b/msm/vidc/hfi_packetization.c index 71efb4c7412c..ebd8066aeba9 100644 --- a/msm/vidc/hfi_packetization.c +++ b/msm/vidc/hfi_packetization.c @@ -632,12 +632,10 @@ int create_pkt_cmd_session_etb_decoder( pkt->time_stamp_hi = upper_32_bits(input_frame->timestamp); pkt->time_stamp_lo = lower_32_bits(input_frame->timestamp); pkt->flags = input_frame->flags; - pkt->mark_target = input_frame->mark_target; - pkt->mark_data = input_frame->mark_data; pkt->offset = input_frame->offset; pkt->alloc_len = input_frame->alloc_len; pkt->filled_len = input_frame->filled_len; - pkt->input_tag = input_frame->clnt_data; + pkt->input_tag = input_frame->input_tag; pkt->packet_buffer = (u32)input_frame->device_addr; trace_msm_v4l2_vidc_buffer_event_start("ETB", @@ -667,12 +665,10 @@ int create_pkt_cmd_session_etb_encoder( pkt->time_stamp_hi = upper_32_bits(input_frame->timestamp); pkt->time_stamp_lo = lower_32_bits(input_frame->timestamp); pkt->flags = input_frame->flags; - pkt->mark_target = input_frame->mark_target; - pkt->mark_data = input_frame->mark_data; pkt->offset = input_frame->offset; pkt->alloc_len = input_frame->alloc_len; pkt->filled_len = input_frame->filled_len; - pkt->input_tag = input_frame->clnt_data; + pkt->input_tag = input_frame->input_tag; pkt->packet_buffer = (u32)input_frame->device_addr; pkt->extra_data_buffer = (u32)input_frame->extradata_addr; diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index 63c25b35d5ea..d452a33515e7 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -780,7 +780,7 @@ static int hfi_process_session_etb_done(u32 device_id, data_done.session_id = (void *)(uintptr_t)pkt->session_id; data_done.status = hfi_map_err_status(pkt->error_type); data_done.size = sizeof(struct msm_vidc_cb_data_done); - data_done.clnt_data = pkt->input_tag; + data_done.input_done.input_tag = pkt->input_tag; data_done.input_done.recon_stats.buffer_index = pkt->ubwc_cr_stats.frame_index; memcpy(&data_done.input_done.recon_stats.ubwc_stats_info, @@ -857,13 +857,11 @@ static int hfi_process_session_ftb_done( data_done.session_id = (void *)(uintptr_t)pkt->session_id; data_done.status = hfi_map_err_status(pkt->error_type); data_done.size = sizeof(struct msm_vidc_cb_data_done); - data_done.clnt_data = 0; + data_done.output_done.input_tag = pkt->input_tag; data_done.output_done.timestamp_hi = pkt->time_stamp_hi; data_done.output_done.timestamp_lo = pkt->time_stamp_lo; data_done.output_done.flags1 = pkt->flags; - data_done.output_done.mark_target = pkt->mark_target; - data_done.output_done.mark_data = pkt->mark_data; data_done.output_done.stats = pkt->stats; data_done.output_done.offset1 = pkt->offset; data_done.output_done.alloc_len1 = pkt->alloc_len; @@ -892,15 +890,12 @@ static int hfi_process_session_ftb_done( data_done.session_id = (void *)(uintptr_t)pkt->session_id; data_done.status = hfi_map_err_status(pkt->error_type); data_done.size = sizeof(struct msm_vidc_cb_data_done); - data_done.clnt_data = 0; data_done.output_done.stream_id = pkt->stream_id; data_done.output_done.view_id = pkt->view_id; data_done.output_done.timestamp_hi = pkt->time_stamp_hi; data_done.output_done.timestamp_lo = pkt->time_stamp_lo; data_done.output_done.flags1 = pkt->flags; - data_done.output_done.mark_target = pkt->mark_target; - data_done.output_done.mark_data = pkt->mark_data; data_done.output_done.stats = pkt->stats; data_done.output_done.alloc_len1 = pkt->alloc_len; data_done.output_done.filled_len1 = pkt->filled_len; @@ -909,7 +904,8 @@ static int hfi_process_session_ftb_done( data_done.output_done.frame_height = pkt->frame_height; data_done.output_done.start_x_coord = pkt->start_x_coord; data_done.output_done.start_y_coord = pkt->start_y_coord; - data_done.output_done.input_tag1 = pkt->input_tag; + data_done.output_done.input_tag = pkt->input_tag; + data_done.output_done.input_tag2 = pkt->input_tag2; data_done.output_done.picture_type = pkt->picture_type; data_done.output_done.packet_buffer1 = pkt->packet_buffer; data_done.output_done.extra_data_buffer = diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 5032227a7f29..08ac0f84a470 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -329,6 +329,7 @@ EXPORT_SYMBOL(msm_vidc_release_buffer); int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) { struct msm_vidc_inst *inst = instance; + struct msm_vidc_client_data *client_data = NULL; int rc = 0; unsigned int i = 0; struct buf_queue *q = NULL; @@ -364,10 +365,17 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) msm_comm_update_input_cr(inst, b->index, cr); } - if (inst->session_type == MSM_VIDC_DECODER && - b->type == INPUT_MPLANE) { - msm_comm_store_mark_data(&inst->etb_data, b->index, - b->m.planes[0].reserved[3], b->m.planes[0].reserved[4]); + if (b->type == INPUT_MPLANE) { + client_data = msm_comm_store_client_data(inst, + b->m.planes[0].reserved[3]); + if (!client_data) { + dprintk(VIDC_ERR, + "%s: %x: failed to store client data\n", + __func__, hash32_ptr(inst->session)); + return -EINVAL; + } + msm_comm_store_input_tag(&inst->etb_data, b->index, + client_data->id, 0); } q = msm_comm_get_vb2q(inst, b->type); @@ -393,6 +401,8 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) int rc = 0; unsigned int i = 0; struct buf_queue *q = NULL; + u32 input_tag = 0, input_tag2 = 0; + bool remove; if (!inst || !b || !valid_v4l2_buffer(b, inst)) { dprintk(VIDC_ERR, "%s: invalid params, inst %pK\n", @@ -421,12 +431,34 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) b->m.planes[i].reserved[0] = b->m.planes[i].m.fd; b->m.planes[i].reserved[1] = b->m.planes[i].data_offset; } - - if (inst->session_type == MSM_VIDC_DECODER && - b->type == OUTPUT_MPLANE) { - msm_comm_fetch_mark_data(&inst->fbd_data, b->index, - &b->m.planes[0].reserved[3], - &b->m.planes[0].reserved[4]); + /** + * Flush handling: + * Don't fetch tag - if flush issued at input/output port. + * Fetch tag - if atleast 1 ebd received after flush. (Flush_done + * event may be notified to userspace even before client + * dequeus all buffers at FBD, to avoid this race condition + * fetch tag atleast 1 ETB is successfully processed after flush) + */ + if (b->type == OUTPUT_MPLANE && !inst->in_flush && + !inst->out_flush && inst->clk_data.buffer_counter) { + rc = msm_comm_fetch_input_tag(&inst->fbd_data, b->index, + &input_tag, &input_tag2); + if (rc) { + dprintk(VIDC_ERR, "Failed to fetch input tag"); + return -EINVAL; + } + /** + * During flush input_tag & input_tag2 will be zero. + * Check before retrieving client data + */ + if (input_tag) { + remove = !(b->flags & V4L2_BUF_FLAG_END_OF_SUBFRAME) && + !(b->flags & V4L2_BUF_FLAG_CODECCONFIG); + msm_comm_fetch_client_data(inst, remove, + input_tag, input_tag2, + &b->m.planes[0].reserved[3], + &b->m.planes[0].reserved[4]); + } } return rc; @@ -1552,6 +1584,7 @@ void *msm_vidc_open(int core_id, int session_type) INIT_MSM_VIDC_LIST(&inst->cvpbufs); INIT_MSM_VIDC_LIST(&inst->refbufs); INIT_MSM_VIDC_LIST(&inst->eosbufs); + INIT_MSM_VIDC_LIST(&inst->client_data); INIT_MSM_VIDC_LIST(&inst->etb_data); INIT_MSM_VIDC_LIST(&inst->fbd_data); INIT_MSM_VIDC_LIST(&inst->window_data); @@ -1667,6 +1700,7 @@ void *msm_vidc_open(int core_id, int session_type) DEINIT_MSM_VIDC_LIST(&inst->eosbufs); DEINIT_MSM_VIDC_LIST(&inst->freqs); DEINIT_MSM_VIDC_LIST(&inst->input_crs); + DEINIT_MSM_VIDC_LIST(&inst->client_data); DEINIT_MSM_VIDC_LIST(&inst->etb_data); DEINIT_MSM_VIDC_LIST(&inst->fbd_data); DEINIT_MSM_VIDC_LIST(&inst->window_data); @@ -1737,9 +1771,11 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst) dprintk(VIDC_ERR, "Failed to release persist buffers\n"); - if (msm_comm_release_mark_data(inst)) + if (msm_comm_release_input_tag(inst)) dprintk(VIDC_ERR, - "Failed to release mark_data buffers\n"); + "Failed to release input_tag buffers\n"); + + msm_comm_release_client_data(inst); msm_comm_release_window_data(inst); @@ -1801,6 +1837,7 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) DEINIT_MSM_VIDC_LIST(&inst->eosbufs); DEINIT_MSM_VIDC_LIST(&inst->freqs); DEINIT_MSM_VIDC_LIST(&inst->input_crs); + DEINIT_MSM_VIDC_LIST(&inst->client_data); DEINIT_MSM_VIDC_LIST(&inst->etb_data); DEINIT_MSM_VIDC_LIST(&inst->fbd_data); DEINIT_MSM_VIDC_LIST(&inst->window_data); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index b9cc0dabc1bf..01bc18e8f9fc 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2117,8 +2117,10 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) goto exit; } - if (flush_type == HAL_FLUSH_ALL) + if (flush_type == HAL_FLUSH_ALL) { msm_comm_release_window_data(inst); + msm_comm_release_client_data(inst); + } dprintk(VIDC_HIGH, "Notify flush complete, flush_type: %x\n", flush_type); @@ -2650,10 +2652,9 @@ static void handle_fbd(enum hal_command_response cmd, void *data) vb->timestamp = (time_usec * NSEC_PER_USEC); - if (inst->session_type == MSM_VIDC_DECODER) { - msm_comm_store_mark_data(&inst->fbd_data, vb->index, - fill_buf_done->mark_data, fill_buf_done->mark_target); - } + msm_comm_store_input_tag(&inst->fbd_data, vb->index, + fill_buf_done->input_tag, fill_buf_done->input_tag2); + if (inst->session_type == MSM_VIDC_ENCODER) { msm_comm_store_filled_length(&inst->fbd_data, vb->index, fill_buf_done->filled_len1); @@ -2674,6 +2675,8 @@ static void handle_fbd(enum hal_command_response cmd, void *data) mbuf->vvb.flags |= V4L2_BUF_FLAG_KEYFRAME; if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DATACORRUPT) mbuf->vvb.flags |= V4L2_BUF_FLAG_DATA_CORRUPT; + if (fill_buf_done->flags1 & HAL_BUFFERFLAG_ENDOFSUBFRAME) + mbuf->vvb.flags |= V4L2_BUF_FLAG_END_OF_SUBFRAME; switch (fill_buf_done->picture_type) { case HFI_PICTURE_TYPE_P: mbuf->vvb.flags |= V4L2_BUF_FLAG_PFRAME; @@ -4036,7 +4039,7 @@ int msm_vidc_send_pending_eos_buffers(struct msm_vidc_inst *inst) list_for_each_entry_safe(binfo, temp, &inst->eosbufs.list, list) { data.alloc_len = binfo->smem.size; data.device_addr = binfo->smem.device_addr; - data.clnt_data = data.device_addr; + data.input_tag = 0; data.buffer_type = HAL_BUFFER_INPUT; data.filled_len = 0; data.offset = 0; @@ -4183,6 +4186,7 @@ static void populate_frame_data(struct vidc_frame_data *data, struct v4l2_format *f = NULL; struct vb2_buffer *vb; struct vb2_v4l2_buffer *vbuf; + u32 itag = 0, itag2 = 0; if (!inst || !mbuf || !data) { dprintk(VIDC_ERR, "%s: invalid params %pK %pK %pK\n", @@ -4200,7 +4204,7 @@ static void populate_frame_data(struct vidc_frame_data *data, data->device_addr = mbuf->smem[0].device_addr; data->timestamp = time_usec; data->flags = 0; - data->clnt_data = data->device_addr; + data->input_tag = 0; if (vb->type == INPUT_MPLANE) { data->buffer_type = HAL_BUFFER_INPUT; @@ -4213,10 +4217,10 @@ static void populate_frame_data(struct vidc_frame_data *data, if (vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG) data->flags |= HAL_BUFFERFLAG_CODECCONFIG; - if (inst->session_type == MSM_VIDC_DECODER) { - msm_comm_fetch_mark_data(&inst->etb_data, vb->index, - &data->mark_data, &data->mark_target); - } + msm_comm_fetch_input_tag(&inst->etb_data, vb->index, + &itag, &itag2); + data->input_tag = itag; + f = &inst->fmts[INPUT_PORT].v4l2_fmt; } else if (vb->type == OUTPUT_MPLANE) { data->buffer_type = msm_comm_get_hal_output_buffer(inst); @@ -6949,6 +6953,110 @@ bool kref_get_mbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) return ret; } +struct msm_vidc_client_data *msm_comm_store_client_data( + struct msm_vidc_inst *inst, u32 itag) +{ + struct msm_vidc_client_data *data = NULL; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params %pK %un", + __func__, inst, itag); + return NULL; + } + + mutex_lock(&inst->client_data.lock); + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + dprintk(VIDC_ERR, "No memory left to allocate tag data"); + goto exit; + } + + /** + * Special handling, if etb_counter reaches to 2^32 - 1, + * then start next value from 1 not 0. + */ + if (!inst->etb_counter) + inst->etb_counter = 1; + + INIT_LIST_HEAD(&data->list); + data->id = inst->etb_counter++; + data->input_tag = itag; + list_add_tail(&data->list, &inst->client_data.list); + +exit: + mutex_unlock(&inst->client_data.lock); + + return data; +} + +void msm_comm_fetch_client_data(struct msm_vidc_inst *inst, bool remove, + u32 itag, u32 itag2, u32 *otag, u32 *otag2) +{ + struct msm_vidc_client_data *temp, *next; + bool found_itag = false, found_itag2 = false; + + if (!inst || !otag || !otag2) { + dprintk(VIDC_ERR, "%s: invalid params %pK %x %x\n", + __func__, inst, otag, otag2); + return; + } + + mutex_lock(&inst->client_data.lock); + list_for_each_entry_safe(temp, next, &inst->client_data.list, list) { + if (temp->id == itag) { + *otag = temp->input_tag; + if (remove) { + list_del(&temp->list); + kfree(temp); + } + found_itag = true; + /** + * Some interlace clips, both BF & TP is available in + * single ETB buffer. In that case, firmware copies + * same input_tag value to both input_tag and + * input_tag2 at FBD. + */ + if (!itag2 || itag == itag2) { + found_itag2 = true; + break; + } + } else if (temp->id == itag2) { + *otag2 = temp->input_tag; + found_itag2 = true; + if (remove) { + list_del(&temp->list); + kfree(temp); + } + } + if (found_itag && found_itag2) + break; + } + mutex_unlock(&inst->client_data.lock); + + if (!found_itag || !found_itag2) { + dprintk(VIDC_ERR, "%s: %x: client data not found - %u, %u\n", + __func__, hash32_ptr(inst->session), itag, itag2); + } +} + +void msm_comm_release_client_data(struct msm_vidc_inst *inst) +{ + struct msm_vidc_client_data *temp, *next; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params %pK\n", + __func__, inst); + return; + } + + mutex_lock(&inst->client_data.lock); + list_for_each_entry_safe(temp, next, &inst->client_data.list, list) { + list_del(&temp->list); + kfree(temp); + } + mutex_unlock(&inst->client_data.lock); +} + void msm_comm_store_filled_length(struct msm_vidc_list *data_list, u32 index, u32 filled_length) { @@ -7006,8 +7114,8 @@ void msm_comm_fetch_filled_length(struct msm_vidc_list *data_list, mutex_unlock(&data_list->lock); } -void msm_comm_store_mark_data(struct msm_vidc_list *data_list, - u32 index, u32 mark_data, u32 mark_target) +void msm_comm_store_input_tag(struct msm_vidc_list *data_list, + u32 index, u32 itag, u32 itag2) { struct msm_vidc_buf_data *pdata = NULL; bool found = false; @@ -7021,8 +7129,8 @@ void msm_comm_store_mark_data(struct msm_vidc_list *data_list, mutex_lock(&data_list->lock); list_for_each_entry(pdata, &data_list->list, list) { if (pdata->index == index) { - pdata->mark_data = mark_data; - pdata->mark_target = mark_target; + pdata->input_tag = itag; + pdata->input_tag2 = itag2; found = true; break; } @@ -7035,8 +7143,8 @@ void msm_comm_store_mark_data(struct msm_vidc_list *data_list, goto exit; } pdata->index = index; - pdata->mark_data = mark_data; - pdata->mark_target = mark_target; + pdata->input_tag = itag; + pdata->input_tag2 = itag2; list_add_tail(&pdata->list, &data_list->list); } @@ -7044,32 +7152,35 @@ void msm_comm_store_mark_data(struct msm_vidc_list *data_list, mutex_unlock(&data_list->lock); } -void msm_comm_fetch_mark_data(struct msm_vidc_list *data_list, - u32 index, u32 *mark_data, u32 *mark_target) +int msm_comm_fetch_input_tag(struct msm_vidc_list *data_list, + u32 index, u32 *itag, u32 *itag2) { struct msm_vidc_buf_data *pdata = NULL; + int rc = 0; - if (!data_list || !mark_data || !mark_target) { + if (!data_list || !itag || !itag2) { dprintk(VIDC_ERR, "%s: invalid params %pK %pK %pK\n", - __func__, data_list, mark_data, mark_target); - return; + __func__, data_list, itag, itag2); + return -EINVAL; } - *mark_data = *mark_target = 0; + *itag = *itag2 = 0; mutex_lock(&data_list->lock); list_for_each_entry(pdata, &data_list->list, list) { if (pdata->index == index) { - *mark_data = pdata->mark_data; - *mark_target = pdata->mark_target; + *itag = pdata->input_tag; + *itag2 = pdata->input_tag2; /* clear after fetch */ - pdata->mark_data = pdata->mark_target = 0; + pdata->input_tag = pdata->input_tag2 = 0; break; } } mutex_unlock(&data_list->lock); + + return rc; } -int msm_comm_release_mark_data(struct msm_vidc_inst *inst) +int msm_comm_release_input_tag(struct msm_vidc_inst *inst) { struct msm_vidc_buf_data *pdata, *next; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index e5ae8c80d803..f5515daecef1 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -295,11 +295,16 @@ void msm_comm_store_filled_length(struct msm_vidc_list *data_list, u32 index, u32 filled_length); void msm_comm_fetch_filled_length(struct msm_vidc_list *data_list, u32 index, u32 *filled_length); -void msm_comm_store_mark_data(struct msm_vidc_list *data_list, - u32 index, u32 mark_data, u32 mark_target); -void msm_comm_fetch_mark_data(struct msm_vidc_list *data_list, - u32 index, u32 *mark_data, u32 *mark_target); -int msm_comm_release_mark_data(struct msm_vidc_inst *inst); +void msm_comm_store_input_tag(struct msm_vidc_list *data_list, + u32 index, u32 itag, u32 itag2); +int msm_comm_fetch_input_tag(struct msm_vidc_list *data_list, + u32 index, u32 *itag, u32 *itag2); +int msm_comm_release_input_tag(struct msm_vidc_inst *inst); +struct msm_vidc_client_data *msm_comm_store_client_data( + struct msm_vidc_inst *inst, u32 itag); +void msm_comm_fetch_client_data(struct msm_vidc_inst *inst, bool remove, + u32 itag, u32 itag2, u32 *mdata, u32 *mtarget); +void msm_comm_release_client_data(struct msm_vidc_inst *inst); int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst, diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index af433a2a17eb..896c3dfa33d8 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -205,8 +205,8 @@ struct msm_vidc_csc_coeff { struct msm_vidc_buf_data { struct list_head list; u32 index; - u32 mark_data; - u32 mark_target; + u32 input_tag; + u32 input_tag2; u32 filled_length; }; @@ -216,6 +216,12 @@ struct msm_vidc_window_data { u32 etb_count; }; +struct msm_vidc_client_data { + struct list_head list; + u32 id; + u32 input_tag; +}; + struct msm_vidc_common_data { char key[128]; int value; @@ -503,6 +509,7 @@ struct msm_vidc_inst { struct msm_vidc_list etb_data; struct msm_vidc_list fbd_data; struct msm_vidc_list window_data; + struct msm_vidc_list client_data; struct buffer_requirements buff_req; struct vidc_frame_data superframe_data[VIDC_SUPERFRAME_MAX]; struct v4l2_ctrl_handler ctrl_handler; @@ -523,6 +530,7 @@ struct msm_vidc_inst { enum multi_stream stream_output_mode; struct v4l2_ctrl **ctrls; u32 num_ctrls; + u32 etb_counter; int bit_depth; struct kref kref; bool in_flush; diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index 24be24e061c3..8b9d20dcbbd2 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -397,8 +397,8 @@ struct hfi_cmd_session_empty_buffer_compressed_packet { u32 time_stamp_hi; u32 time_stamp_lo; u32 flags; - u32 mark_target; - u32 mark_data; + u32 mark_target; /* not used anywhere */ + u32 mark_data; /* not used anywhere */ u32 offset; u32 alloc_len; u32 filled_len; @@ -416,8 +416,8 @@ struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet { u32 time_stamp_hi; u32 time_stamp_lo; u32 flags; - u32 mark_target; - u32 mark_data; + u32 mark_target; /* not used anywhere */ + u32 mark_data; /* not used anywhere */ u32 alloc_len; u32 filled_len; u32 offset; @@ -601,8 +601,8 @@ struct hfi_msg_session_fill_buffer_done_compressed_packet { u32 time_stamp_lo; u32 error_type; u32 flags; - u32 mark_target; - u32 mark_data; + u32 mark_target; /* not used anywhere */ + u32 mark_data; /* not used anywhere */ u32 stats; u32 offset; u32 alloc_len; @@ -625,8 +625,8 @@ struct hfi_msg_session_fbd_uncompressed_plane0_packet { u32 time_stamp_hi; u32 time_stamp_lo; u32 flags; - u32 mark_target; - u32 mark_data; + u32 mark_target; /* not used anywhere */ + u32 mark_data; /* not used anywhere */ u32 stats; u32 alloc_len; u32 filled_len; diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index ba21bbdeecc0..0b34ee56d7df 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -399,9 +399,7 @@ struct vidc_frame_data { u32 offset; u32 alloc_len; u32 filled_len; - u32 mark_target; - u32 mark_data; - u32 clnt_data; + u32 input_tag; u32 extradata_size; }; @@ -524,8 +522,7 @@ struct vidc_hal_ebd { u32 timestamp_lo; u32 flags; enum vidc_status status; - u32 mark_target; - u32 mark_data; + u32 input_tag; u32 stats; u32 offset; u32 alloc_len; @@ -542,8 +539,6 @@ struct vidc_hal_fbd { u32 timestamp_hi; u32 timestamp_lo; u32 flags1; - u32 mark_target; - u32 mark_data; u32 stats; u32 alloc_len1; u32 filled_len1; @@ -553,7 +548,7 @@ struct vidc_hal_fbd { u32 start_x_coord; u32 start_y_coord; u32 input_tag; - u32 input_tag1; + u32 input_tag2; u32 picture_type; u32 packet_buffer1; u32 extra_data_buffer; @@ -638,7 +633,6 @@ struct msm_vidc_cb_data_done { void *session_id; enum vidc_status status; u32 size; - u32 clnt_data; union { struct vidc_hal_ebd input_done; struct vidc_hal_fbd output_done; From 4a3506cb7da16b259a7bdb45c7b04cca2cdbc564 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Thu, 8 Aug 2019 15:38:25 +0530 Subject: [PATCH 134/452] msm: vidc: make venus_hfi_device as a static variable 1. Mostly venus_hfi_device ptr is derived from hal_session (session->device). During session close hal_session is freed in forward path and at the same time RBR arrives at feed_back path leads to race condition. 2. If forward threads acquires device->lock first then reverse thread may have stale device ptr(which is already freed), accessing that ptr leads to device crash 3. To avoid refrencing device from hal_session, made venus_hfi_device as a static variable within hfi_common Change-Id: Ic5db6d4f6da6da08e16f4f00a06a3c4fec4f9c6e Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_common.c | 278 ++++++++++++------------------------------ msm/vidc/vidc_hfi.h | 1 - 2 files changed, 77 insertions(+), 202 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 429ea53534d5..4e823981b52c 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -39,6 +39,7 @@ #define MIN_PAYLOAD_SIZE 3 static struct hal_device_data hal_ctxt; +static struct venus_hfi_device venus_hfi_dev; #define TZBSP_MEM_PROTECT_VIDEO_VAR 0x8 struct tzbsp_memprot { @@ -432,6 +433,9 @@ static int __session_pause(struct venus_hfi_device *device, { int rc = 0; + if (!__is_session_valid(device, session, __func__)) + return -EINVAL; + /* ignore if session paused already */ if (session->flags & SESSION_PAUSE) return 0; @@ -448,6 +452,9 @@ static int __session_resume(struct venus_hfi_device *device, { int rc = 0; + if (!__is_session_valid(device, session, __func__)) + return -EINVAL; + /* ignore if session already resumed */ if (!(session->flags & SESSION_PAUSE)) return 0; @@ -476,13 +483,7 @@ static int venus_hfi_session_pause(void *sess) { int rc; struct hal_session *session = sess; - struct venus_hfi_device *device; - - if (!session || !session->device) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); - return -EINVAL; - } - device = session->device; + struct venus_hfi_device *device = &venus_hfi_dev; mutex_lock(&device->lock); rc = __session_pause(device, session); @@ -495,13 +496,7 @@ static int venus_hfi_session_resume(void *sess) { int rc; struct hal_session *session = sess; - struct venus_hfi_device *device; - - if (!session || !session->device) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); - return -EINVAL; - } - device = session->device; + struct venus_hfi_device *device = &venus_hfi_dev; mutex_lock(&device->lock); rc = __session_resume(device, session); @@ -694,7 +689,6 @@ static void __hal_sim_modify_msg_packet(u8 *packet, fw_bias = device->hal_data->firmware_base; init_done = (struct hfi_msg_sys_session_init_done_packet *)packet; session = __get_session(device, init_done->session_id); - if (!session) { dprintk(VIDC_ERR, "%s: Invalid session id: %x\n", __func__, init_done->session_id); @@ -1245,7 +1239,6 @@ static int venus_hfi_flush_debug_queue(void *dev) } mutex_lock(&device->lock); - if (!device->power_enabled) { dprintk(VIDC_ERR, "%s: venus power off\n", __func__); rc = -EINVAL; @@ -2262,15 +2255,9 @@ static int venus_hfi_session_set_property(void *sess, struct hfi_cmd_session_set_property_packet *pkt = (struct hfi_cmd_session_set_property_packet *) &packet; struct hal_session *session = sess; - struct venus_hfi_device *device; + struct venus_hfi_device *device = &venus_hfi_dev; int rc = 0; - if (!session || !session->device) { - dprintk(VIDC_ERR, "Invalid Params\n"); - return -EINVAL; - } - - device = session->device; mutex_lock(&device->lock); dprintk(VIDC_HIGH, "in set_prop,with prop id: %#x\n", ptype); @@ -2293,7 +2280,7 @@ static int venus_hfi_session_set_property(void *sess, goto err_set_prop; } - if (__iface_cmdq_write(session->device, pkt)) { + if (__iface_cmdq_write(device, pkt)) { rc = -ENOTEMPTY; goto err_set_prop; } @@ -2315,13 +2302,10 @@ static void __set_default_sys_properties(struct venus_hfi_device *device) static void __session_clean(struct hal_session *session) { struct hal_session *temp, *next; - struct venus_hfi_device *device; + struct venus_hfi_device *device = &venus_hfi_dev; - if (!session || !session->device) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + if (!__is_session_valid(device, session, __func__)) return; - } - device = session->device; dprintk(VIDC_HIGH, "deleted the session: %pK\n", session); /* * session might have been removed from the device list in @@ -2338,28 +2322,13 @@ static void __session_clean(struct hal_session *session) kfree(session); } -static int venus_hfi_session_clean(void *session) +static int venus_hfi_session_clean(void *sess) { - struct hal_session *sess_close; - struct venus_hfi_device *device; - - if (!session) { - dprintk(VIDC_ERR, "Invalid Params %s\n", __func__); - return -EINVAL; - } - - sess_close = session; - device = sess_close->device; - - if (!device) { - dprintk(VIDC_ERR, "Invalid device handle %s\n", __func__); - return -EINVAL; - } + struct hal_session *session = sess; + struct venus_hfi_device *device = &venus_hfi_dev; mutex_lock(&device->lock); - - __session_clean(sess_close); - + __session_clean(session); mutex_unlock(&device->lock); return 0; } @@ -2388,7 +2357,6 @@ static int venus_hfi_session_init(void *device, void *session_id, s->session_id = session_id; s->is_decoder = (session_type == HAL_VIDEO_DOMAIN_DECODER); - s->device = dev; s->codec = codec_type; s->domain = session_type; dprintk(VIDC_HIGH|VIDC_PERF, @@ -2424,7 +2392,7 @@ static int __send_session_cmd(struct hal_session *session, int pkt_type) { struct vidc_hal_session_cmd_pkt pkt; int rc = 0; - struct venus_hfi_device *device = session->device; + struct venus_hfi_device *device = &venus_hfi_dev; if (!__is_session_valid(device, session, __func__)) return -EINVAL; @@ -2439,31 +2407,23 @@ static int __send_session_cmd(struct hal_session *session, int pkt_type) goto err_create_pkt; } - if (__iface_cmdq_write(session->device, &pkt)) + if (__iface_cmdq_write(device, &pkt)) rc = -ENOTEMPTY; err_create_pkt: return rc; } -static int venus_hfi_session_end(void *session) +static int venus_hfi_session_end(void *sess) { - struct hal_session *sess; - struct venus_hfi_device *device; + struct hal_session *session = sess; + struct venus_hfi_device *device = &venus_hfi_dev; int rc = 0; - if (!session) { - dprintk(VIDC_ERR, "Invalid Params %s\n", __func__); - return -EINVAL; - } - - sess = session; - device = sess->device; - mutex_lock(&device->lock); if (msm_vidc_fw_coverage) { - if (__sys_set_coverage(sess->device, msm_vidc_fw_coverage)) + if (__sys_set_coverage(device, msm_vidc_fw_coverage)) dprintk(VIDC_ERR, "Fw_coverage msg ON failed\n"); } @@ -2477,16 +2437,9 @@ static int venus_hfi_session_end(void *session) static int venus_hfi_session_abort(void *sess) { struct hal_session *session = sess; - struct venus_hfi_device *device; + struct venus_hfi_device *device = &venus_hfi_dev; int rc = 0; - if (!session || !session->device) { - dprintk(VIDC_ERR, "Invalid Params %s\n", __func__); - return -EINVAL; - } - - device = session->device; - mutex_lock(&device->lock); __flush_debug_queue(device, NULL); @@ -2504,14 +2457,13 @@ static int venus_hfi_session_set_buffers(void *sess, u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE]; int rc = 0; struct hal_session *session = sess; - struct venus_hfi_device *device; + struct venus_hfi_device *device = &venus_hfi_dev; - if (!session || !session->device || !buffer_info) { + if (!buffer_info) { dprintk(VIDC_ERR, "Invalid Params\n"); return -EINVAL; } - device = session->device; mutex_lock(&device->lock); if (!__is_session_valid(device, session, __func__)) { @@ -2537,7 +2489,7 @@ static int venus_hfi_session_set_buffers(void *sess, } dprintk(VIDC_HIGH, "set buffers: %#x\n", buffer_info->buffer_type); - if (__iface_cmdq_write(session->device, pkt)) + if (__iface_cmdq_write(device, pkt)) rc = -ENOTEMPTY; err_create_pkt: @@ -2552,14 +2504,13 @@ static int venus_hfi_session_release_buffers(void *sess, u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE]; int rc = 0; struct hal_session *session = sess; - struct venus_hfi_device *device; + struct venus_hfi_device *device = &venus_hfi_dev; - if (!session || !session->device || !buffer_info) { + if (!buffer_info) { dprintk(VIDC_ERR, "Invalid Params\n"); return -EINVAL; } - device = session->device; mutex_lock(&device->lock); if (!__is_session_valid(device, session, __func__)) { @@ -2581,7 +2532,7 @@ static int venus_hfi_session_release_buffers(void *sess, } dprintk(VIDC_HIGH, "Release buffers: %#x\n", buffer_info->buffer_type); - if (__iface_cmdq_write(session->device, pkt)) + if (__iface_cmdq_write(device, pkt)) rc = -ENOTEMPTY; err_create_pkt: @@ -2596,13 +2547,12 @@ static int venus_hfi_session_register_buffer(void *sess, u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE]; struct hfi_cmd_session_register_buffers_packet *pkt; struct hal_session *session = sess; - struct venus_hfi_device *device; + struct venus_hfi_device *device = &venus_hfi_dev; - if (!session || !session->device || !buffer) { + if (!buffer) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; } - device = session->device; mutex_lock(&device->lock); if (!__is_session_valid(device, session, __func__)) { @@ -2616,7 +2566,7 @@ static int venus_hfi_session_register_buffer(void *sess, dprintk(VIDC_ERR, "%s: failed to create packet\n", __func__); goto exit; } - if (__iface_cmdq_write(session->device, pkt)) + if (__iface_cmdq_write(device, pkt)) rc = -ENOTEMPTY; exit: mutex_unlock(&device->lock); @@ -2631,13 +2581,12 @@ static int venus_hfi_session_unregister_buffer(void *sess, u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE]; struct hfi_cmd_session_unregister_buffers_packet *pkt; struct hal_session *session = sess; - struct venus_hfi_device *device; + struct venus_hfi_device *device = &venus_hfi_dev; - if (!session || !session->device || !buffer) { + if (!buffer) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; } - device = session->device; mutex_lock(&device->lock); if (!__is_session_valid(device, session, __func__)) { @@ -2651,7 +2600,7 @@ static int venus_hfi_session_unregister_buffer(void *sess, dprintk(VIDC_ERR, "%s: failed to create packet\n", __func__); goto exit; } - if (__iface_cmdq_write(session->device, pkt)) + if (__iface_cmdq_write(device, pkt)) rc = -ENOTEMPTY; exit: mutex_unlock(&device->lock); @@ -2659,106 +2608,66 @@ static int venus_hfi_session_unregister_buffer(void *sess, return rc; } -static int venus_hfi_session_load_res(void *session) +static int venus_hfi_session_load_res(void *sess) { - struct hal_session *sess; - struct venus_hfi_device *device; + struct hal_session *session = sess; + struct venus_hfi_device *device = &venus_hfi_dev; int rc = 0; - if (!session) { - dprintk(VIDC_ERR, "Invalid Params %s\n", __func__); - return -EINVAL; - } - - sess = session; - device = sess->device; - mutex_lock(&device->lock); - rc = __send_session_cmd(sess, HFI_CMD_SESSION_LOAD_RESOURCES); + rc = __send_session_cmd(session, HFI_CMD_SESSION_LOAD_RESOURCES); mutex_unlock(&device->lock); return rc; } -static int venus_hfi_session_release_res(void *session) +static int venus_hfi_session_release_res(void *sess) { - struct hal_session *sess; - struct venus_hfi_device *device; + struct hal_session *session = sess; + struct venus_hfi_device *device = &venus_hfi_dev; int rc = 0; - if (!session) { - dprintk(VIDC_ERR, "Invalid Params %s\n", __func__); - return -EINVAL; - } - - sess = session; - device = sess->device; - mutex_lock(&device->lock); - rc = __send_session_cmd(sess, HFI_CMD_SESSION_RELEASE_RESOURCES); + rc = __send_session_cmd(session, HFI_CMD_SESSION_RELEASE_RESOURCES); mutex_unlock(&device->lock); return rc; } -static int venus_hfi_session_start(void *session) +static int venus_hfi_session_start(void *sess) { - struct hal_session *sess; - struct venus_hfi_device *device; + struct hal_session *session = sess; + struct venus_hfi_device *device = &venus_hfi_dev; int rc = 0; - if (!session) { - dprintk(VIDC_ERR, "Invalid Params %s\n", __func__); - return -EINVAL; - } - - sess = session; - device = sess->device; - mutex_lock(&device->lock); - rc = __send_session_cmd(sess, HFI_CMD_SESSION_START); + rc = __send_session_cmd(session, HFI_CMD_SESSION_START); mutex_unlock(&device->lock); return rc; } -static int venus_hfi_session_continue(void *session) +static int venus_hfi_session_continue(void *sess) { - struct hal_session *sess; - struct venus_hfi_device *device; + struct hal_session *session = sess; + struct venus_hfi_device *device = &venus_hfi_dev; int rc = 0; - if (!session) { - dprintk(VIDC_ERR, "Invalid Params %s\n", __func__); - return -EINVAL; - } - - sess = session; - device = sess->device; - mutex_lock(&device->lock); - rc = __send_session_cmd(sess, HFI_CMD_SESSION_CONTINUE); + rc = __send_session_cmd(session, HFI_CMD_SESSION_CONTINUE); mutex_unlock(&device->lock); return rc; } -static int venus_hfi_session_stop(void *session) +static int venus_hfi_session_stop(void *sess) { - struct hal_session *sess; - struct venus_hfi_device *device; + struct hal_session *session = sess; + struct venus_hfi_device *device = &venus_hfi_dev; int rc = 0; - if (!session) { - dprintk(VIDC_ERR, "Invalid Params %s\n", __func__); - return -EINVAL; - } - - sess = session; - device = sess->device; - mutex_lock(&device->lock); - rc = __send_session_cmd(sess, HFI_CMD_SESSION_STOP); + rc = __send_session_cmd(session, HFI_CMD_SESSION_STOP); mutex_unlock(&device->lock); return rc; @@ -2768,7 +2677,7 @@ static int __session_etb(struct hal_session *session, struct vidc_frame_data *input_frame, bool relaxed) { int rc = 0; - struct venus_hfi_device *device = session->device; + struct venus_hfi_device *device = &venus_hfi_dev; if (!__is_session_valid(device, session, __func__)) return -EINVAL; @@ -2785,10 +2694,9 @@ static int __session_etb(struct hal_session *session, } if (!relaxed) - rc = __iface_cmdq_write(session->device, &pkt); + rc = __iface_cmdq_write(device, &pkt); else - rc = __iface_cmdq_write_relaxed(session->device, - &pkt, NULL); + rc = __iface_cmdq_write_relaxed(device, &pkt, NULL); if (rc) goto err_create_pkt; } else { @@ -2804,10 +2712,9 @@ static int __session_etb(struct hal_session *session, } if (!relaxed) - rc = __iface_cmdq_write(session->device, &pkt); + rc = __iface_cmdq_write(device, &pkt); else - rc = __iface_cmdq_write_relaxed(session->device, - &pkt, NULL); + rc = __iface_cmdq_write_relaxed(device, &pkt, NULL); if (rc) goto err_create_pkt; } @@ -2821,14 +2728,13 @@ static int venus_hfi_session_etb(void *sess, { int rc = 0; struct hal_session *session = sess; - struct venus_hfi_device *device; + struct venus_hfi_device *device = &venus_hfi_dev; - if (!session || !session->device || !input_frame) { + if (!input_frame) { dprintk(VIDC_ERR, "Invalid Params\n"); return -EINVAL; } - device = session->device; mutex_lock(&device->lock); rc = __session_etb(session, input_frame, false); mutex_unlock(&device->lock); @@ -2839,7 +2745,7 @@ static int __session_ftb(struct hal_session *session, struct vidc_frame_data *output_frame, bool relaxed) { int rc = 0; - struct venus_hfi_device *device = session->device; + struct venus_hfi_device *device = &venus_hfi_dev; struct hfi_cmd_session_fill_buffer_packet pkt; if (!__is_session_valid(device, session, __func__)) @@ -2853,10 +2759,9 @@ static int __session_ftb(struct hal_session *session, } if (!relaxed) - rc = __iface_cmdq_write(session->device, &pkt); + rc = __iface_cmdq_write(device, &pkt); else - rc = __iface_cmdq_write_relaxed(session->device, - &pkt, NULL); + rc = __iface_cmdq_write_relaxed(device, &pkt, NULL); err_create_pkt: return rc; @@ -2867,14 +2772,13 @@ static int venus_hfi_session_ftb(void *sess, { int rc = 0; struct hal_session *session = sess; - struct venus_hfi_device *device; + struct venus_hfi_device *device = &venus_hfi_dev; - if (!session || !session->device || !output_frame) { + if (!output_frame) { dprintk(VIDC_ERR, "Invalid Params\n"); return -EINVAL; } - device = session->device; mutex_lock(&device->lock); rc = __session_ftb(session, output_frame, false); mutex_unlock(&device->lock); @@ -2887,16 +2791,9 @@ static int venus_hfi_session_process_batch(void *sess, { int rc = 0, c = 0; struct hal_session *session = sess; - struct venus_hfi_device *device; + struct venus_hfi_device *device = &venus_hfi_dev; struct hfi_cmd_session_sync_process_packet pkt; - if (!session || !session->device) { - dprintk(VIDC_ERR, "%s: Invalid Params\n", __func__); - return -EINVAL; - } - - device = session->device; - mutex_lock(&device->lock); if (!__is_session_valid(device, session, __func__)) { @@ -2928,7 +2825,7 @@ static int venus_hfi_session_process_batch(void *sess, goto err_etbs_and_ftbs; } - if (__iface_cmdq_write(session->device, &pkt)) + if (__iface_cmdq_write(device, &pkt)) rc = -ENOTEMPTY; err_etbs_and_ftbs: @@ -2941,18 +2838,12 @@ static int venus_hfi_session_get_buf_req(void *sess) struct hfi_cmd_session_get_property_packet pkt; int rc = 0; struct hal_session *session = sess; - struct venus_hfi_device *device; + struct venus_hfi_device *device = &venus_hfi_dev; - if (!session || !session->device) { - dprintk(VIDC_ERR, "invalid session"); - return -ENODEV; - } - - device = session->device; mutex_lock(&device->lock); if (!__is_session_valid(device, session, __func__)) { - rc = -EINVAL; + rc = -ENODEV; goto err_create_pkt; } rc = call_hfi_pkt_op(device, session_get_buf_req, @@ -2963,7 +2854,7 @@ static int venus_hfi_session_get_buf_req(void *sess) goto err_create_pkt; } - if (__iface_cmdq_write(session->device, &pkt)) + if (__iface_cmdq_write(device, &pkt)) rc = -ENOTEMPTY; err_create_pkt: mutex_unlock(&device->lock); @@ -2975,18 +2866,12 @@ static int venus_hfi_session_flush(void *sess, enum hal_flush flush_mode) struct hfi_cmd_session_flush_packet pkt; int rc = 0; struct hal_session *session = sess; - struct venus_hfi_device *device; + struct venus_hfi_device *device = &venus_hfi_dev; - if (!session || !session->device) { - dprintk(VIDC_ERR, "invalid session"); - return -ENODEV; - } - - device = session->device; mutex_lock(&device->lock); if (!__is_session_valid(device, session, __func__)) { - rc = -EINVAL; + rc = -ENODEV; goto err_create_pkt; } rc = call_hfi_pkt_op(device, session_flush, @@ -2996,7 +2881,7 @@ static int venus_hfi_session_flush(void *sess, enum hal_flush flush_mode) goto err_create_pkt; } - if (__iface_cmdq_write(session->device, &pkt)) + if (__iface_cmdq_write(device, &pkt)) rc = -ENOTEMPTY; err_create_pkt: mutex_unlock(&device->lock); @@ -4977,7 +4862,7 @@ static struct venus_hfi_device *__add_device(u32 device_id, struct msm_vidc_platform_resources *res, hfi_cmd_response_callback callback) { - struct venus_hfi_device *hdevice = NULL; + struct venus_hfi_device *hdevice = &venus_hfi_dev; int rc = 0; if (!res || !callback) { @@ -4987,12 +4872,6 @@ static struct venus_hfi_device *__add_device(u32 device_id, dprintk(VIDC_HIGH, "entered , device_id: %d\n", device_id); - hdevice = kzalloc(sizeof(struct venus_hfi_device), GFP_KERNEL); - if (!hdevice) { - dprintk(VIDC_ERR, "failed to allocate new device\n"); - goto exit; - } - hdevice->response_pkt = kmalloc_array(max_packets, sizeof(*hdevice->response_pkt), GFP_KERNEL); if (!hdevice->response_pkt) { @@ -5047,8 +4926,6 @@ static struct venus_hfi_device *__add_device(u32 device_id, destroy_workqueue(hdevice->vidc_workq); kfree(hdevice->response_pkt); kfree(hdevice->raw_packet); - kfree(hdevice); -exit: return NULL; } @@ -5085,7 +4962,6 @@ void venus_hfi_delete_device(void *device) kfree(close->hal_data); kfree(close->response_pkt); kfree(close->raw_packet); - kfree(close); break; } } diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index 24be24e061c3..328a4c80b1dc 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -819,7 +819,6 @@ struct hal_session { enum hal_video_codec codec; enum hal_domain domain; u32 flags; - void *device; }; struct hal_device_data { From 2b881c253b31959d484551dae83dd1f78cffa952 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Mon, 12 Aug 2019 21:02:47 +0530 Subject: [PATCH 135/452] msm: vidc: update current value while updating the v4l controls A v4l control has current and new value. Current value indicates the permanent value and any change in the control should be reflected to current value. V4l client should ensure that while updating the new value, current value is updated as well. If current value is updated by v4l framework, its good, otherwise, the v4l driver should update it. Change-Id: Id0730465487dc4175516f4ef460758bee0b76308 Signed-off-by: Vikash Garodia --- msm/vidc/msm_venc.c | 41 ++++++++++++++++++++------------------ msm/vidc/msm_vidc_common.h | 13 ++++++++++++ 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 185b6cc9472d..c8e4290e875b 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2231,7 +2231,7 @@ void msm_venc_decide_bframe(struct msm_vidc_inst *inst) * Hence, forcefully enable bframe */ inst->prop.bframe_changed = true; - bframe_ctrl->val = MAX_NUM_B_FRAMES; + update_ctrl(bframe_ctrl, MAX_NUM_B_FRAMES); dprintk(VIDC_HIGH, "Bframe is forcefully enabled\n"); } else { /* @@ -2258,7 +2258,7 @@ void msm_venc_decide_bframe(struct msm_vidc_inst *inst) * Hence, forcefully disable bframe */ inst->prop.bframe_changed = true; - bframe_ctrl->val = 0; + update_ctrl(bframe_ctrl, 0); dprintk(VIDC_HIGH, "Bframe is forcefully disabled!\n"); } else { dprintk(VIDC_HIGH, "Bframe is disabled\n"); @@ -2293,6 +2293,7 @@ void msm_venc_adjust_gop_size(struct msm_vidc_inst *inst) struct v4l2_ctrl *hier_ctrl; struct v4l2_ctrl *bframe_ctrl; struct v4l2_ctrl *gop_size_ctrl; + s32 val; gop_size_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_GOP_SIZE); if (inst->prop.bframe_changed) { @@ -2303,12 +2304,12 @@ void msm_venc_adjust_gop_size(struct msm_vidc_inst *inst) bframe_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); if (!bframe_ctrl->val) /* Forcefully disabled */ - gop_size_ctrl->val = gop_size_ctrl->val * - (1 + MAX_NUM_B_FRAMES); + val = gop_size_ctrl->val * (1 + MAX_NUM_B_FRAMES); else /* Forcefully enabled */ - gop_size_ctrl->val = gop_size_ctrl->val / - (1 + MAX_NUM_B_FRAMES); + val = gop_size_ctrl->val / (1 + MAX_NUM_B_FRAMES); + + update_ctrl(gop_size_ctrl, val); } /* @@ -2324,9 +2325,11 @@ void msm_venc_adjust_gop_size(struct msm_vidc_inst *inst) num_subgops = (gop_size_ctrl->val + (min_gop_size >> 1)) / min_gop_size; if (num_subgops) - gop_size_ctrl->val = num_subgops * min_gop_size; + val = num_subgops * min_gop_size; else - gop_size_ctrl->val = min_gop_size; + val = min_gop_size; + + update_ctrl(gop_size_ctrl, val); } } @@ -2853,14 +2856,14 @@ static void set_all_intra_preconditions(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); if (ctrl->val) { dprintk(VIDC_HIGH, "Disable multi slice for all intra\n"); - ctrl->val = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; + update_ctrl(ctrl, V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE); } /* Disable LTR */ ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); if (ctrl->val) { dprintk(VIDC_HIGH, "Disable LTR for all intra\n"); - ctrl->val = 0; + update_ctrl(ctrl, 0); } /* Disable Layer encoding */ @@ -2869,8 +2872,8 @@ static void set_all_intra_preconditions(struct msm_vidc_inst *inst) V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); if (ctrl->val || ctrl_t->val) { dprintk(VIDC_HIGH, "Disable layer encoding for all intra\n"); - ctrl->val = 0; - ctrl_t->val = 0; + update_ctrl(ctrl, 0); + update_ctrl(ctrl_t, 0); } /* Disable IR */ @@ -2878,8 +2881,8 @@ static void set_all_intra_preconditions(struct msm_vidc_inst *inst) ctrl_t = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB); if (ctrl->val || ctrl_t->val) { dprintk(VIDC_HIGH, "Disable IR for all intra\n"); - ctrl->val = 0; - ctrl_t->val = 0; + update_ctrl(ctrl, 0); + update_ctrl(ctrl_t, 0); } return; @@ -2893,14 +2896,14 @@ static void set_heif_preconditions(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_GOP_SIZE); if (ctrl->val) { dprintk(VIDC_HIGH, "Reset P-frame count for HEIF\n"); - ctrl->val = 0; + update_ctrl(ctrl, 0); } /* Reset BFrames */ ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); if (ctrl->val) { dprintk(VIDC_HIGH, "Reset B-frame count for HEIF\n"); - ctrl->val = 0; + update_ctrl(ctrl, 0); } return; @@ -3075,8 +3078,8 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst) } if (slice_mode == HFI_MULTI_SLICE_OFF) { - ctrl->val = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; - ctrl_t->val = 0; + update_ctrl(ctrl, V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE); + update_ctrl(ctrl_t, 0); } set_and_exit: @@ -3902,7 +3905,7 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) * client sets unsupported codec/rate control. */ if (!is_ltr) { - ctrl->val = 0; + update_ctrl(ctrl, 0); dprintk(VIDC_HIGH, "LTR is forcefully disabled!\n"); } return rc; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index e5ae8c80d803..6dd65832c771 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -76,6 +76,19 @@ static inline struct v4l2_ctrl *get_ctrl(struct msm_vidc_inst *inst, return inst->ctrls[0]; } +static inline void update_ctrl(struct v4l2_ctrl *ctrl, s32 val) +{ + switch (ctrl->type) { + case V4L2_CTRL_TYPE_INTEGER: + *ctrl->p_cur.p_s32 = val; + memcpy(ctrl->p_new.p, ctrl->p_cur.p, + ctrl->elems * ctrl->elem_size); + break; + default: + dprintk(VIDC_ERR, "unhandled control type"); + } +} + static inline u32 get_v4l2_codec(struct msm_vidc_inst *inst) { struct v4l2_format *f; From 9c6de09cc90e63b6e665dbd9bebdc04566695c5c Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 6 Aug 2019 11:43:14 -0700 Subject: [PATCH 136/452] msm: vidc: Update DCVS thresholds DCVS Min Threshold should be FW Min count. Switch to Load_Norm only when buffers are equally distributed between FW and Client. This reduces clock transitions and increases residency in Load_Low and Load_High. CRs-Fixed: 2502809 Change-Id: I4896fd8fdffb44b546c6df3321e0155ee4a18dcb Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vdec.c | 3 +- msm/vidc/msm_venc.c | 2 +- msm/vidc/msm_vidc_buffer_calculations.c | 3 - msm/vidc/msm_vidc_buffer_calculations.h | 3 + msm/vidc/msm_vidc_clocks.c | 128 +++++++++++++----------- msm/vidc/msm_vidc_common.c | 2 +- msm/vidc/msm_vidc_internal.h | 3 +- msm/vidc/msm_vidc_resources.h | 15 --- 8 files changed, 76 insertions(+), 83 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 33c4e07f7a5e..4628185b3bb3 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -380,7 +380,7 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE, - .name = "Set Decoder Operating rate", + .name = "Decoder Operating rate", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = (MINIMUM_FPS << 16), .maximum = INT_MAX, @@ -670,6 +670,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) */ if (inst->batch.enable) inst->batch.enable = is_batching_allowed(inst); + msm_dcvs_try_enable(inst); err_invalid_fmt: return rc; diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 185b6cc9472d..bc5571f2e77e 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -760,7 +760,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE, - .name = "Set Encoder Operating rate", + .name = "Encoder Operating rate", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = (MINIMUM_FPS << 16), .maximum = INT_MAX, diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 13200fc29a58..3250e90bda5b 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -25,9 +25,6 @@ /* extra output buffers in case of decoder batch */ #define BATCH_DEC_EXTRA_OUTPUT_BUFFERS 6 -/* extra o/p buffers in case of decoder dcvs */ -#define DCVS_DEC_EXTRA_OUTPUT_BUFFERS 4 - /* Encoder buffer count macros */ /* total input buffers for encoder HFR usecase */ #define HFR_ENC_TOTAL_INPUT_BUFFERS 8 diff --git a/msm/vidc/msm_vidc_buffer_calculations.h b/msm/vidc/msm_vidc_buffer_calculations.h index 7e4575ad6e56..7a6db350d5fa 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.h +++ b/msm/vidc/msm_vidc_buffer_calculations.h @@ -6,6 +6,9 @@ #ifndef __H_MSM_VIDC_BUFFER_MEM_DEFS_H__ #define __H_MSM_VIDC_BUFFER_MEM_DEFS_H__ +/* extra o/p buffers in case of decoder dcvs */ +#define DCVS_DEC_EXTRA_OUTPUT_BUFFERS 4 + struct msm_vidc_dec_buff_size_calculators { u32 (*calculate_scratch_size)(struct msm_vidc_inst *inst, u32 width, u32 height, bool is_interlaced); diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 12cb998a2d27..861addc889b8 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -48,14 +48,10 @@ struct msm_vidc_core_ops core_ops_iris2 = { static inline void msm_dcvs_print_dcvs_stats(struct clock_data *dcvs) { dprintk(VIDC_PERF, - "DCVS: Load_Low %lld, Load Norm %lld, Load High %lld\n", - dcvs->load_low, - dcvs->load_norm, - dcvs->load_high); - - dprintk(VIDC_PERF, - "DCVS: min_threshold %d, max_threshold %d\n", - dcvs->min_threshold, dcvs->max_threshold); + "DCVS: Loads %lld %lld %lld, Thresholds %d %d %d\n", + dcvs->load_low, dcvs->load_norm, dcvs->load_high, + dcvs->min_threshold, dcvs->nom_threshold, + dcvs->max_threshold); } static inline unsigned long get_ubwc_compression_ratio( @@ -423,7 +419,6 @@ static int msm_dcvs_scale_clocks(struct msm_vidc_inst *inst, { int rc = 0; int bufs_with_fw = 0; - int bufs_with_client = 0; struct msm_vidc_format *fmt; struct clock_data *dcvs; @@ -432,13 +427,9 @@ static int msm_dcvs_scale_clocks(struct msm_vidc_inst *inst, return -EINVAL; } - /* assume no increment or decrement is required initially */ - inst->clk_data.dcvs_flags = 0; - if (!inst->clk_data.dcvs_mode || inst->batch.enable) { dprintk(VIDC_LOW, "Skip DCVS (dcvs %d, batching %d)\n", inst->clk_data.dcvs_mode, inst->batch.enable); - /* update load (freq) with normal value */ inst->clk_data.load = inst->clk_data.load_norm; return 0; } @@ -452,44 +443,46 @@ static int msm_dcvs_scale_clocks(struct msm_vidc_inst *inst, bufs_with_fw = msm_comm_num_queued_bufs(inst, INPUT_MPLANE); fmt = &inst->fmts[INPUT_PORT]; } + /* +1 as one buffer is going to be queued after the function */ bufs_with_fw += 1; - bufs_with_client = fmt->count_actual - bufs_with_fw; /* - * PMS decides clock level based on below algo + * DCVS decides clock level based on below algo * Limits : - * max_threshold : Client extra allocated buffers. Client - * reserves these buffers for it's smooth flow. - * min_output_buf : HW requested buffers for it's smooth - * flow of buffers. - * min_threshold : Driver requested extra buffers for PMS. + * min_threshold : Buffers required for reference by FW. + * nom_threshold : Midpoint of Min and Max thresholds + * max_threshold : Total - Client extra buffers, allocated + * for it's smooth flow. * 1) When buffers outside FW are reaching client's extra buffers, * FW is slow and will impact pipeline, Increase clock. * 2) When pending buffers with FW are same as FW requested, * pipeline has cushion to absorb FW slowness, Decrease clocks. - * 3) When none of 1) or 2) FW is just fast enough to maintain - * pipeline, request Right Clocks. + * 3) When buffers are equally distributed between FW and Client + * switch to NOM as this is the ideal steady state. + * 4) Otherwise maintain previous Load config. */ - if (bufs_with_client <= dcvs->max_threshold) { - dcvs->load = dcvs->load_high; - dcvs->dcvs_flags |= MSM_VIDC_DCVS_INCR; - } else if (bufs_with_fw < (int) fmt->count_min) { - dcvs->load = dcvs->load_low; - dcvs->dcvs_flags |= MSM_VIDC_DCVS_DECR; - } else { + if (dcvs->dcvs_window < DCVS_DEC_EXTRA_OUTPUT_BUFFERS || + bufs_with_fw == dcvs->nom_threshold) { dcvs->load = dcvs->load_norm; dcvs->dcvs_flags = 0; + } else if (bufs_with_fw >= dcvs->max_threshold) { + dcvs->load = dcvs->load_high; + dcvs->dcvs_flags |= MSM_VIDC_DCVS_INCR; + } else if (bufs_with_fw < dcvs->min_threshold) { + dcvs->load = dcvs->load_low; + dcvs->dcvs_flags |= MSM_VIDC_DCVS_DECR; } dprintk(VIDC_PERF, - "DCVS: %x : total bufs %d outside fw %d max threshold %d with fw %d min bufs %d flags %#x\n", - hash32_ptr(inst->session), fmt->count_actual, - bufs_with_client, dcvs->max_threshold, bufs_with_fw, - fmt->count_min, dcvs->dcvs_flags); + "DCVS: %x: bufs_with_fw %d Th[%d %d %d] Flag %#x Load %llu\n", + hash32_ptr(inst->session), bufs_with_fw, + dcvs->min_threshold, dcvs->nom_threshold, dcvs->max_threshold, + dcvs->dcvs_flags, dcvs->load); + return rc; } @@ -672,6 +665,9 @@ static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, break; } + if (i < 0) + i = 0; + dcvs->load_norm = rate; dcvs->load_low = i < (int) (core->resources.allowed_clks_tbl_size - 1) ? allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm; @@ -765,6 +761,9 @@ static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst, break; } + if (i < 0) + i = 0; + dcvs->load_norm = rate; dcvs->load_low = i < (int) (core->resources.allowed_clks_tbl_size - 1) ? allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm; @@ -865,6 +864,9 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, break; } + if (i < 0) + i = 0; + dcvs->load_norm = rate; dcvs->load_low = i < (int) (core->resources.allowed_clks_tbl_size - 1) ? allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm; @@ -959,6 +961,10 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core) if (rate >= freq_core_max) break; } + + if (i < 0) + i = 0; + if (increment) { if (i > 0) rate = allowed_clks_tbl[i-1].clock_rate; @@ -1016,15 +1022,15 @@ int msm_comm_scale_clocks(struct msm_vidc_inst *inst) return 0; } - freq = call_core_op(inst->core, calc_freq, inst, filled_len); - inst->clk_data.min_freq = freq; - /* update dcvs flags */ - msm_dcvs_scale_clocks(inst, freq); - if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW || is_turbo || msm_vidc_clock_voting) { inst->clk_data.min_freq = msm_vidc_max_freq(inst->core); inst->clk_data.dcvs_flags = 0; + } else { + freq = call_core_op(inst->core, calc_freq, inst, filled_len); + inst->clk_data.min_freq = freq; + /* update dcvs flags */ + msm_dcvs_scale_clocks(inst, freq); } msm_vidc_update_freq_entry(inst, freq, device_addr, is_turbo); @@ -1067,20 +1073,18 @@ int msm_dcvs_try_enable(struct msm_vidc_inst *inst) return -EINVAL; } - if (msm_vidc_clock_voting || + inst->clk_data.dcvs_mode = + !(msm_vidc_clock_voting || !inst->core->resources.dcvs || inst->flags & VIDC_THUMBNAIL || inst->clk_data.low_latency_mode || inst->batch.enable || - inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) { - dprintk(VIDC_HIGH, "DCVS disabled: %pK\n", inst); - inst->clk_data.dcvs_mode = false; - return false; - } - inst->clk_data.dcvs_mode = true; - dprintk(VIDC_HIGH, "DCVS enabled: %pK\n", inst); + inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ); - return true; + dprintk(VIDC_HIGH|VIDC_PERF, "DCVS %s: %pK\n", + inst->clk_data.dcvs_mode ? "enabled" : "disabled", inst); + + return 0; } int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst) @@ -1149,26 +1153,26 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) inst->clk_data.entry->low_power_cycles : cycles; - dcvs->buffer_type = HAL_BUFFER_INPUT; - dcvs->min_threshold = - msm_vidc_get_extra_buff_count(inst, HAL_BUFFER_INPUT); fmt = &inst->fmts[INPUT_PORT]; - dcvs->max_threshold = - fmt->count_actual - fmt->count_min_host + 2; } else if (inst->session_type == MSM_VIDC_DECODER) { - dcvs->buffer_type = HAL_BUFFER_OUTPUT; fmt = &inst->fmts[OUTPUT_PORT]; - dcvs->max_threshold = - fmt->count_actual - fmt->count_min_host + 2; - - dcvs->min_threshold = - msm_vidc_get_extra_buff_count(inst, dcvs->buffer_type); } else { dprintk(VIDC_ERR, "%s: invalid session type %#x\n", __func__, inst->session_type); return; } + dcvs->min_threshold = fmt->count_min; + dcvs->max_threshold = + max(fmt->count_min, + (fmt->count_actual - DCVS_DEC_EXTRA_OUTPUT_BUFFERS)); + + dcvs->dcvs_window = + dcvs->max_threshold - dcvs->min_threshold; + dcvs->nom_threshold = dcvs->min_threshold + + (dcvs->dcvs_window ? + (dcvs->dcvs_window / 2) : 0); + total_freq = cycles * load; for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) { @@ -1177,12 +1181,14 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) break; } - dcvs->load = dcvs->load_norm = rate; + if (i < 0) + i = 0; + dcvs->load = dcvs->load_norm = rate; dcvs->load_low = i < (core->resources.allowed_clks_tbl_size - 1) ? allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm; - dcvs->load_high = i > 0 ? allowed_clks_tbl[i-1].clock_rate : - dcvs->load_norm; + dcvs->load_high = i > 0 ? + allowed_clks_tbl[i-1].clock_rate : dcvs->load_norm; inst->clk_data.buffer_counter = 0; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index b9cc0dabc1bf..a270b6c8cbf3 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1820,7 +1820,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data) dprintk(VIDC_HIGH|VIDC_PERF, "%s: %x : batching %s\n", __func__, hash32_ptr(inst->session), inst->batch.enable ? "enabled" : "disabled"); - + msm_dcvs_try_enable(inst); extra_buff_count = msm_vidc_get_extra_buff_count(inst, HAL_BUFFER_OUTPUT); fmt->count_min = event_notify->capture_buf_count; diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index af433a2a17eb..891a15a80fa7 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -393,9 +393,10 @@ struct clock_data { u64 load_norm; u64 load_high; int min_threshold; + int nom_threshold; int max_threshold; - enum hal_buffer buffer_type; bool dcvs_mode; + u32 dcvs_window; unsigned long bitrate; unsigned long min_freq; unsigned long curr_freq; diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 7c5619de22dc..443e07be14b1 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -13,18 +13,6 @@ #define MAX_BUFFER_TYPES 32 -struct dcvs_table { - u32 load; - u32 load_low; - u32 load_high; - u32 supported_codecs; -}; - -struct dcvs_limit { - u32 min_mbpf; - u32 fps; -}; - struct reg_value_pair { u32 reg; u32 value; @@ -156,9 +144,6 @@ struct msm_vidc_platform_resources { struct allowed_clock_rates_table *allowed_clks_tbl; u32 allowed_clks_tbl_size; struct clock_freq_table clock_freq_tbl; - struct dcvs_table *dcvs_tbl; - uint32_t dcvs_tbl_size; - struct dcvs_limit *dcvs_limit; bool sys_cache_present; bool sys_cache_res_set; struct subcache_set subcache_set; From 1b9472cc6fccc8f1e8e516dea34a19f55a746498 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Mon, 29 Jul 2019 18:27:24 -0700 Subject: [PATCH 137/452] msm: vidc: Add support for V4L2_FLAG_CVPMETADATA_SKIP flag Introduced CVP skip flag as part of qbuf to indicate buffer is skipped CVP processing. This is required in order to re-use CVP metadata from previous frame when it is not an error case. Video firmware will look at this flag and reuse CVP metadata from earlier frame to encode current frame. Change-Id: Icf89daa2d5f19790a04f0467a15165870b283ee4 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_cvp_external.c | 4 +++- msm/vidc/msm_vidc_common.c | 24 ++++++++++++++++++++---- msm/vidc/vidc_hfi.h | 1 + msm/vidc/vidc_hfi_api.h | 2 +- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index 62eed1185afb..4fab5a81fdd2 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -864,6 +864,7 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, else operating_rate = cvp->operating_rate; + mbuf->vvb.flags &= ~V4L2_BUF_FLAG_CVPMETADATA_SKIP; /* frame skip logic */ fps = max(cvp->frame_rate, operating_rate) >> 16; if (fps > fps_max) { @@ -878,10 +879,11 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, skipframe = cvp->framecount % skip_framecount; } if (skipframe) { - print_cvp_buffer(VIDC_LOW, "input frame skipped", + print_cvp_buffer(VIDC_LOW, "input frame with skipflag", inst, &cvp->fullres_buffer); cvp->framecount++; cvp->metadata_available = false; + mbuf->vvb.flags |= V4L2_BUF_FLAG_CVPMETADATA_SKIP; return 0; } diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index c6802a320bb0..ac5cd6d17ffb 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -4220,6 +4220,9 @@ static void populate_frame_data(struct vidc_frame_data *data, if (vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG) data->flags |= HAL_BUFFERFLAG_CODECCONFIG; + if(vbuf->flags & V4L2_BUF_FLAG_CVPMETADATA_SKIP) + data->flags |= HAL_BUFFERFLAG_CVPMETADATA_SKIP; + msm_comm_fetch_input_tag(&inst->etb_data, vb->index, &itag, &itag2); data->input_tag = itag; @@ -4385,6 +4388,7 @@ static int msm_comm_qbuf_superframe_to_hfi(struct msm_vidc_inst *inst, u64 ts_delta_us; struct vidc_frame_data *frames; u32 num_etbs, superframe_count, frame_size, hfi_fmt; + bool skip_allowed = false; if (!inst || !inst->core || !inst->core->device || !mbuf) { dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); @@ -4425,16 +4429,23 @@ static int msm_comm_qbuf_superframe_to_hfi(struct msm_vidc_inst *inst, /* prepare superframe buffers */ frames[0].filled_len = frame_size; /* - * superframe logic updates extradata and eos flags only, so - * ensure no other flags are populated in populate_frame_data() + * superframe logic updates extradata, cvpmetadata_skip and eos flags only, + * so ensure no other flags are populated in populate_frame_data() */ frames[0].flags &= ~HAL_BUFFERFLAG_EXTRADATA; frames[0].flags &= ~HAL_BUFFERFLAG_EOS; + frames[0].flags &= ~HAL_BUFFERFLAG_CVPMETADATA_SKIP; if (frames[0].flags) dprintk(VIDC_ERR, "%s: invalid flags %#x\n", __func__, frames[0].flags); frames[0].flags = 0; + /* Add skip flag only if CVP metadata is enabled */ + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) { + skip_allowed = true; + frames[0].flags |= HAL_BUFFERFLAG_CVPMETADATA_SKIP; + } + for (i = 0; i < superframe_count; i++) { if (i) memcpy(&frames[i], &frames[0], @@ -4443,8 +4454,8 @@ static int msm_comm_qbuf_superframe_to_hfi(struct msm_vidc_inst *inst, frames[i].timestamp += i * ts_delta_us; if (!i) { /* first frame */ - if (frames[i].extradata_addr) - frames[i].flags |= HAL_BUFFERFLAG_EXTRADATA; + if (frames[0].extradata_addr) + frames[0].flags |= HAL_BUFFERFLAG_EXTRADATA; } else if (i == superframe_count - 1) { /* last frame */ if (mbuf->vvb.flags & V4L2_BUF_FLAG_EOS) @@ -4453,6 +4464,11 @@ static int msm_comm_qbuf_superframe_to_hfi(struct msm_vidc_inst *inst, num_etbs++; } + /* If cvp metadata is enabled and metadata is available, + * do not add skip flag for only first frame */ + if (skip_allowed && !(mbuf->vvb.flags & V4L2_BUF_FLAG_CVPMETADATA_SKIP)) + frames[0].flags &= ~HAL_BUFFERFLAG_CVPMETADATA_SKIP; + rc = call_hfi_op(hdev, session_process_batch, inst->session, num_etbs, frames, 0, NULL); if (rc) { diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index 8b9d20dcbbd2..8ba52402cbe6 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -37,6 +37,7 @@ #define HFI_BUFFERFLAG_DROP_FRAME 0x20000000 #define HFI_BUFFERFLAG_TEI 0x40000000 #define HFI_BUFFERFLAG_DISCONTINUITY 0x80000000 +#define HFI_BUFFERFLAG_CVPMETADATA_REPEAT 0x00000800 #define HFI_ERR_SESSION_EMPTY_BUFFER_DONE_OUTPUT_PENDING \ diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 0b34ee56d7df..a2746df040f8 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -38,7 +38,7 @@ #define HAL_BUFFERFLAG_DROP_FRAME 0x20000000 #define HAL_BUFFERFLAG_TS_DISCONTINUITY 0x40000000 #define HAL_BUFFERFLAG_TS_ERROR 0x80000000 - +#define HAL_BUFFERFLAG_CVPMETADATA_SKIP 0x00000800 #define HAL_DEBUG_MSG_LOW 0x00000001 From 1ec1845dab9191ebd5d42cdd1f9e554b63ba6848 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Fri, 9 Aug 2019 11:14:47 +0800 Subject: [PATCH 138/452] msm: vidc: refine bus bw voting - Avoid redundant memory alloc/free at frame level. - Only calculate bus bw for current session. - Skip bus bw voting if change is less than 50MBps. Change-Id: I944670c6ac0bf663cb43f47a06b8e828ccdb28cc Signed-off-by: Qiwei Liu --- msm/vidc/hfi_common.c | 97 +++++++----------- msm/vidc/hfi_common.h | 2 - msm/vidc/msm_cvp_internal.c | 2 +- msm/vidc/msm_vidc_bus.h | 30 +----- msm/vidc/msm_vidc_bus_iris1.c | 33 ++----- msm/vidc/msm_vidc_bus_iris2.c | 33 ++----- msm/vidc/msm_vidc_clocks.c | 178 +++++++++++++++++++--------------- msm/vidc/msm_vidc_clocks.h | 2 +- msm/vidc/msm_vidc_internal.h | 23 +++++ msm/vidc/vidc_hfi_api.h | 6 +- 10 files changed, 179 insertions(+), 227 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 429ea53534d5..d1155eaaba3b 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -69,13 +69,16 @@ struct tzbsp_video_set_state_req { }; const struct msm_vidc_bus_data DEFAULT_BUS_VOTE = { - .data = NULL, - .data_count = 0, .total_bw_ddr = 0, .total_bw_llcc = 0, - .calc_bw = NULL, }; +/* Less than 50MBps is treated as trivial BW change */ +#define TRIVIAL_BW_THRESHOLD 50000 +#define TRIVIAL_BW_CHANGE(a, b) \ + ((a) > (b) ? (a) - (b) < TRIVIAL_BW_THRESHOLD : \ + (b) - (a) < TRIVIAL_BW_THRESHOLD) + const int max_packets = 1000; static void venus_hfi_pm_handler(struct work_struct *work); @@ -1001,9 +1004,7 @@ int __unvote_buses(struct venus_hfi_device *device) int rc = 0; struct bus_info *bus = NULL; - kfree(device->bus_vote.data); - device->bus_vote.data = NULL; - device->bus_vote.data_count = 0; + device->bus_vote = DEFAULT_BUS_VOTE; venus_hfi_for_each_bus(device, bus) { rc = __vote_bandwidth(bus, 0); @@ -1016,63 +1017,56 @@ int __unvote_buses(struct venus_hfi_device *device) } static int __vote_buses(struct venus_hfi_device *device, - struct vidc_bus_vote_data *data, int num_data) + unsigned long bw_ddr, unsigned long bw_llcc) { int rc = 0; struct bus_info *bus = NULL; - struct vidc_bus_vote_data *new_data = NULL; - unsigned long bw_kbps = 0; + unsigned long bw_kbps = 0, bw_prev = 0; enum vidc_bus_type type; - if (!num_data) { - dprintk(VIDC_LOW, "No vote data available\n"); - goto no_data_count; - } else if (!data) { - dprintk(VIDC_ERR, "Invalid voting data\n"); - return -EINVAL; - } - - new_data = kmemdup(data, num_data * sizeof(*new_data), GFP_KERNEL); - if (!new_data) { - dprintk(VIDC_ERR, "Can't alloc memory to cache bus votes\n"); - rc = -ENOMEM; - goto err_no_mem; - } - -no_data_count: - kfree(device->bus_vote.data); - device->bus_vote.data = new_data; - device->bus_vote.data_count = num_data; - - if (device->bus_vote.calc_bw) - device->bus_vote.calc_bw(&device->bus_vote); - venus_hfi_for_each_bus(device, bus) { if (bus && bus->client) { type = get_type_frm_name(bus->name); - if (type == DDR) - bw_kbps = device->bus_vote.total_bw_ddr; - else if (type == LLCC) - bw_kbps = device->bus_vote.total_bw_llcc; - else + if (type == DDR) { + bw_kbps = bw_ddr; + bw_prev = device->bus_vote.total_bw_ddr; + } else if (type == LLCC) { + bw_kbps = bw_llcc; + bw_prev = device->bus_vote.total_bw_llcc; + } else { bw_kbps = bus->range[1]; + bw_prev = device->bus_vote.total_bw_ddr ? + bw_kbps : 0; + } /* ensure freq is within limits */ bw_kbps = clamp_t(typeof(bw_kbps), bw_kbps, bus->range[0], bus->range[1]); + if (TRIVIAL_BW_CHANGE(bw_kbps, bw_prev) && bw_prev) { + dprintk(VIDC_PERF, + "Skip voting bus %s to %llu bps", + bus->name, bw_kbps * 1000); + continue; + } + rc = __vote_bandwidth(bus, bw_kbps); + + if (type == DDR) + device->bus_vote.total_bw_ddr = bw_kbps; + else if (type == LLCC) + device->bus_vote.total_bw_llcc = bw_kbps; } else { dprintk(VIDC_ERR, "No BUS to Vote\n"); } } -err_no_mem: return rc; } -static int venus_hfi_vote_buses(void *dev, struct vidc_bus_vote_data *d, int n) +static int venus_hfi_vote_buses(void *dev, unsigned long bw_ddr, + unsigned long bw_llcc) { int rc = 0; struct venus_hfi_device *device = dev; @@ -1081,11 +1075,10 @@ static int venus_hfi_vote_buses(void *dev, struct vidc_bus_vote_data *d, int n) return -EINVAL; mutex_lock(&device->lock); - rc = __vote_buses(device, d, n); + rc = __vote_buses(device, bw_ddr, bw_llcc); mutex_unlock(&device->lock); return rc; - } static int __core_set_resource(struct venus_hfi_device *device, struct vidc_resource_hdr *resource_hdr, void *resource_value) @@ -2055,16 +2048,7 @@ static int venus_hfi_core_init(void *device) mutex_lock(&dev->lock); - dev->bus_vote.data = - kzalloc(sizeof(struct vidc_bus_vote_data), GFP_KERNEL); - if (!dev->bus_vote.data) { - dprintk(VIDC_ERR, "Bus vote data memory is not allocated\n"); - rc = -ENOMEM; - goto err_no_mem; - } - - dev->bus_vote.data_count = 1; - dev->bus_vote.data->power_mode = VIDC_POWER_TURBO; + dev->bus_vote = DEFAULT_BUS_VOTE; rc = __load_fw(dev); if (rc) { @@ -2131,7 +2115,6 @@ static int venus_hfi_core_init(void *device) __set_state(dev, VENUS_STATE_DEINIT); __unload_fw(dev); err_load_fw: -err_no_mem: dprintk(VIDC_ERR, "Core init failed\n"); mutex_unlock(&dev->lock); return rc; @@ -3924,7 +3907,6 @@ static void __deinit_bus(struct venus_hfi_device *device) if (!device) return; - kfree(device->bus_vote.data); device->bus_vote = DEFAULT_BUS_VOTE; venus_hfi_for_each_bus_reverse(device, bus) { @@ -3962,11 +3944,6 @@ static int __init_bus(struct venus_hfi_device *device) } } - if (device->res->vpu_ver == VPU_VERSION_IRIS1) - device->bus_vote.calc_bw = calc_bw_iris1; - else - device->bus_vote.calc_bw = calc_bw_iris2; - return 0; err_add_dev: @@ -4508,8 +4485,7 @@ static int __venus_power_on(struct venus_hfi_device *device) device->power_enabled = true; /* Vote for all hardware resources */ - rc = __vote_buses(device, device->bus_vote.data, - device->bus_vote.data_count); + rc = __vote_buses(device, INT_MAX, INT_MAX); if (rc) { dprintk(VIDC_ERR, "Failed to vote buses, err: %d\n", rc); goto fail_vote_buses; @@ -4774,7 +4750,6 @@ static void __unload_fw(struct venus_hfi_device *device) if (device->state != VENUS_STATE_DEINIT) flush_workqueue(device->venus_pm_workq); - __vote_buses(device, NULL, 0); subsystem_put(device->resources.fw.cookie); __interface_queues_release(device); call_venus_op(device, power_off, device); diff --git a/msm/vidc/hfi_common.h b/msm/vidc/hfi_common.h index acbbe3b3d191..dc6c5706489a 100644 --- a/msm/vidc/hfi_common.h +++ b/msm/vidc/hfi_common.h @@ -255,8 +255,6 @@ struct venus_hfi_device { u32 device_id; u32 clk_freq; u32 last_packet_type; - unsigned long clk_bitrate; - unsigned long scaled_rate; struct msm_vidc_bus_data bus_vote; bool power_enabled; struct mutex lock; diff --git a/msm/vidc/msm_cvp_internal.c b/msm/vidc/msm_cvp_internal.c index e5ae10750404..b5c7350b70c9 100644 --- a/msm/vidc/msm_cvp_internal.c +++ b/msm/vidc/msm_cvp_internal.c @@ -239,7 +239,7 @@ static int msm_cvp_scale_clocks_and_bus(struct msm_vidc_inst *inst) goto exit; } - rc = msm_comm_vote_bus(inst->core); + rc = msm_comm_vote_bus(inst); if (rc) { dprintk(VIDC_ERR, "%s: failed vote_bus for inst %pK (%#x)\n", diff --git a/msm/vidc/msm_vidc_bus.h b/msm/vidc/msm_vidc_bus.h index bc2c5f17fab4..ea25ba1c25e0 100644 --- a/msm/vidc/msm_vidc_bus.h +++ b/msm/vidc/msm_vidc_bus.h @@ -213,40 +213,14 @@ struct dump { size_t val; }; -struct vidc_bus_vote_data { - enum hal_domain domain; - enum hal_video_codec codec; - enum hal_uncompressed_format color_formats[2]; - int num_formats; /* 1 = DPB-OPB unified; 2 = split */ - int input_height, input_width, bitrate; - int output_height, output_width; - int rotation; - int compression_ratio; - int complexity_factor; - int input_cr; - u32 ddr_bw; - u32 sys_cache_bw; - unsigned int lcu_size; - unsigned int fps; - enum msm_vidc_power_mode power_mode; - u32 work_mode; - bool use_sys_cache; - bool b_frames_enabled; - unsigned long calc_bw_ddr; - unsigned long calc_bw_llcc; -}; - struct msm_vidc_bus_data { - struct vidc_bus_vote_data *data; - u32 data_count; unsigned long total_bw_ddr; unsigned long total_bw_llcc; - int (*calc_bw)(struct msm_vidc_bus_data *data); }; -int calc_bw_iris1(struct msm_vidc_bus_data *vidc_data); +int calc_bw_iris1(struct vidc_bus_vote_data *vidc_data); -int calc_bw_iris2(struct msm_vidc_bus_data *vidc_data); +int calc_bw_iris2(struct vidc_bus_vote_data *vidc_data); struct lut const *__lut(int width, int height, int fps); fp_t __compression_ratio(struct lut const *entry, int bpp); diff --git a/msm/vidc/msm_vidc_bus_iris1.c b/msm/vidc/msm_vidc_bus_iris1.c index 45879927a7ec..a141b3dfbc85 100644 --- a/msm/vidc/msm_vidc_bus_iris1.c +++ b/msm/vidc/msm_vidc_bus_iris1.c @@ -75,12 +75,7 @@ static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d) static unsigned long __calculate_cvp(struct vidc_bus_vote_data *d) { - unsigned long ret = 0; - - d->calc_bw_ddr = d->ddr_bw; - d->calc_bw_llcc = d->sys_cache_bw; - - return ret; + return 0; } static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) @@ -641,31 +636,15 @@ static unsigned long __calculate(struct vidc_bus_vote_data *d) return value; } -int calc_bw_iris1(struct msm_vidc_bus_data *vidc_data) +int calc_bw_iris1(struct vidc_bus_vote_data *vidc_data) { - int ret = 0, c = 0; + int ret = 0; - if (!vidc_data || !vidc_data->data_count || !vidc_data->data) - goto exit; + if (!vidc_data) + return ret; - vidc_data->total_bw_ddr = 0; - vidc_data->total_bw_llcc = 0; + ret = __calculate(vidc_data); - for (c = 0; c < vidc_data->data_count; ++c) { - if (vidc_data->data->power_mode == VIDC_POWER_TURBO) { - vidc_data->total_bw_ddr = INT_MAX; - vidc_data->total_bw_llcc = INT_MAX; - goto exit; - } - } - - for (c = 0; c < vidc_data->data_count; ++c) { - __calculate(&vidc_data->data[c]); - vidc_data->total_bw_ddr += vidc_data->data[c].calc_bw_ddr; - vidc_data->total_bw_llcc += vidc_data->data[c].calc_bw_llcc; - } - -exit: return ret; } diff --git a/msm/vidc/msm_vidc_bus_iris2.c b/msm/vidc/msm_vidc_bus_iris2.c index 620411ead52b..d18b4a258865 100644 --- a/msm/vidc/msm_vidc_bus_iris2.c +++ b/msm/vidc/msm_vidc_bus_iris2.c @@ -13,12 +13,7 @@ static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d) static unsigned long __calculate_cvp(struct vidc_bus_vote_data *d) { - unsigned long ret = 0; - - d->calc_bw_ddr = d->ddr_bw; - d->calc_bw_llcc = d->sys_cache_bw; - - return ret; + return 0; } static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) @@ -545,30 +540,14 @@ static unsigned long __calculate(struct vidc_bus_vote_data *d) return value; } -int calc_bw_iris2(struct msm_vidc_bus_data *vidc_data) +int calc_bw_iris2(struct vidc_bus_vote_data *vidc_data) { - int ret = 0, c = 0; + int ret = 0; - if (!vidc_data || !vidc_data->data_count || !vidc_data->data) - goto exit; + if (!vidc_data) + return ret; - vidc_data->total_bw_ddr = 0; - vidc_data->total_bw_llcc = 0; + ret = __calculate(vidc_data); - for (c = 0; c < vidc_data->data_count; ++c) { - if (vidc_data->data->power_mode == VIDC_POWER_TURBO) { - vidc_data->total_bw_ddr = INT_MAX; - vidc_data->total_bw_llcc = INT_MAX; - goto exit; - } - } - - for (c = 0; c < vidc_data->data_count; ++c) { - __calculate(&vidc_data->data[c]); - vidc_data->total_bw_ddr += vidc_data->data[c].calc_bw_ddr; - vidc_data->total_bw_llcc += vidc_data->data[c].calc_bw_llcc; - } - -exit: return ret; } diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 861addc889b8..07aadad0818f 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -29,6 +29,7 @@ struct msm_vidc_core_ops core_ops_ar50 = { .decide_work_route = NULL, .decide_work_mode = msm_vidc_decide_work_mode_ar50, .decide_core_and_power_mode = NULL, + .calc_bw = NULL, }; struct msm_vidc_core_ops core_ops_iris1 = { @@ -36,6 +37,7 @@ struct msm_vidc_core_ops core_ops_iris1 = { .decide_work_route = msm_vidc_decide_work_route_iris1, .decide_work_mode = msm_vidc_decide_work_mode_iris1, .decide_core_and_power_mode = msm_vidc_decide_core_and_power_mode_iris1, + .calc_bw = calc_bw_iris1, }; struct msm_vidc_core_ops core_ops_iris2 = { @@ -43,6 +45,7 @@ struct msm_vidc_core_ops core_ops_iris2 = { .decide_work_route = msm_vidc_decide_work_route_iris2, .decide_work_mode = msm_vidc_decide_work_mode_iris2, .decide_core_and_power_mode = msm_vidc_decide_core_and_power_mode_iris2, + .calc_bw = calc_bw_iris2, }; static inline void msm_dcvs_print_dcvs_stats(struct clock_data *dcvs) @@ -256,15 +259,12 @@ static int fill_dynamic_stats(struct msm_vidc_inst *inst, return 0; } -int msm_comm_vote_bus(struct msm_vidc_core *core) +int msm_comm_set_buses(struct msm_vidc_core *core) { - int rc = 0, vote_data_count = 0, i = 0; - struct hfi_device *hdev; + int rc = 0; struct msm_vidc_inst *inst = NULL; - struct vidc_bus_vote_data *vote_data = NULL; - bool is_turbo = false; - struct v4l2_format *out_f; - struct v4l2_format *inp_f; + struct hfi_device *hdev; + unsigned long total_bw_ddr = 0, total_bw_llcc = 0; if (!core || !core->device) { dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core); @@ -272,23 +272,8 @@ int msm_comm_vote_bus(struct msm_vidc_core *core) } hdev = core->device; - vote_data = kzalloc(sizeof(struct vidc_bus_vote_data) * - MAX_SUPPORTED_INSTANCES, GFP_ATOMIC); - if (!vote_data) { - dprintk(VIDC_LOW, - "vote_data allocation with GFP_ATOMIC failed\n"); - vote_data = kzalloc(sizeof(struct vidc_bus_vote_data) * - MAX_SUPPORTED_INSTANCES, GFP_KERNEL); - if (!vote_data) { - dprintk(VIDC_ERR, - "vote_data allocation failed\n"); - return -EINVAL; - } - } - mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { - int codec = 0; struct msm_vidc_buffer *temp, *next; u32 filled_len = 0; u32 device_addr = 0; @@ -301,11 +286,6 @@ int msm_comm_vote_bus(struct msm_vidc_core *core) temp->vvb.vb2_buf.planes[0].bytesused); device_addr = temp->smem[0].device_addr; } - if (inst->session_type == MSM_VIDC_ENCODER && - (temp->vvb.flags & - V4L2_BUF_FLAG_PERF_MODE)) { - is_turbo = true; - } } mutex_unlock(&inst->registeredbufs.lock); @@ -316,8 +296,75 @@ int msm_comm_vote_bus(struct msm_vidc_core *core) continue; } - ++vote_data_count; + if (inst->bus_data.power_mode == VIDC_POWER_TURBO) { + total_bw_ddr = total_bw_llcc = INT_MAX; + break; + } + total_bw_ddr += inst->bus_data.calc_bw_ddr; + total_bw_llcc += inst->bus_data.calc_bw_llcc; + } + mutex_unlock(&core->lock); + rc = call_hfi_op(hdev, vote_bus, hdev->hfi_device_data, + total_bw_ddr, total_bw_llcc); + + return rc; +} + +int msm_comm_vote_bus(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_vidc_core *core; + struct vidc_bus_vote_data *vote_data = NULL; + bool is_turbo = false; + struct v4l2_format *out_f; + struct v4l2_format *inp_f; + struct msm_vidc_buffer *temp, *next; + u32 filled_len = 0; + u32 device_addr = 0; + int codec = 0; + + if (!inst || !inst->core) { + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); + return -EINVAL; + } + core = inst->core; + vote_data = &inst->bus_data; + + mutex_lock(&inst->registeredbufs.lock); + list_for_each_entry_safe(temp, next, + &inst->registeredbufs.list, list) { + if (temp->vvb.vb2_buf.type == INPUT_MPLANE) { + filled_len = max(filled_len, + temp->vvb.vb2_buf.planes[0].bytesused); + device_addr = temp->smem[0].device_addr; + } + if (inst->session_type == MSM_VIDC_ENCODER && + (temp->vvb.flags & V4L2_BUF_FLAG_PERF_MODE)) { + is_turbo = true; + } + } + mutex_unlock(&inst->registeredbufs.lock); + + if ((!filled_len || !device_addr) && + (inst->session_type != MSM_VIDC_CVP)) { + dprintk(VIDC_LOW, "%s: no input for session %x\n", + __func__, hash32_ptr(inst->session)); + return 0; + } + + vote_data->domain = get_hal_domain(inst->session_type); + vote_data->power_mode = 0; + if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW && + inst->session_type != MSM_VIDC_CVP) + vote_data->power_mode = VIDC_POWER_TURBO; + if (msm_vidc_clock_voting || is_turbo) + vote_data->power_mode = VIDC_POWER_TURBO; + + if (inst->session_type == MSM_VIDC_CVP) { + vote_data->calc_bw_ddr= inst->clk_data.ddr_bw; + vote_data->calc_bw_llcc= inst->clk_data.sys_cache_bw; + } else if (vote_data->power_mode != VIDC_POWER_TURBO) { out_f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; inp_f = &inst->fmts[INPUT_PORT].v4l2_fmt; switch (inst->session_type) { @@ -336,81 +383,60 @@ int msm_comm_vote_bus(struct msm_vidc_core *core) break; } - memset(&(vote_data[i]), 0x0, sizeof(struct vidc_bus_vote_data)); - - vote_data[i].domain = get_hal_domain(inst->session_type); - vote_data[i].codec = get_hal_codec(codec); - vote_data[i].input_width = inp_f->fmt.pix_mp.width; - vote_data[i].input_height = inp_f->fmt.pix_mp.height; - vote_data[i].output_width = out_f->fmt.pix_mp.width; - vote_data[i].output_height = out_f->fmt.pix_mp.height; - vote_data[i].lcu_size = (codec == V4L2_PIX_FMT_HEVC || + vote_data->codec = get_hal_codec(codec); + vote_data->input_width = inp_f->fmt.pix_mp.width; + vote_data->input_height = inp_f->fmt.pix_mp.height; + vote_data->output_width = out_f->fmt.pix_mp.width; + vote_data->output_height = out_f->fmt.pix_mp.height; + vote_data->lcu_size = (codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_VP9) ? 32 : 16; - vote_data[i].fps = msm_vidc_get_fps(inst); + vote_data->fps = msm_vidc_get_fps(inst); if (inst->session_type == MSM_VIDC_ENCODER) { - vote_data[i].bitrate = inst->clk_data.bitrate; - vote_data[i].rotation = + vote_data->bitrate = inst->clk_data.bitrate; + vote_data->rotation = msm_comm_g_ctrl_for_id(inst, V4L2_CID_ROTATE); - vote_data[i].b_frames_enabled = + vote_data->b_frames_enabled = msm_comm_g_ctrl_for_id(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES) != 0; /* scale bitrate if operating rate is larger than fps */ - if (vote_data[i].fps > (inst->clk_data.frame_rate >> 16) + if (vote_data->fps > (inst->clk_data.frame_rate >> 16) && (inst->clk_data.frame_rate >> 16)) { - vote_data[i].bitrate = vote_data[i].bitrate / + vote_data->bitrate = vote_data->bitrate / (inst->clk_data.frame_rate >> 16) * - vote_data[i].fps; + vote_data->fps; } } else if (inst->session_type == MSM_VIDC_DECODER) { - vote_data[i].bitrate = - filled_len * vote_data[i].fps * 8; + vote_data->bitrate = + filled_len * vote_data->fps * 8; } - vote_data[i].power_mode = 0; - if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW && - inst->session_type != MSM_VIDC_CVP) - vote_data[i].power_mode = VIDC_POWER_TURBO; - if (msm_vidc_clock_voting || is_turbo) - vote_data[i].power_mode = VIDC_POWER_TURBO; - if (msm_comm_get_stream_output_mode(inst) == HAL_VIDEO_DECODER_PRIMARY) { - vote_data[i].color_formats[0] = + vote_data->color_formats[0] = msm_comm_get_hal_uncompressed( inst->clk_data.opb_fourcc); - vote_data[i].num_formats = 1; + vote_data->num_formats = 1; } else { - vote_data[i].color_formats[0] = + vote_data->color_formats[0] = msm_comm_get_hal_uncompressed( inst->clk_data.dpb_fourcc); - vote_data[i].color_formats[1] = + vote_data->color_formats[1] = msm_comm_get_hal_uncompressed( inst->clk_data.opb_fourcc); - vote_data[i].num_formats = 2; + vote_data->num_formats = 2; } - vote_data[i].work_mode = inst->clk_data.work_mode; - fill_dynamic_stats(inst, &vote_data[i]); + vote_data->work_mode = inst->clk_data.work_mode; + fill_dynamic_stats(inst, vote_data); if (core->resources.sys_cache_res_set) - vote_data[i].use_sys_cache = true; + vote_data->use_sys_cache = true; - if (inst->session_type == MSM_VIDC_CVP) { - vote_data[i].domain = - get_hal_domain(inst->session_type); - vote_data[i].ddr_bw = inst->clk_data.ddr_bw; - vote_data[i].sys_cache_bw = - inst->clk_data.sys_cache_bw; - } - - i++; + call_core_op(core, calc_bw, vote_data); } - mutex_unlock(&core->lock); - if (vote_data_count) - rc = call_hfi_op(hdev, vote_bus, hdev->hfi_device_data, - vote_data, vote_data_count); - kfree(vote_data); + rc = msm_comm_set_buses(core); + return rc; } @@ -1058,7 +1084,7 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc) } if (do_bw_calc) { - if (msm_comm_vote_bus(core)) { + if (msm_comm_vote_bus(inst)) { dprintk(VIDC_ERR, "Failed to scale DDR bus. May impact perf\n"); } diff --git a/msm/vidc/msm_vidc_clocks.h b/msm/vidc/msm_vidc_clocks.h index 4872cdaa8754..956838e78c36 100644 --- a/msm/vidc/msm_vidc_clocks.h +++ b/msm/vidc/msm_vidc_clocks.h @@ -9,7 +9,7 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst); int msm_vidc_set_clocks(struct msm_vidc_core *core); -int msm_comm_vote_bus(struct msm_vidc_core *core); +int msm_comm_vote_bus(struct msm_vidc_inst *inst); int msm_dcvs_try_enable(struct msm_vidc_inst *inst); bool res_is_less_than(u32 width, u32 height, u32 ref_width, u32 ref_height); bool res_is_greater_than(u32 width, u32 height, u32 ref_width, u32 ref_height); diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 506a4b80f659..c54bb0ea2cda 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -423,6 +423,27 @@ struct clock_data { u32 frame_rate; }; +struct vidc_bus_vote_data { + enum hal_domain domain; + enum hal_video_codec codec; + enum hal_uncompressed_format color_formats[2]; + int num_formats; /* 1 = DPB-OPB unified; 2 = split */ + int input_height, input_width, bitrate; + int output_height, output_width; + int rotation; + int compression_ratio; + int complexity_factor; + int input_cr; + unsigned int lcu_size; + unsigned int fps; + enum msm_vidc_power_mode power_mode; + u32 work_mode; + bool use_sys_cache; + bool b_frames_enabled; + unsigned long calc_bw_ddr; + unsigned long calc_bw_llcc; +}; + struct profile_data { int start; int stop; @@ -450,6 +471,7 @@ struct msm_vidc_core_ops { int (*decide_work_route)(struct msm_vidc_inst *inst); int (*decide_work_mode)(struct msm_vidc_inst *inst); int (*decide_core_and_power_mode)(struct msm_vidc_inst *inst); + int (*calc_bw)(struct vidc_bus_vote_data *vidc_data); }; struct msm_vidc_core { @@ -524,6 +546,7 @@ struct msm_vidc_inst { struct msm_vidc_debug debug; struct buf_count count; struct clock_data clk_data; + struct vidc_bus_vote_data bus_data; enum msm_vidc_modes flags; struct msm_vidc_capability capability; u32 buffer_size_limit; diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index a2746df040f8..86ce8e48ea1b 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -58,8 +58,6 @@ /* 16 video sessions */ #define VIDC_MAX_SESSIONS 16 -struct vidc_bus_vote_data; - enum vidc_status { VIDC_ERR_NONE = 0x0, VIDC_ERR_FAIL = 0x80000000, @@ -721,8 +719,8 @@ struct hfi_device { int (*session_pause)(void *sess); int (*session_resume)(void *sess); int (*scale_clocks)(void *dev, u32 freq); - int (*vote_bus)(void *dev, struct vidc_bus_vote_data *data, - int num_data); + int (*vote_bus)(void *dev, unsigned long bw_ddr, + unsigned long bw_llcc); int (*get_fw_info)(void *dev, struct hal_fw_info *fw_info); int (*session_clean)(void *sess); int (*get_core_capabilities)(void *dev); From d27e0f61155a6f06b96c1bdd2d74d8fee885d91e Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Thu, 15 Aug 2019 21:49:55 +0800 Subject: [PATCH 139/452] msm: vidc: optimize buffer alloc in bitrate check Avoid alloc/free buffer at frame level in window based bitrate check, re-use existing nodes to reduce CPU workload, especially for HFR video. Change-Id: I8bbbbef5229af7e608d7da1dfa4f75aab3903649 Signed-off-by: Qiwei Liu --- msm/vidc/msm_vidc_common.c | 60 +++++++++++++++++++++++++++----------- msm/vidc/msm_vidc_common.h | 1 + 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index ac5cd6d17ffb..bb52869c5fbc 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2121,7 +2121,7 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) } if (flush_type == HAL_FLUSH_ALL) { - msm_comm_release_window_data(inst); + msm_comm_clear_window_data(inst); msm_comm_release_client_data(inst); } @@ -7376,7 +7376,7 @@ bool msm_comm_check_for_inst_overload(struct msm_vidc_core *core) int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, struct vidc_frame_data *frame_data) { - struct msm_vidc_window_data *pdata, *next; + struct msm_vidc_window_data *pdata, *temp = NULL; u32 bitrate, max_br, window_size; int buf_cnt = 1, fps, window_start; @@ -7385,7 +7385,8 @@ int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, return -EINVAL; } - if (!inst->core->resources.avsync_window_size) + if (!inst->core->resources.avsync_window_size || + !frame_data->filled_len) return 0; fps = inst->clk_data.frame_rate >> 16; @@ -7397,28 +7398,36 @@ int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, window_size = inst->core->resources.avsync_window_size * fps; window_size = DIV_ROUND_UP(window_size, 1000); - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - dprintk(VIDC_ERR, "%s: malloc failure.\n", __func__); - return -ENOMEM; - } - - bitrate = pdata->frame_size = frame_data->filled_len; - window_start = pdata->etb_count = inst->count.etb; + bitrate = frame_data->filled_len; + window_start = inst->count.etb; mutex_lock(&inst->window_data.lock); - list_add(&pdata->list, &inst->window_data.list); - list_for_each_entry_safe_continue(pdata, next, - &inst->window_data.list, list) { - if (buf_cnt < window_size) { + list_for_each_entry(pdata, &inst->window_data.list, list) { + if (buf_cnt < window_size && pdata->frame_size) { bitrate += pdata->frame_size; window_start = pdata->etb_count; buf_cnt++; } else { - list_del(&pdata->list); - kfree(pdata); + pdata->frame_size = 0; + temp = pdata; } } + + pdata = NULL; + if(!temp) { + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + dprintk(VIDC_ERR, "%s: malloc failure.\n", __func__); + mutex_unlock(&inst->window_data.lock); + return -ENOMEM; + } + } else { + pdata = temp; + list_del(&pdata->list); + } + pdata->frame_size = frame_data->filled_len; + pdata->etb_count = inst->count.etb; + list_add(&pdata->list, &inst->window_data.list); mutex_unlock(&inst->window_data.lock); bitrate = DIV_ROUND_UP(((u64)bitrate * 8 * fps), window_size); @@ -7432,6 +7441,23 @@ int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, return 0; } +void msm_comm_clear_window_data(struct msm_vidc_inst *inst) +{ + struct msm_vidc_window_data *pdata; + + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid params %pK\n", + __func__, inst); + return; + } + + mutex_lock(&inst->window_data.lock); + list_for_each_entry(pdata, &inst->window_data.list, list) { + pdata->frame_size = 0; + } + mutex_unlock(&inst->window_data.lock); +} + void msm_comm_release_window_data(struct msm_vidc_inst *inst) { struct msm_vidc_window_data *pdata, *next; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index b8bbc5995cd3..8a9e516411bc 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -333,5 +333,6 @@ bool msm_comm_check_for_inst_overload(struct msm_vidc_core *core); void msm_vidc_batch_handler(struct work_struct *work); int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, struct vidc_frame_data *frame_data); +void msm_comm_clear_window_data(struct msm_vidc_inst *inst); void msm_comm_release_window_data(struct msm_vidc_inst *inst); #endif From b1e18454d0c2c1a2df2054f2698ebe45d9e3fbe4 Mon Sep 17 00:00:00 2001 From: Akshay Chandrashekhar Kalghatgi Date: Fri, 16 Aug 2019 10:39:51 -0700 Subject: [PATCH 140/452] msm: vidc: Check NAL stream format for secure session In case of secure encoding, NAL length based NAL header not supported. Only startcode based NAL header is supported. Change-Id: I119ffa47a003006e5b0d3bf7fbb5eb547de00830 --- msm/vidc/msm_venc.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 4b2cc1495bba..514997a45cee 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3823,6 +3823,19 @@ int msm_venc_set_nal_stream_format(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD); stream_format.nal_stream_format_select = BIT(ctrl->val); + + /* + * Secure encode session supports 0x00000001 satrtcode based + * encoding only + */ + if (is_secure_session(inst) && + ctrl->val != V4L2_MPEG_VIDEO_HEVC_SIZE_0) { + dprintk(VIDC_ERR, + "%s: Invalid stream format setting for secure session\n", + __func__); + return -EINVAL; + } + switch (ctrl->val) { case V4L2_MPEG_VIDEO_HEVC_SIZE_0: stream_format.nal_stream_format_select = From 408a8050fb2319991bd5e9432f82e1986d4c5194 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Fri, 16 Aug 2019 12:06:11 -0700 Subject: [PATCH 141/452] msm: vidc: Add support to disable CVP usage Add support to disable overall CVP usage. Change-Id: I82e7a3e6533008b29f0beafba61fa7b6906aab53 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_venc.c | 3 +++ msm/vidc/msm_vidc_common.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 4b2cc1495bba..c2a2c19ff0a0 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -4184,6 +4184,9 @@ int msm_venc_set_extradata(struct msm_vidc_inst *inst) } } + if(!msm_vidc_cvp_usage) + inst->prop.extradata_ctrls &= ~EXTRADATA_ENC_INPUT_CVP; + /* CVP extradata is common between user space and external CVP kernel to kernel. Hence, skipping here and will be set after msm_vidc_prepare_preprocess in start_streaming*/ diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index bb52869c5fbc..5cb580239fb6 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -4220,7 +4220,7 @@ static void populate_frame_data(struct vidc_frame_data *data, if (vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG) data->flags |= HAL_BUFFERFLAG_CODECCONFIG; - if(vbuf->flags & V4L2_BUF_FLAG_CVPMETADATA_SKIP) + if(msm_vidc_cvp_usage && (vbuf->flags & V4L2_BUF_FLAG_CVPMETADATA_SKIP)) data->flags |= HAL_BUFFERFLAG_CVPMETADATA_SKIP; msm_comm_fetch_input_tag(&inst->etb_data, vb->index, From 8f3af55bc56035555cdfae96a8136b7134aeb74f Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Thu, 15 Aug 2019 15:48:55 -0700 Subject: [PATCH 142/452] msm: vidc: Force venus to max if operating rate is INT_MAX If client sets operating rate as INT_MAX, vote the highest Venus clock and BW. This will allow operating the video session at highest possible performance. DCVS & Batching is disabled. CRs-Fixed: 2502809 Change-Id: I33e952f501a3ba6c1c8588ee319e10a586941d05 Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_cvp_external.c | 4 +- msm/vidc/msm_vdec.c | 5 ++- msm/vidc/msm_venc.c | 6 ++- msm/vidc/msm_vidc_clocks.c | 17 ++++---- msm/vidc/msm_vidc_common.c | 85 ++++++++++++++++--------------------- msm/vidc/msm_vidc_common.h | 8 ++-- 6 files changed, 60 insertions(+), 65 deletions(-) diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index 4fab5a81fdd2..5725062d96cf 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -854,12 +854,12 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, } /* - * Special handling for operating rate 0xFFFFFFFF, + * Special handling for operating rate INT_MAX, * client's intention is not to skip cvp preprocess * based on operating rate, skip logic can still be * executed based on framerate though. */ - if (cvp->operating_rate == 0xFFFFFFFF) + if (cvp->operating_rate == INT_MAX) operating_rate = fps_max << 16; else operating_rate = cvp->operating_rate; diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 4628185b3bb3..4e309de188bd 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -382,7 +382,7 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE, .name = "Decoder Operating rate", .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = (MINIMUM_FPS << 16), + .minimum = (DEFAULT_FPS << 16),/* Power Vote min fps */ .maximum = INT_MAX, .default_value = (DEFAULT_FPS << 16), .step = 1, @@ -906,6 +906,9 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: inst->clk_data.operating_rate = ctrl->val; + inst->flags &= ~VIDC_TURBO; + if (ctrl->val == INT_MAX) + inst->flags |= VIDC_TURBO; break; case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE: inst->clk_data.low_latency_mode = !!ctrl->val; diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 4b2cc1495bba..a11caf3339fb 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -762,7 +762,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE, .name = "Encoder Operating rate", .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = (MINIMUM_FPS << 16), + .minimum = (DEFAULT_FPS << 16),/* Power Vote min fps */ .maximum = INT_MAX, .default_value = (DEFAULT_FPS << 16), .step = 1, @@ -1601,6 +1601,10 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: inst->clk_data.operating_rate = ctrl->val; + inst->flags &= ~VIDC_TURBO; + if (ctrl->val == INT_MAX) + inst->flags |= VIDC_TURBO; + if (inst->state < MSM_VIDC_LOAD_RESOURCES) msm_vidc_calculate_buffer_counts(inst); if (inst->state == MSM_VIDC_START_DONE) { diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 39cb2b83845a..00684eab68c4 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -358,7 +358,7 @@ int msm_comm_vote_bus(struct msm_vidc_inst *inst) if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW && inst->session_type != MSM_VIDC_CVP) vote_data->power_mode = VIDC_POWER_TURBO; - if (msm_vidc_clock_voting || is_turbo) + if (msm_vidc_clock_voting || is_turbo || is_turbo_session(inst)) vote_data->power_mode = VIDC_POWER_TURBO; if (inst->session_type == MSM_VIDC_CVP) { @@ -640,7 +640,7 @@ static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, dcvs = &inst->clk_data; mbs_per_second = msm_comm_get_inst_load_per_core(inst, - LOAD_CALC_NO_QUIRKS); + LOAD_POWER); fps = msm_vidc_get_fps(inst); @@ -726,7 +726,7 @@ static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst, dcvs = &inst->clk_data; mbs_per_second = msm_comm_get_inst_load_per_core(inst, - LOAD_CALC_NO_QUIRKS); + LOAD_POWER); fps = msm_vidc_get_fps(inst); @@ -822,7 +822,7 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, dcvs = &inst->clk_data; mbs_per_second = msm_comm_get_inst_load_per_core(inst, - LOAD_CALC_NO_QUIRKS); + LOAD_POWER); fps = msm_vidc_get_fps(inst); @@ -1105,6 +1105,7 @@ int msm_dcvs_try_enable(struct msm_vidc_inst *inst) inst->flags & VIDC_THUMBNAIL || inst->clk_data.low_latency_mode || inst->batch.enable || + is_turbo_session(inst) || inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ); dprintk(VIDC_HIGH|VIDC_PERF, "DCVS %s: %pK\n", @@ -1171,7 +1172,7 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) core = inst->core; dcvs = &inst->clk_data; - load = msm_comm_get_inst_load_per_core(inst, LOAD_CALC_NO_QUIRKS); + load = msm_comm_get_inst_load_per_core(inst, LOAD_POWER); cycles = inst->clk_data.entry->vpp_cycles; allowed_clks_tbl = core->resources.allowed_clks_tbl; if (inst->session_type == MSM_VIDC_ENCODER) { @@ -1678,7 +1679,7 @@ static u32 get_core_load(struct msm_vidc_core *core, continue; } current_inst_mbs_per_sec = msm_comm_get_inst_load_per_core(inst, - LOAD_CALC_NO_QUIRKS); + LOAD_POWER); load += current_inst_mbs_per_sec * cycles / inst->clk_data.work_route; } @@ -1715,11 +1716,11 @@ int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) inst->clk_data.entry->low_power_cycles : inst->clk_data.entry->vpp_cycles; - cur_inst_load = (msm_comm_get_inst_load(inst, LOAD_CALC_NO_QUIRKS) * + cur_inst_load = (msm_comm_get_inst_load(inst, LOAD_POWER) * inst->clk_data.entry->vpp_cycles)/inst->clk_data.work_route; cur_inst_lp_load = (msm_comm_get_inst_load(inst, - LOAD_CALC_NO_QUIRKS) * lp_cycles)/inst->clk_data.work_route; + LOAD_POWER) * lp_cycles)/inst->clk_data.work_route; mbpf = msm_vidc_get_mbs_per_frame(inst); mbps = mbpf * msm_vidc_get_fps(inst); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index bb52869c5fbc..1e03c00711a4 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -775,7 +775,8 @@ int msm_comm_get_num_perf_sessions(struct msm_vidc_inst *inst) return count; } -static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst) +static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst, + enum load_calc_quirks quirks) { int input_port_mbs, output_port_mbs; int fps; @@ -789,11 +790,15 @@ static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst) output_port_mbs = NUM_MBS_PER_FRAME(f->fmt.pix_mp.width, f->fmt.pix_mp.height); - if (inst->clk_data.operating_rate > inst->clk_data.frame_rate) - fps = (inst->clk_data.operating_rate >> 16) ? - inst->clk_data.operating_rate >> 16 : 1; - else - fps = inst->clk_data.frame_rate >> 16; + fps = inst->clk_data.frame_rate; + + /* For admission control operating rate is ignored */ + if (quirks == LOAD_POWER) + fps = max(inst->clk_data.operating_rate, + inst->clk_data.frame_rate); + + /* In case of fps < 1 we assume 1 */ + fps = max(fps >> 16, 1); return max(input_port_mbs, output_port_mbs) * fps; } @@ -809,40 +814,28 @@ int msm_comm_get_inst_load(struct msm_vidc_inst *inst, inst->state < MSM_VIDC_STOP_DONE)) goto exit; - load = msm_comm_get_mbs_per_sec(inst); - - if (is_thumbnail_session(inst)) { - if (quirks & LOAD_CALC_IGNORE_THUMBNAIL_LOAD) - load = 0; - } - - if (is_turbo_session(inst)) { - if (!(quirks & LOAD_CALC_IGNORE_TURBO_LOAD)) - load = inst->core->resources.max_load; - } - /* Clock and Load calculations for REALTIME/NON-REALTIME - * OPERATING RATE SET/NO OPERATING RATE SET - * - * | OPERATING RATE SET | OPERATING RATE NOT SET | - * ----------------|--------------------- |------------------------| - * REALTIME | load = res * op_rate | load = res * fps | - * | clk = res * op_rate | clk = res * fps | - * ----------------|----------------------|------------------------| - * NON-REALTIME | load = res * 1 fps | load = res * 1 fps | - * | clk = res * op_rate | clk = res * fps | - * ----------------|----------------------|------------------------| + * Operating rate will either Default or Client value. + * Session admission control will be based on Load. + * Power requests based of calculated Clock/Freq. + * ----------------|----------------------------| + * REALTIME | Admission Control Load = | + * | res * fps | + * | Power Request Load = | + * | res * max(op, fps)| + * ----------------|----------------------------| + * NON-REALTIME/ | Admission Control Load = 0 | + * THUMBNAIL | Power Request Load = | + * | res * max(op, fps)| + * ----------------|----------------------------| */ - if (!is_realtime_session(inst) && - (quirks & LOAD_CALC_IGNORE_NON_REALTIME_LOAD)) { - if (!(inst->clk_data.frame_rate >> 16)) { - dprintk(VIDC_LOW, "instance:%pK fps = 0\n", inst); - load = 0; - } else { - load = msm_comm_get_mbs_per_sec(inst) / - (inst->clk_data.frame_rate >> 16); - } + if ((is_thumbnail_session(inst) || + !is_realtime_session(inst)) && + quirks == LOAD_ADMISSION_CONTROL) { + load = 0; + } else { + load = msm_comm_get_mbs_per_sec(inst, quirks); } exit: @@ -861,7 +854,7 @@ int msm_comm_get_inst_load_per_core(struct msm_vidc_inst *inst, return load; } -int msm_comm_get_load(struct msm_vidc_core *core, +int msm_comm_get_device_load(struct msm_vidc_core *core, enum session_type type, enum load_calc_quirks quirks) { struct msm_vidc_inst *inst = NULL; @@ -3277,9 +3270,7 @@ static int msm_vidc_load_resources(int flipped_state, struct hfi_device *hdev; int num_mbs_per_sec = 0, max_load_adj = 0; struct msm_vidc_core *core; - enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD | - LOAD_CALC_IGNORE_THUMBNAIL_LOAD | - LOAD_CALC_IGNORE_NON_REALTIME_LOAD; + enum load_calc_quirks quirks = LOAD_ADMISSION_CONTROL; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); @@ -3298,8 +3289,8 @@ static int msm_vidc_load_resources(int flipped_state, core = inst->core; num_mbs_per_sec = - msm_comm_get_load(core, MSM_VIDC_DECODER, quirks) + - msm_comm_get_load(core, MSM_VIDC_ENCODER, quirks); + msm_comm_get_device_load(core, MSM_VIDC_DECODER, quirks) + + msm_comm_get_device_load(core, MSM_VIDC_ENCODER, quirks); max_load_adj = core->resources.max_load + inst->capability.cap[CAP_MBS_PER_FRAME].max; @@ -5629,15 +5620,13 @@ static int msm_vidc_check_mbpf_supported(struct msm_vidc_inst *inst) static int msm_vidc_check_mbps_supported(struct msm_vidc_inst *inst) { int num_mbs_per_sec = 0, max_load_adj = 0; - enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD | - LOAD_CALC_IGNORE_THUMBNAIL_LOAD | - LOAD_CALC_IGNORE_NON_REALTIME_LOAD; + enum load_calc_quirks quirks = LOAD_ADMISSION_CONTROL; if (inst->state == MSM_VIDC_OPEN_DONE) { max_load_adj = inst->core->resources.max_load; - num_mbs_per_sec = msm_comm_get_load(inst->core, + num_mbs_per_sec = msm_comm_get_device_load(inst->core, MSM_VIDC_DECODER, quirks); - num_mbs_per_sec += msm_comm_get_load(inst->core, + num_mbs_per_sec += msm_comm_get_device_load(inst->core, MSM_VIDC_ENCODER, quirks); if (num_mbs_per_sec > max_load_adj) { dprintk(VIDC_ERR, diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 8a9e516411bc..e854cd3abf3d 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -33,10 +33,8 @@ struct getprop_buf { }; enum load_calc_quirks { - LOAD_CALC_NO_QUIRKS = 0, - LOAD_CALC_IGNORE_TURBO_LOAD = 1 << 0, - LOAD_CALC_IGNORE_THUMBNAIL_LOAD = 1 << 1, - LOAD_CALC_IGNORE_NON_REALTIME_LOAD = 1 << 2, + LOAD_POWER = 0, + LOAD_ADMISSION_CONTROL = 1, }; enum client_set_controls { @@ -241,7 +239,7 @@ int msm_comm_get_inst_load(struct msm_vidc_inst *inst, enum load_calc_quirks quirks); int msm_comm_get_inst_load_per_core(struct msm_vidc_inst *inst, enum load_calc_quirks quirks); -int msm_comm_get_load(struct msm_vidc_core *core, +int msm_comm_get_device_load(struct msm_vidc_core *core, enum session_type type, enum load_calc_quirks quirks); int msm_comm_set_color_format(struct msm_vidc_inst *inst, enum hal_buffer buffer_type, int fourcc); From 1dd6b69b530324020038bc5601831191d635ca7c Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Mon, 19 Aug 2019 13:27:16 -0700 Subject: [PATCH 143/452] msm: vidc: Set ETB extradata address to NULL during EOS Firmware needs to access extradata buffer to find the size of extradata. In secure sessions, assigning input buffer address to extradata address causes fault since firmware does not have access to input adderss. Extradata address and size in ETB must be set to zero for EOS cases so that firmware skips accessing the extradata buffer. CRs-Fixed: 2444064 Change-Id: Ia916d2f5f0500c85426fee3274f88fcf36103068 Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index f6b984f2dcc4..32815d811d5f 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -4039,7 +4039,7 @@ int msm_vidc_send_pending_eos_buffers(struct msm_vidc_inst *inst) data.offset = 0; data.flags = HAL_BUFFERFLAG_EOS; data.timestamp = 0; - data.extradata_addr = data.device_addr; + data.extradata_addr = 0; data.extradata_size = 0; dprintk(VIDC_HIGH, "Queueing EOS buffer 0x%x\n", data.device_addr); From 4b98f5a1ae6ec2b4bba85b6fa56cdc41fcfacc05 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 14 Aug 2019 11:28:01 +0530 Subject: [PATCH 144/452] msm: vidc: optimize buffer tag allocation - Possiblilty of performance hit due to memory alloc/free at frame level. - Reuse same buffer_tag instead of reallocating. Change-Id: Ifb8efc43907feea4d6da5e8a0bf0aeaa47c8e1d7 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc.c | 2 +- msm/vidc/msm_vidc_common.c | 64 ++++++++++++++++++++------------------ msm/vidc/msm_vidc_common.h | 2 +- 3 files changed, 36 insertions(+), 32 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index a77421da93e8..14f58f89e547 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1776,7 +1776,7 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst) dprintk(VIDC_ERR, "Failed to release input_tag buffers\n"); - msm_comm_release_client_data(inst); + msm_comm_release_client_data(inst, true); msm_comm_release_window_data(inst); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index f6b984f2dcc4..bf2c52235232 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2115,7 +2115,8 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) if (flush_type == HAL_FLUSH_ALL) { msm_comm_clear_window_data(inst); - msm_comm_release_client_data(inst); + msm_comm_release_client_data(inst, false); + inst->clk_data.buffer_counter = 0; } dprintk(VIDC_HIGH, @@ -6973,7 +6974,7 @@ bool kref_get_mbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) struct msm_vidc_client_data *msm_comm_store_client_data( struct msm_vidc_inst *inst, u32 itag) { - struct msm_vidc_client_data *data = NULL; + struct msm_vidc_client_data *data = NULL, *temp = NULL; if (!inst) { dprintk(VIDC_ERR, "%s: invalid params %pK %un", @@ -6982,10 +6983,20 @@ struct msm_vidc_client_data *msm_comm_store_client_data( } mutex_lock(&inst->client_data.lock); - data = kzalloc(sizeof(*data), GFP_KERNEL); + list_for_each_entry(temp, &inst->client_data.list, list) { + if (!temp->id) { + data = temp; + break; + } + } if (!data) { - dprintk(VIDC_ERR, "No memory left to allocate tag data"); - goto exit; + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + dprintk(VIDC_ERR, "No memory avilable - tag data"); + goto exit; + } + INIT_LIST_HEAD(&data->list); + list_add_tail(&data->list, &inst->client_data.list); } /** @@ -6995,10 +7006,8 @@ struct msm_vidc_client_data *msm_comm_store_client_data( if (!inst->etb_counter) inst->etb_counter = 1; - INIT_LIST_HEAD(&data->list); data->id = inst->etb_counter++; data->input_tag = itag; - list_add_tail(&data->list, &inst->client_data.list); exit: mutex_unlock(&inst->client_data.lock); @@ -7017,33 +7026,25 @@ void msm_comm_fetch_client_data(struct msm_vidc_inst *inst, bool remove, __func__, inst, otag, otag2); return; } - + /** + * Some interlace clips, both BF & TF is available in single ETB buffer. + * In that case, firmware copies same input_tag value to both input_tag + * and input_tag2 at FBD. + */ + if (!itag2 || itag == itag2) + found_itag2 = true; mutex_lock(&inst->client_data.lock); list_for_each_entry_safe(temp, next, &inst->client_data.list, list) { if (temp->id == itag) { *otag = temp->input_tag; - if (remove) { - list_del(&temp->list); - kfree(temp); - } found_itag = true; - /** - * Some interlace clips, both BF & TP is available in - * single ETB buffer. In that case, firmware copies - * same input_tag value to both input_tag and - * input_tag2 at FBD. - */ - if (!itag2 || itag == itag2) { - found_itag2 = true; - break; - } - } else if (temp->id == itag2) { + if (remove) + temp->id = 0; + } else if (!found_itag2 && temp->id == itag2) { *otag2 = temp->input_tag; found_itag2 = true; - if (remove) { - list_del(&temp->list); - kfree(temp); - } + if (remove) + temp->id = 0; } if (found_itag && found_itag2) break; @@ -7056,7 +7057,7 @@ void msm_comm_fetch_client_data(struct msm_vidc_inst *inst, bool remove, } } -void msm_comm_release_client_data(struct msm_vidc_inst *inst) +void msm_comm_release_client_data(struct msm_vidc_inst *inst, bool remove) { struct msm_vidc_client_data *temp, *next; @@ -7068,8 +7069,11 @@ void msm_comm_release_client_data(struct msm_vidc_inst *inst) mutex_lock(&inst->client_data.lock); list_for_each_entry_safe(temp, next, &inst->client_data.list, list) { - list_del(&temp->list); - kfree(temp); + temp->id = 0; + if (remove) { + list_del(&temp->list); + kfree(temp); + } } mutex_unlock(&inst->client_data.lock); } diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index e854cd3abf3d..c6e5758b7267 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -315,7 +315,7 @@ struct msm_vidc_client_data *msm_comm_store_client_data( struct msm_vidc_inst *inst, u32 itag); void msm_comm_fetch_client_data(struct msm_vidc_inst *inst, bool remove, u32 itag, u32 itag2, u32 *mdata, u32 *mtarget); -void msm_comm_release_client_data(struct msm_vidc_inst *inst); +void msm_comm_release_client_data(struct msm_vidc_inst *inst, bool remove); int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst, From b6d2a310889cd187ff05a24fe1ea6140206fea9e Mon Sep 17 00:00:00 2001 From: Amit Shekhar Date: Tue, 20 Aug 2019 17:40:07 -0700 Subject: [PATCH 145/452] msm_vidc: Skip mbpf check for image sessions MBs per frame for HEIF encode can be pretty large for high resolution images. Skip mbpf check for image sessions. Change-Id: I993115743f4792377a3a008b341d4c8256b102b9 Signed-off-by: Amit Shekhar --- msm/vidc/msm_vidc_common.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index f6b984f2dcc4..85a4a4aaca5d 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5877,7 +5877,11 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) width_max, height_max); rc = -ENOTSUPP; } - if (!rc && NUM_MBS_PER_FRAME(input_width, input_height) > + /* Image size max capability has equal width and height, + * hence, don't check mbpf for image sessions. + */ + if (!rc && !is_image_session(inst) && + NUM_MBS_PER_FRAME(input_width, input_height) > mbpf_max) { dprintk(VIDC_ERR, "Unsupported mbpf %d, max %d\n", NUM_MBS_PER_FRAME(input_width, input_height), From 5becaa46828283344d1b054a2ca25510e6f53ece Mon Sep 17 00:00:00 2001 From: Akshay Chandrashekhar Kalghatgi Date: Mon, 19 Aug 2019 15:40:12 -0700 Subject: [PATCH 146/452] msm: vidc: Update video-CVP interaction call flow Update video-CVP interaction with new call flow sequence. Add session create and session delete commands (reference gerrit#2756413). Remove CVP persist buffer release command. Change-Id: Ia3a9ad10e93e19a26f59d9abb7dcccd1605e1ff9 --- msm/vidc/msm_cvp_external.c | 441 +++++++++++++++++++++++++----------- msm/vidc/msm_vidc.c | 4 +- 2 files changed, 314 insertions(+), 131 deletions(-) diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index 5725062d96cf..0389047ff17f 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -257,7 +257,7 @@ static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst) int rc = 0; struct msm_cvp_external *cvp; struct cvp_kmd_arg *arg; - struct v4l2_format *f; + struct v4l2_format *fmt; struct cvp_kmd_usecase_desc desc; struct cvp_kmd_request_power power; const u32 fps_max = CVP_FRAME_RATE_MAX; @@ -271,7 +271,7 @@ static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst) memset(&desc, 0, sizeof(struct cvp_kmd_usecase_desc)); memset(&power, 0, sizeof(struct cvp_kmd_request_power)); - f = &inst->fmts[INPUT_PORT].v4l2_fmt; + fmt = &inst->fmts[INPUT_PORT].v4l2_fmt; desc.fullres_width = cvp->width; desc.fullres_height = cvp->height; desc.downscale_width = cvp->ds_width; @@ -279,7 +279,7 @@ static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst) desc.is_downscale = cvp->downscale; desc.fps = min(cvp->frame_rate >> 16, fps_max); desc.op_rate = cvp->operating_rate >> 16; - desc.colorfmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat); + desc.colorfmt = msm_comm_convert_color_fmt(fmt->fmt.pix_mp.pixelformat); rc = msm_cvp_est_cycles(&desc, &power); if (rc) { dprintk(VIDC_ERR, "%s: estimate failed\n", __func__); @@ -514,8 +514,6 @@ static void msm_cvp_deinit_internal_buffers(struct msm_vidc_inst *inst) { int rc = 0; struct msm_cvp_external *cvp; - struct cvp_kmd_arg *arg; - struct msm_cvp_session_release_persist_buffers_packet persist2_packet; if (!inst || !inst->cvp) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); @@ -538,41 +536,6 @@ static void msm_cvp_deinit_internal_buffers(struct msm_vidc_inst *inst) if (cvp->persist2_buffer.dbuf) { print_cvp_buffer(VIDC_HIGH, "free: persist2_buffer", inst, &cvp->persist2_buffer); - memset(&persist2_packet, 0, sizeof(struct - msm_cvp_session_release_persist_buffers_packet)); - persist2_packet.size = sizeof(struct - msm_cvp_session_release_persist_buffers_packet); - persist2_packet.packet_type = - HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS; - persist2_packet.session_id = cvp->session_id; - persist2_packet.cvp_op = CVP_DME; - fill_cvp_buffer(&persist2_packet.persist2_buffer, - &cvp->persist2_buffer); - - arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL); - if (arg) { - arg->type = CVP_KMD_HFI_PERSIST_CMD; - arg->buf_offset = offsetof(struct - msm_cvp_session_release_persist_buffers_packet, - persist1_buffer) / sizeof(u32); - arg->buf_num = (sizeof(struct - msm_cvp_session_release_persist_buffers_packet) - - (arg->buf_offset * sizeof(u32))) / - sizeof(struct msm_cvp_buffer_type); - memcpy(&(arg->data.pbuf_cmd), &persist2_packet, - sizeof(struct - msm_cvp_session_release_persist_buffers_packet)); - rc = msm_cvp_private(cvp->priv, - CVP_KMD_HFI_PERSIST_CMD, arg); - if (rc) - print_cvp_buffer(VIDC_ERR, - "release failed: persist2_buffer", - inst, &cvp->persist2_buffer); - kfree(arg); - } else { - dprintk(VIDC_ERR, "%s: alloc failed\n", __func__); - } - rc = msm_cvp_free_buffer(inst, &cvp->persist2_buffer); if (rc) print_cvp_buffer(VIDC_ERR, @@ -581,12 +544,12 @@ static void msm_cvp_deinit_internal_buffers(struct msm_vidc_inst *inst) } } -static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst) +static int msm_cvp_set_persist_buffer(struct msm_vidc_inst *inst) { int rc = 0; struct msm_cvp_external *cvp; struct cvp_kmd_arg *arg; - struct msm_cvp_session_set_persist_buffers_packet persist2_packet; + struct msm_cvp_session_set_persist_buffers_packet persist2_packet = {0}; if (!inst || !inst->cvp || !inst->cvp->arg) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); @@ -594,22 +557,7 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst) } cvp = inst->cvp; arg = cvp->arg; - dprintk(VIDC_HIGH, "%s:\n", __func__); - cvp->persist2_buffer.size = HFI_DME_INTERNAL_PERSIST_2_BUFFER_SIZE; - rc = msm_cvp_allocate_buffer(inst, &cvp->persist2_buffer, false); - if (rc) { - print_cvp_buffer(VIDC_ERR, - "allocate failed: persist2_buffer", - inst, &cvp->persist2_buffer); - goto error; - } - print_cvp_buffer(VIDC_HIGH, "alloc: persist2_buffer", - inst, &cvp->persist2_buffer); - - /* set buffer */ - memset(&persist2_packet, 0, - sizeof(struct msm_cvp_session_set_persist_buffers_packet)); persist2_packet.size = sizeof(struct msm_cvp_session_set_persist_buffers_packet); persist2_packet.packet_type = HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS; @@ -634,8 +582,32 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst) print_cvp_buffer(VIDC_ERR, "set failed: persist2_buffer", inst, &cvp->persist2_buffer); + } + + return rc; +} + +static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; + + cvp->persist2_buffer.size = HFI_DME_INTERNAL_PERSIST_2_BUFFER_SIZE; + rc = msm_cvp_allocate_buffer(inst, &cvp->persist2_buffer, false); + if (rc) { + print_cvp_buffer(VIDC_ERR, + "allocate failed: persist2_buffer", + inst, &cvp->persist2_buffer); goto error; } + print_cvp_buffer(VIDC_HIGH, "alloc: persist2_buffer", + inst, &cvp->persist2_buffer); /* allocate one output buffer for internal use */ cvp->output_buffer.size = HFI_DME_OUTPUT_BUFFER_SIZE; @@ -812,6 +784,69 @@ static int msm_cvp_reference_management(struct msm_vidc_inst *inst) return rc; } +static int msm_vidc_cvp_session_start(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp = NULL; + struct cvp_kmd_session_control *ctrl = NULL; + struct cvp_kmd_arg *arg = NULL; + + if (!inst || !inst->cvp || !inst->cvp->arg) { + dprintk(VIDC_ERR, "%s: invalid param\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; + arg = cvp->arg; + + memset(arg, 0, sizeof(struct cvp_kmd_arg)); + arg->type = CVP_KMD_SESSION_CONTROL; + ctrl = (struct cvp_kmd_session_control *)&arg->data.session_ctrl; + ctrl->ctrl_type = SESSION_START; + + rc = msm_cvp_private(cvp->priv, CVP_KMD_SESSION_CONTROL, arg); + if (rc) { + dprintk(VIDC_ERR, + "%s: CVP_KMD_SESSION_CONTROL failed, rc %d\n", + __func__, rc); + return rc; + } + + return rc; +} + +static int msm_vidc_cvp_session_stop(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp = NULL; + struct cvp_kmd_session_control *ctrl = NULL; + struct cvp_kmd_arg *arg = NULL; + + if (!inst || !inst->cvp || !inst->cvp->arg) { + dprintk(VIDC_ERR, "%s: invalid param\n", __func__); + return -EINVAL; + } + + cvp = inst->cvp; + arg = cvp->arg; + + memset(arg, 0, sizeof(struct cvp_kmd_arg)); + + arg->type = CVP_KMD_SESSION_CONTROL; + + ctrl = (struct cvp_kmd_session_control *)&arg->data.session_ctrl; + ctrl->ctrl_type = SESSION_STOP; + + rc = msm_cvp_private(cvp->priv, CVP_KMD_SESSION_CONTROL, arg); + if (rc) { + dprintk(VIDC_ERR, + "%s: CVP_KMD_SESSION_CONTROL failed, rc %d\n", + __func__, rc); + return rc; + } + + return rc; +} + static int msm_cvp_frame_process(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) { @@ -982,7 +1017,37 @@ int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst, return rc; } -static int msm_vidc_cvp_deinit(struct msm_vidc_inst *inst) +static int msm_vidc_cvp_session_delete(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp = NULL; + struct cvp_kmd_session_control *ctrl = NULL; + struct cvp_kmd_arg *arg = NULL; + + if (!inst || !inst->cvp || !inst->cvp->arg) { + dprintk(VIDC_ERR, "%s: invalid param\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; + arg = cvp->arg; + + memset(arg, 0, sizeof(struct cvp_kmd_arg)); + arg->type = CVP_KMD_SESSION_CONTROL; + ctrl = (struct cvp_kmd_session_control *)&arg->data.session_ctrl; + ctrl->ctrl_type = SESSION_DELETE; + + rc = msm_cvp_private(cvp->priv, CVP_KMD_SESSION_CONTROL, arg); + if (rc) { + dprintk(VIDC_ERR, + "%s: CVP_KMD_SESSION_CONTROL failed, rc %d\n", + __func__, rc); + return rc; + } + + return rc; +} + +static int msm_cvp_mem_deinit(struct msm_vidc_inst *inst) { int rc = 0; struct msm_cvp_external *cvp; @@ -998,6 +1063,32 @@ static int msm_vidc_cvp_deinit(struct msm_vidc_inst *inst) msm_cvp_deinit_context_buffers(inst); msm_cvp_deinit_downscale_buffers(inst); + cvp->priv = NULL; + kfree(cvp->arg); + cvp->arg = NULL; + kfree(inst->cvp); + inst->cvp = NULL; + + return rc; +} + +static int msm_vidc_cvp_deinit(struct msm_vidc_inst *inst) +{ + int rc = 0; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + rc = msm_vidc_cvp_session_stop(inst); + if (rc) { + dprintk(VIDC_ERR, "%s: cvp stop failed with error %d\n", + __func__, rc); + } + + msm_vidc_cvp_session_delete(inst); + return rc; } @@ -1014,15 +1105,10 @@ static int msm_vidc_cvp_close(struct msm_vidc_inst *inst) dprintk(VIDC_HIGH, "%s: cvp session %#x\n", __func__, cvp->session_id); rc = msm_cvp_close(cvp->priv); - if (rc) + if (rc) { dprintk(VIDC_ERR, "%s: cvp close failed with error %d\n", __func__, rc); - cvp->priv = NULL; - - kfree(cvp->arg); - cvp->arg = NULL; - kfree(inst->cvp); - inst->cvp = NULL; + } return rc; } @@ -1040,17 +1126,84 @@ int msm_vidc_cvp_unprepare_preprocess(struct msm_vidc_inst *inst) msm_vidc_cvp_deinit(inst); msm_vidc_cvp_close(inst); + msm_cvp_mem_deinit(inst); return 0; } -static int msm_vidc_cvp_init(struct msm_vidc_inst *inst) +static int msm_vidc_cvp_session_create(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp = NULL; + struct cvp_kmd_session_control *ctrl = NULL; + struct cvp_kmd_arg *arg = NULL; + + if (!inst || !inst->cvp || !inst->cvp->arg) { + dprintk(VIDC_ERR, "%s: invalid param\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; + arg = cvp->arg; + + memset(arg, 0, sizeof(struct cvp_kmd_arg)); + arg->type = CVP_KMD_SESSION_CONTROL; + ctrl = (struct cvp_kmd_session_control *)&arg->data.session_ctrl; + ctrl->ctrl_type = SESSION_CREATE; + + rc = msm_cvp_private(cvp->priv, CVP_KMD_SESSION_CONTROL, arg); + if (rc) { + dprintk(VIDC_ERR, + "%s: CVP_KMD_SESSION_CONTROL failed, rc %d\n", + __func__, rc); + return rc; + } + + return rc; +} + +static int msm_vidc_cvp_getsessioninfo(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp; + struct cvp_kmd_arg *arg; + + if (!inst || !inst->cvp || !inst->cvp->arg) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; + arg = cvp->arg; + + memset(arg, 0, sizeof(struct cvp_kmd_arg)); + arg->type = CVP_KMD_GET_SESSION_INFO; + rc = msm_cvp_private(cvp->priv, CVP_KMD_GET_SESSION_INFO, arg); + if (rc) { + dprintk(VIDC_ERR, "%s: get_session_info failed\n", __func__); + goto error; + } + cvp->session_id = arg->data.session.session_id; + dprintk(VIDC_HIGH, "%s: cvp session id %#x\n", + __func__, cvp->session_id); + + rc = msm_cvp_get_version_info(inst); + if (rc) { + dprintk(VIDC_ERR, "%s: get_version_info failed\n", __func__); + goto error; + } + return rc; + +error: + msm_vidc_cvp_deinit(inst); + return rc; +} + +static int msm_vidc_cvp_dme_basic_config(struct msm_vidc_inst *inst) { int rc = 0; struct msm_cvp_external *cvp; - struct v4l2_format *f; struct cvp_kmd_arg *arg; struct msm_cvp_dme_basic_config_packet *dmecfg; + struct v4l2_format *fmt; u32 color_fmt; if (!inst || !inst->cvp || !inst->cvp->arg) { @@ -1059,35 +1212,6 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst) } cvp = inst->cvp; arg = cvp->arg; - cvp->framecount = 0; - cvp->metadata_available = false; - f = &inst->fmts[INPUT_PORT].v4l2_fmt; - cvp->width = f->fmt.pix_mp.width; - cvp->height = f->fmt.pix_mp.height; - cvp->frame_rate = inst->clk_data.frame_rate; - cvp->operating_rate = inst->clk_data.operating_rate; - color_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat); - - /* enable downscale always */ - cvp->downscale = true; - rc = msm_cvp_init_downscale_resolution(inst); - if (rc) - goto error; - - dprintk(VIDC_HIGH, - "%s: pixelformat %#x, wxh %dx%d downscale %d ds_wxh %dx%d fps %d op_rate %d\n", - __func__, f->fmt.pix_mp.pixelformat, - cvp->width, cvp->height, cvp->downscale, - cvp->ds_width, cvp->ds_height, - cvp->frame_rate >> 16, cvp->operating_rate >> 16); - - rc = msm_cvp_set_priority(inst); - if (rc) - goto error; - - rc = msm_cvp_set_clocks_and_bus(inst); - if (rc) - goto error; memset(arg, 0, sizeof(struct cvp_kmd_arg)); arg->type = CVP_KMD_SEND_CMD_PKT; @@ -1104,8 +1228,11 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst) COLOR_FMT_NV12_UBWC, dmecfg->src_width, dmecfg->src_height); if (rc) goto error; + + fmt = &inst->fmts[INPUT_PORT].v4l2_fmt; + color_fmt = msm_comm_convert_color_fmt(fmt->fmt.pix_mp.pixelformat); dmecfg->fullresbuffer_format = msm_comm_get_hfi_uncompressed( - f->fmt.pix_mp.pixelformat); + fmt->fmt.pix_mp.pixelformat); dmecfg->fullres_width = cvp->width; dmecfg->fullres_height = cvp->height; rc = msm_cvp_fill_planeinfo(&dmecfg->fullresbuffer_planeinfo, @@ -1121,28 +1248,15 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst) goto error; } - rc = msm_cvp_init_downscale_buffers(inst); - if (rc) - goto error; - rc = msm_cvp_init_internal_buffers(inst); - if (rc) - goto error; - rc = msm_cvp_init_context_buffers(inst); - if (rc) - goto error; - - return rc; - error: - msm_vidc_cvp_deinit(inst); return rc; } -static int msm_vidc_cvp_open(struct msm_vidc_inst *inst) +static int msm_cvp_mem_init(struct msm_vidc_inst *inst) { int rc = 0; struct msm_cvp_external *cvp; - struct cvp_kmd_arg *arg; + struct v4l2_format *fmt; if (!inst) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); @@ -1162,37 +1276,102 @@ static int msm_vidc_cvp_open(struct msm_vidc_inst *inst) inst->cvp = NULL; return -ENOMEM; } - arg = cvp->arg; + + cvp->framecount = 0; + cvp->metadata_available = false; + fmt = &inst->fmts[INPUT_PORT].v4l2_fmt; + cvp->width = fmt->fmt.pix_mp.width; + cvp->height = fmt->fmt.pix_mp.height; + cvp->frame_rate = inst->clk_data.frame_rate; + cvp->operating_rate = inst->clk_data.operating_rate; + + /* enable downscale always */ + cvp->downscale = true; + rc = msm_cvp_init_downscale_resolution(inst); + if (rc) + goto error; + + dprintk(VIDC_HIGH, + "%s: pixelformat %#x, wxh %dx%d downscale %d ds_wxh %dx%d fps %d op_rate %d\n", + __func__, fmt->fmt.pix_mp.pixelformat, + cvp->width, cvp->height, cvp->downscale, + cvp->ds_width, cvp->ds_height, + cvp->frame_rate >> 16, cvp->operating_rate >> 16); + + rc = msm_cvp_init_downscale_buffers(inst); + if (rc) + goto error; + rc = msm_cvp_init_internal_buffers(inst); + if (rc) + goto error; + rc = msm_cvp_init_context_buffers(inst); + if (rc) + goto error; + + return rc; + +error: + msm_cvp_mem_deinit(inst); + return rc; +} + +static int msm_vidc_cvp_open(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp; + + if (!inst || !inst->cvp) { + dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + cvp = inst->cvp; dprintk(VIDC_HIGH, "%s: opening cvp\n", __func__); cvp->priv = msm_cvp_open(0, MSM_VIDC_CVP); if (!cvp->priv) { dprintk(VIDC_ERR, "%s: failed to open cvp session\n", __func__); rc = -EINVAL; - goto error; } - memset(arg, 0, sizeof(struct cvp_kmd_arg)); - arg->type = CVP_KMD_GET_SESSION_INFO; - rc = msm_cvp_private(cvp->priv, CVP_KMD_GET_SESSION_INFO, arg); - if (rc) { - dprintk(VIDC_ERR, "%s: get_session_info failed\n", __func__); - goto error; - } - cvp->session_id = arg->data.session.session_id; - dprintk(VIDC_HIGH, "%s: cvp session id %#x\n", - __func__, cvp->session_id); + return rc; +} - rc = msm_cvp_get_version_info(inst); - if (rc) { - dprintk(VIDC_ERR, "%s: get_version_info failed\n", __func__); +static int msm_vidc_cvp_init(struct msm_vidc_inst *inst) +{ + int rc; + + rc = msm_cvp_set_priority(inst); + if (rc) + goto error; + + rc = msm_vidc_cvp_session_create(inst); + if (rc) + return rc; + + rc = msm_vidc_cvp_getsessioninfo(inst); + if (rc) + return rc; + + rc = msm_cvp_set_clocks_and_bus(inst); + if (rc) + goto error; + + rc = msm_vidc_cvp_dme_basic_config(inst); + if (rc) + goto error; + + rc = msm_cvp_set_persist_buffer(inst); + if (rc) + goto error; + + rc = msm_vidc_cvp_session_start(inst); + if (rc) goto error; - } return 0; error: - msm_vidc_cvp_close(inst); + msm_vidc_cvp_deinit(inst); return rc; } @@ -1205,6 +1384,10 @@ int msm_vidc_cvp_prepare_preprocess(struct msm_vidc_inst *inst) return -EINVAL; } + rc = msm_cvp_mem_init(inst); + if (rc) + return rc; + rc = msm_vidc_cvp_open(inst); if (rc) return rc; diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index a77421da93e8..c740dd3b3e1d 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -786,11 +786,11 @@ bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst) allowed = true; } else { dprintk(VIDC_HIGH, - "%s: cvp not allowed, cvp_external %d cvp_disable %d extradata %#x rc_type %d legacy_cbr %d secure %d\n", + "%s: cvp not allowed, cvp_external %d cvp_disable %d extradata %#x rc_type %d legacy_cbr %d secure %d superframe %d\n", __func__, core->resources.cvp_external, cvp_disable->val, inst->prop.extradata_ctrls, inst->rc_type, inst->clk_data.is_legacy_cbr, - is_secure_session(inst)); + is_secure_session(inst), superframe_enable->val); allowed = false; } exit: From 040e0b96c7d404217c30e41fd08c2a7679fa56c4 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Tue, 20 Aug 2019 15:51:26 +0800 Subject: [PATCH 147/452] msm_vidc: vdec: add codec check for reconfig event Add codec check for bit depth or color space only reconfig event. VP9 and HEVC have bit depth reconfig event while only HEVC has color space reconfig event. Change-Id: Ia6732e31a15957dc7116535131203a69fe19c987 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_vidc_common.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index f6b984f2dcc4..040d548ac853 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1645,6 +1645,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data) goto err_bad_event; } hdev = inst->core->device; + codec = get_v4l2_codec(inst); switch (event_notify->hal_event_type) { case HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES: @@ -1661,13 +1662,15 @@ static void handle_event_change(enum hal_command_response cmd, void *data) "event_notify->height = %d event_notify->width = %d\n", event_notify->height, event_notify->width); - event_fields_changed |= (inst->bit_depth != - event_notify->bit_depth); + if (codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_VP9) + event_fields_changed |= (inst->bit_depth != + event_notify->bit_depth); /* Check for change from hdr->non-hdr and vice versa */ - if ((event_notify->colour_space == MSM_VIDC_BT2020 && - inst->colour_space != MSM_VIDC_BT2020) || + if (codec == V4L2_PIX_FMT_HEVC && + ((event_notify->colour_space == MSM_VIDC_BT2020 && + inst->colour_space != MSM_VIDC_BT2020) || (event_notify->colour_space != MSM_VIDC_BT2020 && - inst->colour_space == MSM_VIDC_BT2020)) + inst->colour_space == MSM_VIDC_BT2020))) event_fields_changed = true; f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; @@ -1769,7 +1772,6 @@ static void handle_event_change(enum hal_command_response cmd, void *data) ptr[6] = event_notify->crop_data.left; ptr[7] = event_notify->crop_data.height; ptr[8] = event_notify->crop_data.width; - codec = get_v4l2_codec(inst); ptr[9] = msm_comm_get_v4l2_profile(codec, event_notify->profile); ptr[10] = msm_comm_get_v4l2_level(codec, From 65106f1bc6d6e773368803ff3ee351036892992a Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 21 Aug 2019 19:41:16 +0530 Subject: [PATCH 148/452] msm: vidc: Remove cluster controls V4L controls are made to be part of a cluster when they are interdependent. If any one control in that cluster is updated, all the remaining controls get updated as well with the current control value. Existing video usecase does not require any v4l controls to be clustered. Hence removing the cluster controls. Change-Id: I98dfc4af5291837054a8a28b00942fea6866f0a9 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc.c | 13 ++----------- msm/vidc/msm_vidc_common.c | 29 ----------------------------- msm/vidc/msm_vidc_internal.h | 6 ------ 3 files changed, 2 insertions(+), 46 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index a77421da93e8..a3bb1e8850d6 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1443,7 +1443,6 @@ static int msm_vidc_op_s_ctrl(struct v4l2_ctrl *ctrl) { int rc = 0; - unsigned int c = 0; struct msm_vidc_inst *inst; const char *ctrl_name = NULL; @@ -1459,17 +1458,9 @@ static int msm_vidc_op_s_ctrl(struct v4l2_ctrl *ctrl) return -EINVAL; } - for (c = 0; c < ctrl->ncontrols; ++c) { - if (ctrl->cluster[c]->is_new) { - rc = msm_vidc_try_set_ctrl(inst, ctrl->cluster[c]); - if (rc) { - dprintk(VIDC_ERR, "Failed setting %x\n", - ctrl->cluster[c]->id); - break; - } - } - } + rc = msm_vidc_try_set_ctrl(inst, ctrl); if (rc) { + dprintk(VIDC_ERR, "Failed setting %x\n", ctrl->id); ctrl_name = v4l2_ctrl_get_name(ctrl->id); dprintk(VIDC_ERR, "Failed setting control: Inst = %pK (%s)\n", inst, ctrl_name ? ctrl_name : "Invalid ctrl"); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index f6b984f2dcc4..e7b4d24982d5 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -43,24 +43,6 @@ int msm_comm_g_ctrl_for_id(struct msm_vidc_inst *inst, int id) return ctrl->val; } -static struct v4l2_ctrl **get_super_cluster(struct msm_vidc_inst *inst, - int num_ctrls) -{ - int c = 0; - struct v4l2_ctrl **cluster = kmalloc(sizeof(struct v4l2_ctrl *) * - num_ctrls, GFP_KERNEL); - - if (!cluster || !inst) { - kfree(cluster); - return NULL; - } - - for (c = 0; c < num_ctrls; c++) - cluster[c] = inst->ctrls[c]; - - return cluster; -} - int msm_comm_hfi_to_v4l2(int id, int value) { switch (id) { @@ -658,16 +640,6 @@ int msm_comm_ctrl_init(struct msm_vidc_inst *inst, } inst->num_ctrls = num_ctrls; - /* Construct a super cluster of all controls */ - inst->cluster = get_super_cluster(inst, num_ctrls); - if (!inst->cluster) { - dprintk(VIDC_ERR, - "Failed to setup super cluster\n"); - return -EINVAL; - } - - v4l2_ctrl_cluster(num_ctrls, inst->cluster); - return ret_val; } @@ -679,7 +651,6 @@ int msm_comm_ctrl_deinit(struct msm_vidc_inst *inst) } kfree(inst->ctrls); - kfree(inst->cluster); v4l2_ctrl_handler_free(&inst->ctrl_handler); return 0; diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index c54bb0ea2cda..f30ae5fb1c0f 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -537,7 +537,6 @@ struct msm_vidc_inst { struct vidc_frame_data superframe_data[VIDC_SUPERFRAME_MAX]; struct v4l2_ctrl_handler ctrl_handler; struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1]; - struct v4l2_ctrl **cluster; struct v4l2_fh event_handler; struct msm_smem *extradata_handle; bool in_reconfig; @@ -582,11 +581,6 @@ struct msm_vidc_inst { extern struct msm_vidc_drv *vidc_driver; -struct msm_vidc_ctrl_cluster { - struct v4l2_ctrl **cluster; - struct list_head list; -}; - struct msm_vidc_ctrl { u32 id; char name[MAX_NAME_LENGTH]; From d168b1dab5fb1163bde5d7fc6fc2984c8ed91633 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 23 Aug 2019 14:36:33 +0530 Subject: [PATCH 149/452] msm: vidc: Invalidate encoder output buffer cache For encode usecase, video driver operates cache always on the encoded data length rather than the buffer length. This is an optimization and saves cache operation on unused memory region. VB index is used to identify a buffer given to client and fed again to encoder. Based on that, the filled length of that buffer is then operated for cache operations. For certain usecases, it is difficult to identify the buffer based on VB index. Hence keep a counter to track the max filled length during the usecase and operate cache on that length Change-Id: I62cfe876077786ec9d14f541a0080cd2fc124b01 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc.c | 1 + msm/vidc/msm_vidc_common.c | 70 +++--------------------------------- msm/vidc/msm_vidc_common.h | 4 --- msm/vidc/msm_vidc_internal.h | 2 +- 4 files changed, 7 insertions(+), 70 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index a37b89f676ba..45f1b5f64253 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1597,6 +1597,7 @@ void *msm_vidc_open(int core_id, int session_type) inst->rc_type = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR; inst->dpb_extra_binfo = NULL; inst->all_intra = false; + inst->max_filled_len = 0; for (i = SESSION_MSG_INDEX(SESSION_MSG_START); i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) { diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index c98dc6216853..cef7372396c6 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2626,8 +2626,8 @@ static void handle_fbd(enum hal_command_response cmd, void *data) fill_buf_done->input_tag, fill_buf_done->input_tag2); if (inst->session_type == MSM_VIDC_ENCODER) { - msm_comm_store_filled_length(&inst->fbd_data, vb->index, - fill_buf_done->filled_len1); + if (inst->max_filled_len < fill_buf_done->filled_len1) + inst->max_filled_len = fill_buf_done->filled_len1; } f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; @@ -6482,14 +6482,11 @@ int msm_comm_qbuf_cache_operations(struct msm_vidc_inst *inst, } } else if (vb->type == OUTPUT_MPLANE) { if (!i) { /* bitstream */ - u32 size_u32; skip = false; offset = 0; - size_u32 = vb->planes[i].length; - msm_comm_fetch_filled_length( - &inst->fbd_data, vb->index, - &size_u32); - size = size_u32; + size = vb->planes[i].length; + if (inst->max_filled_len) + size = inst->max_filled_len; cache_op = SMEM_CACHE_INVALIDATE; } } @@ -7055,63 +7052,6 @@ void msm_comm_release_client_data(struct msm_vidc_inst *inst, bool remove) mutex_unlock(&inst->client_data.lock); } -void msm_comm_store_filled_length(struct msm_vidc_list *data_list, - u32 index, u32 filled_length) -{ - struct msm_vidc_buf_data *pdata = NULL; - bool found = false; - - if (!data_list) { - dprintk(VIDC_ERR, "%s: invalid params %pK\n", - __func__, data_list); - return; - } - - mutex_lock(&data_list->lock); - list_for_each_entry(pdata, &data_list->list, list) { - if (pdata->index == index) { - pdata->filled_length = filled_length; - found = true; - break; - } - } - - if (!found) { - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - dprintk(VIDC_ERR, "%s: malloc failure.\n", __func__); - goto exit; - } - pdata->index = index; - pdata->filled_length = filled_length; - list_add_tail(&pdata->list, &data_list->list); - } - -exit: - mutex_unlock(&data_list->lock); -} - -void msm_comm_fetch_filled_length(struct msm_vidc_list *data_list, - u32 index, u32 *filled_length) -{ - struct msm_vidc_buf_data *pdata = NULL; - - if (!data_list || !filled_length) { - dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", - __func__, data_list, filled_length); - return; - } - - mutex_lock(&data_list->lock); - list_for_each_entry(pdata, &data_list->list, list) { - if (pdata->index == index) { - *filled_length = pdata->filled_length; - break; - } - } - mutex_unlock(&data_list->lock); -} - void msm_comm_store_input_tag(struct msm_vidc_list *data_list, u32 index, u32 itag, u32 itag2) { diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index c6e5758b7267..45172d170cf4 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -302,10 +302,6 @@ void print_v4l2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, struct v4l2_buffer *v4l2); void kref_put_mbuf(struct msm_vidc_buffer *mbuf); bool kref_get_mbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); -void msm_comm_store_filled_length(struct msm_vidc_list *data_list, - u32 index, u32 filled_length); -void msm_comm_fetch_filled_length(struct msm_vidc_list *data_list, - u32 index, u32 *filled_length); void msm_comm_store_input_tag(struct msm_vidc_list *data_list, u32 index, u32 itag, u32 itag2); int msm_comm_fetch_input_tag(struct msm_vidc_list *data_list, diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index f30ae5fb1c0f..73615c74a673 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -207,7 +207,6 @@ struct msm_vidc_buf_data { u32 index; u32 input_tag; u32 input_tag2; - u32 filled_length; }; struct msm_vidc_window_data { @@ -577,6 +576,7 @@ struct msm_vidc_inst { int (*buffer_size_calculators)(struct msm_vidc_inst *inst); bool all_intra; bool is_perf_eligible_session; + u32 max_filled_len; }; extern struct msm_vidc_drv *vidc_driver; From 17ed11c5eaa11cb7a40315e519816b58a2e765a0 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Fri, 23 Aug 2019 14:20:30 -0700 Subject: [PATCH 150/452] msm: vidc: Update CVP skip pattern logic Update CVP metadata skip logic to send a frame for CVP processing every time frame rate or operatimg rate changes dynamically. This helps in handling skipping of CVP metadata processing for a random number of frames whenever frame rate or operating rate changes dynamically, and avoid sending CVP metadata to video firmware for an unpredictable frame. Signed-off-by: Akshata Sahukar Change-Id: I049f0c0ade1700816203713cd82382c2a614f20a --- msm/vidc/msm_cvp_external.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index 5725062d96cf..8b1adc80f235 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -666,6 +666,9 @@ static int msm_cvp_prepare_extradata(struct msm_vidc_inst *inst, char *kvaddr = NULL; struct msm_vidc_extradata_header *e_hdr; bool input_extradata, found_end; + char *cvpframe = NULL; + u32 cvp_metadata_valid_flag = 0; + int nIsValid_offset = 232; if (!inst || !inst->cvp || !mbuf) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); @@ -753,6 +756,11 @@ static int msm_cvp_prepare_extradata(struct msm_vidc_inst *inst, DMA_BIDIRECTIONAL); memcpy(e_hdr->data, cvp->output_buffer.kvaddr, sizeof(struct msm_vidc_enc_cvp_metadata_payload)); + cvpframe = (char *) e_hdr->data; + cvp_metadata_valid_flag = *(u32*)(cvpframe + nIsValid_offset); + dprintk(VIDC_HIGH, + "CVP metadata nIsValid flag = %u frame: %u", + cvp_metadata_valid_flag, cvp->framecount); dma_buf_end_cpu_access(cvp->output_buffer.dbuf, DMA_BIDIRECTIONAL); } @@ -823,6 +831,7 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, const u32 fps_max = CVP_FRAME_RATE_MAX; u32 fps, operating_rate, skip_framecount; bool skipframe = false; + bool first_frame = false; if (!inst || !inst->cvp || !inst->cvp->arg || !mbuf) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); @@ -838,10 +847,14 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, cvp->fullres_buffer.offset = vb->planes[0].data_offset; cvp->fullres_buffer.dbuf = mbuf->smem[0].dma_buf; + if(!cvp->framecount) + first_frame = true; + /* handle framerate or operarating rate changes dynamically */ if (cvp->frame_rate != inst->clk_data.frame_rate || cvp->operating_rate != inst->clk_data.operating_rate) { /* update cvp parameters */ + cvp->framecount = 0; cvp->frame_rate = inst->clk_data.frame_rate; cvp->operating_rate = inst->clk_data.operating_rate; rc = msm_cvp_set_clocks_and_bus(inst); @@ -898,7 +911,7 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, frame->size = sizeof(struct msm_cvp_dme_frame_packet); frame->packet_type = HFI_CMD_SESSION_CVP_DME_FRAME; frame->session_id = cvp->session_id; - if (!cvp->framecount) + if (first_frame) frame->skip_mv_calc = 1; else frame->skip_mv_calc = 0; From 736bca1b484414bfff6a1b6147ce08d1564eca75 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Mon, 26 Aug 2019 16:03:16 -0700 Subject: [PATCH 151/452] msm: vidc: fix vp8 frame rate capabilities Corrected VP8 frame rate capabilities for encoder and decoder as per PRD.Added bframe ctrl capability for VP8.Moved LTR count null check. Signed-off-by: Darshana Patil Change-Id: I2111719e711d6bc67c2279d4c4fc6ef63215a5cb --- msm/vidc/msm_venc.c | 4 ++-- msm/vidc/msm_vidc_platform.c | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index f6887a0b48f5..59b7b3b2e078 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3884,6 +3884,8 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) } hdev = inst->core->device; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); + if (!ctrl->val) + return 0; codec = get_v4l2_codec(inst); if (!(codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264)) { @@ -3898,8 +3900,6 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) goto disable_ltr; } - if (!ctrl->val) - return 0; if (ctrl->val > inst->capability.cap[CAP_LTR_COUNT].max) { dprintk(VIDC_ERR, "%s: invalid ltr count %d, max %d\n", __func__, ctrl->val, diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index a1ea7062e77e..7d7715a8da4c 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -325,7 +325,9 @@ static struct msm_vidc_codec_capability kona_capabilities[] = { {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 64, 36864, 1, 8160}, /* ((4096 * 2304) / 256) * 120 */ {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 64, 4423680, 1, 244800}, - {CAP_FRAMERATE, ENC|DEC, VP8, 1, 120, 1, 30}, + {CAP_BFRAME, ENC, VP8, 0, 0, 1, 0}, + {CAP_FRAMERATE, ENC, VP8, 1, 60, 1, 30}, + {CAP_FRAMERATE, DEC, VP8, 1, 120, 1, 30}, {CAP_BITRATE, ENC, VP8, 1, 74000000, 1, 20000000}, {CAP_BITRATE, DEC, VP8, 1, 220000000, 1, 20000000}, From f9a35e6304ac28d820547d08399d316116900063 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Tue, 27 Aug 2019 20:59:02 +0800 Subject: [PATCH 152/452] msm: vidc: remove redundant freq calculations Remove freq list, which is unused in current dcvs design. Remove unused dcvs load, load_low, load_norm, load_high, as current dcvs design only use min_freq and dcvs_flags. Change-Id: Ifbf251a9506286f2f34eca6eeb1af79bd07c0f43 Signed-off-by: Qiwei Liu --- msm/vidc/msm_vidc.c | 5 -- msm/vidc/msm_vidc_clocks.c | 114 +++-------------------------------- msm/vidc/msm_vidc_clocks.h | 3 - msm/vidc/msm_vidc_common.c | 2 +- msm/vidc/msm_vidc_internal.h | 5 -- 5 files changed, 8 insertions(+), 121 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 8fc1a6d2a32f..1974251de698 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1567,7 +1567,6 @@ void *msm_vidc_open(int core_id, int session_type) mutex_init(&inst->flush_lock); INIT_MSM_VIDC_LIST(&inst->scratchbufs); - INIT_MSM_VIDC_LIST(&inst->freqs); INIT_MSM_VIDC_LIST(&inst->input_crs); INIT_MSM_VIDC_LIST(&inst->persistbufs); INIT_MSM_VIDC_LIST(&inst->pending_getpropq); @@ -1691,7 +1690,6 @@ void *msm_vidc_open(int core_id, int session_type) DEINIT_MSM_VIDC_LIST(&inst->cvpbufs); DEINIT_MSM_VIDC_LIST(&inst->registeredbufs); DEINIT_MSM_VIDC_LIST(&inst->eosbufs); - DEINIT_MSM_VIDC_LIST(&inst->freqs); DEINIT_MSM_VIDC_LIST(&inst->input_crs); DEINIT_MSM_VIDC_LIST(&inst->client_data); DEINIT_MSM_VIDC_LIST(&inst->etb_data); @@ -1748,8 +1746,6 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst) cancel_batch_work(inst); - msm_comm_free_freq_table(inst); - msm_comm_free_input_cr_table(inst); if (msm_comm_release_scratch_buffers(inst, false)) @@ -1828,7 +1824,6 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) DEINIT_MSM_VIDC_LIST(&inst->cvpbufs); DEINIT_MSM_VIDC_LIST(&inst->registeredbufs); DEINIT_MSM_VIDC_LIST(&inst->eosbufs); - DEINIT_MSM_VIDC_LIST(&inst->freqs); DEINIT_MSM_VIDC_LIST(&inst->input_crs); DEINIT_MSM_VIDC_LIST(&inst->client_data); DEINIT_MSM_VIDC_LIST(&inst->etb_data); diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 00684eab68c4..fc262a771ceb 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -48,15 +48,6 @@ struct msm_vidc_core_ops core_ops_iris2 = { .calc_bw = calc_bw_iris2, }; -static inline void msm_dcvs_print_dcvs_stats(struct clock_data *dcvs) -{ - dprintk(VIDC_PERF, - "DCVS: Loads %lld %lld %lld, Thresholds %d %d %d\n", - dcvs->load_low, dcvs->load_norm, dcvs->load_high, - dcvs->min_threshold, dcvs->nom_threshold, - dcvs->max_threshold); -} - static inline unsigned long get_ubwc_compression_ratio( struct ubwc_cr_stats_info_type ubwc_stats_info) { @@ -456,7 +447,7 @@ static int msm_dcvs_scale_clocks(struct msm_vidc_inst *inst, if (!inst->clk_data.dcvs_mode || inst->batch.enable) { dprintk(VIDC_LOW, "Skip DCVS (dcvs %d, batching %d)\n", inst->clk_data.dcvs_mode, inst->batch.enable); - inst->clk_data.load = inst->clk_data.load_norm; + inst->clk_data.dcvs_flags = 0; return 0; } @@ -493,70 +484,22 @@ static int msm_dcvs_scale_clocks(struct msm_vidc_inst *inst, if (dcvs->dcvs_window < DCVS_DEC_EXTRA_OUTPUT_BUFFERS || bufs_with_fw == dcvs->nom_threshold) { - dcvs->load = dcvs->load_norm; dcvs->dcvs_flags = 0; } else if (bufs_with_fw >= dcvs->max_threshold) { - dcvs->load = dcvs->load_high; dcvs->dcvs_flags |= MSM_VIDC_DCVS_INCR; } else if (bufs_with_fw < dcvs->min_threshold) { - dcvs->load = dcvs->load_low; dcvs->dcvs_flags |= MSM_VIDC_DCVS_DECR; } dprintk(VIDC_PERF, - "DCVS: %x: bufs_with_fw %d Th[%d %d %d] Flag %#x Load %llu\n", + "DCVS: %x: bufs_with_fw %d Th[%d %d %d] Flag %#x\n", hash32_ptr(inst->session), bufs_with_fw, dcvs->min_threshold, dcvs->nom_threshold, dcvs->max_threshold, - dcvs->dcvs_flags, dcvs->load); + dcvs->dcvs_flags); return rc; } -static void msm_vidc_update_freq_entry(struct msm_vidc_inst *inst, - unsigned long freq, u32 device_addr, bool is_turbo) -{ - struct vidc_freq_data *temp, *next; - bool found = false; - - mutex_lock(&inst->freqs.lock); - list_for_each_entry_safe(temp, next, &inst->freqs.list, list) { - if (temp->device_addr == device_addr) { - temp->freq = freq; - found = true; - break; - } - } - - if (!found) { - temp = kzalloc(sizeof(*temp), GFP_KERNEL); - if (!temp) { - dprintk(VIDC_ERR, "%s: malloc failure.\n", __func__); - goto exit; - } - temp->freq = freq; - temp->device_addr = device_addr; - list_add_tail(&temp->list, &inst->freqs.list); - } - temp->turbo = !!is_turbo; -exit: - mutex_unlock(&inst->freqs.lock); -} - -void msm_vidc_clear_freq_entry(struct msm_vidc_inst *inst, - u32 device_addr) -{ - struct vidc_freq_data *temp, *next; - - mutex_lock(&inst->freqs.lock); - list_for_each_entry_safe(temp, next, &inst->freqs.list, list) { - if (temp->device_addr == device_addr) - temp->freq = 0; - } - mutex_unlock(&inst->freqs.lock); - - inst->clk_data.buffer_counter++; -} - static unsigned long msm_vidc_max_freq(struct msm_vidc_core *core) { struct allowed_clock_rates_table *allowed_clks_tbl = NULL; @@ -568,19 +511,6 @@ static unsigned long msm_vidc_max_freq(struct msm_vidc_core *core) return freq; } -void msm_comm_free_freq_table(struct msm_vidc_inst *inst) -{ - struct vidc_freq_data *temp, *next; - - mutex_lock(&inst->freqs.lock); - list_for_each_entry_safe(temp, next, &inst->freqs.list, list) { - list_del(&temp->list); - kfree(temp); - } - INIT_LIST_HEAD(&inst->freqs.list); - mutex_unlock(&inst->freqs.lock); -} - void msm_comm_free_input_cr_table(struct msm_vidc_inst *inst) { struct vidc_input_cr_data *temp, *next; @@ -694,14 +624,6 @@ static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, if (i < 0) i = 0; - dcvs->load_norm = rate; - dcvs->load_low = i < (int) (core->resources.allowed_clks_tbl_size - 1) ? - allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm; - dcvs->load_high = i > 0 ? allowed_clks_tbl[i-1].clock_rate : - dcvs->load_norm; - - msm_dcvs_print_dcvs_stats(dcvs); - dprintk(VIDC_PERF, "%s Inst %pK : Filled Len = %d Freq = %llu\n", __func__, inst, filled_len, freq); @@ -790,16 +712,10 @@ static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst, if (i < 0) i = 0; - dcvs->load_norm = rate; - dcvs->load_low = i < (int) (core->resources.allowed_clks_tbl_size - 1) ? - allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm; - dcvs->load_high = i > 0 ? allowed_clks_tbl[i-1].clock_rate : - dcvs->load_norm; - dprintk(VIDC_PERF, - "%s: inst %pK: %x : filled len %d required freq %llu load_norm %llu\n", + "%s: inst %pK: %x : filled len %d required freq %llu\n", __func__, inst, hash32_ptr(inst->session), - filled_len, freq, dcvs->load_norm); + filled_len, freq); return (unsigned long) freq; } @@ -893,16 +809,10 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, if (i < 0) i = 0; - dcvs->load_norm = rate; - dcvs->load_low = i < (int) (core->resources.allowed_clks_tbl_size - 1) ? - allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm; - dcvs->load_high = i > 0 ? allowed_clks_tbl[i-1].clock_rate : - dcvs->load_norm; - dprintk(VIDC_PERF, - "%s: inst %pK: %x : filled len %d required freq %llu load_norm %llu\n", + "%s: inst %pK: %x : filled len %d required freq %llu\n", __func__, inst, hash32_ptr(inst->session), - filled_len, freq, dcvs->load_norm); + filled_len, freq); return (unsigned long) freq; } @@ -1059,8 +969,6 @@ int msm_comm_scale_clocks(struct msm_vidc_inst *inst) msm_dcvs_scale_clocks(inst, freq); } - msm_vidc_update_freq_entry(inst, freq, device_addr, is_turbo); - msm_vidc_set_clocks(inst->core); return 0; @@ -1211,16 +1119,8 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) if (i < 0) i = 0; - dcvs->load = dcvs->load_norm = rate; - dcvs->load_low = i < (core->resources.allowed_clks_tbl_size - 1) ? - allowed_clks_tbl[i+1].clock_rate : dcvs->load_norm; - dcvs->load_high = i > 0 ? - allowed_clks_tbl[i-1].clock_rate : dcvs->load_norm; - inst->clk_data.buffer_counter = 0; - msm_dcvs_print_dcvs_stats(dcvs); - rc = msm_comm_scale_clocks_and_bus(inst, 1); if (rc) diff --git a/msm/vidc/msm_vidc_clocks.h b/msm/vidc/msm_vidc_clocks.h index 956838e78c36..c9b463637e77 100644 --- a/msm/vidc/msm_vidc_clocks.h +++ b/msm/vidc/msm_vidc_clocks.h @@ -21,7 +21,6 @@ int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst); int msm_vidc_get_fps(struct msm_vidc_inst *inst); int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc); int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst); -void msm_comm_free_freq_table(struct msm_vidc_inst *inst); int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst); int msm_vidc_decide_work_mode_iris1(struct msm_vidc_inst *inst); int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst); @@ -29,8 +28,6 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst); int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst); int msm_vidc_decide_core_and_power_mode_iris2(struct msm_vidc_inst *inst); void msm_print_core_status(struct msm_vidc_core *core, u32 core_id); -void msm_vidc_clear_freq_entry(struct msm_vidc_inst *inst, - u32 device_addr); void msm_comm_free_input_cr_table(struct msm_vidc_inst *inst); void msm_comm_update_input_cr(struct msm_vidc_inst *inst, u32 index, u32 cr); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index cef7372396c6..4a3e6e56d341 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2485,7 +2485,7 @@ static void handle_ebd(enum hal_command_response cmd, void *data) vb->planes[1].bytesused = vb->planes[1].length; update_recon_stats(inst, &empty_buf_done->recon_stats); - msm_vidc_clear_freq_entry(inst, mbuf->smem[0].device_addr); + inst->clk_data.buffer_counter++; /* * dma cache operations need to be performed before dma_unmap * which is done inside msm_comm_put_vidc_buffer() diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 73615c74a673..822d9c392d67 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -393,10 +393,6 @@ enum dcvs_flags { struct clock_data { int buffer_counter; - u64 load; - u64 load_low; - u64 load_norm; - u64 load_high; int min_threshold; int nom_threshold; int max_threshold; @@ -518,7 +514,6 @@ struct msm_vidc_inst { enum instance_state state; struct msm_vidc_format fmts[MAX_PORT_NUM]; struct buf_queue bufq[MAX_PORT_NUM]; - struct msm_vidc_list freqs; struct msm_vidc_list input_crs; struct msm_vidc_list scratchbufs; struct msm_vidc_list persistbufs; From 72f29165b3695016032bf0577129227c74f59873 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Wed, 28 Aug 2019 10:59:50 -0700 Subject: [PATCH 153/452] msm: vidc: Fix to allocate right scratch1 buffer size Avoid allocating smaller encoder scratch1 buffer for Video firmware when frame height is greater than frame width. Change-Id: I663da164b3cbb945d7da2d6ab40199d8ef14d979 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_vidc_buffer_calculations.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 3250e90bda5b..5fa0a05415e1 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1680,7 +1680,7 @@ static inline u32 calculate_enc_scratch1_size(struct msm_vidc_inst *inst, override_buffer_size = ALIGN(override_buffer_size, VENUS_DMA_ALIGNMENT) * 2; ir_buffer_size = (((frame_num_lcu << 1) + 7) & (~7)) * 3; - vpss_line_buf = ((((width_coded + 3) >> 2) << 5) + 256) * 16; + vpss_line_buf = ((((max(width_coded, height_coded) + 3) >> 2) << 5) + 256) * 16; topline_bufsize_fe_1stg_sao = (16 * (width_coded >> 5)); topline_bufsize_fe_1stg_sao = ALIGN(topline_bufsize_fe_1stg_sao, VENUS_DMA_ALIGNMENT); From cb10315c3cc5f4eab598a7c9e750e10ff6357db6 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Mon, 19 Aug 2019 16:10:13 +0530 Subject: [PATCH 154/452] msm-vidc: add image encode capabilities for lito add image encode capabilities for lito. Change-Id: Ic4fd706fc54c9e231cf6872e5478a0972ec78134 --- msm/vidc/msm_vidc_platform.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index a1ea7062e77e..56df8a2cda01 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -220,6 +220,12 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 36, 8160, 1, 8160}, /* (1920 * 1080) / 256 */ {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, + + /* Image specific */ + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 1, 8192}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192}, }; static struct msm_vidc_codec_capability lito_capabilities_v1[] = { @@ -285,6 +291,12 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 36, 8160, 1, 8160}, /* (1920 * 1080) / 256 */ {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, + + /* Image specific */ + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 1, 8192}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192}, }; static struct msm_vidc_codec_capability kona_capabilities[] = { From c705bf58efaefd7e9dddf4b4e7973f86c58d75e6 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 26 Aug 2019 20:28:19 +0530 Subject: [PATCH 155/452] msm: vidc: print session_id in logs Print session_id details in all possible call flow paths. Change-Id: I0c583dc99d4ebee7fbcb4e36d917ba9120fa670e Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_ar50.c | 4 +- msm/vidc/hfi_common.c | 1283 ++++++++++---------- msm/vidc/hfi_common.h | 41 +- msm/vidc/hfi_iris1.c | 40 +- msm/vidc/hfi_iris2.c | 178 ++- msm/vidc/hfi_packetization.c | 225 ++-- msm/vidc/hfi_packetization.h | 39 +- msm/vidc/hfi_response_handler.c | 295 ++--- msm/vidc/msm_cvp_external.c | 222 ++-- msm/vidc/msm_cvp_external.h | 10 +- msm/vidc/msm_cvp_internal.c | 136 +-- msm/vidc/msm_smem.c | 112 +- msm/vidc/msm_v4l2_private.c | 14 +- msm/vidc/msm_v4l2_vidc.c | 67 +- msm/vidc/msm_vdec.c | 163 +-- msm/vidc/msm_venc.c | 618 +++++----- msm/vidc/msm_vidc.c | 392 +++--- msm/vidc/msm_vidc_buffer_calculations.c | 47 +- msm/vidc/msm_vidc_bus.h | 7 +- msm/vidc/msm_vidc_bus_iris1.c | 16 +- msm/vidc/msm_vidc_bus_iris2.c | 10 +- msm/vidc/msm_vidc_clocks.c | 214 ++-- msm/vidc/msm_vidc_clocks.h | 4 +- msm/vidc/msm_vidc_common.c | 1472 +++++++++++------------ msm/vidc/msm_vidc_common.h | 44 +- msm/vidc/msm_vidc_debug.c | 63 +- msm/vidc/msm_vidc_debug.h | 50 +- msm/vidc/msm_vidc_internal.h | 15 +- msm/vidc/msm_vidc_platform.c | 11 +- msm/vidc/msm_vidc_res_parse.c | 248 ++-- msm/vidc/vidc_hfi.c | 10 +- msm/vidc/vidc_hfi.h | 61 +- msm/vidc/vidc_hfi_api.h | 21 +- msm/vidc/vidc_hfi_helper.h | 22 +- 34 files changed, 2885 insertions(+), 3269 deletions(-) diff --git a/msm/vidc/hfi_ar50.c b/msm/vidc/hfi_ar50.c index a5428dbfe246..55f3f5ee9247 100644 --- a/msm/vidc/hfi_ar50.c +++ b/msm/vidc/hfi_ar50.c @@ -6,8 +6,8 @@ #include "hfi_common.h" #include "hfi_io_common.h" -void __interrupt_init_ar50(struct venus_hfi_device *device) +void __interrupt_init_ar50(struct venus_hfi_device *device, u32 sid) { __write_register(device, WRAPPER_INTR_MASK, - WRAPPER_INTR_MASK_A2HVCODEC_BMSK); + WRAPPER_INTR_MASK_A2HVCODEC_BMSK, sid); } diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 20d31a0f5586..162db79feff3 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -84,37 +84,40 @@ const int max_packets = 1000; static void venus_hfi_pm_handler(struct work_struct *work); static DECLARE_DELAYED_WORK(venus_hfi_pm_work, venus_hfi_pm_handler); -static inline int __resume(struct venus_hfi_device *device); +static inline int __resume(struct venus_hfi_device *device, u32 sid); static inline int __suspend(struct venus_hfi_device *device); -static int __enable_regulators(struct venus_hfi_device *device); -static inline int __prepare_enable_clks(struct venus_hfi_device *device); +static int __enable_regulators(struct venus_hfi_device *device, u32 sid); +static inline int __prepare_enable_clks( + struct venus_hfi_device *device, u32 sid); static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet); static int __initialize_packetization(struct venus_hfi_device *device); static struct hal_session *__get_session(struct venus_hfi_device *device, - u32 session_id); + u32 sid); static bool __is_session_valid(struct venus_hfi_device *device, struct hal_session *session, const char *func); -static int __set_clocks(struct venus_hfi_device *device, u32 freq); +static int __set_clocks(struct venus_hfi_device *device, u32 freq, u32 sid); static int __iface_cmdq_write(struct venus_hfi_device *device, - void *pkt); + void *pkt, u32 sid); static int __load_fw(struct venus_hfi_device *device); static void __unload_fw(struct venus_hfi_device *device); -static int __tzbsp_set_video_state(enum tzbsp_video_state state); -static int __enable_subcaches(struct venus_hfi_device *device); -static int __set_subcaches(struct venus_hfi_device *device); -static int __release_subcaches(struct venus_hfi_device *device); -static int __disable_subcaches(struct venus_hfi_device *device); +static int __tzbsp_set_video_state(enum tzbsp_video_state state, u32 sid); +static int __enable_subcaches(struct venus_hfi_device *device, u32 sid); +static int __set_subcaches(struct venus_hfi_device *device, u32 sid); +static int __release_subcaches(struct venus_hfi_device *device, u32 sid); +static int __disable_subcaches(struct venus_hfi_device *device, u32 sid); static int __power_collapse(struct venus_hfi_device *device, bool force); static int venus_hfi_noc_error_info(void *dev); static int __set_ubwc_config(struct venus_hfi_device *device); static void __power_off_common(struct venus_hfi_device *device); static int __prepare_pc_common(struct venus_hfi_device *device); -static void __raise_interrupt_common(struct venus_hfi_device *device); +static void __raise_interrupt_common(struct venus_hfi_device *device, u32 sid); static bool __watchdog_common(u32 intr_status); static void __noc_error_info_common(struct venus_hfi_device *device); static void __core_clear_interrupt_common(struct venus_hfi_device *device); -static inline int __boot_firmware_common(struct venus_hfi_device *device); -static void __setup_ucregion_memory_map_common(struct venus_hfi_device *device); +static inline int __boot_firmware_common( + struct venus_hfi_device *device, u32 sid); +static void __setup_ucregion_memory_map_common( + struct venus_hfi_device *device, u32 sid); struct venus_hfi_vpu_ops vpu4_ops = { .interrupt_init = __interrupt_init_ar50, @@ -184,7 +187,7 @@ static inline bool is_sys_cache_present(struct venus_hfi_device *device) return device->res->sys_cache_present; } -static void __dump_packet(u8 *packet, enum vidc_msg_prio log_level) +static void __dump_packet(u8 *packet, u32 sid) { u32 c = 0, packet_size = *(u32 *)packet; const int row_size = 32; @@ -199,7 +202,7 @@ static void __dump_packet(u8 *packet, enum vidc_msg_prio log_level) packet_size % row_size : row_size; hex_dump_to_buffer(packet + c * row_size, bytes_to_read, row_size, 4, row, sizeof(row), false); - dprintk(log_level, "%s\n", row); + s_vpr_t(sid, "%s\n", row); } } @@ -210,21 +213,20 @@ static void __sim_modify_cmd_packet(u8 *packet, struct venus_hfi_device *device) u8 i; phys_addr_t fw_bias = 0; - if (!device || !packet) { - dprintk(VIDC_ERR, "Invalid Param\n"); + sys_init = (struct hfi_cmd_sys_session_init_packet *)packet; + if (!device || !sys_init) { + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, device, sys_init); return; } else if (!device->hal_data->firmware_base || is_iommu_present(device->res)) { return; } - fw_bias = device->hal_data->firmware_base; - sys_init = (struct hfi_cmd_sys_session_init_packet *)packet; - session = __get_session(device, sys_init->session_id); + session = __get_session(device, sys_init->sid); if (!session) { - dprintk(VIDC_ERR, "%s :Invalid session id: %x\n", - __func__, sys_init->session_id); + d_vpr_e("%s: Invalid session id\n", __func__); return; } @@ -312,28 +314,28 @@ static int __dsp_send_hfi_queue(struct venus_hfi_device *device) return 0; if (!device->dsp_iface_q_table.mem_data.dma_handle) { - dprintk(VIDC_ERR, "%s: invalid dsm_handle\n", __func__); + d_vpr_e("%s: invalid dsm_handle\n", __func__); return -EINVAL; } if (device->dsp_flags & DSP_INIT) { - dprintk(VIDC_HIGH, "%s: dsp already inited\n", __func__); + d_vpr_h("%s: dsp already inited\n", __func__); return 0; } - dprintk(VIDC_HIGH, "%s: hfi queue %#llx size %d\n", + d_vpr_h("%s: hfi queue %#llx size %d\n", __func__, device->dsp_iface_q_table.mem_data.dma_handle, device->dsp_iface_q_table.mem_data.size); rc = fastcvpd_video_send_cmd_hfi_queue( (phys_addr_t *)device->dsp_iface_q_table.mem_data.dma_handle, device->dsp_iface_q_table.mem_data.size); if (rc) { - dprintk(VIDC_ERR, "%s: dsp init failed\n", __func__); + d_vpr_e("%s: dsp init failed\n", __func__); return rc; } device->dsp_flags |= DSP_INIT; - dprintk(VIDC_HIGH, "%s: dsp inited\n", __func__); + d_vpr_h("%s: dsp inited\n", __func__); return rc; } @@ -358,24 +360,24 @@ static int __dsp_suspend(struct venus_hfi_device *device, bool force, u32 flags) if (temp->domain == HAL_VIDEO_DOMAIN_CVP) { /* don't suspend if cvp session is not paused */ if (!(temp->flags & SESSION_PAUSE)) { - dprintk(VIDC_HIGH, - "%s: cvp session %x not paused\n", - __func__, hash32_ptr(temp)); + s_vpr_h(temp->sid, + "%s: cvp session not paused\n", + __func__); return -EBUSY; } } } - dprintk(VIDC_HIGH, "%s: suspend dsp\n", __func__); + d_vpr_h("%s: suspend dsp\n", __func__); rc = fastcvpd_video_suspend(flags); if (rc) { - dprintk(VIDC_ERR, "%s: dsp suspend failed with error %d\n", + d_vpr_e("%s: dsp suspend failed with error %d\n", __func__, rc); return -EINVAL; } device->dsp_flags |= DSP_SUSPEND; - dprintk(VIDC_HIGH, "%s: dsp suspended\n", __func__); + d_vpr_h("%s: dsp suspended\n", __func__); return 0; } @@ -387,21 +389,20 @@ static int __dsp_resume(struct venus_hfi_device *device, u32 flags) return 0; if (!(device->dsp_flags & DSP_SUSPEND)) { - dprintk(VIDC_HIGH, "%s: dsp not suspended\n", __func__); + d_vpr_h("%s: dsp not suspended\n", __func__); return 0; } - dprintk(VIDC_HIGH, "%s: resume dsp\n", __func__); + d_vpr_h("%s: resume dsp\n", __func__); rc = fastcvpd_video_resume(flags); if (rc) { - dprintk(VIDC_ERR, - "%s: dsp resume failed with error %d\n", + d_vpr_e("%s: dsp resume failed with error %d\n", __func__, rc); return rc; } device->dsp_flags &= ~DSP_SUSPEND; - dprintk(VIDC_HIGH, "%s: dsp resumed\n", __func__); + d_vpr_h("%s: dsp resumed\n", __func__); return rc; } @@ -413,21 +414,20 @@ static int __dsp_shutdown(struct venus_hfi_device *device, u32 flags) return 0; if (!(device->dsp_flags & DSP_INIT)) { - dprintk(VIDC_HIGH, "%s: dsp not inited\n", __func__); + d_vpr_h("%s: dsp not inited\n", __func__); return 0; } - dprintk(VIDC_HIGH, "%s: shutdown dsp\n", __func__); + d_vpr_h("%s: shutdown dsp\n", __func__); rc = fastcvpd_video_shutdown(flags); if (rc) { - dprintk(VIDC_ERR, - "%s: dsp shutdown failed with error %d\n", + d_vpr_e("%s: dsp shutdown failed with error %d\n", __func__, rc); WARN_ON(1); } device->dsp_flags &= ~DSP_INIT; - dprintk(VIDC_HIGH, "%s: dsp shutdown successful\n", __func__); + d_vpr_h("%s: dsp shutdown successful\n", __func__); return rc; } @@ -444,8 +444,7 @@ static int __session_pause(struct venus_hfi_device *device, return 0; session->flags |= SESSION_PAUSE; - dprintk(VIDC_HIGH, "%s: cvp session %x paused\n", __func__, - hash32_ptr(session)); + s_vpr_h(session->sid, "%s: cvp session paused\n", __func__); return rc; } @@ -463,17 +462,16 @@ static int __session_resume(struct venus_hfi_device *device, return 0; session->flags &= ~SESSION_PAUSE; - dprintk(VIDC_HIGH, "%s: cvp session %x resumed\n", __func__, - hash32_ptr(session)); + s_vpr_h(session->sid, "%s: cvp session resumed\n", __func__); - rc = __resume(device); + rc = __resume(device, session->sid); if (rc) { - dprintk(VIDC_ERR, "%s: resume failed\n", __func__); + s_vpr_e(session->sid, "%s: resume failed\n", __func__); goto exit; } if (device->dsp_flags & DSP_SUSPEND) { - dprintk(VIDC_ERR, "%s: dsp not resumed\n", __func__); + s_vpr_e(session->sid, "%s: dsp not resumed\n", __func__); rc = -EINVAL; goto exit; } @@ -509,7 +507,7 @@ static int venus_hfi_session_resume(void *sess) } static int __acquire_regulator(struct regulator_info *rinfo, - struct venus_hfi_device *device) + struct venus_hfi_device *device, u32 sid) { int rc = 0; @@ -522,20 +520,19 @@ static int __acquire_regulator(struct regulator_info *rinfo, * about it. We can't disable the regulator w/o * getting it back under s/w control */ - dprintk(VIDC_ERR, + s_vpr_e(sid, "Failed to acquire regulator control: %s\n", - rinfo->name); + rinfo->name); } else { - dprintk(VIDC_HIGH, - "Acquire regulator control from HW: %s\n", + s_vpr_h(sid, "Acquire regulator control from HW: %s\n", rinfo->name); } } if (!regulator_is_enabled(rinfo->regulator)) { - dprintk(VIDC_ERR, "Regulator is not enabled %s\n", + s_vpr_e(sid, "Regulator is not enabled %s\n", rinfo->name); msm_vidc_res_handle_fatal_hw_error(device->res, true); } @@ -543,7 +540,7 @@ static int __acquire_regulator(struct regulator_info *rinfo, return rc; } -static int __hand_off_regulator(struct regulator_info *rinfo) +static int __hand_off_regulator(struct regulator_info *rinfo, u32 sid) { int rc = 0; @@ -551,12 +548,11 @@ static int __hand_off_regulator(struct regulator_info *rinfo) rc = regulator_set_mode(rinfo->regulator, REGULATOR_MODE_FAST); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(sid, "Failed to hand off regulator control: %s\n", - rinfo->name); + rinfo->name); } else { - dprintk(VIDC_HIGH, - "Hand off regulator control to HW: %s\n", + s_vpr_h(sid, "Hand off regulator control to HW: %s\n", rinfo->name); } } @@ -564,13 +560,13 @@ static int __hand_off_regulator(struct regulator_info *rinfo) return rc; } -static int __hand_off_regulators(struct venus_hfi_device *device) +static int __hand_off_regulators(struct venus_hfi_device *device, u32 sid) { struct regulator_info *rinfo; int rc = 0, c = 0; venus_hfi_for_each_regulator(device, rinfo) { - rc = __hand_off_regulator(rinfo); + rc = __hand_off_regulator(rinfo, sid); /* * If one regulator hand off failed, driver should take * the control for other regulators back. @@ -583,13 +579,13 @@ static int __hand_off_regulators(struct venus_hfi_device *device) return rc; err_reg_handoff_failed: venus_hfi_for_each_regulator_reverse_continue(device, rinfo, c) - __acquire_regulator(rinfo, device); + __acquire_regulator(rinfo, device, sid); return rc; } static int __write_queue(struct vidc_iface_q_info *qinfo, u8 *packet, - bool *rx_req_is_set) + bool *rx_req_is_set, u32 sid) { struct hfi_queue_header *queue; u32 packet_size_in_words, new_write_idx; @@ -597,28 +593,29 @@ static int __write_queue(struct vidc_iface_q_info *qinfo, u8 *packet, u32 *write_ptr; if (!qinfo || !packet) { - dprintk(VIDC_ERR, "Invalid Params\n"); + s_vpr_e(sid, "%s: invalid params %pK %pK\n", + __func__, qinfo, packet); return -EINVAL; } else if (!qinfo->q_array.align_virtual_addr) { - dprintk(VIDC_ERR, "Queues have already been freed\n"); + s_vpr_e(sid, "Queues have already been freed\n"); return -EINVAL; } queue = (struct hfi_queue_header *) qinfo->q_hdr; if (!queue) { - dprintk(VIDC_ERR, "queue not present\n"); + s_vpr_e(sid, "queue not present\n"); return -ENOENT; } if (msm_vidc_debug & VIDC_PKT) { - dprintk(VIDC_PKT, "%s: %pK\n", __func__, qinfo); - __dump_packet(packet, VIDC_PKT); + s_vpr_t(sid, "%s: %pK\n", __func__, qinfo); + __dump_packet(packet, sid); } packet_size_in_words = (*(u32 *)packet) >> 2; if (!packet_size_in_words || packet_size_in_words > qinfo->q_array.mem_size>>2) { - dprintk(VIDC_ERR, "Invalid packet size\n"); + s_vpr_e(sid, "Invalid packet size\n"); return -ENODATA; } @@ -630,7 +627,7 @@ static int __write_queue(struct vidc_iface_q_info *qinfo, u8 *packet, (read_idx - write_idx); if (empty_space <= packet_size_in_words) { queue->qhdr_tx_req = 1; - dprintk(VIDC_ERR, "Insufficient size (%d) to write (%d)\n", + s_vpr_e(sid, "Insufficient size (%d) to write (%d)\n", empty_space, packet_size_in_words); return -ENOTEMPTY; } @@ -643,7 +640,7 @@ static int __write_queue(struct vidc_iface_q_info *qinfo, u8 *packet, if (write_ptr < (u32 *)qinfo->q_array.align_virtual_addr || write_ptr > (u32 *)(qinfo->q_array.align_virtual_addr + qinfo->q_array.mem_size)) { - dprintk(VIDC_ERR, "Invalid write index"); + s_vpr_e(sid, "Invalid write index"); return -ENODATA; } @@ -682,7 +679,8 @@ static void __hal_sim_modify_msg_packet(u8 *packet, phys_addr_t fw_bias = 0; if (!device || !packet) { - dprintk(VIDC_ERR, "Invalid Param\n"); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, device, packet); return; } else if (!device->hal_data->firmware_base || is_iommu_present(device->res)) { @@ -691,10 +689,10 @@ static void __hal_sim_modify_msg_packet(u8 *packet, fw_bias = device->hal_data->firmware_base; init_done = (struct hfi_msg_sys_session_init_done_packet *)packet; - session = __get_session(device, init_done->session_id); + session = __get_session(device, init_done->sid); if (!session) { - dprintk(VIDC_ERR, "%s: Invalid session id: %x\n", - __func__, init_done->session_id); + d_vpr_e("%s: Invalid session id: %x\n", + __func__, init_done->sid); return; } @@ -737,12 +735,14 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, u32 receive_request = 0; u32 read_idx, write_idx; int rc = 0; + u32 sid; if (!qinfo || !packet || !pb_tx_req_is_set) { - dprintk(VIDC_ERR, "Invalid Params\n"); + d_vpr_e("%s: invalid params %pK %pK %pK\n", + __func__, qinfo, packet, pb_tx_req_is_set); return -EINVAL; } else if (!qinfo->q_array.align_virtual_addr) { - dprintk(VIDC_ERR, "Queues have already been freed\n"); + d_vpr_e("Queues have already been freed\n"); return -EINVAL; } @@ -754,7 +754,7 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, queue = (struct hfi_queue_header *) qinfo->q_hdr; if (!queue) { - dprintk(VIDC_ERR, "Queue memory is not allocated\n"); + d_vpr_e("Queue memory is not allocated\n"); return -ENOMEM; } @@ -780,7 +780,7 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, */ mb(); *pb_tx_req_is_set = 0; - dprintk(VIDC_LOW, + d_vpr_l( "%s queue is empty, rx_req = %u, tx_req = %u, read_idx = %u\n", receive_request ? "message" : "debug", queue->qhdr_rx_req, queue->qhdr_tx_req, @@ -793,13 +793,13 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, if (read_ptr < (u32 *)qinfo->q_array.align_virtual_addr || read_ptr > (u32 *)(qinfo->q_array.align_virtual_addr + qinfo->q_array.mem_size - sizeof(*read_ptr))) { - dprintk(VIDC_ERR, "Invalid read index\n"); + d_vpr_e("Invalid read index\n"); return -ENODATA; } packet_size_in_words = (*read_ptr) >> 2; if (!packet_size_in_words) { - dprintk(VIDC_ERR, "Zero packet size\n"); + d_vpr_e("Zero packet size\n"); return -ENODATA; } @@ -819,10 +819,9 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, new_read_idx << 2); } } else { - dprintk(VIDC_ERR, - "BAD packet received, read_idx: %#x, pkt_size: %d\n", + d_vpr_e("BAD packet received, read_idx: %#x, pkt_size: %d\n", read_idx, packet_size_in_words << 2); - dprintk(VIDC_ERR, "Dropping this packet\n"); + d_vpr_e("Dropping this packet\n"); new_read_idx = write_idx; rc = -ENODATA; } @@ -843,8 +842,9 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, if ((msm_vidc_debug & VIDC_PKT) && !(queue->qhdr_type & HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q)) { - dprintk(VIDC_PKT, "%s: %pK\n", __func__, qinfo); - __dump_packet(packet, VIDC_PKT); + sid = *((u32 *)packet + 2); + s_vpr_t(sid, "%s: %pK\n", __func__, qinfo); + __dump_packet(packet, sid); } return rc; @@ -858,21 +858,22 @@ static int __smem_alloc(struct venus_hfi_device *dev, int rc = 0; if (!dev || !mem || !size) { - dprintk(VIDC_ERR, "Invalid Params\n"); + d_vpr_e("%s: invalid params %pK %pK %pK\n", + __func__, dev, mem, size); return -EINVAL; } - dprintk(VIDC_HIGH, "start to alloc size: %d, flags: %d\n", size, flags); + d_vpr_h("start to alloc size: %d, flags: %d\n", size, flags); rc = msm_smem_alloc( size, align, flags, usage, 1, (void *)dev->res, - MSM_VIDC_UNKNOWN, alloc); + MSM_VIDC_UNKNOWN, alloc, DEFAULT_SID); if (rc) { - dprintk(VIDC_ERR, "Alloc failed\n"); + d_vpr_e("%s: alloc failed\n", __func__); rc = -ENOMEM; goto fail_smem_alloc; } - dprintk(VIDC_HIGH, "%s: ptr = %pK, size = %d\n", __func__, + d_vpr_h("%s: ptr = %pK, size = %d\n", __func__, alloc->kvaddr, size); mem->mem_size = alloc->size; @@ -887,35 +888,35 @@ static int __smem_alloc(struct venus_hfi_device *dev, static void __smem_free(struct venus_hfi_device *dev, struct msm_smem *mem) { if (!dev || !mem) { - dprintk(VIDC_ERR, "invalid param %pK %pK\n", dev, mem); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, dev, mem); return; } - msm_smem_free(mem); + msm_smem_free(mem, DEFAULT_SID); } void __write_register(struct venus_hfi_device *device, - u32 reg, u32 value) + u32 reg, u32 value, u32 sid) { u32 hwiosymaddr = reg; u8 *base_addr; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %pK\n", device); + s_vpr_e(sid, "%s: invalid params\n", __func__); return; } __strict_check(device); if (!device->power_enabled) { - dprintk(VIDC_ERR, - "HFI Write register failed : Power is OFF\n"); + s_vpr_e(sid, "HFI Write register failed : Power is OFF\n"); msm_vidc_res_handle_fatal_hw_error(device->res, true); return; } base_addr = device->hal_data->register_base; - dprintk(VIDC_LOW, "Base addr: %pK, writing to: %#x, Value: %#x...\n", + s_vpr_l(sid, "Base addr: %pK, writing to: %#x, Value: %#x...\n", base_addr, hwiosymaddr, value); base_addr += hwiosymaddr; writel_relaxed(value, base_addr); @@ -926,21 +927,20 @@ void __write_register(struct venus_hfi_device *device, wmb(); } -int __read_register(struct venus_hfi_device *device, u32 reg) +int __read_register(struct venus_hfi_device *device, u32 reg, u32 sid) { int rc = 0; u8 *base_addr; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %pK\n", device); + s_vpr_e(sid, "%s: invalid params\n", __func__); return -EINVAL; } __strict_check(device); if (!device->power_enabled) { - dprintk(VIDC_ERR, - "HFI Read register failed : Power is OFF\n"); + s_vpr_e(sid, "HFI Read register failed : Power is OFF\n"); msm_vidc_res_handle_fatal_hw_error(device->res, true); return -EINVAL; } @@ -953,47 +953,47 @@ int __read_register(struct venus_hfi_device *device, u32 reg) * register. */ rmb(); - dprintk(VIDC_LOW, "Base addr: %pK, read from: %#x, value: %#x...\n", + s_vpr_l(sid, "Base addr: %pK, read from: %#x, value: %#x...\n", base_addr, reg, rc); return rc; } -static void __set_registers(struct venus_hfi_device *device) +static void __set_registers(struct venus_hfi_device *device, u32 sid) { struct reg_set *reg_set; int i; if (!device->res) { - dprintk(VIDC_ERR, - "device resources null, cannot set registers\n"); + s_vpr_e(sid, "device resources null, cannot set registers\n"); return; } reg_set = &device->res->reg_set; for (i = 0; i < reg_set->count; i++) { __write_register(device, reg_set->reg_tbl[i].reg, - reg_set->reg_tbl[i].value); + reg_set->reg_tbl[i].value, sid); } } -static int __vote_bandwidth(struct bus_info *bus, unsigned long bw_kbps) +static int __vote_bandwidth(struct bus_info *bus, + unsigned long bw_kbps, u32 sid) { int rc = 0; uint64_t ab = 0; /* Bus Driver expects values in Bps */ ab = bw_kbps * 1000; - dprintk(VIDC_PERF, "Voting bus %s to ab %llu bps\n", bus->name, ab); + s_vpr_p(sid, "Voting bus %s to ab %llu bps\n", bus->name, ab); rc = msm_bus_scale_update_bw(bus->client, ab, 0); if (rc) - dprintk(VIDC_ERR, "Failed voting bus %s to ab %llu, rc=%d\n", + s_vpr_e(sid, "Failed voting bus %s to ab %llu, rc=%d\n", bus->name, ab, rc); return rc; } -int __unvote_buses(struct venus_hfi_device *device) +int __unvote_buses(struct venus_hfi_device *device, u32 sid) { int rc = 0; struct bus_info *bus = NULL; @@ -1001,7 +1001,7 @@ int __unvote_buses(struct venus_hfi_device *device) device->bus_vote = DEFAULT_BUS_VOTE; venus_hfi_for_each_bus(device, bus) { - rc = __vote_bandwidth(bus, 0); + rc = __vote_bandwidth(bus, 0, sid); if (rc) goto err_unknown_device; } @@ -1011,7 +1011,7 @@ int __unvote_buses(struct venus_hfi_device *device) } static int __vote_buses(struct venus_hfi_device *device, - unsigned long bw_ddr, unsigned long bw_llcc) + unsigned long bw_ddr, unsigned long bw_llcc, u32 sid) { int rc = 0; struct bus_info *bus = NULL; @@ -1039,20 +1039,19 @@ static int __vote_buses(struct venus_hfi_device *device, bus->range[0], bus->range[1]); if (TRIVIAL_BW_CHANGE(bw_kbps, bw_prev) && bw_prev) { - dprintk(VIDC_PERF, - "Skip voting bus %s to %llu bps", + s_vpr_p(sid, "Skip voting bus %s to %llu bps", bus->name, bw_kbps * 1000); continue; } - rc = __vote_bandwidth(bus, bw_kbps); + rc = __vote_bandwidth(bus, bw_kbps, sid); if (type == DDR) device->bus_vote.total_bw_ddr = bw_kbps; else if (type == LLCC) device->bus_vote.total_bw_llcc = bw_kbps; } else { - dprintk(VIDC_ERR, "No BUS to Vote\n"); + s_vpr_e(sid, "No BUS to Vote\n"); } } @@ -1060,7 +1059,7 @@ static int __vote_buses(struct venus_hfi_device *device, } static int venus_hfi_vote_buses(void *dev, unsigned long bw_ddr, - unsigned long bw_llcc) + unsigned long bw_llcc, u32 sid) { int rc = 0; struct venus_hfi_device *device = dev; @@ -1069,7 +1068,7 @@ static int venus_hfi_vote_buses(void *dev, unsigned long bw_ddr, return -EINVAL; mutex_lock(&device->lock); - rc = __vote_buses(device, bw_ddr, bw_llcc); + rc = __vote_buses(device, bw_ddr, bw_llcc, sid); mutex_unlock(&device->lock); return rc; @@ -1082,7 +1081,8 @@ static int __core_set_resource(struct venus_hfi_device *device, int rc = 0; if (!device || !resource_hdr || !resource_value) { - dprintk(VIDC_ERR, "set_res: Invalid Params\n"); + d_vpr_e("%s: invalid params %pK %pK %pK\n", __func__, + device, resource_hdr, resource_value); return -EINVAL; } @@ -1091,11 +1091,11 @@ static int __core_set_resource(struct venus_hfi_device *device, rc = call_hfi_pkt_op(device, sys_set_resource, pkt, resource_hdr, resource_value); if (rc) { - dprintk(VIDC_ERR, "set_res: failed to create packet\n"); + d_vpr_e("set_res: failed to create packet\n"); goto err_create_pkt; } - rc = __iface_cmdq_write(device, pkt); + rc = __iface_cmdq_write(device, pkt, DEFAULT_SID); if (rc) rc = -ENOTEMPTY; @@ -1111,7 +1111,8 @@ static int __core_release_resource(struct venus_hfi_device *device, int rc = 0; if (!device || !resource_hdr) { - dprintk(VIDC_ERR, "release_res: Invalid Params\n"); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, device, resource_hdr); return -EINVAL; } @@ -1121,11 +1122,11 @@ static int __core_release_resource(struct venus_hfi_device *device, pkt, resource_hdr); if (rc) { - dprintk(VIDC_ERR, "release_res: failed to create packet\n"); + d_vpr_e("release_res: failed to create packet\n"); goto err_create_pkt; } - rc = __iface_cmdq_write(device, pkt); + rc = __iface_cmdq_write(device, pkt, DEFAULT_SID); if (rc) rc = -ENOTEMPTY; @@ -1133,7 +1134,7 @@ static int __core_release_resource(struct venus_hfi_device *device, return rc; } -static int __tzbsp_set_video_state(enum tzbsp_video_state state) +static int __tzbsp_set_video_state(enum tzbsp_video_state state, u32 sid) { struct tzbsp_video_set_state_req cmd = {0}; int tzbsp_rsp = 0; @@ -1149,22 +1150,22 @@ static int __tzbsp_set_video_state(enum tzbsp_video_state state) tzbsp_rsp = desc.ret[0]; if (rc) { - dprintk(VIDC_ERR, "Failed scm_call %d\n", rc); + s_vpr_e(sid, "Failed scm_call %d\n", rc); return rc; } - dprintk(VIDC_LOW, "Set state %d, resp %d\n", state, tzbsp_rsp); + s_vpr_l(sid, "Set state %d, resp %d\n", state, tzbsp_rsp); if (tzbsp_rsp) { - dprintk(VIDC_ERR, - "Failed to set video core state to suspend: %d\n", - tzbsp_rsp); + s_vpr_e(sid, "Failed to set video core state to suspend: %d\n", + tzbsp_rsp); return -EINVAL; } return 0; } -static inline int __boot_firmware_common(struct venus_hfi_device *device) +static inline int __boot_firmware_common( + struct venus_hfi_device *device, u32 sid) { int rc = 0; u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 1000; @@ -1173,11 +1174,11 @@ static inline int __boot_firmware_common(struct venus_hfi_device *device) if (device->res->cvp_internal) ctrl_init_val |= BIT(1); - __write_register(device, CTRL_INIT, ctrl_init_val); + __write_register(device, CTRL_INIT, ctrl_init_val, sid); while (!ctrl_status && count < max_tries) { - ctrl_status = __read_register(device, CTRL_STATUS); + ctrl_status = __read_register(device, CTRL_STATUS, sid); if ((ctrl_status & CTRL_ERROR_STATUS__M) == 0x4) { - dprintk(VIDC_ERR, "invalid setting for UC_REGION\n"); + s_vpr_e(sid, "invalid setting for UC_REGION\n"); break; } @@ -1186,7 +1187,7 @@ static inline int __boot_firmware_common(struct venus_hfi_device *device) } if (count >= max_tries) { - dprintk(VIDC_ERR, "Error booting up vidc firmware\n"); + s_vpr_e(sid, "Error booting up vidc firmware\n"); rc = -ETIME; } @@ -1199,17 +1200,17 @@ static int venus_hfi_suspend(void *dev) struct venus_hfi_device *device = (struct venus_hfi_device *) dev; if (!device) { - dprintk(VIDC_ERR, "%s invalid device\n", __func__); + d_vpr_e("%s: invalid device\n", __func__); return -EINVAL; } else if (!device->res->sw_power_collapsible) { return -ENOTSUPP; } - dprintk(VIDC_HIGH, "Suspending Venus\n"); + d_vpr_h("Suspending Venus\n"); mutex_lock(&device->lock); rc = __power_collapse(device, true); if (rc) { - dprintk(VIDC_ERR, "%s: Venus is busy\n", __func__); + d_vpr_e("%s: Venus is busy\n", __func__); rc = -EBUSY; } mutex_unlock(&device->lock); @@ -1227,13 +1228,13 @@ static int venus_hfi_flush_debug_queue(void *dev) struct venus_hfi_device *device = (struct venus_hfi_device *) dev; if (!device) { - dprintk(VIDC_ERR, "%s invalid device\n", __func__); + d_vpr_e("%s: invalid device\n", __func__); return -EINVAL; } mutex_lock(&device->lock); if (!device->power_enabled) { - dprintk(VIDC_ERR, "%s: venus power off\n", __func__); + d_vpr_e("%s: venus power off\n", __func__); rc = -EINVAL; goto exit; } @@ -1243,26 +1244,8 @@ static int venus_hfi_flush_debug_queue(void *dev) return rc; } -static enum hal_default_properties venus_hfi_get_default_properties(void *dev) -{ - enum hal_default_properties prop = 0; - struct venus_hfi_device *device = (struct venus_hfi_device *) dev; - - if (!device) { - dprintk(VIDC_ERR, "%s invalid device\n", __func__); - return -EINVAL; - } - - mutex_lock(&device->lock); - - prop = HAL_VIDEO_DYNAMIC_BUF_MODE; - - mutex_unlock(&device->lock); - return prop; -} - static int __set_clk_rate(struct venus_hfi_device *device, - struct clock_info *cl, u64 rate) + struct clock_info *cl, u64 rate, u32 sid) { int rc = 0; u64 threshold_freq = device->res->clk_freq_threshold; @@ -1272,18 +1255,17 @@ static int __set_clk_rate(struct venus_hfi_device *device, if (ipeak && device->clk_freq < threshold_freq && rate >= threshold_freq) { rc = cx_ipeak_update(ipeak, true); if (rc) { - dprintk(VIDC_ERR, - "%s: cx_ipeak_update failed!\n", __func__); + s_vpr_e(sid, "%s: cx_ipeak_update failed!\n", __func__); return rc; } - dprintk(VIDC_PERF, - "cx_ipeak_update: up, clk freq = %lu rate = %lu threshold_freq = %lu\n", - device->clk_freq, rate, threshold_freq); + s_vpr_p(sid, + "cx_ipeak_update: up, clk freq = %lu rate = %lu threshold_freq = %lu\n", + device->clk_freq, rate, threshold_freq); } rc = clk_set_rate(clk, rate); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(sid, "%s: Failed to set clock rate %llu %s: %d\n", __func__, rate, cl->name, rc); return rc; @@ -1292,14 +1274,14 @@ static int __set_clk_rate(struct venus_hfi_device *device, if (ipeak && device->clk_freq >= threshold_freq && rate < threshold_freq) { rc = cx_ipeak_update(ipeak, false); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(sid, "cx_ipeak_update failed! ipeak %pK\n", ipeak); device->clk_freq = rate; return rc; } - dprintk(VIDC_PERF, - "cx_ipeak_update: up, clk freq = %lu rate = %lu threshold_freq = %lu\n", - device->clk_freq, rate, threshold_freq); + s_vpr_p(sid, + "cx_ipeak_update: up, clk freq = %lu rate = %lu threshold_freq = %lu\n", + device->clk_freq, rate, threshold_freq); } device->clk_freq = rate; @@ -1307,7 +1289,7 @@ static int __set_clk_rate(struct venus_hfi_device *device, return rc; } -static int __set_clocks(struct venus_hfi_device *device, u32 freq) +static int __set_clocks(struct venus_hfi_device *device, u32 freq, u32 sid) { struct clock_info *cl; int rc = 0; @@ -1318,12 +1300,12 @@ static int __set_clocks(struct venus_hfi_device *device, u32 freq) venus_hfi_for_each_clock(device, cl) { if (cl->has_scaling) {/* has_scaling */ - rc = __set_clk_rate(device, cl, freq); + rc = __set_clk_rate(device, cl, freq, sid); if (rc) return rc; trace_msm_vidc_perf_clock_scale(cl->name, freq); - dprintk(VIDC_PERF, "Scaling clock %s to %u\n", + s_vpr_p(sid, "Scaling clock %s to %u\n", cl->name, freq); } } @@ -1331,32 +1313,32 @@ static int __set_clocks(struct venus_hfi_device *device, u32 freq) return 0; } -static int venus_hfi_scale_clocks(void *dev, u32 freq) +static int venus_hfi_scale_clocks(void *dev, u32 freq, u32 sid) { int rc = 0; struct venus_hfi_device *device = dev; if (!device) { - dprintk(VIDC_ERR, "Invalid args: %pK\n", device); + s_vpr_e(sid, "Invalid args: %pK\n", device); return -EINVAL; } mutex_lock(&device->lock); - if (__resume(device)) { - dprintk(VIDC_ERR, "Resume from power collapse failed\n"); + if (__resume(device, sid)) { + s_vpr_e(sid, "Resume from power collapse failed\n"); rc = -ENODEV; goto exit; } - rc = __set_clocks(device, freq); + rc = __set_clocks(device, freq, sid); exit: mutex_unlock(&device->lock); return rc; } -static int __scale_clocks(struct venus_hfi_device *device) +static int __scale_clocks(struct venus_hfi_device *device, u32 sid) { int rc = 0; struct allowed_clock_rates_table *allowed_clks_tbl = NULL; @@ -1366,27 +1348,28 @@ static int __scale_clocks(struct venus_hfi_device *device) rate = device->clk_freq ? device->clk_freq : allowed_clks_tbl[0].clock_rate; - rc = __set_clocks(device, rate); + rc = __set_clocks(device, rate, sid); return rc; } /* Writes into cmdq without raising an interrupt */ static int __iface_cmdq_write_relaxed(struct venus_hfi_device *device, - void *pkt, bool *requires_interrupt) + void *pkt, bool *requires_interrupt, u32 sid) { struct vidc_iface_q_info *q_info; struct vidc_hal_cmd_pkt_hdr *cmd_packet; int result = -E2BIG; if (!device || !pkt) { - dprintk(VIDC_ERR, "Invalid Params\n"); + s_vpr_e(sid, "%s: invalid params %pK %pK\n", + __func__, device, pkt); return -EINVAL; } __strict_check(device); if (!__core_in_valid_state(device)) { - dprintk(VIDC_ERR, "%s - fw not in init state\n", __func__); + s_vpr_e(sid, "%s: fw not in init state\n", __func__); result = -EINVAL; goto err_q_null; } @@ -1396,37 +1379,36 @@ static int __iface_cmdq_write_relaxed(struct venus_hfi_device *device, q_info = &device->iface_queues[VIDC_IFACEQ_CMDQ_IDX]; if (!q_info) { - dprintk(VIDC_ERR, "cannot write to shared Q's\n"); + s_vpr_e(sid, "cannot write to shared Q's\n"); goto err_q_null; } if (!q_info->q_array.align_virtual_addr) { - dprintk(VIDC_ERR, "cannot write to shared CMD Q's\n"); + s_vpr_e(sid, "cannot write to shared CMD Q's\n"); result = -ENODATA; goto err_q_null; } __sim_modify_cmd_packet((u8 *)pkt, device); - if (__resume(device)) { - dprintk(VIDC_ERR, "%s: Power on failed\n", __func__); + if (__resume(device, sid)) { + s_vpr_e(sid, "%s: Power on failed\n", __func__); goto err_q_write; } - if (!__write_queue(q_info, (u8 *)pkt, requires_interrupt)) { + if (!__write_queue(q_info, (u8 *)pkt, requires_interrupt, sid)) { if (device->res->sw_power_collapsible) { cancel_delayed_work(&venus_hfi_pm_work); if (!queue_delayed_work(device->venus_pm_workq, &venus_hfi_pm_work, msecs_to_jiffies( device->res->msm_vidc_pwr_collapse_delay))) { - dprintk(VIDC_LOW, - "PM work already scheduled\n"); + s_vpr_l(sid, "PM work already scheduled\n"); } } result = 0; } else { - dprintk(VIDC_ERR, "__iface_cmdq_write: queue full\n"); + s_vpr_e(sid, "__iface_cmdq_write: queue full\n"); } err_q_write: @@ -1434,19 +1416,20 @@ static int __iface_cmdq_write_relaxed(struct venus_hfi_device *device, return result; } -static void __raise_interrupt_common(struct venus_hfi_device *device) +static void __raise_interrupt_common(struct venus_hfi_device *device, u32 sid) { __write_register(device, CPU_IC_SOFTINT, - 1 << CPU_IC_SOFTINT_H2A_SHFT); + 1 << CPU_IC_SOFTINT_H2A_SHFT, sid); } -static int __iface_cmdq_write(struct venus_hfi_device *device, void *pkt) +static int __iface_cmdq_write(struct venus_hfi_device *device, + void *pkt, u32 sid) { bool needs_interrupt = false; - int rc = __iface_cmdq_write_relaxed(device, pkt, &needs_interrupt); + int rc = __iface_cmdq_write_relaxed(device, pkt, &needs_interrupt, sid); if (!rc && needs_interrupt) - call_venus_op(device, raise_interrupt, device); + call_venus_op(device, raise_interrupt, device, sid); return rc; } @@ -1458,21 +1441,21 @@ static int __iface_msgq_read(struct venus_hfi_device *device, void *pkt) struct vidc_iface_q_info *q_info; if (!pkt) { - dprintk(VIDC_ERR, "Invalid Params\n"); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } __strict_check(device); if (!__core_in_valid_state(device)) { - dprintk(VIDC_ERR, "%s - fw not in init state\n", __func__); + d_vpr_e("%s: fw not in init state\n", __func__); rc = -EINVAL; goto read_error_null; } q_info = &device->iface_queues[VIDC_IFACEQ_MSGQ_IDX]; if (!q_info->q_array.align_virtual_addr) { - dprintk(VIDC_ERR, "cannot read from shared MSG Q's\n"); + d_vpr_e("cannot read from shared MSG Q's\n"); rc = -ENODATA; goto read_error_null; } @@ -1480,7 +1463,8 @@ static int __iface_msgq_read(struct venus_hfi_device *device, void *pkt) if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) { __hal_sim_modify_msg_packet((u8 *)pkt, device); if (tx_req_is_set) - call_venus_op(device, raise_interrupt, device); + call_venus_op(device, raise_interrupt, device, + DEFAULT_SID); rc = 0; } else rc = -ENODATA; @@ -1496,7 +1480,7 @@ static int __iface_dbgq_read(struct venus_hfi_device *device, void *pkt) struct vidc_iface_q_info *q_info; if (!pkt) { - dprintk(VIDC_ERR, "Invalid Params\n"); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -1504,14 +1488,15 @@ static int __iface_dbgq_read(struct venus_hfi_device *device, void *pkt) q_info = &device->iface_queues[VIDC_IFACEQ_DBGQ_IDX]; if (!q_info->q_array.align_virtual_addr) { - dprintk(VIDC_ERR, "cannot read from shared DBG Q's\n"); + d_vpr_e("cannot read from shared DBG Q's\n"); rc = -ENODATA; goto dbg_error_null; } if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) { if (tx_req_is_set) - call_venus_op(device, raise_interrupt, device); + call_venus_op(device, raise_interrupt, device, + DEFAULT_SID); rc = 0; } else rc = -ENODATA; @@ -1543,7 +1528,7 @@ static void __interface_dsp_queues_release(struct venus_hfi_device *device) struct context_bank_info *cb = mem_data->mapping_info.cb_info; if (!device->dsp_iface_q_table.align_virtual_addr) { - dprintk(VIDC_ERR, "%s: already released\n", __func__); + d_vpr_e("%s: already released\n", __func__); return; } @@ -1584,24 +1569,22 @@ static int __interface_dsp_queues_init(struct venus_hfi_device *dev) kvaddr = dma_alloc_coherent(dev->res->mem_cdsp.dev, q_size, &dma_handle, GFP_KERNEL); if (IS_ERR_OR_NULL(kvaddr)) { - dprintk(VIDC_ERR, "%s: failed dma allocation\n", __func__); + d_vpr_e("%s: failed dma allocation\n", __func__); goto fail_dma_alloc; } cb = msm_smem_get_context_bank(MSM_VIDC_UNKNOWN, 0, - dev->res, HAL_BUFFER_INTERNAL_CMD_QUEUE); + dev->res, HAL_BUFFER_INTERNAL_CMD_QUEUE, DEFAULT_SID); if (!cb) { - dprintk(VIDC_ERR, - "%s: failed to get context bank\n", __func__); + d_vpr_e("%s: failed to get context bank\n", __func__); goto fail_dma_map; } iova = dma_map_single_attrs(cb->dev, phys_to_virt(dma_handle), q_size, DMA_BIDIRECTIONAL, 0); if (dma_mapping_error(cb->dev, iova)) { - dprintk(VIDC_ERR, "%s: failed dma mapping\n", __func__); + d_vpr_e("%s: failed dma mapping\n", __func__); goto fail_dma_map; } - dprintk(VIDC_HIGH, - "%s: kvaddr %pK dma_handle %#llx iova %#llx size %zd\n", + d_vpr_h("%s: kvaddr %pK dma_handle %#llx iova %#llx size %zd\n", __func__, kvaddr, dma_handle, iova, q_size); memset(mem_data, 0, sizeof(struct msm_smem)); @@ -1690,14 +1673,14 @@ static void __interface_queues_release(struct venus_hfi_device *device) (u32)mem_map_table_base_addr; if ((unsigned long)qdss->mem_map_table_base_addr != mem_map_table_base_addr) { - dprintk(VIDC_ERR, - "Invalid mem_map_table_base_addr %#lx", + d_vpr_e("Invalid mem_map_table_base_addr %#lx", mem_map_table_base_addr); } mem_map = (struct hfi_mem_map *)(qdss + 1); cb = msm_smem_get_context_bank(MSM_VIDC_UNKNOWN, - false, device->res, HAL_BUFFER_INTERNAL_CMD_QUEUE); + false, device->res, HAL_BUFFER_INTERNAL_CMD_QUEUE, + DEFAULT_SID); for (i = 0; cb && i < num_entries; i++) { iommu_unmap(cb->domain, @@ -1753,9 +1736,9 @@ static int __get_qdss_iommu_virtual_addr(struct venus_hfi_device *dev, IOMMU_READ | IOMMU_WRITE); if (rc) { - dprintk(VIDC_ERR, - "IOMMU QDSS mapping failed for addr %#x\n", - qdss_addr_tbl[i].start); + d_vpr_e( + "IOMMU QDSS mapping failed for addr %#x\n", + qdss_addr_tbl[i].start); rc = -ENOMEM; break; } @@ -1772,8 +1755,7 @@ static int __get_qdss_iommu_virtual_addr(struct venus_hfi_device *dev, } if (i < num_entries) { - dprintk(VIDC_ERR, - "QDSS mapping failed, Freeing other entries %d\n", i); + d_vpr_e("QDSS mapping failed, Freeing other entries %d\n", i); for (--i; domain && i >= 0; i--) { iommu_unmap(domain, @@ -1785,20 +1767,21 @@ static int __get_qdss_iommu_virtual_addr(struct venus_hfi_device *dev, return rc; } -static void __setup_ucregion_memory_map_common(struct venus_hfi_device *device) +static void __setup_ucregion_memory_map_common(struct venus_hfi_device *device, + u32 sid) { __write_register(device, UC_REGION_ADDR, - (u32)device->iface_q_table.align_device_addr); - __write_register(device, UC_REGION_SIZE, SHARED_QSIZE); + (u32)device->iface_q_table.align_device_addr, sid); + __write_register(device, UC_REGION_SIZE, SHARED_QSIZE, sid); __write_register(device, QTBL_ADDR, - (u32)device->iface_q_table.align_device_addr); - __write_register(device, QTBL_INFO, 0x01); + (u32)device->iface_q_table.align_device_addr, sid); + __write_register(device, QTBL_INFO, 0x01, sid); if (device->sfr.align_device_addr) __write_register(device, SFR_ADDR, - (u32)device->sfr.align_device_addr); + (u32)device->sfr.align_device_addr, sid); if (device->qdss.align_device_addr) __write_register(device, MMAP_ADDR, - (u32)device->qdss.align_device_addr); + (u32)device->qdss.align_device_addr, sid); } static int __interface_queues_init(struct venus_hfi_device *dev) @@ -1826,7 +1809,7 @@ static int __interface_queues_init(struct venus_hfi_device *dev) rc = __smem_alloc(dev, mem_addr, q_size, 1, SMEM_UNCACHED, HAL_BUFFER_INTERNAL_CMD_QUEUE); if (rc) { - dprintk(VIDC_ERR, "iface_q_table_alloc_fail\n"); + d_vpr_e("iface_q_table_alloc_fail\n"); goto fail_alloc_queue; } @@ -1855,7 +1838,7 @@ static int __interface_queues_init(struct venus_hfi_device *dev) ALIGNED_QDSS_SIZE, 1, SMEM_UNCACHED, HAL_BUFFER_INTERNAL_CMD_QUEUE); if (rc) { - dprintk(VIDC_ERR, + d_vpr_e( "qdss_alloc_fail: QDSS messages logging will not work\n"); dev->qdss.align_device_addr = 0; } else { @@ -1872,7 +1855,7 @@ static int __interface_queues_init(struct venus_hfi_device *dev) ALIGNED_SFR_SIZE, 1, SMEM_UNCACHED, HAL_BUFFER_INTERNAL_CMD_QUEUE); if (rc) { - dprintk(VIDC_ERR, "sfr_alloc_fail: SFR not will work\n"); + d_vpr_e("sfr_alloc_fail: SFR not will work\n"); dev->sfr.align_device_addr = 0; } else { dev->sfr.align_device_addr = mem_addr->align_device_addr - @@ -1924,17 +1907,15 @@ static int __interface_queues_init(struct venus_hfi_device *dev) mem_map = (struct hfi_mem_map *)(qdss + 1); cb = msm_smem_get_context_bank(MSM_VIDC_UNKNOWN, false, - dev->res, HAL_BUFFER_INTERNAL_CMD_QUEUE); + dev->res, HAL_BUFFER_INTERNAL_CMD_QUEUE, DEFAULT_SID); if (!cb) { - dprintk(VIDC_ERR, - "%s: failed to get context bank\n", __func__); + d_vpr_e("%s: failed to get context bank\n", __func__); return -EINVAL; } rc = __get_qdss_iommu_virtual_addr(dev, mem_map, cb->domain); if (rc) { - dprintk(VIDC_ERR, - "IOMMU mapping failed, Freeing qdss memdata\n"); + d_vpr_e("IOMMU mapping failed, Freeing qdss memdata\n"); __smem_free(dev, &dev->qdss.mem_data); dev->qdss.align_virtual_addr = NULL; dev->qdss.align_device_addr = 0; @@ -1945,18 +1926,18 @@ static int __interface_queues_init(struct venus_hfi_device *dev) if (dev->res->cvp_internal) { rc = __interface_dsp_queues_init(dev); if (rc) { - dprintk(VIDC_ERR, "dsp_queues_init failed\n"); + d_vpr_e("dsp_queues_init failed\n"); goto fail_alloc_queue; } } - call_venus_op(dev, setup_ucregion_memmap, dev); + call_venus_op(dev, setup_ucregion_memmap, dev, DEFAULT_SID); return 0; fail_alloc_queue: return -ENOMEM; } -static int __sys_set_debug(struct venus_hfi_device *device, u32 debug) +static int __sys_set_debug(struct venus_hfi_device *device, u32 debug, u32 sid) { u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE]; int rc = 0; @@ -1965,17 +1946,17 @@ static int __sys_set_debug(struct venus_hfi_device *device, u32 debug) rc = call_hfi_pkt_op(device, sys_debug_config, pkt, debug); if (rc) { - dprintk(VIDC_ERR, - "Debug mode setting to FW failed\n"); + s_vpr_e(sid, "Debug mode setting to FW failed\n"); return -ENOTEMPTY; } - if (__iface_cmdq_write(device, pkt)) + if (__iface_cmdq_write(device, pkt, sid)) return -ENOTEMPTY; return 0; } -static int __sys_set_coverage(struct venus_hfi_device *device, u32 mode) +static int __sys_set_coverage(struct venus_hfi_device *device, + u32 mode, u32 sid) { u8 packet[VIDC_IFACEQ_VAR_SMALL_PKT_SIZE]; int rc = 0; @@ -1983,15 +1964,14 @@ static int __sys_set_coverage(struct venus_hfi_device *device, u32 mode) (struct hfi_cmd_sys_set_property_packet *) &packet; rc = call_hfi_pkt_op(device, sys_coverage_config, - pkt, mode); + pkt, mode, sid); if (rc) { - dprintk(VIDC_ERR, - "Coverage mode setting to FW failed\n"); + s_vpr_e(sid, "Coverage mode setting to FW failed\n"); return -ENOTEMPTY; } - if (__iface_cmdq_write(device, pkt)) { - dprintk(VIDC_ERR, "Failed to send coverage pkt to f/w\n"); + if (__iface_cmdq_write(device, pkt, sid)) { + s_vpr_e(sid, "Failed to send coverage pkt to f/w\n"); return -ENOTEMPTY; } @@ -1999,7 +1979,7 @@ static int __sys_set_coverage(struct venus_hfi_device *device, u32 mode) } static int __sys_set_power_control(struct venus_hfi_device *device, - bool enable) + bool enable, u32 sid) { struct regulator_info *rinfo; bool supported = false; @@ -2018,7 +1998,7 @@ static int __sys_set_power_control(struct venus_hfi_device *device, return 0; call_hfi_pkt_op(device, sys_power_control, pkt, enable); - if (__iface_cmdq_write(device, pkt)) + if (__iface_cmdq_write(device, pkt, sid)) return -ENOTEMPTY; return 0; } @@ -2031,13 +2011,13 @@ static int venus_hfi_core_init(void *device) struct venus_hfi_device *dev; if (!device) { - dprintk(VIDC_ERR, "Invalid device\n"); + d_vpr_e("Invalid device\n"); return -ENODEV; } dev = device; - dprintk(VIDC_HIGH, "Core initializing\n"); + d_vpr_h("Core initializing\n"); mutex_lock(&dev->lock); @@ -2045,50 +2025,51 @@ static int venus_hfi_core_init(void *device) rc = __load_fw(dev); if (rc) { - dprintk(VIDC_ERR, "Failed to load Venus FW\n"); + d_vpr_e("Failed to load Venus FW\n"); goto err_load_fw; } __set_state(dev, VENUS_STATE_INIT); - dprintk(VIDC_HIGH, "Dev_Virt: %pa, Reg_Virt: %pK\n", + d_vpr_h("Dev_Virt: %pa, Reg_Virt: %pK\n", &dev->hal_data->firmware_base, dev->hal_data->register_base); rc = __interface_queues_init(dev); if (rc) { - dprintk(VIDC_ERR, "failed to init queues\n"); + d_vpr_e("failed to init queues\n"); rc = -ENOMEM; goto err_core_init; } - rc = call_venus_op(dev, boot_firmware, dev); + rc = call_venus_op(dev, boot_firmware, dev, DEFAULT_SID); if (rc) { - dprintk(VIDC_ERR, "Failed to start core\n"); + d_vpr_e("Failed to start core\n"); rc = -ENODEV; goto err_core_init; } rc = call_hfi_pkt_op(dev, sys_init, &pkt, HFI_VIDEO_ARCH_OX); if (rc) { - dprintk(VIDC_ERR, "Failed to create sys init pkt\n"); + d_vpr_e("Failed to create sys init pkt\n"); goto err_core_init; } - if (__iface_cmdq_write(dev, &pkt)) { + if (__iface_cmdq_write(dev, &pkt, DEFAULT_SID)) { rc = -ENOTEMPTY; goto err_core_init; } rc = call_hfi_pkt_op(dev, sys_image_version, &version_pkt); - if (rc || __iface_cmdq_write(dev, &version_pkt)) - dprintk(VIDC_ERR, "Failed to send image version pkt to f/w\n"); + if (rc || __iface_cmdq_write(dev, &version_pkt, DEFAULT_SID)) + d_vpr_e("Failed to send image version pkt to f/w\n"); - __sys_set_debug(device, (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT); + __sys_set_debug(device, (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT, + DEFAULT_SID); - __enable_subcaches(device); - __set_subcaches(device); + __enable_subcaches(device, DEFAULT_SID); + __set_subcaches(device, DEFAULT_SID); __dsp_send_hfi_queue(device); __set_ubwc_config(device); @@ -2101,14 +2082,14 @@ static int venus_hfi_core_init(void *device) pm_qos_add_request(&dev->qos, PM_QOS_CPU_DMA_LATENCY, dev->res->pm_qos_latency_us); } - dprintk(VIDC_HIGH, "Core inited successfully\n"); + d_vpr_h("Core inited successfully\n"); mutex_unlock(&dev->lock); return rc; err_core_init: __set_state(dev, VENUS_STATE_DEINIT); __unload_fw(dev); err_load_fw: - dprintk(VIDC_ERR, "Core init failed\n"); + d_vpr_e("Core init failed\n"); mutex_unlock(&dev->lock); return rc; } @@ -2120,17 +2101,17 @@ static int venus_hfi_core_release(void *dev) struct hal_session *session, *next; if (!device) { - dprintk(VIDC_ERR, "invalid device\n"); + d_vpr_e("invalid device\n"); return -ENODEV; } mutex_lock(&device->lock); - dprintk(VIDC_HIGH, "Core releasing\n"); + d_vpr_h("Core releasing\n"); if (device->res->pm_qos_latency_us && pm_qos_request_active(&device->qos)) pm_qos_remove_request(&device->qos); - __resume(device); + __resume(device, DEFAULT_SID); __set_state(device, VENUS_STATE_DEINIT); __dsp_shutdown(device, 0); @@ -2140,7 +2121,7 @@ static int venus_hfi_core_release(void *dev) list_for_each_entry_safe(session, next, &device->sess_head, list) list_del(&session->list); - dprintk(VIDC_HIGH, "Core released successfully\n"); + d_vpr_h("Core released successfully\n"); mutex_unlock(&device->lock); return rc; @@ -2153,19 +2134,19 @@ static int __get_q_size(struct venus_hfi_device *dev, unsigned int q_index) u32 write_ptr, read_ptr; if (q_index >= VIDC_IFACEQ_NUMQ) { - dprintk(VIDC_ERR, "Invalid q index: %d\n", q_index); + d_vpr_e("Invalid q index: %d\n", q_index); return -ENOENT; } q_info = &dev->iface_queues[q_index]; if (!q_info) { - dprintk(VIDC_ERR, "cannot read shared Q's\n"); + d_vpr_e("cannot read shared Q's\n"); return -ENOENT; } queue = (struct hfi_queue_header *)q_info->q_hdr; if (!queue) { - dprintk(VIDC_ERR, "queue not present\n"); + d_vpr_e("queue not present\n"); return -ENOENT; } @@ -2179,11 +2160,11 @@ static void __core_clear_interrupt_common(struct venus_hfi_device *device) u32 intr_status = 0, mask = 0; if (!device) { - dprintk(VIDC_ERR, "%s: NULL device\n", __func__); + d_vpr_e("%s: NULL device\n", __func__); return; } - intr_status = __read_register(device, WRAPPER_INTR_STATUS); + intr_status = __read_register(device, WRAPPER_INTR_STATUS, DEFAULT_SID); mask = (WRAPPER_INTR_STATUS_A2H_BMSK | WRAPPER_INTR_STATUS_A2HWD_BMSK | CTRL_INIT_IDLE_MSG_BMSK); @@ -2191,15 +2172,14 @@ static void __core_clear_interrupt_common(struct venus_hfi_device *device) if (intr_status & mask) { device->intr_status |= intr_status; device->reg_count++; - dprintk(VIDC_LOW, - "INTERRUPT for device: %pK: times: %d interrupt_status: %d\n", - device, device->reg_count, intr_status); + d_vpr_l("INTERRUPT: times: %d interrupt_status: %d\n", + device->reg_count, intr_status); } else { device->spur_count++; } - __write_register(device, CPU_CS_A2HSOFTINTCLR, 1); - __write_register(device, WRAPPER_INTR_CLEAR, intr_status); + __write_register(device, CPU_CS_A2HSOFTINTCLR, 1, DEFAULT_SID); + __write_register(device, WRAPPER_INTR_CLEAR, intr_status, DEFAULT_SID); } static int venus_hfi_core_trigger_ssr(void *device, @@ -2210,7 +2190,7 @@ static int venus_hfi_core_trigger_ssr(void *device, struct venus_hfi_device *dev; if (!device) { - dprintk(VIDC_ERR, "invalid device\n"); + d_vpr_e("invalid device\n"); return -ENODEV; } @@ -2219,11 +2199,11 @@ static int venus_hfi_core_trigger_ssr(void *device, rc = call_hfi_pkt_op(dev, ssr_cmd, type, &pkt); if (rc) { - dprintk(VIDC_ERR, "core_ping: failed to create packet\n"); + d_vpr_e("core_ping: failed to create packet\n"); goto err_create_pkt; } - if (__iface_cmdq_write(dev, &pkt)) + if (__iface_cmdq_write(dev, &pkt, DEFAULT_SID)) rc = -ENOTEMPTY; err_create_pkt: @@ -2243,27 +2223,28 @@ static int venus_hfi_session_set_property(void *sess, mutex_lock(&device->lock); - dprintk(VIDC_HIGH, "in set_prop,with prop id: %#x\n", ptype); if (!__is_session_valid(device, session, __func__)) { rc = -EINVAL; goto err_set_prop; } + s_vpr_h(session->sid, "in set_prop,with prop id: %#x\n", ptype); rc = call_hfi_pkt_op(device, session_set_property, - pkt, session, ptype, pdata, size); + pkt, session->sid, ptype, pdata, size); if (rc == -ENOTSUPP) { - dprintk(VIDC_ERR, + s_vpr_e(session->sid, "set property: unsupported prop id: %#x\n", ptype); rc = 0; goto err_set_prop; } else if (rc) { - dprintk(VIDC_ERR, "set property: failed to create packet\n"); + s_vpr_e(session->sid, + "set property: failed to create packet\n"); rc = -EINVAL; goto err_set_prop; } - if (__iface_cmdq_write(device, pkt)) { + if (__iface_cmdq_write(device, pkt, session->sid)) { rc = -ENOTEMPTY; goto err_set_prop; } @@ -2273,13 +2254,14 @@ static int venus_hfi_session_set_property(void *sess, return rc; } -static void __set_default_sys_properties(struct venus_hfi_device *device) +static void __set_default_sys_properties(struct venus_hfi_device *device, + u32 sid) { if (__sys_set_debug(device, - (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT)) - dprintk(VIDC_ERR, "Setting fw_debug msg ON failed\n"); - if (__sys_set_power_control(device, true)) - dprintk(VIDC_ERR, "Setting h/w power collapse ON failed\n"); + (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT, sid)) + s_vpr_e(sid, "Setting fw_debug msg ON failed\n"); + if (__sys_set_power_control(device, true, sid)) + s_vpr_e(sid, "Setting h/w power collapse ON failed\n"); } static void __session_clean(struct hal_session *session) @@ -2289,7 +2271,7 @@ static void __session_clean(struct hal_session *session) if (!__is_session_valid(device, session, __func__)) return; - dprintk(VIDC_HIGH, "deleted the session: %pK\n", session); + s_vpr_h(session->sid, "deleted the session: %pK\n", session); /* * session might have been removed from the device list in * core_release, so check and remove if it is in the list @@ -2316,16 +2298,16 @@ static int venus_hfi_session_clean(void *sess) return 0; } -static int venus_hfi_session_init(void *device, void *session_id, +static int venus_hfi_session_init(void *device, void *inst_id, enum hal_domain session_type, enum hal_video_codec codec_type, - void **new_session) + void **new_session, u32 sid) { struct hfi_cmd_sys_session_init_packet pkt; struct venus_hfi_device *dev; struct hal_session *s; if (!device || !new_session) { - dprintk(VIDC_ERR, "%s - invalid input\n", __func__); + d_vpr_e("%s: invalid input\n", __func__); return -EINVAL; } @@ -2334,30 +2316,30 @@ static int venus_hfi_session_init(void *device, void *session_id, s = kzalloc(sizeof(struct hal_session), GFP_KERNEL); if (!s) { - dprintk(VIDC_ERR, "new session fail: Out of memory\n"); + s_vpr_e(sid, "new session fail: Out of memory\n"); goto err_session_init_fail; } - s->session_id = session_id; + s->inst_id = inst_id; s->is_decoder = (session_type == HAL_VIDEO_DOMAIN_DECODER); s->codec = codec_type; s->domain = session_type; - dprintk(VIDC_HIGH|VIDC_PERF, - "%s: inst %pK, session %pK, codec 0x%x, domain 0x%x\n", - __func__, session_id, s, s->codec, s->domain); + s->sid = sid; + s_vpr_hp(sid, "%s: inst %pK, session %pK, codec 0x%x, domain 0x%x\n", + __func__, inst_id, s, s->codec, s->domain); list_add_tail(&s->list, &dev->sess_head); - __set_default_sys_properties(device); + __set_default_sys_properties(device, sid); if (call_hfi_pkt_op(dev, session_init, &pkt, - s, session_type, codec_type)) { - dprintk(VIDC_ERR, "session_init: failed to create packet\n"); + sid, session_type, codec_type)) { + s_vpr_e(sid, "session_init: failed to create packet\n"); goto err_session_init_fail; } *new_session = s; - if (__iface_cmdq_write(dev, &pkt)) + if (__iface_cmdq_write(dev, &pkt, sid)) goto err_session_init_fail; mutex_unlock(&dev->lock); @@ -2381,16 +2363,16 @@ static int __send_session_cmd(struct hal_session *session, int pkt_type) return -EINVAL; rc = call_hfi_pkt_op(device, session_cmd, - &pkt, pkt_type, session); + &pkt, pkt_type, session->sid); if (rc == -EPERM) return 0; if (rc) { - dprintk(VIDC_ERR, "send session cmd: create pkt failed\n"); + s_vpr_e(session->sid, "send session cmd: create pkt failed\n"); goto err_create_pkt; } - if (__iface_cmdq_write(device, &pkt)) + if (__iface_cmdq_write(device, &pkt, session->sid)) rc = -ENOTEMPTY; err_create_pkt: @@ -2403,15 +2385,16 @@ static int venus_hfi_session_end(void *sess) struct venus_hfi_device *device = &venus_hfi_dev; int rc = 0; + if (!__is_session_valid(device, session, __func__)) + return -EINVAL; + mutex_lock(&device->lock); - if (msm_vidc_fw_coverage) { - if (__sys_set_coverage(device, msm_vidc_fw_coverage)) - dprintk(VIDC_ERR, "Fw_coverage msg ON failed\n"); + if (__sys_set_coverage(device, msm_vidc_fw_coverage, + session->sid)) + s_vpr_e(session->sid, "Fw_coverage msg ON failed\n"); } - rc = __send_session_cmd(session, HFI_CMD_SYS_SESSION_END); - mutex_unlock(&device->lock); return rc; @@ -2443,7 +2426,7 @@ static int venus_hfi_session_set_buffers(void *sess, struct venus_hfi_device *device = &venus_hfi_dev; if (!buffer_info) { - dprintk(VIDC_ERR, "Invalid Params\n"); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -2465,14 +2448,14 @@ static int venus_hfi_session_set_buffers(void *sess, pkt = (struct hfi_cmd_session_set_buffers_packet *)packet; rc = call_hfi_pkt_op(device, session_set_buffers, - pkt, session, buffer_info); + pkt, session->sid, buffer_info); if (rc) { - dprintk(VIDC_ERR, "set buffers: failed to create packet\n"); + s_vpr_e(session->sid, "set buffers: failed to create packet\n"); goto err_create_pkt; } - dprintk(VIDC_HIGH, "set buffers: %#x\n", buffer_info->buffer_type); - if (__iface_cmdq_write(device, pkt)) + s_vpr_h(session->sid, "set buffers: %#x\n", buffer_info->buffer_type); + if (__iface_cmdq_write(device, pkt, session->sid)) rc = -ENOTEMPTY; err_create_pkt: @@ -2490,7 +2473,7 @@ static int venus_hfi_session_release_buffers(void *sess, struct venus_hfi_device *device = &venus_hfi_dev; if (!buffer_info) { - dprintk(VIDC_ERR, "Invalid Params\n"); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -2508,14 +2491,16 @@ static int venus_hfi_session_release_buffers(void *sess, pkt = (struct hfi_cmd_session_release_buffer_packet *) packet; rc = call_hfi_pkt_op(device, session_release_buffers, - pkt, session, buffer_info); + pkt, session->sid, buffer_info); if (rc) { - dprintk(VIDC_ERR, "release buffers: failed to create packet\n"); + s_vpr_e(session->sid, "%s: failed to create packet\n", + __func__); goto err_create_pkt; } - dprintk(VIDC_HIGH, "Release buffers: %#x\n", buffer_info->buffer_type); - if (__iface_cmdq_write(device, pkt)) + s_vpr_h(session->sid, "Release buffers: %#x\n", + buffer_info->buffer_type); + if (__iface_cmdq_write(device, pkt, session->sid)) rc = -ENOTEMPTY; err_create_pkt: @@ -2533,7 +2518,7 @@ static int venus_hfi_session_register_buffer(void *sess, struct venus_hfi_device *device = &venus_hfi_dev; if (!buffer) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -2544,12 +2529,13 @@ static int venus_hfi_session_register_buffer(void *sess, } pkt = (struct hfi_cmd_session_register_buffers_packet *)packet; rc = call_hfi_pkt_op(device, session_register_buffer, pkt, - session, buffer); + session->sid, buffer); if (rc) { - dprintk(VIDC_ERR, "%s: failed to create packet\n", __func__); + s_vpr_e(session->sid, + "%s: failed to create packet\n", __func__); goto exit; } - if (__iface_cmdq_write(device, pkt)) + if (__iface_cmdq_write(device, pkt, session->sid)) rc = -ENOTEMPTY; exit: mutex_unlock(&device->lock); @@ -2567,7 +2553,7 @@ static int venus_hfi_session_unregister_buffer(void *sess, struct venus_hfi_device *device = &venus_hfi_dev; if (!buffer) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -2578,12 +2564,13 @@ static int venus_hfi_session_unregister_buffer(void *sess, } pkt = (struct hfi_cmd_session_unregister_buffers_packet *)packet; rc = call_hfi_pkt_op(device, session_unregister_buffer, pkt, - session, buffer); + session->sid, buffer); if (rc) { - dprintk(VIDC_ERR, "%s: failed to create packet\n", __func__); + s_vpr_e(session->sid, + "%s: failed to create packet\n", __func__); goto exit; } - if (__iface_cmdq_write(device, pkt)) + if (__iface_cmdq_write(device, pkt, session->sid)) rc = -ENOTEMPTY; exit: mutex_unlock(&device->lock); @@ -2669,17 +2656,18 @@ static int __session_etb(struct hal_session *session, struct hfi_cmd_session_empty_buffer_compressed_packet pkt; rc = call_hfi_pkt_op(device, session_etb_decoder, - &pkt, session, input_frame); + &pkt, session->sid, input_frame); if (rc) { - dprintk(VIDC_ERR, - "Session etb decoder: failed to create pkt\n"); + s_vpr_e(session->sid, + "etb decoder: failed to create pkt\n"); goto err_create_pkt; } if (!relaxed) - rc = __iface_cmdq_write(device, &pkt); + rc = __iface_cmdq_write(device, &pkt, session->sid); else - rc = __iface_cmdq_write_relaxed(device, &pkt, NULL); + rc = __iface_cmdq_write_relaxed(device, + &pkt, NULL, session->sid); if (rc) goto err_create_pkt; } else { @@ -2687,17 +2675,18 @@ static int __session_etb(struct hal_session *session, pkt; rc = call_hfi_pkt_op(device, session_etb_encoder, - &pkt, session, input_frame); + &pkt, session->sid, input_frame); if (rc) { - dprintk(VIDC_ERR, - "Session etb encoder: failed to create pkt\n"); + s_vpr_e(session->sid, + "etb encoder: failed to create pkt\n"); goto err_create_pkt; } if (!relaxed) - rc = __iface_cmdq_write(device, &pkt); + rc = __iface_cmdq_write(device, &pkt, session->sid); else - rc = __iface_cmdq_write_relaxed(device, &pkt, NULL); + rc = __iface_cmdq_write_relaxed(device, + &pkt, NULL, session->sid); if (rc) goto err_create_pkt; } @@ -2714,7 +2703,7 @@ static int venus_hfi_session_etb(void *sess, struct venus_hfi_device *device = &venus_hfi_dev; if (!input_frame) { - dprintk(VIDC_ERR, "Invalid Params\n"); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -2735,16 +2724,17 @@ static int __session_ftb(struct hal_session *session, return -EINVAL; rc = call_hfi_pkt_op(device, session_ftb, - &pkt, session, output_frame); + &pkt, session->sid, output_frame); if (rc) { - dprintk(VIDC_ERR, "Session ftb: failed to create pkt\n"); + s_vpr_e(session->sid, "Session ftb: failed to create pkt\n"); goto err_create_pkt; } if (!relaxed) - rc = __iface_cmdq_write(device, &pkt); + rc = __iface_cmdq_write(device, &pkt, session->sid); else - rc = __iface_cmdq_write_relaxed(device, &pkt, NULL); + rc = __iface_cmdq_write_relaxed(device, + &pkt, NULL, session->sid); err_create_pkt: return rc; @@ -2758,7 +2748,7 @@ static int venus_hfi_session_ftb(void *sess, struct venus_hfi_device *device = &venus_hfi_dev; if (!output_frame) { - dprintk(VIDC_ERR, "Invalid Params\n"); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -2787,8 +2777,8 @@ static int venus_hfi_session_process_batch(void *sess, for (c = 0; c < num_ftbs; ++c) { rc = __session_ftb(session, &ftbs[c], true); if (rc) { - dprintk(VIDC_ERR, "Failed to queue batched ftb: %d\n", - rc); + s_vpr_e(session->sid, + "Failed to queue batched ftb: %d\n", rc); goto err_etbs_and_ftbs; } } @@ -2796,19 +2786,19 @@ static int venus_hfi_session_process_batch(void *sess, for (c = 0; c < num_etbs; ++c) { rc = __session_etb(session, &etbs[c], true); if (rc) { - dprintk(VIDC_ERR, "Failed to queue batched etb: %d\n", - rc); + s_vpr_e(session->sid, + "Failed to queue batched etb: %d\n", rc); goto err_etbs_and_ftbs; } } - rc = call_hfi_pkt_op(device, session_sync_process, &pkt, session); + rc = call_hfi_pkt_op(device, session_sync_process, &pkt, session->sid); if (rc) { - dprintk(VIDC_ERR, "Failed to create sync packet\n"); + s_vpr_e(session->sid, "Failed to create sync packet\n"); goto err_etbs_and_ftbs; } - if (__iface_cmdq_write(device, &pkt)) + if (__iface_cmdq_write(device, &pkt, session->sid)) rc = -ENOTEMPTY; err_etbs_and_ftbs: @@ -2830,14 +2820,13 @@ static int venus_hfi_session_get_buf_req(void *sess) goto err_create_pkt; } rc = call_hfi_pkt_op(device, session_get_buf_req, - &pkt, session); + &pkt, session->sid); if (rc) { - dprintk(VIDC_ERR, - "Session get buf req: failed to create pkt\n"); + s_vpr_e(session->sid, "%s: failed to create pkt\n", __func__); goto err_create_pkt; } - if (__iface_cmdq_write(device, &pkt)) + if (__iface_cmdq_write(device, &pkt, session->sid)) rc = -ENOTEMPTY; err_create_pkt: mutex_unlock(&device->lock); @@ -2852,19 +2841,18 @@ static int venus_hfi_session_flush(void *sess, enum hal_flush flush_mode) struct venus_hfi_device *device = &venus_hfi_dev; mutex_lock(&device->lock); - if (!__is_session_valid(device, session, __func__)) { rc = -ENODEV; goto err_create_pkt; } rc = call_hfi_pkt_op(device, session_flush, - &pkt, session, flush_mode); + &pkt, session->sid, flush_mode); if (rc) { - dprintk(VIDC_ERR, "Session flush: failed to create pkt\n"); + s_vpr_e(session->sid, "Session flush: failed to create pkt\n"); goto err_create_pkt; } - if (__iface_cmdq_write(device, &pkt)) + if (__iface_cmdq_write(device, &pkt, session->sid)) rc = -ENOTEMPTY; err_create_pkt: mutex_unlock(&device->lock); @@ -2880,7 +2868,7 @@ static int __check_core_registered(struct hal_device_data core, struct list_head *curr, *next; if (!core.dev_count) { - dprintk(VIDC_ERR, "no device Registered\n"); + d_vpr_e("no device Registered\n"); return -EINVAL; } @@ -2911,7 +2899,7 @@ static int __check_core_registered(struct hal_device_data core, return 0; } - dprintk(VIDC_ERR, "Device not registered\n"); + d_vpr_e("Device not registered\n"); return -EINVAL; } return -EINVAL; @@ -2933,14 +2921,14 @@ int __prepare_pc(struct venus_hfi_device *device) rc = call_hfi_pkt_op(device, sys_pc_prep, &pkt); if (rc) { - dprintk(VIDC_ERR, "Failed to create sys pc prep pkt\n"); + d_vpr_e("Failed to create sys pc prep pkt\n"); goto err_pc_prep; } - if (__iface_cmdq_write(device, &pkt)) + if (__iface_cmdq_write(device, &pkt, DEFAULT_SID)) rc = -ENOTEMPTY; if (rc) - dprintk(VIDC_ERR, "Failed to prepare venus for power off"); + d_vpr_e("Failed to prepare venus for power off"); err_pc_prep: return rc; } @@ -2952,17 +2940,17 @@ static void venus_hfi_pm_handler(struct work_struct *work) &hal_ctxt.dev_head, struct venus_hfi_device, list); if (!device) { - dprintk(VIDC_ERR, "%s: NULL device\n", __func__); + d_vpr_e("%s: NULL device\n", __func__); return; } - dprintk(VIDC_HIGH, "Entering %s\n", __func__); + d_vpr_h("Entering %s\n", __func__); /* * It is ok to check this variable outside the lock since * it is being updated in this context only */ if (device->skip_pc_count >= VIDC_MAX_PC_SKIP_COUNT) { - dprintk(VIDC_ERR, "Failed to PC for %d times\n", + d_vpr_e("Failed to PC for %d times\n", device->skip_pc_count); device->skip_pc_count = 0; __process_fatal_error(device); @@ -2977,26 +2965,25 @@ static void venus_hfi_pm_handler(struct work_struct *work) device->skip_pc_count = 0; /* Cancel pending delayed works if any */ cancel_delayed_work(&venus_hfi_pm_work); - dprintk(VIDC_HIGH, "%s: power collapse successful!\n", - __func__); + d_vpr_h("%s: power collapse successful!\n", __func__); break; case -EBUSY: device->skip_pc_count = 0; - dprintk(VIDC_HIGH, "%s: retry PC as dsp is busy\n", __func__); + d_vpr_h("%s: retry PC as dsp is busy\n", __func__); queue_delayed_work(device->venus_pm_workq, &venus_hfi_pm_work, msecs_to_jiffies( device->res->msm_vidc_pwr_collapse_delay)); break; case -EAGAIN: device->skip_pc_count++; - dprintk(VIDC_ERR, "%s: retry power collapse (count %d)\n", + d_vpr_e("%s: retry power collapse (count %d)\n", __func__, device->skip_pc_count); queue_delayed_work(device->venus_pm_workq, &venus_hfi_pm_work, msecs_to_jiffies( device->res->msm_vidc_pwr_collapse_delay)); break; default: - dprintk(VIDC_ERR, "%s: power collapse failed\n", __func__); + d_vpr_e("%s: power collapse failed\n", __func__); break; } } @@ -3009,32 +2996,32 @@ static int __prepare_pc_common(struct venus_hfi_device *device) int count = 0; const int max_tries = 10; - ctrl_status = __read_register(device, CTRL_STATUS); + ctrl_status = __read_register(device, CTRL_STATUS, DEFAULT_SID); pc_ready = ctrl_status & CTRL_STATUS_PC_READY; idle_status = ctrl_status & BIT(30); if (pc_ready) { - dprintk(VIDC_HIGH, "Already in pc_ready state\n"); + d_vpr_h("Already in pc_ready state\n"); return 0; } wfi_status = BIT(0) & __read_register(device, - WRAPPER_CPU_STATUS); + WRAPPER_CPU_STATUS, DEFAULT_SID); if (!wfi_status || !idle_status) { - dprintk(VIDC_ERR, "Skipping PC, wfi status not set\n"); + d_vpr_e("Skipping PC, wfi status not set\n"); goto skip_power_off; } rc = __prepare_pc(device); if (rc) { - dprintk(VIDC_ERR, "Failed __prepare_pc %d\n", rc); + d_vpr_e("Failed __prepare_pc %d\n", rc); goto skip_power_off; } while (count < max_tries) { wfi_status = BIT(0) & __read_register(device, - WRAPPER_CPU_STATUS); - ctrl_status = __read_register(device, CTRL_STATUS); + WRAPPER_CPU_STATUS, DEFAULT_SID); + ctrl_status = __read_register(device, CTRL_STATUS, DEFAULT_SID); if (wfi_status && (ctrl_status & CTRL_STATUS_PC_READY)) break; usleep_range(150, 250); @@ -3042,14 +3029,14 @@ static int __prepare_pc_common(struct venus_hfi_device *device) } if (count == max_tries) { - dprintk(VIDC_ERR, "Skip PC. Core is not in right state\n"); + d_vpr_e("Skip PC. Core is not in right state\n"); goto skip_power_off; } return rc; skip_power_off: - dprintk(VIDC_ERR, "Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n", + d_vpr_e("Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n", wfi_status, idle_status, pc_ready, ctrl_status); return -EAGAIN; } @@ -3060,17 +3047,16 @@ static int __power_collapse(struct venus_hfi_device *device, bool force) u32 flags = 0; if (!device) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } if (!device->power_enabled) { - dprintk(VIDC_HIGH, "%s: Power already disabled\n", - __func__); + d_vpr_h("%s: Power already disabled\n", __func__); goto exit; } if (!__core_in_valid_state(device)) { - dprintk(VIDC_ERR, "%s - Core not in init state\n", __func__); + d_vpr_e("%s: Core not in init state\n", __func__); return -EINVAL; } @@ -3088,7 +3074,7 @@ static int __power_collapse(struct venus_hfi_device *device, bool force) rc = __suspend(device); if (rc) - dprintk(VIDC_ERR, "Failed __suspend\n"); + d_vpr_e("Failed __suspend\n"); exit: return rc; @@ -3112,8 +3098,7 @@ static void __process_sys_error(struct venus_hfi_device *device) if (p == NULL) vsfr->rg_data[vsfr->bufSize - 1] = '\0'; - dprintk(VIDC_ERR, "SFR Message from FW: %s\n", - vsfr->rg_data); + d_vpr_e("SFR Message from FW: %s\n", vsfr->rg_data); } } @@ -3123,15 +3108,14 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) enum vidc_msg_prio log_level = msm_vidc_debug; if (!device) { - dprintk(VIDC_ERR, "%s: Invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return; } if (!packet) { packet = kzalloc(VIDC_IFACEQ_VAR_HUGE_PKT_SIZE, GFP_KERNEL); if (!packet) { - dprintk(VIDC_ERR, "In %s() Fail to allocate mem\n", - __func__); + d_vpr_e("In %s() Fail to allocate mem\n", __func__); return; } @@ -3149,8 +3133,7 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) payload_size < MIN_PAYLOAD_SIZE || \ payload_size > \ (pkt_size - pkt_hdr_size + sizeof(u8))) { \ - dprintk(VIDC_ERR, \ - "%s: invalid msg size - %d\n", \ + d_vpr_e("%s: invalid msg size - %d\n", \ __func__, pkt->msg_size); \ continue; \ } \ @@ -3161,8 +3144,7 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) (struct hfi_packet_header *) packet; if (pkt->size < sizeof(struct hfi_packet_header)) { - dprintk(VIDC_ERR, "Invalid pkt size - %s\n", - __func__); + d_vpr_e("Invalid pkt size - %s\n", __func__); continue; } @@ -3177,8 +3159,7 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) stm_size = stm_log_inv_ts(0, 0, pkt->rg_msg_data, pkt->msg_size); if (stm_size == 0) - dprintk(VIDC_ERR, - "In %s, stm_log returned size of 0\n", + d_vpr_e("In %s, stm_log returned size of 0\n", __func__); } else if (pkt->packet_type == HFI_MSG_SYS_DEBUG) { @@ -3218,18 +3199,17 @@ static bool __is_session_valid(struct venus_hfi_device *device, return true; invalid: - dprintk(VIDC_ERR, "%s: device %pK, invalid session %pK\n", - func, device, session); + d_vpr_e("%s: device %pK, invalid session %pK\n", func, device, session); return false; } static struct hal_session *__get_session(struct venus_hfi_device *device, - u32 session_id) + u32 sid) { struct hal_session *temp = NULL; list_for_each_entry(temp, &device->sess_head, list) { - if (session_id == hash32_ptr(temp)) + if (sid == temp->sid) return temp; } @@ -3261,9 +3241,8 @@ static int __response_handler(struct venus_hfi_device *device) raw_packet = device->raw_packet; if (!raw_packet || !packets) { - dprintk(VIDC_ERR, - "%s: Invalid args : Res packet = %pK, Raw packet = %pK\n", - __func__, packets, raw_packet); + d_vpr_e("%s: Invalid args %pK, %pK\n", + __func__, raw_packet, packets); return 0; } @@ -3278,25 +3257,23 @@ static int __response_handler(struct venus_hfi_device *device) }; if (vsfr) - dprintk(VIDC_ERR, "SFR Message from FW: %s\n", - vsfr->rg_data); + d_vpr_e("SFR Message from FW: %s\n", vsfr->rg_data); - dprintk(VIDC_ERR, "Received watchdog timeout\n"); + d_vpr_e("Received watchdog timeout\n"); packets[packet_count++] = info; goto exit; } /* Bleed the msg queue dry of packets */ while (!__iface_msgq_read(device, raw_packet)) { - void **session_id = NULL; + void **inst_id = NULL; struct msm_vidc_cb_info *info = &packets[packet_count++]; int rc = 0; rc = hfi_process_msg_packet(device->device_id, (struct vidc_hal_msg_pkt_hdr *)raw_packet, info); if (rc) { - dprintk(VIDC_ERR, - "Corrupt/unknown packet found, discarding\n"); + d_vpr_e("Corrupt/unknown packet found, discarding\n"); --packet_count; continue; } @@ -3307,10 +3284,10 @@ static int __response_handler(struct venus_hfi_device *device) __process_sys_error(device); break; case HAL_SYS_RELEASE_RESOURCE_DONE: - dprintk(VIDC_HIGH, "Received SYS_RELEASE_RESOURCE\n"); + d_vpr_h("Received SYS_RELEASE_RESOURCE\n"); break; case HAL_SYS_INIT_DONE: - dprintk(VIDC_HIGH, "Received SYS_INIT_DONE\n"); + d_vpr_h("Received SYS_INIT_DONE\n"); break; case HAL_SESSION_LOAD_RESOURCE_DONE: break; @@ -3336,55 +3313,52 @@ static int __response_handler(struct venus_hfi_device *device) case HAL_SESSION_UNREGISTER_BUFFER_DONE: case HAL_SESSION_RELEASE_RESOURCE_DONE: case HAL_SESSION_PROPERTY_INFO: - session_id = &info->response.cmd.session_id; + inst_id = &info->response.cmd.inst_id; break; case HAL_SESSION_ERROR: case HAL_SESSION_ETB_DONE: case HAL_SESSION_FTB_DONE: - session_id = &info->response.data.session_id; + inst_id = &info->response.data.inst_id; break; case HAL_SESSION_EVENT_CHANGE: - session_id = &info->response.event.session_id; + inst_id = &info->response.event.inst_id; break; case HAL_RESPONSE_UNUSED: default: - session_id = NULL; + inst_id = NULL; break; } /* - * hfi_process_msg_packet provides a session_id that's a hashed - * value of struct hal_session, we need to coerce the hashed - * value back to pointer that we can use. Ideally, hfi_process\ - * _msg_packet should take care of this, but it doesn't have - * required information for it + * hfi_process_msg_packet provides a sid, we need to coerce + * the sid value back to pointer(inst_id) that we can + * use. Ideally, hfi_process_msg_packet should take care of + * this, but it doesn't have required information for it */ - if (session_id) { + if (inst_id) { struct hal_session *session = NULL; - if (upper_32_bits((uintptr_t)*session_id) != 0) { - dprintk(VIDC_ERR, - "Upper 32-bits != 0 for sess_id=%pK\n", - *session_id); + if (upper_32_bits((uintptr_t)*inst_id) != 0) { + d_vpr_e("Upper 32-bits != 0 for sess_id=%pK\n", + *inst_id); } session = __get_session(device, - (u32)(uintptr_t)*session_id); + (u32)(uintptr_t)*inst_id); if (!session) { - dprintk(VIDC_ERR, - "Received a packet (%#x) for an unrecognized session (%pK), discarding\n", - info->response_type, - *session_id); + d_vpr_e( + "Received a packet (%#x) for an unrecognized session (%pK), discarding\n", + info->response_type, *inst_id); --packet_count; continue; } - *session_id = session->session_id; + *inst_id = session->inst_id; } if (packet_count >= max_packets && __get_q_size(device, VIDC_IFACEQ_MSGQ_IDX)) { - dprintk(VIDC_ERR, - "Too many packets in message queue to handle at once, deferring read\n"); + d_vpr_e( + "Too many packets in message queue to handle at once, deferring read\n"); break; } @@ -3399,7 +3373,7 @@ static int __response_handler(struct venus_hfi_device *device) &venus_hfi_pm_work, msecs_to_jiffies( device->res->msm_vidc_pwr_collapse_delay))) { - dprintk(VIDC_ERR, "PM work already scheduled\n"); + d_vpr_e("PM work already scheduled\n"); } } @@ -3417,21 +3391,19 @@ static void venus_hfi_core_work_handler(struct work_struct *work) u32 intr_status; mutex_lock(&device->lock); - - if (!__core_in_valid_state(device)) { - dprintk(VIDC_ERR, "%s - Core not in init state\n", __func__); + d_vpr_e("%s: Core not in init state\n", __func__); goto err_no_work; } if (!device->callback) { - dprintk(VIDC_ERR, "No interrupt callback function: %pK\n", + d_vpr_e("No interrupt callback function: %pK\n", device); goto err_no_work; } - if (__resume(device)) { - dprintk(VIDC_ERR, "%s: Power enable failed\n", __func__); + if (__resume(device, DEFAULT_SID)) { + d_vpr_e("%s: Power enable failed\n", __func__); goto err_no_work; } @@ -3454,13 +3426,11 @@ static void venus_hfi_core_work_handler(struct work_struct *work) struct msm_vidc_cb_info *r = &device->response_pkt[i]; if (!__core_in_valid_state(device)) { - dprintk(VIDC_ERR, + d_vpr_e( "Ignore responses from %d to %d as device is in invalid state", (i + 1), num_responses); break; } - dprintk(VIDC_LOW, "Processing response %d of %d, type %d\n", - (i + 1), num_responses, r->response_type); device->callback(r->response_type, &r->response); } @@ -3495,15 +3465,15 @@ static int __init_regs_and_interrupts(struct venus_hfi_device *device, (u8 *)(uintptr_t)res->register_base, res->register_size, res->irq); if (!rc) { - dprintk(VIDC_ERR, "Core present/Already added\n"); + d_vpr_e("Core present/Already added\n"); rc = -EEXIST; goto err_core_init; } - dprintk(VIDC_HIGH, "HAL_DATA will be assigned now\n"); + d_vpr_h("HAL_DATA will be assigned now\n"); hal = kzalloc(sizeof(struct hal_data), GFP_KERNEL); if (!hal) { - dprintk(VIDC_ERR, "Failed to alloc\n"); + d_vpr_e("Failed to alloc\n"); rc = -ENOMEM; goto err_core_init; } @@ -3514,8 +3484,7 @@ static int __init_regs_and_interrupts(struct venus_hfi_device *device, res->register_base, res->register_size); hal->register_size = res->register_size; if (!hal->register_base) { - dprintk(VIDC_ERR, - "could not map reg addr %pa of size %d\n", + d_vpr_e("could not map reg addr %pa of size %d\n", &res->register_base, res->register_size); goto error_irq_fail; } @@ -3524,13 +3493,12 @@ static int __init_regs_and_interrupts(struct venus_hfi_device *device, rc = request_irq(res->irq, venus_hfi_isr, IRQF_TRIGGER_HIGH, "msm_vidc", device); if (unlikely(rc)) { - dprintk(VIDC_ERR, "() :request_irq failed\n"); + d_vpr_e("%s: request_irq failed\n", __func__); goto error_irq_fail; } disable_irq_nosync(res->irq); - dprintk(VIDC_HIGH, - "firmware_base = %pa, register_base = %pa, register_size = %d\n", + d_vpr_h("firmware_base = %pa, reg_base = %pa, reg_size = %d\n", &res->firmware_base, &res->register_base, res->register_size); @@ -3562,13 +3530,12 @@ static inline int __init_clocks(struct venus_hfi_device *device) struct clock_info *cl = NULL; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %pK\n", device); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } venus_hfi_for_each_clock(device, cl) { - - dprintk(VIDC_HIGH, "%s: scalable? %d, count %d\n", + d_vpr_h("%s: scalable? %d, count %d\n", cl->name, cl->has_scaling, cl->count); } @@ -3576,8 +3543,7 @@ static inline int __init_clocks(struct venus_hfi_device *device) if (!cl->clk) { cl->clk = clk_get(&device->res->pdev->dev, cl->name); if (IS_ERR_OR_NULL(cl->clk)) { - dprintk(VIDC_ERR, - "Failed to get clock: %s\n", cl->name); + d_vpr_e("Failed to get clock: %s\n", cl->name); rc = PTR_ERR(cl->clk) ? PTR_ERR(cl->clk) : -EINVAL; cl->clk = NULL; @@ -3594,7 +3560,7 @@ static inline int __init_clocks(struct venus_hfi_device *device) } static int __handle_reset_clk(struct msm_vidc_platform_resources *res, - int reset_index, enum reset_state state) + int reset_index, enum reset_state state, u32 sid) { int rc = 0; struct reset_control *rst; @@ -3604,7 +3570,7 @@ static int __handle_reset_clk(struct msm_vidc_platform_resources *res, return 0; rst = rst_set->reset_tbl[reset_index].rst; - dprintk(VIDC_HIGH, "reset_clk: name %s reset_state %d rst %pK\n", + s_vpr_h(sid, "reset_clk: name %s reset_state %d rst %pK\n", rst_set->reset_tbl[reset_index].name, state, rst); switch (state) { @@ -3635,7 +3601,7 @@ static int __handle_reset_clk(struct msm_vidc_platform_resources *res, rc = reset_control_deassert(rst); break; default: - dprintk(VIDC_ERR, "Invalid reset request\n"); + s_vpr_e(sid, "Invalid reset request\n"); if (rc) goto failed_to_reset; } @@ -3653,63 +3619,59 @@ void __disable_unprepare_clks(struct venus_hfi_device *device) int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %pK\n", device); + d_vpr_e("%s: invalid params\n", __func__); return; } venus_hfi_for_each_clock_reverse(device, cl) { - dprintk(VIDC_HIGH, "Clock: %s disable and unprepare\n", + d_vpr_h("Clock: %s disable and unprepare\n", cl->name); rc = clk_set_flags(cl->clk, CLKFLAG_NORETAIN_PERIPH); if (rc) { - dprintk(VIDC_ERR, - "Failed set flag NORETAIN_PERIPH %s\n", + d_vpr_e("Failed set flag NORETAIN_PERIPH %s\n", cl->name); } rc = clk_set_flags(cl->clk, CLKFLAG_NORETAIN_MEM); if (rc) { - dprintk(VIDC_ERR, - "Failed set flag NORETAIN_MEM %s\n", + d_vpr_e("Failed set flag NORETAIN_MEM %s\n", cl->name); } if (!__clk_is_enabled(cl->clk)) - dprintk(VIDC_ERR, "%s: clock %s already disabled\n", + d_vpr_e("%s: clock %s already disabled\n", __func__, cl->name); clk_disable_unprepare(cl->clk); if (__clk_is_enabled(cl->clk)) - dprintk(VIDC_ERR, "%s: clock %s not disabled\n", + d_vpr_e("%s: clock %s not disabled\n", __func__, cl->name); } } -int __reset_ahb2axi_bridge_common(struct venus_hfi_device *device) +int __reset_ahb2axi_bridge_common(struct venus_hfi_device *device, u32 sid) { int rc, i; if (!device) { - dprintk(VIDC_ERR, "NULL device\n"); + s_vpr_e(sid, "NULL device\n"); rc = -EINVAL; goto failed_to_reset; } for (i = 0; i < device->res->reset_set.count; i++) { - rc = __handle_reset_clk(device->res, i, ASSERT); + rc = __handle_reset_clk(device->res, i, ASSERT, sid); if (rc) { - dprintk(VIDC_ERR, - "failed to assert reset clocks\n"); + s_vpr_e(sid, "failed to assert reset clocks\n"); goto failed_to_reset; } /* wait for deassert */ usleep_range(150, 250); - rc = __handle_reset_clk(device->res, i, DEASSERT); + rc = __handle_reset_clk(device->res, i, DEASSERT, sid); if (rc) { - dprintk(VIDC_ERR, - "failed to deassert reset clocks\n"); + s_vpr_e(sid, "failed to deassert reset clocks\n"); goto failed_to_reset; } } @@ -3720,13 +3682,14 @@ int __reset_ahb2axi_bridge_common(struct venus_hfi_device *device) return rc; } -static inline int __prepare_enable_clks(struct venus_hfi_device *device) +static inline int __prepare_enable_clks(struct venus_hfi_device *device, + u32 sid) { struct clock_info *cl = NULL, *cl_fail = NULL; int rc = 0, c = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %pK\n", device); + s_vpr_e(sid, "%s: invalid params\n", __func__); return -EINVAL; } @@ -3737,47 +3700,45 @@ static inline int __prepare_enable_clks(struct venus_hfi_device *device) * it to the lowest frequency possible */ if (cl->has_scaling) - __set_clk_rate(device, cl, clk_round_rate(cl->clk, 0)); + __set_clk_rate(device, cl, + clk_round_rate(cl->clk, 0), sid); rc = clk_set_flags(cl->clk, CLKFLAG_RETAIN_PERIPH); if (rc) { - dprintk(VIDC_ERR, - "Failed set flag RETAIN_PERIPH %s\n", + s_vpr_e(sid, "Failed set flag RETAIN_PERIPH %s\n", cl->name); } rc = clk_set_flags(cl->clk, CLKFLAG_RETAIN_MEM); if (rc) { - dprintk(VIDC_ERR, - "Failed set flag RETAIN_MEM %s\n", + s_vpr_e(sid, "Failed set flag RETAIN_MEM %s\n", cl->name); } if (__clk_is_enabled(cl->clk)) - dprintk(VIDC_ERR, "%s: clock %s already enabled\n", + s_vpr_e(sid, "%s: clock %s already enabled\n", __func__, cl->name); rc = clk_prepare_enable(cl->clk); if (rc) { - dprintk(VIDC_ERR, "Failed to enable clocks\n"); + s_vpr_e(sid, "Failed to enable clocks\n"); cl_fail = cl; goto fail_clk_enable; } if (!__clk_is_enabled(cl->clk)) - dprintk(VIDC_ERR, "%s: clock %s not enabled\n", + s_vpr_e(sid, "%s: clock %s not enabled\n", __func__, cl->name); c++; - dprintk(VIDC_HIGH, - "Clock: %s prepared and enabled\n", cl->name); + s_vpr_h(sid, "Clock: %s prepared and enabled\n", cl->name); } - call_venus_op(device, clock_config_on_enable, device); + call_venus_op(device, clock_config_on_enable, device, sid); return rc; fail_clk_enable: venus_hfi_for_each_clock_reverse_continue(device, cl, c) { - dprintk(VIDC_ERR, "Clock: %s disable and unprepare\n", + s_vpr_e(sid, "Clock: %s disable and unprepare\n", cl->name); clk_disable_unprepare(cl->clk); } @@ -3811,8 +3772,7 @@ static int __init_bus(struct venus_hfi_device *device) venus_hfi_for_each_bus(device, bus) { if (!strcmp(bus->mode, "msm-vidc-llcc")) { if (msm_vidc_syscache_disable) { - dprintk(VIDC_HIGH, - "Skipping LLC bus init %s: %s\n", + d_vpr_h("Skipping LLC bus init %s: %s\n", bus->name, bus->mode); continue; } @@ -3822,7 +3782,7 @@ static int __init_bus(struct venus_hfi_device *device) if (IS_ERR_OR_NULL(bus->client)) { rc = PTR_ERR(bus->client) ? PTR_ERR(bus->client) : -EBADHANDLE; - dprintk(VIDC_ERR, "Failed to register bus %s: %d\n", + d_vpr_e("Failed to register bus %s: %d\n", bus->name, rc); bus->client = NULL; goto err_add_dev; @@ -3859,8 +3819,7 @@ static int __init_regulators(struct venus_hfi_device *device) if (IS_ERR_OR_NULL(rinfo->regulator)) { rc = PTR_ERR(rinfo->regulator) ? PTR_ERR(rinfo->regulator) : -EBADHANDLE; - dprintk(VIDC_ERR, "Failed to get regulator: %s\n", - rinfo->name); + d_vpr_e("Failed to get regulator: %s\n", rinfo->name); rinfo->regulator = NULL; goto err_reg_get; } @@ -3878,8 +3837,7 @@ static void __deinit_subcaches(struct venus_hfi_device *device) struct subcache_info *sinfo = NULL; if (!device) { - dprintk(VIDC_ERR, "deinit_subcaches: invalid device %pK\n", - device); + d_vpr_e("deinit_subcaches: invalid device %pK\n", device); goto exit; } @@ -3888,8 +3846,7 @@ static void __deinit_subcaches(struct venus_hfi_device *device) venus_hfi_for_each_subcache_reverse(device, sinfo) { if (sinfo->subcache) { - dprintk(VIDC_HIGH, "deinit_subcaches: %s\n", - sinfo->name); + d_vpr_h("deinit_subcaches: %s\n", sinfo->name); llcc_slice_putd(sinfo->subcache); sinfo->subcache = NULL; } @@ -3905,7 +3862,7 @@ static int __init_subcaches(struct venus_hfi_device *device) struct subcache_info *sinfo = NULL; if (!device) { - dprintk(VIDC_ERR, "init_subcaches: invalid device %pK\n", + d_vpr_e("init_subcaches: invalid device %pK\n", device); return -EINVAL; } @@ -3921,20 +3878,18 @@ static int __init_subcaches(struct venus_hfi_device *device) } else if (!strcmp("vidscfw", sinfo->name)) { sinfo->subcache = llcc_slice_getd(LLCC_VIDFW); } else { - dprintk(VIDC_ERR, "Invalid subcache name %s\n", + d_vpr_e("Invalid subcache name %s\n", sinfo->name); } if (IS_ERR_OR_NULL(sinfo->subcache)) { rc = PTR_ERR(sinfo->subcache) ? PTR_ERR(sinfo->subcache) : -EBADHANDLE; - dprintk(VIDC_ERR, - "init_subcaches: invalid subcache: %s rc %d\n", + d_vpr_e("init_subcaches: invalid subcache: %s rc %d\n", sinfo->name, rc); sinfo->subcache = NULL; goto err_subcache_get; } - dprintk(VIDC_HIGH, "init_subcaches: %s\n", - sinfo->name); + d_vpr_h("init_subcaches: %s\n", sinfo->name); } return 0; @@ -3951,21 +3906,21 @@ static int __init_resources(struct venus_hfi_device *device, rc = __init_regulators(device); if (rc) { - dprintk(VIDC_ERR, "Failed to get all regulators\n"); + d_vpr_e("Failed to get all regulators\n"); return -ENODEV; } rc = __init_clocks(device); if (rc) { - dprintk(VIDC_ERR, "Failed to init clocks\n"); + d_vpr_e("Failed to init clocks\n"); rc = -ENODEV; goto err_init_clocks; } for (i = 0; i < device->res->reset_set.count; i++) { - rc = __handle_reset_clk(res, i, INIT); + rc = __handle_reset_clk(res, i, INIT, DEFAULT_SID); if (rc) { - dprintk(VIDC_ERR, "Failed to init reset clocks\n"); + d_vpr_e("Failed to init reset clocks\n"); rc = -ENODEV; goto err_init_reset_clk; } @@ -3973,13 +3928,13 @@ static int __init_resources(struct venus_hfi_device *device, rc = __init_bus(device); if (rc) { - dprintk(VIDC_ERR, "Failed to init bus: %d\n", rc); + d_vpr_e("Failed to init bus: %d\n", rc); goto err_init_bus; } rc = __init_subcaches(device); if (rc) - dprintk(VIDC_ERR, "Failed to init subcaches: %d\n", rc); + d_vpr_e("Failed to init subcaches: %d\n", rc); return rc; @@ -4019,7 +3974,7 @@ static int __protect_cp_mem(struct venus_hfi_device *device) if (!strcmp(cb->name, "venus_ns")) { desc.args[1] = memprot.cp_size = cb->addr_range.start; - dprintk(VIDC_HIGH, "%s memprot.cp_size: %#x\n", + d_vpr_h("%s: memprot.cp_size: %#x\n", __func__, memprot.cp_size); } @@ -4028,8 +3983,7 @@ static int __protect_cp_mem(struct venus_hfi_device *device) cb->addr_range.start; desc.args[3] = memprot.cp_nonpixel_size = cb->addr_range.size; - dprintk(VIDC_HIGH, - "%s memprot.cp_nonpixel_start: %#x size: %#x\n", + d_vpr_h("%s: cp_nonpixel_start: %#x size: %#x\n", __func__, memprot.cp_nonpixel_start, memprot.cp_nonpixel_size); } @@ -4041,7 +3995,7 @@ static int __protect_cp_mem(struct venus_hfi_device *device) resp = desc.ret[0]; if (rc) { - dprintk(VIDC_ERR, "Failed to protect memory(%d) response: %d\n", + d_vpr_e("Failed to protect memory(%d) response: %d\n", rc, resp); } @@ -4056,7 +4010,7 @@ static int __disable_regulator(struct regulator_info *rinfo, { int rc = 0; - dprintk(VIDC_HIGH, "Disabling regulator %s\n", rinfo->name); + d_vpr_h("Disabling regulator %s\n", rinfo->name); /* * This call is needed. Driver needs to acquire the control back @@ -4064,34 +4018,32 @@ static int __disable_regulator(struct regulator_info *rinfo, * is unknown. */ - rc = __acquire_regulator(rinfo, device); + rc = __acquire_regulator(rinfo, device, DEFAULT_SID); if (rc) { /* * This is somewhat fatal, but nothing we can do * about it. We can't disable the regulator w/o * getting it back under s/w control */ - dprintk(VIDC_ERR, - "Failed to acquire control on %s\n", + d_vpr_e("Failed to acquire control on %s\n", rinfo->name); goto disable_regulator_failed; } if (!regulator_is_enabled(rinfo->regulator)) - dprintk(VIDC_ERR, "%s: regulator %s already disabled\n", + d_vpr_e("%s: regulator %s already disabled\n", __func__, rinfo->name); rc = regulator_disable(rinfo->regulator); if (rc) { - dprintk(VIDC_ERR, - "Failed to disable %s: %d\n", + d_vpr_e("Failed to disable %s: %d\n", rinfo->name, rc); goto disable_regulator_failed; } if (regulator_is_enabled(rinfo->regulator)) - dprintk(VIDC_ERR, "%s: regulator %s not disabled\n", + d_vpr_e("%s: regulator %s not disabled\n", __func__, rinfo->name); return 0; @@ -4102,43 +4054,41 @@ static int __disable_regulator(struct regulator_info *rinfo, return rc; } -static int __enable_hw_power_collapse(struct venus_hfi_device *device) +static int __enable_hw_power_collapse(struct venus_hfi_device *device, u32 sid) { int rc = 0; - rc = __hand_off_regulators(device); + rc = __hand_off_regulators(device, sid); if (rc) - dprintk(VIDC_ERR, - "%s : Failed to enable HW power collapse %d\n", + s_vpr_e(sid, "%s: Failed to enable HW power collapse %d\n", __func__, rc); return rc; } -static int __enable_regulators(struct venus_hfi_device *device) +static int __enable_regulators(struct venus_hfi_device *device, u32 sid) { int rc = 0, c = 0; struct regulator_info *rinfo; - dprintk(VIDC_HIGH, "Enabling regulators\n"); + s_vpr_h(sid, "Enabling regulators\n"); venus_hfi_for_each_regulator(device, rinfo) { if (regulator_is_enabled(rinfo->regulator)) - dprintk(VIDC_ERR, "%s: regulator %s already enabled\n", + s_vpr_e(sid, "%s: regulator %s already enabled\n", __func__, rinfo->name); rc = regulator_enable(rinfo->regulator); if (rc) { - dprintk(VIDC_ERR, - "Failed to enable %s: %d\n", + s_vpr_e(sid, "Failed to enable %s: %d\n", rinfo->name, rc); goto err_reg_enable_failed; } if (!regulator_is_enabled(rinfo->regulator)) - dprintk(VIDC_ERR, "%s: regulator %s not enabled\n", + s_vpr_e(sid, "%s: regulator %s not enabled\n", __func__, rinfo->name); - dprintk(VIDC_HIGH, "Enabled regulator %s\n", + s_vpr_h(sid, "Enabled regulator %s\n", rinfo->name); c++; } @@ -4156,15 +4106,14 @@ int __disable_regulators(struct venus_hfi_device *device) { struct regulator_info *rinfo; - dprintk(VIDC_HIGH, "Disabling regulators\n"); - + d_vpr_h("Disabling regulators\n"); venus_hfi_for_each_regulator_reverse(device, rinfo) __disable_regulator(rinfo, device); return 0; } -static int __enable_subcaches(struct venus_hfi_device *device) +static int __enable_subcaches(struct venus_hfi_device *device, u32 sid) { int rc = 0; u32 c = 0; @@ -4177,27 +4126,27 @@ static int __enable_subcaches(struct venus_hfi_device *device) venus_hfi_for_each_subcache(device, sinfo) { rc = llcc_slice_activate(sinfo->subcache); if (rc) { - dprintk(VIDC_ERR, "Failed to activate %s: %d\n", + s_vpr_e(sid, "Failed to activate %s: %d\n", sinfo->name, rc); msm_vidc_res_handle_fatal_hw_error(device->res, true); goto err_activate_fail; } sinfo->isactive = true; - dprintk(VIDC_HIGH, "Activated subcache %s\n", sinfo->name); + s_vpr_h(sid, "Activated subcache %s\n", sinfo->name); c++; } - dprintk(VIDC_HIGH, "Activated %d Subcaches to Venus\n", c); + s_vpr_h(sid, "Activated %d Subcaches to Venus\n", c); return 0; err_activate_fail: - __release_subcaches(device); - __disable_subcaches(device); + __release_subcaches(device, sid); + __disable_subcaches(device, sid); return 0; } -static int __set_subcaches(struct venus_hfi_device *device) +static int __set_subcaches(struct venus_hfi_device *device, u32 sid) { int rc = 0; u32 c = 0; @@ -4208,7 +4157,7 @@ static int __set_subcaches(struct venus_hfi_device *device) struct vidc_resource_hdr rhdr; if (device->res->sys_cache_res_set) { - dprintk(VIDC_HIGH, "Subcaches already set to Venus\n"); + s_vpr_h(sid, "Subcaches already set to Venus\n"); return 0; } @@ -4227,7 +4176,7 @@ static int __set_subcaches(struct venus_hfi_device *device) /* Set resource to Venus for activated subcaches */ if (c) { - dprintk(VIDC_HIGH, "Setting %d Subcaches\n", c); + s_vpr_h(sid, "Setting %d Subcaches\n", c); rhdr.resource_handle = sc_res_info; /* cookie */ rhdr.resource_id = VIDC_RESOURCE_SYSCACHE; @@ -4236,7 +4185,7 @@ static int __set_subcaches(struct venus_hfi_device *device) rc = __core_set_resource(device, &rhdr, (void *)sc_res_info); if (rc) { - dprintk(VIDC_ERR, "Failed to set subcaches %d\n", rc); + s_vpr_e(sid, "Failed to set subcaches %d\n", rc); goto err_fail_set_subacaches; } @@ -4245,19 +4194,19 @@ static int __set_subcaches(struct venus_hfi_device *device) sinfo->isset = true; } - dprintk(VIDC_HIGH, "Set Subcaches done to Venus\n"); + s_vpr_h(sid, "Set Subcaches done to Venus\n"); device->res->sys_cache_res_set = true; } return 0; err_fail_set_subacaches: - __disable_subcaches(device); + __disable_subcaches(device, sid); return 0; } -static int __release_subcaches(struct venus_hfi_device *device) +static int __release_subcaches(struct venus_hfi_device *device, u32 sid) { struct subcache_info *sinfo; int rc = 0; @@ -4287,14 +4236,13 @@ static int __release_subcaches(struct venus_hfi_device *device) } if (c > 0) { - dprintk(VIDC_HIGH, "Releasing %d subcaches\n", c); + s_vpr_h(sid, "Releasing %d subcaches\n", c); rhdr.resource_handle = sc_res_info; /* cookie */ rhdr.resource_id = VIDC_RESOURCE_SYSCACHE; rc = __core_release_resource(device, &rhdr); if (rc) - dprintk(VIDC_ERR, - "Failed to release %d subcaches\n", c); + s_vpr_e(sid, "Failed to release %d subcaches\n", c); } device->res->sys_cache_res_set = false; @@ -4302,7 +4250,7 @@ static int __release_subcaches(struct venus_hfi_device *device) return 0; } -static int __disable_subcaches(struct venus_hfi_device *device) +static int __disable_subcaches(struct venus_hfi_device *device, u32 sid) { struct subcache_info *sinfo; int rc = 0; @@ -4313,12 +4261,11 @@ static int __disable_subcaches(struct venus_hfi_device *device) /* De-activate subcaches */ venus_hfi_for_each_subcache_reverse(device, sinfo) { if (sinfo->isactive) { - dprintk(VIDC_HIGH, "De-activate subcache %s\n", + s_vpr_h(sid, "De-activate subcache %s\n", sinfo->name); rc = llcc_slice_deactivate(sinfo->subcache); if (rc) { - dprintk(VIDC_ERR, - "Failed to de-activate %s: %d\n", + s_vpr_e(sid, "Failed to de-activate %s: %d\n", sinfo->name, rc); } sinfo->isactive = false; @@ -4342,62 +4289,59 @@ static int __set_ubwc_config(struct venus_hfi_device *device) rc = call_hfi_pkt_op(device, sys_ubwc_config, pkt, device->res->ubwc_config); if (rc) { - dprintk(VIDC_ERR, - "ubwc config setting to FW failed\n"); + d_vpr_e("ubwc config setting to FW failed\n"); rc = -ENOTEMPTY; goto fail_to_set_ubwc_config; } - if (__iface_cmdq_write(device, pkt)) { + if (__iface_cmdq_write(device, pkt, DEFAULT_SID)) { rc = -ENOTEMPTY; goto fail_to_set_ubwc_config; } - dprintk(VIDC_HIGH, - "Configured UBWC Config to Venus\n"); + d_vpr_h("Configured UBWC Config to Venus\n"); fail_to_set_ubwc_config: return rc; } -static int __venus_power_on(struct venus_hfi_device *device) +static int __venus_power_on(struct venus_hfi_device *device, u32 sid) { int rc = 0; - if (device->power_enabled) return 0; device->power_enabled = true; /* Vote for all hardware resources */ - rc = __vote_buses(device, INT_MAX, INT_MAX); + rc = __vote_buses(device, INT_MAX, INT_MAX, sid); if (rc) { - dprintk(VIDC_ERR, "Failed to vote buses, err: %d\n", rc); + s_vpr_e(sid, "Failed to vote buses, err: %d\n", rc); goto fail_vote_buses; } - rc = __enable_regulators(device); + rc = __enable_regulators(device, sid); if (rc) { - dprintk(VIDC_ERR, "Failed to enable GDSC, err = %d\n", rc); + s_vpr_e(sid, "Failed to enable GDSC, err = %d\n", rc); goto fail_enable_gdsc; } - rc = call_venus_op(device, reset_ahb2axi_bridge, device); + rc = call_venus_op(device, reset_ahb2axi_bridge, device, sid); if (rc) { - dprintk(VIDC_ERR, "Failed to reset ahb2axi: %d\n", rc); + s_vpr_e(sid, "Failed to reset ahb2axi: %d\n", rc); goto fail_enable_clks; } - rc = __prepare_enable_clks(device); + rc = __prepare_enable_clks(device, sid); if (rc) { - dprintk(VIDC_ERR, "Failed to enable clocks: %d\n", rc); + s_vpr_e(sid, "Failed to enable clocks: %d\n", rc); goto fail_enable_clks; } - rc = __scale_clocks(device); + rc = __scale_clocks(device, sid); if (rc) { - dprintk(VIDC_ERR, - "Failed to scale clocks, performance might be affected\n"); + s_vpr_e(sid, + "Failed to scale clocks, performance might be affected\n"); rc = 0; } @@ -4405,9 +4349,9 @@ static int __venus_power_on(struct venus_hfi_device *device) * Re-program all of the registers that get reset as a result of * regulator_disable() and _enable() */ - __set_registers(device); + __set_registers(device, sid); - call_venus_op(device, interrupt_init, device); + call_venus_op(device, interrupt_init, device, sid); device->intr_status = 0; enable_irq(device->hal_data->irq); @@ -4416,7 +4360,7 @@ static int __venus_power_on(struct venus_hfi_device *device) fail_enable_clks: __disable_regulators(device); fail_enable_gdsc: - __unvote_buses(device); + __unvote_buses(device, sid); fail_vote_buses: device->power_enabled = false; return rc; @@ -4432,14 +4376,14 @@ static void __power_off_common(struct venus_hfi_device *device) device->intr_status = 0; __disable_unprepare_clks(device); - if (call_venus_op(device, reset_ahb2axi_bridge, device)) - dprintk(VIDC_ERR, "Failed to reset ahb2axi\n"); + if (call_venus_op(device, reset_ahb2axi_bridge, device, DEFAULT_SID)) + d_vpr_e("Failed to reset ahb2axi\n"); if (__disable_regulators(device)) - dprintk(VIDC_ERR, "Failed to disable regulators\n"); + d_vpr_e("Failed to disable regulators\n"); - if (__unvote_buses(device)) - dprintk(VIDC_ERR, "Failed to unvote for buses\n"); + if (__unvote_buses(device, DEFAULT_SID)) + d_vpr_e("Failed to unvote for buses\n"); device->power_enabled = false; } @@ -4448,61 +4392,61 @@ static inline int __suspend(struct venus_hfi_device *device) int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %pK\n", device); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } else if (!device->power_enabled) { - dprintk(VIDC_HIGH, "Power already disabled\n"); + d_vpr_h("Power already disabled\n"); return 0; } - dprintk(VIDC_HIGH, "Entering suspend\n"); + d_vpr_h("Entering suspend\n"); if (device->res->pm_qos_latency_us && pm_qos_request_active(&device->qos)) pm_qos_remove_request(&device->qos); - rc = __tzbsp_set_video_state(TZBSP_VIDEO_STATE_SUSPEND); + rc = __tzbsp_set_video_state(TZBSP_VIDEO_STATE_SUSPEND, DEFAULT_SID); if (rc) { - dprintk(VIDC_ERR, "Failed to suspend video core %d\n", rc); + d_vpr_e("Failed to suspend video core %d\n", rc); goto err_tzbsp_suspend; } - __disable_subcaches(device); + __disable_subcaches(device, DEFAULT_SID); call_venus_op(device, power_off, device); - dprintk(VIDC_HIGH, "Venus power off\n"); + d_vpr_h("Venus power off\n"); return rc; err_tzbsp_suspend: return rc; } -static inline int __resume(struct venus_hfi_device *device) +static inline int __resume(struct venus_hfi_device *device, u32 sid) { int rc = 0; u32 flags = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %pK\n", device); + s_vpr_e(sid, "%s: invalid params\n", __func__); return -EINVAL; } else if (device->power_enabled) { goto exit; } else if (!__core_in_valid_state(device)) { - dprintk(VIDC_ERR, "venus_hfi_device in deinit state."); + s_vpr_e(sid, "venus_hfi_device in deinit state."); return -EINVAL; } - dprintk(VIDC_HIGH, "Resuming from power collapse\n"); - rc = __venus_power_on(device); + s_vpr_h(sid, "Resuming from power collapse\n"); + rc = __venus_power_on(device, sid); if (rc) { - dprintk(VIDC_ERR, "Failed to power on venus\n"); + s_vpr_e(sid, "Failed to power on venus\n"); goto err_venus_power_on; } /* Reboot the firmware */ - rc = __tzbsp_set_video_state(TZBSP_VIDEO_STATE_RESUME); + rc = __tzbsp_set_video_state(TZBSP_VIDEO_STATE_RESUME, sid); if (rc) { - dprintk(VIDC_ERR, "Failed to resume video core %d\n", rc); + s_vpr_e(sid, "Failed to resume video core %d\n", rc); goto err_set_video_state; } @@ -4512,15 +4456,15 @@ static inline int __resume(struct venus_hfi_device *device) * (s/w triggered) to fast (HW triggered) unless the h/w vote is * present. */ - if (__enable_hw_power_collapse(device)) - dprintk(VIDC_ERR, "Failed to enabled inter-frame PC\n"); + if (__enable_hw_power_collapse(device, sid)) + s_vpr_e(sid, "Failed to enabled inter-frame PC\n"); - call_venus_op(device, setup_ucregion_memmap, device); + call_venus_op(device, setup_ucregion_memmap, device, sid); /* Wait for boot completion */ - rc = call_venus_op(device, boot_firmware, device); + rc = call_venus_op(device, boot_firmware, device, sid); if (rc) { - dprintk(VIDC_ERR, "Failed to reset venus core\n"); + s_vpr_e(sid, "Failed to reset venus core\n"); goto err_reset_core; } @@ -4533,24 +4477,25 @@ static inline int __resume(struct venus_hfi_device *device) device->res->pm_qos_latency_us); } - __sys_set_debug(device, (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT); + __sys_set_debug(device, (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT, + sid); - __enable_subcaches(device); - __set_subcaches(device); + __enable_subcaches(device, sid); + __set_subcaches(device, sid); __dsp_resume(device, flags); - dprintk(VIDC_HIGH, "Resumed from power collapse\n"); + s_vpr_h(sid, "Resumed from power collapse\n"); exit: /* Don't reset skip_pc_count for SYS_PC_PREP cmd */ if (device->last_packet_type != HFI_CMD_SYS_PC_PREP) device->skip_pc_count = 0; return rc; err_reset_core: - __tzbsp_set_video_state(TZBSP_VIDEO_STATE_SUSPEND); + __tzbsp_set_video_state(TZBSP_VIDEO_STATE_SUSPEND, sid); err_set_video_state: call_venus_op(device, power_off, device); err_venus_power_on: - dprintk(VIDC_ERR, "Failed to resume from power collapse\n"); + s_vpr_e(sid, "Failed to resume from power collapse\n"); return rc; } @@ -4561,20 +4506,20 @@ static int __load_fw(struct venus_hfi_device *device) /* Initialize resources */ rc = __init_resources(device, device->res); if (rc) { - dprintk(VIDC_ERR, "Failed to init resources: %d\n", rc); + d_vpr_e("Failed to init resources: %d\n", rc); goto fail_init_res; } rc = __initialize_packetization(device); if (rc) { - dprintk(VIDC_ERR, "Failed to initialize packetization\n"); + d_vpr_e("Failed to initialize packetization\n"); goto fail_init_pkt; } trace_msm_v4l2_vidc_fw_load_start("msm_v4l2_vidc venus_fw load start"); - rc = __venus_power_on(device); + rc = __venus_power_on(device, DEFAULT_SID); if (rc) { - dprintk(VIDC_ERR, "Failed to power on venus in in load_fw\n"); + d_vpr_e("Failed to power on venus in in load_fw\n"); goto fail_venus_power_on; } @@ -4585,19 +4530,19 @@ static int __load_fw(struct venus_hfi_device *device) device->res->fw_name); if (IS_ERR_OR_NULL(device->resources.fw.cookie)) { - dprintk(VIDC_ERR, "Failed to download firmware\n"); + d_vpr_e("Failed to download firmware\n"); device->resources.fw.cookie = NULL; rc = -ENOMEM; goto fail_load_fw; } } else { - dprintk(VIDC_ERR, "Firmware base must be 0\n"); + d_vpr_e("Firmware base must be 0\n"); } if (!device->res->firmware_base) { rc = __protect_cp_mem(device); if (rc) { - dprintk(VIDC_ERR, "Failed to protect memory\n"); + d_vpr_e("Failed to protect memory\n"); goto fail_protect_mem; } } @@ -4607,8 +4552,8 @@ static int __load_fw(struct venus_hfi_device *device) * (s/w triggered) to fast (HW triggered) unless the h/w vote is * present. */ - if (__enable_hw_power_collapse(device)) - dprintk(VIDC_ERR, "Failed to enabled inter-frame PC\n"); + if (__enable_hw_power_collapse(device, DEFAULT_SID)) + d_vpr_e("Failed to enabled inter-frame PC\n"); trace_msm_v4l2_vidc_fw_load_end("msm_v4l2_vidc venus_fw load end"); return rc; @@ -4641,7 +4586,7 @@ static void __unload_fw(struct venus_hfi_device *device) device->resources.fw.cookie = NULL; __deinit_resources(device); - dprintk(VIDC_HIGH, "Firmware unloaded successfully\n"); + d_vpr_h("Firmware unloaded successfully\n"); } static int venus_hfi_get_fw_info(void *dev, struct hal_fw_info *fw_info) @@ -4654,8 +4599,7 @@ static int venus_hfi_get_fw_info(void *dev, struct hal_fw_info *fw_info) const u32 smem_image_index_venus = 14 * 128; if (!device || !fw_info) { - dprintk(VIDC_ERR, - "%s Invalid parameter: device = %pK fw_info = %pK\n", + d_vpr_e("%s: Invalid parameter: device = %pK fw_info = %pK\n", __func__, device, fw_info); return -EINVAL; } @@ -4675,7 +4619,7 @@ static int venus_hfi_get_fw_info(void *dev, struct hal_fw_info *fw_info) ; if (i == VENUS_VERSION_LENGTH - 1) { - dprintk(VIDC_ERR, "Venus version string is not proper\n"); + d_vpr_e("Venus version string is not proper\n"); fw_info->version[0] = '\0'; goto fail_version_string; } @@ -4685,7 +4629,7 @@ static int venus_hfi_get_fw_info(void *dev, struct hal_fw_info *fw_info) fw_info->version[j] = '\0'; fail_version_string: - dprintk(VIDC_HIGH, "F/W version retrieved : %s\n", fw_info->version); + d_vpr_h("F/W version retrieved : %s\n", fw_info->version); fw_info->base_addr = device->hal_data->firmware_base; fw_info->register_base = device->res->register_base; fw_info->register_size = device->hal_data->register_size; @@ -4718,9 +4662,10 @@ static int venus_hfi_get_core_capabilities(void *dev) static void __noc_error_info(struct venus_hfi_device *device, u32 core_num) { u32 vcodec_core_video_noc_base_offs, val; + u32 sid = DEFAULT_SID; if (!device) { - dprintk(VIDC_ERR, "%s: null device\n", __func__); + d_vpr_e("%s: null device\n", __func__); return; } if (!core_num) { @@ -4730,44 +4675,43 @@ static void __noc_error_info(struct venus_hfi_device *device, u32 core_num) vcodec_core_video_noc_base_offs = VCODEC_CORE1_VIDEO_NOC_BASE_OFFS; } else { - dprintk(VIDC_ERR, "%s: invalid core_num %u\n", - __func__, core_num); + d_vpr_e("%s: invalid core_num %u\n", __func__, core_num); return; } val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_SWID_LOW_OFFS); - dprintk(VIDC_ERR, "CORE%d_NOC_ERR_SWID_LOW: %#x\n", core_num, val); + VCODEC_COREX_VIDEO_NOC_ERR_SWID_LOW_OFFS, sid); + d_vpr_e("CORE%d_NOC_ERR_SWID_LOW: %#x\n", core_num, val); val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_SWID_HIGH_OFFS); - dprintk(VIDC_ERR, "CORE%d_NOC_ERR_SWID_HIGH: %#x\n", core_num, val); + VCODEC_COREX_VIDEO_NOC_ERR_SWID_HIGH_OFFS, sid); + d_vpr_e("CORE%d_NOC_ERR_SWID_HIGH: %#x\n", core_num, val); val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_MAINCTL_LOW_OFFS); - dprintk(VIDC_ERR, "CORE%d_NOC_ERR_MAINCTL_LOW: %#x\n", core_num, val); + VCODEC_COREX_VIDEO_NOC_ERR_MAINCTL_LOW_OFFS, sid); + d_vpr_e("CORE%d_NOC_ERR_MAINCTL_LOW: %#x\n", core_num, val); val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_LOW_OFFS); - dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG0_LOW: %#x\n", core_num, val); + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_LOW_OFFS, sid); + d_vpr_e("CORE%d_NOC_ERR_ERRLOG0_LOW: %#x\n", core_num, val); val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_HIGH_OFFS); - dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG0_HIGH: %#x\n", core_num, val); + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_HIGH_OFFS, sid); + d_vpr_e("CORE%d_NOC_ERR_ERRLOG0_HIGH: %#x\n", core_num, val); val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_LOW_OFFS); - dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG1_LOW: %#x\n", core_num, val); + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_LOW_OFFS, sid); + d_vpr_e("CORE%d_NOC_ERR_ERRLOG1_LOW: %#x\n", core_num, val); val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_HIGH_OFFS); - dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG1_HIGH: %#x\n", core_num, val); + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_HIGH_OFFS, sid); + d_vpr_e("CORE%d_NOC_ERR_ERRLOG1_HIGH: %#x\n", core_num, val); val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_LOW_OFFS); - dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG2_LOW: %#x\n", core_num, val); + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_LOW_OFFS, sid); + d_vpr_e("CORE%d_NOC_ERR_ERRLOG2_LOW: %#x\n", core_num, val); val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_HIGH_OFFS); - dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG2_HIGH: %#x\n", core_num, val); + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_HIGH_OFFS, sid); + d_vpr_e("CORE%d_NOC_ERR_ERRLOG2_HIGH: %#x\n", core_num, val); val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_LOW_OFFS); - dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG3_LOW: %#x\n", core_num, val); + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_LOW_OFFS, sid); + d_vpr_e("CORE%d_NOC_ERR_ERRLOG3_LOW: %#x\n", core_num, val); val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_HIGH_OFFS); - dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG3_HIGH: %#x\n", core_num, val); + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_HIGH_OFFS, sid); + d_vpr_e("CORE%d_NOC_ERR_ERRLOG3_HIGH: %#x\n", core_num, val); } static void __noc_error_info_common(struct venus_hfi_device *device) @@ -4775,11 +4719,13 @@ static void __noc_error_info_common(struct venus_hfi_device *device) const u32 core0 = 0, core1 = 1; if (__read_register(device, VCODEC_CORE0_VIDEO_NOC_BASE_OFFS + - VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS)) + VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS, + DEFAULT_SID)) __noc_error_info(device, core0); if (__read_register(device, VCODEC_CORE1_VIDEO_NOC_BASE_OFFS + - VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS)) + VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS, + DEFAULT_SID)) __noc_error_info(device, core1); } @@ -4788,13 +4734,13 @@ static int venus_hfi_noc_error_info(void *dev) struct venus_hfi_device *device; if (!dev) { - dprintk(VIDC_ERR, "%s: null device\n", __func__); + d_vpr_e("%s: null device\n", __func__); return -EINVAL; } device = dev; mutex_lock(&device->lock); - dprintk(VIDC_ERR, "%s: non error information\n", __func__); + d_vpr_e("%s: non error information\n", __func__); call_venus_op(device, noc_error_info, device); @@ -4808,7 +4754,7 @@ static int __initialize_packetization(struct venus_hfi_device *device) int rc = 0; if (!device || !device->res) { - dprintk(VIDC_ERR, "%s - invalid param\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, device); return -EINVAL; } @@ -4817,7 +4763,7 @@ static int __initialize_packetization(struct venus_hfi_device *device) device->pkt_ops = hfi_get_pkt_ops_handle(device->packetization_type); if (!device->pkt_ops) { rc = -EINVAL; - dprintk(VIDC_ERR, "Failed to get pkt_ops handle\n"); + d_vpr_e("Failed to get pkt_ops handle\n"); } return rc; @@ -4841,23 +4787,24 @@ static struct venus_hfi_device *__add_device(u32 device_id, int rc = 0; if (!res || !callback) { - dprintk(VIDC_ERR, "Invalid Parameters\n"); + d_vpr_e("%s: Invalid Parameters %pK %pK\n", + __func__, res, callback); return NULL; } - dprintk(VIDC_HIGH, "entered , device_id: %d\n", device_id); + d_vpr_h("%s: entered, device_id: %d\n", __func__, device_id); hdevice->response_pkt = kmalloc_array(max_packets, sizeof(*hdevice->response_pkt), GFP_KERNEL); if (!hdevice->response_pkt) { - dprintk(VIDC_ERR, "failed to allocate response_pkt\n"); + d_vpr_e("failed to allocate response_pkt\n"); goto err_cleanup; } hdevice->raw_packet = kzalloc(VIDC_IFACEQ_VAR_HUGE_PKT_SIZE, GFP_KERNEL); if (!hdevice->raw_packet) { - dprintk(VIDC_ERR, "failed to allocate raw packet\n"); + d_vpr_e("failed to allocate raw packet\n"); goto err_cleanup; } @@ -4874,14 +4821,14 @@ static struct venus_hfi_device *__add_device(u32 device_id, hdevice->vidc_workq = create_singlethread_workqueue( "msm_vidc_workerq_venus"); if (!hdevice->vidc_workq) { - dprintk(VIDC_ERR, ": create vidc workq failed\n"); + d_vpr_e("%s: create vidc workq failed\n", __func__); goto err_cleanup; } hdevice->venus_pm_workq = create_singlethread_workqueue( "pm_workerq_venus"); if (!hdevice->venus_pm_workq) { - dprintk(VIDC_ERR, ": create pm workq failed\n"); + d_vpr_e("%s: create pm workq failed\n", __func__); goto err_cleanup; } @@ -4909,7 +4856,8 @@ static struct venus_hfi_device *__get_device(u32 device_id, hfi_cmd_response_callback callback) { if (!res || !callback) { - dprintk(VIDC_ERR, "Invalid params: %pK %pK\n", res, callback); + d_vpr_e("%s: invalid params: %pK %pK\n", + __func__, res, callback); return NULL; } @@ -4975,7 +4923,6 @@ static void venus_init_hfi_callbacks(struct hfi_device *hdev) hdev->suspend = venus_hfi_suspend; hdev->flush_debug_queue = venus_hfi_flush_debug_queue; hdev->noc_error_info = venus_hfi_noc_error_info; - hdev->get_default_properties = venus_hfi_get_default_properties; } int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id, @@ -4985,8 +4932,8 @@ int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id, int rc = 0; if (!hdev || !res || !callback) { - dprintk(VIDC_ERR, "Invalid params: %pK %pK %pK\n", - hdev, res, callback); + d_vpr_e("%s: invalid params: %pK %pK %pK\n", + __func__, hdev, res, callback); rc = -EINVAL; goto err_venus_hfi_init; } diff --git a/msm/vidc/hfi_common.h b/msm/vidc/hfi_common.h index dc6c5706489a..500d73091a2a 100644 --- a/msm/vidc/hfi_common.h +++ b/msm/vidc/hfi_common.h @@ -235,17 +235,18 @@ enum reset_state { struct venus_hfi_device; struct venus_hfi_vpu_ops { - void (*interrupt_init)(struct venus_hfi_device *device); - void (*setup_ucregion_memmap)(struct venus_hfi_device *device); - void (*clock_config_on_enable)(struct venus_hfi_device *device); - int (*reset_ahb2axi_bridge)(struct venus_hfi_device *device); + void (*interrupt_init)(struct venus_hfi_device *device, u32 sid); + void (*setup_ucregion_memmap)(struct venus_hfi_device *device, u32 sid); + void (*clock_config_on_enable)(struct venus_hfi_device *device, + u32 sid); + int (*reset_ahb2axi_bridge)(struct venus_hfi_device *device, u32 sid); void (*power_off)(struct venus_hfi_device *device); int (*prepare_pc)(struct venus_hfi_device *device); - void (*raise_interrupt)(struct venus_hfi_device *device); + void (*raise_interrupt)(struct venus_hfi_device *device, u32 sid); bool (*watchdog)(u32 intr_status); void (*noc_error_info)(struct venus_hfi_device *device); void (*core_clear_interrupt)(struct venus_hfi_device *device); - int (*boot_firmware)(struct venus_hfi_device *device); + int (*boot_firmware)(struct venus_hfi_device *device, u32 sid); }; struct venus_hfi_device { @@ -290,30 +291,34 @@ int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id, struct msm_vidc_platform_resources *res, hfi_cmd_response_callback callback); -void __write_register(struct venus_hfi_device *device, u32 reg, u32 value); -int __read_register(struct venus_hfi_device *device, u32 reg); +void __write_register(struct venus_hfi_device *device, + u32 reg, u32 value, u32 sid); +int __read_register(struct venus_hfi_device *device, u32 reg, u32 sid); void __disable_unprepare_clks(struct venus_hfi_device *device); int __disable_regulators(struct venus_hfi_device *device); -int __unvote_buses(struct venus_hfi_device *device); -int __reset_ahb2axi_bridge_common(struct venus_hfi_device *device); +int __unvote_buses(struct venus_hfi_device *device, u32 sid); +int __reset_ahb2axi_bridge_common(struct venus_hfi_device *device, u32 sid); int __prepare_pc(struct venus_hfi_device *device); /* AR50 specific */ -void __interrupt_init_ar50(struct venus_hfi_device *device); +void __interrupt_init_ar50(struct venus_hfi_device *device, u32 sid); /* IRIS1 specific */ -void __interrupt_init_iris1(struct venus_hfi_device *device); +void __interrupt_init_iris1(struct venus_hfi_device *device, u32 sid); void __setup_dsp_uc_memmap_iris1(struct venus_hfi_device *device); -void __clock_config_on_enable_iris1(struct venus_hfi_device *device); -void __setup_ucregion_memory_map_iris1(struct venus_hfi_device *device); +void __clock_config_on_enable_iris1(struct venus_hfi_device *device, + u32 sid); +void __setup_ucregion_memory_map_iris1(struct venus_hfi_device *device, + u32 sid); /* IRIS2 specific */ -void __interrupt_init_iris2(struct venus_hfi_device *device); -void __setup_ucregion_memory_map_iris2(struct venus_hfi_device *device); +void __interrupt_init_iris2(struct venus_hfi_device *device, u32 sid); +void __setup_ucregion_memory_map_iris2(struct venus_hfi_device *device, + u32 sid); void __power_off_iris2(struct venus_hfi_device *device); int __prepare_pc_iris2(struct venus_hfi_device *device); -void __raise_interrupt_iris2(struct venus_hfi_device *device); +void __raise_interrupt_iris2(struct venus_hfi_device *device, u32 sid); bool __watchdog_iris2(u32 intr_status); void __noc_error_info_iris2(struct venus_hfi_device *device); void __core_clear_interrupt_iris2(struct venus_hfi_device *device); -int __boot_firmware_iris2(struct venus_hfi_device *device); +int __boot_firmware_iris2(struct venus_hfi_device *device, u32 sid); #endif diff --git a/msm/vidc/hfi_iris1.c b/msm/vidc/hfi_iris1.c index 5789bd856394..b08eb68d9358 100644 --- a/msm/vidc/hfi_iris1.c +++ b/msm/vidc/hfi_iris1.c @@ -6,55 +6,55 @@ #include "hfi_common.h" #include "hfi_io_common.h" -void __interrupt_init_iris1(struct venus_hfi_device *device) +void __interrupt_init_iris1(struct venus_hfi_device *device, u32 sid) { u32 mask_val = 0; /* All interrupts should be disabled initially 0x1F6 : Reset value */ - mask_val = __read_register(device, WRAPPER_INTR_MASK); + mask_val = __read_register(device, WRAPPER_INTR_MASK, sid); /* Write 0 to unmask CPU and WD interrupts */ mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BMSK | WRAPPER_INTR_MASK_A2HCPU_BMSK); - __write_register(device, WRAPPER_INTR_MASK, mask_val); + __write_register(device, WRAPPER_INTR_MASK, mask_val, sid); } -void __setup_ucregion_memory_map_iris1(struct venus_hfi_device *device) +void __setup_ucregion_memory_map_iris1(struct venus_hfi_device *device, u32 sid) { /* initialize CPU QTBL & UCREGION */ __write_register(device, UC_REGION_ADDR, - (u32)device->iface_q_table.align_device_addr); - __write_register(device, UC_REGION_SIZE, SHARED_QSIZE); + (u32)device->iface_q_table.align_device_addr, sid); + __write_register(device, UC_REGION_SIZE, SHARED_QSIZE, sid); __write_register(device, QTBL_ADDR, - (u32)device->iface_q_table.align_device_addr); - __write_register(device, QTBL_INFO, 0x01); - if (device->sfr.align_device_addr) + (u32)device->iface_q_table.align_device_addr, sid); + __write_register(device, QTBL_INFO, 0x01, sid); + if (device->sfr.align_device_addr, sid) __write_register(device, SFR_ADDR, - (u32)device->sfr.align_device_addr); + (u32)device->sfr.align_device_addr, sid); if (device->qdss.align_device_addr) __write_register(device, MMAP_ADDR, - (u32)device->qdss.align_device_addr); + (u32)device->qdss.align_device_addr, sid); /* initialize DSP QTBL & UCREGION with CPU queues by default */ __write_register(device, HFI_DSP_QTBL_ADDR, - (u32)device->iface_q_table.align_device_addr); + (u32)device->iface_q_table.align_device_addr, sid); __write_register(device, HFI_DSP_UC_REGION_ADDR, - (u32)device->iface_q_table.align_device_addr); - __write_register(device, HFI_DSP_UC_REGION_SIZE, SHARED_QSIZE); + (u32)device->iface_q_table.align_device_addr, sid); + __write_register(device, HFI_DSP_UC_REGION_SIZE, SHARED_QSIZE, sid); if (device->res->cvp_internal) { /* initialize DSP QTBL & UCREGION with DSP queues */ __write_register(device, HFI_DSP_QTBL_ADDR, - (u32)device->dsp_iface_q_table.align_device_addr); + (u32)device->dsp_iface_q_table.align_device_addr, sid); __write_register(device, HFI_DSP_UC_REGION_ADDR, - (u32)device->dsp_iface_q_table.align_device_addr); + (u32)device->dsp_iface_q_table.align_device_addr, sid); __write_register(device, HFI_DSP_UC_REGION_SIZE, - device->dsp_iface_q_table.mem_data.size); + device->dsp_iface_q_table.mem_data.size, sid); } } -void __clock_config_on_enable_iris1(struct venus_hfi_device *device) +void __clock_config_on_enable_iris1(struct venus_hfi_device *device, u32 sid) { - __write_register(device, WRAPPER_CPU_CGC_DIS, 0); - __write_register(device, WRAPPER_CPU_CLOCK_CONFIG, 0); + __write_register(device, WRAPPER_CPU_CGC_DIS, 0, sid); + __write_register(device, WRAPPER_CPU_CLOCK_CONFIG, 0, sid); } diff --git a/msm/vidc/hfi_iris2.c b/msm/vidc/hfi_iris2.c index a352fbd4625c..e6eb40cd8f17 100644 --- a/msm/vidc/hfi_iris2.c +++ b/msm/vidc/hfi_iris2.c @@ -138,43 +138,45 @@ #define VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW 0x00011238 #define VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH 0x0001123C -void __interrupt_init_iris2(struct venus_hfi_device *device) +void __interrupt_init_iris2(struct venus_hfi_device *device, u32 sid) { u32 mask_val = 0; /* All interrupts should be disabled initially 0x1F6 : Reset value */ - mask_val = __read_register(device, WRAPPER_INTR_MASK_IRIS2); + mask_val = __read_register(device, WRAPPER_INTR_MASK_IRIS2, sid); /* Write 0 to unmask CPU and WD interrupts */ mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BMSK_IRIS2| WRAPPER_INTR_MASK_A2HCPU_BMSK_IRIS2); - __write_register(device, WRAPPER_INTR_MASK_IRIS2, mask_val); + __write_register(device, WRAPPER_INTR_MASK_IRIS2, mask_val, sid); } -void __setup_ucregion_memory_map_iris2(struct venus_hfi_device *device) +void __setup_ucregion_memory_map_iris2(struct venus_hfi_device *device, u32 sid) { __write_register(device, UC_REGION_ADDR_IRIS2, - (u32)device->iface_q_table.align_device_addr); - __write_register(device, UC_REGION_SIZE_IRIS2, SHARED_QSIZE); + (u32)device->iface_q_table.align_device_addr, sid); + __write_register(device, UC_REGION_SIZE_IRIS2, SHARED_QSIZE, sid); __write_register(device, QTBL_ADDR_IRIS2, - (u32)device->iface_q_table.align_device_addr); - __write_register(device, QTBL_INFO_IRIS2, 0x01); + (u32)device->iface_q_table.align_device_addr, sid); + __write_register(device, QTBL_INFO_IRIS2, 0x01, sid); if (device->sfr.align_device_addr) __write_register(device, SFR_ADDR_IRIS2, - (u32)device->sfr.align_device_addr); + (u32)device->sfr.align_device_addr, sid); if (device->qdss.align_device_addr) __write_register(device, MMAP_ADDR_IRIS2, - (u32)device->qdss.align_device_addr); + (u32)device->qdss.align_device_addr, sid); /* update queues vaddr for debug purpose */ __write_register(device, CPU_CS_VCICMDARG0_IRIS2, - (u32)device->iface_q_table.align_virtual_addr); + (u32)device->iface_q_table.align_virtual_addr, sid); __write_register(device, CPU_CS_VCICMDARG1_IRIS2, - (u32)((u64)device->iface_q_table.align_virtual_addr >> 32)); + (u32)((u64)device->iface_q_table.align_virtual_addr >> 32), + sid); } void __power_off_iris2(struct venus_hfi_device *device) { u32 lpi_status, reg_status = 0, count = 0, max_count = 10; + u32 sid = DEFAULT_SID; if (!device->power_enabled) return; @@ -184,78 +186,70 @@ void __power_off_iris2(struct venus_hfi_device *device) device->intr_status = 0; /* HPG 6.1.2 Step 1 */ - __write_register(device, CPU_CS_X2RPMh_IRIS2, 0x3); + __write_register(device, CPU_CS_X2RPMh_IRIS2, 0x3, sid); /* HPG 6.1.2 Step 2, noc to low power */ - __write_register(device, AON_WRAPPER_MVP_NOC_LPI_CONTROL, 0x1); + __write_register(device, AON_WRAPPER_MVP_NOC_LPI_CONTROL, 0x1, sid); while (!reg_status && count < max_count) { lpi_status = __read_register(device, - AON_WRAPPER_MVP_NOC_LPI_STATUS); + AON_WRAPPER_MVP_NOC_LPI_STATUS, sid); reg_status = lpi_status & BIT(0); - dprintk(VIDC_HIGH, - "Noc: lpi_status %d noc_status %d (count %d)\n", + d_vpr_h("Noc: lpi_status %d noc_status %d (count %d)\n", lpi_status, reg_status, count); usleep_range(50, 100); count++; } if (count == max_count) { - dprintk(VIDC_ERR, - "NOC not in qaccept status %d\n", reg_status); + d_vpr_e("NOC not in qaccept status %d\n", reg_status); } /* HPG 6.1.2 Step 3, debug bridge to low power */ __write_register(device, - WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2, 0x7); + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2, 0x7, sid); reg_status = 0; count = 0; while ((reg_status != 0x7) && count < max_count) { lpi_status = __read_register(device, - WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2); + WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2, sid); reg_status = lpi_status & 0x7; - dprintk(VIDC_HIGH, - "DBLP Set : lpi_status %d reg_status %d (count %d)\n", + d_vpr_h("DBLP Set : lpi_status %d reg_status %d (count %d)\n", lpi_status, reg_status, count); usleep_range(50, 100); count++; } - if (count == max_count) { - dprintk(VIDC_ERR, - "DBLP Set: status %d\n", reg_status); - } + if (count == max_count) + d_vpr_e("DBLP Set: status %d\n", reg_status); /* HPG 6.1.2 Step 4, debug bridge to lpi release */ __write_register(device, - WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2, 0x0); + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2, 0x0, sid); lpi_status = 0x1; count = 0; while (lpi_status && count < max_count) { lpi_status = __read_register(device, - WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2); - dprintk(VIDC_HIGH, - "DBLP Release: lpi_status %d(count %d)\n", + WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2, sid); + d_vpr_h("DBLP Release: lpi_status %d(count %d)\n", lpi_status, count); usleep_range(50, 100); count++; } - if (count == max_count) { - dprintk(VIDC_ERR, - "DBLP Release: lpi_status %d\n", lpi_status); - } + if (count == max_count) + d_vpr_e("DBLP Release: lpi_status %d\n", lpi_status); /* HPG 6.1.2 Step 6 */ __disable_unprepare_clks(device); /* HPG 6.1.2 Step 7 & 8 */ - if (call_venus_op(device, reset_ahb2axi_bridge, device)) - dprintk(VIDC_ERR, "Failed to reset ahb2axi\n"); + if (call_venus_op(device, reset_ahb2axi_bridge, device, sid)) + d_vpr_e("%s: Failed to reset ahb2axi\n", __func__); /* HPG 6.1.2 Step 5 */ if (__disable_regulators(device)) - dprintk(VIDC_ERR, "Failed to disable regulators\n"); + d_vpr_e("%s: Failed to disable regulators\n", __func__); - if (__unvote_buses(device)) - dprintk(VIDC_ERR, "Failed to unvote for buses\n"); + if (__unvote_buses(device, sid)) + d_vpr_e("%s: Failed to unvote for buses\n", __func__); device->power_enabled = false; } @@ -267,32 +261,33 @@ int __prepare_pc_iris2(struct venus_hfi_device *device) int count = 0; const int max_tries = 10; - ctrl_status = __read_register(device, CTRL_STATUS_IRIS2); + ctrl_status = __read_register(device, CTRL_STATUS_IRIS2, DEFAULT_SID); pc_ready = ctrl_status & CTRL_STATUS_PC_READY_IRIS2; idle_status = ctrl_status & BIT(30); if (pc_ready) { - dprintk(VIDC_HIGH, "Already in pc_ready state\n"); + d_vpr_h("Already in pc_ready state\n"); return 0; } - wfi_status = BIT(0) & __read_register(device, - WRAPPER_TZ_CPU_STATUS); + wfi_status = BIT(0) & __read_register(device, WRAPPER_TZ_CPU_STATUS, + DEFAULT_SID); if (!wfi_status || !idle_status) { - dprintk(VIDC_ERR, "Skipping PC, wfi status not set\n"); + d_vpr_e("Skipping PC, wfi status not set\n"); goto skip_power_off; } rc = __prepare_pc(device); if (rc) { - dprintk(VIDC_ERR, "Failed __prepare_pc %d\n", rc); + d_vpr_e("Failed __prepare_pc %d\n", rc); goto skip_power_off; } while (count < max_tries) { wfi_status = BIT(0) & __read_register(device, - WRAPPER_TZ_CPU_STATUS); - ctrl_status = __read_register(device, CTRL_STATUS_IRIS2); + WRAPPER_TZ_CPU_STATUS, DEFAULT_SID); + ctrl_status = __read_register(device, + CTRL_STATUS_IRIS2, DEFAULT_SID); if (wfi_status && (ctrl_status & CTRL_STATUS_PC_READY_IRIS2)) break; usleep_range(150, 250); @@ -300,22 +295,22 @@ int __prepare_pc_iris2(struct venus_hfi_device *device) } if (count == max_tries) { - dprintk(VIDC_ERR, "Skip PC. Core is not in right state\n"); + d_vpr_e("Skip PC. Core is not in right state\n"); goto skip_power_off; } return rc; skip_power_off: - dprintk(VIDC_ERR, "Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n", + d_vpr_e("Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n", wfi_status, idle_status, pc_ready, ctrl_status); return -EAGAIN; } -void __raise_interrupt_iris2(struct venus_hfi_device *device) +void __raise_interrupt_iris2(struct venus_hfi_device *device, u32 sid) { __write_register(device, CPU_IC_SOFTINT_IRIS2, - 1 << CPU_IC_SOFTINT_H2A_SHFT_IRIS2); + 1 << CPU_IC_SOFTINT_H2A_SHFT_IRIS2, sid); } bool __watchdog_iris2(u32 intr_status) @@ -331,33 +326,34 @@ bool __watchdog_iris2(u32 intr_status) void __noc_error_info_iris2(struct venus_hfi_device *device) { u32 val = 0; + u32 sid = DEFAULT_SID; - val = __read_register(device, VCODEC_NOC_ERL_MAIN_SWID_LOW); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_SWID_LOW: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_SWID_HIGH); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_SWID_HIGH: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_MAINCTL_LOW); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_MAINCTL_LOW: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRVLD_LOW); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRVLD_LOW: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRCLR_LOW); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRCLR_LOW: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW: %#x\n", val); - val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH); - dprintk(VIDC_ERR, "VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_SWID_LOW, sid); + d_vpr_e("VCODEC_NOC_ERL_MAIN_SWID_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_SWID_HIGH, sid); + d_vpr_e("VCODEC_NOC_ERL_MAIN_SWID_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_MAINCTL_LOW, sid); + d_vpr_e("VCODEC_NOC_ERL_MAIN_MAINCTL_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRVLD_LOW, sid); + d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRVLD_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRCLR_LOW, sid); + d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRCLR_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW, sid); + d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH, sid); + d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW, sid); + d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG1_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH, sid); + d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW, sid); + d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG2_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH, sid); + d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW, sid); + d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW: %#x\n", val); + val = __read_register(device, VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH, sid); + d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val); } void __core_clear_interrupt_iris2(struct venus_hfi_device *device) @@ -365,11 +361,12 @@ void __core_clear_interrupt_iris2(struct venus_hfi_device *device) u32 intr_status = 0, mask = 0; if (!device) { - dprintk(VIDC_ERR, "%s: NULL device\n", __func__); + d_vpr_e("%s: NULL device\n", __func__); return; } - intr_status = __read_register(device, WRAPPER_INTR_STATUS_IRIS2); + intr_status = __read_register(device, WRAPPER_INTR_STATUS_IRIS2, + DEFAULT_SID); mask = (WRAPPER_INTR_STATUS_A2H_BMSK_IRIS2| WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2| CTRL_INIT_IDLE_MSG_BMSK_IRIS2); @@ -377,17 +374,16 @@ void __core_clear_interrupt_iris2(struct venus_hfi_device *device) if (intr_status & mask) { device->intr_status |= intr_status; device->reg_count++; - dprintk(VIDC_LOW, - "INTERRUPT for device: %pK: times: %d interrupt_status: %d\n", - device, device->reg_count, intr_status); + d_vpr_l("INTERRUPT: times: %d interrupt_status: %d\n", + device->reg_count, intr_status); } else { device->spur_count++; } - __write_register(device, CPU_CS_A2HSOFTINTCLR_IRIS2, 1); + __write_register(device, CPU_CS_A2HSOFTINTCLR_IRIS2, 1, DEFAULT_SID); } -int __boot_firmware_iris2(struct venus_hfi_device *device) +int __boot_firmware_iris2(struct venus_hfi_device *device, u32 sid) { int rc = 0; u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 1000; @@ -396,11 +392,11 @@ int __boot_firmware_iris2(struct venus_hfi_device *device) if (device->res->cvp_internal) ctrl_init_val |= BIT(1); - __write_register(device, CTRL_INIT_IRIS2, ctrl_init_val); + __write_register(device, CTRL_INIT_IRIS2, ctrl_init_val, sid); while (!ctrl_status && count < max_tries) { - ctrl_status = __read_register(device, CTRL_STATUS_IRIS2); + ctrl_status = __read_register(device, CTRL_STATUS_IRIS2, sid); if ((ctrl_status & CTRL_ERROR_STATUS__M_IRIS2) == 0x4) { - dprintk(VIDC_ERR, "invalid setting for UC_REGION\n"); + s_vpr_e(sid, "invalid setting for UC_REGION\n"); break; } @@ -409,13 +405,13 @@ int __boot_firmware_iris2(struct venus_hfi_device *device) } if (count >= max_tries) { - dprintk(VIDC_ERR, "Error booting up vidc firmware\n"); + s_vpr_e(sid, "Error booting up vidc firmware\n"); rc = -ETIME; } /* Enable interrupt before sending commands to venus */ - __write_register(device, CPU_CS_H2XSOFTINTEN_IRIS2, 0x1); - __write_register(device, CPU_CS_X2RPMh_IRIS2, 0x0); + __write_register(device, CPU_CS_H2XSOFTINTEN_IRIS2, 0x1, sid); + __write_register(device, CPU_CS_X2RPMh_IRIS2, 0x0, sid); return rc; } diff --git a/msm/vidc/hfi_packetization.c b/msm/vidc/hfi_packetization.c index ebd8066aeba9..27cd92c17c70 100644 --- a/msm/vidc/hfi_packetization.c +++ b/msm/vidc/hfi_packetization.c @@ -5,81 +5,7 @@ #include "hfi_packetization.h" #include "msm_vidc_debug.h" -/* Set up look-up tables to convert HAL_* to HFI_*. - * - * The tables below mostly take advantage of the fact that most - * HAL_* types are defined bitwise. So if we index them normally - * when declaring the tables, we end up with huge arrays with wasted - * space. So before indexing them, we apply log2 to use a more - * sensible index. - */ - -enum hal_domain vidc_get_hal_domain(u32 hfi_domain) -{ - enum hal_domain hal_domain = 0; - - switch (hfi_domain) { - case HFI_VIDEO_DOMAIN_VPE: - hal_domain = HAL_VIDEO_DOMAIN_VPE; - break; - case HFI_VIDEO_DOMAIN_ENCODER: - hal_domain = HAL_VIDEO_DOMAIN_ENCODER; - break; - case HFI_VIDEO_DOMAIN_DECODER: - hal_domain = HAL_VIDEO_DOMAIN_DECODER; - break; - case HFI_VIDEO_DOMAIN_CVP: - hal_domain = HAL_VIDEO_DOMAIN_CVP; - break; - default: - dprintk(VIDC_ERR, "%s: invalid domain %x\n", - __func__, hfi_domain); - hal_domain = 0; - break; - } - return hal_domain; -} - -enum hal_video_codec vidc_get_hal_codec(u32 hfi_codec) -{ - enum hal_video_codec hal_codec = 0; - - switch (hfi_codec) { - case HFI_VIDEO_CODEC_H264: - hal_codec = HAL_VIDEO_CODEC_H264; - break; - case HFI_VIDEO_CODEC_MPEG1: - hal_codec = HAL_VIDEO_CODEC_MPEG1; - break; - case HFI_VIDEO_CODEC_MPEG2: - hal_codec = HAL_VIDEO_CODEC_MPEG2; - break; - case HFI_VIDEO_CODEC_VP8: - hal_codec = HAL_VIDEO_CODEC_VP8; - break; - case HFI_VIDEO_CODEC_HEVC: - hal_codec = HAL_VIDEO_CODEC_HEVC; - break; - case HFI_VIDEO_CODEC_VP9: - hal_codec = HAL_VIDEO_CODEC_VP9; - break; - case HFI_VIDEO_CODEC_TME: - hal_codec = HAL_VIDEO_CODEC_TME; - break; - case HFI_VIDEO_CODEC_CVP: - hal_codec = HAL_VIDEO_CODEC_CVP; - break; - default: - dprintk(VIDC_HIGH, "%s: invalid codec 0x%x\n", - __func__, hfi_codec); - hal_codec = 0; - break; - } - return hal_codec; -} - - -u32 vidc_get_hfi_domain(enum hal_domain hal_domain) +u32 vidc_get_hfi_domain(enum hal_domain hal_domain, u32 sid) { u32 hfi_domain; @@ -97,7 +23,7 @@ u32 vidc_get_hfi_domain(enum hal_domain hal_domain) hfi_domain = HFI_VIDEO_DOMAIN_CVP; break; default: - dprintk(VIDC_ERR, "%s: invalid domain 0x%x\n", + s_vpr_e(sid, "%s: invalid domain 0x%x\n", __func__, hal_domain); hfi_domain = 0; break; @@ -105,7 +31,7 @@ u32 vidc_get_hfi_domain(enum hal_domain hal_domain) return hfi_domain; } -u32 vidc_get_hfi_codec(enum hal_video_codec hal_codec) +u32 vidc_get_hfi_codec(enum hal_video_codec hal_codec, u32 sid) { u32 hfi_codec = 0; @@ -135,7 +61,7 @@ u32 vidc_get_hfi_codec(enum hal_video_codec hal_codec) hfi_codec = HFI_VIDEO_CODEC_CVP; break; default: - dprintk(VIDC_HIGH, "%s: invalid codec 0x%x\n", + s_vpr_h(sid, "%s: invalid codec 0x%x\n", __func__, hal_codec); hfi_codec = 0; break; @@ -194,10 +120,10 @@ int create_pkt_cmd_sys_debug_config( int create_pkt_cmd_sys_coverage_config( struct hfi_cmd_sys_set_property_packet *pkt, - u32 mode) + u32 mode, u32 sid) { if (!pkt) { - dprintk(VIDC_ERR, "In %s(), No input packet\n", __func__); + s_vpr_e(sid, "In %s(), No input packet\n", __func__); return -EINVAL; } @@ -207,8 +133,7 @@ int create_pkt_cmd_sys_coverage_config( pkt->num_properties = 1; pkt->rg_property_data[0] = HFI_PROPERTY_SYS_CONFIG_COVERAGE; pkt->rg_property_data[1] = mode; - dprintk(VIDC_HIGH, "Firmware coverage mode %d\n", - pkt->rg_property_data[1]); + s_vpr_h(sid, "Firmware coverage mode %d\n", pkt->rg_property_data[1]); return 0; } @@ -221,8 +146,7 @@ int create_pkt_cmd_sys_set_resource( u32 i = 0; if (!pkt || !res_hdr || !res_value) { - dprintk(VIDC_ERR, - "Invalid paramas pkt %pK res_hdr %pK res_value %pK\n", + d_vpr_e("Invalid paramas pkt %pK res_hdr %pK res_value %pK\n", pkt, res_hdr, res_value); return -EINVAL; } @@ -256,14 +180,13 @@ int create_pkt_cmd_sys_set_resource( for (i = 0; i < hfi_sc_info->num_entries; i++) { hfi_sc[i] = res_sc[i]; - dprintk(VIDC_HIGH, "entry hfi#%d, sc_id %d, size %d\n", + d_vpr_h("entry hfi#%d, sc_id %d, size %d\n", i, hfi_sc[i].sc_id, hfi_sc[i].size); } break; } default: - dprintk(VIDC_ERR, - "Invalid resource_id %d\n", res_hdr->resource_id); + d_vpr_e("Invalid resource_id %d\n", res_hdr->resource_id); rc = -ENOTSUPP; } @@ -277,8 +200,7 @@ int create_pkt_cmd_sys_release_resource( int rc = 0; if (!pkt || !res_hdr) { - dprintk(VIDC_ERR, - "Invalid paramas pkt %pK res_hdr %pK\n", + d_vpr_e("Invalid paramas pkt %pK res_hdr %pK\n", pkt, res_hdr); return -EINVAL; } @@ -292,13 +214,11 @@ int create_pkt_cmd_sys_release_resource( pkt->resource_type = HFI_RESOURCE_SYSCACHE; break; default: - dprintk(VIDC_ERR, - "Invalid resource_id %d\n", res_hdr->resource_id); + d_vpr_e("Invalid resource_id %d\n", res_hdr->resource_id); rc = -ENOTSUPP; } - dprintk(VIDC_HIGH, - "rel_res: pkt_type 0x%x res_type 0x%x prepared\n", + d_vpr_h("rel_res: pkt_type 0x%x res_type 0x%x prepared\n", pkt->packet_type, pkt->resource_type); return rc; @@ -306,8 +226,7 @@ int create_pkt_cmd_sys_release_resource( inline int create_pkt_cmd_sys_session_init( struct hfi_cmd_sys_session_init_packet *pkt, - struct hal_session *session, - u32 session_domain, u32 session_codec) + u32 sid, u32 session_domain, u32 session_codec) { int rc = 0; @@ -316,9 +235,9 @@ inline int create_pkt_cmd_sys_session_init( pkt->size = sizeof(struct hfi_cmd_sys_session_init_packet); pkt->packet_type = HFI_CMD_SYS_SESSION_INIT; - pkt->session_id = hash32_ptr(session); - pkt->session_domain = vidc_get_hfi_domain(session_domain); - pkt->session_codec = vidc_get_hfi_codec(session_codec); + pkt->sid = sid; + pkt->session_domain = vidc_get_hfi_domain(session_domain, sid); + pkt->session_codec = vidc_get_hfi_codec(session_codec, sid); if (!pkt->session_codec) return -EINVAL; @@ -369,9 +288,8 @@ int create_pkt_cmd_sys_ubwc_config( return rc; } - int create_pkt_cmd_session_cmd(struct vidc_hal_session_cmd_pkt *pkt, - int pkt_type, struct hal_session *session) + int pkt_type, u32 sid) { int rc = 0; @@ -380,7 +298,7 @@ int create_pkt_cmd_session_cmd(struct vidc_hal_session_cmd_pkt *pkt, pkt->size = sizeof(struct vidc_hal_session_cmd_pkt); pkt->packet_type = pkt_type; - pkt->session_id = hash32_ptr(session); + pkt->sid = sid; return rc; } @@ -391,7 +309,7 @@ int create_pkt_cmd_sys_power_control( struct hfi_enable *hfi; if (!pkt) { - dprintk(VIDC_ERR, "No input packet\n"); + d_vpr_e("%s: No input packet\n", __func__); return -EINVAL; } @@ -405,7 +323,7 @@ int create_pkt_cmd_sys_power_control( return 0; } -static u32 get_hfi_buffer(int hal_buffer) +static u32 get_hfi_buffer(int hal_buffer, u32 sid) { u32 buffer; @@ -444,8 +362,7 @@ static u32 get_hfi_buffer(int hal_buffer) buffer = HFI_BUFFER_INTERNAL_PERSIST_1; break; default: - dprintk(VIDC_ERR, "Invalid buffer: %#x\n", - hal_buffer); + s_vpr_e(sid, "Invalid buffer: %#x\n", hal_buffer); buffer = 0; break; } @@ -454,17 +371,16 @@ static u32 get_hfi_buffer(int hal_buffer) int create_pkt_cmd_session_set_buffers( struct hfi_cmd_session_set_buffers_packet *pkt, - struct hal_session *session, - struct vidc_buffer_addr_info *buffer_info) + u32 sid, struct vidc_buffer_addr_info *buffer_info) { int rc = 0; u32 i = 0; - if (!pkt || !session) + if (!pkt) return -EINVAL; pkt->packet_type = HFI_CMD_SESSION_SET_BUFFERS; - pkt->session_id = hash32_ptr(session); + pkt->sid = sid; pkt->buffer_size = buffer_info->buffer_size; pkt->min_buffer_size = buffer_info->buffer_size; pkt->num_buffers = buffer_info->num_buffers; @@ -495,7 +411,8 @@ int create_pkt_cmd_session_set_buffers( } } - pkt->buffer_type = get_hfi_buffer(buffer_info->buffer_type); + pkt->buffer_type = + get_hfi_buffer(buffer_info->buffer_type, pkt->sid); if (!pkt->buffer_type) return -EINVAL; @@ -504,17 +421,16 @@ int create_pkt_cmd_session_set_buffers( int create_pkt_cmd_session_release_buffers( struct hfi_cmd_session_release_buffer_packet *pkt, - struct hal_session *session, - struct vidc_buffer_addr_info *buffer_info) + u32 sid, struct vidc_buffer_addr_info *buffer_info) { int rc = 0; u32 i = 0; - if (!pkt || !session) + if (!pkt) return -EINVAL; pkt->packet_type = HFI_CMD_SESSION_RELEASE_BUFFERS; - pkt->session_id = hash32_ptr(session); + pkt->sid = sid; pkt->buffer_size = buffer_info->buffer_size; pkt->num_buffers = buffer_info->num_buffers; @@ -542,7 +458,8 @@ int create_pkt_cmd_session_release_buffers( ((buffer_info->num_buffers - 1) * sizeof(u32)); } pkt->response_req = buffer_info->response_required; - pkt->buffer_type = get_hfi_buffer(buffer_info->buffer_type); + pkt->buffer_type = + get_hfi_buffer(buffer_info->buffer_type, pkt->sid); if (!pkt->buffer_type) return -EINVAL; return rc; @@ -550,20 +467,18 @@ int create_pkt_cmd_session_release_buffers( int create_pkt_cmd_session_register_buffer( struct hfi_cmd_session_register_buffers_packet *pkt, - struct hal_session *session, - struct vidc_register_buffer *buffer) + u32 sid, struct vidc_register_buffer *buffer) { int rc = 0; u32 i; struct hfi_buffer_mapping_type *buf; - if (!pkt || !session) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + if (!pkt) { + d_vpr_e("%s: invalid params %pK\n", __func__, pkt); return -EINVAL; } - pkt->packet_type = HFI_CMD_SESSION_REGISTER_BUFFERS; - pkt->session_id = hash32_ptr(session); + pkt->sid = sid; pkt->client_data = buffer->client_data; pkt->response_req = buffer->response_required; pkt->num_buffers = 1; @@ -584,20 +499,18 @@ int create_pkt_cmd_session_register_buffer( int create_pkt_cmd_session_unregister_buffer( struct hfi_cmd_session_unregister_buffers_packet *pkt, - struct hal_session *session, - struct vidc_unregister_buffer *buffer) + u32 sid, struct vidc_unregister_buffer *buffer) { int rc = 0; u32 i; struct hfi_buffer_mapping_type *buf; - if (!pkt || !session) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + if (!pkt) { + d_vpr_e("%s: invalid params %pK\n", __func__, pkt); return -EINVAL; } - pkt->packet_type = HFI_CMD_SESSION_UNREGISTER_BUFFERS; - pkt->session_id = hash32_ptr(session); + pkt->sid = sid; pkt->client_data = buffer->client_data; pkt->response_req = buffer->response_required; pkt->num_buffers = 1; @@ -618,17 +531,17 @@ int create_pkt_cmd_session_unregister_buffer( int create_pkt_cmd_session_etb_decoder( struct hfi_cmd_session_empty_buffer_compressed_packet *pkt, - struct hal_session *session, struct vidc_frame_data *input_frame) + u32 sid, struct vidc_frame_data *input_frame) { int rc = 0; - if (!pkt || !session) + if (!pkt) return -EINVAL; pkt->size = sizeof(struct hfi_cmd_session_empty_buffer_compressed_packet); pkt->packet_type = HFI_CMD_SESSION_EMPTY_BUFFER; - pkt->session_id = hash32_ptr(session); + pkt->sid = sid; pkt->time_stamp_hi = upper_32_bits(input_frame->timestamp); pkt->time_stamp_lo = lower_32_bits(input_frame->timestamp); pkt->flags = input_frame->flags; @@ -650,17 +563,17 @@ int create_pkt_cmd_session_etb_decoder( int create_pkt_cmd_session_etb_encoder( struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet *pkt, - struct hal_session *session, struct vidc_frame_data *input_frame) + u32 sid, struct vidc_frame_data *input_frame) { int rc = 0; - if (!pkt || !session) + if (!pkt) return -EINVAL; pkt->size = sizeof(struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet); pkt->packet_type = HFI_CMD_SESSION_EMPTY_BUFFER; - pkt->session_id = hash32_ptr(session); + pkt->sid = sid; pkt->view_id = 0; pkt->time_stamp_hi = upper_32_bits(input_frame->timestamp); pkt->time_stamp_lo = lower_32_bits(input_frame->timestamp); @@ -683,17 +596,16 @@ int create_pkt_cmd_session_etb_encoder( } int create_pkt_cmd_session_ftb(struct hfi_cmd_session_fill_buffer_packet *pkt, - struct hal_session *session, - struct vidc_frame_data *output_frame) + u32 sid, struct vidc_frame_data *output_frame) { int rc = 0; - if (!pkt || !session || !output_frame) + if (!pkt || !output_frame) return -EINVAL; pkt->size = sizeof(struct hfi_cmd_session_fill_buffer_packet); pkt->packet_type = HFI_CMD_SESSION_FILL_BUFFER; - pkt->session_id = hash32_ptr(session); + pkt->sid = sid; if (output_frame->buffer_type == HAL_BUFFER_OUTPUT) pkt->stream_id = 0; @@ -720,16 +632,16 @@ int create_pkt_cmd_session_ftb(struct hfi_cmd_session_fill_buffer_packet *pkt, int create_pkt_cmd_session_get_buf_req( struct hfi_cmd_session_get_property_packet *pkt, - struct hal_session *session) + u32 sid) { int rc = 0; - if (!pkt || !session) + if (!pkt) return -EINVAL; pkt->size = sizeof(struct hfi_cmd_session_get_property_packet); pkt->packet_type = HFI_CMD_SESSION_GET_PROPERTY; - pkt->session_id = hash32_ptr(session); + pkt->sid = sid; pkt->num_properties = 1; pkt->rg_property_data[0] = HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS; @@ -737,16 +649,16 @@ int create_pkt_cmd_session_get_buf_req( } int create_pkt_cmd_session_flush(struct hfi_cmd_session_flush_packet *pkt, - struct hal_session *session, enum hal_flush flush_mode) + u32 sid, enum hal_flush flush_mode) { int rc = 0; - if (!pkt || !session) + if (!pkt) return -EINVAL; pkt->size = sizeof(struct hfi_cmd_session_flush_packet); pkt->packet_type = HFI_CMD_SESSION_FLUSH; - pkt->session_id = hash32_ptr(session); + pkt->sid = sid; switch (flush_mode) { case HAL_FLUSH_INPUT: pkt->flush_type = HFI_FLUSH_INPUT; @@ -758,7 +670,7 @@ int create_pkt_cmd_session_flush(struct hfi_cmd_session_flush_packet *pkt, pkt->flush_type = HFI_FLUSH_ALL; break; default: - dprintk(VIDC_ERR, "Invalid flush mode: %#x\n", flush_mode); + s_vpr_e(pkt->sid, "Invalid flush mode: %#x\n", flush_mode); return -EINVAL; } return rc; @@ -766,22 +678,22 @@ int create_pkt_cmd_session_flush(struct hfi_cmd_session_flush_packet *pkt, int create_pkt_cmd_session_set_property( struct hfi_cmd_session_set_property_packet *pkt, - struct hal_session *session, + u32 sid, u32 ptype, void *pdata, u32 size) { - if (!pkt || !session) + if (!pkt) return -EINVAL; pkt->size = sizeof(struct hfi_cmd_session_set_property_packet); pkt->packet_type = HFI_CMD_SESSION_SET_PROPERTY; - pkt->session_id = hash32_ptr(session); + pkt->sid = sid; pkt->num_properties = 1; pkt->size += size; pkt->rg_property_data[0] = ptype; if (size && pdata) memcpy(&pkt->rg_property_data[1], pdata, size); - dprintk(VIDC_HIGH, "Setting HAL Property = 0x%x\n", ptype); + s_vpr_h(pkt->sid, "Setting HAL Property = 0x%x\n", ptype); return 0; } @@ -800,8 +712,7 @@ static int get_hfi_ssr_type(enum hal_ssr_trigger_type type) rc = HFI_TEST_SSR_HW_WDOG_IRQ; break; default: - dprintk(VIDC_ERR, - "SSR trigger type not recognized, using WDOG.\n"); + d_vpr_e("SSR trigger type not recognized, using WDOG.\n"); } return rc; } @@ -810,7 +721,7 @@ int create_pkt_ssr_cmd(enum hal_ssr_trigger_type type, struct hfi_cmd_sys_test_ssr_packet *pkt) { if (!pkt) { - dprintk(VIDC_ERR, "Invalid params, device: %pK\n", pkt); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } pkt->size = sizeof(struct hfi_cmd_sys_test_ssr_packet); @@ -823,7 +734,7 @@ int create_pkt_cmd_sys_image_version( struct hfi_cmd_sys_get_property_packet *pkt) { if (!pkt) { - dprintk(VIDC_ERR, "%s invalid param :%pK\n", __func__, pkt); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } pkt->size = sizeof(struct hfi_cmd_sys_get_property_packet); @@ -834,16 +745,15 @@ int create_pkt_cmd_sys_image_version( } int create_pkt_cmd_session_sync_process( - struct hfi_cmd_session_sync_process_packet *pkt, - struct hal_session *session) + struct hfi_cmd_session_sync_process_packet *pkt, u32 sid) { - if (!pkt || !session) + if (!pkt) return -EINVAL; *pkt = (struct hfi_cmd_session_sync_process_packet) {0}; pkt->size = sizeof(*pkt); pkt->packet_type = HFI_CMD_SESSION_SYNC; - pkt->session_id = hash32_ptr(session); + pkt->sid = sid; pkt->sync_id = 0; return 0; @@ -878,8 +788,7 @@ static struct hfi_packetization_ops hfi_default = { struct hfi_packetization_ops *hfi_get_pkt_ops_handle( enum hfi_packetization_type type) { - dprintk(VIDC_HIGH, "%s selected\n", - type == HFI_PACKETIZATION_4XX ? + d_vpr_h("%s selected\n", type == HFI_PACKETIZATION_4XX ? "4xx packetization" : "Unknown hfi"); switch (type) { diff --git a/msm/vidc/hfi_packetization.h b/msm/vidc/hfi_packetization.h index d3bb415c27d7..95278637bd0b 100644 --- a/msm/vidc/hfi_packetization.h +++ b/msm/vidc/hfi_packetization.h @@ -30,7 +30,7 @@ struct hfi_packetization_ops { int (*sys_debug_config)(struct hfi_cmd_sys_set_property_packet *pkt, u32 mode); int (*sys_coverage_config)(struct hfi_cmd_sys_set_property_packet *pkt, - u32 mode); + u32 mode, u32 sid); int (*sys_release_resource)( struct hfi_cmd_sys_release_resource_packet *pkt, struct vidc_resource_hdr *resource_hdr); @@ -41,49 +41,38 @@ struct hfi_packetization_ops { struct hfi_cmd_sys_test_ssr_packet *pkt); int (*session_init)( struct hfi_cmd_sys_session_init_packet *pkt, - struct hal_session *session, - u32 session_domain, u32 session_codec); + u32 sid, u32 session_domain, u32 session_codec); int (*session_cmd)(struct vidc_hal_session_cmd_pkt *pkt, - int pkt_type, struct hal_session *session); + int pkt_type, u32 sid); int (*session_set_buffers)( struct hfi_cmd_session_set_buffers_packet *pkt, - struct hal_session *session, - struct vidc_buffer_addr_info *buffer_info); + u32 sid, struct vidc_buffer_addr_info *buffer_info); int (*session_release_buffers)( struct hfi_cmd_session_release_buffer_packet *pkt, - struct hal_session *session, - struct vidc_buffer_addr_info *buffer_info); + u32 sid, struct vidc_buffer_addr_info *buffer_info); int (*session_register_buffer)( struct hfi_cmd_session_register_buffers_packet *pkt, - struct hal_session *session, - struct vidc_register_buffer *buffer); + u32 sid, struct vidc_register_buffer *buffer); int (*session_unregister_buffer)( struct hfi_cmd_session_unregister_buffers_packet *pkt, - struct hal_session *session, - struct vidc_unregister_buffer *buffer); + u32 sid, struct vidc_unregister_buffer *buffer); int (*session_etb_decoder)( struct hfi_cmd_session_empty_buffer_compressed_packet *pkt, - struct hal_session *session, - struct vidc_frame_data *input_frame); + u32 sid, struct vidc_frame_data *input_frame); int (*session_etb_encoder)( struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet - *pkt, struct hal_session *session, - struct vidc_frame_data *input_frame); + *pkt, u32 sid, struct vidc_frame_data *input_frame); int (*session_ftb)(struct hfi_cmd_session_fill_buffer_packet *pkt, - struct hal_session *session, - struct vidc_frame_data *output_frame); + u32 sid, struct vidc_frame_data *output_frame); int (*session_get_buf_req)( - struct hfi_cmd_session_get_property_packet *pkt, - struct hal_session *session); + struct hfi_cmd_session_get_property_packet *pkt, u32 sid); int (*session_flush)(struct hfi_cmd_session_flush_packet *pkt, - struct hal_session *session, enum hal_flush flush_mode); + u32 sid, enum hal_flush flush_mode); int (*session_set_property)( struct hfi_cmd_session_set_property_packet *pkt, - struct hal_session *session, - u32 ptype, void *pdata, u32 size); + u32 sid, u32 ptype, void *pdata, u32 size); int (*session_sync_process)( - struct hfi_cmd_session_sync_process_packet *pkt, - struct hal_session *session); + struct hfi_cmd_session_sync_process_packet *pkt, u32 sid); }; struct hfi_packetization_ops *hfi_get_pkt_ops_handle( diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index d452a33515e7..81d833dc3920 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -79,22 +79,21 @@ static enum vidc_status hfi_map_err_status(u32 hfi_err) return vidc_err; } -static int get_hal_pixel_depth(u32 hfi_bit_depth) +static int get_hal_pixel_depth(u32 hfi_bit_depth, u32 sid) { switch (hfi_bit_depth) { case HFI_BITDEPTH_8: return MSM_VIDC_BIT_DEPTH_8; case HFI_BITDEPTH_9: case HFI_BITDEPTH_10: return MSM_VIDC_BIT_DEPTH_10; } - dprintk(VIDC_ERR, "Unsupported bit depth: %d\n", hfi_bit_depth); + s_vpr_e(sid, "Unsupported bit depth: %d\n", hfi_bit_depth); return MSM_VIDC_BIT_DEPTH_UNSUPPORTED; } static inline int validate_pkt_size(u32 rem_size, u32 msg_size) { if (rem_size < msg_size) { - dprintk(VIDC_ERR, "%s: bad_packet_size: %d\n", - __func__, rem_size); + d_vpr_e("%s: bad_packet_size: %d\n", __func__, rem_size); return false; } return true; @@ -117,13 +116,15 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, int prop_id; int luma_bit_depth, chroma_bit_depth; struct hfi_colour_space *colour_info; + u32 sid; if (!validate_pkt_size(pkt->size, sizeof(struct hfi_msg_event_notify_packet))) return -E2BIG; + sid = pkt->sid; event_notify.device_id = device_id; - event_notify.session_id = (void *)(uintptr_t)pkt->session_id; + event_notify.inst_id = (void *)(uintptr_t)pkt->sid; event_notify.status = VIDC_ERR_NONE; num_properties_changed = pkt->event_data2; switch (pkt->event_data1) { @@ -158,8 +159,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, (struct hfi_frame_size *) data_ptr; event_notify.width = frame_sz->width; event_notify.height = frame_sz->height; - dprintk(VIDC_HIGH|VIDC_PERF, - "height: %d width: %d\n", + s_vpr_hp(sid, "height: %d width: %d\n", frame_sz->height, frame_sz->width); data_ptr += sizeof(struct hfi_frame_size); @@ -174,8 +174,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, (struct hfi_profile_level *) data_ptr; event_notify.profile = profile_level->profile; event_notify.level = profile_level->level; - dprintk(VIDC_HIGH|VIDC_PERF, - "profile: %d level: %d\n", + s_vpr_hp(sid, "profile: %d level: %d\n", profile_level->profile, profile_level->level); data_ptr += @@ -200,10 +199,10 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, */ luma_bit_depth = get_hal_pixel_depth( pixel_depth->bit_depth & - GENMASK(15, 0)); + GENMASK(15, 0), sid); chroma_bit_depth = get_hal_pixel_depth( (pixel_depth->bit_depth & - GENMASK(31, 16)) >> 16); + GENMASK(31, 16)) >> 16, sid); if (luma_bit_depth == MSM_VIDC_BIT_DEPTH_10 || chroma_bit_depth == MSM_VIDC_BIT_DEPTH_10) @@ -211,7 +210,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, MSM_VIDC_BIT_DEPTH_10; else event_notify.bit_depth = luma_bit_depth; - dprintk(VIDC_HIGH|VIDC_PERF, + s_vpr_hp(sid, "bitdepth(%d), luma_bit_depth(%d), chroma_bit_depth(%d)\n", event_notify.bit_depth, luma_bit_depth, chroma_bit_depth); @@ -226,8 +225,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, pic_struct = (struct hfi_pic_struct *) data_ptr; event_notify.pic_struct = pic_struct->progressive_only; - dprintk(VIDC_HIGH|VIDC_PERF, - "Progressive only flag: %d\n", + s_vpr_hp(sid, "Progressive only flag: %d\n", pic_struct->progressive_only); data_ptr += sizeof(struct hfi_pic_struct); @@ -242,8 +240,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, (struct hfi_colour_space *) data_ptr; event_notify.colour_space = colour_info->colour_space; - dprintk(VIDC_HIGH, - "Colour space value is: %d\n", + s_vpr_h(sid, "Colour space value is: %d\n", colour_info->colour_space); data_ptr += sizeof(struct hfi_colour_space); @@ -255,8 +252,8 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, data_ptr = data_ptr + sizeof(u32); entropy_mode = *(u32 *)data_ptr; event_notify.entropy_mode = entropy_mode; - dprintk(VIDC_HIGH|VIDC_PERF, - "Entropy Mode: 0x%x\n", entropy_mode); + s_vpr_hp(sid, "Entropy Mode: 0x%x\n", + entropy_mode); data_ptr += sizeof(u32); rem_size -= sizeof(u32); @@ -271,8 +268,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, data_ptr; event_notify.capture_buf_count = buf_req->buffer_count_min; - dprintk(VIDC_HIGH|VIDC_PERF, - "Capture Count : 0x%x\n", + s_vpr_hp(sid, "Capture Count : 0x%x\n", event_notify.capture_buf_count); data_ptr += sizeof(struct hfi_buffer_requirements); @@ -292,14 +288,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, event_notify.crop_data.width = crop_info->width; event_notify.crop_data.height = crop_info->height; - dprintk(VIDC_HIGH, + s_vpr_h(sid, "CROP info : Left = %d Top = %d\n", - crop_info->left, - crop_info->top); - dprintk(VIDC_HIGH, + crop_info->left, crop_info->top); + s_vpr_h(sid, "CROP info : Width = %d Height = %d\n", - crop_info->width, - crop_info->height); + crop_info->width, crop_info->height); data_ptr += sizeof(struct hfi_index_extradata_input_crop_payload); @@ -307,8 +301,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, hfi_index_extradata_input_crop_payload); break; default: - dprintk(VIDC_ERR, - "%s cmd: %#x not supported\n", + s_vpr_e(sid, "%s: cmd: %#x not supported\n", __func__, prop_id); break; } @@ -329,25 +322,24 @@ static int hfi_process_evt_release_buffer_ref(u32 device_id, struct msm_vidc_cb_event event_notify = {0}; struct hfi_msg_release_buffer_ref_event_packet *data; - dprintk(VIDC_LOW, - "RECEIVED: EVENT_NOTIFY - release_buffer_reference\n"); if (sizeof(struct hfi_msg_event_notify_packet) > pkt->size) { - dprintk(VIDC_ERR, "%s: bad_pkt_size\n", __func__); + d_vpr_e("%s: bad_pkt_size\n", __func__); return -E2BIG; } if (pkt->size < sizeof(struct hfi_msg_event_notify_packet) - sizeof(u32) + sizeof(struct hfi_msg_release_buffer_ref_event_packet)) { - dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", - __func__, pkt->size); + d_vpr_e("%s: bad_pkt_size: %d\n", __func__, pkt->size); return -E2BIG; } data = (struct hfi_msg_release_buffer_ref_event_packet *) pkt->rg_ext_event_data; + s_vpr_l(pkt->sid, + "RECEIVED: EVENT_NOTIFY - release_buffer_reference\n"); event_notify.device_id = device_id; - event_notify.session_id = (void *)(uintptr_t)pkt->session_id; + event_notify.inst_id = (void *)(uintptr_t)pkt->sid; event_notify.status = VIDC_ERR_NONE; event_notify.hal_event_type = HAL_EVENT_RELEASE_BUFFER_REFERENCE; event_notify.packet_buffer = data->packet_buffer; @@ -379,24 +371,24 @@ static int hfi_process_session_error(u32 device_id, struct msm_vidc_cb_info *info) { struct msm_vidc_cb_cmd_done cmd_done = {0}; + u32 sid = pkt->sid; cmd_done.device_id = device_id; - cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; cmd_done.status = hfi_map_err_status(pkt->event_data1); info->response.cmd = cmd_done; - dprintk(VIDC_HIGH, "Received: SESSION_ERROR with event id : %#x %#x\n", + s_vpr_h(sid, "RECEIVED: SESSION_ERROR with event id : %#x %#x\n", pkt->event_data1, pkt->event_data2); switch (pkt->event_data1) { /* Ignore below errors */ case HFI_ERR_SESSION_INVALID_SCALE_FACTOR: case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED: - dprintk(VIDC_HIGH, "Non Fatal: HFI_EVENT_SESSION_ERROR\n"); + s_vpr_h(sid, "Non Fatal: HFI_EVENT_SESSION_ERROR\n"); info->response_type = HAL_RESPONSE_UNUSED; break; default: - dprintk(VIDC_ERR, - "%s: session %x data1 %#x, data2 %#x\n", __func__, - pkt->session_id, pkt->event_data1, pkt->event_data2); + s_vpr_e(sid, "%s: data1 %#x, data2 %#x\n", __func__, + pkt->event_data1, pkt->event_data2); info->response_type = HAL_SESSION_ERROR; break; } @@ -409,31 +401,30 @@ static int hfi_process_event_notify(u32 device_id, struct msm_vidc_cb_info *info) { struct hfi_msg_event_notify_packet *pkt = _pkt; - dprintk(VIDC_LOW, "Received: EVENT_NOTIFY\n"); if (pkt->size < sizeof(struct hfi_msg_event_notify_packet)) { - dprintk(VIDC_ERR, "Invalid Params\n"); + d_vpr_e("%s: invalid params %u %u\n", __func__, + pkt->size, sizeof(struct hfi_msg_event_notify_packet)); return -E2BIG; } + s_vpr_l(pkt->sid, "RECEIVED: EVENT_NOTIFY\n"); + switch (pkt->event_id) { case HFI_EVENT_SYS_ERROR: - dprintk(VIDC_ERR, "HFI_EVENT_SYS_ERROR: %d, %#x\n", + s_vpr_e(pkt->sid, "HFI_EVENT_SYS_ERROR: %d, %#x\n", pkt->event_data1, pkt->event_data2); return hfi_process_sys_error(device_id, pkt, info); case HFI_EVENT_SESSION_ERROR: - dprintk(VIDC_HIGH, "HFI_EVENT_SESSION_ERROR[%#x]\n", - pkt->session_id); + s_vpr_h(pkt->sid, "HFI_EVENT_SESSION_ERROR\n"); return hfi_process_session_error(device_id, pkt, info); case HFI_EVENT_SESSION_SEQUENCE_CHANGED: - dprintk(VIDC_HIGH, "HFI_EVENT_SESSION_SEQUENCE_CHANGED[%#x]\n", - pkt->session_id); + s_vpr_h(pkt->sid, "HFI_EVENT_SESSION_SEQUENCE_CHANGED\n"); return hfi_process_sess_evt_seq_changed(device_id, pkt, info); case HFI_EVENT_RELEASE_BUFFER_REFERENCE: - dprintk(VIDC_LOW, "HFI_EVENT_RELEASE_BUFFER_REFERENCE[%#x]\n", - pkt->session_id); + s_vpr_l(pkt->sid, "HFI_EVENT_RELEASE_BUFFER_REFERENCE\n"); return hfi_process_evt_release_buffer_ref(device_id, pkt, info); case HFI_EVENT_SESSION_PROPERTY_CHANGED: @@ -454,19 +445,19 @@ static int hfi_process_sys_init_done(u32 device_id, struct msm_vidc_cb_cmd_done cmd_done = {0}; enum vidc_status status = VIDC_ERR_NONE; - dprintk(VIDC_HIGH, "RECEIVED: SYS_INIT_DONE\n"); if (sizeof(struct hfi_msg_sys_init_done_packet) > pkt->size) { - dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", __func__, + d_vpr_e("%s: bad_pkt_size: %d\n", __func__, pkt->size); return -E2BIG; } + d_vpr_h("RECEIVED: SYS_INIT_DONE\n"); + status = hfi_map_err_status(pkt->error_type); if (status) - dprintk(VIDC_ERR, "%s: status %#x\n", - __func__, status); + d_vpr_e("%s: status %#x\n", __func__, status); cmd_done.device_id = device_id; - cmd_done.session_id = NULL; + cmd_done.inst_id = NULL; cmd_done.status = (u32)status; cmd_done.size = sizeof(struct vidc_hal_sys_init_done); @@ -485,18 +476,17 @@ static int hfi_process_sys_rel_resource_done(u32 device_id, enum vidc_status status = VIDC_ERR_NONE; u32 pkt_size; - dprintk(VIDC_HIGH, "RECEIVED: SYS_RELEASE_RESOURCE_DONE\n"); pkt_size = sizeof(struct hfi_msg_sys_release_resource_done_packet); if (pkt_size > pkt->size) { - dprintk(VIDC_ERR, - "hal_process_sys_rel_resource_done: bad size: %d\n", + d_vpr_e("hal_process_sys_rel_resource_done: bad size: %d\n", pkt->size); return -E2BIG; } + d_vpr_h("RECEIVED: SYS_RELEASE_RESOURCE_DONE\n"); status = hfi_map_err_status(pkt->error_type); cmd_done.device_id = device_id; - cmd_done.session_id = NULL; + cmd_done.inst_id = NULL; cmd_done.status = (u32) status; cmd_done.size = 0; @@ -508,15 +498,13 @@ static int hfi_process_sys_rel_resource_done(u32 device_id, static void hfi_process_sess_get_prop_buf_req( struct hfi_msg_session_property_info_packet *prop, - struct buffer_requirements *buffreq) + struct buffer_requirements *buffreq, u32 sid) { struct hfi_buffer_requirements *hfi_buf_req; u32 req_bytes; if (!prop) { - dprintk(VIDC_ERR, - "hal_process_sess_get_prop_buf_req: bad_prop: %pK\n", - prop); + s_vpr_e(sid, "%s: bad_prop: %pK\n", __func__, prop); return; } @@ -524,9 +512,7 @@ static void hfi_process_sess_get_prop_buf_req( struct hfi_msg_session_property_info_packet); if (!req_bytes || req_bytes % sizeof(struct hfi_buffer_requirements) || !prop->rg_property_data[1]) { - dprintk(VIDC_ERR, - "hal_process_sess_get_prop_buf_req: bad_pkt: %d\n", - req_bytes); + s_vpr_e(sid, "%s: bad_pkt: %d\n", __func__, req_bytes); return; } @@ -534,13 +520,12 @@ static void hfi_process_sess_get_prop_buf_req( &prop->rg_property_data[1]; if (!hfi_buf_req) { - dprintk(VIDC_ERR, "%s - invalid buffer req pointer\n", - __func__); + s_vpr_e(sid, "%s: invalid buffer req pointer\n", __func__); return; } while (req_bytes) { - dprintk(VIDC_HIGH, "got buffer requirements for: %d\n", + s_vpr_h(sid, "got buffer requirements for: %d\n", hfi_buf_req->buffer_type); switch (hfi_buf_req->buffer_type) { case HFI_BUFFER_INPUT: @@ -613,9 +598,8 @@ static void hfi_process_sess_get_prop_buf_req( HAL_BUFFER_INTERNAL_RECON; break; default: - dprintk(VIDC_ERR, - "hal_process_sess_get_prop_buf_req: bad_buffer_type: %d\n", - hfi_buf_req->buffer_type); + s_vpr_e(sid, "%s: bad_buffer_type: %d\n", + __func__, hfi_buf_req->buffer_type); break; } req_bytes -= sizeof(struct hfi_buffer_requirements); @@ -631,24 +615,20 @@ static int hfi_process_session_prop_info(u32 device_id, struct msm_vidc_cb_cmd_done cmd_done = {0}; struct buffer_requirements buff_req = { { {0} } }; - dprintk(VIDC_HIGH, "Received SESSION_PROPERTY_INFO[%#x]\n", - pkt->session_id); - if (pkt->size < sizeof(struct hfi_msg_session_property_info_packet)) { - dprintk(VIDC_ERR, - "hal_process_session_prop_info: bad_pkt_size\n"); + d_vpr_e("hal_process_session_prop_info: bad_pkt_size\n"); return -E2BIG; } else if (!pkt->num_properties) { - dprintk(VIDC_ERR, - "hal_process_session_prop_info: no_properties\n"); + d_vpr_e("hal_process_session_prop_info: no_properties\n"); return -EINVAL; } + s_vpr_h(pkt->sid, "Received SESSION_PROPERTY_INFO\n"); switch (pkt->rg_property_data[0]) { case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS: - hfi_process_sess_get_prop_buf_req(pkt, &buff_req); + hfi_process_sess_get_prop_buf_req(pkt, &buff_req, pkt->sid); cmd_done.device_id = device_id; - cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; cmd_done.status = VIDC_ERR_NONE; cmd_done.data.property.buf_req = buff_req; cmd_done.size = sizeof(buff_req); @@ -658,9 +638,8 @@ static int hfi_process_session_prop_info(u32 device_id, return 0; default: - dprintk(VIDC_HIGH, - "hal_process_session_prop_info: unknown_prop_id: %x\n", - pkt->rg_property_data[0]); + s_vpr_h(pkt->sid, "%s: unknown_prop_id: %x\n", + __func__, pkt->rg_property_data[0]); return -ENOTSUPP; } } @@ -672,16 +651,14 @@ static int hfi_process_session_init_done(u32 device_id, struct hfi_msg_sys_session_init_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_HIGH, "RECEIVED: SESSION_INIT_DONE[%x]\n", pkt->session_id); - if (sizeof(struct hfi_msg_sys_session_init_done_packet) > pkt->size) { - dprintk(VIDC_ERR, - "hal_process_session_init_done: bad_pkt_size\n"); + d_vpr_e("hal_process_session_init_done: bad_pkt_size\n"); return -E2BIG; } + s_vpr_h(pkt->sid, "RECEIVED: SESSION_INIT_DONE\n"); cmd_done.device_id = device_id; - cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; cmd_done.status = hfi_map_err_status(pkt->error_type); info->response_type = HAL_SESSION_INIT_DONE; @@ -697,19 +674,15 @@ static int hfi_process_session_load_res_done(u32 device_id, struct hfi_msg_session_load_resources_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_HIGH, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%#x]\n", - pkt->session_id); - if (sizeof(struct hfi_msg_session_load_resources_done_packet) != pkt->size) { - dprintk(VIDC_ERR, - "hal_process_session_load_res_done: bad packet size: %d\n", - pkt->size); + d_vpr_e("%s: bad packet size: %d\n", __func__, pkt->size); return -E2BIG; } + s_vpr_h(pkt->sid, "RECEIVED: SESSION_LOAD_RESOURCES_DONE\n"); cmd_done.device_id = device_id; - cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; cmd_done.status = hfi_map_err_status(pkt->error_type); cmd_done.size = 0; @@ -726,18 +699,15 @@ static int hfi_process_session_flush_done(u32 device_id, struct hfi_msg_session_flush_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_HIGH, "RECEIVED: SESSION_FLUSH_DONE[%#x]\n", - pkt->session_id); - if (sizeof(struct hfi_msg_session_flush_done_packet) != pkt->size) { - dprintk(VIDC_ERR, - "hal_process_session_flush_done: bad packet size: %d\n", + d_vpr_e("hal_process_session_flush_done: bad packet size: %d\n", pkt->size); return -E2BIG; } + s_vpr_h(pkt->sid, "RECEIVED: SESSION_FLUSH_DONE\n"); cmd_done.device_id = device_id; - cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; cmd_done.status = hfi_map_err_status(pkt->error_type); cmd_done.size = sizeof(u32); @@ -752,8 +722,7 @@ static int hfi_process_session_flush_done(u32 device_id, cmd_done.data.flush_type = HAL_FLUSH_ALL; break; default: - dprintk(VIDC_ERR, - "%s: invalid flush type!", __func__); + s_vpr_e(pkt->sid, "%s: invalid flush type!", __func__); return -EINVAL; } @@ -770,14 +739,14 @@ static int hfi_process_session_etb_done(u32 device_id, struct hfi_msg_session_empty_buffer_done_packet *pkt = _pkt; struct msm_vidc_cb_data_done data_done = {0}; - dprintk(VIDC_LOW, "RECEIVED: SESSION_ETB_DONE[%#x]\n", pkt->session_id); - if (!pkt || pkt->size < sizeof(struct hfi_msg_session_empty_buffer_done_packet)) goto bad_packet_size; + s_vpr_l(pkt->sid, "RECEIVED: SESSION_ETB_DONE\n"); + data_done.device_id = device_id; - data_done.session_id = (void *)(uintptr_t)pkt->session_id; + data_done.inst_id = (void *)(uintptr_t)pkt->sid; data_done.status = hfi_map_err_status(pkt->error_type); data_done.size = sizeof(struct msm_vidc_cb_data_done); data_done.input_done.input_tag = pkt->input_tag; @@ -805,7 +774,7 @@ static int hfi_process_session_etb_done(u32 device_id, return 0; bad_packet_size: - dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", + d_vpr_e("%s: ebd - bad_pkt_size: %d\n", __func__, pkt ? pkt->size : 0); return -E2BIG; } @@ -819,7 +788,7 @@ static int hfi_process_session_ftb_done( bool is_decoder = false, is_encoder = false; if (!msg_hdr) { - dprintk(VIDC_ERR, "Invalid Params\n"); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -829,7 +798,7 @@ static int hfi_process_session_ftb_done( hfi_msg_session_fbd_uncompressed_plane0_packet) + 4; if (!(is_encoder ^ is_decoder)) { - dprintk(VIDC_ERR, "Ambiguous packet (%#x) received (size %d)\n", + d_vpr_e("Ambiguous packet (%#x) received (size %d)\n", msg_hdr->packet, msg_hdr->size); return -EBADHANDLE; } @@ -838,23 +807,20 @@ static int hfi_process_session_ftb_done( struct hfi_msg_session_fill_buffer_done_compressed_packet *pkt = (struct hfi_msg_session_fill_buffer_done_compressed_packet *) msg_hdr; - dprintk(VIDC_LOW, "RECEIVED: SESSION_FTB_DONE[%#x]\n", - pkt->session_id); if (sizeof(struct hfi_msg_session_fill_buffer_done_compressed_packet) > pkt->size) { - dprintk(VIDC_ERR, - "hal_process_session_ftb_done: bad_pkt_size\n"); + d_vpr_e("hal_process_session_ftb_done: bad_pkt_size\n"); return -E2BIG; } else if (pkt->error_type != HFI_ERR_NONE) { - dprintk(VIDC_ERR, - "got buffer back with error %x\n", + s_vpr_e(pkt->sid, "got buffer back with error %x\n", pkt->error_type); /* Proceed with the FBD */ } + s_vpr_l(pkt->sid, "RECEIVED: SESSION_FTB_DONE\n"); data_done.device_id = device_id; - data_done.session_id = (void *)(uintptr_t)pkt->session_id; + data_done.inst_id = (void *)(uintptr_t)pkt->sid; data_done.status = hfi_map_err_status(pkt->error_type); data_done.size = sizeof(struct msm_vidc_cb_data_done); @@ -875,19 +841,16 @@ static int hfi_process_session_ftb_done( struct hfi_msg_session_fbd_uncompressed_plane0_packet *pkt = (struct hfi_msg_session_fbd_uncompressed_plane0_packet *) msg_hdr; - - dprintk(VIDC_LOW, "RECEIVED: SESSION_FTB_DONE[%#x]\n", - pkt->session_id); if (sizeof( struct hfi_msg_session_fbd_uncompressed_plane0_packet) > pkt->size) { - dprintk(VIDC_ERR, - "hal_process_session_ftb_done: bad_pkt_size\n"); + d_vpr_e("hal_process_session_ftb_done: bad_pkt_size\n"); return -E2BIG; } + s_vpr_l(pkt->sid, "RECEIVED: SESSION_FTB_DONE\n"); data_done.device_id = device_id; - data_done.session_id = (void *)(uintptr_t)pkt->session_id; + data_done.inst_id = (void *)(uintptr_t)pkt->sid; data_done.status = hfi_map_err_status(pkt->error_type); data_done.size = sizeof(struct msm_vidc_cb_data_done); @@ -938,18 +901,15 @@ static int hfi_process_session_start_done(u32 device_id, struct hfi_msg_session_start_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_HIGH, "RECEIVED: SESSION_START_DONE[%#x]\n", - pkt->session_id); - if (!pkt || pkt->size != sizeof(struct hfi_msg_session_start_done_packet)) { - dprintk(VIDC_ERR, "%s: bad packet/packet size\n", - __func__); + d_vpr_e("%s: bad packet/packet size\n", __func__); return -E2BIG; } + s_vpr_h(pkt->sid, "RECEIVED: SESSION_START_DONE\n"); cmd_done.device_id = device_id; - cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; cmd_done.status = hfi_map_err_status(pkt->error_type); cmd_done.size = 0; @@ -965,18 +925,15 @@ static int hfi_process_session_stop_done(u32 device_id, struct hfi_msg_session_stop_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_HIGH, "RECEIVED: SESSION_STOP_DONE[%#x]\n", - pkt->session_id); - if (!pkt || pkt->size != sizeof(struct hfi_msg_session_stop_done_packet)) { - dprintk(VIDC_ERR, "%s: bad packet/packet size\n", - __func__); + d_vpr_e("%s: bad packet/packet size\n", __func__); return -E2BIG; } + s_vpr_h(pkt->sid, "RECEIVED: SESSION_STOP_DONE\n"); cmd_done.device_id = device_id; - cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; cmd_done.status = hfi_map_err_status(pkt->error_type); cmd_done.size = 0; @@ -993,18 +950,15 @@ static int hfi_process_session_rel_res_done(u32 device_id, struct hfi_msg_session_release_resources_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_HIGH, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%#x]\n", - pkt->session_id); - if (!pkt || pkt->size != sizeof(struct hfi_msg_session_release_resources_done_packet)) { - dprintk(VIDC_ERR, "%s: bad packet/packet size\n", - __func__); + d_vpr_e("%s: bad packet/packet size\n", __func__); return -E2BIG; } + s_vpr_h(pkt->sid, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE\n"); cmd_done.device_id = device_id; - cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; cmd_done.status = hfi_map_err_status(pkt->error_type); cmd_done.size = 0; @@ -1023,16 +977,15 @@ static int hfi_process_session_rel_buf_done(u32 device_id, if (!pkt || pkt->size < sizeof(struct hfi_msg_session_release_buffers_done_packet)) { - dprintk(VIDC_ERR, "bad packet/packet size %d\n", + d_vpr_e("bad packet/packet size %d\n", pkt ? pkt->size : 0); return -E2BIG; } - dprintk(VIDC_HIGH, "RECEIVED:SESSION_RELEASE_BUFFER_DONE[%#x]\n", - pkt->session_id); + s_vpr_h(pkt->sid, "RECEIVED:SESSION_RELEASE_BUFFER_DONE\n"); cmd_done.device_id = device_id; cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done); - cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; cmd_done.status = hfi_map_err_status(pkt->error_type); cmd_done.data.buffer_info.buffer_addr = *pkt->rg_buffer_info; cmd_done.size = sizeof(struct hal_buffer_info); @@ -1052,16 +1005,15 @@ static int hfi_process_session_register_buffer_done(u32 device_id, if (!pkt || pkt->size < sizeof(struct hfi_msg_session_register_buffers_done_packet)) { - dprintk(VIDC_ERR, "%s: bad packet/packet size %d\n", + d_vpr_e("%s: bad packet/packet size %d\n", __func__, pkt ? pkt->size : 0); return -E2BIG; } - dprintk(VIDC_HIGH, "RECEIVED: SESSION_REGISTER_BUFFERS_DONE[%#x]\n", - pkt->session_id); + s_vpr_h(pkt->sid, "RECEIVED: SESSION_REGISTER_BUFFERS_DONE\n"); cmd_done.device_id = device_id; cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done); - cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; cmd_done.status = hfi_map_err_status(pkt->error_type); cmd_done.data.regbuf.client_data = pkt->client_data; @@ -1080,16 +1032,15 @@ static int hfi_process_session_unregister_buffer_done(u32 device_id, if (!pkt || pkt->size < sizeof(struct hfi_msg_session_unregister_buffers_done_packet)) { - dprintk(VIDC_ERR, "%s: bad packet/packet size %d\n", + d_vpr_e("%s: bad packet/packet size %d\n", __func__, pkt ? pkt->size : 0); return -E2BIG; } - dprintk(VIDC_HIGH, "RECEIVED: SESSION_UNREGISTER_BUFFERS_DONE[%#x]\n", - pkt->session_id); + s_vpr_h(pkt->sid, "RECEIVED: SESSION_UNREGISTER_BUFFERS_DONE\n"); cmd_done.device_id = device_id; cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done); - cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; cmd_done.status = hfi_map_err_status(pkt->error_type); cmd_done.data.unregbuf.client_data = pkt->client_data; @@ -1106,16 +1057,15 @@ static int hfi_process_session_end_done(u32 device_id, struct hfi_msg_sys_session_end_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_HIGH, "RECEIVED: SESSION_END_DONE[%#x]\n", pkt->session_id); - if (!pkt || pkt->size != sizeof(struct hfi_msg_sys_session_end_done_packet)) { - dprintk(VIDC_ERR, "%s: bad packet/packet size\n", __func__); + d_vpr_e("%s: bad packet/packet size\n", __func__); return -E2BIG; } + s_vpr_h(pkt->sid, "RECEIVED: SESSION_END_DONE\n"); cmd_done.device_id = device_id; - cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; cmd_done.status = hfi_map_err_status(pkt->error_type); cmd_done.size = 0; @@ -1132,17 +1082,15 @@ static int hfi_process_session_abort_done(u32 device_id, struct hfi_msg_sys_session_abort_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_HIGH, "RECEIVED: SESSION_ABORT_DONE[%#x]\n", - pkt->session_id); - if (!pkt || pkt->size != sizeof(struct hfi_msg_sys_session_abort_done_packet)) { - dprintk(VIDC_ERR, "%s: bad packet/packet size: %d\n", + d_vpr_e("%s: bad packet/packet size: %d\n", __func__, pkt ? pkt->size : 0); return -E2BIG; } + s_vpr_h(pkt->sid, "RECEIVED: SESSION_ABORT_DONE\n"); cmd_done.device_id = device_id; - cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; cmd_done.status = hfi_map_err_status(pkt->error_type); cmd_done.size = 0; @@ -1168,7 +1116,7 @@ static void hfi_process_sys_get_prop_image_version( if (req_bytes < version_string_size || !pkt->rg_property_data[1] || pkt->num_properties > 1) { - dprintk(VIDC_ERR, "%s: bad_pkt: %d\n", __func__, req_bytes); + d_vpr_e("%s: bad_pkt: %d\n", __func__, req_bytes); return; } str_image_version = (u8 *)&pkt->rg_property_data[1]; @@ -1184,7 +1132,7 @@ static void hfi_process_sys_get_prop_image_version( version[i] = ' '; } version[i] = '\0'; - dprintk(VIDC_HIGH, "F/W version: %s\n", version); + d_vpr_h("F/W version: %s\n", version); smem_table_ptr = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_IMAGE_VERSION_TABLE, &smem_block_size); @@ -1200,15 +1148,13 @@ static int hfi_process_sys_property_info(u32 device_id, { struct hfi_msg_sys_property_info_packet *pkt = _pkt; if (!pkt) { - dprintk(VIDC_ERR, "%s: invalid param\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } else if (pkt->size < sizeof(*pkt)) { - dprintk(VIDC_ERR, - "%s: bad_pkt_size\n", __func__); + d_vpr_e("%s: bad_pkt_size\n", __func__); return -E2BIG; } else if (!pkt->num_properties) { - dprintk(VIDC_ERR, - "%s: no_properties\n", __func__); + d_vpr_e("%s: no_properties\n", __func__); return -EINVAL; } @@ -1221,8 +1167,7 @@ static int hfi_process_sys_property_info(u32 device_id, }; return 0; default: - dprintk(VIDC_HIGH, - "%s: unknown_prop_id: %x\n", + d_vpr_h("%s: unknown_prop_id: %x\n", __func__, pkt->rg_property_data[0]); return -ENOTSUPP; } @@ -1236,6 +1181,7 @@ static int hfi_process_ignore(u32 device_id, *info = (struct msm_vidc_cb_info) { .response_type = HAL_RESPONSE_UNUSED, }; + d_vpr_h("RECEIVED: SESSION_SYNC_DONE\n"); return 0; } @@ -1247,17 +1193,15 @@ int hfi_process_msg_packet(u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr, pkt_func_def pkt_func = NULL; if (!info || !msg_hdr || msg_hdr->size < VIDC_IFACEQ_MIN_PKT_SIZE) { - dprintk(VIDC_ERR, "%s: bad packet/packet size\n", - __func__); + d_vpr_e("%s: bad packet/packet size\n", __func__); return -EINVAL; } - dprintk(VIDC_LOW, "Parse response %#x\n", msg_hdr->packet); switch (msg_hdr->packet) { case HFI_MSG_EVENT_NOTIFY: pkt_func = (pkt_func_def)hfi_process_event_notify; break; - case HFI_MSG_SYS_INIT_DONE: + case HFI_MSG_SYS_INIT_DONE: pkt_func = (pkt_func_def)hfi_process_sys_init_done; break; case HFI_MSG_SYS_SESSION_INIT_DONE: @@ -1314,8 +1258,7 @@ int hfi_process_msg_packet(u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr, pkt_func = (pkt_func_def)hfi_process_ignore; break; default: - dprintk(VIDC_LOW, "Unable to parse message: %#x\n", - msg_hdr->packet); + d_vpr_l("Unable to parse message: %#x\n", msg_hdr->packet); break; } diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index 730e4b5e2983..5fb23bbe1c5a 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -19,17 +19,18 @@ static void print_cvp_buffer(u32 tag, const char *str, return; cvp = inst->cvp; - dprintk(tag, + dprintk(tag, inst->sid, "%s: %x : idx %d fd %d size %d offset %d dbuf %pK kvaddr %pK\n", - str, cvp->session_id, cbuf->index, cbuf->fd, cbuf->size, + str, cvp->sid, cbuf->index, cbuf->fd, cbuf->size, cbuf->offset, cbuf->dbuf, cbuf->kvaddr); } static int fill_cvp_buffer(struct msm_cvp_buffer_type *dst, - struct msm_cvp_buf *src) + struct msm_cvp_buf *src, u32 sid) { if (!dst || !src) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + s_vpr_e(sid, "%s: invalid params %pK %pK\n", + __func__, dst, src); return -EINVAL; } @@ -50,8 +51,9 @@ static int msm_cvp_get_version_info(struct msm_vidc_inst *inst) struct cvp_kmd_sys_property *prop_data; u32 version; + if (!inst || !inst->cvp) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; @@ -66,11 +68,11 @@ static int msm_cvp_get_version_info(struct msm_vidc_inst *inst) prop_data->prop_type = CVP_KMD_HFI_VERSION_PROP_TYPE; rc = msm_cvp_private(cvp->priv, CVP_KMD_GET_SYS_PROPERTY, arg); if (rc) { - dprintk(VIDC_ERR, "%s: failed, rc %d\n", __func__, rc); + s_vpr_e(inst->sid, "%s: failed, rc %d\n", __func__, rc); return rc; } version = prop_data->data; - dprintk(VIDC_HIGH, "%s: version %#x\n", __func__, version); + s_vpr_h(inst->sid, "%s: version %#x\n", __func__, version); return 0; } @@ -84,7 +86,7 @@ static int msm_cvp_set_priority(struct msm_vidc_inst *inst) struct cvp_kmd_sys_property *prop_array; if (!inst || !inst->cvp) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; @@ -101,10 +103,10 @@ static int msm_cvp_set_priority(struct msm_vidc_inst *inst) prop_array[0].data = VIDEO_REALTIME; else prop_array[0].data = VIDEO_NONREALTIME; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, prop_array[0].data); + s_vpr_h(inst->sid, "%s: %d\n", __func__, prop_array[0].data); rc = msm_cvp_private(cvp->priv, CVP_KMD_SET_SYS_PROPERTY, arg); if (rc) { - dprintk(VIDC_ERR, "%s: failed, rc %d\n", __func__, rc); + s_vpr_e(inst->sid, "%s: failed, rc %d\n", __func__, rc); return rc; } @@ -112,7 +114,7 @@ static int msm_cvp_set_priority(struct msm_vidc_inst *inst) } static int msm_cvp_fill_planeinfo(struct msm_cvp_color_plane_info *plane_info, - u32 color_fmt, u32 width, u32 height) + u32 color_fmt, u32 width, u32 height, u32 sid) { int rc = 0; u32 y_stride, y_sclines, uv_stride, uv_sclines; @@ -169,7 +171,7 @@ static int msm_cvp_fill_planeinfo(struct msm_cvp_color_plane_info *plane_info, break; } default: - dprintk(VIDC_ERR, "%s: invalid color_fmt %#x\n", + s_vpr_e(sid, "%s: invalid color_fmt %#x\n", __func__, color_fmt); rc = -EINVAL; break; @@ -184,7 +186,8 @@ static int msm_cvp_free_buffer(struct msm_vidc_inst *inst, struct msm_cvp_external *cvp; if (!inst || !inst->cvp || !buffer) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, inst, buffer); return -EINVAL; } cvp = inst->cvp; @@ -210,7 +213,8 @@ static int msm_cvp_allocate_buffer(struct msm_vidc_inst *inst, struct dma_buf *dbuf; if (!inst || !inst->cvp || !buffer) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, inst, buffer); return -EINVAL; } cvp = inst->cvp; @@ -223,7 +227,7 @@ static int msm_cvp_allocate_buffer(struct msm_vidc_inst *inst, dbuf = ion_alloc(buffer->size, heap_mask, ion_flags); if (IS_ERR_OR_NULL(dbuf)) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: failed to allocate, size %d heap_mask %#lx flags %d\n", __func__, buffer->size, heap_mask, ion_flags); rc = -ENOMEM; @@ -235,7 +239,7 @@ static int msm_cvp_allocate_buffer(struct msm_vidc_inst *inst, if (kernel_map) { buffer->kvaddr = dma_buf_vmap(dbuf); if (!buffer->kvaddr) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: dma_buf_vmap failed\n", __func__); rc = -EINVAL; goto error; @@ -263,7 +267,7 @@ static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst) const u32 fps_max = CVP_FRAME_RATE_MAX; if (!inst || !inst->cvp) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; @@ -279,14 +283,15 @@ static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst) desc.is_downscale = cvp->downscale; desc.fps = min(cvp->frame_rate >> 16, fps_max); desc.op_rate = cvp->operating_rate >> 16; - desc.colorfmt = msm_comm_convert_color_fmt(fmt->fmt.pix_mp.pixelformat); + desc.colorfmt = + msm_comm_convert_color_fmt(fmt->fmt.pix_mp.pixelformat, + inst->sid); rc = msm_cvp_est_cycles(&desc, &power); if (rc) { - dprintk(VIDC_ERR, "%s: estimate failed\n", __func__); + s_vpr_e(inst->sid, "%s: estimate failed\n", __func__); return rc; } - dprintk(VIDC_HIGH, - "%s: core %d controller %d ddr bw %d\n", + s_vpr_h(inst->sid, "%s: core %d controller %d ddr bw %d\n", __func__, power.clock_cycles_a, power.clock_cycles_b, power.ddr_bw); @@ -296,8 +301,8 @@ static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst) sizeof(struct cvp_kmd_request_power)); rc = msm_cvp_private(cvp->priv, CVP_KMD_REQUEST_POWER, arg); if (rc) { - dprintk(VIDC_ERR, - "%s: request_power failed with %d\n", __func__, rc); + s_vpr_e(inst->sid, "%s: request_power failed with %d\n", + __func__, rc); return rc; } @@ -311,7 +316,7 @@ static int msm_cvp_init_downscale_resolution(struct msm_vidc_inst *inst) u32 width, height, ds_width, ds_height, temp; if (!inst || !inst->cvp) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; @@ -320,7 +325,7 @@ static int msm_cvp_init_downscale_resolution(struct msm_vidc_inst *inst) ds_height = cvp->height; if (!cvp->downscale) { - dprintk(VIDC_HIGH, "%s: downscaling not enabled\n", __func__); + s_vpr_h(inst->sid, "%s: downscaling not enabled\n", __func__); goto exit; } @@ -369,11 +374,11 @@ static void msm_cvp_deinit_downscale_buffers(struct msm_vidc_inst *inst) struct msm_cvp_external *cvp; if (!inst || !inst->cvp) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return; } cvp = inst->cvp; - dprintk(VIDC_HIGH, "%s:\n", __func__); + s_vpr_h(inst->sid, "%s:\n", __func__); if (cvp->src_buffer.dbuf) { print_cvp_buffer(VIDC_HIGH, "free: src_buffer", @@ -399,16 +404,16 @@ static int msm_cvp_init_downscale_buffers(struct msm_vidc_inst *inst) struct msm_cvp_external *cvp; if (!inst || !inst->cvp) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; if (!cvp->downscale) { - dprintk(VIDC_HIGH, "%s: downscaling not enabled\n", __func__); + s_vpr_h(inst->sid, "%s: downscaling not enabled\n", __func__); return 0; } - dprintk(VIDC_HIGH, "%s:\n", __func__); + s_vpr_h(inst->sid, "%s:\n", __func__); cvp->src_buffer.size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, cvp->ds_width, cvp->ds_height); @@ -445,11 +450,11 @@ static void msm_cvp_deinit_context_buffers(struct msm_vidc_inst *inst) struct msm_cvp_external *cvp; if (!inst || !inst->cvp) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return; } cvp = inst->cvp; - dprintk(VIDC_HIGH, "%s:\n", __func__); + s_vpr_h(inst->sid, "%s:\n", __func__); if (cvp->context_buffer.dbuf) { print_cvp_buffer(VIDC_HIGH, "free: context_buffer", @@ -475,11 +480,11 @@ static int msm_cvp_init_context_buffers(struct msm_vidc_inst *inst) struct msm_cvp_external *cvp; if (!inst || !inst->cvp) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; - dprintk(VIDC_HIGH, "%s:\n", __func__); + s_vpr_h(inst->sid, "%s:\n", __func__); cvp->context_buffer.size = HFI_DME_FRAME_CONTEXT_BUFFER_SIZE; rc = msm_cvp_allocate_buffer(inst, &cvp->context_buffer, false); @@ -516,12 +521,12 @@ static void msm_cvp_deinit_internal_buffers(struct msm_vidc_inst *inst) struct msm_cvp_external *cvp; if (!inst || !inst->cvp) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return; } cvp = inst->cvp; - dprintk(VIDC_HIGH, "%s:\n", __func__); + s_vpr_h(inst->sid, "%s:\n", __func__); if (cvp->output_buffer.dbuf) { print_cvp_buffer(VIDC_HIGH, "free: output_buffer", @@ -552,7 +557,7 @@ static int msm_cvp_set_persist_buffer(struct msm_vidc_inst *inst) struct msm_cvp_session_set_persist_buffers_packet persist2_packet = {0}; if (!inst || !inst->cvp || !inst->cvp->arg) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; @@ -561,10 +566,10 @@ static int msm_cvp_set_persist_buffer(struct msm_vidc_inst *inst) persist2_packet.size = sizeof(struct msm_cvp_session_set_persist_buffers_packet); persist2_packet.packet_type = HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS; - persist2_packet.session_id = cvp->session_id; + persist2_packet.sid = cvp->sid; persist2_packet.cvp_op = CVP_DME; fill_cvp_buffer(&persist2_packet.persist2_buffer, - &cvp->persist2_buffer); + &cvp->persist2_buffer, inst->sid); memset(arg, 0, sizeof(struct cvp_kmd_arg)); arg->type = CVP_KMD_HFI_PERSIST_CMD; @@ -593,7 +598,7 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst) struct msm_cvp_external *cvp; if (!inst || !inst->cvp) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; @@ -643,38 +648,39 @@ static int msm_cvp_prepare_extradata(struct msm_vidc_inst *inst, int nIsValid_offset = 232; if (!inst || !inst->cvp || !mbuf) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, inst, mbuf); return -EINVAL; } cvp = inst->cvp; vb = &mbuf->vvb.vb2_buf; if (vb->num_planes <= 1) { - dprintk(VIDC_ERR, "%s: extradata plane not enabled\n", + s_vpr_e(inst->sid, "%s: extradata plane not enabled\n", __func__); return -EINVAL; } dbuf = dma_buf_get(vb->planes[1].m.fd); if (!dbuf) { - dprintk(VIDC_ERR, "%s: dma_buf_get(%d) failed\n", + s_vpr_e(inst->sid, "%s: dma_buf_get(%d) failed\n", __func__, vb->planes[1].m.fd); return -EINVAL; } if (dbuf->size < vb->planes[1].length) { - dprintk(VIDC_ERR, "%s: invalid size %d vs %d\n", __func__, + s_vpr_e(inst->sid, "%s: invalid size %d vs %d\n", __func__, dbuf->size, vb->planes[1].length); rc = -EINVAL; goto error; } rc = dma_buf_begin_cpu_access(dbuf, DMA_BIDIRECTIONAL); if (rc) { - dprintk(VIDC_ERR, "%s: begin_cpu_access failed\n", __func__); + s_vpr_e(inst->sid, "%s: begin_cpu_access failed\n", __func__); goto error; } kvaddr = dma_buf_vmap(dbuf); if (!kvaddr) { - dprintk(VIDC_ERR, "%s: dma_buf_vmap(%d) failed\n", + s_vpr_e(inst->sid, "%s: dma_buf_vmap(%d) failed\n", __func__, vb->planes[1].m.fd); rc = -EINVAL; goto error; @@ -698,7 +704,7 @@ static int msm_cvp_prepare_extradata(struct msm_vidc_inst *inst, e_hdr += e_hdr->size; } if (!found_end) { - dprintk(VIDC_ERR, "%s: extradata_none not found\n", __func__); + s_vpr_e(inst->sid, "%s: extradata_none not found\n", __func__); e_hdr = (struct msm_vidc_extradata_header *)((char *)kvaddr + vb->planes[1].data_offset); } @@ -707,7 +713,7 @@ static int msm_cvp_prepare_extradata(struct msm_vidc_inst *inst, sizeof(struct msm_vidc_enc_cvp_metadata_payload) + sizeof(struct msm_vidc_extradata_header)) > (kvaddr + dbuf->size)) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: couldn't append extradata, (e_hdr[%pK] - kvaddr[%pK]) %#x, size %d\n", __func__, e_hdr, kvaddr, (char *)e_hdr - (char *)kvaddr, dbuf->size); @@ -730,8 +736,7 @@ static int msm_cvp_prepare_extradata(struct msm_vidc_inst *inst, sizeof(struct msm_vidc_enc_cvp_metadata_payload)); cvpframe = (char *) e_hdr->data; cvp_metadata_valid_flag = *(u32*)(cvpframe + nIsValid_offset); - dprintk(VIDC_HIGH, - "CVP metadata nIsValid flag = %u frame: %u", + s_vpr_h(inst->sid, "CVP metadata nIsValid flag = %u frame: %u", cvp_metadata_valid_flag, cvp->framecount); dma_buf_end_cpu_access(cvp->output_buffer.dbuf, DMA_BIDIRECTIONAL); @@ -770,7 +775,7 @@ static int msm_cvp_reference_management(struct msm_vidc_inst *inst) struct msm_cvp_buf temp; if (!inst || !inst->cvp) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; @@ -800,7 +805,7 @@ static int msm_vidc_cvp_session_start(struct msm_vidc_inst *inst) struct cvp_kmd_arg *arg = NULL; if (!inst || !inst->cvp || !inst->cvp->arg) { - dprintk(VIDC_ERR, "%s: invalid param\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; @@ -813,7 +818,7 @@ static int msm_vidc_cvp_session_start(struct msm_vidc_inst *inst) rc = msm_cvp_private(cvp->priv, CVP_KMD_SESSION_CONTROL, arg); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: CVP_KMD_SESSION_CONTROL failed, rc %d\n", __func__, rc); return rc; @@ -830,7 +835,7 @@ static int msm_vidc_cvp_session_stop(struct msm_vidc_inst *inst) struct cvp_kmd_arg *arg = NULL; if (!inst || !inst->cvp || !inst->cvp->arg) { - dprintk(VIDC_ERR, "%s: invalid param\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } @@ -846,7 +851,7 @@ static int msm_vidc_cvp_session_stop(struct msm_vidc_inst *inst) rc = msm_cvp_private(cvp->priv, CVP_KMD_SESSION_CONTROL, arg); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: CVP_KMD_SESSION_CONTROL failed, rc %d\n", __func__, rc); return rc; @@ -869,7 +874,8 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, bool first_frame = false; if (!inst || !inst->cvp || !inst->cvp->arg || !mbuf) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, inst, mbuf); return -EINVAL; } cvp = inst->cvp; @@ -894,7 +900,7 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, cvp->operating_rate = inst->clk_data.operating_rate; rc = msm_cvp_set_clocks_and_bus(inst); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: unsupported dynamic changes %#x %#x\n", __func__, cvp->frame_rate, cvp->operating_rate); goto error; @@ -945,7 +951,7 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, frame = (struct msm_cvp_dme_frame_packet *)&arg->data.hfi_pkt.pkt_data; frame->size = sizeof(struct msm_cvp_dme_frame_packet); frame->packet_type = HFI_CMD_SESSION_CVP_DME_FRAME; - frame->session_id = cvp->session_id; + frame->sid = cvp->sid; if (first_frame) frame->skip_mv_calc = 1; else @@ -957,18 +963,20 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, frame->ncc_robustness_threshold = 0; fill_cvp_buffer(&frame->fullres_srcbuffer, - &cvp->fullres_buffer); + &cvp->fullres_buffer, inst->sid); fill_cvp_buffer(&frame->videospatialtemporal_statsbuffer, - &cvp->output_buffer); - fill_cvp_buffer(&frame->src_buffer, &cvp->fullres_buffer); + &cvp->output_buffer, inst->sid); + fill_cvp_buffer(&frame->src_buffer, &cvp->fullres_buffer, inst->sid); if (cvp->downscale) { - fill_cvp_buffer(&frame->src_buffer, &cvp->src_buffer); - fill_cvp_buffer(&frame->ref_buffer, &cvp->ref_buffer); + fill_cvp_buffer(&frame->src_buffer, &cvp->src_buffer, + inst->sid); + fill_cvp_buffer(&frame->ref_buffer, &cvp->ref_buffer, + inst->sid); } fill_cvp_buffer(&frame->srcframe_contextbuffer, - &cvp->context_buffer); + &cvp->context_buffer, inst->sid); fill_cvp_buffer(&frame->refframe_contextbuffer, - &cvp->refcontext_buffer); + &cvp->refcontext_buffer, inst->sid); print_cvp_buffer(VIDC_LOW, "input frame", inst, &cvp->fullres_buffer); rc = msm_cvp_private(cvp->priv, CVP_KMD_SEND_CMD_PKT, arg); @@ -999,11 +1007,12 @@ int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst, struct msm_cvp_external *cvp; if (!inst || !inst->cvp || !mbuf) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, inst, mbuf); return -EINVAL; } if (inst->state != MSM_VIDC_START_DONE) { - dprintk(VIDC_ERR, "%s: invalid inst state %d\n", + s_vpr_e(inst->sid, "%s: invalid inst state %d\n", __func__, inst->state); return -EINVAL; } @@ -1011,19 +1020,19 @@ int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst, rc = msm_cvp_frame_process(inst, mbuf); if (rc) { - dprintk(VIDC_ERR, "%s: cvp process failed\n", __func__); + s_vpr_e(inst->sid, "%s: cvp process failed\n", __func__); return rc; } rc = msm_cvp_prepare_extradata(inst, mbuf); if (rc) { - dprintk(VIDC_ERR, "%s: prepare extradata failed\n", __func__); + s_vpr_e(inst->sid, "%s: prepare extradata failed\n", __func__); return rc; } rc = msm_cvp_reference_management(inst); if (rc) { - dprintk(VIDC_ERR, "%s: ref management failed\n", __func__); + s_vpr_e(inst->sid, "%s: ref management failed\n", __func__); return rc; } @@ -1038,7 +1047,7 @@ static int msm_vidc_cvp_session_delete(struct msm_vidc_inst *inst) struct cvp_kmd_arg *arg = NULL; if (!inst || !inst->cvp || !inst->cvp->arg) { - dprintk(VIDC_ERR, "%s: invalid param\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; @@ -1051,7 +1060,7 @@ static int msm_vidc_cvp_session_delete(struct msm_vidc_inst *inst) rc = msm_cvp_private(cvp->priv, CVP_KMD_SESSION_CONTROL, arg); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: CVP_KMD_SESSION_CONTROL failed, rc %d\n", __func__, rc); return rc; @@ -1066,12 +1075,12 @@ static int msm_cvp_mem_deinit(struct msm_vidc_inst *inst) struct msm_cvp_external *cvp; if (!inst || !inst->cvp) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; - dprintk(VIDC_HIGH, "%s: cvp session %#x\n", __func__, cvp->session_id); + s_vpr_h(inst->sid, "%s: cvp session %#x\n", __func__, cvp->sid); msm_cvp_deinit_internal_buffers(inst); msm_cvp_deinit_context_buffers(inst); msm_cvp_deinit_downscale_buffers(inst); @@ -1090,13 +1099,13 @@ static int msm_vidc_cvp_deinit(struct msm_vidc_inst *inst) int rc = 0; if (!inst || !inst->cvp) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } rc = msm_vidc_cvp_session_stop(inst); if (rc) { - dprintk(VIDC_ERR, "%s: cvp stop failed with error %d\n", + s_vpr_e(inst->sid, "%s: cvp stop failed with error %d\n", __func__, rc); } @@ -1111,16 +1120,16 @@ static int msm_vidc_cvp_close(struct msm_vidc_inst *inst) struct msm_cvp_external *cvp; if (!inst || !inst->cvp) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; - dprintk(VIDC_HIGH, "%s: cvp session %#x\n", __func__, cvp->session_id); + s_vpr_h(inst->sid, "%s: cvp session %#x\n", __func__, cvp->sid); rc = msm_cvp_close(cvp->priv); if (rc) { - dprintk(VIDC_ERR, - "%s: cvp close failed with error %d\n", __func__, rc); + s_vpr_e(inst->sid, "%s: cvp close failed with error %d\n", + __func__, rc); } return rc; @@ -1129,11 +1138,11 @@ static int msm_vidc_cvp_close(struct msm_vidc_inst *inst) int msm_vidc_cvp_unprepare_preprocess(struct msm_vidc_inst *inst) { if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } if (!inst->cvp) { - dprintk(VIDC_HIGH, "%s: cvp not enabled or closed\n", __func__); + s_vpr_h(inst->sid, "%s: cvp not enabled or closed\n", __func__); return 0; } @@ -1152,7 +1161,7 @@ static int msm_vidc_cvp_session_create(struct msm_vidc_inst *inst) struct cvp_kmd_arg *arg = NULL; if (!inst || !inst->cvp || !inst->cvp->arg) { - dprintk(VIDC_ERR, "%s: invalid param\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; @@ -1165,7 +1174,7 @@ static int msm_vidc_cvp_session_create(struct msm_vidc_inst *inst) rc = msm_cvp_private(cvp->priv, CVP_KMD_SESSION_CONTROL, arg); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: CVP_KMD_SESSION_CONTROL failed, rc %d\n", __func__, rc); return rc; @@ -1181,7 +1190,7 @@ static int msm_vidc_cvp_getsessioninfo(struct msm_vidc_inst *inst) struct cvp_kmd_arg *arg; if (!inst || !inst->cvp || !inst->cvp->arg) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; @@ -1191,16 +1200,16 @@ static int msm_vidc_cvp_getsessioninfo(struct msm_vidc_inst *inst) arg->type = CVP_KMD_GET_SESSION_INFO; rc = msm_cvp_private(cvp->priv, CVP_KMD_GET_SESSION_INFO, arg); if (rc) { - dprintk(VIDC_ERR, "%s: get_session_info failed\n", __func__); + s_vpr_e(inst->sid, "%s: get_session_info failed\n", __func__); goto error; } - cvp->session_id = arg->data.session.session_id; - dprintk(VIDC_HIGH, "%s: cvp session id %#x\n", - __func__, cvp->session_id); + cvp->sid = arg->data.session.session_id; + s_vpr_h(inst->sid, "%s: cvp session id %#x\n", + __func__, cvp->sid); rc = msm_cvp_get_version_info(inst); if (rc) { - dprintk(VIDC_ERR, "%s: get_version_info failed\n", __func__); + s_vpr_e(inst->sid, "%s: get_version_info failed\n", __func__); goto error; } return rc; @@ -1220,7 +1229,7 @@ static int msm_vidc_cvp_dme_basic_config(struct msm_vidc_inst *inst) u32 color_fmt; if (!inst || !inst->cvp || !inst->cvp->arg) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; @@ -1232,24 +1241,28 @@ static int msm_vidc_cvp_dme_basic_config(struct msm_vidc_inst *inst) &arg->data.hfi_pkt.pkt_data; dmecfg->size = sizeof(struct msm_cvp_dme_basic_config_packet); dmecfg->packet_type = HFI_CMD_SESSION_CVP_DME_BASIC_CONFIG; - dmecfg->session_id = cvp->session_id; + dmecfg->sid = cvp->sid; /* source buffer format should be NV12_UBWC always */ dmecfg->srcbuffer_format = HFI_COLOR_FORMAT_NV12_UBWC; dmecfg->src_width = cvp->ds_width; dmecfg->src_height = cvp->ds_height; rc = msm_cvp_fill_planeinfo(&dmecfg->srcbuffer_planeinfo, - COLOR_FMT_NV12_UBWC, dmecfg->src_width, dmecfg->src_height); + COLOR_FMT_NV12_UBWC, dmecfg->src_width, + dmecfg->src_height, inst->sid); if (rc) goto error; fmt = &inst->fmts[INPUT_PORT].v4l2_fmt; - color_fmt = msm_comm_convert_color_fmt(fmt->fmt.pix_mp.pixelformat); + color_fmt = + msm_comm_convert_color_fmt(fmt->fmt.pix_mp.pixelformat, + inst->sid); dmecfg->fullresbuffer_format = msm_comm_get_hfi_uncompressed( - fmt->fmt.pix_mp.pixelformat); + fmt->fmt.pix_mp.pixelformat, inst->sid); dmecfg->fullres_width = cvp->width; dmecfg->fullres_height = cvp->height; rc = msm_cvp_fill_planeinfo(&dmecfg->fullresbuffer_planeinfo, - color_fmt, dmecfg->fullres_width, dmecfg->fullres_height); + color_fmt, dmecfg->fullres_width, + dmecfg->fullres_height, inst->sid); if (rc) goto error; dmecfg->ds_enable = cvp->downscale; @@ -1257,7 +1270,7 @@ static int msm_vidc_cvp_dme_basic_config(struct msm_vidc_inst *inst) dmecfg->enable_inlier_tracking = 1; rc = msm_cvp_private(cvp->priv, CVP_KMD_SEND_CMD_PKT, arg); if (rc) { - dprintk(VIDC_ERR, "%s: cvp configuration failed\n", __func__); + s_vpr_e(inst->sid, "%s: cvp configuration failed\n", __func__); goto error; } @@ -1272,13 +1285,13 @@ static int msm_cvp_mem_init(struct msm_vidc_inst *inst) struct v4l2_format *fmt; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } inst->cvp = kzalloc(sizeof(struct msm_cvp_external), GFP_KERNEL); if (!inst->cvp) { - dprintk(VIDC_ERR, "%s: failed to allocate\n", __func__); + s_vpr_e(inst->sid, "%s: failed to allocate\n", __func__); return -ENOMEM; } cvp = inst->cvp; @@ -1304,7 +1317,7 @@ static int msm_cvp_mem_init(struct msm_vidc_inst *inst) if (rc) goto error; - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "%s: pixelformat %#x, wxh %dx%d downscale %d ds_wxh %dx%d fps %d op_rate %d\n", __func__, fmt->fmt.pix_mp.pixelformat, cvp->width, cvp->height, cvp->downscale, @@ -1334,15 +1347,16 @@ static int msm_vidc_cvp_open(struct msm_vidc_inst *inst) struct msm_cvp_external *cvp; if (!inst || !inst->cvp) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } cvp = inst->cvp; - dprintk(VIDC_HIGH, "%s: opening cvp\n", __func__); + s_vpr_h(inst->sid, "%s: opening cvp\n", __func__); cvp->priv = msm_cvp_open(0, MSM_VIDC_CVP); if (!cvp->priv) { - dprintk(VIDC_ERR, "%s: failed to open cvp session\n", __func__); + s_vpr_e(inst->sid, + "%s: failed to open cvp session\n", __func__); rc = -EINVAL; } @@ -1393,7 +1407,7 @@ int msm_vidc_cvp_prepare_preprocess(struct msm_vidc_inst *inst) int rc; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } diff --git a/msm/vidc/msm_cvp_external.h b/msm/vidc/msm_cvp_external.h index 90b3e7722ced..b0f14c8127d2 100644 --- a/msm/vidc/msm_cvp_external.h +++ b/msm/vidc/msm_cvp_external.h @@ -82,7 +82,7 @@ struct msm_cvp_buffer_type { struct msm_cvp_session_release_persist_buffers_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; struct msm_cvp_client_data client_data; u32 cvp_op; struct msm_cvp_buffer_type persist1_buffer; @@ -92,7 +92,7 @@ struct msm_cvp_session_release_persist_buffers_packet { struct msm_cvp_session_set_persist_buffers_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; struct msm_cvp_client_data client_data; u32 cvp_op; struct msm_cvp_buffer_type persist1_buffer; @@ -102,7 +102,7 @@ struct msm_cvp_session_set_persist_buffers_packet { struct msm_cvp_dme_frame_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; struct msm_cvp_client_data client_data; u32 stream_idx; u32 skip_mv_calc; @@ -126,7 +126,7 @@ struct msm_cvp_dme_frame_packet { struct msm_cvp_dme_basic_config_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; struct msm_cvp_client_data client_data; u32 stream_idx; u32 srcbuffer_format; @@ -167,7 +167,7 @@ struct msm_cvp_buf { struct msm_cvp_external { void *priv; void *arg; - u32 session_id; + u32 sid; u32 width; u32 height; u32 ds_width; diff --git a/msm/vidc/msm_cvp_internal.c b/msm/vidc/msm_cvp_internal.c index b5c7350b70c9..f0788d9ba41d 100644 --- a/msm/vidc/msm_cvp_internal.c +++ b/msm/vidc/msm_cvp_internal.c @@ -19,9 +19,9 @@ static void print_client_buffer(u32 tag, const char *str, if (!(tag & msm_vidc_debug) || !inst || !cbuf) return; - dprintk(tag, - "%s: %x : idx %2d fd %d off %d size %d type %d flags 0x%x\n", - str, hash32_ptr(inst->session), cbuf->index, cbuf->fd, + dprintk(tag, inst->sid, + "%s: idx %2d fd %d off %d size %d type %d flags 0x%x\n", + str, cbuf->index, cbuf->fd, cbuf->offset, cbuf->size, cbuf->type, cbuf->flags); } @@ -31,14 +31,15 @@ static void print_cvp_buffer(u32 tag, const char *str, if (!(tag & msm_vidc_debug) || !inst || !cbuf) return; - dprintk(tag, - "%s: %x : idx %2d fd %d off %d daddr %x size %d type %d flags 0x%x\n", - str, hash32_ptr(inst->session), cbuf->buf.index, cbuf->buf.fd, + dprintk(tag, inst->sid, + "%s: idx %2d fd %d off %d daddr %x size %d type %d flags 0x%x\n", + str, cbuf->buf.index, cbuf->buf.fd, cbuf->buf.offset, cbuf->smem.device_addr, cbuf->buf.size, cbuf->buf.type, cbuf->buf.flags); } -static enum hal_buffer get_hal_buftype(const char *str, unsigned int type) +static enum hal_buffer get_hal_buftype(const char *str, + unsigned int type, u32 sid) { enum hal_buffer buftype = HAL_BUFFER_NONE; @@ -51,7 +52,7 @@ static enum hal_buffer get_hal_buftype(const char *str, unsigned int type) else if (type == MSM_CVP_BUFTYPE_INTERNAL_2) buftype = HAL_BUFFER_INTERNAL_SCRATCH_1; else - dprintk(VIDC_ERR, "%s: unknown buffer type %#x\n", + s_vpr_e(sid, "%s: unknown buffer type %#x\n", str, type); return buftype; @@ -68,14 +69,14 @@ void handle_session_register_buffer_done(enum hal_command_response cmd, bool found; if (!response) { - dprintk(VIDC_ERR, "%s: invalid response\n", __func__); + d_vpr_e("%s: invalid response\n", __func__); return; } inst = get_inst(get_vidc_core(response->device_id), - response->session_id); + response->inst_id); if (!inst) { - dprintk(VIDC_ERR, "%s: invalid session %pK\n", __func__, - response->session_id); + d_vpr_e("%s: invalid session %pK\n", __func__, + response->inst_id); return; } @@ -90,7 +91,7 @@ void handle_session_register_buffer_done(enum hal_command_response cmd, } mutex_unlock(&inst->cvpbufs.lock); if (!found) { - dprintk(VIDC_ERR, "%s: client_data %x not found\n", + s_vpr_e(inst->sid, "%s: client_data %x not found\n", __func__, response->data.regbuf.client_data); goto exit; } @@ -106,6 +107,7 @@ void handle_session_register_buffer_done(enum hal_command_response cmd, exit: put_inst(inst); + s_vpr_l(inst->sid, "handled: SESSION_REGISTER_BUFFER_DONE\n"); } void handle_session_unregister_buffer_done(enum hal_command_response cmd, @@ -120,14 +122,14 @@ void handle_session_unregister_buffer_done(enum hal_command_response cmd, bool found; if (!response) { - dprintk(VIDC_ERR, "%s: invalid response\n", __func__); + d_vpr_e("%s: invalid response\n", __func__); return; } inst = get_inst(get_vidc_core(response->device_id), - response->session_id); + response->inst_id); if (!inst) { - dprintk(VIDC_ERR, "%s: invalid session %pK\n", __func__, - response->session_id); + d_vpr_e("%s: invalid session %pK\n", __func__, + response->inst_id); return; } @@ -142,7 +144,7 @@ void handle_session_unregister_buffer_done(enum hal_command_response cmd, } mutex_unlock(&inst->cvpbufs.lock); if (!found) { - dprintk(VIDC_ERR, "%s: client_data %x not found\n", + s_vpr_e(inst->sid, "%s: client_data %x not found\n", __func__, response->data.unregbuf.client_data); goto exit; } @@ -169,6 +171,7 @@ void handle_session_unregister_buffer_done(enum hal_command_response cmd, cbuf = NULL; exit: put_inst(inst); + s_vpr_l(inst->sid, "handled: SESSION_UNREGISTER_BUFFER_DONE\n"); } static void print_cvp_cycles(struct msm_vidc_inst *inst) @@ -183,8 +186,7 @@ static void print_cvp_cycles(struct msm_vidc_inst *inst) mutex_lock(&core->lock); list_for_each_entry(temp, &core->instances, list) { if (temp->session_type == MSM_VIDC_CVP) { - dprintk(VIDC_ERR, "session %#x, vpss %d ise %d\n", - hash32_ptr(temp->session), + s_vpr_e(temp->sid, "vpss %d ise %d\n", temp->clk_data.vpss_cycles, temp->clk_data.ise_cycles); } @@ -201,7 +203,7 @@ static bool msm_cvp_check_session_supported(struct msm_vidc_inst *inst, u32 total_ise_cycles = 0; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return false; } core = inst->core; @@ -227,23 +229,21 @@ static int msm_cvp_scale_clocks_and_bus(struct msm_vidc_inst *inst) int rc = 0; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } - rc = msm_vidc_set_clocks(inst->core); + rc = msm_vidc_set_clocks(inst->core, inst->sid); if (rc) { - dprintk(VIDC_ERR, - "%s: failed set_clocks for inst %pK (%#x)\n", - __func__, inst, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, "%s: failed set_clocks for inst %pK\n", + __func__, inst); goto exit; } rc = msm_comm_vote_bus(inst); if (rc) { - dprintk(VIDC_ERR, - "%s: failed vote_bus for inst %pK (%#x)\n", - __func__, inst, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, + "%s: failed vote_bus for inst %pK\n", __func__, inst); goto exit; } @@ -257,12 +257,13 @@ static int msm_cvp_get_session_info(struct msm_vidc_inst *inst, int rc = 0; if (!inst || !inst->core || !session) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, inst, session); return -EINVAL; } - session->session_id = hash32_ptr(inst->session); - dprintk(VIDC_HIGH, "%s: id 0x%x\n", __func__, session->session_id); + session->session_id = inst->sid; + s_vpr_h(inst->sid, "%s: id 0x%x\n", __func__, session->session_id); return rc; } @@ -273,11 +274,12 @@ static int msm_cvp_request_power(struct msm_vidc_inst *inst, int rc = 0; if (!inst || !power) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, inst, power); return -EINVAL; } - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "%s: clock_cycles_a %d, clock_cycles_b %d, ddr_bw %d sys_cache_bw %d\n", __func__, power->clock_cycles_a, power->clock_cycles_b, power->ddr_bw, power->sys_cache_bw); @@ -285,10 +287,8 @@ static int msm_cvp_request_power(struct msm_vidc_inst *inst, rc = msm_cvp_check_session_supported(inst, power->clock_cycles_a, power->clock_cycles_b); if (!rc) { - dprintk(VIDC_ERR, - "%s: session %#x rejected, cycles: vpss %d, ise %d\n", - __func__, hash32_ptr(inst->session), - power->clock_cycles_a, power->clock_cycles_b); + s_vpr_e(inst->sid, "%s: rejected, cycles: vpss %d, ise %d\n", + __func__, power->clock_cycles_a, power->clock_cycles_b); print_cvp_cycles(inst); msm_comm_kill_session(inst); return -EOVERFLOW; @@ -301,9 +301,9 @@ static int msm_cvp_request_power(struct msm_vidc_inst *inst, inst->clk_data.sys_cache_bw = power->sys_cache_bw / 1000; rc = msm_cvp_scale_clocks_and_bus(inst); if (rc) { - dprintk(VIDC_ERR, - "%s: failed to scale clocks and bus for inst %pK (%#x)\n", - __func__, inst, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, + "%s: failed to scale clocks and bus for inst %pK\n", + __func__, inst); goto exit; } @@ -311,17 +311,13 @@ static int msm_cvp_request_power(struct msm_vidc_inst *inst, !inst->clk_data.sys_cache_bw) { rc = msm_cvp_inst_pause(inst); if (rc) { - dprintk(VIDC_ERR, - "%s: failed to pause inst %pK (%#x)\n", - __func__, inst, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, "%s: failed to pause\n", __func__); goto exit; } } else { rc = msm_cvp_inst_resume(inst); if (rc) { - dprintk(VIDC_ERR, - "%s: failed to resume inst %pK (%#x)\n", - __func__, inst, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, "%s: failed to resume\n", __func__); goto exit; } } @@ -340,7 +336,8 @@ static int msm_cvp_register_buffer(struct msm_vidc_inst *inst, struct vidc_register_buffer vbuf; if (!inst || !inst->core || !buf) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, inst, buf); return -EINVAL; } hdev = inst->core->device; @@ -364,7 +361,7 @@ static int msm_cvp_register_buffer(struct msm_vidc_inst *inst, cbuf = kzalloc(sizeof(struct msm_vidc_cvp_buffer), GFP_KERNEL); if (!cbuf) { - dprintk(VIDC_ERR, "%s: cbuf alloc failed\n", __func__); + s_vpr_e(inst->sid, "%s: cbuf alloc failed\n", __func__); return -ENOMEM; } mutex_lock(&inst->cvpbufs.lock); @@ -372,7 +369,8 @@ static int msm_cvp_register_buffer(struct msm_vidc_inst *inst, mutex_unlock(&inst->cvpbufs.lock); memcpy(&cbuf->buf, buf, sizeof(struct msm_cvp_buffer)); - cbuf->smem.buffer_type = get_hal_buftype(__func__, buf->type); + cbuf->smem.buffer_type = get_hal_buftype(__func__, buf->type, + inst->sid); cbuf->smem.fd = buf->fd; cbuf->smem.offset = buf->offset; cbuf->smem.size = buf->size; @@ -384,7 +382,7 @@ static int msm_cvp_register_buffer(struct msm_vidc_inst *inst, memset(&vbuf, 0, sizeof(struct vidc_register_buffer)); vbuf.index = buf->index; - vbuf.type = get_hal_buftype(__func__, buf->type); + vbuf.type = get_hal_buftype(__func__, buf->type, inst->sid); vbuf.size = buf->size; vbuf.device_addr = cbuf->smem.device_addr; vbuf.client_data = cbuf->smem.device_addr; @@ -419,7 +417,8 @@ static int msm_cvp_unregister_buffer(struct msm_vidc_inst *inst, struct vidc_unregister_buffer vbuf; if (!inst || !inst->core || !buf) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, inst, buf); return -EINVAL; } hdev = inst->core->device; @@ -443,7 +442,7 @@ static int msm_cvp_unregister_buffer(struct msm_vidc_inst *inst, memset(&vbuf, 0, sizeof(struct vidc_unregister_buffer)); vbuf.index = cbuf->buf.index; - vbuf.type = get_hal_buftype(__func__, cbuf->buf.type); + vbuf.type = get_hal_buftype(__func__, cbuf->buf.type, inst->sid); vbuf.size = cbuf->buf.size; vbuf.device_addr = cbuf->smem.device_addr; vbuf.client_data = cbuf->smem.device_addr; @@ -461,7 +460,8 @@ int msm_vidc_cvp(struct msm_vidc_inst *inst, struct msm_vidc_arg *arg) int rc = 0; if (!inst || !arg) { - dprintk(VIDC_ERR, "%s: invalid args\n", __func__); + d_vpr_e("%s: invalid args %pK %pK\n", + __func__, inst, arg); return -EINVAL; } @@ -499,7 +499,7 @@ int msm_vidc_cvp(struct msm_vidc_inst *inst, struct msm_vidc_arg *arg) break; } default: - dprintk(VIDC_ERR, "%s: unknown arg type 0x%x\n", + s_vpr_e(inst->sid, "%s: unknown arg type 0x%x\n", __func__, arg->type); rc = -ENOTSUPP; break; @@ -535,15 +535,14 @@ int msm_cvp_inst_pause(struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; rc = call_hfi_op(hdev, session_pause, (void *)inst->session); if (rc) - dprintk(VIDC_ERR, "%s: failed to pause inst %pK (%#x)\n", - __func__, inst, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, "%s: failed to pause\n", __func__); return rc; } @@ -554,15 +553,14 @@ int msm_cvp_inst_resume(struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; rc = call_hfi_op(hdev, session_resume, (void *)inst->session); if (rc) - dprintk(VIDC_ERR, "%s: failed to resume inst %pK (%#x)\n", - __func__, inst, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, "%s: failed to resume\n", __func__); return rc; } @@ -573,22 +571,21 @@ int msm_cvp_inst_deinit(struct msm_vidc_inst *inst) struct msm_vidc_cvp_buffer *cbuf, *temp; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } - dprintk(VIDC_HIGH, "%s: inst %pK (%#x)\n", __func__, - inst, hash32_ptr(inst->session)); + s_vpr_h(inst->sid, "%s: inst %pK\n", __func__, inst); rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE); if (rc) - dprintk(VIDC_ERR, "%s: close failed\n", __func__); + s_vpr_e(inst->sid, "%s: close failed\n", __func__); mutex_lock(&inst->cvpbufs.lock); list_for_each_entry_safe(cbuf, temp, &inst->cvpbufs.list, list) { print_cvp_buffer(VIDC_ERR, "unregistered", inst, cbuf); rc = inst->smem_ops->smem_unmap_dma_buf(inst, &cbuf->smem); if (rc) - dprintk(VIDC_ERR, "%s: unmap failed\n", __func__); + s_vpr_e(inst->sid, "%s: unmap failed\n", __func__); list_del(&cbuf->list); kfree(cbuf); } @@ -599,7 +596,7 @@ int msm_cvp_inst_deinit(struct msm_vidc_inst *inst) inst->clk_data.sys_cache_bw = 0; rc = msm_cvp_scale_clocks_and_bus(inst); if (rc) - dprintk(VIDC_ERR, "%s: failed to scale_clocks_and_bus\n", + s_vpr_e(inst->sid, "%s: failed to scale_clocks_and_bus\n", __func__); return rc; @@ -610,12 +607,11 @@ int msm_cvp_inst_init(struct msm_vidc_inst *inst) int rc = 0; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } - dprintk(VIDC_HIGH, "%s: inst %pK (%#x)\n", __func__, - inst, hash32_ptr(inst->session)); + s_vpr_h(inst->sid, "%s: inst %pK\n", __func__, inst); /* set default frequency */ inst->clk_data.core_id = VIDC_CORE_ID_2; diff --git a/msm/vidc/msm_smem.c b/msm/vidc/msm_smem.c index 6a748bf09647..12f645981e37 100644 --- a/msm/vidc/msm_smem.c +++ b/msm/vidc/msm_smem.c @@ -21,7 +21,7 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, unsigned long align, dma_addr_t *iova, unsigned long *buffer_size, unsigned long flags, enum hal_buffer buffer_type, unsigned long session_type, struct msm_vidc_platform_resources *res, - struct dma_mapping_info *mapping_info) + struct dma_mapping_info *mapping_info, u32 sid) { int rc = 0; struct dma_buf_attachment *attach; @@ -29,18 +29,17 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, unsigned long align, struct context_bank_info *cb = NULL; if (!dbuf || !iova || !buffer_size || !mapping_info) { - dprintk(VIDC_ERR, "Invalid params: %pK, %pK, %pK, %pK\n", - dbuf, iova, buffer_size, mapping_info); + s_vpr_e(sid, "%s: invalid params: %pK, %pK, %pK, %pK\n", + __func__, dbuf, iova, buffer_size, mapping_info); return -EINVAL; } if (is_iommu_present(res)) { cb = msm_smem_get_context_bank( session_type, (flags & SMEM_SECURE), - res, buffer_type); + res, buffer_type, sid); if (!cb) { - dprintk(VIDC_ERR, - "%s: Failed to get context bank device\n", + s_vpr_e(sid, "%s: Failed to get context bank device\n", __func__); rc = -EIO; goto mem_map_failed; @@ -49,7 +48,7 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, unsigned long align, /* Check if the dmabuf size matches expected size */ if (dbuf->size < *buffer_size) { rc = -EINVAL; - dprintk(VIDC_ERR, + s_vpr_e(sid, "Size mismatch: Dmabuf size: %zu Expected Size: %lu", dbuf->size, *buffer_size); msm_vidc_res_handle_fatal_hw_error(res, @@ -61,7 +60,7 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, unsigned long align, attach = dma_buf_attach(dbuf, cb->dev); if (IS_ERR_OR_NULL(attach)) { rc = PTR_ERR(attach) ? PTR_ERR(attach) : -ENOMEM; - dprintk(VIDC_ERR, "Failed to attach dmabuf\n"); + s_vpr_e(sid, "Failed to attach dmabuf\n"); goto mem_buf_attach_failed; } @@ -84,7 +83,7 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, unsigned long align, table = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); if (IS_ERR_OR_NULL(table)) { rc = PTR_ERR(table) ? PTR_ERR(table) : -ENOMEM; - dprintk(VIDC_ERR, "Failed to map table\n"); + s_vpr_e(sid, "Failed to map table\n"); goto mem_map_table_failed; } @@ -96,7 +95,7 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, unsigned long align, *iova = table->sgl->dma_address; *buffer_size = table->sgl->dma_length; } else { - dprintk(VIDC_ERR, "sgl is NULL\n"); + s_vpr_e(sid, "sgl is NULL\n"); rc = -ENOMEM; goto mem_map_sg_failed; } @@ -111,7 +110,7 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, unsigned long align, trace_msm_smem_buffer_iommu_op_end("MAP", 0, 0, align, *iova, *buffer_size); } else { - dprintk(VIDC_HIGH, "iommu not present, use phys mem addr\n"); + s_vpr_h(sid, "iommu not present, use phys mem addr\n"); } return 0; @@ -127,19 +126,19 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, unsigned long align, static int msm_dma_put_device_address(u32 flags, struct dma_mapping_info *mapping_info, - enum hal_buffer buffer_type) + enum hal_buffer buffer_type, u32 sid) { int rc = 0; if (!mapping_info) { - dprintk(VIDC_ERR, "Invalid mapping_info\n"); + s_vpr_e(sid, "Invalid mapping_info\n"); return -EINVAL; } if (!mapping_info->dev || !mapping_info->table || !mapping_info->buf || !mapping_info->attach || !mapping_info->cb_info) { - dprintk(VIDC_ERR, "Invalid params\n"); + s_vpr_e(sid, "%s: invalid params\n", __func__); return -EINVAL; } @@ -156,17 +155,16 @@ static int msm_dma_put_device_address(u32 flags, mapping_info->buf = NULL; mapping_info->cb_info = NULL; - return rc; } -struct dma_buf *msm_smem_get_dma_buf(int fd) +struct dma_buf *msm_smem_get_dma_buf(int fd, u32 sid) { struct dma_buf *dma_buf; dma_buf = dma_buf_get(fd); if (IS_ERR_OR_NULL(dma_buf)) { - dprintk(VIDC_ERR, "Failed to get dma_buf for %d, error %ld\n", + s_vpr_e(sid, "Failed to get dma_buf for %d, error %ld\n", fd, PTR_ERR(dma_buf)); dma_buf = NULL; } @@ -174,10 +172,10 @@ struct dma_buf *msm_smem_get_dma_buf(int fd) return dma_buf; } -void msm_smem_put_dma_buf(void *dma_buf) +void msm_smem_put_dma_buf(void *dma_buf, u32 sid) { if (!dma_buf) { - dprintk(VIDC_ERR, "%s: NULL dma_buf\n", __func__); + s_vpr_e(sid, "%s: NULL dma_buf\n", __func__); return; } @@ -196,7 +194,7 @@ int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) unsigned long ion_flags = 0; if (!inst || !smem) { - dprintk(VIDC_ERR, "%s: Invalid params: %pK %pK\n", + d_vpr_e("%s: invalid params: %pK %pK\n", __func__, inst, smem); rc = -EINVAL; goto exit; @@ -207,7 +205,7 @@ int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) goto exit; } - dbuf = msm_smem_get_dma_buf(smem->fd); + dbuf = msm_smem_get_dma_buf(smem->fd, inst->sid); if (!dbuf) { rc = -EINVAL; goto exit; @@ -217,7 +215,7 @@ int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) rc = dma_buf_get_flags(dbuf, &ion_flags); if (rc) { - dprintk(VIDC_ERR, "Failed to get dma buf flags: %d\n", rc); + s_vpr_e(inst->sid, "Failed to get dma buf flags: %d\n", rc); goto exit; } if (ion_flags & ION_FLAG_CACHED) @@ -230,14 +228,15 @@ int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) rc = msm_dma_get_device_address(dbuf, align, &iova, &buffer_size, smem->flags, smem->buffer_type, inst->session_type, - &(inst->core->resources), &smem->mapping_info); + &(inst->core->resources), &smem->mapping_info, + inst->sid); if (rc) { - dprintk(VIDC_ERR, "Failed to get device address: %d\n", rc); + s_vpr_e(inst->sid, "Failed to get device address: %d\n", rc); goto exit; } temp = (u32)iova; if ((dma_addr_t)temp != iova) { - dprintk(VIDC_ERR, "iova(%pa) truncated to %#x", &iova, temp); + s_vpr_e(inst->sid, "iova(%pa) truncated to %#x", &iova, temp); rc = -EINVAL; goto exit; } @@ -254,7 +253,7 @@ int msm_smem_unmap_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) int rc = 0; if (!inst || !smem) { - dprintk(VIDC_ERR, "%s: Invalid params: %pK %pK\n", + d_vpr_e("%s: invalid params: %pK %pK\n", __func__, inst, smem); rc = -EINVAL; goto exit; @@ -263,7 +262,7 @@ int msm_smem_unmap_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) if (smem->refcount) { smem->refcount--; } else { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "unmap called while refcount is zero already\n"); return -EINVAL; } @@ -272,13 +271,13 @@ int msm_smem_unmap_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) goto exit; rc = msm_dma_put_device_address(smem->flags, &smem->mapping_info, - smem->buffer_type); + smem->buffer_type, inst->sid); if (rc) { - dprintk(VIDC_ERR, "Failed to put device address: %d\n", rc); + s_vpr_e(inst->sid, "Failed to put device address: %d\n", rc); goto exit; } - msm_smem_put_dma_buf(smem->dma_buf); + msm_smem_put_dma_buf(smem->dma_buf, inst->sid); smem->device_addr = 0x0; smem->dma_buf = NULL; @@ -325,7 +324,7 @@ static int get_secure_flag_for_buffer_type( static int alloc_dma_mem(size_t size, u32 align, u32 flags, enum hal_buffer buffer_type, int map_kernel, struct msm_vidc_platform_resources *res, u32 session_type, - struct msm_smem *mem) + struct msm_smem *mem, u32 sid) { dma_addr_t iova = 0; unsigned long buffer_size = 0; @@ -335,7 +334,7 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, struct dma_buf *dbuf = NULL; if (!res) { - dprintk(VIDC_ERR, "%s: NULL res\n", __func__); + s_vpr_e(sid, "%s: NULL res\n", __func__); return -EINVAL; } @@ -344,13 +343,13 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, if (is_iommu_present(res)) { if (flags & SMEM_ADSP) { - dprintk(VIDC_HIGH, "Allocating from ADSP heap\n"); + s_vpr_h(sid, "Allocating from ADSP heap\n"); heap_mask = ION_HEAP(ION_ADSP_HEAP_ID); } else { heap_mask = ION_HEAP(ION_SYSTEM_HEAP_ID); } } else { - dprintk(VIDC_HIGH, + s_vpr_h(sid, "allocate shared memory from adsp heap size %zx align %d\n", size, align); heap_mask = ION_HEAP(ION_ADSP_HEAP_ID); @@ -385,8 +384,7 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, heap_mask, size, align, flags, map_kernel); dbuf = ion_alloc(size, heap_mask, ion_flags); if (IS_ERR_OR_NULL(dbuf)) { - dprintk(VIDC_ERR, - "Failed to allocate shared memory = %zx, %#x\n", + s_vpr_e(sid, "Failed to allocate shared memory = %zx, %#x\n", size, flags); rc = -ENOMEM; goto fail_shared_mem_alloc; @@ -403,15 +401,15 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, rc = msm_dma_get_device_address(dbuf, align, &iova, &buffer_size, flags, buffer_type, - session_type, res, &mem->mapping_info); + session_type, res, &mem->mapping_info, sid); if (rc) { - dprintk(VIDC_ERR, "Failed to get device address: %d\n", + s_vpr_e(sid, "Failed to get device address: %d\n", rc); goto fail_device_address; } mem->device_addr = (u32)iova; if ((dma_addr_t)mem->device_addr != iova) { - dprintk(VIDC_ERR, "iova(%pa) truncated to %#x", + s_vpr_e(sid, "iova(%pa) truncated to %#x", &iova, mem->device_addr); goto fail_device_address; } @@ -420,14 +418,13 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, dma_buf_begin_cpu_access(dbuf, DMA_BIDIRECTIONAL); mem->kvaddr = dma_buf_vmap(dbuf); if (!mem->kvaddr) { - dprintk(VIDC_ERR, - "Failed to map shared mem in kernel\n"); + s_vpr_e(sid, "Failed to map shared mem in kernel\n"); rc = -EIO; goto fail_map; } } - dprintk(VIDC_HIGH, + s_vpr_h(sid, "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, buffer_type = %#x, flags = %#lx\n", __func__, mem->dma_buf, mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type, mem->flags); @@ -442,16 +439,16 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, return rc; } -static int free_dma_mem(struct msm_smem *mem) +static int free_dma_mem(struct msm_smem *mem, u32 sid) { - dprintk(VIDC_HIGH, + s_vpr_h(sid, "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, buffer_type = %#x\n", __func__, mem->dma_buf, mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type); if (mem->device_addr) { msm_dma_put_device_address(mem->flags, - &mem->mapping_info, mem->buffer_type); + &mem->mapping_info, mem->buffer_type, sid); mem->device_addr = 0x0; } @@ -476,51 +473,52 @@ static int free_dma_mem(struct msm_smem *mem) int msm_smem_alloc(size_t size, u32 align, u32 flags, enum hal_buffer buffer_type, int map_kernel, - void *res, u32 session_type, struct msm_smem *smem) + void *res, u32 session_type, struct msm_smem *smem, u32 sid) { int rc = 0; if (!smem || !size) { - dprintk(VIDC_ERR, "%s: NULL smem or %d size\n", + s_vpr_e(sid, "%s: NULL smem or %d size\n", __func__, (u32)size); return -EINVAL; } rc = alloc_dma_mem(size, align, flags, buffer_type, map_kernel, (struct msm_vidc_platform_resources *)res, - session_type, smem); + session_type, smem, sid); return rc; } -int msm_smem_free(struct msm_smem *smem) +int msm_smem_free(struct msm_smem *smem, u32 sid) { int rc = 0; if (!smem) { - dprintk(VIDC_ERR, "NULL smem passed\n"); + s_vpr_e(sid, "NULL smem passed\n"); return -EINVAL; } - rc = free_dma_mem(smem); + rc = free_dma_mem(smem, sid); return rc; }; int msm_smem_cache_operations(struct dma_buf *dbuf, - enum smem_cache_ops cache_op, unsigned long offset, unsigned long size) + enum smem_cache_ops cache_op, unsigned long offset, + unsigned long size, u32 sid) { int rc = 0; unsigned long flags = 0; if (!dbuf) { - dprintk(VIDC_ERR, "%s: Invalid params\n", __func__); + s_vpr_e(sid, "%s: invalid params\n", __func__); return -EINVAL; } /* Return if buffer doesn't support caching */ rc = dma_buf_get_flags(dbuf, &flags); if (rc) { - dprintk(VIDC_ERR, "%s: dma_buf_get_flags failed, err %d\n", + s_vpr_e(sid, "%s: dma_buf_get_flags failed, err %d\n", __func__, rc); return rc; } else if (!(flags & ION_FLAG_CACHED)) { @@ -546,7 +544,7 @@ int msm_smem_cache_operations(struct dma_buf *dbuf, offset, size); break; default: - dprintk(VIDC_ERR, "%s: cache (%d) operation not supported\n", + s_vpr_e(sid, "%s: cache (%d) operation not supported\n", __func__, cache_op); rc = -EINVAL; break; @@ -557,7 +555,7 @@ int msm_smem_cache_operations(struct dma_buf *dbuf, struct context_bank_info *msm_smem_get_context_bank(u32 session_type, bool is_secure, struct msm_vidc_platform_resources *res, - enum hal_buffer buffer_type) + enum hal_buffer buffer_type, u32 sid) { struct context_bank_info *cb = NULL, *match = NULL; @@ -585,7 +583,7 @@ struct context_bank_info *msm_smem_get_context_bank(u32 session_type, } } if (!match) - dprintk(VIDC_ERR, + s_vpr_e(sid, "%s: cb not found for buffer_type %x, is_secure %d\n", __func__, buffer_type, is_secure); diff --git a/msm/vidc/msm_v4l2_private.c b/msm/vidc/msm_v4l2_private.c index 6200054e0dbd..7155c2d42bc3 100644 --- a/msm/vidc/msm_v4l2_private.c +++ b/msm/vidc/msm_v4l2_private.c @@ -12,7 +12,7 @@ static int convert_from_user(struct msm_vidc_arg *kp, unsigned long arg) struct msm_vidc_arg __user *up = compat_ptr(arg); if (!kp || !up) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params%pK %pK\n", __func__, kp, up); return -EINVAL; } @@ -88,7 +88,7 @@ static int convert_from_user(struct msm_vidc_arg *kp, unsigned long arg) break; } default: - dprintk(VIDC_ERR, "%s: unknown cmd type 0x%x\n", + d_vpr_e("%s: unknown cmd type 0x%x\n", __func__, kp->type); rc = -EINVAL; break; @@ -104,7 +104,7 @@ static int convert_to_user(struct msm_vidc_arg *kp, unsigned long arg) struct msm_vidc_arg __user *up = compat_ptr(arg); if (!kp || !up) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", __func__, kp, up); return -EINVAL; } @@ -180,8 +180,7 @@ static int convert_to_user(struct msm_vidc_arg *kp, unsigned long arg) break; } default: - dprintk(VIDC_ERR, "%s: unknown cmd type 0x%x\n", - __func__, kp->type); + d_vpr_e("%s: unknown cmd type 0x%x\n", __func__, kp->type); rc = -EINVAL; break; } @@ -196,7 +195,7 @@ long msm_v4l2_private(struct file *filp, unsigned int cmd, unsigned long arg) struct msm_vidc_arg karg; if (!filp || !filp->private_data) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, filp); return -EINVAL; } @@ -214,8 +213,7 @@ long msm_v4l2_private(struct file *filp, unsigned int cmd, unsigned long arg) rc = msm_vidc_private((void *)inst, cmd, &karg); if (rc) { - dprintk(VIDC_ERR, "%s: failed cmd type %x\n", - __func__, karg.type); + d_vpr_e("%s: failed cmd type %x\n", __func__, karg.type); return -EINVAL; } diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index 804c9b124f96..22a8683a0820 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -49,8 +49,7 @@ static int msm_v4l2_open(struct file *filp) trace_msm_v4l2_vidc_open_start("msm v4l2_open start"); vidc_inst = msm_vidc_open(core->id, vid_dev->type); if (!vidc_inst) { - dprintk(VIDC_ERR, - "Failed to create video instance, core: %d, type = %d\n", + d_vpr_e("Failed to create instance, core: %d, type = %d\n", core->id, vid_dev->type); return -ENOMEM; } @@ -270,11 +269,10 @@ static int read_platform_resources(struct msm_vidc_core *core, int rc = 0; if (!core || !pdev) { - dprintk(VIDC_ERR, "%s: Invalid params %pK %pK\n", + d_vpr_e("%s: invalid params %pK %pK\n", __func__, core, pdev); return -EINVAL; } - core->hfi_type = VIDC_HFI_VENUS; core->resources.pdev = pdev; if (pdev->dev.of_node) { @@ -282,7 +280,7 @@ static int read_platform_resources(struct msm_vidc_core *core, rc = read_platform_resources_from_drv_data(core); rc = read_platform_resources_from_dt(&core->resources); } else { - dprintk(VIDC_ERR, "pdev node is NULL\n"); + d_vpr_e("pdev node is NULL\n"); rc = -EINVAL; } return rc; @@ -298,7 +296,7 @@ static int msm_vidc_initialize_core(struct platform_device *pdev, return -EINVAL; rc = read_platform_resources(core, pdev); if (rc) { - dprintk(VIDC_ERR, "Failed to get platform resources\n"); + d_vpr_e("Failed to get platform resources\n"); return rc; } @@ -391,11 +389,10 @@ static ssize_t thermal_level_store(struct device *dev, rc = kstrtoint(buf, 0, &val); if (rc || val < 0) { - dprintk(VIDC_ERR, - "Invalid thermal level value: %s\n", buf); + d_vpr_e("Invalid thermal level value: %s\n", buf); return -EINVAL; } - dprintk(VIDC_HIGH, "Thermal level old %d new %d\n", + d_vpr_h("Thermal level old %d new %d\n", vidc_driver->thermal_level, val); if (val == vidc_driver->thermal_level) @@ -451,14 +448,14 @@ static int msm_vidc_register_video_device(enum session_type sess_type, rc = video_register_device(&core->vdev[sess_type].vdev, VFL_TYPE_GRABBER, nr); if (rc) { - dprintk(VIDC_ERR, "Failed to register the video device\n"); + d_vpr_e("Failed to register the video device\n"); return rc; } video_set_drvdata(&core->vdev[sess_type].vdev, core); dev = &core->vdev[sess_type].vdev.dev; rc = device_create_file(dev, &dev_attr_link_name); if (rc) { - dprintk(VIDC_ERR, "Failed to create video device file\n"); + d_vpr_e("Failed to create video device file\n"); video_unregister_device(&core->vdev[sess_type].vdev); return rc; } @@ -472,7 +469,7 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) int nr = BASE_DEVICE_NUMBER; if (!vidc_driver) { - dprintk(VIDC_ERR, "Invalid vidc driver\n"); + d_vpr_e("Invalid vidc driver\n"); return -EINVAL; } @@ -484,13 +481,12 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, core); rc = msm_vidc_initialize_core(pdev, core); if (rc) { - dprintk(VIDC_ERR, "Failed to init core\n"); + d_vpr_e("Failed to init core\n"); goto err_core_init; } rc = sysfs_create_group(&pdev->dev.kobj, &msm_vidc_core_attr_group); if (rc) { - dprintk(VIDC_ERR, - "Failed to create attributes\n"); + d_vpr_e("Failed to create attributes\n"); goto err_core_init; } @@ -498,7 +494,7 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) rc = v4l2_device_register(&pdev->dev, &core->v4l2_dev); if (rc) { - dprintk(VIDC_ERR, "Failed to register v4l2 device\n"); + d_vpr_e("Failed to register v4l2 device\n"); goto err_v4l2_register; } @@ -506,7 +502,7 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) rc = msm_vidc_register_video_device(MSM_VIDC_DECODER, nr, core, dev); if (rc) { - dprintk(VIDC_ERR, "Failed to register video decoder\n"); + d_vpr_e("Failed to register video decoder\n"); goto err_dec; } @@ -514,7 +510,7 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) rc = msm_vidc_register_video_device(MSM_VIDC_ENCODER, nr + 1, core, dev); if (rc) { - dprintk(VIDC_ERR, "Failed to register video encoder\n"); + d_vpr_e("Failed to register video encoder\n"); goto err_enc; } @@ -523,7 +519,7 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) rc = msm_vidc_register_video_device(MSM_VIDC_CVP, nr + 2, core, dev); if (rc) { - dprintk(VIDC_ERR, "Failed to register video CVP\n"); + d_vpr_e("Failed to register video CVP\n"); goto err_cvp; } } @@ -532,8 +528,8 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) mutex_lock(&vidc_driver->lock); if (vidc_driver->num_cores + 1 > MSM_VIDC_CORES_MAX) { mutex_unlock(&vidc_driver->lock); - dprintk(VIDC_ERR, "Maximum cores already exist, core_no = %d\n", - vidc_driver->num_cores); + d_vpr_e("Maximum cores already exist, core_no = %d\n", + vidc_driver->num_cores); goto err_cores_exceeded; } vidc_driver->num_cores++; @@ -549,16 +545,16 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) rc = PTR_ERR(core->device) ? PTR_ERR(core->device) : -EBADHANDLE; if (rc != -EPROBE_DEFER) - dprintk(VIDC_ERR, "Failed to create HFI device\n"); + d_vpr_e("Failed to create HFI device\n"); else - dprintk(VIDC_HIGH, "msm_vidc: request probe defer\n"); + d_vpr_h("msm_vidc: request probe defer\n"); goto err_cores_exceeded; } core->vidc_core_workq = create_singlethread_workqueue( "vidc_core_workq"); if (!core->vidc_core_workq) { - dprintk(VIDC_ERR, "%s: create core workq failed\n", __func__); + d_vpr_e("%s: create core workq failed\n", __func__); goto err_core_workq; } mutex_lock(&vidc_driver->lock); @@ -570,7 +566,7 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) vidc_driver->sku_version = core->resources.sku_version; - dprintk(VIDC_HIGH, "populating sub devices\n"); + d_vpr_h("populating sub devices\n"); /* * Trigger probe for each sub-device i.e. qcom,msm-vidc,context-bank. * When msm_vidc_probe is called for each sub-device, parse the @@ -580,7 +576,7 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) rc = of_platform_populate(pdev->dev.of_node, msm_vidc_dt_match, NULL, &pdev->dev); if (rc) { - dprintk(VIDC_ERR, "Failed to trigger probe for sub-devices\n"); + d_vpr_e("Failed to trigger probe for sub-devices\n"); goto err_fail_sub_device_probe; } @@ -661,13 +657,13 @@ static int msm_vidc_remove(struct platform_device *pdev) struct msm_vidc_core *core; if (!pdev) { - dprintk(VIDC_ERR, "%s invalid input %pK", __func__, pdev); + d_vpr_e("%s: invalid input %pK", __func__, pdev); return -EINVAL; } core = dev_get_drvdata(&pdev->dev); if (!core) { - dprintk(VIDC_ERR, "%s invalid core", __func__); + d_vpr_e("%s: invalid core", __func__); return -EINVAL; } @@ -712,7 +708,7 @@ static int msm_vidc_pm_suspend(struct device *dev) core = dev_get_drvdata(dev); if (!core) { - dprintk(VIDC_ERR, "%s invalid core\n", __func__); + d_vpr_e("%s: invalid core\n", __func__); return -EINVAL; } @@ -720,7 +716,7 @@ static int msm_vidc_pm_suspend(struct device *dev) if (rc == -ENOTSUPP) rc = 0; else if (rc) - dprintk(VIDC_ERR, "Failed to suspend: %d\n", rc); + d_vpr_e("Failed to suspend: %d\n", rc); return rc; @@ -728,7 +724,7 @@ static int msm_vidc_pm_suspend(struct device *dev) static int msm_vidc_pm_resume(struct device *dev) { - dprintk(VIDC_HIGH, "%s\n", __func__); + d_vpr_h("%s\n", __func__); return 0; } @@ -755,8 +751,7 @@ static int __init msm_vidc_init(void) vidc_driver = kzalloc(sizeof(*vidc_driver), GFP_KERNEL); if (!vidc_driver) { - dprintk(VIDC_ERR, - "Failed to allocate memroy for msm_vidc_drv\n"); + d_vpr_e("Failed to allocate memroy for msm_vidc_drv\n"); return -ENOMEM; } @@ -764,13 +759,11 @@ static int __init msm_vidc_init(void) mutex_init(&vidc_driver->lock); vidc_driver->debugfs_root = msm_vidc_debugfs_init_drv(); if (!vidc_driver->debugfs_root) - dprintk(VIDC_ERR, - "Failed to create debugfs for msm_vidc\n"); + d_vpr_e("Failed to create debugfs for msm_vidc\n"); rc = platform_driver_register(&msm_vidc_driver); if (rc) { - dprintk(VIDC_ERR, - "Failed to register platform driver\n"); + d_vpr_e("Failed to register platform driver\n"); debugfs_remove_recursive(vidc_driver->debugfs_root); kfree(vidc_driver); vidc_driver = NULL; diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 4e309de188bd..edc8d26a9182 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -515,7 +515,7 @@ int msm_vdec_update_stream_output_mode(struct msm_vidc_inst *inst) u32 fourcc; if (!inst) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } @@ -548,7 +548,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) u32 color_format; if (!inst || !f) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters %pK %pK\n", __func__, inst, f); return -EINVAL; } @@ -562,9 +562,9 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) fmt = &inst->fmts[OUTPUT_PORT]; fmt_desc = msm_comm_get_pixel_fmt_fourcc(vdec_output_formats, ARRAY_SIZE(vdec_output_formats), - f->fmt.pix_mp.pixelformat); + f->fmt.pix_mp.pixelformat, inst->sid); if (!fmt_desc) { - dprintk(VIDC_ERR, "Invalid fmt set : %x\n", + s_vpr_e(inst->sid, "Invalid fmt set : %x\n", f->fmt.pix_mp.pixelformat); return -EINVAL; } @@ -586,7 +586,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) mplane->plane_fmt[1].sizeimage = msm_vidc_calculate_dec_output_extra_size(inst); color_format = msm_comm_convert_color_fmt( - f->fmt.pix_mp.pixelformat); + f->fmt.pix_mp.pixelformat, inst->sid); mplane->plane_fmt[0].bytesperline = VENUS_Y_STRIDE(color_format, f->fmt.pix_mp.width); mplane->plane_fmt[0].reserved[0] = @@ -601,14 +601,14 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) rc = msm_vidc_check_session_supported(inst); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: session not supported\n", __func__); goto err_invalid_fmt; } rc = msm_vdec_update_stream_output_mode(inst); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: failed to update output stream mode\n", __func__); goto err_invalid_fmt; @@ -619,9 +619,9 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) fmt = &inst->fmts[INPUT_PORT]; fmt_desc = msm_comm_get_pixel_fmt_fourcc(vdec_input_formats, ARRAY_SIZE(vdec_input_formats), - f->fmt.pix_mp.pixelformat); + f->fmt.pix_mp.pixelformat, inst->sid); if (!fmt_desc) { - dprintk(VIDC_ERR, "Invalid fmt set : %x\n", + s_vpr_e(inst->sid, "Invalid fmt set : %x\n", f->fmt.pix_mp.pixelformat); return -EINVAL; } @@ -631,7 +631,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) if (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_VP9) { if (msm_vidc_check_for_vp9d_overload(inst->core)) { - dprintk(VIDC_ERR, "VP9 Decode overload\n"); + s_vpr_e(inst->sid, "VP9 Decode overload\n"); rc = -ENOTSUPP; goto err_invalid_fmt; } @@ -644,7 +644,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) mplane->pixelformat = f->fmt.pix_mp.pixelformat; rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE); if (rc) { - dprintk(VIDC_ERR, "Failed to open instance\n"); + s_vpr_e(inst->sid, "Failed to open instance\n"); goto err_invalid_fmt; } @@ -653,7 +653,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) rc = msm_vidc_check_session_supported(inst); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: session not supported\n", __func__); goto err_invalid_fmt; } @@ -694,7 +694,7 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) msm_vidc_calculate_dec_input_frame_size(inst); memcpy(f, fmt, sizeof(struct v4l2_format)); } else { - dprintk(VIDC_ERR, "%s - Unsupported buf type: %d\n", + s_vpr_e(inst->sid, "%s: Unsupported buf type: %d\n", __func__, f->type); return -EINVAL; } @@ -708,16 +708,15 @@ int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) int rc = 0; if (!inst || !f) { - dprintk(VIDC_ERR, - "Invalid input, inst = %pK, f = %pK\n", inst, f); + d_vpr_e("Invalid input, inst = %pK, f = %pK\n", inst, f); return -EINVAL; } if (f->type == OUTPUT_MPLANE) { fmt_desc = msm_comm_get_pixel_fmt_index(vdec_output_formats, - ARRAY_SIZE(vdec_output_formats), f->index); + ARRAY_SIZE(vdec_output_formats), f->index, inst->sid); } else if (f->type == INPUT_MPLANE) { fmt_desc = msm_comm_get_pixel_fmt_index(vdec_input_formats, - ARRAY_SIZE(vdec_input_formats), f->index); + ARRAY_SIZE(vdec_input_formats), f->index, inst->sid); f->flags = V4L2_FMT_FLAG_COMPRESSED; } @@ -727,7 +726,7 @@ int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) sizeof(f->description)); f->pixelformat = fmt_desc->fourcc; } else { - dprintk(VIDC_HIGH, "No more formats found\n"); + s_vpr_h(inst->sid, "No more formats found\n"); rc = -EINVAL; } return rc; @@ -741,7 +740,7 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) struct v4l2_format *f = NULL; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "Invalid input = %pK\n", inst); + d_vpr_e("Invalid input = %pK\n", inst); return -EINVAL; } core = inst->core; @@ -757,9 +756,10 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) f->fmt.pix_mp.plane_fmt[1].sizeimage = msm_vidc_calculate_dec_output_extra_size(inst); fmt_desc = msm_comm_get_pixel_fmt_fourcc(vdec_output_formats, - ARRAY_SIZE(vdec_output_formats), f->fmt.pix_mp.pixelformat); + ARRAY_SIZE(vdec_output_formats), + f->fmt.pix_mp.pixelformat, inst->sid); if (!fmt_desc) { - dprintk(VIDC_ERR, "Invalid fmt set : %x\n", + s_vpr_e(inst->sid, "Invalid fmt set: %x\n", f->fmt.pix_mp.pixelformat); return -EINVAL; } @@ -775,9 +775,10 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) f->fmt.pix_mp.plane_fmt[0].sizeimage = msm_vidc_calculate_dec_input_frame_size(inst); fmt_desc = msm_comm_get_pixel_fmt_fourcc(vdec_input_formats, - ARRAY_SIZE(vdec_input_formats), f->fmt.pix_mp.pixelformat); + ARRAY_SIZE(vdec_input_formats), f->fmt.pix_mp.pixelformat, + inst->sid); if (!fmt_desc) { - dprintk(VIDC_ERR, "Invalid fmt set : %x\n", + s_vpr_e(inst->sid, "Invalid fmt set: %x\n", f->fmt.pix_mp.pixelformat); return -EINVAL; } @@ -829,14 +830,12 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) int rc = 0; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } - dprintk(VIDC_HIGH, - "%s: %x : control name = %s, id = 0x%x value = %d\n", - __func__, hash32_ptr(inst->session), ctrl->name, - ctrl->id, ctrl->val); + s_vpr_h(inst->sid, "%s: control name = %s, id = 0x%x value = %d\n", + __func__, ctrl->name, ctrl->id, ctrl->val); switch (ctrl->id) { case V4L2_CID_MPEG_VIDEO_H264_PROFILE: @@ -844,18 +843,21 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE: - inst->profile = msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val); + inst->profile = msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val, + inst->sid); break; case V4L2_CID_MPEG_VIDEO_H264_LEVEL: case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL: case V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL: case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL: - inst->level = msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val); + inst->level = msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val, + inst->sid); break; case V4L2_CID_MPEG_VIDEO_HEVC_TIER: inst->level |= - (msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val) << 28); + (msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val, + inst->sid) << 28); break; case V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER: case V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_8BIT: @@ -868,9 +870,9 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) rc = msm_vidc_calculate_buffer_counts(inst); if (rc) { - dprintk(VIDC_ERR, - "%s: %x : failed to calculate thumbnail buffer count\n", - __func__, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, + "%s: failed to calculate thumbnail buffer count\n", + __func__); return rc; } break; @@ -879,7 +881,7 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (ctrl->val) inst->flags |= VIDC_SECURE; if (msm_comm_check_for_inst_overload(inst->core)) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: Instance count reached Max limit, rejecting session", __func__); return -ENOTSUPP; @@ -914,8 +916,7 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) inst->clk_data.low_latency_mode = !!ctrl->val; break; default: - dprintk(VIDC_ERR, - "Unknown control %#x\n", ctrl->id); + s_vpr_e(inst->sid, "Unknown control %#x\n", ctrl->id); break; } @@ -930,7 +931,7 @@ int msm_vdec_set_frame_size(struct msm_vidc_inst *inst) struct v4l2_format *f; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -939,12 +940,12 @@ int msm_vdec_set_frame_size(struct msm_vidc_inst *inst) frame_size.buffer_type = HFI_BUFFER_INPUT; frame_size.width = f->fmt.pix_mp.width; frame_size.height = f->fmt.pix_mp.height; - dprintk(VIDC_HIGH, "%s: input wxh %dx%d\n", __func__, + s_vpr_h(inst->sid, "%s: input wxh %dx%d\n", __func__, frame_size.width, frame_size.height); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_FRAME_SIZE, &frame_size, sizeof(frame_size)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -956,7 +957,7 @@ int msm_vdec_set_color_format(struct msm_vidc_inst *inst) struct msm_vidc_format_constraint *fmt_constraint; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -965,21 +966,20 @@ int msm_vdec_set_color_format(struct msm_vidc_inst *inst) msm_comm_get_hal_output_buffer(inst), inst->clk_data.opb_fourcc); if (rc) { - dprintk(VIDC_ERR, - "%s: set color format (%#x) failed\n", + s_vpr_e(inst->sid, "%s: set color format (%#x) failed\n", __func__, inst->clk_data.opb_fourcc); return rc; } fmt_constraint = msm_comm_get_pixel_fmt_constraints( dec_pix_format_constraints, ARRAY_SIZE(dec_pix_format_constraints), - inst->clk_data.opb_fourcc); + inst->clk_data.opb_fourcc, inst->sid); if (fmt_constraint) { rc = msm_comm_set_color_format_constraints(inst, msm_comm_get_hal_output_buffer(inst), fmt_constraint); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: Set constraints for color format %#x failed\n", __func__, inst->clk_data.opb_fourcc); return rc; @@ -997,7 +997,7 @@ int msm_vdec_set_input_buffer_counts(struct msm_vidc_inst *inst) enum hal_buffer buffer_type; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -1009,7 +1009,7 @@ int msm_vdec_set_input_buffer_counts(struct msm_vidc_inst *inst) fmt->count_actual, buffer_type); if (rc) { - dprintk(VIDC_ERR, "%s: failed to set bufreqs(%#x)\n", + s_vpr_e(inst->sid, "%s: failed to set bufreqs(%#x)\n", __func__, buffer_type); return -EINVAL; } @@ -1025,7 +1025,7 @@ int msm_vdec_set_output_buffer_counts(struct msm_vidc_inst *inst) enum hal_buffer buffer_type; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -1043,7 +1043,7 @@ int msm_vdec_set_output_buffer_counts(struct msm_vidc_inst *inst) fmt->count_min, HAL_BUFFER_OUTPUT); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: failed to set buffer count(%#x)\n", __func__, buffer_type); return -EINVAL; @@ -1054,7 +1054,7 @@ int msm_vdec_set_output_buffer_counts(struct msm_vidc_inst *inst) fmt->count_actual, buffer_type); if (rc) { - dprintk(VIDC_ERR, "%s: failed to set bufreqs(%#x)\n", + s_vpr_e(inst->sid, "%s: failed to set bufreqs(%#x)\n", __func__, buffer_type); return -EINVAL; } @@ -1069,7 +1069,7 @@ int msm_vdec_set_profile_level(struct msm_vidc_inst *inst) struct hfi_profile_level profile_level; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -1077,13 +1077,13 @@ int msm_vdec_set_profile_level(struct msm_vidc_inst *inst) profile_level.profile = inst->profile; profile_level.level = inst->level; - dprintk(VIDC_HIGH, "%s: %#x %#x\n", __func__, + s_vpr_h(inst->sid, "%s: %#x %#x\n", __func__, profile_level.profile, profile_level.level); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT, &profile_level, sizeof(profile_level)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -1096,13 +1096,13 @@ int msm_vdec_set_output_order(struct msm_vidc_inst *inst) u32 output_order; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER); - dprintk(VIDC_HIGH, "%s: %d\n", __func__, ctrl->val); + s_vpr_h(inst->sid, "%s: %d\n", __func__, ctrl->val); if (ctrl->val == V4L2_MPEG_MSM_VIDC_ENABLE) output_order = HFI_OUTPUT_ORDER_DECODE; else @@ -1112,7 +1112,7 @@ int msm_vdec_set_output_order(struct msm_vidc_inst *inst) HFI_PROPERTY_PARAM_VDEC_OUTPUT_ORDER, &output_order, sizeof(u32)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -1125,7 +1125,7 @@ int msm_vdec_set_sync_frame_mode(struct msm_vidc_inst *inst) struct hfi_enable hfi_property; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -1133,12 +1133,12 @@ int msm_vdec_set_sync_frame_mode(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE); hfi_property.enable = (bool)ctrl->val; - dprintk(VIDC_HIGH, "%s: %#x\n", __func__, hfi_property.enable); + s_vpr_h(inst->sid, "%s: %#x\n", __func__, hfi_property.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VDEC_THUMBNAIL_MODE, &hfi_property, sizeof(hfi_property)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -1151,7 +1151,7 @@ int msm_vdec_set_secure_mode(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -1164,18 +1164,18 @@ int msm_vdec_set_secure_mode(struct msm_vidc_inst *inst) codec == V4L2_PIX_FMT_H264 || codec == V4L2_PIX_FMT_VP9 || codec == V4L2_PIX_FMT_MPEG2)) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: Secure allowed for HEVC/H264/VP9/MPEG2\n", __func__); return -EINVAL; } } - dprintk(VIDC_HIGH, "%s: %#x\n", __func__, ctrl->val); + s_vpr_h(inst->sid, "%s: %#x\n", __func__, ctrl->val); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_SECURE_SESSION, &ctrl->val, sizeof(u32)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -1187,12 +1187,14 @@ int msm_vdec_set_output_stream_mode(struct msm_vidc_inst *inst) struct hfi_multi_stream multi_stream; struct hfi_frame_size frame_sz; struct v4l2_format *f; + u32 sid; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; + sid = inst->sid; if (is_primary_output_mode(inst)) { multi_stream.buffer_type = HFI_BUFFER_OUTPUT; @@ -1201,8 +1203,8 @@ int msm_vdec_set_output_stream_mode(struct msm_vidc_inst *inst) HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, &multi_stream, sizeof(multi_stream)); if (rc) { - dprintk(VIDC_ERR, - "%s: set prop multistream primary failed : %d\n", + s_vpr_e(sid, + "%s: set prop multistream primary failed: %d\n", __func__, rc); return rc; } @@ -1212,7 +1214,7 @@ int msm_vdec_set_output_stream_mode(struct msm_vidc_inst *inst) HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, &multi_stream, sizeof(multi_stream)); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(sid, "%s: set prop multistream primary2 failed : %d\n", __func__, rc); return rc; @@ -1229,7 +1231,7 @@ int msm_vdec_set_output_stream_mode(struct msm_vidc_inst *inst) HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, &multi_stream, sizeof(multi_stream)); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(sid, "%s: set prop multistream secondary failed : %d\n", __func__, rc); return rc; @@ -1240,8 +1242,8 @@ int msm_vdec_set_output_stream_mode(struct msm_vidc_inst *inst) HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, &multi_stream, sizeof(multi_stream)); if (rc) { - dprintk(VIDC_ERR, - "%s: set prop multistream secondary2 failed : %d\n", + s_vpr_e(sid, + "%s: set prop multistream secondary2 failed: %d\n", __func__, rc); return rc; } @@ -1249,15 +1251,14 @@ int msm_vdec_set_output_stream_mode(struct msm_vidc_inst *inst) f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; frame_sz.width = f->fmt.pix_mp.width; frame_sz.height = f->fmt.pix_mp.height; - dprintk(VIDC_HIGH, + s_vpr_h(sid, "frame_size: hal buffer type %d, width %d, height %d\n", frame_sz.buffer_type, frame_sz.width, frame_sz.height); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_FRAME_SIZE, &frame_sz, sizeof(frame_sz)); if (rc) { - dprintk(VIDC_ERR, - "%s: set prop frame_size failed\n", + s_vpr_e(sid, "%s: set prop frame_size failed\n", __func__); return rc; } @@ -1273,19 +1274,19 @@ int msm_vdec_set_priority(struct msm_vidc_inst *inst) struct hfi_enable hfi_property; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; hfi_property.enable = is_realtime_session(inst); - dprintk(VIDC_HIGH, "%s: %#x\n", __func__, hfi_property.enable); + s_vpr_h(inst->sid, "%s: %#x\n", __func__, hfi_property.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_REALTIME, &hfi_property, sizeof(hfi_property)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -1299,7 +1300,7 @@ int msm_vdec_set_conceal_color(struct msm_vidc_inst *inst) struct hfi_conceal_color conceal_color; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -1309,14 +1310,14 @@ int msm_vdec_set_conceal_color(struct msm_vidc_inst *inst) conceal_color.conceal_color_8bit = ctrl_8b->val; conceal_color.conceal_color_10bit = ctrl_10b->val; - dprintk(VIDC_HIGH, "%s: %#x %#x\n", __func__, + s_vpr_h(inst->sid, "%s: %#x %#x\n", __func__, conceal_color.conceal_color_8bit, conceal_color.conceal_color_10bit); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR, &conceal_color, sizeof(conceal_color)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -1439,9 +1440,9 @@ int msm_vdec_set_properties(struct msm_vidc_inst *inst) exit: if (rc) - dprintk(VIDC_ERR, "%s: failed with %d\n", __func__, rc); + s_vpr_e(inst->sid, "%s: failed with %d\n", __func__, rc); else - dprintk(VIDC_HIGH, "%s: set properties successful\n", __func__); + s_vpr_h(inst->sid, "%s: set properties successful\n", __func__); return rc; } diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 59b7b3b2e078..3dc2bc192faf 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1096,10 +1096,9 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) struct v4l2_format *f = NULL; if (!inst) { - dprintk(VIDC_ERR, "Invalid input = %pK\n", inst); + d_vpr_e("Invalid input = %pK\n", inst); return -EINVAL; } - f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; f->fmt.pix_mp.height = DEFAULT_HEIGHT; f->fmt.pix_mp.width = DEFAULT_WIDTH; @@ -1108,9 +1107,10 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) f->fmt.pix_mp.plane_fmt[0].sizeimage = msm_vidc_calculate_enc_output_frame_size(inst); fmt_desc = msm_comm_get_pixel_fmt_fourcc(venc_output_formats, - ARRAY_SIZE(venc_output_formats), f->fmt.pix_mp.pixelformat); + ARRAY_SIZE(venc_output_formats), + f->fmt.pix_mp.pixelformat, inst->sid); if (!fmt_desc) { - dprintk(VIDC_ERR, "Invalid fmt set : %x\n", + s_vpr_e(inst->sid, "Invalid fmt set : %x\n", f->fmt.pix_mp.pixelformat); return -EINVAL; } @@ -1131,9 +1131,10 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) f->fmt.pix_mp.plane_fmt[1].sizeimage = msm_vidc_calculate_enc_input_extra_size(inst); fmt_desc = msm_comm_get_pixel_fmt_fourcc(venc_input_formats, - ARRAY_SIZE(venc_input_formats), f->fmt.pix_mp.pixelformat); + ARRAY_SIZE(venc_input_formats), f->fmt.pix_mp.pixelformat, + inst->sid); if (!fmt_desc) { - dprintk(VIDC_ERR, "Invalid fmt set : %x\n", + s_vpr_e(inst->sid, "Invalid fmt set : %x\n", f->fmt.pix_mp.pixelformat); return -EINVAL; } @@ -1183,16 +1184,15 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) int rc = 0; if (!inst || !f) { - dprintk(VIDC_ERR, - "Invalid input, inst = %pK, f = %pK\n", inst, f); + d_vpr_e("Invalid input, inst = %pK, f = %pK\n", inst, f); return -EINVAL; } if (f->type == OUTPUT_MPLANE) { fmt_desc = msm_comm_get_pixel_fmt_index(venc_output_formats, - ARRAY_SIZE(venc_output_formats), f->index); + ARRAY_SIZE(venc_output_formats), f->index, inst->sid); } else if (f->type == INPUT_MPLANE) { fmt_desc = msm_comm_get_pixel_fmt_index(venc_input_formats, - ARRAY_SIZE(venc_input_formats), f->index); + ARRAY_SIZE(venc_input_formats), f->index, inst->sid); f->flags = V4L2_FMT_FLAG_COMPRESSED; } @@ -1202,7 +1202,7 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) sizeof(f->description)); f->pixelformat = fmt_desc->fourcc; } else { - dprintk(VIDC_HIGH, "No more formats found\n"); + s_vpr_h(inst->sid, "No more formats found\n"); rc = -EINVAL; } return rc; @@ -1252,8 +1252,7 @@ static int msm_venc_set_csc(struct msm_vidc_inst *inst, HFI_PROPERTY_PARAM_VPE_COLOR_SPACE_CONVERSION, &vpe_csc, sizeof(vpe_csc)); if (rc) - dprintk(VIDC_ERR, - "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -1266,8 +1265,7 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) u32 color_format; if (!inst || !f) { - dprintk(VIDC_ERR, - "Invalid input, inst = %pK, format = %pK\n", inst, f); + d_vpr_e("Invalid input, inst = %pK, format = %pK\n", inst, f); return -EINVAL; } @@ -1281,9 +1279,9 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) fmt = &inst->fmts[OUTPUT_PORT]; fmt_desc = msm_comm_get_pixel_fmt_fourcc(venc_output_formats, ARRAY_SIZE(venc_output_formats), - f->fmt.pix_mp.pixelformat); + f->fmt.pix_mp.pixelformat, inst->sid); if (!fmt_desc) { - dprintk(VIDC_ERR, "Invalid fmt set : %x\n", + s_vpr_e(inst->sid, "Invalid fmt set : %x\n", f->fmt.pix_mp.pixelformat); return -EINVAL; } @@ -1300,14 +1298,16 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) if (!inst->profile) { rc = msm_venc_set_default_profile(inst); if (rc) { - dprintk(VIDC_ERR, "%s: Failed to set default profile type\n", __func__); + s_vpr_e(inst->sid, + "%s: Failed to set default profile type\n", + __func__); goto exit; } } rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE); if (rc) { - dprintk(VIDC_ERR, "Failed to open instance\n"); + s_vpr_e(inst->sid, "Failed to open instance\n"); goto exit; } @@ -1319,7 +1319,7 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) rc = msm_vidc_check_session_supported(inst); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: session not supported\n", __func__); goto exit; } @@ -1329,9 +1329,9 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) fmt = &inst->fmts[INPUT_PORT]; fmt_desc = msm_comm_get_pixel_fmt_fourcc(venc_input_formats, ARRAY_SIZE(venc_input_formats), - f->fmt.pix_mp.pixelformat); + f->fmt.pix_mp.pixelformat, inst->sid); if (!fmt_desc) { - dprintk(VIDC_ERR, "Invalid fmt set : %x\n", + s_vpr_e(inst->sid, "Invalid fmt set : %x\n", f->fmt.pix_mp.pixelformat); return -EINVAL; } @@ -1352,7 +1352,7 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) mplane->plane_fmt[1].sizeimage = msm_vidc_calculate_enc_input_extra_size(inst); color_format = msm_comm_convert_color_fmt( - f->fmt.pix_mp.pixelformat); + f->fmt.pix_mp.pixelformat, inst->sid); mplane->plane_fmt[0].bytesperline = VENUS_Y_STRIDE(color_format, f->fmt.pix_mp.width); mplane->plane_fmt[0].reserved[0] = @@ -1367,14 +1367,14 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) rc = msm_vidc_check_session_supported(inst); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: session not supported\n", __func__); goto exit; } memcpy(f, &fmt->v4l2_fmt, sizeof(struct v4l2_format)); } else { - dprintk(VIDC_ERR, "%s - Unsupported buf type: %d\n", + s_vpr_e(inst->sid, "%s: Unsupported buf type: %d\n", __func__, f->type); rc = -EINVAL; goto exit; @@ -1386,8 +1386,7 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) int msm_venc_set_default_profile(struct msm_vidc_inst *inst) { if (!inst) { - dprintk(VIDC_ERR, - "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -1398,8 +1397,8 @@ int msm_venc_set_default_profile(struct msm_vidc_inst *inst) else if (get_v4l2_codec(inst) == V4L2_PIX_FMT_H264) inst->profile = HFI_H264_PROFILE_HIGH; else - dprintk(VIDC_ERR, - "%s: Invalid codec type %#x\n", __func__, get_v4l2_codec(inst)); + s_vpr_e(inst->sid, "%s: Invalid codec type %#x\n", + __func__, get_v4l2_codec(inst)); return 0; } @@ -1425,7 +1424,7 @@ int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) } memcpy(f, fmt, sizeof(struct v4l2_format)); } else { - dprintk(VIDC_ERR, "%s - Unsupported buf type: %d\n", + s_vpr_e(inst->sid, "%s: Unsupported buf type: %d\n", __func__, f->type); return -EINVAL; } @@ -1447,8 +1446,7 @@ static int msm_venc_resolve_rc_enable(struct msm_vidc_inst *inst, u32 codec; if (!ctrl->val) { - dprintk(VIDC_HIGH, - "RC is not enabled. Setting RC OFF\n"); + s_vpr_h(inst->sid, "RC is not enabled. Setting RC OFF\n"); inst->rc_type = RATE_CONTROL_OFF; } else { rc_mode = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE_MODE); @@ -1459,7 +1457,7 @@ static int msm_venc_resolve_rc_enable(struct msm_vidc_inst *inst, if (msm_vidc_lossless_encode && (codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264)) { - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "Reset RC mode to RC_LOSSLESS for HEVC lossless encoding\n"); inst->rc_type = RATE_CONTROL_LOSSLESS; } @@ -1470,20 +1468,19 @@ static int msm_venc_resolve_rate_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) { if (inst->rc_type == RATE_CONTROL_LOSSLESS) { - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "Skip RC mode when enabling lossless encoding\n"); return 0; } if (inst->rc_type == RATE_CONTROL_OFF) { - dprintk(VIDC_ERR, - "RC is not enabled.\n"); + s_vpr_e(inst->sid, "RC is not enabled.\n"); return -EINVAL; } if ((ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) && get_v4l2_codec(inst) != V4L2_PIX_FMT_HEVC) { - dprintk(VIDC_ERR, "CQ supported only for HEVC\n"); + s_vpr_e(inst->sid, "CQ supported only for HEVC\n"); return -EINVAL; } inst->rc_type = ctrl->val; @@ -1498,34 +1495,33 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) u32 i_qp_min, i_qp_max, p_qp_min, p_qp_max, b_qp_min, b_qp_max; struct v4l2_format *f; u32 codec; + u32 sid; if (!inst || !inst->core || !inst->core->device || !ctrl) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } mdisp_sei = &(inst->hdr10_sei_params.disp_color_sei); cll_sei = &(inst->hdr10_sei_params.cll_sei); codec = get_v4l2_codec(inst); + sid = inst->sid; - dprintk(VIDC_HIGH, - "%s: %x : name %s, id 0x%x value %d\n", - __func__, hash32_ptr(inst->session), ctrl->name, - ctrl->id, ctrl->val); + s_vpr_h(sid, "%s: name %s, id 0x%x value %d\n", + __func__, ctrl->name, ctrl->id, ctrl->val); switch (ctrl->id) { case V4L2_CID_MPEG_VIDEO_GOP_SIZE: if (inst->state == MSM_VIDC_START_DONE) { if (inst->all_intra) { - dprintk(VIDC_HIGH, + s_vpr_h(sid, "%s: ignore dynamic gop size for all intra\n", __func__); break; } rc = msm_venc_set_intra_period(inst); if (rc) - dprintk(VIDC_ERR, - "%s: set intra period failed.\n", + s_vpr_e(sid, "%s: set intra period failed\n", __func__); } break; @@ -1533,16 +1529,15 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (inst->state == MSM_VIDC_START_DONE) { rc = msm_venc_set_request_keyframe(inst); if (rc) - dprintk(VIDC_ERR, - "%s: set bitrate failed\n", __func__); + s_vpr_e(sid, "%s: set bitrate failed\n", + __func__); } break; case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: { rc = msm_venc_resolve_rate_control(inst, ctrl); if (rc) - dprintk(VIDC_ERR, - "%s: set bitrate mode failed\n", __func__); + s_vpr_e(sid, "%s: set bitrate mode failed\n", __func__); break; } case V4L2_CID_MPEG_VIDEO_BITRATE: @@ -1550,8 +1545,8 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (inst->state == MSM_VIDC_START_DONE) { rc = msm_venc_set_bitrate(inst); if (rc) - dprintk(VIDC_ERR, - "%s: set bitrate failed\n", __func__); + s_vpr_e(sid, "%s: set bitrate failed\n", + __func__); } break; case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE: @@ -1561,8 +1556,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (inst->state == MSM_VIDC_START_DONE) { rc = msm_venc_set_frame_rate(inst); if (rc) - dprintk(VIDC_ERR, - "%s: set frame rate failed\n", + s_vpr_e(sid, "%s: set frame rate failed\n", __func__); } break; @@ -1570,7 +1564,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: if (codec != V4L2_PIX_FMT_HEVC && codec != V4L2_PIX_FMT_H264) { - dprintk(VIDC_ERR, + s_vpr_e(sid, "Slice mode not supported for encoder %#x\n", codec); rc = -ENOTSUPP; @@ -1585,8 +1579,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (inst->state == MSM_VIDC_START_DONE) { rc = msm_venc_set_ltr_useframe(inst); if (rc) - dprintk(VIDC_ERR, - "%s: ltr useframe failed\n", + s_vpr_e(sid, "%s: ltr useframe failed\n", __func__); } break; @@ -1594,8 +1587,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (inst->state == MSM_VIDC_START_DONE) { rc = msm_venc_set_ltr_markframe(inst); if (rc) - dprintk(VIDC_ERR, - "%s: ltr markframe failed\n", + s_vpr_e(sid, "%s: ltr markframe failed\n", __func__); } break; @@ -1610,8 +1602,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (inst->state == MSM_VIDC_START_DONE) { rc = msm_venc_set_operating_rate(inst); if (rc) - dprintk(VIDC_ERR, - "%s: set operating rate failed\n", + s_vpr_e(sid, "%s: set operating rate failed\n", __func__); } break; @@ -1622,7 +1613,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) u32 info_type = ((u32)ctrl->val >> 28) & 0xF; u32 val = (ctrl->val & 0xFFFFFFF); - dprintk(VIDC_HIGH, "Ctrl:%d, HDR Info with value %u (%#X)", + s_vpr_h(sid, "Ctrl:%d, HDR Info with value %u (%#X)", info_type, val, ctrl->val); switch (info_type) { case MSM_VIDC_RGB_PRIMARY_00: @@ -1662,9 +1653,9 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) cll_sei->nMaxPicAverageLight = val; break; default: - dprintk(VIDC_ERR, + s_vpr_e(sid, "Unknown Ctrl:%d, not part of HDR Info with value %u", - info_type, val); + info_type, val); } } break; @@ -1693,22 +1684,21 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: rc = msm_venc_resolve_rc_enable(inst, ctrl); if (rc) - dprintk(VIDC_ERR, - "%s: set rc enable failed.\n", __func__); + s_vpr_e(sid, "%s: set rc enable failed\n", __func__); break; case V4L2_CID_MPEG_VIDEO_H264_PROFILE: case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: - inst->profile = msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val); + inst->profile = msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val, sid); break; case V4L2_CID_MPEG_VIDEO_H264_LEVEL: case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL: - inst->level = msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val); + inst->level = msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val, sid); break; case V4L2_CID_MPEG_VIDEO_HEVC_TIER: inst->level |= - (msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val) << 28); + (msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val, sid) << 28); break; case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP: case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP: @@ -1724,7 +1714,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) (ctrl->val & 0xff) > i_qp_max || ((ctrl->val >> 8) & 0xff) > p_qp_max || ((ctrl->val >> 16) & 0xff) > b_qp_max) { - dprintk(VIDC_ERR, "Invalid QP %#x\n", ctrl->val); + s_vpr_e(sid, "Invalid QP %#x\n", ctrl->val); return -EINVAL; } if (ctrl->id == V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP) @@ -1736,14 +1726,14 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) i_qp_min = inst->capability.cap[CAP_I_FRAME_QP].min; i_qp_max = inst->capability.cap[CAP_I_FRAME_QP].max; if (ctrl->val < i_qp_min || ctrl->val > i_qp_max) { - dprintk(VIDC_ERR, "Invalid I QP %#x\n", ctrl->val); + s_vpr_e(sid, "Invalid I QP %#x\n", ctrl->val); return -EINVAL; } inst->client_set_ctrls |= CLIENT_SET_I_QP; if (inst->state == MSM_VIDC_START_DONE) { rc = msm_venc_set_dyn_qp(inst, ctrl); if (rc) - dprintk(VIDC_ERR, + s_vpr_e(sid, "%s: setting dyn frame QP failed\n", __func__); } @@ -1752,7 +1742,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) p_qp_min = inst->capability.cap[CAP_P_FRAME_QP].min; p_qp_max = inst->capability.cap[CAP_P_FRAME_QP].max; if (ctrl->val < p_qp_min || ctrl->val > p_qp_max) { - dprintk(VIDC_ERR, "Invalid P QP %#x\n", ctrl->val); + s_vpr_e(sid, "Invalid P QP %#x\n", ctrl->val); return -EINVAL; } inst->client_set_ctrls |= CLIENT_SET_P_QP; @@ -1761,7 +1751,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) b_qp_min = inst->capability.cap[CAP_B_FRAME_QP].min; b_qp_max = inst->capability.cap[CAP_B_FRAME_QP].max; if (ctrl->val < b_qp_min || ctrl->val > b_qp_max) { - dprintk(VIDC_ERR, "Invalid B QP %#x\n", ctrl->val); + s_vpr_e(sid, "Invalid B QP %#x\n", ctrl->val); return -EINVAL; } inst->client_set_ctrls |= CLIENT_SET_B_QP; @@ -1770,8 +1760,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (inst->state == MSM_VIDC_START_DONE) { rc = msm_venc_set_hp_layer(inst); if (rc) - dprintk(VIDC_ERR, - "%s: set dyn hp layer failed.\n", + s_vpr_e(sid, "%s: set dyn hp layer failed\n", __func__); } break; @@ -1779,8 +1768,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (inst->state == MSM_VIDC_START_DONE) { rc = msm_venc_set_base_layer_priority_id(inst); if (rc) - dprintk(VIDC_ERR, - "%s: set baselayer id failed.\n", + s_vpr_e(sid, "%s: set baselayer id failed\n", __func__); } break; @@ -1793,16 +1781,15 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (inst->state == MSM_VIDC_START_DONE) { rc = msm_venc_set_layer_bitrate(inst); if (rc) - dprintk(VIDC_ERR, - "%s: set layer bitrate failed\n", - __func__); + s_vpr_e(sid, "%s: set layer bitrate failed\n", + __func__); } break; case V4L2_CID_MPEG_VIDEO_B_FRAMES: if (inst->state == MSM_VIDC_START_DONE) { - dprintk(VIDC_ERR, - "%s: Dynamic setting of Bframe is not supported\n", - __func__); + s_vpr_e(sid, + "%s: Dynamic setting of Bframe is not supported\n", + __func__); return -EINVAL; } break; @@ -1810,8 +1797,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (inst->state == MSM_VIDC_START_DONE) { rc = msm_venc_set_blur_resolution(inst); if (rc) - dprintk(VIDC_ERR, - "%s: set blur resolution failed\n", + s_vpr_e(sid, "%s: set blur resolution failed\n", __func__); } break; @@ -1820,9 +1806,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (inst->state == MSM_VIDC_START_DONE) { rc = msm_venc_set_dynamic_flip(inst); if (rc) - dprintk(VIDC_ERR, - "%s: set flip failed\n", - __func__); + s_vpr_e(sid, "%s: set flip failed\n", __func__); } break; case V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY: @@ -1864,11 +1848,11 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDEO_VBV_DELAY: case V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS: case V4L2_CID_MPEG_VIDC_SUPERFRAME: - dprintk(VIDC_HIGH, "Control set: ID : %x Val : %d\n", + s_vpr_h(sid, "Control set: ID : %x Val : %d\n", ctrl->id, ctrl->val); break; default: - dprintk(VIDC_ERR, "Unsupported index: %x\n", ctrl->id); + s_vpr_e(sid, "Unsupported index: %x\n", ctrl->id); rc = -ENOTSUPP; break; } @@ -1884,7 +1868,7 @@ int msm_venc_set_frame_size(struct msm_vidc_inst *inst) struct v4l2_format *f; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -1893,12 +1877,12 @@ int msm_venc_set_frame_size(struct msm_vidc_inst *inst) frame_sz.buffer_type = HFI_BUFFER_INPUT; frame_sz.width = f->fmt.pix_mp.width; frame_sz.height = f->fmt.pix_mp.height; - dprintk(VIDC_HIGH, "%s: input %d %d\n", __func__, + s_vpr_h(inst->sid, "%s: input %d %d\n", __func__, frame_sz.width, frame_sz.height); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_FRAME_SIZE, &frame_sz, sizeof(frame_sz)); if (rc) { - dprintk(VIDC_ERR, "%s: failed to set input frame size %d %d\n", + s_vpr_e(inst->sid, "%s: failed to set input frame size %d %d\n", __func__, frame_sz.width, frame_sz.height); return rc; } @@ -1907,12 +1891,12 @@ int msm_venc_set_frame_size(struct msm_vidc_inst *inst) frame_sz.buffer_type = HFI_BUFFER_OUTPUT; frame_sz.width = f->fmt.pix_mp.width; frame_sz.height = f->fmt.pix_mp.height; - dprintk(VIDC_HIGH, "%s: output %d %d\n", __func__, + s_vpr_h(inst->sid, "%s: output %d %d\n", __func__, frame_sz.width, frame_sz.height); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_FRAME_SIZE, &frame_sz, sizeof(frame_sz)); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: failed to set output frame size %d %d\n", __func__, frame_sz.width, frame_sz.height); return rc; @@ -1930,7 +1914,7 @@ int msm_venc_set_frame_rate(struct msm_vidc_inst *inst) u32 fps_max; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -1943,21 +1927,22 @@ int msm_venc_set_frame_rate(struct msm_vidc_inst *inst) fps_max = capability->cap[CAP_FRAMERATE].max; if (inst->clk_data.frame_rate >> 16 > fps_max) { - dprintk(VIDC_ERR, "%s: Unsupported frame rate\n", - __func__); + s_vpr_e(inst->sid, + "%s: Unsupported frame rate, fps %u, max_fps %u\n", + __func__, inst->clk_data.frame_rate >> 16, fps_max); return -ENOTSUPP; } frame_rate.buffer_type = HFI_BUFFER_OUTPUT; frame_rate.frame_rate = inst->clk_data.frame_rate; - dprintk(VIDC_HIGH, "%s: %#x\n", __func__, frame_rate.frame_rate); + s_vpr_h(inst->sid, "%s: %#x\n", __func__, frame_rate.frame_rate); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_FRAME_RATE, &frame_rate, sizeof(frame_rate)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -1977,13 +1962,13 @@ int msm_venc_set_color_format(struct msm_vidc_inst *inst) fmt_constraints = msm_comm_get_pixel_fmt_constraints( enc_pix_format_constraints, ARRAY_SIZE(enc_pix_format_constraints), - f->fmt.pix_mp.pixelformat); + f->fmt.pix_mp.pixelformat, inst->sid); if (fmt_constraints) { rc = msm_comm_set_color_format_constraints(inst, HAL_BUFFER_INPUT, fmt_constraints); if (rc) { - dprintk(VIDC_ERR, "Set constraints for %d failed\n", + s_vpr_e(inst->sid, "Set constraints for %d failed\n", f->fmt.pix_mp.pixelformat); return rc; } @@ -1999,7 +1984,7 @@ int msm_venc_set_buffer_counts(struct msm_vidc_inst *inst) enum hal_buffer buffer_type; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -2010,7 +1995,7 @@ int msm_venc_set_buffer_counts(struct msm_vidc_inst *inst) fmt->count_actual, buffer_type); if (rc) { - dprintk(VIDC_ERR, "%s: failed to set bufcounts(%#x)\n", + s_vpr_e(inst->sid, "%s: failed to set bufcounts(%#x)\n", __func__, buffer_type); return -EINVAL; } @@ -2022,7 +2007,7 @@ int msm_venc_set_buffer_counts(struct msm_vidc_inst *inst) fmt->count_actual, buffer_type); if (rc) { - dprintk(VIDC_ERR, "%s: failed to set buf counts(%#x)\n", + s_vpr_e(inst->sid, "%s: failed to set buf counts(%#x)\n", __func__, buffer_type); return -EINVAL; } @@ -2039,7 +2024,7 @@ int msm_venc_set_secure_mode(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -2051,18 +2036,18 @@ int msm_venc_set_secure_mode(struct msm_vidc_inst *inst) codec = get_v4l2_codec(inst); if (!(codec == V4L2_PIX_FMT_H264 || codec == V4L2_PIX_FMT_HEVC)) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: Secure mode only allowed for HEVC/H264\n", __func__); return -EINVAL; } } - dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); + s_vpr_h(inst->sid, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_SECURE_SESSION, &enable, sizeof(enable)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -2074,18 +2059,18 @@ int msm_venc_set_priority(struct msm_vidc_inst *inst) struct hfi_enable enable; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; enable.enable = is_realtime_session(inst); - dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); + s_vpr_h(inst->sid, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_REALTIME, &enable, sizeof(enable)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -2098,7 +2083,7 @@ int msm_venc_set_operating_rate(struct msm_vidc_inst *inst) struct hfi_operating_rate op_rate; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -2106,11 +2091,11 @@ int msm_venc_set_operating_rate(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE); op_rate.operating_rate = ctrl->val; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, op_rate.operating_rate >> 16); + s_vpr_h(inst->sid, "%s: %d\n", __func__, op_rate.operating_rate >> 16); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_OPERATING_RATE, &op_rate, sizeof(op_rate)); if (rc) { - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -2124,27 +2109,26 @@ int msm_venc_set_profile_level(struct msm_vidc_inst *inst) struct hfi_profile_level profile_level; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; if (!inst->profile) { - dprintk(VIDC_ERR, - "%s: skip as client did not set profile\n", + s_vpr_e(inst->sid, "%s: skip as client did not set profile\n", __func__); return -EINVAL; } profile_level.profile = inst->profile; profile_level.level = inst->level; - dprintk(VIDC_HIGH, "%s: %#x %#x\n", __func__, + s_vpr_h(inst->sid, "%s: %#x %#x\n", __func__, profile_level.profile, profile_level.level); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT, &profile_level, sizeof(profile_level)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -2157,7 +2141,7 @@ int msm_venc_set_idr_period(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -2168,12 +2152,12 @@ int msm_venc_set_idr_period(struct msm_vidc_inst *inst) idr_period.idr_period = 1; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, idr_period.idr_period); + s_vpr_h(inst->sid, "%s: %d\n", __func__, idr_period.idr_period); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD, &idr_period, sizeof(idr_period)); if (rc) { - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -2235,8 +2219,8 @@ void msm_venc_decide_bframe(struct msm_vidc_inst *inst) * Hence, forcefully enable bframe */ inst->prop.bframe_changed = true; - update_ctrl(bframe_ctrl, MAX_NUM_B_FRAMES); - dprintk(VIDC_HIGH, "Bframe is forcefully enabled\n"); + update_ctrl(bframe_ctrl, MAX_NUM_B_FRAMES, inst->sid); + s_vpr_h(inst->sid, "Bframe is forcefully enabled\n"); } else { /* * Native recorder is not enabled @@ -2251,7 +2235,7 @@ void msm_venc_decide_bframe(struct msm_vidc_inst *inst) if (ctrl->val) goto disable_bframe; - dprintk(VIDC_HIGH, "Bframe can be enabled!\n"); + s_vpr_h(inst->sid, "Bframe can be enabled!\n"); return; disable_bframe: @@ -2262,10 +2246,10 @@ void msm_venc_decide_bframe(struct msm_vidc_inst *inst) * Hence, forcefully disable bframe */ inst->prop.bframe_changed = true; - update_ctrl(bframe_ctrl, 0); - dprintk(VIDC_HIGH, "Bframe is forcefully disabled!\n"); + update_ctrl(bframe_ctrl, 0, inst->sid); + s_vpr_h(inst->sid, "Bframe is forcefully disabled!\n"); } else { - dprintk(VIDC_HIGH, "Bframe is disabled\n"); + s_vpr_h(inst->sid, "Bframe is disabled\n"); } } @@ -2276,18 +2260,18 @@ int msm_venc_set_adaptive_bframes(struct msm_vidc_inst *inst) struct hfi_enable enable; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; enable.enable = true; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); + s_vpr_h(inst->sid, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_ADAPTIVE_B, &enable, sizeof(enable)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -2313,7 +2297,7 @@ void msm_venc_adjust_gop_size(struct msm_vidc_inst *inst) /* Forcefully enabled */ val = gop_size_ctrl->val / (1 + MAX_NUM_B_FRAMES); - update_ctrl(gop_size_ctrl, val); + update_ctrl(gop_size_ctrl, val, inst->sid); } /* @@ -2333,7 +2317,7 @@ void msm_venc_adjust_gop_size(struct msm_vidc_inst *inst) else val = min_gop_size; - update_ctrl(gop_size_ctrl, val); + update_ctrl(gop_size_ctrl, val, inst->sid); } } @@ -2345,7 +2329,7 @@ int msm_venc_set_intra_period(struct msm_vidc_inst *inst) struct hfi_intra_period intra_period; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -2364,19 +2348,19 @@ int msm_venc_set_intra_period(struct msm_vidc_inst *inst) if (inst->state == MSM_VIDC_START_DONE && !intra_period.pframes && !intra_period.bframes) { - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "%s: Switch from IPPP to All Intra is not allowed\n", __func__); return rc; } - dprintk(VIDC_HIGH, "%s: %d %d\n", __func__, intra_period.pframes, + s_vpr_h(inst->sid, "%s: %d %d\n", __func__, intra_period.pframes, intra_period.bframes); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD, &intra_period, sizeof(intra_period)); if (rc) { - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -2384,7 +2368,7 @@ int msm_venc_set_intra_period(struct msm_vidc_inst *inst) /* Enable adaptive bframes as nbframes!= 0 */ rc = msm_venc_set_adaptive_bframes(inst); if (rc) { - dprintk(VIDC_ERR, "%s: set property failed\n", + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -2398,16 +2382,16 @@ int msm_venc_set_request_keyframe(struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; - dprintk(VIDC_HIGH, "%s\n", __func__); + s_vpr_h(inst->sid, "%s\n", __func__); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME, NULL, 0); if (rc) { - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -2423,7 +2407,7 @@ int msm_venc_set_rate_control(struct msm_vidc_inst *inst) struct v4l2_format *f; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } @@ -2466,17 +2450,17 @@ int msm_venc_set_rate_control(struct msm_vidc_inst *inst) break; default: hfi_rc = HFI_RATE_CONTROL_OFF; - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Invalid Rate control setting: %d Default RCOFF\n", inst->rc_type); break; } - dprintk(VIDC_HIGH, "%s: %d\n", __func__, inst->rc_type); + s_vpr_h(inst->sid, "%s: %d\n", __func__, inst->rc_type); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_RATE_CONTROL, &hfi_rc, sizeof(u32)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -2494,7 +2478,7 @@ int msm_venc_set_vbv_delay(struct msm_vidc_inst *inst) struct v4l2_format *f; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } @@ -2546,16 +2530,15 @@ int msm_venc_set_vbv_delay(struct msm_vidc_inst *inst) set_vbv_delay: inst->clk_data.is_legacy_cbr = is_legacy_cbr; hrd_buf_size.vbv_hrd_buf_size = buf_size; - dprintk(VIDC_HIGH, "Set hrd_buf_size %d", - hrd_buf_size.vbv_hrd_buf_size); + s_vpr_h(inst->sid, + "Set hrd_buf_size %d", hrd_buf_size.vbv_hrd_buf_size); rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_CONFIG_VENC_VBV_HRD_BUF_SIZE, (void *)&hrd_buf_size, sizeof(hrd_buf_size)); if (rc) { - dprintk(VIDC_ERR, "%s: set HRD_BUF_SIZE %u failed\n", - __func__, - hrd_buf_size.vbv_hrd_buf_size); + s_vpr_e(inst->sid, "%s: set HRD_BUF_SIZE %u failed\n", + __func__, hrd_buf_size.vbv_hrd_buf_size); } return rc; } @@ -2569,7 +2552,7 @@ int msm_venc_set_input_timestamp_rc(struct msm_vidc_inst *inst) struct hfi_enable enable; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -2583,12 +2566,12 @@ int msm_venc_set_input_timestamp_rc(struct msm_vidc_inst *inst) */ enable.enable = !!ctrl->val; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); + s_vpr_h(inst->sid, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_DISABLE_RC_TIMESTAMP, &enable, sizeof(enable)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -2602,36 +2585,36 @@ int msm_venc_set_bitrate(struct msm_vidc_inst *inst) struct hfi_enable enable; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; if (inst->layer_bitrate) { - dprintk(VIDC_HIGH, "%s: Layer bitrate is enabled\n", __func__); + s_vpr_h(inst->sid, "%s: Layer bitrate is enabled\n", __func__); return 0; } enable.enable = 0; - dprintk(VIDC_HIGH, "%s: bitrate type: %d\n", + s_vpr_h(inst->sid, "%s: bitrate type: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_BITRATE_TYPE, &enable, sizeof(enable)); if (rc) { - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE); bitrate.bit_rate = ctrl->val; bitrate.layer_id = MSM_VIDC_ALL_LAYER_ID; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, bitrate.bit_rate); + s_vpr_h(inst->sid, "%s: %d\n", __func__, bitrate.bit_rate); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE, &bitrate, sizeof(bitrate)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -2648,7 +2631,7 @@ int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst) struct hfi_enable enable; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -2659,14 +2642,14 @@ int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst) V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); if (!max_layer->val || !layer->val) { - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "%s: Hierp layer not set. Ignore layer bitrate\n", __func__); goto error; } if (max_layer->val < layer->val) { - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "%s: Hierp layer greater than max isn't allowed\n", __func__); goto error; @@ -2688,16 +2671,14 @@ int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst) /* Set layer bitrates only when highest layer br ratio is 100. */ if (layer_br_ratios[layer->val-1]->val != MAX_BIT_RATE_RATIO || layer_br_ratios[0]->val == 0) { - dprintk(VIDC_HIGH, - "%s: Improper layer bitrate ratio\n", + s_vpr_h(inst->sid, "%s: Improper layer bitrate ratio\n", __func__); goto error; } for (i = layer->val - 1; i > 0; --i) { if (layer_br_ratios[i]->val == 0) { - dprintk(VIDC_HIGH, - "%s: Layer ratio must be non-zero\n", + s_vpr_h(inst->sid, "%s: Layer ratio must be non-zero\n", __func__); goto error; } @@ -2705,12 +2686,12 @@ int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst) } enable.enable = 1; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); + s_vpr_h(inst->sid, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_BITRATE_TYPE, &enable, sizeof(enable)); if (rc) { - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); goto error; } @@ -2719,15 +2700,14 @@ int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst) layer_br.bit_rate = bitrate->val * layer_br_ratios[i]->val / 100; layer_br.layer_id = i; - dprintk(VIDC_HIGH, - "%s: Bitrate for Layer[%u]: [%u]\n", + s_vpr_h(inst->sid, "%s: Bitrate for Layer[%u]: [%u]\n", __func__, layer_br.layer_id, layer_br.bit_rate); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE, &layer_br, sizeof(layer_br)); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: set property failed for layer: %u\n", __func__, layer_br.layer_id); goto error; @@ -2752,7 +2732,7 @@ int msm_venc_set_frame_qp(struct msm_vidc_inst *inst) struct hfi_quantization qp; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -2784,7 +2764,7 @@ int msm_venc_set_frame_qp(struct msm_vidc_inst *inst) return 0; } else { if (!(inst->client_set_ctrls & CLIENT_SET_I_QP)) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: Client value is not valid\n", __func__); return -EINVAL; } @@ -2800,12 +2780,12 @@ int msm_venc_set_frame_qp(struct msm_vidc_inst *inst) qp.qp_packed = i_qp->val | p_qp->val << 8 | b_qp->val << 16; - dprintk(VIDC_HIGH, "%s: layers %#x frames %#x qp_packed %#x\n", + s_vpr_h(inst->sid, "%s: layers %#x frames %#x qp_packed %#x\n", __func__, qp.layer_id, qp.enable, qp.qp_packed); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_FRAME_QP, &qp, sizeof(qp)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -2818,15 +2798,15 @@ int msm_venc_set_qp_range(struct msm_vidc_inst *inst) struct hfi_quantization_range qp_range; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; if (!(inst->client_set_ctrls & CLIENT_SET_MIN_QP) && !(inst->client_set_ctrls & CLIENT_SET_MAX_QP)) { - dprintk(VIDC_HIGH, - "%s: Client didn't set QP range.\n", __func__); + s_vpr_h(inst->sid, + "%s: Client didn't set QP range\n", __func__); return 0; } @@ -2839,15 +2819,14 @@ int msm_venc_set_qp_range(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP); qp_range.max_qp.qp_packed = ctrl->val; - dprintk(VIDC_HIGH, - "%s: layers %#x qp_min %#x qp_max %#x\n", + s_vpr_h(inst->sid, "%s: layers %#x qp_min %#x qp_max %#x\n", __func__, qp_range.min_qp.layer_id, qp_range.min_qp.qp_packed, qp_range.max_qp.qp_packed); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE, &qp_range, sizeof(qp_range)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -2859,15 +2838,16 @@ static void set_all_intra_preconditions(struct msm_vidc_inst *inst) /* Disable multi slice */ ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); if (ctrl->val) { - dprintk(VIDC_HIGH, "Disable multi slice for all intra\n"); - update_ctrl(ctrl, V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE); + d_vpr_h("Disable multi slice for all intra\n"); + update_ctrl(ctrl, V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE, + inst->sid); } /* Disable LTR */ ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); if (ctrl->val) { - dprintk(VIDC_HIGH, "Disable LTR for all intra\n"); - update_ctrl(ctrl, 0); + s_vpr_h(inst->sid, "Disable LTR for all intra\n"); + update_ctrl(ctrl, 0, inst->sid); } /* Disable Layer encoding */ @@ -2875,18 +2855,18 @@ static void set_all_intra_preconditions(struct msm_vidc_inst *inst) ctrl_t = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); if (ctrl->val || ctrl_t->val) { - dprintk(VIDC_HIGH, "Disable layer encoding for all intra\n"); - update_ctrl(ctrl, 0); - update_ctrl(ctrl_t, 0); + s_vpr_h(inst->sid, "Disable layer encoding for all intra\n"); + update_ctrl(ctrl, 0, inst->sid); + update_ctrl(ctrl_t, 0, inst->sid); } /* Disable IR */ ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM); ctrl_t = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB); if (ctrl->val || ctrl_t->val) { - dprintk(VIDC_HIGH, "Disable IR for all intra\n"); - update_ctrl(ctrl, 0); - update_ctrl(ctrl_t, 0); + s_vpr_h(inst->sid, "Disable IR for all intra\n"); + update_ctrl(ctrl, 0, inst->sid); + update_ctrl(ctrl_t, 0, inst->sid); } return; @@ -2899,15 +2879,15 @@ static void set_heif_preconditions(struct msm_vidc_inst *inst) /* Reset PFrames */ ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_GOP_SIZE); if (ctrl->val) { - dprintk(VIDC_HIGH, "Reset P-frame count for HEIF\n"); - update_ctrl(ctrl, 0); + d_vpr_h("Reset P-frame count for HEIF\n"); + update_ctrl(ctrl, 0, inst->sid); } /* Reset BFrames */ ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); if (ctrl->val) { - dprintk(VIDC_HIGH, "Reset B-frame count for HEIF\n"); - update_ctrl(ctrl, 0); + s_vpr_h(inst->sid, "Reset B-frame count for HEIF\n"); + update_ctrl(ctrl, 0, inst->sid); } return; @@ -2922,7 +2902,7 @@ int msm_venc_set_image_properties(struct msm_vidc_inst *inst) struct hfi_heic_grid_enable grid_enable; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -2933,13 +2913,13 @@ int msm_venc_set_image_properties(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY); frame_quality.frame_quality = ctrl->val; - dprintk(VIDC_HIGH, "%s: frame quality: %d\n", __func__, + s_vpr_h(inst->sid, "%s: frame quality: %d\n", __func__, frame_quality.frame_quality); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_HEIC_FRAME_QUALITY, &frame_quality, sizeof(frame_quality)); if (rc) - dprintk(VIDC_ERR, "%s: set frame quality failed\n", __func__); + s_vpr_e(inst->sid, "%s: set frame quality failed\n", __func__); ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE); @@ -2949,13 +2929,13 @@ int msm_venc_set_image_properties(struct msm_vidc_inst *inst) else grid_enable.grid_enable = true; - dprintk(VIDC_HIGH, "%s: grid enable: %d\n", __func__, + s_vpr_h(inst->sid, "%s: grid enable: %d\n", __func__, grid_enable.grid_enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_HEIC_GRID_ENABLE, &grid_enable, sizeof(grid_enable)); if (rc) - dprintk(VIDC_ERR, "%s: set grid enable failed\n", __func__); + s_vpr_e(inst->sid, "%s: set grid enable failed\n", __func__); set_all_intra_preconditions(inst); set_heif_preconditions(inst); @@ -2971,7 +2951,7 @@ int msm_venc_set_entropy_mode(struct msm_vidc_inst *inst) struct hfi_h264_entropy_control entropy; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -2982,15 +2962,15 @@ int msm_venc_set_entropy_mode(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE); entropy.entropy_mode = msm_comm_v4l2_to_hfi( V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, - ctrl->val); + ctrl->val, inst->sid); entropy.cabac_model = HFI_H264_CABAC_MODEL_2; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, entropy.entropy_mode); + s_vpr_h(inst->sid, "%s: %d\n", __func__, entropy.entropy_mode); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL, &entropy, sizeof(entropy)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -3010,7 +2990,7 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } @@ -3082,8 +3062,9 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst) } if (slice_mode == HFI_MULTI_SLICE_OFF) { - update_ctrl(ctrl, V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE); - update_ctrl(ctrl_t, 0); + update_ctrl(ctrl, V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE, + inst->sid); + update_ctrl(ctrl_t, 0, inst->sid); } set_and_exit: @@ -3091,14 +3072,14 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst) multi_slice_control.slice_size = slice_val; hdev = inst->core->device; - dprintk(VIDC_HIGH, "%s: %d %d\n", __func__, + s_vpr_h(inst->sid, "%s: %d %d\n", __func__, multi_slice_control.multi_slice, multi_slice_control.slice_size); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_CONTROL, &multi_slice_control, sizeof(multi_slice_control)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -3112,7 +3093,7 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst) struct v4l2_format *f; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -3147,13 +3128,13 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst) intra_refresh.mbs = 0; } - dprintk(VIDC_HIGH, "%s: %d %d\n", __func__, + s_vpr_h(inst->sid, "%s: %d %d\n", __func__, intra_refresh.mode, intra_refresh.mbs); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH, &intra_refresh, sizeof(intra_refresh)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -3166,7 +3147,7 @@ int msm_venc_set_bitrate_savings_mode(struct msm_vidc_inst *inst) struct hfi_enable enable; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -3174,17 +3155,17 @@ int msm_venc_set_bitrate_savings_mode(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS); enable.enable = !!ctrl->val; if (!ctrl->val && inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "Can't disable bitrate savings for non-VBR_CFR\n"); enable.enable = 1; } - dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); + s_vpr_h(inst->sid, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_BITRATE_SAVINGS, &enable, sizeof(enable)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -3200,7 +3181,7 @@ int msm_venc_set_loop_filter_mode(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -3214,18 +3195,18 @@ int msm_venc_set_loop_filter_mode(struct msm_vidc_inst *inst) ctrl_b = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA); h264_db_control.mode = msm_comm_v4l2_to_hfi( V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE, - ctrl->val); + ctrl->val, inst->sid); h264_db_control.slice_alpha_offset = ctrl_a->val; h264_db_control.slice_beta_offset = ctrl_b->val; - dprintk(VIDC_HIGH, "%s: %d %d %d\n", __func__, + s_vpr_h(inst->sid, "%s: %d %d %d\n", __func__, h264_db_control.mode, h264_db_control.slice_alpha_offset, h264_db_control.slice_beta_offset); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL, &h264_db_control, sizeof(h264_db_control)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -3239,7 +3220,7 @@ int msm_venc_set_sequence_header_mode(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -3254,12 +3235,12 @@ int msm_venc_set_sequence_header_mode(struct msm_vidc_inst *inst) else enable.enable = false; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); + s_vpr_h(inst->sid, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER, &enable, sizeof(enable)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -3273,7 +3254,7 @@ int msm_venc_set_au_delimiter_mode(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -3285,12 +3266,12 @@ int msm_venc_set_au_delimiter_mode(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_AU_DELIMITER); enable.enable = !!ctrl->val; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); + s_vpr_h(inst->sid, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_GENERATE_AUDNAL, &enable, sizeof(enable)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -3301,7 +3282,7 @@ int msm_venc_enable_hybrid_hp(struct msm_vidc_inst *inst) struct v4l2_ctrl *layer = NULL; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } @@ -3344,7 +3325,7 @@ int msm_venc_set_base_layer_priority_id(struct msm_vidc_inst *inst) u32 baselayerid; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -3352,7 +3333,7 @@ int msm_venc_set_base_layer_priority_id(struct msm_vidc_inst *inst) max_layer = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); if (max_layer->val <= 0) { - dprintk(VIDC_HIGH, "%s: Layer id can only be set with Hierp\n", + s_vpr_h(inst->sid, "%s: Layer id can only be set with Hierp\n", __func__); return 0; } @@ -3360,12 +3341,12 @@ int msm_venc_set_base_layer_priority_id(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID); baselayerid = ctrl->val; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, baselayerid); + s_vpr_h(inst->sid, "%s: %d\n", __func__, baselayerid); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_BASELAYER_PRIORITYID, &baselayerid, sizeof(baselayerid)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -3379,7 +3360,7 @@ int msm_venc_set_hp_max_layer(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -3393,7 +3374,7 @@ int msm_venc_set_hp_max_layer(struct msm_vidc_inst *inst) rc = msm_venc_enable_hybrid_hp(inst); if (rc) { - dprintk(VIDC_ERR, "%s: get hybrid hp decision failed\n", + s_vpr_e(inst->sid, "%s: get hybrid hp decision failed\n", __func__); return rc; } @@ -3406,21 +3387,20 @@ int msm_venc_set_hp_max_layer(struct msm_vidc_inst *inst) hp_layer = ctrl->val - 1; if (inst->hybrid_hp) { - dprintk(VIDC_HIGH, "%s: Hybrid hierp layer: %d\n", + s_vpr_h(inst->sid, "%s: Hybrid hierp layer: %d\n", __func__, hp_layer); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_HIER_P_HYBRID_MODE, &hp_layer, sizeof(hp_layer)); } else { - dprintk(VIDC_HIGH, "%s: Hierp max layer: %d\n", + s_vpr_h(inst->sid, "%s: Hierp max layer: %d\n", __func__, hp_layer); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER, &hp_layer, sizeof(hp_layer)); } if (rc) - dprintk(VIDC_ERR, - "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -3434,7 +3414,7 @@ int msm_venc_set_hp_layer(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -3444,7 +3424,7 @@ int msm_venc_set_hp_layer(struct msm_vidc_inst *inst) return 0; if (inst->hybrid_hp) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: Setting layer isn't allowed with hybrid hp\n", __func__); return 0; @@ -3454,9 +3434,10 @@ int msm_venc_set_hp_layer(struct msm_vidc_inst *inst) V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER); - + s_vpr_h(inst->sid, "%s: heir_layer: %d, max_hier_layer: %d\n", + __func__, ctrl->val, max_layer->val); if (max_layer->val < ctrl->val) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: HP layer count greater than max isn't allowed\n", __func__); return 0; @@ -3469,14 +3450,13 @@ int msm_venc_set_hp_layer(struct msm_vidc_inst *inst) if (ctrl->val) hp_layer = ctrl->val - 1; - dprintk(VIDC_HIGH, "%s: Hierp enhancement layer: %d\n", + s_vpr_h(inst->sid, "%s: Hierp enhancement layer: %d\n", __func__, hp_layer); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER, &hp_layer, sizeof(hp_layer)); if (rc) - dprintk(VIDC_ERR, - "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -3489,7 +3469,7 @@ int msm_venc_set_vpx_error_resilience(struct msm_vidc_inst *inst) struct hfi_enable enable; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -3500,12 +3480,12 @@ int msm_venc_set_vpx_error_resilience(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE); enable.enable = !!ctrl->val; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); + s_vpr_h(inst->sid, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_VPX_ERROR_RESILIENCE_MODE, &enable, sizeof(enable)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -3522,7 +3502,7 @@ int msm_venc_set_video_signal_info(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -3546,7 +3526,7 @@ int msm_venc_set_video_signal_info(struct msm_vidc_inst *inst) signal_info.transfer_characteristics = ctrl_tr->val; signal_info.matrix_coeffs = ctrl_mc->val; - dprintk(VIDC_HIGH, "%s: %d %d %d %d\n", __func__, + s_vpr_h(inst->sid, "%s: %d %d %d %d\n", __func__, signal_info.color_primaries, signal_info.video_full_range, signal_info.transfer_characteristics, signal_info.matrix_coeffs); @@ -3554,7 +3534,7 @@ int msm_venc_set_video_signal_info(struct msm_vidc_inst *inst) HFI_PROPERTY_PARAM_VENC_VIDEO_SIGNAL_INFO, &signal_info, sizeof(signal_info)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -3567,7 +3547,6 @@ int msm_venc_set_rotation(struct msm_vidc_inst *inst) struct hfi_vpe_rotation_type vpe_rotation; hdev = inst->core->device; - rotation = get_ctrl(inst, V4L2_CID_ROTATE); vpe_rotation.rotation = HFI_ROTATE_NONE; @@ -3580,14 +3559,14 @@ int msm_venc_set_rotation(struct msm_vidc_inst *inst) vpe_rotation.flip = v4l2_to_hfi_flip(inst); - dprintk(VIDC_HIGH, "Set rotation = %d, flip = %d\n", + s_vpr_h(inst->sid, "Set rotation = %d, flip = %d\n", vpe_rotation.rotation, vpe_rotation.flip); rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_PARAM_VPE_ROTATION, &vpe_rotation, sizeof(vpe_rotation)); if (rc) { - dprintk(VIDC_ERR, "Set rotation/flip failed\n"); + s_vpr_e(inst->sid, "Set rotation/flip failed\n"); return rc; } @@ -3630,15 +3609,16 @@ int msm_venc_check_dynamic_flip_constraints(struct msm_vidc_inst *inst) ((blur->val & 0xFFFF) != input_height || (blur->val & 0x7FFF0000) >> 16 != input_width)) blur_enable = true; - + s_vpr_h(inst->sid, "Blur = %u, height = %u, width = %u\n", + blur->val, input_height, input_width); if (blur_enable) { /* Reject dynamic flip with external blur enabled */ - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Unsupported dynamic flip with external blur\n"); rc = -EINVAL; } else if (scalar_enable && !inst->static_rotation_flip_enabled) { /* Reject dynamic flip with scalar enabled */ - dprintk(VIDC_ERR, "Unsupported dynamic flip with scalar\n"); + s_vpr_e(inst->sid, "Unsupported dynamic flip with scalar\n"); rc = -EINVAL; } @@ -3655,28 +3635,26 @@ int msm_venc_set_dynamic_flip(struct msm_vidc_inst *inst) rc = msm_venc_check_dynamic_flip_constraints(inst); if (rc) { - dprintk(VIDC_ERR, - "%s: Dynamic flip unsupported\n", __func__); + d_vpr_e("%s: Dynamic flip unsupported\n", __func__); return rc; } /* Require IDR frame first */ - dprintk(VIDC_HIGH, "Set dynamic IDR frame\n"); + s_vpr_h(inst->sid, "Set dynamic IDR frame\n"); rc = msm_venc_set_request_keyframe(inst); if (rc) { - dprintk(VIDC_ERR, - "%s: Dynamic IDR failed\n", __func__); + s_vpr_e(inst->sid, "%s: Dynamic IDR failed\n", __func__); return rc; } dynamic_flip = v4l2_to_hfi_flip(inst); - dprintk(VIDC_HIGH, "Dynamic flip = %d\n", dynamic_flip); + s_vpr_h(inst->sid, "Dynamic flip = %d\n", dynamic_flip); rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_CONFIG_VPE_FLIP, &dynamic_flip, sizeof(dynamic_flip)); if (rc) { - dprintk(VIDC_ERR, "Set dynamic flip failed\n"); + s_vpr_e(inst->sid, "Set dynamic flip failed\n"); return rc; } @@ -3693,7 +3671,7 @@ int msm_venc_set_video_csc(struct msm_vidc_inst *inst) u32 color_primaries, custom_matrix; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -3714,7 +3692,7 @@ int msm_venc_set_video_csc(struct msm_vidc_inst *inst) custom_matrix = ctrl_cm->val; rc = msm_venc_set_csc(inst, color_primaries, custom_matrix); if (rc) - dprintk(VIDC_ERR, "%s: msm_venc_set_csc failed\n", __func__); + s_vpr_e(inst->sid, "%s: msm_venc_set_csc failed\n", __func__); return rc; } @@ -3727,20 +3705,20 @@ int msm_venc_set_8x8_transform(struct msm_vidc_inst *inst) struct hfi_enable enable; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; if (get_v4l2_codec(inst) != V4L2_PIX_FMT_H264) { - dprintk(VIDC_HIGH, "%s: skip as codec is not H264\n", + s_vpr_h(inst->sid, "%s: skip as codec is not H264\n", __func__); return 0; } if (inst->profile != HFI_H264_PROFILE_HIGH && inst->profile != HFI_H264_PROFILE_CONSTRAINED_HIGH) { - dprintk(VIDC_HIGH, "%s: skip due to %#x\n", + s_vpr_h(inst->sid, "%s: skip due to %#x\n", __func__, inst->profile); return 0; } @@ -3748,12 +3726,12 @@ int msm_venc_set_8x8_transform(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM); enable.enable = !!ctrl->val; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, enable.enable); + s_vpr_h(inst->sid, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_H264_8X8_TRANSFORM, &enable, sizeof(enable)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -3768,7 +3746,7 @@ int msm_venc_set_vui_timing_info(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -3796,13 +3774,13 @@ int msm_venc_set_vui_timing_info(struct msm_vidc_inst *inst) timing_info.fixed_frame_rate = cfr; timing_info.time_scale = NSEC_PER_SEC; - dprintk(VIDC_HIGH, "%s: %d %d\n", __func__, timing_info.enable, + s_vpr_h(inst->sid, "%s: %d %d\n", __func__, timing_info.enable, timing_info.fixed_frame_rate); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_VUI_TIMING_INFO, &timing_info, sizeof(timing_info)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -3816,7 +3794,7 @@ int msm_venc_set_nal_stream_format(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -3834,7 +3812,7 @@ int msm_venc_set_nal_stream_format(struct msm_vidc_inst *inst) */ if (is_secure_session(inst) && ctrl->val != V4L2_MPEG_VIDEO_HEVC_SIZE_0) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: Invalid stream format setting for secure session\n", __func__); return -EINVAL; @@ -3850,7 +3828,7 @@ int msm_venc_set_nal_stream_format(struct msm_vidc_inst *inst) HFI_NAL_FORMAT_FOUR_BYTE_LENGTH; break; default: - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: Invalid stream format setting. Setting default\n", __func__); stream_format.nal_stream_format_select = @@ -3858,13 +3836,13 @@ int msm_venc_set_nal_stream_format(struct msm_vidc_inst *inst) break; } - dprintk(VIDC_HIGH, "%s: %#x\n", __func__, + s_vpr_h(inst->sid, "%s: %#x\n", __func__, stream_format.nal_stream_format_select); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT, &stream_format, sizeof(stream_format)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -3879,7 +3857,7 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -3901,7 +3879,7 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) } if (ctrl->val > inst->capability.cap[CAP_LTR_COUNT].max) { - dprintk(VIDC_ERR, "%s: invalid ltr count %d, max %d\n", + s_vpr_e(inst->sid, "%s: invalid ltr count %d, max %d\n", __func__, ctrl->val, inst->capability.cap[CAP_LTR_COUNT].max); return -EINVAL; @@ -3909,12 +3887,12 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) ltr.ltr_count = ctrl->val; ltr.ltr_mode = HFI_LTR_MODE_MANUAL; ltr.trust_mode = 1; - dprintk(VIDC_HIGH, "%s: %d %d\n", __func__, + s_vpr_h(inst->sid, "%s: %d %d\n", __func__, ltr.ltr_mode, ltr.ltr_count); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_LTRMODE, <r, sizeof(ltr)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); disable_ltr: /* @@ -3922,8 +3900,8 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) * client sets unsupported codec/rate control. */ if (!is_ltr) { - update_ctrl(ctrl, 0); - dprintk(VIDC_HIGH, "LTR is forcefully disabled!\n"); + update_ctrl(ctrl, 0, inst->sid); + s_vpr_h(inst->sid, "LTR is forcefully disabled!\n"); } return rc; } @@ -3937,7 +3915,7 @@ int msm_venc_set_ltr_useframe(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -3954,12 +3932,12 @@ int msm_venc_set_ltr_useframe(struct msm_vidc_inst *inst) use_ltr.ref_ltr = ctrl->val; use_ltr.use_constrnt = true; use_ltr.frames = 0; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, use_ltr.ref_ltr); + s_vpr_h(inst->sid, "%s: %d\n", __func__, use_ltr.ref_ltr); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_USELTRFRAME, &use_ltr, sizeof(use_ltr)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -3973,7 +3951,7 @@ int msm_venc_set_ltr_markframe(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -3989,12 +3967,12 @@ int msm_venc_set_ltr_markframe(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME); mark_ltr.mark_frame = ctrl->val; - dprintk(VIDC_HIGH, "%s: %d\n", __func__, mark_ltr.mark_frame); + s_vpr_h(inst->sid, "%s: %d\n", __func__, mark_ltr.mark_frame); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME, &mark_ltr, sizeof(mark_ltr)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -4006,13 +3984,13 @@ int msm_venc_set_dyn_qp(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) struct hfi_quantization qp; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; if (inst->rc_type != RATE_CONTROL_OFF) { - dprintk(VIDC_ERR, "%s: Dyn qp is set only when RC is OFF\n", + s_vpr_e(inst->sid, "%s: Dyn qp is set only when RC is OFF\n", __func__); return -EINVAL; } @@ -4025,12 +4003,12 @@ int msm_venc_set_dyn_qp(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (get_v4l2_codec(inst) == V4L2_PIX_FMT_VP8) qp.enable &= ~QP_ENABLE_B; - dprintk(VIDC_HIGH, "%s: %#x\n", __func__, + s_vpr_h(inst->sid, "%s: %#x\n", __func__, ctrl->val); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_FRAME_QP, &qp, sizeof(qp)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -4044,7 +4022,7 @@ int msm_venc_set_aspect_ratio(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -4063,12 +4041,12 @@ int msm_venc_set_aspect_ratio(struct msm_vidc_inst *inst) return 0; sar.aspect_height = ctrl->val; - dprintk(VIDC_HIGH, "%s: %d %d\n", __func__, + s_vpr_h(inst->sid, "%s: %d %d\n", __func__, sar.aspect_width, sar.aspect_height); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_ASPECT_RATIO, &sar, sizeof(sar)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -4082,7 +4060,7 @@ int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst) struct v4l2_format *f; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -4101,7 +4079,7 @@ int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst) */ if (ctrl->val == 0x2) { if (inst->state == MSM_VIDC_START_DONE) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Dynamic disable all blur not supported\n"); return -EINVAL; } @@ -4112,23 +4090,23 @@ int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst) */ frame_sz.width = f->fmt.pix_mp.width; frame_sz.height = f->fmt.pix_mp.height; - dprintk(VIDC_HIGH, "Disable both auto and external blur\n"); + s_vpr_h(inst->sid, "Disable both auto and external blur\n"); } else if (ctrl->val != 0){ if (check_blur_restrictions(inst)) { /* reject external blur */ - dprintk(VIDC_ERR, - "External blur is unsupported with rotation/flip/scalar\n"); + s_vpr_e(inst->sid, + "External blur is unsupported with rotation/flip/scalar\n"); return -EINVAL; } } - dprintk(VIDC_HIGH, "%s: type %u, height %u, width %u\n", __func__, + s_vpr_h(inst->sid, "%s: type %u, height %u, width %u\n", __func__, frame_sz.buffer_type, frame_sz.height, frame_sz.width); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_BLUR_FRAME_SIZE, &frame_sz, sizeof(frame_sz)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -4140,7 +4118,7 @@ int msm_venc_set_hdr_info(struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; @@ -4153,12 +4131,12 @@ int msm_venc_set_hdr_info(struct msm_vidc_inst *inst) return 0; /* No conversion to HFI needed as both structures are same */ - dprintk(VIDC_HIGH, "%s: setting hdr info\n", __func__); + s_vpr_h(inst->sid, "%s: setting hdr info\n", __func__); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_HDR10_PQ_SEI, &inst->hdr10_sei_params, sizeof(inst->hdr10_sei_params)); if (rc) - dprintk(VIDC_ERR, "%s: set property failed\n", __func__); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } @@ -4221,7 +4199,7 @@ int msm_venc_set_lossless(struct msm_vidc_inst *inst) if (inst->rc_type != RATE_CONTROL_LOSSLESS) return 0; - dprintk(VIDC_HIGH, "%s: enable lossless encoding\n", __func__); + s_vpr_h(inst->sid, "%s: enable lossless encoding\n", __func__); enable.enable = 1; rc = call_hfi_op(hdev, session_set_property, inst->session, @@ -4229,7 +4207,7 @@ int msm_venc_set_lossless(struct msm_vidc_inst *inst) &enable, sizeof(enable)); if (rc) - dprintk(VIDC_ERR, "Failed to set lossless mode\n"); + s_vpr_e(inst->sid, "Failed to set lossless mode\n"); return rc; } @@ -4244,7 +4222,7 @@ int handle_all_intra_restrictions(struct msm_vidc_inst *inst) struct hfi_intra_period intra_period; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } @@ -4261,17 +4239,17 @@ int handle_all_intra_restrictions(struct msm_vidc_inst *inst) else return 0; - dprintk(VIDC_HIGH, "All Intra(IDRs) Encoding\n"); + s_vpr_h(inst->sid, "All Intra(IDRs) Encoding\n"); /* check codec and profile */ f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; - codec = get_hal_codec(f->fmt.pix_mp.pixelformat); + codec = get_hal_codec(f->fmt.pix_mp.pixelformat, inst->sid); if (codec != HAL_VIDEO_CODEC_HEVC && codec != HAL_VIDEO_CODEC_H264) { - dprintk(VIDC_ERR, "Unsupported codec for all intra\n"); + s_vpr_e(inst->sid, "Unsupported codec for all intra\n"); return -ENOTSUPP; } if (codec == HAL_VIDEO_CODEC_HEVC && inst->profile == HFI_HEVC_PROFILE_MAIN10) { - dprintk(VIDC_ERR, "Unsupported HEVC profile for all intra\n"); + s_vpr_e(inst->sid, "Unsupported HEVC profile for all intra\n"); return -ENOTSUPP; } @@ -4279,11 +4257,13 @@ int handle_all_intra_restrictions(struct msm_vidc_inst *inst) capability = &inst->capability; n_fps = inst->clk_data.frame_rate >> 16; fps_max = capability->cap[CAP_ALLINTRA_MAX_FPS].max; + s_vpr_h(inst->sid, "%s: rc_type %u, fps %u, fps_max %u\n", + inst->rc_type, n_fps, fps_max); if ((inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR && inst->rc_type != RATE_CONTROL_OFF && inst->rc_type != RATE_CONTROL_LOSSLESS) || n_fps > fps_max) { - dprintk(VIDC_ERR, "Unsupported bitrate mode or frame rate\n"); + s_vpr_e(inst->sid, "Unsupported bitrate mode or frame rate\n"); return -ENOTSUPP; } @@ -4474,9 +4454,9 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) exit: if (rc) - dprintk(VIDC_ERR, "%s: failed with %d\n", __func__, rc); + s_vpr_e(inst->sid, "%s: failed with %d\n", __func__, rc); else - dprintk(VIDC_HIGH, "%s: set properties successful\n", __func__); + s_vpr_h(inst->sid, "%s: set properties successful\n", __func__); return rc; } diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 1974251de698..aa4128ff365d 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -131,13 +131,14 @@ int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *q_ctrl) struct v4l2_ctrl *ctrl; if (!inst || !q_ctrl) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, inst, q_ctrl); return -EINVAL; } ctrl = v4l2_ctrl_find(&inst->ctrl_handler, q_ctrl->id); if (!ctrl) { - dprintk(VIDC_ERR, "%s: get_ctrl failed for id %d\n", + s_vpr_e(inst->sid, "%s: get_ctrl failed for id %d\n", __func__, q_ctrl->id); return -EINVAL; } @@ -153,7 +154,7 @@ int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *q_ctrl) else q_ctrl->flags = 0; - dprintk(VIDC_HIGH, "query ctrl: %s: min %d, max %d, flags %#x\n", + s_vpr_h(inst->sid, "query ctrl: %s: min %d, max %d, flags %#x\n", ctrl->name, q_ctrl->minimum, q_ctrl->maximum, q_ctrl->flags); return rc; } @@ -172,10 +173,9 @@ int msm_vidc_s_fmt(void *instance, struct v4l2_format *f) if (inst->session_type == MSM_VIDC_ENCODER) rc = msm_venc_s_fmt(instance, f); - dprintk(VIDC_HIGH, - "s_fmt: %x : type %d wxh %dx%d pixelfmt %#x num_planes %d size[0] %d size[1] %d in_reconfig %d\n", - hash32_ptr(inst->session), f->type, - f->fmt.pix_mp.width, f->fmt.pix_mp.height, + s_vpr_h(inst->sid, + "s_fmt: type %d wxh %dx%d pixelfmt %#x num_planes %d size[0] %d size[1] %d in_reconfig %d\n", + f->type, f->fmt.pix_mp.width, f->fmt.pix_mp.height, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.num_planes, f->fmt.pix_mp.plane_fmt[0].sizeimage, f->fmt.pix_mp.plane_fmt[1].sizeimage, inst->in_reconfig); @@ -196,10 +196,9 @@ int msm_vidc_g_fmt(void *instance, struct v4l2_format *f) if (inst->session_type == MSM_VIDC_ENCODER) rc = msm_venc_g_fmt(instance, f); - dprintk(VIDC_HIGH, - "g_fmt: %x : type %d wxh %dx%d pixelfmt %#x num_planes %d size[0] %d size[1] %d in_reconfig %d\n", - hash32_ptr(inst->session), f->type, - f->fmt.pix_mp.width, f->fmt.pix_mp.height, + s_vpr_h(inst->sid, + "g_fmt: type %d wxh %dx%d pixelfmt %#x num_planes %d size[0] %d size[1] %d in_reconfig %d\n", + f->type, f->fmt.pix_mp.width, f->fmt.pix_mp.height, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.num_planes, f->fmt.pix_mp.plane_fmt[0].sizeimage, f->fmt.pix_mp.plane_fmt[1].sizeimage, inst->in_reconfig); @@ -248,9 +247,8 @@ int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b) return -EINVAL; q = msm_comm_get_vb2q(inst, b->type); if (!q) { - dprintk(VIDC_ERR, - "Failed to find buffer queue for type = %d\n", - b->type); + s_vpr_e(inst->sid, + "Failed to find buffer queue. type %d\n", b->type); return -EINVAL; } @@ -259,7 +257,7 @@ int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b) mutex_unlock(&q->lock); if (rc) - dprintk(VIDC_ERR, "Failed to get reqbufs, %d\n", rc); + s_vpr_e(inst->sid, "Failed to get reqbufs, %d\n", rc); return rc; } EXPORT_SYMBOL(msm_vidc_reqbufs); @@ -286,7 +284,7 @@ int msm_vidc_release_buffer(void *instance, int type, unsigned int index) struct msm_vidc_buffer *mbuf, *dummy; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid inst\n", __func__); + d_vpr_e("%s: invalid inst\n", __func__); return -EINVAL; } @@ -295,9 +293,9 @@ int msm_vidc_release_buffer(void *instance, int type, unsigned int index) inst->state < MSM_VIDC_RELEASE_RESOURCES_DONE) { rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: Failed to move inst: %pK to rel res done\n", - __func__, inst); + __func__, inst); } } @@ -336,21 +334,20 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) u32 cr = 0; if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) { - dprintk(VIDC_ERR, "%s: invalid params, inst %pK\n", - __func__, inst); + d_vpr_e("%s: invalid params %pK %pK\n", __func__, inst, b); return -EINVAL; } if (!IS_ALIGNED(b->m.planes[0].length, SZ_4K)) { - dprintk(VIDC_ERR, "qbuf: %x: buffer size not 4K aligned - %u\n", - hash32_ptr(inst->session), b->m.planes[0].length); + s_vpr_e(inst->sid, "qbuf: buffer size not 4K aligned - %u\n", + b->m.planes[0].length); return -EINVAL; } if ((inst->out_flush && b->type == OUTPUT_MPLANE) || inst->in_flush) { - dprintk(VIDC_ERR, - "%s: %x: in flush, discarding qbuf, type %u, index %u\n", - __func__, hash32_ptr(inst->session), b->type, b->index); + s_vpr_e(inst->sid, + "%s: in flush, discarding qbuf, type %u, index %u\n", + __func__, b->type, b->index); return -EINVAL; } @@ -370,19 +367,18 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) client_data = msm_comm_store_client_data(inst, b->m.planes[0].reserved[3]); if (!client_data) { - dprintk(VIDC_ERR, - "%s: %x: failed to store client data\n", - __func__, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, + "%s: failed to store client data\n", __func__); return -EINVAL; } msm_comm_store_input_tag(&inst->etb_data, b->index, - client_data->id, 0); + client_data->id, 0, inst->sid); } q = msm_comm_get_vb2q(inst, b->type); if (!q) { - dprintk(VIDC_ERR, - "Failed to find buffer queue for type = %d\n", b->type); + s_vpr_e(inst->sid, + "Failed to find buffer queue. type %d\n", b->type); return -EINVAL; } @@ -390,7 +386,7 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) rc = vb2_qbuf(&q->vb2_bufq, b); mutex_unlock(&q->lock); if (rc) - dprintk(VIDC_ERR, "Failed to qbuf, %d\n", rc); + s_vpr_e(inst->sid, "Failed to qbuf, %d\n", rc); return rc; } @@ -406,15 +402,15 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) bool remove; if (!inst || !b || !valid_v4l2_buffer(b, inst)) { - dprintk(VIDC_ERR, "%s: invalid params, inst %pK\n", - __func__, inst); + d_vpr_e("%s: invalid params, %pK %pK\n", + __func__, inst, b); return -EINVAL; } q = msm_comm_get_vb2q(inst, b->type); if (!q) { - dprintk(VIDC_ERR, - "Failed to find buffer queue for type = %d\n", b->type); + s_vpr_e(inst->sid, "Failed to find buffer queue. type %d\n", + b->type); return -EINVAL; } @@ -424,7 +420,7 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) if (rc == -EAGAIN) { return rc; } else if (rc) { - dprintk(VIDC_ERR, "Failed to dqbuf, %d\n", rc); + s_vpr_e(inst->sid, "Failed to dqbuf, %d\n", rc); return rc; } @@ -443,9 +439,9 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) if (b->type == OUTPUT_MPLANE && !inst->in_flush && !inst->out_flush && inst->clk_data.buffer_counter) { rc = msm_comm_fetch_input_tag(&inst->fbd_data, b->index, - &input_tag, &input_tag2); + &input_tag, &input_tag2, inst->sid); if (rc) { - dprintk(VIDC_ERR, "Failed to fetch input tag"); + s_vpr_e(inst->sid, "Failed to fetch input tag"); return -EINVAL; } /** @@ -477,16 +473,15 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type i) q = msm_comm_get_vb2q(inst, i); if (!q) { - dprintk(VIDC_ERR, - "Failed to find buffer queue for type = %d\n", i); + d_vpr_e("Failed to find buffer queue. type %d\n", i); return -EINVAL; } - dprintk(VIDC_HIGH, "Calling streamon\n"); + s_vpr_h(inst->sid, "Calling streamon\n"); mutex_lock(&q->lock); rc = vb2_streamon(&q->vb2_bufq, i); mutex_unlock(&q->lock); if (rc) { - dprintk(VIDC_ERR, "streamon failed on port: %d\n", i); + s_vpr_e(inst->sid, "streamon failed on port: %d\n", i); msm_comm_kill_session(inst); } return rc; @@ -504,27 +499,26 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i) q = msm_comm_get_vb2q(inst, i); if (!q) { - dprintk(VIDC_ERR, - "Failed to find buffer queue for type = %d\n", i); + s_vpr_e(inst->sid, "Failed to find buffer queue. type %d\n", i); return -EINVAL; } if (!inst->in_reconfig) { - dprintk(VIDC_HIGH, "%s: inst %pK release resources\n", + s_vpr_h(inst->sid, "%s: inst %pK release resources\n", __func__, inst); rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: inst %pK move to rel res done failed\n", __func__, inst); } - dprintk(VIDC_HIGH, "Calling streamoff\n"); + s_vpr_h(inst->sid, "Calling streamoff\n"); mutex_lock(&q->lock); rc = vb2_streamoff(&q->vb2_bufq, i); mutex_unlock(&q->lock); if (rc) - dprintk(VIDC_ERR, "streamoff failed on port: %d\n", i); + s_vpr_e(inst->sid, "streamoff failed on port: %d\n", i); return rc; } EXPORT_SYMBOL(msm_vidc_streamoff); @@ -535,7 +529,7 @@ int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize) struct msm_vidc_capability *capability = NULL; if (!inst || !fsize) { - dprintk(VIDC_ERR, "%s: invalid parameter: %pK %pK\n", + d_vpr_e("%s: invalid parameter: %pK %pK\n", __func__, inst, fsize); return -EINVAL; } @@ -578,35 +572,33 @@ static void msm_vidc_cleanup_buffer(struct vb2_buffer *vb) struct msm_vidc_inst *inst = NULL; if (!vb) { - dprintk(VIDC_ERR, "%s : Invalid vb pointer %pK", - __func__, vb); + d_vpr_e("%s: Invalid vb pointer", __func__); return; } inst = vb2_get_drv_priv(vb->vb2_queue); if (!inst) { - dprintk(VIDC_ERR, "%s : Invalid inst pointer", - __func__); + d_vpr_e("%s: Invalid inst pointer", __func__); return; } q = msm_comm_get_vb2q(inst, vb->type); if (!q) { - dprintk(VIDC_ERR, - "%s : Failed to find buffer queue for type = %d\n", + s_vpr_e(inst->sid, + "%s: Failed to find buffer queue. type %d\n", __func__, vb->type); return; } if (q->vb2_bufq.streaming) { - dprintk(VIDC_HIGH, "%d PORT is streaming\n", + s_vpr_h(inst->sid, "%d PORT is streaming\n", vb->type); return; } rc = msm_vidc_release_buffer(inst, vb->type, vb->index); if (rc) - dprintk(VIDC_ERR, "%s : Failed to release buffers : %d\n", + s_vpr_e(inst->sid, "%s: Failed to release buffers: %d\n", __func__, rc); } @@ -622,14 +614,13 @@ static int msm_vidc_queue_setup(struct vb2_queue *q, if (!q || !num_buffers || !num_planes || !sizes || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %pK, %pK, %pK\n", + d_vpr_e("Invalid input, q = %pK, %pK, %pK\n", q, num_buffers, num_planes); return -EINVAL; } inst = q->drv_priv; - if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } @@ -637,7 +628,7 @@ static int msm_vidc_queue_setup(struct vb2_queue *q, case INPUT_MPLANE: { fmt = &inst->fmts[INPUT_PORT]; if (*num_buffers < fmt->count_min_host) { - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "Client passed num buffers %d less than the min_host count %d\n", *num_buffers, fmt->count_min_host); } @@ -658,7 +649,7 @@ static int msm_vidc_queue_setup(struct vb2_queue *q, if (inst->session_type != MSM_VIDC_DECODER && inst->state > MSM_VIDC_LOAD_RESOURCES_DONE) { if (*num_buffers < fmt->count_min_host) { - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "Client passed num buffers %d less than the min_host count %d\n", *num_buffers, fmt->count_min_host); @@ -678,15 +669,14 @@ static int msm_vidc_queue_setup(struct vb2_queue *q, } break; default: - dprintk(VIDC_ERR, "Invalid q type = %d\n", q->type); + s_vpr_e(inst->sid, "Invalid q type = %d\n", q->type); rc = -EINVAL; break; } - dprintk(VIDC_HIGH, - "queue_setup: %x : type %d num_buffers %d num_planes %d sizes[0] %d sizes[1] %d\n", - hash32_ptr(inst->session), q->type, *num_buffers, - *num_planes, sizes[0], sizes[1]); + s_vpr_h(inst->sid, + "queue_setup:type %d num_buffers %d num_planes %d sizes[0] %d sizes[1] %d\n", + q->type, *num_buffers, *num_planes, sizes[0], sizes[1]); return rc; } @@ -698,8 +688,7 @@ static inline int msm_vidc_verify_buffer_counts(struct msm_vidc_inst *inst) if (inst->session_type == MSM_VIDC_DECODER && (inst->state < MSM_VIDC_LOAD_RESOURCES_DONE || inst->state >= MSM_VIDC_RELEASE_RESOURCES_DONE)) { - dprintk(VIDC_HIGH, - "No need to verify buffer counts : %pK\n", inst); + s_vpr_h(inst->sid, "No need to verify buffer counts\n"); return 0; } @@ -707,23 +696,20 @@ static inline int msm_vidc_verify_buffer_counts(struct msm_vidc_inst *inst) struct hal_buffer_requirements *req = &inst->buff_req.buffer[i]; if (req && (req->buffer_type == HAL_BUFFER_OUTPUT)) { - dprintk(VIDC_HIGH, "Verifying Buffer : %d\n", + s_vpr_h(inst->sid, "Verifying Buffer : %d\n", req->buffer_type); if (req->buffer_count_actual < req->buffer_count_min_host || req->buffer_count_min_host < req->buffer_count_min) { - dprintk(VIDC_ERR, - "Invalid data : Counts mismatch\n"); - dprintk(VIDC_ERR, - "Min Count = %d ", + s_vpr_e(inst->sid, + "Invalid data : Counts mismatch\n"); + s_vpr_e(inst->sid, "Min Count = %d ", req->buffer_count_min); - dprintk(VIDC_ERR, - "Min Host Count = %d ", + s_vpr_e(inst->sid, "Min Host Count = %d ", req->buffer_count_min_host); - dprintk(VIDC_ERR, - "Min Actual Count = %d\n", + s_vpr_e(inst->sid, "Min Actual Count = %d\n", req->buffer_count_actual); rc = -EINVAL; break; @@ -753,7 +739,7 @@ bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst) struct v4l2_ctrl *superframe_enable; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); goto exit; } core = inst->core; @@ -782,10 +768,10 @@ bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst) !inst->clk_data.is_legacy_cbr && !is_secure_session(inst) && !superframe_enable->val) { - dprintk(VIDC_HIGH, "%s: cvp allowed\n", __func__); + s_vpr_h(inst->sid, "%s: cvp allowed\n", __func__); allowed = true; } else { - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "%s: cvp not allowed, cvp_external %d cvp_disable %d extradata %#x rc_type %d legacy_cbr %d secure %d superframe %d\n", __func__, core->resources.cvp_external, cvp_disable->val, inst->prop.extradata_ctrls, @@ -802,26 +788,26 @@ static int msm_vidc_prepare_preprocess(struct msm_vidc_inst *inst) int rc = 0; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } if (!msm_vidc_cvp_usage) { - dprintk(VIDC_HIGH, "%s: cvp usage disabled\n", __func__); + s_vpr_h(inst->sid, "%s: cvp usage disabled\n", __func__); return 0; } if (!is_vidc_cvp_allowed(inst)) { - dprintk(VIDC_HIGH, "%s: cvp not allowed\n", __func__); + s_vpr_h(inst->sid, "%s: cvp not allowed\n", __func__); return 0; } rc = msm_vidc_cvp_prepare_preprocess(inst); if (rc) { - dprintk(VIDC_ERR, "%s: no cvp preprocessing\n", __func__); + s_vpr_e(inst->sid, "%s: no cvp preprocessing\n", __func__); goto exit; } - dprintk(VIDC_HIGH, "%s: kernel to kernel cvp enabled\n", __func__); + s_vpr_h(inst->sid, "%s: kernel to kernel cvp enabled\n", __func__); inst->prop.extradata_ctrls |= EXTRADATA_ENC_INPUT_KK_CVP; exit: @@ -836,7 +822,7 @@ static bool msm_vidc_set_cvp_metadata(struct msm_vidc_inst *inst) { u32 value = 0x0; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return false; } @@ -844,12 +830,11 @@ static bool msm_vidc_set_cvp_metadata(struct msm_vidc_inst *inst) { (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_KK_CVP)) value = 0x1; - dprintk(VIDC_HIGH, "%s: CVP extradata %d\n", __func__, value); + s_vpr_h(inst->sid, "%s: CVP extradata %d\n", __func__, value); rc = msm_comm_set_extradata(inst, HFI_PROPERTY_PARAM_VENC_CVP_METADATA_EXTRADATA, value); if (rc) { - dprintk(VIDC_ERR, - "%s: set CVP extradata failed\n", __func__); + s_vpr_e(inst->sid, "%s: set CVP extradata failed\n", __func__); return false; } return true; @@ -862,21 +847,19 @@ static inline int start_streaming(struct msm_vidc_inst *inst) struct hfi_buffer_size_minimum b; struct v4l2_format *f; - dprintk(VIDC_HIGH, "%s: %x : inst %pK\n", __func__, - hash32_ptr(inst->session), inst); + s_vpr_h(inst->sid, "%s: inst %pK\n", __func__, inst); hdev = inst->core->device; rc = msm_vidc_set_properties(inst); if (rc) { - dprintk(VIDC_ERR, "%s: %x: set props failed\n", - __func__, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, "%s: set props failed\n", __func__); goto fail_start; } if (is_encode_session(inst)) { rc = msm_vidc_prepare_preprocess(inst); if (rc) { - dprintk(VIDC_ERR, "%s: no preprocessing\n", __func__); + s_vpr_e(inst->sid, "%s: no preprocessing\n", __func__); /* ignore error */ rc = 0; } @@ -892,38 +875,34 @@ static inline int start_streaming(struct msm_vidc_inst *inst) /* Check if current session is under HW capability */ rc = msm_vidc_check_session_supported(inst); if (rc) { - dprintk(VIDC_ERR, - "This session is not supported %pK\n", inst); + s_vpr_e(inst->sid, "This session is not supported\n"); goto fail_start; } rc = msm_vidc_check_scaling_supported(inst); if (rc) { - dprintk(VIDC_ERR, - "This session scaling is not supported %pK\n", inst); + s_vpr_e(inst->sid, "scaling is not supported\n"); goto fail_start; } /* Decide work mode for current session */ rc = call_core_op(inst->core, decide_work_mode, inst); if (rc) { - dprintk(VIDC_ERR, - "Failed to decide work mode for session %pK\n", inst); + s_vpr_e(inst->sid, "Failed to decide work mode\n"); goto fail_start; } /* Decide work route for current session */ rc = call_core_op(inst->core, decide_work_route, inst); if (rc) { - dprintk(VIDC_ERR, - "Failed to decide work route for session %pK\n", inst); + s_vpr_e(inst->sid, "Failed to decide work route\n"); goto fail_start; } /* Assign Core and LP mode for current session */ rc = call_core_op(inst->core, decide_core_and_power_mode, inst); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "This session can't be submitted to HW %pK\n", inst); goto fail_start; } @@ -939,28 +918,25 @@ static inline int start_streaming(struct msm_vidc_inst *inst) /* Verify if buffer counts are correct */ rc = msm_vidc_verify_buffer_counts(inst); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "This session has mis-match buffer counts%pK\n", inst); goto fail_start; } rc = msm_comm_set_scratch_buffers(inst); if (rc) { - dprintk(VIDC_ERR, - "Failed to set scratch buffers: %d\n", rc); + s_vpr_e(inst->sid, "Failed to set scratch buffers: %d\n", rc); goto fail_start; } rc = msm_comm_set_persist_buffers(inst); if (rc) { - dprintk(VIDC_ERR, - "Failed to set persist buffers: %d\n", rc); + s_vpr_e(inst->sid, "Failed to set persist buffers: %d\n", rc); goto fail_start; } rc = msm_comm_set_recon_buffers(inst); if (rc) { - dprintk(VIDC_ERR, - "Failed to set recon buffers: %d\n", rc); + s_vpr_e(inst->sid, "Failed to set recon buffers: %d\n", rc); goto fail_start; } @@ -968,7 +944,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) HAL_VIDEO_DECODER_SECONDARY) { rc = msm_comm_set_dpb_only_buffers(inst); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to set output buffers: %d\n", rc); goto fail_start; } @@ -983,9 +959,8 @@ static inline int start_streaming(struct msm_vidc_inst *inst) */ if (inst->batch.enable) inst->batch.enable = is_batching_allowed(inst); - dprintk(VIDC_HIGH|VIDC_PERF, "%s: batching %s for inst %pK (%#x)\n", - __func__, inst->batch.enable ? "enabled" : "disabled", - inst, hash32_ptr(inst->session)); + s_vpr_hp(inst->sid, "%s: batching %s for inst %pK\n", + __func__, inst->batch.enable ? "enabled" : "disabled", inst); msm_dcvs_try_enable(inst); @@ -1007,7 +982,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to move inst: %pK to start done state\n", inst); goto fail_start; } @@ -1018,7 +993,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) HAL_VIDEO_DECODER_SECONDARY) { rc = msm_comm_queue_dpb_only_buffers(inst); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to queue output buffers: %d\n", rc); goto fail_start; } @@ -1026,8 +1001,8 @@ static inline int start_streaming(struct msm_vidc_inst *inst) fail_start: if (rc) - dprintk(VIDC_ERR, "%s: inst %pK session %x failed to start\n", - __func__, inst, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, "%s: inst %pK failed to start\n", + __func__, inst); return rc; } @@ -1038,16 +1013,16 @@ static int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count) struct hfi_device *hdev; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); + d_vpr_e("Invalid input, q = %pK\n", q); return -EINVAL; } inst = q->drv_priv; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } hdev = inst->core->device; - dprintk(VIDC_HIGH, "Streamon called on: %d capability for inst: %pK\n", + s_vpr_h(inst->sid, "Streamon called on: %d capability for inst: %pK\n", q->type, inst); switch (q->type) { case INPUT_MPLANE: @@ -1059,30 +1034,28 @@ static int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count) rc = start_streaming(inst); break; default: - dprintk(VIDC_ERR, "Queue type is not supported: %d\n", q->type); + s_vpr_e(inst->sid, + "Queue type is not supported: %d\n", q->type); rc = -EINVAL; goto stream_start_failed; } if (rc) { - dprintk(VIDC_ERR, - "Streamon failed on: %d capability for inst: %pK\n", + s_vpr_e(inst->sid, "Streamon failed: %d, inst: %pK\n", q->type, inst); goto stream_start_failed; } rc = msm_comm_qbufs(inst); if (rc) { - dprintk(VIDC_ERR, - "Failed to commit buffers queued before STREAM_ON to hardware: %d\n", - rc); + s_vpr_e(inst->sid, + "Failed to commit buffers queued before STREAM_ON: %d\n", + rc); goto stream_start_failed; } rc = msm_vidc_send_pending_eos_buffers(inst); if (rc) { - dprintk(VIDC_ERR, - "Failed : Send pending EOS buffs for Inst = %pK, %d\n", - inst, rc); + s_vpr_e(inst->sid, "Failed : Send pending EOS: %d\n", rc); goto stream_start_failed; } @@ -1103,8 +1076,7 @@ static int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count) list_for_each_entry(vb, &q->queued_list, queued_entry) { if (msm_comm_compare_vb2_planes(inst, temp, vb)) { - print_vb2_buffer(VIDC_ERR, "return vb", - inst, vb); + print_vb2_buffer("return vb", inst, vb); vb2_buffer_done(vb, VB2_BUF_STATE_QUEUED); break; @@ -1124,7 +1096,7 @@ static int msm_vidc_unprepare_preprocess(struct msm_vidc_inst *inst) int rc = 0; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -1133,9 +1105,7 @@ static int msm_vidc_unprepare_preprocess(struct msm_vidc_inst *inst) rc = msm_vidc_cvp_unprepare_preprocess(inst); if (rc) - dprintk(VIDC_ERR, - "%s: cvp unprepare preprocess failed with rc %d\n", - __func__, rc); + s_vpr_e(inst->sid, "%s: failed rc %d\n", __func__, rc); return rc; } @@ -1144,19 +1114,21 @@ static inline int stop_streaming(struct msm_vidc_inst *inst) { int rc = 0; - dprintk(VIDC_HIGH, "%s: %x : inst %pK\n", __func__, - hash32_ptr(inst->session), inst); + if (!inst) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + s_vpr_h(inst->sid, "%s: inst %pK\n", __func__, inst); rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) - dprintk(VIDC_ERR, - "Failed to move inst: %pK to state %d\n", + s_vpr_e(inst->sid, "Failed to move inst: %pK to state %d\n", inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (is_encode_session(inst)) { rc = msm_vidc_unprepare_preprocess(inst); if (rc) - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: failed to unprepare preprocess\n", __func__); inst->all_intra = false; @@ -1173,12 +1145,12 @@ static void msm_vidc_stop_streaming(struct vb2_queue *q) int rc = 0; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); + d_vpr_e("Invalid input, q = %pK\n", q); return; } inst = q->drv_priv; - dprintk(VIDC_HIGH, "Streamoff called on: %d capability\n", q->type); + s_vpr_h(inst->sid, "Streamoff called on: %d capability\n", q->type); switch (q->type) { case INPUT_MPLANE: if (!inst->bufq[OUTPUT_PORT].vb2_bufq.streaming) @@ -1189,8 +1161,7 @@ static void msm_vidc_stop_streaming(struct vb2_queue *q) rc = stop_streaming(inst); break; default: - dprintk(VIDC_ERR, - "Q-type is not supported: %d\n", q->type); + s_vpr_e(inst->sid, "Q-type is not supported: %d\n", q->type); rc = -EINVAL; break; } @@ -1198,7 +1169,7 @@ static void msm_vidc_stop_streaming(struct vb2_queue *q) msm_comm_scale_clocks_and_bus(inst, 1); if (rc) - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed STOP Streaming inst = %pK on cap = %d\n", inst, q->type); } @@ -1210,7 +1181,8 @@ static int msm_vidc_queue_buf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf; if (!inst || !vb2) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK, %pK\n", + __func__, inst, vb2); return -EINVAL; } @@ -1223,16 +1195,16 @@ static int msm_vidc_queue_buf(struct msm_vidc_inst *inst, */ if (PTR_ERR(mbuf) == -EEXIST) return 0; - dprintk(VIDC_ERR, "%s: failed to get vidc-buf\n", __func__); + s_vpr_e(inst->sid, "%s: failed to get vidc-buf\n", __func__); return -EINVAL; } if (!kref_get_mbuf(inst, mbuf)) { - dprintk(VIDC_ERR, "%s: mbuf not found\n", __func__); + s_vpr_e(inst->sid, "%s: mbuf not found\n", __func__); return -EINVAL; } rc = msm_comm_qbuf(inst, mbuf); if (rc) - dprintk(VIDC_ERR, "%s: failed qbuf\n", __func__); + s_vpr_e(inst->sid, "%s: failed qbuf\n", __func__); kref_put_mbuf(mbuf); return rc; @@ -1245,17 +1217,18 @@ static int msm_vidc_queue_buf_decode_batch(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf; if (!inst || !vb2) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK, %pK\n", + __func__, inst, vb2); return -EINVAL; } mbuf = msm_comm_get_vidc_buffer(inst, vb2); if (IS_ERR_OR_NULL(mbuf)) { - dprintk(VIDC_ERR, "%s: failed to get vidc-buf\n", __func__); + s_vpr_e(inst->sid, "%s: failed to get vidc-buf\n", __func__); return -EINVAL; } if (!kref_get_mbuf(inst, mbuf)) { - dprintk(VIDC_ERR, "%s: mbuf not found\n", __func__); + s_vpr_e(inst->sid, "%s: mbuf not found\n", __func__); return -EINVAL; } /* @@ -1264,7 +1237,7 @@ static int msm_vidc_queue_buf_decode_batch(struct msm_vidc_inst *inst, */ rc = msm_comm_qbuf_decode_batch(inst, mbuf); if (rc) - dprintk(VIDC_ERR, "%s: failed qbuf\n", __func__); + s_vpr_e(inst->sid, "%s: failed qbuf\n", __func__); kref_put_mbuf(mbuf); return rc; @@ -1276,7 +1249,8 @@ static int msm_vidc_queue_buf_batch(struct msm_vidc_inst *inst, int rc; if (!inst || !vb2) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK, %pK\n", + __func__, inst, vb2); return -EINVAL; } @@ -1296,7 +1270,7 @@ static void msm_vidc_buf_queue(struct vb2_buffer *vb2) inst = vb2_get_drv_priv(vb2->vb2_queue); if (!inst) { - dprintk(VIDC_ERR, "%s: invalid inst\n", __func__); + d_vpr_e("%s: invalid inst\n", __func__); return; } @@ -1306,7 +1280,7 @@ static void msm_vidc_buf_queue(struct vb2_buffer *vb2) rc = msm_vidc_queue_buf(inst, vb2); if (rc) { - print_vb2_buffer(VIDC_ERR, "failed vb2-qbuf", inst, vb2); + print_vb2_buffer("failed vb2-qbuf", inst, vb2); msm_comm_generate_session_error(inst); } } @@ -1329,7 +1303,7 @@ static inline int vb2_bufq_init(struct msm_vidc_inst *inst, } else if (type == INPUT_MPLANE) { q = &inst->bufq[INPUT_PORT].vb2_bufq; } else { - dprintk(VIDC_ERR, "buf_type = %d not recognised\n", type); + s_vpr_e(inst->sid, "buf_type = %d not recognised\n", type); return -EINVAL; } @@ -1404,21 +1378,20 @@ int msm_vidc_private(void *vidc_inst, unsigned int cmd, int rc = 0; struct msm_vidc_inst *inst = (struct msm_vidc_inst *)vidc_inst; + if (!inst || !arg) { + d_vpr_e("%s: invalid args\n", __func__); + return -EINVAL; + } if (cmd != VIDIOC_VIDEO_CMD) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: invalid private cmd %#x\n", __func__, cmd); return -ENOIOCTLCMD; } - if (!inst || !arg) { - dprintk(VIDC_ERR, "%s: invalid args\n", __func__); - return -EINVAL; - } - if (inst->session_type == MSM_VIDC_CVP) { rc = msm_vidc_cvp(inst, arg); } else { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: private cmd %#x not supported for session_type %d\n", __func__, cmd, inst->session_type); rc = -EINVAL; @@ -1447,22 +1420,22 @@ static int msm_vidc_op_s_ctrl(struct v4l2_ctrl *ctrl) const char *ctrl_name = NULL; if (!ctrl) { - dprintk(VIDC_ERR, "%s invalid parameters for ctrl\n", __func__); + d_vpr_e("%s: invalid parameters for ctrl\n", __func__); return -EINVAL; } inst = container_of(ctrl->handler, struct msm_vidc_inst, ctrl_handler); if (!inst) { - dprintk(VIDC_ERR, "%s invalid parameters for inst\n", __func__); + d_vpr_e("%s: invalid parameters for inst\n", __func__); return -EINVAL; } rc = msm_vidc_try_set_ctrl(inst, ctrl); if (rc) { - dprintk(VIDC_ERR, "Failed setting %x\n", ctrl->id); + s_vpr_e(inst->sid, "Failed setting %x\n", ctrl->id); ctrl_name = v4l2_ctrl_get_name(ctrl->id); - dprintk(VIDC_ERR, "Failed setting control: Inst = %pK (%s)\n", + s_vpr_e(inst->sid, "Failed setting control: Inst = %pK (%s)\n", inst, ctrl_name ? ctrl_name : "Invalid ctrl"); } @@ -1478,38 +1451,37 @@ static int try_get_ctrl_for_instance(struct msm_vidc_inst *inst, case V4L2_CID_MPEG_VIDEO_H264_PROFILE: ctrl->val = msm_comm_hfi_to_v4l2( V4L2_CID_MPEG_VIDEO_H264_PROFILE, - inst->profile); + inst->profile, inst->sid); break; case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: ctrl->val = msm_comm_hfi_to_v4l2( V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, - inst->profile); + inst->profile, inst->sid); break; case V4L2_CID_MPEG_VIDEO_H264_LEVEL: ctrl->val = msm_comm_hfi_to_v4l2( V4L2_CID_MPEG_VIDEO_H264_LEVEL, - inst->level); + inst->level, inst->sid); break; case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL: ctrl->val = msm_comm_hfi_to_v4l2( V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL, - inst->level); + inst->level, inst->sid); break; case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: ctrl->val = msm_comm_hfi_to_v4l2( V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, - inst->level); + inst->level, inst->sid); break; case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: ctrl->val = inst->fmts[OUTPUT_PORT].count_min_host; - dprintk(VIDC_HIGH, "g_min: %x : hal_buffer %d min buffers %d\n", - hash32_ptr(inst->session), HAL_BUFFER_OUTPUT, - ctrl->val); + s_vpr_h(inst->sid, "g_min: hal_buffer %d min buffers %d\n", + HAL_BUFFER_OUTPUT, ctrl->val); break; case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: ctrl->val = inst->fmts[INPUT_PORT].count_min_host; - dprintk(VIDC_HIGH, "g_min: %x : hal_buffer %d min buffers %d\n", - hash32_ptr(inst->session), HAL_BUFFER_INPUT, ctrl->val); + s_vpr_h(inst->sid, "g_min: hal_buffer %d min buffers %d\n", + HAL_BUFFER_INPUT, ctrl->val); break; case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA: ctrl->val = inst->prop.extradata_ctrls; @@ -1540,26 +1512,26 @@ void *msm_vidc_open(int core_id, int session_type) if (core_id >= MSM_VIDC_CORES_MAX || session_type >= MSM_VIDC_MAX_DEVICES) { - dprintk(VIDC_ERR, "Invalid input, core_id = %d, session = %d\n", + d_vpr_e("Invalid input, core_id = %d, session = %d\n", core_id, session_type); goto err_invalid_core; } core = get_vidc_core(core_id); if (!core) { - dprintk(VIDC_ERR, - "Failed to find core for core_id = %d\n", core_id); + d_vpr_e("Failed to find core for core_id = %d\n", core_id); goto err_invalid_core; } inst = kzalloc(sizeof(*inst), GFP_KERNEL); if (!inst) { - dprintk(VIDC_ERR, "Failed to allocate memory\n"); + d_vpr_e("Failed to allocate memory\n"); rc = -ENOMEM; goto err_invalid_core; } + inst->sid = hash32_ptr(inst); pr_info(VIDC_DBG_TAG "Opening video instance: %pK, %d\n", - "high", inst, session_type); + "high", inst->sid, inst, session_type); mutex_init(&inst->sync_lock); mutex_init(&inst->bufq[OUTPUT_PORT].lock); mutex_init(&inst->bufq[INPUT_PORT].lock); @@ -1614,19 +1586,19 @@ void *msm_vidc_open(int core_id, int session_type) rc = msm_cvp_ctrl_init(inst, &msm_vidc_ctrl_ops); } if (rc) { - dprintk(VIDC_ERR, "Failed control initialization\n"); + s_vpr_e(inst->sid, "Failed control initialization\n"); goto fail_bufq_capture; } rc = vb2_bufq_init(inst, OUTPUT_MPLANE, session_type); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to initialize vb2 queue on capture port\n"); goto fail_bufq_capture; } rc = vb2_bufq_init(inst, INPUT_MPLANE, session_type); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to initialize vb2 queue on capture port\n"); goto fail_bufq_output; } @@ -1639,13 +1611,13 @@ void *msm_vidc_open(int core_id, int session_type) rc = msm_comm_try_state(inst, MSM_VIDC_CORE_INIT_DONE); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to move video instance to init state\n"); goto fail_init; } if (msm_comm_check_for_inst_overload(core)) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Instance count reached Max limit, rejecting session"); goto fail_init; } @@ -1658,7 +1630,7 @@ void *msm_vidc_open(int core_id, int session_type) if (inst->session_type == MSM_VIDC_CVP) { rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to move video instance to open done state\n"); goto fail_init; } @@ -1712,7 +1684,7 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst) int c = 0; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return; } @@ -1726,8 +1698,7 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst) struct vb2_buffer, queued_entry); if (vb->state == VB2_BUF_STATE_ACTIVE) { vb->planes[0].bytesused = 0; - print_vb2_buffer(VIDC_ERR, "undequeud vb2", - inst, vb); + print_vb2_buffer("undequeud vb2", inst, vb); vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); } } @@ -1749,20 +1720,16 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst) msm_comm_free_input_cr_table(inst); if (msm_comm_release_scratch_buffers(inst, false)) - dprintk(VIDC_ERR, - "Failed to release scratch buffers\n"); + s_vpr_e(inst->sid, "Failed to release scratch buffers\n"); if (msm_comm_release_recon_buffers(inst)) - dprintk(VIDC_ERR, - "Failed to release recon buffers\n"); + s_vpr_e(inst->sid, "Failed to release recon buffers\n"); if (msm_comm_release_persist_buffers(inst)) - dprintk(VIDC_ERR, - "Failed to release persist buffers\n"); + s_vpr_e(inst->sid, "Failed to release persist buffers\n"); if (msm_comm_release_input_tag(inst)) - dprintk(VIDC_ERR, - "Failed to release input_tag buffers\n"); + s_vpr_e(inst->sid, "Failed to release input_tag buffers\n"); msm_comm_release_client_data(inst, true); @@ -1771,17 +1738,14 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst) msm_comm_release_eos_buffers(inst); if (msm_comm_release_dpb_only_buffers(inst, true)) - dprintk(VIDC_ERR, - "Failed to release output buffers\n"); + s_vpr_e(inst->sid, "Failed to release output buffers\n"); if (inst->extradata_handle) msm_comm_smem_free(inst, inst->extradata_handle); mutex_lock(&inst->pending_getpropq.lock); if (!list_empty(&inst->pending_getpropq.list)) { - dprintk(VIDC_ERR, - "pending_getpropq not empty for instance %pK\n", - inst); + s_vpr_e(inst->sid, "pending_getpropq not empty\n"); list_for_each_entry_safe(temp_prop, dummy_prop, &inst->pending_getpropq.list, list) { kfree(temp_prop->data); @@ -1798,7 +1762,7 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) int i = 0; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -1839,7 +1803,7 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) msm_vidc_debugfs_deinit_inst(inst); pr_info(VIDC_DBG_TAG "Closed video instance: %pK\n", - "high", inst); + "high", inst->sid, inst); kfree(inst); return 0; } @@ -1858,7 +1822,7 @@ int msm_vidc_close(void *instance) int rc = 0; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -1868,9 +1832,7 @@ int msm_vidc_close(void *instance) */ rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) - dprintk(VIDC_ERR, - "Failed to move inst %pK to rel resource done state\n", - inst); + s_vpr_e(inst->sid, "Failed: move to rel resource done state\n"); /* * deinit instance after REL_RES_DONE to ensure hardware @@ -1887,7 +1849,7 @@ int msm_vidc_close(void *instance) rc = msm_comm_try_state(inst, MSM_VIDC_CORE_UNINIT); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to move inst %pK to uninit state\n", inst); rc = msm_comm_force_cleanup(inst); } diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 5fa0a05415e1..72d252395274 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -383,7 +383,7 @@ int msm_vidc_get_decoder_internal_buffer_sizes(struct msm_vidc_inst *inst) struct v4l2_format *f; if (!inst) { - dprintk(VIDC_ERR, "Instance is null!"); + d_vpr_e("%s: Instance is null!", __func__); return -EINVAL; } @@ -405,8 +405,8 @@ int msm_vidc_get_decoder_internal_buffer_sizes(struct msm_vidc_inst *inst) dec_calculators = &mpeg2d_calculators; break; default: - dprintk(VIDC_ERR, - "Invalid pix format. Internal buffer cal not defined : %x ", + s_vpr_e(inst->sid, + "Invalid pix format. Internal buffer cal not defined : %x\n", f->fmt.pix_mp.pixelformat); return -EINVAL; } @@ -503,7 +503,7 @@ int msm_vidc_get_encoder_internal_buffer_sizes(struct msm_vidc_inst *inst) struct v4l2_format *f; if (!inst) { - dprintk(VIDC_ERR, "Instance is null!"); + d_vpr_e("%s: Instance is null!", __func__); return -EINVAL; } @@ -519,7 +519,7 @@ int msm_vidc_get_encoder_internal_buffer_sizes(struct msm_vidc_inst *inst) enc_calculators = &vp8e_calculators; break; default: - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Invalid pix format. Internal buffer cal not defined : %x ", f->fmt.pix_mp.pixelformat); return -EINVAL; @@ -531,8 +531,7 @@ int msm_vidc_get_encoder_internal_buffer_sizes(struct msm_vidc_inst *inst) bframe = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); num_bframes = bframe->val; if (num_bframes < 0) { - dprintk(VIDC_ERR, - "%s: get num bframe failed\n", __func__); + s_vpr_e(inst->sid, "%s: get num bframe failed\n", __func__); return -EINVAL; } @@ -583,7 +582,7 @@ int msm_vidc_get_encoder_internal_buffer_sizes(struct msm_vidc_inst *inst) int msm_vidc_calculate_internal_buffer_sizes(struct msm_vidc_inst *inst) { if (!inst) { - dprintk(VIDC_ERR, "Instance is null!"); + d_vpr_e("%s: Instance is null!", __func__); return -EINVAL; } @@ -617,7 +616,7 @@ int msm_vidc_calculate_input_buffer_count(struct msm_vidc_inst *inst) int extra_buff_count = 0; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } fmt = &inst->fmts[INPUT_PORT]; @@ -641,9 +640,9 @@ int msm_vidc_calculate_input_buffer_count(struct msm_vidc_inst *inst) fmt->count_min_host = fmt->count_actual = fmt->count_min + extra_buff_count; - dprintk(VIDC_HIGH, "%s: %x : input min %d min_host %d actual %d\n", - __func__, hash32_ptr(inst->session), - fmt->count_min, fmt->count_min_host, fmt->count_actual); + s_vpr_h(inst->sid, "%s: input min %d min_host %d actual %d\n", + __func__, fmt->count_min, + fmt->count_min_host, fmt->count_actual); return 0; } @@ -655,7 +654,7 @@ int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst) u32 codec, output_min_count; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } fmt = &inst->fmts[OUTPUT_PORT]; @@ -697,9 +696,9 @@ int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst) fmt->count_min_host = fmt->count_actual = fmt->count_min + extra_buff_count; - dprintk(VIDC_HIGH, "%s: %x : output min %d min_host %d actual %d\n", - __func__, hash32_ptr(inst->session), - fmt->count_min, fmt->count_min_host, fmt->count_actual); + s_vpr_h(inst->sid, "%s: output min %d min_host %d actual %d\n", + __func__, fmt->count_min, fmt->count_min_host, + fmt->count_actual); return 0; } @@ -722,7 +721,7 @@ int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, enum hal_buffer buffer_type) { if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s Invalid args\n", __func__); + d_vpr_e("%s: Invalid args\n", __func__); return 0; } @@ -744,7 +743,7 @@ static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst) struct v4l2_format *f; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } @@ -820,7 +819,7 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) struct v4l2_format *f; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } @@ -914,10 +913,10 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) if (inst->buffer_size_limit && (inst->buffer_size_limit < frame_size)) { frame_size = inst->buffer_size_limit; - dprintk(VIDC_HIGH, "input buffer size limited to %d\n", + s_vpr_h(inst->sid, "input buffer size limited to %d\n", frame_size); } else { - dprintk(VIDC_HIGH, "set input buffer size to %d\n", + s_vpr_h(inst->sid, "set input buffer size to %d\n", frame_size); } @@ -930,7 +929,8 @@ u32 msm_vidc_calculate_dec_output_frame_size(struct msm_vidc_inst *inst) struct v4l2_format *f; f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; - hfi_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat); + hfi_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat, + inst->sid); return VENUS_BUFFER_SIZE(hfi_fmt, f->fmt.pix_mp.width, f->fmt.pix_mp.height); } @@ -949,7 +949,8 @@ u32 msm_vidc_calculate_enc_input_frame_size(struct msm_vidc_inst *inst) struct v4l2_format *f; f = &inst->fmts[INPUT_PORT].v4l2_fmt; - hfi_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat); + hfi_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat, + inst->sid); return VENUS_BUFFER_SIZE(hfi_fmt, f->fmt.pix_mp.width, f->fmt.pix_mp.height); } diff --git a/msm/vidc/msm_vidc_bus.h b/msm/vidc/msm_vidc_bus.h index ea25ba1c25e0..07a5371df699 100644 --- a/msm/vidc/msm_vidc_bus.h +++ b/msm/vidc/msm_vidc_bus.h @@ -224,7 +224,7 @@ int calc_bw_iris2(struct vidc_bus_vote_data *vidc_data); struct lut const *__lut(int width, int height, int fps); fp_t __compression_ratio(struct lut const *entry, int bpp); -void __dump(struct dump dump[], int len); +void __dump(struct dump dump[], int len, u32 sid); static inline bool __ubwc(enum hal_uncompressed_format f) { @@ -237,7 +237,7 @@ static inline bool __ubwc(enum hal_uncompressed_format f) } } -static inline int __bpp(enum hal_uncompressed_format f) +static inline int __bpp(enum hal_uncompressed_format f, u32 sid) { switch (f) { case HAL_COLOR_FORMAT_NV12: @@ -248,8 +248,7 @@ static inline int __bpp(enum hal_uncompressed_format f) case HAL_COLOR_FORMAT_P010: return 10; default: - dprintk(VIDC_ERR, - "Unsupported colorformat (%x)", f); + s_vpr_e(sid, "Unsupported colorformat (%x)", f); return INT_MAX; } } diff --git a/msm/vidc/msm_vidc_bus_iris1.c b/msm/vidc/msm_vidc_bus_iris1.c index a141b3dfbc85..91c1f6f2ec69 100644 --- a/msm/vidc/msm_vidc_bus_iris1.c +++ b/msm/vidc/msm_vidc_bus_iris1.c @@ -31,7 +31,7 @@ fp_t __compression_ratio(struct lut const *entry, int bpp) return FP_ZERO; /* impossible */ } -void __dump(struct dump dump[], int len) +void __dump(struct dump dump[], int len, u32 sid) { int c = 0; @@ -64,7 +64,7 @@ void __dump(struct dump dump[], int len) } } - dprintk(VIDC_BUS, "%s", formatted_line); + s_vpr_b(sid, "%s", formatted_line); } } @@ -128,7 +128,8 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) lcu_size = d->lcu_size; - dpb_bpp = d->num_formats >= 1 ? __bpp(d->color_formats[0]) : INT_MAX; + dpb_bpp = d->num_formats >= 1 ? + __bpp(d->color_formats[0], d->sid) : INT_MAX; unified_dpb_opb = d->num_formats == 1; @@ -315,7 +316,7 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) {"llc line buffer write", DUMP_FP_FMT, llc.line_buffer_write}, }; - __dump(dump, ARRAY_SIZE(dump)); + __dump(dump, ARRAY_SIZE(dump), d->sid); } d->calc_bw_ddr = kbps(fp_round(ddr.total)); @@ -403,7 +404,8 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) original_color_format = d->num_formats >= 1 ? d->color_formats[0] : HAL_UNUSED_COLOR; - dpb_bpp = d->num_formats >= 1 ? __bpp(d->color_formats[0]) : INT_MAX; + dpb_bpp = d->num_formats >= 1 ? + __bpp(d->color_formats[0], d->sid) : INT_MAX; original_compression_enabled = __ubwc(original_color_format); @@ -603,7 +605,7 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) {"llc ref read crcb", DUMP_FP_FMT, llc.ref_read_crcb}, {"llc line buffer", DUMP_FP_FMT, llc.line_buffer}, }; - __dump(dump, ARRAY_SIZE(dump)); + __dump(dump, ARRAY_SIZE(dump), d->sid); } d->calc_bw_ddr = kbps(fp_round(ddr.total)); @@ -630,7 +632,7 @@ static unsigned long __calculate(struct vidc_bus_vote_data *d) value = __calculate_cvp(d); break; default: - dprintk(VIDC_ERR, "Unknown Domain"); + s_vpr_e(d->sid, "Unknown Domain %#x", d->domain); } return value; diff --git a/msm/vidc/msm_vidc_bus_iris2.c b/msm/vidc/msm_vidc_bus_iris2.c index d18b4a258865..0da868b57612 100644 --- a/msm/vidc/msm_vidc_bus_iris2.c +++ b/msm/vidc/msm_vidc_bus_iris2.c @@ -66,7 +66,7 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) lcu_size = d->lcu_size; - dpb_bpp = __bpp(d->color_formats[0]); + dpb_bpp = __bpp(d->color_formats[0], d->sid); unified_dpb_opb = d->num_formats == 1; @@ -245,7 +245,7 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) {"llc line buffer write", DUMP_FP_FMT, llc.line_buffer_write}, }; - __dump(dump, ARRAY_SIZE(dump)); + __dump(dump, ARRAY_SIZE(dump), d->sid); } d->calc_bw_ddr = kbps(fp_round(ddr.total)); @@ -329,7 +329,7 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) DIV_ROUND_UP(height, lcu_size); tnbr_per_lcu = 16; - dpb_bpp = __bpp(d->color_formats[0]); + dpb_bpp = __bpp(d->color_formats[0], d->sid); y_bw_no_ubwc_8bpp = fp_div(FP_INT(width * height * fps), FP_INT(1000 * 1000)); @@ -507,7 +507,7 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) {"llc ref read crcb", DUMP_FP_FMT, llc.ref_read_crcb}, {"llc line buffer", DUMP_FP_FMT, llc.line_buffer}, }; - __dump(dump, ARRAY_SIZE(dump)); + __dump(dump, ARRAY_SIZE(dump), d->sid); } d->calc_bw_ddr = kbps(fp_round(ddr.total)); @@ -534,7 +534,7 @@ static unsigned long __calculate(struct vidc_bus_vote_data *d) value = __calculate_cvp(d); break; default: - dprintk(VIDC_ERR, "Unknown Domain"); + s_vpr_e(d->sid, "Unknown Domain %#x", d->domain); } return value; diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index fc262a771ceb..b30a21285186 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -242,15 +242,15 @@ static int fill_dynamic_stats(struct msm_vidc_inst *inst, vote_data->complexity_factor = max_cf; vote_data->input_cr = min_input_cr; - dprintk(VIDC_PERF, + s_vpr_p(inst->sid, "Input CR = %d Recon CR = %d Complexity Factor = %d\n", - vote_data->input_cr, vote_data->compression_ratio, - vote_data->complexity_factor); + vote_data->input_cr, vote_data->compression_ratio, + vote_data->complexity_factor); return 0; } -int msm_comm_set_buses(struct msm_vidc_core *core) +int msm_comm_set_buses(struct msm_vidc_core *core, u32 sid) { int rc = 0; struct msm_vidc_inst *inst = NULL; @@ -258,7 +258,7 @@ int msm_comm_set_buses(struct msm_vidc_core *core) unsigned long total_bw_ddr = 0, total_bw_llcc = 0; if (!core || !core->device) { - dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core); + s_vpr_e(sid, "%s: Invalid args: %pK\n", __func__, core); return -EINVAL; } hdev = core->device; @@ -282,8 +282,7 @@ int msm_comm_set_buses(struct msm_vidc_core *core) if ((!filled_len || !device_addr) && (inst->session_type != MSM_VIDC_CVP)) { - dprintk(VIDC_LOW, "%s: no input for session %x\n", - __func__, hash32_ptr(inst->session)); + s_vpr_l(sid, "%s: no input\n", __func__); continue; } @@ -297,7 +296,7 @@ int msm_comm_set_buses(struct msm_vidc_core *core) mutex_unlock(&core->lock); rc = call_hfi_op(hdev, vote_bus, hdev->hfi_device_data, - total_bw_ddr, total_bw_llcc); + total_bw_ddr, total_bw_llcc, sid); return rc; } @@ -316,7 +315,7 @@ int msm_comm_vote_bus(struct msm_vidc_inst *inst) int codec = 0; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); + d_vpr_e("%s: Invalid args: %pK\n", __func__, inst); return -EINVAL; } core = inst->core; @@ -339,12 +338,12 @@ int msm_comm_vote_bus(struct msm_vidc_inst *inst) if ((!filled_len || !device_addr) && (inst->session_type != MSM_VIDC_CVP)) { - dprintk(VIDC_LOW, "%s: no input for session %x\n", - __func__, hash32_ptr(inst->session)); + s_vpr_l(inst->sid, "%s: no input\n", __func__); return 0; } - vote_data->domain = get_hal_domain(inst->session_type); + vote_data->sid = inst->sid; + vote_data->domain = get_hal_domain(inst->session_type, inst->sid); vote_data->power_mode = 0; if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW && inst->session_type != MSM_VIDC_CVP) @@ -369,12 +368,12 @@ int msm_comm_vote_bus(struct msm_vidc_inst *inst) codec = V4L2_PIX_FMT_CVP; break; default: - dprintk(VIDC_ERR, "%s: invalid session_type %#x\n", + s_vpr_e(inst->sid, "%s: invalid session_type %#x\n", __func__, inst->session_type); break; } - vote_data->codec = get_hal_codec(codec); + vote_data->codec = get_hal_codec(codec, inst->sid); vote_data->input_width = inp_f->fmt.pix_mp.width; vote_data->input_height = inp_f->fmt.pix_mp.height; vote_data->output_width = out_f->fmt.pix_mp.width; @@ -426,7 +425,7 @@ int msm_comm_vote_bus(struct msm_vidc_inst *inst) call_core_op(core, calc_bw, vote_data); } - rc = msm_comm_set_buses(core); + rc = msm_comm_set_buses(core, inst->sid); return rc; } @@ -440,12 +439,12 @@ static int msm_dcvs_scale_clocks(struct msm_vidc_inst *inst, struct clock_data *dcvs; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s Invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } if (!inst->clk_data.dcvs_mode || inst->batch.enable) { - dprintk(VIDC_LOW, "Skip DCVS (dcvs %d, batching %d)\n", + s_vpr_l(inst->sid, "Skip DCVS (dcvs %d, batching %d)\n", inst->clk_data.dcvs_mode, inst->batch.enable); inst->clk_data.dcvs_flags = 0; return 0; @@ -491,23 +490,22 @@ static int msm_dcvs_scale_clocks(struct msm_vidc_inst *inst, dcvs->dcvs_flags |= MSM_VIDC_DCVS_DECR; } - dprintk(VIDC_PERF, - "DCVS: %x: bufs_with_fw %d Th[%d %d %d] Flag %#x\n", - hash32_ptr(inst->session), bufs_with_fw, - dcvs->min_threshold, dcvs->nom_threshold, dcvs->max_threshold, + s_vpr_p(inst->sid, "DCVS: bufs_with_fw %d Th[%d %d %d] Flag %#x\n", + bufs_with_fw, dcvs->min_threshold, + dcvs->nom_threshold, dcvs->max_threshold, dcvs->dcvs_flags); return rc; } -static unsigned long msm_vidc_max_freq(struct msm_vidc_core *core) +static unsigned long msm_vidc_max_freq(struct msm_vidc_core *core, u32 sid) { struct allowed_clock_rates_table *allowed_clks_tbl = NULL; unsigned long freq = 0; allowed_clks_tbl = core->resources.allowed_clks_tbl; freq = allowed_clks_tbl[0].clock_rate; - dprintk(VIDC_PERF, "Max rate = %lu\n", freq); + s_vpr_p(sid, "Max rate = %lu\n", freq); return freq; } @@ -542,7 +540,7 @@ void msm_comm_update_input_cr(struct msm_vidc_inst *inst, if (!found) { temp = kzalloc(sizeof(*temp), GFP_KERNEL); if (!temp) { - dprintk(VIDC_ERR, "%s: malloc failure.\n", __func__); + s_vpr_e(inst->sid, "%s: malloc failure.\n", __func__); goto exit; } temp->index = index; @@ -606,14 +604,14 @@ static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, vsp_cycles += ((fps * filled_len * 8) * 10) / 7; } else { - dprintk(VIDC_ERR, "Unknown session type = %s\n", __func__); - return msm_vidc_max_freq(inst->core); + s_vpr_e(inst->sid, "%s: Unknown session type\n", __func__); + return msm_vidc_max_freq(inst->core, inst->sid); } freq = max(vpp_cycles, vsp_cycles); freq = max(freq, fw_cycles); - dprintk(VIDC_LOW, "Update DCVS Load\n"); + s_vpr_l(inst->sid, "Update DCVS Load\n"); allowed_clks_tbl = core->resources.allowed_clks_tbl; for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) { rate = allowed_clks_tbl[i].clock_rate; @@ -624,7 +622,7 @@ static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, if (i < 0) i = 0; - dprintk(VIDC_PERF, "%s Inst %pK : Filled Len = %d Freq = %llu\n", + s_vpr_p(inst->sid, "%s: Inst %pK : Filled Len = %d Freq = %llu\n", __func__, inst, filled_len, freq); return (unsigned long) freq; @@ -695,8 +693,8 @@ static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst, vsp_cycles += ((fps * filled_len * 8) * 10) / 5; } else { - dprintk(VIDC_ERR, "Unknown session type = %s\n", __func__); - return msm_vidc_max_freq(inst->core); + s_vpr_e(inst->sid, "%s: Unknown session type\n", __func__); + return msm_vidc_max_freq(inst->core, inst->sid); } freq = max(vpp_cycles, vsp_cycles); @@ -712,10 +710,8 @@ static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst, if (i < 0) i = 0; - dprintk(VIDC_PERF, - "%s: inst %pK: %x : filled len %d required freq %llu\n", - __func__, inst, hash32_ptr(inst->session), - filled_len, freq); + s_vpr_p(inst->sid, "%s: inst %pK: filled len %d required freq %llu\n", + __func__, inst, filled_len, freq); return (unsigned long) freq; } @@ -792,8 +788,8 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, /* vsp perf is about 0.5 bits/cycle */ vsp_cycles += ((fps * filled_len * 8) * 10) / 5; } else { - dprintk(VIDC_ERR, "Unknown session type = %s\n", __func__); - return msm_vidc_max_freq(inst->core); + s_vpr_e(inst->sid, "%s: Unknown session type\n", __func__); + return msm_vidc_max_freq(inst->core, inst->sid); } freq = max(vpp_cycles, vsp_cycles); @@ -809,15 +805,13 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, if (i < 0) i = 0; - dprintk(VIDC_PERF, - "%s: inst %pK: %x : filled len %d required freq %llu\n", - __func__, inst, hash32_ptr(inst->session), - filled_len, freq); + s_vpr_p(inst->sid, "%s: inst %pK: filled len %d required freq %llu\n", + __func__, inst, filled_len, freq); return (unsigned long) freq; } -int msm_vidc_set_clocks(struct msm_vidc_core *core) +int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid) { struct hfi_device *hdev; unsigned long freq_core_1 = 0, freq_core_2 = 0, rate = 0; @@ -832,8 +826,7 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core) hdev = core->device; allowed_clks_tbl = core->resources.allowed_clks_tbl; if (!allowed_clks_tbl) { - dprintk(VIDC_ERR, - "%s Invalid parameters\n", __func__); + s_vpr_e(sid, "%s: Invalid parameters\n", __func__); return -EINVAL; } @@ -855,8 +848,7 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core) mutex_unlock(&inst->registeredbufs.lock); if (!filled_len || !device_addr) { - dprintk(VIDC_LOW, "%s no input for session %x\n", - __func__, hash32_ptr(inst->session)); + s_vpr_l(sid, "%s: no input\n", __func__); continue; } @@ -872,8 +864,7 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core) freq_core_max = max_t(unsigned long, freq_core_1, freq_core_2); if (msm_vidc_clock_voting) { - dprintk(VIDC_PERF, - "msm_vidc_clock_voting %d\n", + s_vpr_p(sid, "msm_vidc_clock_voting %d\n", msm_vidc_clock_voting); freq_core_max = msm_vidc_clock_voting; decrement = false; @@ -913,12 +904,12 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core) core->curr_freq = rate; mutex_unlock(&core->lock); - dprintk(VIDC_PERF, + s_vpr_p(sid, "%s: clock rate %lu requested %lu increment %d decrement %d\n", __func__, core->curr_freq, core->min_freq, increment, decrement); rc = call_hfi_op(hdev, scale_clocks, - hdev->hfi_device_data, core->curr_freq); + hdev->hfi_device_data, core->curr_freq, sid); return rc; } @@ -932,8 +923,7 @@ int msm_comm_scale_clocks(struct msm_vidc_inst *inst) bool is_turbo = false; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n", - __func__, inst); + d_vpr_e("%s: Invalid args: Inst = %pK\n", __func__, inst); return -EINVAL; } @@ -953,14 +943,14 @@ int msm_comm_scale_clocks(struct msm_vidc_inst *inst) mutex_unlock(&inst->registeredbufs.lock); if (!filled_len || !device_addr) { - dprintk(VIDC_LOW, "%s no input for session %x\n", - __func__, hash32_ptr(inst->session)); + s_vpr_l(inst->sid, "%s: no input\n", __func__); return 0; } if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW || is_turbo || msm_vidc_clock_voting) { - inst->clk_data.min_freq = msm_vidc_max_freq(inst->core); + inst->clk_data.min_freq = + msm_vidc_max_freq(inst->core, inst->sid); inst->clk_data.dcvs_flags = 0; } else { freq = call_core_op(inst->core, calc_freq, inst, filled_len); @@ -968,8 +958,7 @@ int msm_comm_scale_clocks(struct msm_vidc_inst *inst) /* update dcvs flags */ msm_dcvs_scale_clocks(inst, freq); } - - msm_vidc_set_clocks(inst->core); + msm_vidc_set_clocks(inst->core, inst->sid); return 0; } @@ -980,20 +969,20 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc) struct hfi_device *hdev; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s Invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } core = inst->core; hdev = core->device; if (msm_comm_scale_clocks(inst)) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to scale clocks. May impact performance\n"); } if (do_bw_calc) { if (msm_comm_vote_bus(inst)) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to scale DDR bus. May impact perf\n"); } } @@ -1003,7 +992,7 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc) int msm_dcvs_try_enable(struct msm_vidc_inst *inst) { if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: Invalid args: %p\n", __func__, inst); + d_vpr_e("%s: Invalid args: %p\n", __func__, inst); return -EINVAL; } @@ -1016,7 +1005,7 @@ int msm_dcvs_try_enable(struct msm_vidc_inst *inst) is_turbo_session(inst) || inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ); - dprintk(VIDC_HIGH|VIDC_PERF, "DCVS %s: %pK\n", + s_vpr_hp(inst->sid, "DCVS %s: %pK\n", inst->clk_data.dcvs_mode ? "enabled" : "disabled", inst); return 0; @@ -1028,13 +1017,13 @@ int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst) int fourcc, count; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n", + d_vpr_e("%s: Invalid args: Inst = %pK\n", __func__, inst); return -EINVAL; } if (inst->session_type == MSM_VIDC_CVP) { - dprintk(VIDC_LOW, "%s: cvp session\n", __func__); + s_vpr_l(inst->sid, "%s: cvp session\n", __func__); return 0; } @@ -1053,7 +1042,7 @@ int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst) } if (!inst->clk_data.entry) { - dprintk(VIDC_ERR, "%s No match found\n", __func__); + s_vpr_e(inst->sid, "%s: No match found\n", __func__); rc = -EINVAL; } @@ -1070,13 +1059,12 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) struct clock_data *dcvs; struct msm_vidc_format *fmt; - dprintk(VIDC_HIGH, "Init DCVS Load\n"); - if (!inst || !inst->core || !inst->clk_data.entry) { - dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n", + d_vpr_e("%s: Invalid args: Inst = %pK\n", __func__, inst); return; } + s_vpr_h(inst->sid, "Init DCVS Load\n"); core = inst->core; dcvs = &inst->clk_data; @@ -1092,7 +1080,7 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) } else if (inst->session_type == MSM_VIDC_DECODER) { fmt = &inst->fmts[OUTPUT_PORT]; } else { - dprintk(VIDC_ERR, "%s: invalid session type %#x\n", + s_vpr_e(inst->sid, "%s: invalid session type %#x\n", __func__, inst->session_type); return; } @@ -1124,7 +1112,7 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) rc = msm_comm_scale_clocks_and_bus(inst, 1); if (rc) - dprintk(VIDC_ERR, "%s Failed to scale Clocks and Bus\n", + s_vpr_e(inst->sid, "%s: Failed to scale Clocks and Bus\n", __func__); } @@ -1137,8 +1125,7 @@ int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, - "%s Invalid args: Inst = %pK\n", + d_vpr_e("%s: Invalid args: Inst = %pK\n", __func__, inst); return -EINVAL; } @@ -1188,7 +1175,7 @@ int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst) V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR && mbps <= CBR_VFR_MB_LIMIT)) { pdata.video_work_route = 1; - dprintk(VIDC_HIGH, "Configured work route = 1"); + s_vpr_h(inst->sid, "Configured work route = 1"); } } else { return -EINVAL; @@ -1201,8 +1188,7 @@ int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst) (void *)inst->session, HFI_PROPERTY_PARAM_WORK_ROUTE, (void *)&pdata, sizeof(pdata)); if (rc) - dprintk(VIDC_ERR, - " Failed to configure work route %pK\n", inst); + s_vpr_e(inst->sid, "Failed to configure work route\n"); return rc; } @@ -1216,8 +1202,7 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, - "%s Invalid args: Inst = %pK\n", + d_vpr_e("%s: Invalid args: Inst = %pK\n", __func__, inst); return -EINVAL; } @@ -1249,15 +1234,14 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) return -EINVAL; } - dprintk(VIDC_HIGH, "Configurng work route = %u", + s_vpr_h(inst->sid, "Configurng work route = %u", pdata.video_work_route); rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_PARAM_WORK_ROUTE, (void *)&pdata, sizeof(pdata)); if (rc) - dprintk(VIDC_ERR, - " Failed to configure work route %pK\n", inst); + s_vpr_e(inst->sid, "Failed to configure work route\n"); else inst->clk_data.work_route = pdata.video_work_route; @@ -1273,8 +1257,7 @@ static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst) struct v4l2_format *f; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, - "%s Invalid args: Inst = %pK\n", + d_vpr_e("%s: Invalid args: Inst = %pK\n", __func__, inst); return -EINVAL; } @@ -1312,8 +1295,7 @@ static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst) (void *)inst->session, HFI_PROPERTY_PARAM_WORK_MODE, (void *)&pdata, sizeof(pdata)); if (rc) - dprintk(VIDC_ERR, - " Failed to configure Work Mode %pK\n", inst); + s_vpr_e(inst->sid, "Failed to configure Work Mode\n"); /* For WORK_MODE_1, set Low Latency mode by default to HW. */ @@ -1342,8 +1324,7 @@ int msm_vidc_decide_work_mode_iris1(struct msm_vidc_inst *inst) u32 codec; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, - "%s Invalid args: Inst = %pK\n", + d_vpr_e("%s: Invalid args: Inst = %pK\n", __func__, inst); return -EINVAL; } @@ -1352,7 +1333,7 @@ int msm_vidc_decide_work_mode_iris1(struct msm_vidc_inst *inst) if (inst->clk_data.low_latency_mode) { pdata.video_work_mode = HFI_WORKMODE_1; - dprintk(VIDC_HIGH, "Configured work mode = 1"); + s_vpr_h(inst->sid, "Configured work mode = 1"); goto decision_done; } @@ -1396,8 +1377,8 @@ int msm_vidc_decide_work_mode_iris1(struct msm_vidc_inst *inst) (void *)inst->session, HFI_PROPERTY_PARAM_WORK_MODE, (void *)&pdata, sizeof(pdata)); if (rc) - dprintk(VIDC_ERR, - " Failed to configure Work Mode %pK\n", inst); + s_vpr_e(inst->sid, "Failed to configure Work Mode %u\n", + pdata.video_work_mode); /* For WORK_MODE_1, set Low Latency mode by default to HW. */ @@ -1425,8 +1406,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) struct v4l2_format *inp_f; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, - "%s Invalid args: Inst = %pK\n", + d_vpr_e("%s: Invalid args: Inst = %pK\n", __func__, inst); return -EINVAL; } @@ -1464,7 +1444,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) return -EINVAL; } - dprintk(VIDC_HIGH, "Configuring work mode = %u low latency = %u", + s_vpr_h(inst->sid, "Configuring work mode = %u low latency = %u", pdata.video_work_mode, latency.enable); @@ -1474,8 +1454,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE, (void *)&latency, sizeof(latency)); if (rc) - dprintk(VIDC_ERR, - " Failed to configure low latency %pK\n", inst); + s_vpr_e(inst->sid, "Failed to configure low latency\n"); else inst->clk_data.low_latency_mode = latency.enable; } @@ -1484,8 +1463,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) (void *)inst->session, HFI_PROPERTY_PARAM_WORK_MODE, (void *)&pdata, sizeof(pdata)); if (rc) - dprintk(VIDC_ERR, - " Failed to configure Work Mode %pK\n", inst); + s_vpr_e(inst->sid, "Failed to configure Work Mode\n"); else inst->clk_data.work_mode = pdata.video_work_mode; @@ -1503,9 +1481,9 @@ static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, hdev = inst->core->device; if (inst->session_type != MSM_VIDC_ENCODER) { - dprintk(VIDC_LOW, - "%s : Not an encoder session. Nothing to do\n", - __func__); + s_vpr_l(inst->sid, + "%s: Not an encoder session. Nothing to do\n", + __func__); return 0; } @@ -1517,8 +1495,7 @@ static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, (void *)inst->session, prop_id, pdata, sizeof(hfi_perf_mode)); if (rc) { - dprintk(VIDC_ERR, - "%s: Failed to set power save mode for inst: %pK\n", + s_vpr_e(inst->sid, "%s: Failed to set power save mode\n", __func__, inst); return rc; } @@ -1526,18 +1503,18 @@ static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, inst->flags | VIDC_LOW_POWER : inst->flags & ~VIDC_LOW_POWER; - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "Power Save Mode for inst: %pK Enable = %d\n", inst, enable); return rc; } static int msm_vidc_move_core_to_power_save_mode(struct msm_vidc_core *core, - u32 core_id) + u32 core_id, u32 sid) { struct msm_vidc_inst *inst = NULL; - dprintk(VIDC_HIGH, "Core %d : Moving all inst to LP mode\n", core_id); + s_vpr_h(sid, "Core %d : Moving all inst to LP mode\n", core_id); mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { if (inst->clk_data.core_id == core_id && @@ -1599,14 +1576,13 @@ int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) struct msm_vidc_core *core; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, - "%s Invalid args: Inst = %pK\n", + d_vpr_e("%s: Invalid args: Inst = %pK\n", __func__, inst); return -EINVAL; } core = inst->core; - max_freq = msm_vidc_max_freq(inst->core); + max_freq = msm_vidc_max_freq(inst->core, inst->sid); inst->clk_data.core_id = 0; core_load = get_core_load(core, VIDC_CORE_ID_1, false, true); @@ -1627,15 +1603,15 @@ int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) max_hq_mbpf = core->resources.max_hq_mbs_per_frame; max_hq_mbps = core->resources.max_hq_mbs_per_sec; - dprintk(VIDC_HIGH, "Core RT Load = %d LP Load = %d\n", + s_vpr_h(inst->sid, "Core RT Load = %d LP Load = %d\n", core_load, core_lp_load); - dprintk(VIDC_HIGH, "Max Load = %lu\n", max_freq); - dprintk(VIDC_HIGH, "Current Load = %d Current LP Load = %d\n", + s_vpr_h(inst->sid, "Max Load = %lu\n", max_freq); + s_vpr_h(inst->sid, "Current Load = %d Current LP Load = %d\n", cur_inst_load, cur_inst_lp_load); if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ && (core_load > max_freq || core_lp_load > max_freq)) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "CQ session - Core cannot support this load\n"); return -EINVAL; } @@ -1647,16 +1623,17 @@ int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) } else if (cur_inst_lp_load + core_load <= max_freq) { msm_vidc_power_save_mode_enable(inst, true); } else if (cur_inst_lp_load + core_lp_load <= max_freq) { - dprintk(VIDC_HIGH, "Moved all inst's to LP"); - msm_vidc_move_core_to_power_save_mode(core, VIDC_CORE_ID_1); + s_vpr_h(inst->sid, "Moved all inst's to LP"); + msm_vidc_move_core_to_power_save_mode(core, + VIDC_CORE_ID_1, inst->sid); } else { - dprintk(VIDC_ERR, "Core cannot support this load\n"); + s_vpr_e(inst->sid, "Core cannot support this load\n"); return -EINVAL; } inst->clk_data.core_id = VIDC_CORE_ID_1; rc = msm_comm_scale_clocks_and_bus(inst, 1); - msm_print_core_status(core, VIDC_CORE_ID_1); + msm_print_core_status(core, VIDC_CORE_ID_1, inst->sid); return rc; } @@ -1666,7 +1643,7 @@ int msm_vidc_decide_core_and_power_mode_iris2(struct msm_vidc_inst *inst) bool enable = true; inst->clk_data.core_id = VIDC_CORE_ID_1; - msm_print_core_status(inst->core, VIDC_CORE_ID_1); + msm_print_core_status(inst->core, VIDC_CORE_ID_1, inst->sid); /* Power saving always disabled for CQ and LOSSLESS RC modes. */ mbpf = msm_vidc_get_mbs_per_frame(inst); @@ -1696,22 +1673,21 @@ void msm_vidc_init_core_clk_ops(struct msm_vidc_core *core) core->core_ops = &core_ops_iris2; } -void msm_print_core_status(struct msm_vidc_core *core, u32 core_id) +void msm_print_core_status(struct msm_vidc_core *core, u32 core_id, u32 sid) { struct msm_vidc_inst *inst = NULL; struct v4l2_format *out_f; struct v4l2_format *inp_f; - dprintk(VIDC_PERF, "Instances running on core %u", core_id); + s_vpr_p(sid, "Instances running on core %u", core_id); mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { - if ((inst->clk_data.core_id != core_id) && (inst->clk_data.core_id != VIDC_CORE_ID_3)) continue; out_f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; inp_f = &inst->fmts[INPUT_PORT].v4l2_fmt; - dprintk(VIDC_PERF, + s_vpr_p(sid, "inst %pK (%4ux%4u) to (%4ux%4u) %3u %s %s %u %s %s %lu\n", inst, inp_f->fmt.pix_mp.width, diff --git a/msm/vidc/msm_vidc_clocks.h b/msm/vidc/msm_vidc_clocks.h index c9b463637e77..7a2be7e613b1 100644 --- a/msm/vidc/msm_vidc_clocks.h +++ b/msm/vidc/msm_vidc_clocks.h @@ -8,7 +8,7 @@ #include "msm_vidc_internal.h" void msm_clock_data_reset(struct msm_vidc_inst *inst); -int msm_vidc_set_clocks(struct msm_vidc_core *core); +int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid); int msm_comm_vote_bus(struct msm_vidc_inst *inst); int msm_dcvs_try_enable(struct msm_vidc_inst *inst); bool res_is_less_than(u32 width, u32 height, u32 ref_width, u32 ref_height); @@ -27,7 +27,7 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst); int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst); int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst); int msm_vidc_decide_core_and_power_mode_iris2(struct msm_vidc_inst *inst); -void msm_print_core_status(struct msm_vidc_core *core, u32 core_id); +void msm_print_core_status(struct msm_vidc_core *core, u32 core_id, u32 sid); void msm_comm_free_input_cr_table(struct msm_vidc_inst *inst); void msm_comm_update_input_cr(struct msm_vidc_inst *inst, u32 index, u32 cr); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 4a3e6e56d341..d1f57b0e8700 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -43,7 +43,7 @@ int msm_comm_g_ctrl_for_id(struct msm_vidc_inst *inst, int id) return ctrl->val; } -int msm_comm_hfi_to_v4l2(int id, int value) +int msm_comm_hfi_to_v4l2(int id, int value, u32 sid) { switch (id) { /* H264 */ @@ -245,11 +245,11 @@ int msm_comm_hfi_to_v4l2(int id, int value) } unknown_value: - dprintk(VIDC_ERR, "Unknown control (%x, %d)\n", id, value); + s_vpr_e(sid, "Unknown control (%x, %d)\n", id, value); return -EINVAL; } -static int h264_level_v4l2_to_hfi(int value) +static int h264_level_v4l2_to_hfi(int value, u32 sid) { switch (value) { case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: @@ -299,11 +299,11 @@ static int h264_level_v4l2_to_hfi(int value) } unknown_value: - dprintk(VIDC_ERR, "Unknown level (%d)\n", value); + s_vpr_e(sid, "Unknown level (%d)\n", value); return -EINVAL; } -static int hevc_level_v4l2_to_hfi(int value) +static int hevc_level_v4l2_to_hfi(int value, u32 sid) { switch (value) { case V4L2_MPEG_VIDEO_HEVC_LEVEL_1: @@ -339,11 +339,11 @@ static int hevc_level_v4l2_to_hfi(int value) } unknown_value: - dprintk(VIDC_ERR, "Unknown level (%d)\n", value); + s_vpr_e(sid, "Unknown level (%d)\n", value); return -EINVAL; } -static int vp9_level_v4l2_to_hfi(int value) +static int vp9_level_v4l2_to_hfi(int value, u32 sid) { switch (value) { case V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_1: @@ -377,11 +377,11 @@ static int vp9_level_v4l2_to_hfi(int value) } unknown_value: - dprintk(VIDC_ERR, "Unknown level (%d)\n", value); + s_vpr_e(sid, "Unknown level (%d)\n", value); return -EINVAL; - } -int msm_comm_v4l2_to_hfi(int id, int value) + +int msm_comm_v4l2_to_hfi(int id, int value, u32 sid) { switch (id) { /* H264 */ @@ -405,7 +405,7 @@ int msm_comm_v4l2_to_hfi(int id, int value) return HFI_H264_PROFILE_HIGH; } case V4L2_CID_MPEG_VIDEO_H264_LEVEL: - return h264_level_v4l2_to_hfi(value); + return h264_level_v4l2_to_hfi(value, sid); case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: switch (value) { case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC: @@ -447,7 +447,7 @@ int msm_comm_v4l2_to_hfi(int id, int value) return HFI_VP9_PROFILE_P0; } case V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL: - return vp9_level_v4l2_to_hfi(value); + return vp9_level_v4l2_to_hfi(value, sid); case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: switch (value) { case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN: @@ -460,7 +460,7 @@ int msm_comm_v4l2_to_hfi(int id, int value) return HFI_HEVC_PROFILE_MAIN; } case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: - return hevc_level_v4l2_to_hfi(value); + return hevc_level_v4l2_to_hfi(value, sid); case V4L2_CID_MPEG_VIDEO_HEVC_TIER: switch (value) { case V4L2_MPEG_VIDEO_HEVC_TIER_MAIN: @@ -503,52 +503,52 @@ int msm_comm_v4l2_to_hfi(int id, int value) return HFI_H264_DB_MODE_ALL_BOUNDARY; } } - dprintk(VIDC_ERR, "Unknown control (%x, %d)\n", id, value); + s_vpr_e(sid, "Unknown control (%x, %d)\n", id, value); return -EINVAL; } -int msm_comm_get_v4l2_profile(int fourcc, int profile) +int msm_comm_get_v4l2_profile(int fourcc, int profile, u32 sid) { switch (fourcc) { case V4L2_PIX_FMT_H264: return msm_comm_hfi_to_v4l2( V4L2_CID_MPEG_VIDEO_H264_PROFILE, - profile); + profile, sid); case V4L2_PIX_FMT_HEVC: return msm_comm_hfi_to_v4l2( V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, - profile); + profile, sid); case V4L2_PIX_FMT_VP8: case V4L2_PIX_FMT_VP9: case V4L2_PIX_FMT_MPEG2: return 0; default: - dprintk(VIDC_ERR, "Unknown codec id %x\n", fourcc); + s_vpr_e(sid, "Unknown codec id %x\n", fourcc); return 0; } } -int msm_comm_get_v4l2_level(int fourcc, int level) +int msm_comm_get_v4l2_level(int fourcc, int level, u32 sid) { switch (fourcc) { case V4L2_PIX_FMT_H264: return msm_comm_hfi_to_v4l2( V4L2_CID_MPEG_VIDEO_H264_LEVEL, - level); + level, sid); case V4L2_PIX_FMT_HEVC: level &= ~(0xF << 28); return msm_comm_hfi_to_v4l2( V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, - level); + level, sid); case V4L2_PIX_FMT_VP8: return msm_comm_hfi_to_v4l2( V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL, - level); + level, sid); case V4L2_PIX_FMT_VP9: case V4L2_PIX_FMT_MPEG2: return 0; default: - dprintk(VIDC_ERR, "Unknown codec id %x\n", fourcc); + s_vpr_e(sid, "Unknown codec id %x\n", fourcc); return 0; } } @@ -562,21 +562,21 @@ int msm_comm_ctrl_init(struct msm_vidc_inst *inst, int ret_val = 0; if (!inst || !drv_ctrls || !ctrl_ops || !num_ctrls) { - dprintk(VIDC_ERR, "%s - invalid input\n", __func__); + d_vpr_e("%s: invalid input\n", __func__); return -EINVAL; } inst->ctrls = kcalloc(num_ctrls, sizeof(struct v4l2_ctrl *), GFP_KERNEL); if (!inst->ctrls) { - dprintk(VIDC_ERR, "%s - failed to allocate ctrl\n", __func__); + s_vpr_e(inst->sid, "%s: failed to allocate ctrl\n", __func__); return -ENOMEM; } ret_val = v4l2_ctrl_handler_init(&inst->ctrl_handler, num_ctrls); if (ret_val) { - dprintk(VIDC_ERR, "CTRL ERR: Control handler init failed, %d\n", + s_vpr_e(inst->sid, "Control handler init failed, %d\n", inst->ctrl_handler.error); return ret_val; } @@ -622,14 +622,14 @@ int msm_comm_ctrl_init(struct msm_vidc_inst *inst, } if (!ctrl) { - dprintk(VIDC_ERR, "%s - invalid ctrl %s\n", __func__, + s_vpr_e(inst->sid, "%s: invalid ctrl %s\n", __func__, drv_ctrls[idx].name); return -EINVAL; } ret_val = inst->ctrl_handler.error; if (ret_val) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Error adding ctrl (%s) to ctrl handle, %d\n", drv_ctrls[idx].name, inst->ctrl_handler.error); return ret_val; @@ -646,7 +646,7 @@ int msm_comm_ctrl_init(struct msm_vidc_inst *inst, int msm_comm_ctrl_deinit(struct msm_vidc_inst *inst) { if (!inst) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } @@ -660,13 +660,12 @@ int msm_comm_set_stream_output_mode(struct msm_vidc_inst *inst, enum multi_stream mode) { if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } if (!is_decode_session(inst)) { - dprintk(VIDC_HIGH, "%s: not a decode session %x\n", - __func__, hash32_ptr(inst->session)); + s_vpr_h(inst->sid, "%s: not a decode session\n", __func__); return -EINVAL; } @@ -681,8 +680,7 @@ int msm_comm_set_stream_output_mode(struct msm_vidc_inst *inst, enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst) { if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params, return default mode\n", - __func__); + d_vpr_e("%s: invalid params\n", __func__); return HAL_VIDEO_DECODER_PRIMARY; } @@ -702,7 +700,7 @@ bool is_single_session(struct msm_vidc_inst *inst, u32 ignore_flags) struct msm_vidc_inst *temp; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return false; } core = inst->core; @@ -732,7 +730,7 @@ int msm_comm_get_num_perf_sessions(struct msm_vidc_inst *inst) struct msm_vidc_inst *temp; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); goto exit; } core = inst->core; @@ -832,7 +830,7 @@ int msm_comm_get_device_load(struct msm_vidc_core *core, int num_mbs_per_sec = 0; if (!core) { - dprintk(VIDC_ERR, "Invalid args: %pK\n", core); + d_vpr_e("Invalid args: %pK\n", core); return -EINVAL; } @@ -848,7 +846,7 @@ int msm_comm_get_device_load(struct msm_vidc_core *core, return num_mbs_per_sec; } -enum hal_domain get_hal_domain(int session_type) +enum hal_domain get_hal_domain(int session_type, u32 sid) { enum hal_domain domain; @@ -863,7 +861,7 @@ enum hal_domain get_hal_domain(int session_type) domain = HAL_VIDEO_DOMAIN_CVP; break; default: - dprintk(VIDC_ERR, "Wrong domain %d\n", session_type); + s_vpr_e(sid, "Wrong domain %d\n", session_type); domain = HAL_UNUSED_DOMAIN; break; } @@ -871,7 +869,7 @@ enum hal_domain get_hal_domain(int session_type) return domain; } -enum hal_video_codec get_hal_codec(int fourcc) +enum hal_video_codec get_hal_codec(int fourcc, u32 sid) { enum hal_video_codec codec; @@ -905,7 +903,7 @@ enum hal_video_codec get_hal_codec(int fourcc) codec = HAL_VIDEO_CODEC_CVP; break; default: - dprintk(VIDC_ERR, "Wrong codec: %#x\n", fourcc); + s_vpr_e(sid, "Wrong codec: %#x\n", fourcc); codec = HAL_UNUSED_CODEC; break; } @@ -944,7 +942,7 @@ enum hal_uncompressed_format msm_comm_get_hal_uncompressed(int fourcc) return format; } -u32 msm_comm_get_hfi_uncompressed(int fourcc) +u32 msm_comm_get_hfi_uncompressed(int fourcc, u32 sid) { u32 format; @@ -969,7 +967,7 @@ u32 msm_comm_get_hfi_uncompressed(int fourcc) break; default: format = HFI_COLOR_FORMAT_NV12_UBWC; - dprintk(VIDC_ERR, "Invalid format, defaulting to UBWC"); + s_vpr_e(sid, "Invalid format, defaulting to UBWC"); break; } @@ -981,7 +979,7 @@ struct msm_vidc_core *get_vidc_core(int core_id) int found = 0; if (core_id > MSM_VIDC_CORES_MAX) { - dprintk(VIDC_ERR, "Core id = %d is greater than max = %d\n", + d_vpr_e("Core id = %d is greater than max = %d\n", core_id, MSM_VIDC_CORES_MAX); return NULL; } @@ -999,13 +997,13 @@ struct msm_vidc_core *get_vidc_core(int core_id) } const struct msm_vidc_format_desc *msm_comm_get_pixel_fmt_index( - const struct msm_vidc_format_desc fmt[], int size, int index) + const struct msm_vidc_format_desc fmt[], int size, int index, u32 sid) { int i, k = 0; if (!fmt || index < 0) { - dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK, index = %d\n", - fmt, index); + s_vpr_e(sid, "Invalid inputs, fmt = %pK, index = %d\n", + fmt, index); return NULL; } for (i = 0; i < size; i++) { @@ -1014,18 +1012,18 @@ const struct msm_vidc_format_desc *msm_comm_get_pixel_fmt_index( k++; } if (i == size) { - dprintk(VIDC_HIGH, "Format not found\n"); + s_vpr_h(sid, "Format not found\n"); return NULL; } return &fmt[i]; } struct msm_vidc_format_desc *msm_comm_get_pixel_fmt_fourcc( - struct msm_vidc_format_desc fmt[], int size, int fourcc) + struct msm_vidc_format_desc fmt[], int size, int fourcc, u32 sid) { int i; if (!fmt) { - dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK\n", fmt); + s_vpr_e(sid, "Invalid inputs, fmt = %pK\n", fmt); return NULL; } for (i = 0; i < size; i++) { @@ -1033,19 +1031,19 @@ struct msm_vidc_format_desc *msm_comm_get_pixel_fmt_fourcc( break; } if (i == size) { - dprintk(VIDC_HIGH, "Format not found\n"); + s_vpr_h(sid, "Format not found\n"); return NULL; } return &fmt[i]; } struct msm_vidc_format_constraint *msm_comm_get_pixel_fmt_constraints( - struct msm_vidc_format_constraint fmt[], int size, int fourcc) + struct msm_vidc_format_constraint fmt[], int size, int fourcc, u32 sid) { int i; if (!fmt) { - dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK\n", fmt); + s_vpr_e(sid, "Invalid inputs, fmt = %pK\n", fmt); return NULL; } for (i = 0; i < size; i++) { @@ -1053,7 +1051,7 @@ struct msm_vidc_format_constraint *msm_comm_get_pixel_fmt_constraints( break; } if (i == size) { - dprintk(VIDC_HIGH, "Format constraint not found.\n"); + s_vpr_h(sid, "Format constraint not found.\n"); return NULL; } return &fmt[i]; @@ -1073,10 +1071,10 @@ static void update_capability(struct msm_vidc_codec_capability *in, struct msm_vidc_capability *capability) { if (!in || !capability) { - dprintk(VIDC_ERR, "%s Invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, in, capability); return; } - if (in->capability_type < CAP_MAX) { capability->cap[in->capability_type].capability_type = in->capability_type; @@ -1086,7 +1084,7 @@ static void update_capability(struct msm_vidc_codec_capability *in, capability->cap[in->capability_type].default_value = in->default_value; } else { - dprintk(VIDC_ERR, "%s: invalid capability_type %d\n", + d_vpr_e("%s: invalid capability_type %d\n", __func__, in->capability_type); } } @@ -1098,13 +1096,13 @@ static int msm_vidc_capabilities(struct msm_vidc_core *core) int i, j, num_platform_caps; if (!core || !core->capabilities) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, core); return -EINVAL; } platform_caps = core->resources.codec_caps; num_platform_caps = core->resources.codec_caps_count; - dprintk(VIDC_HIGH, "%s: num caps %d\n", __func__, num_platform_caps); + d_vpr_h("%s: num caps %d\n", __func__, num_platform_caps); /* loop over each platform capability */ for (i = 0; i < num_platform_caps; i++) { /* select matching core codec and update it */ @@ -1129,20 +1127,19 @@ static void handle_sys_init_done(enum hal_command_response cmd, void *data) struct msm_vidc_core *core; if (!IS_HAL_SYS_CMD(cmd)) { - dprintk(VIDC_ERR, "%s - invalid cmd\n", __func__); + d_vpr_e("%s: invalid cmd\n", __func__); return; } if (!response) { - dprintk(VIDC_ERR, - "Failed to get valid response for sys init\n"); + d_vpr_e("Failed to get valid response for sys init\n"); return; } core = get_vidc_core(response->device_id); if (!core) { - dprintk(VIDC_ERR, "Wrong device_id received\n"); + d_vpr_e("Wrong device_id received\n"); return; } - dprintk(VIDC_HIGH, "%s: core %pK\n", __func__, core); + d_vpr_l("handled: SYS_INIT_DONE\n"); complete(&(core->completions[SYS_MSG_INDEX(cmd)])); } @@ -1163,12 +1160,12 @@ void put_inst(struct msm_vidc_inst *inst) } struct msm_vidc_inst *get_inst(struct msm_vidc_core *core, - void *session_id) + void *inst_id) { struct msm_vidc_inst *inst = NULL; bool matches = false; - if (!core || !session_id) + if (!core || !inst_id) return NULL; mutex_lock(&core->lock); @@ -1179,7 +1176,7 @@ struct msm_vidc_inst *get_inst(struct msm_vidc_core *core, * sessions */ list_for_each_entry(inst, &core->instances, list) { - if (inst == session_id) { + if (inst == inst_id) { /* * Even if the instance is valid, we really shouldn't * be receiving or handling callbacks when we've deleted @@ -1213,14 +1210,13 @@ static void handle_session_release_buf_done(enum hal_command_response cmd, u32 address; if (!response) { - dprintk(VIDC_ERR, "Invalid release_buf_done response\n"); + d_vpr_e("Invalid release_buf_done response\n"); return; } - inst = get_inst(get_vidc_core(response->device_id), - response->session_id); + response->inst_id); if (!inst) { - dprintk(VIDC_ERR, "Got a response for an inactive session\n"); + d_vpr_e("Got a response for an inactive session\n"); return; } @@ -1231,7 +1227,7 @@ static void handle_session_release_buf_done(enum hal_command_response cmd, list_for_each_safe(ptr, next, &inst->scratchbufs.list) { buf = list_entry(ptr, struct internal_buf, list); if (address == buf->smem.device_addr) { - dprintk(VIDC_HIGH, "releasing scratch: %x\n", + s_vpr_h(inst->sid, "releasing scratch: %x\n", buf->smem.device_addr); buf_found = true; } @@ -1242,7 +1238,7 @@ static void handle_session_release_buf_done(enum hal_command_response cmd, list_for_each_safe(ptr, next, &inst->persistbufs.list) { buf = list_entry(ptr, struct internal_buf, list); if (address == buf->smem.device_addr) { - dprintk(VIDC_HIGH, "releasing persist: %x\n", + s_vpr_h(inst->sid, "releasing persist: %x\n", buf->smem.device_addr); buf_found = true; } @@ -1250,13 +1246,14 @@ static void handle_session_release_buf_done(enum hal_command_response cmd, mutex_unlock(&inst->persistbufs.lock); if (!buf_found) - dprintk(VIDC_ERR, "invalid buffer received from firmware"); + s_vpr_e(inst->sid, "invalid buffer received from firmware"); if (IS_HAL_SESSION_CMD(cmd)) complete(&inst->completions[SESSION_MSG_INDEX(cmd)]); else - dprintk(VIDC_ERR, "Invalid inst cmd response: %d\n", cmd); + s_vpr_e(inst->sid, "Invalid inst cmd response: %d\n", cmd); put_inst(inst); + s_vpr_l(inst->sid, "handled: SESSION_RELEASE_BUFFER_DONE\n"); } static void handle_sys_release_res_done( @@ -1266,15 +1263,15 @@ static void handle_sys_release_res_done( struct msm_vidc_core *core; if (!response) { - dprintk(VIDC_ERR, - "Failed to get valid response for sys init\n"); + d_vpr_e("Failed to get valid response for sys init\n"); return; } core = get_vidc_core(response->device_id); if (!core) { - dprintk(VIDC_ERR, "Wrong device_id received\n"); + d_vpr_e("Wrong device_id received\n"); return; } + d_vpr_l("handled: SYS_RELEASE_RESOURCE_DONE\n"); complete(&core->completions[ SYS_MSG_INDEX(HAL_SYS_RELEASE_RESOURCE_DONE)]); } @@ -1282,17 +1279,17 @@ static void handle_sys_release_res_done( void change_inst_state(struct msm_vidc_inst *inst, enum instance_state state) { if (!inst) { - dprintk(VIDC_ERR, "Invalid parameter %s\n", __func__); + d_vpr_e("Invalid parameter %s\n", __func__); return; } mutex_lock(&inst->lock); if (inst->state == MSM_VIDC_CORE_INVALID) { - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "Inst: %pK is in bad state can't change state to %d\n", inst, state); goto exit; } - dprintk(VIDC_HIGH, "Moved inst: %pK from state: %d to state: %d\n", + s_vpr_h(inst->sid, "Moved inst: %pK from state: %d to state: %d\n", inst, inst->state, state); inst->state = state; exit: @@ -1303,13 +1300,13 @@ static int signal_session_msg_receipt(enum hal_command_response cmd, struct msm_vidc_inst *inst) { if (!inst) { - dprintk(VIDC_ERR, "Invalid(%pK) instance id\n", inst); + d_vpr_e("Invalid(%pK) instance id\n", inst); return -EINVAL; } if (IS_HAL_SESSION_CMD(cmd)) { complete(&inst->completions[SESSION_MSG_INDEX(cmd)]); } else { - dprintk(VIDC_ERR, "Invalid inst cmd response: %d\n", cmd); + s_vpr_e(inst->sid, "Invalid inst cmd response: %d\n", cmd); return -EINVAL; } return 0; @@ -1321,8 +1318,12 @@ static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst, int rc = 0; struct hfi_device *hdev; + if (!inst) { + d_vpr_e("Invalid(%pK) instance id\n", inst); + return -EINVAL; + } if (!IS_HAL_SESSION_CMD(cmd)) { - dprintk(VIDC_ERR, "Invalid inst cmd response: %d\n", cmd); + s_vpr_e(inst->sid, "Invalid inst cmd response: %d\n", cmd); return -EINVAL; } hdev = (struct hfi_device *)(inst->core->device); @@ -1331,7 +1332,7 @@ static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst, msecs_to_jiffies( inst->core->resources.msm_vidc_hw_rsp_timeout)); if (!rc) { - dprintk(VIDC_ERR, "Wait interrupted or timed out: %d\n", + s_vpr_e(inst->sid, "Wait interrupted or timed out: %d\n", SESSION_MSG_INDEX(cmd)); msm_comm_kill_session(inst); rc = -EIO; @@ -1348,12 +1349,16 @@ static int wait_for_state(struct msm_vidc_inst *inst, { int rc = 0; + if (!inst) { + d_vpr_e("Invalid parameter %s\n", __func__); + return -EINVAL; + } if (IS_ALREADY_IN_STATE(flipped_state, desired_state)) { - dprintk(VIDC_HIGH, "inst: %pK is already in state: %d\n", + s_vpr_h(inst->sid, "inst: %pK is already in state: %d\n", inst, inst->state); goto err_same_state; } - dprintk(VIDC_HIGH, "Waiting for hal_cmd: %d\n", hal_cmd); + s_vpr_h(inst->sid, "Waiting for hal_cmd: %d\n", hal_cmd); rc = wait_for_sess_signal_receipt(inst, hal_cmd); if (!rc) change_inst_state(inst, desired_state); @@ -1374,20 +1379,19 @@ static void msm_comm_generate_max_clients_error(struct msm_vidc_inst *inst) struct msm_vidc_cb_cmd_done response = {0}; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); + d_vpr_e("%s: invalid input parameters\n", __func__); return; } - dprintk(VIDC_ERR, "%s: Too many clients\n", __func__); - response.session_id = inst; + s_vpr_e(inst->sid, "%s: Too many clients\n", __func__); + response.inst_id = inst; response.status = VIDC_ERR_MAX_CLIENTS; handle_session_error(cmd, (void *)&response); } -static void print_cap(const char *type, +static void print_cap(u32 sid, const char *type, struct hal_capability_supported *cap) { - dprintk(VIDC_HIGH, - "%-24s: %-10d %-10d %-10d %-10d\n", + s_vpr_h(sid, "%-24s: %-10d %-10d %-10d %-10d\n", type, cap->min, cap->max, cap->step_size, cap->default_value); } @@ -1399,7 +1403,7 @@ static int msm_vidc_comm_update_ctrl(struct msm_vidc_inst *inst, ctrl = v4l2_ctrl_find(&inst->ctrl_handler, id); if (!ctrl) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: Conrol id %d not found\n", __func__, id); return -EINVAL; } @@ -1407,7 +1411,7 @@ static int msm_vidc_comm_update_ctrl(struct msm_vidc_inst *inst, rc = v4l2_ctrl_modify_range(ctrl, cap->min, cap->max, cap->step_size, cap->default_value); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: failed: control name %s, min %d, max %d, step %d, default_value %d\n", __func__, ctrl->name, cap->min, cap->max, cap->step_size, cap->default_value); @@ -1419,12 +1423,11 @@ static int msm_vidc_comm_update_ctrl(struct msm_vidc_inst *inst, */ rc = v4l2_ctrl_s_ctrl(ctrl, cap->default_value); if (rc) { - dprintk(VIDC_ERR, - "%s: failed s_ctrl: %s with value %d\n", + s_vpr_e(inst->sid, "%s: failed s_ctrl: %s with value %d\n", __func__, ctrl->name, cap->default_value); goto error; } - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "Updated control: %s: min %lld, max %lld, step %lld, default value = %lld\n", ctrl->name, ctrl->minimum, ctrl->maximum, ctrl->step, ctrl->default_value); @@ -1439,8 +1442,9 @@ static void msm_vidc_comm_update_ctrl_limits(struct msm_vidc_inst *inst) if (inst->session_type == MSM_VIDC_ENCODER) { f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; - if (get_hal_codec(f->fmt.pix_mp.pixelformat) == - HAL_VIDEO_CODEC_TME) + if (get_hal_codec(f->fmt.pix_mp.pixelformat, + inst->sid) == + HAL_VIDEO_CODEC_TME) return; msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE, &inst->capability.cap[CAP_BITRATE]); @@ -1462,29 +1466,25 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data) u32 i, codec; if (!response) { - dprintk(VIDC_ERR, - "Failed to get valid response for session init\n"); + d_vpr_e("Failed to get valid response for session init\n"); return; } inst = get_inst(get_vidc_core(response->device_id), - response->session_id); - + response->inst_id); if (!inst) { - dprintk(VIDC_ERR, "Got a response for an inactive session\n"); + d_vpr_e("Got a response for an inactive session\n"); return; } if (response->status) { - dprintk(VIDC_ERR, - "Session init response from FW : %#x\n", + s_vpr_e(inst->sid, "Session init response from FW: %#x\n", response->status); goto error; } if (inst->session_type == MSM_VIDC_CVP) { - dprintk(VIDC_HIGH, "%s: cvp session %#x\n", - __func__, hash32_ptr(inst->session)); + s_vpr_h(inst->sid, "%s: cvp session\n", __func__); signal_session_msg_receipt(cmd, inst); put_inst(inst); return; @@ -1495,73 +1495,81 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data) for (i = 0; i < core->resources.codecs_count; i++) { if (core->capabilities[i].codec == - get_hal_codec(codec) && + get_hal_codec(codec, inst->sid) && core->capabilities[i].domain == - get_hal_domain(inst->session_type)) { + get_hal_domain(inst->session_type, inst->sid)) { capability = &core->capabilities[i]; break; } } if (!capability) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: capabilities not found for domain %#x codec %#x\n", - __func__, get_hal_domain(inst->session_type), - get_hal_codec(codec)); + __func__, get_hal_domain(inst->session_type, inst->sid), + get_hal_codec(codec, inst->sid)); goto error; } - dprintk(VIDC_HIGH, - "%s: capabilities for domain %#x codec %#x\n", + s_vpr_h(inst->sid, "%s: capabilities for domain %#x codec %#x\n", __func__, capability->domain, capability->codec); memcpy(&inst->capability, capability, sizeof(struct msm_vidc_capability)); - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "Capability type : min max step_size default_value\n"); - print_cap("width", &inst->capability.cap[CAP_FRAME_WIDTH]); - print_cap("height", &inst->capability.cap[CAP_FRAME_HEIGHT]); - print_cap("mbs_per_frame", &inst->capability.cap[CAP_MBS_PER_FRAME]); - print_cap("mbs_per_sec", &inst->capability.cap[CAP_MBS_PER_SECOND]); - print_cap("frame_rate", &inst->capability.cap[CAP_FRAMERATE]); - print_cap("bitrate", &inst->capability.cap[CAP_BITRATE]); - print_cap("scale_x", &inst->capability.cap[CAP_SCALE_X]); - print_cap("scale_y", &inst->capability.cap[CAP_SCALE_Y]); - print_cap("hier_p", &inst->capability.cap[CAP_HIER_P_NUM_ENH_LAYERS]); - print_cap("ltr_count", &inst->capability.cap[CAP_LTR_COUNT]); - print_cap("bframe", &inst->capability.cap[CAP_BFRAME]); - print_cap("mbs_per_sec_low_power", + print_cap(inst->sid, "width", &inst->capability.cap[CAP_FRAME_WIDTH]); + print_cap(inst->sid, "height", &inst->capability.cap[CAP_FRAME_HEIGHT]); + print_cap(inst->sid, "mbs_per_frame", + &inst->capability.cap[CAP_MBS_PER_FRAME]); + print_cap(inst->sid, "mbs_per_sec", + &inst->capability.cap[CAP_MBS_PER_SECOND]); + print_cap(inst->sid, "frame_rate", + &inst->capability.cap[CAP_FRAMERATE]); + print_cap(inst->sid, "bitrate", &inst->capability.cap[CAP_BITRATE]); + print_cap(inst->sid, "scale_x", &inst->capability.cap[CAP_SCALE_X]); + print_cap(inst->sid, "scale_y", &inst->capability.cap[CAP_SCALE_Y]); + print_cap(inst->sid, "hier_p", + &inst->capability.cap[CAP_HIER_P_NUM_ENH_LAYERS]); + print_cap(inst->sid, "ltr_count", &inst->capability.cap[CAP_LTR_COUNT]); + print_cap(inst->sid, "bframe", &inst->capability.cap[CAP_BFRAME]); + print_cap(inst->sid, "mbs_per_sec_low_power", &inst->capability.cap[CAP_MBS_PER_SECOND_POWER_SAVE]); - print_cap("i_qp", &inst->capability.cap[CAP_I_FRAME_QP]); - print_cap("p_qp", &inst->capability.cap[CAP_P_FRAME_QP]); - print_cap("b_qp", &inst->capability.cap[CAP_B_FRAME_QP]); - print_cap("slice_bytes", &inst->capability.cap[CAP_SLICE_BYTE]); - print_cap("slice_mbs", &inst->capability.cap[CAP_SLICE_MB]); - print_cap("max_videocores", &inst->capability.cap[CAP_MAX_VIDEOCORES]); + print_cap(inst->sid, "i_qp", &inst->capability.cap[CAP_I_FRAME_QP]); + print_cap(inst->sid, "p_qp", &inst->capability.cap[CAP_P_FRAME_QP]); + print_cap(inst->sid, "b_qp", &inst->capability.cap[CAP_B_FRAME_QP]); + print_cap(inst->sid, "slice_bytes", + &inst->capability.cap[CAP_SLICE_BYTE]); + print_cap(inst->sid, "slice_mbs", &inst->capability.cap[CAP_SLICE_MB]); + print_cap(inst->sid, "max_videocores", + &inst->capability.cap[CAP_MAX_VIDEOCORES]); /* Secure usecase specific */ - print_cap("secure_width", + print_cap(inst->sid, "secure_width", &inst->capability.cap[CAP_SECURE_FRAME_WIDTH]); - print_cap("secure_height", + print_cap(inst->sid, "secure_height", &inst->capability.cap[CAP_SECURE_FRAME_HEIGHT]); - print_cap("secure_mbs_per_frame", + print_cap(inst->sid, "secure_mbs_per_frame", &inst->capability.cap[CAP_SECURE_MBS_PER_FRAME]); - print_cap("secure_bitrate", &inst->capability.cap[CAP_SECURE_BITRATE]); + print_cap(inst->sid, "secure_bitrate", + &inst->capability.cap[CAP_SECURE_BITRATE]); /* Batch Mode Decode */ - print_cap("batch_mbs_per_frame", + print_cap(inst->sid, "batch_mbs_per_frame", &inst->capability.cap[CAP_BATCH_MAX_MB_PER_FRAME]); - print_cap("batch_frame_rate", &inst->capability.cap[CAP_BATCH_MAX_FPS]); + print_cap(inst->sid, "batch_frame_rate", + &inst->capability.cap[CAP_BATCH_MAX_FPS]); /* Lossless encoding usecase specific */ - print_cap("lossless_width", + print_cap(inst->sid, "lossless_width", &inst->capability.cap[CAP_LOSSLESS_FRAME_WIDTH]); - print_cap("lossless_height", + print_cap(inst->sid, "lossless_height", &inst->capability.cap[CAP_LOSSLESS_FRAME_HEIGHT]); - print_cap("lossless_mbs_per_frame", + print_cap(inst->sid, "lossless_mbs_per_frame", &inst->capability.cap[CAP_LOSSLESS_MBS_PER_FRAME]); /* All intra encoding usecase specific */ - print_cap("all_intra_frame_rate", + print_cap(inst->sid, "all_intra_frame_rate", &inst->capability.cap[CAP_ALLINTRA_MAX_FPS]); msm_vidc_comm_update_ctrl_limits(inst); + s_vpr_l(inst->sid, "handled: SESSION_INIT_DONE\n"); signal_session_msg_receipt(cmd, inst); put_inst(inst); return; @@ -1605,14 +1613,14 @@ static void handle_event_change(enum hal_command_response cmd, void *data) u32 codec; if (!event_notify) { - dprintk(VIDC_ERR, "Got an empty event from hfi\n"); + d_vpr_e("Got an empty event from hfi\n"); return; } inst = get_inst(get_vidc_core(event_notify->device_id), - event_notify->session_id); + event_notify->inst_id); if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "Got a response for an inactive session\n"); + d_vpr_e("Got a response for an inactive session\n"); goto err_bad_event; } hdev = inst->core->device; @@ -1628,11 +1636,10 @@ static void handle_event_change(enum hal_command_response cmd, void *data) */ bool event_fields_changed = false; - dprintk(VIDC_HIGH, "V4L2_EVENT_SEQ_CHANGED_SUFFICIENT\n"); - dprintk(VIDC_HIGH, - "event_notify->height = %d event_notify->width = %d\n", - event_notify->height, - event_notify->width); + s_vpr_h(inst->sid, "seq: V4L2_EVENT_SEQ_CHANGED_SUFFICIENT\n"); + s_vpr_h(inst->sid, + "seq: event_notify->height = %d event_notify->width = %d\n", + event_notify->height, event_notify->width); if (codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_VP9) event_fields_changed |= (inst->bit_depth != event_notify->bit_depth); @@ -1653,12 +1660,12 @@ static void handle_event_change(enum hal_command_response cmd, void *data) if (event_fields_changed) { event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT; } else { - dprintk(VIDC_HIGH, - "No parameter change continue session\n"); + s_vpr_h(inst->sid, + "seq: No parameter change continue session\n"); rc = call_hfi_op(hdev, session_continue, (void *)inst->session); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "failed to send session_continue\n"); } goto err_bad_event; @@ -1673,9 +1680,9 @@ static void handle_event_change(enum hal_command_response cmd, void *data) struct msm_vidc_buffer *mbuf; u32 planes[VIDEO_MAX_PLANES] = {0}; - dprintk(VIDC_LOW, - "%s: inst: %pK data_buffer: %x extradata_buffer: %x\n", - __func__, inst, event_notify->packet_buffer, + s_vpr_l(inst->sid, + "rbr: data_buffer: %x extradata_buffer: %x\n", + event_notify->packet_buffer, event_notify->extra_data_buffer); planes[0] = event_notify->packet_buffer; @@ -1683,7 +1690,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data) mbuf = msm_comm_get_buffer_using_device_planes(inst, OUTPUT_MPLANE, planes); if (!mbuf || !kref_get_mbuf(inst, mbuf)) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: data_addr %x, extradata_addr %x not found\n", __func__, planes[0], planes[1]); } else { @@ -1744,26 +1751,23 @@ static void handle_event_change(enum hal_command_response cmd, void *data) ptr[7] = event_notify->crop_data.height; ptr[8] = event_notify->crop_data.width; ptr[9] = msm_comm_get_v4l2_profile(codec, - event_notify->profile); + event_notify->profile, inst->sid); ptr[10] = msm_comm_get_v4l2_level(codec, - event_notify->level); + event_notify->level, inst->sid); - dprintk(VIDC_HIGH, - "Event payload: height = %u width = %u profile = %u level = %u\n", - event_notify->height, event_notify->width, - ptr[9], ptr[10]); + s_vpr_h(inst->sid, + "seq: height = %u width = %u profile = %u level = %u\n", + event_notify->height, event_notify->width, ptr[9], ptr[10]); - dprintk(VIDC_HIGH, - "Event payload: bit_depth = %u pic_struct = %u colour_space = %u\n", + s_vpr_h(inst->sid, + "seq: bit_depth = %u pic_struct = %u colour_space = %u\n", event_notify->bit_depth, event_notify->pic_struct, - event_notify->colour_space); + event_notify->colour_space); - dprintk(VIDC_HIGH, - "Event payload: CROP top = %u left = %u Height = %u Width = %u\n", - event_notify->crop_data.top, - event_notify->crop_data.left, - event_notify->crop_data.height, - event_notify->crop_data.width); + s_vpr_h(inst->sid, + "seq: CROP top = %u left = %u Height = %u Width = %u\n", + event_notify->crop_data.top, event_notify->crop_data.left, + event_notify->crop_data.height, event_notify->crop_data.width); mutex_lock(&inst->lock); inst->in_reconfig = true; @@ -1778,22 +1782,21 @@ static void handle_event_change(enum hal_command_response cmd, void *data) mutex_unlock(&inst->lock); if (event == V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT) { - dprintk(VIDC_HIGH, "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT\n"); + s_vpr_h(inst->sid, + "seq: V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT\n"); /* decide batching as configuration changed */ if (inst->batch.enable) inst->batch.enable = is_batching_allowed(inst); - dprintk(VIDC_HIGH|VIDC_PERF, "%s: %x : batching %s\n", - __func__, hash32_ptr(inst->session), + s_vpr_hp(inst->sid, "seq : batching %s\n", __func__, inst->batch.enable ? "enabled" : "disabled"); msm_dcvs_try_enable(inst); extra_buff_count = msm_vidc_get_extra_buff_count(inst, HAL_BUFFER_OUTPUT); fmt->count_min = event_notify->capture_buf_count; fmt->count_min_host = fmt->count_min + extra_buff_count; - dprintk(VIDC_HIGH, - "%s: %x : hal buffer[%d] count: min %d min_host %d\n", - __func__, hash32_ptr(inst->session), + s_vpr_h(inst->sid, + "seq: hal buffer[%d] count: min %d min_host %d\n", HAL_BUFFER_OUTPUT, fmt->count_min, fmt->count_min_host); } @@ -1809,6 +1812,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data) msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_HW_OVERLOAD); } + s_vpr_l(inst->sid, "handled: SESSION_EVENT_CHANGE\n"); err_bad_event: put_inst(inst); @@ -1821,28 +1825,27 @@ static void handle_session_prop_info(enum hal_command_response cmd, void *data) struct msm_vidc_inst *inst; if (!response) { - dprintk(VIDC_ERR, - "Failed to get valid response for prop info\n"); + d_vpr_e("Failed to get valid response for prop info\n"); return; } inst = get_inst(get_vidc_core(response->device_id), - response->session_id); + response->inst_id); if (!inst) { - dprintk(VIDC_ERR, "Got a response for an inactive session\n"); + d_vpr_e("Got a response for an inactive session\n"); return; } getprop = kzalloc(sizeof(*getprop), GFP_KERNEL); if (!getprop) { - dprintk(VIDC_ERR, "%s: getprop kzalloc failed\n", __func__); + s_vpr_e(inst->sid, "%s: getprop kzalloc failed\n", __func__); goto err_prop_info; } getprop->data = kmemdup((void *) (&response->data.property), sizeof(union hal_get_property), GFP_KERNEL); if (!getprop->data) { - dprintk(VIDC_ERR, "%s: kmemdup failed\n", __func__); + s_vpr_e(inst->sid, "%s: kmemdup failed\n", __func__); kfree(getprop); goto err_prop_info; } @@ -1850,8 +1853,9 @@ static void handle_session_prop_info(enum hal_command_response cmd, void *data) mutex_lock(&inst->pending_getpropq.lock); list_add_tail(&getprop->list, &inst->pending_getpropq.list); mutex_unlock(&inst->pending_getpropq.lock); - + s_vpr_l(inst->sid, "handled: SESSION_PROPERTY_INFO\n"); signal_session_msg_receipt(cmd, inst); + err_prop_info: put_inst(inst); } @@ -1862,26 +1866,25 @@ static void handle_load_resource_done(enum hal_command_response cmd, void *data) struct msm_vidc_inst *inst; if (!response) { - dprintk(VIDC_ERR, - "Failed to get valid response for load resource\n"); + d_vpr_e("Failed to get valid response for load resource\n"); return; } inst = get_inst(get_vidc_core(response->device_id), - response->session_id); + response->inst_id); if (!inst) { - dprintk(VIDC_ERR, "Got a response for an inactive session\n"); + d_vpr_e("Got a response for an inactive session\n"); return; } if (response->status) { - dprintk(VIDC_ERR, - "Load resource response from FW : %#x\n", + s_vpr_e(inst->sid, "Load resource response from FW : %#x\n", response->status); msm_comm_generate_session_error(inst); } put_inst(inst); + s_vpr_l(inst->sid, "handled: SESSION_LOAD_RESOURCE_DONE\n"); } static void handle_start_done(enum hal_command_response cmd, void *data) @@ -1890,16 +1893,17 @@ static void handle_start_done(enum hal_command_response cmd, void *data) struct msm_vidc_inst *inst; if (!response) { - dprintk(VIDC_ERR, "Failed to get valid response for start\n"); + d_vpr_e("Failed to get valid response for start\n"); return; } inst = get_inst(get_vidc_core(response->device_id), - response->session_id); + response->inst_id); if (!inst) { - dprintk(VIDC_ERR, "Got a response for an inactive session\n"); + d_vpr_e("Got a response for an inactive session\n"); return; } + s_vpr_l(inst->sid, "handled: SESSION_START_DONE\n"); signal_session_msg_receipt(cmd, inst); put_inst(inst); @@ -1911,17 +1915,18 @@ static void handle_stop_done(enum hal_command_response cmd, void *data) struct msm_vidc_inst *inst; if (!response) { - dprintk(VIDC_ERR, "Failed to get valid response for stop\n"); + d_vpr_e("Failed to get valid response for stop\n"); return; } inst = get_inst(get_vidc_core(response->device_id), - response->session_id); + response->inst_id); if (!inst) { - dprintk(VIDC_ERR, "Got a response for an inactive session\n"); + d_vpr_e("Got a response for an inactive session\n"); return; } + s_vpr_l(inst->sid, "handled: SESSION_STOP_DONE\n"); signal_session_msg_receipt(cmd, inst); put_inst(inst); } @@ -1932,18 +1937,18 @@ static void handle_release_res_done(enum hal_command_response cmd, void *data) struct msm_vidc_inst *inst; if (!response) { - dprintk(VIDC_ERR, - "Failed to get valid response for release resource\n"); + d_vpr_e("Failed to get valid response for release resource\n"); return; } inst = get_inst(get_vidc_core(response->device_id), - response->session_id); + response->inst_id); if (!inst) { - dprintk(VIDC_ERR, "Got a response for an inactive session\n"); + d_vpr_e("Got a response for an inactive session\n"); return; } + s_vpr_l(inst->sid, "handled: SESSION_RELEASE_RESOURCE_DONE\n"); signal_session_msg_receipt(cmd, inst); put_inst(inst); } @@ -1958,15 +1963,14 @@ void msm_comm_validate_output_buffers(struct msm_vidc_inst *inst) mutex_lock(&inst->outputbufs.lock); if (list_empty(&inst->outputbufs.list)) { - dprintk(VIDC_HIGH, "%s: no OUTPUT buffers allocated\n", + s_vpr_h(inst->sid, "%s: no OUTPUT buffers allocated\n", __func__); mutex_unlock(&inst->outputbufs.lock); return; } list_for_each_entry(binfo, &inst->outputbufs.list, list) { if (binfo->buffer_ownership != DRIVER) { - dprintk(VIDC_HIGH, - "This buffer is with FW %x\n", + s_vpr_h(inst->sid, "This buffer is with FW %x\n", binfo->smem.device_addr); continue; } @@ -1976,8 +1980,7 @@ void msm_comm_validate_output_buffers(struct msm_vidc_inst *inst) /* Only minimum number of DPBs are allocated */ if (buffers_owned_by_driver != fmt->count_min) { - dprintk(VIDC_ERR, - "OUTPUT Buffer count mismatch %d of %d\n", + s_vpr_e(inst->sid, "OUTPUT Buffer count mismatch %d of %d\n", buffers_owned_by_driver, fmt->count_min); msm_vidc_handle_hw_error(inst->core); @@ -1992,7 +1995,7 @@ int msm_comm_queue_dpb_only_buffers(struct msm_vidc_inst *inst) int rc = 0; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } @@ -2034,14 +2037,14 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) int rc; if (!response) { - dprintk(VIDC_ERR, "Failed to get valid response for flush\n"); + d_vpr_e("Failed to get valid response for flush\n"); return; } inst = get_inst(get_vidc_core(response->device_id), - response->session_id); + response->inst_id); if (!inst) { - dprintk(VIDC_ERR, "Got a response for an inactive session\n"); + d_vpr_e("Got a response for an inactive session\n"); return; } @@ -2056,9 +2059,8 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) if (!inst->in_reconfig) { rc = msm_comm_queue_dpb_only_buffers(inst); if (rc) { - dprintk(VIDC_ERR, - "Failed to queue output buffers: %d\n", - rc); + s_vpr_e(inst->sid, + "Failed to queue output buffers\n"); } } } @@ -2082,7 +2084,7 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) ptr[0] |= V4L2_CMD_FLUSH_OUTPUT; break; default: - dprintk(VIDC_ERR, "Invalid flush type received!"); + s_vpr_e(inst->sid, "Invalid flush type received!"); goto exit; } @@ -2092,13 +2094,14 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) inst->clk_data.buffer_counter = 0; } - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "Notify flush complete, flush_type: %x\n", flush_type); v4l2_event_queue_fh(&inst->event_handler, &flush_event); exit: mutex_unlock(&inst->flush_lock); put_inst(inst); + s_vpr_l(inst->sid, "handled: SESSION_FLUSH_DONE\n"); } static void handle_session_error(enum hal_command_response cmd, void *data) @@ -2109,24 +2112,22 @@ static void handle_session_error(enum hal_command_response cmd, void *data) int event = V4L2_EVENT_MSM_VIDC_SYS_ERROR; if (!response) { - dprintk(VIDC_ERR, - "Failed to get valid response for session error\n"); + d_vpr_e("Failed to get valid response for session error\n"); return; } inst = get_inst(get_vidc_core(response->device_id), - response->session_id); + response->inst_id); if (!inst) { - dprintk(VIDC_ERR, "Got a response for an inactive session\n"); + d_vpr_e("Got a response for an inactive session\n"); return; } hdev = inst->core->device; - dprintk(VIDC_ERR, "Session error received for inst %pK session %x\n", - inst, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, "Session error received for inst %pK\n", inst); if (response->status == VIDC_ERR_MAX_CLIENTS) { - dprintk(VIDC_ERR, "Too many clients, rejecting %pK", inst); + s_vpr_e(inst->sid, "Too many clients, rejecting %pK", inst); event = V4L2_EVENT_MSM_VIDC_MAX_CLIENTS; /* @@ -2138,10 +2139,10 @@ static void handle_session_error(enum hal_command_response cmd, void *data) msm_comm_session_clean(inst); } else if (response->status == VIDC_ERR_NOT_SUPPORTED) { - dprintk(VIDC_ERR, "Unsupported bitstream in %pK", inst); + s_vpr_e(inst->sid, "Unsupported bitstream in %pK", inst); event = V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED; } else { - dprintk(VIDC_ERR, "Unknown session error (%d) for %pK\n", + s_vpr_e(inst->sid, "Unknown session error (%d) for %pK\n", response->status, inst); event = V4L2_EVENT_MSM_VIDC_SYS_ERROR; } @@ -2150,6 +2151,7 @@ static void handle_session_error(enum hal_command_response cmd, void *data) change_inst_state(inst, MSM_VIDC_CORE_INVALID); msm_vidc_queue_v4l2_event(inst, event); put_inst(inst); + s_vpr_l(inst->sid, "handled: SESSION_ERROR\n"); } static void msm_comm_clean_notify_client(struct msm_vidc_core *core) @@ -2157,19 +2159,19 @@ static void msm_comm_clean_notify_client(struct msm_vidc_core *core) struct msm_vidc_inst *inst = NULL; if (!core) { - dprintk(VIDC_ERR, "%s: Invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return; } - dprintk(VIDC_ERR, "%s: Core %pK\n", __func__, core); + d_vpr_e("%s: Core %pK\n", __func__, core); mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { mutex_lock(&inst->lock); inst->state = MSM_VIDC_CORE_INVALID; mutex_unlock(&inst->lock); - dprintk(VIDC_ERR, - "%s Send sys error for inst %pK\n", __func__, inst); + s_vpr_e(inst->sid, + "%s: Send sys error for inst %pK\n", __func__, inst); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); } @@ -2186,33 +2188,30 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) subsystem_crashed("venus"); if (!response) { - dprintk(VIDC_ERR, - "Failed to get valid response for sys error\n"); + d_vpr_e("Failed to get valid response for sys error\n"); return; } core = get_vidc_core(response->device_id); if (!core) { - dprintk(VIDC_ERR, - "Got SYS_ERR but unable to identify core\n"); + d_vpr_e("Got SYS_ERR but unable to identify core\n"); return; } hdev = core->device; mutex_lock(&core->lock); if (core->state == VIDC_CORE_UNINIT) { - dprintk(VIDC_ERR, - "%s: Core %pK already moved to state %d\n", + d_vpr_e("%s: Core %pK already moved to state %d\n", __func__, core, core->state); mutex_unlock(&core->lock); return; } - dprintk(VIDC_ERR, "SYS_ERROR received for core %pK\n", core); + d_vpr_e("SYS_ERROR received for core %pK\n", core); msm_vidc_noc_error_info(core); call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); list_for_each_entry(inst, &core->instances, list) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: Send sys error for inst %pK\n", __func__, inst); change_inst_state(inst, MSM_VIDC_CORE_INVALID); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); @@ -2223,21 +2222,21 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) /* handle the hw error before core released to get full debug info */ msm_vidc_handle_hw_error(core); if (response->status == VIDC_ERR_NOC_ERROR) { - dprintk(VIDC_ERR, "Got NOC error"); + d_vpr_e("Got NOC error"); MSM_VIDC_ERROR(true); } - dprintk(VIDC_ERR, "Calling core_release\n"); + d_vpr_e("Calling core_release\n"); rc = call_hfi_op(hdev, core_release, hdev->hfi_device_data); if (rc) { - dprintk(VIDC_ERR, "core_release failed\n"); + d_vpr_e("core_release failed\n"); mutex_unlock(&core->lock); return; } core->state = VIDC_CORE_UNINIT; mutex_unlock(&core->lock); - dprintk(VIDC_ERR, "SYS_ERROR handled.\n"); + d_vpr_l("handled: SYS_ERROR\n"); } void msm_comm_session_clean(struct msm_vidc_inst *inst) @@ -2246,23 +2245,22 @@ void msm_comm_session_clean(struct msm_vidc_inst *inst) struct hfi_device *hdev = NULL; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return; } if (!inst->session) { - dprintk(VIDC_HIGH, "%s: inst %pK session already cleaned\n", + s_vpr_h(inst->sid, "%s: inst %pK session already cleaned\n", __func__, inst); return; } hdev = inst->core->device; mutex_lock(&inst->lock); - dprintk(VIDC_HIGH, "%s: inst %pK\n", __func__, inst); + s_vpr_h(inst->sid, "%s: inst %pK\n", __func__, inst); rc = call_hfi_op(hdev, session_clean, (void *)inst->session); if (rc) { - dprintk(VIDC_ERR, - "Session clean failed :%pK\n", inst); + s_vpr_e(inst->sid, "Session clean failed :%pK\n", inst); } inst->session = NULL; mutex_unlock(&inst->lock); @@ -2274,18 +2272,18 @@ static void handle_session_close(enum hal_command_response cmd, void *data) struct msm_vidc_inst *inst; if (!response) { - dprintk(VIDC_ERR, - "Failed to get valid response for session close\n"); + d_vpr_e("Failed to get valid response for session close\n"); return; } inst = get_inst(get_vidc_core(response->device_id), - response->session_id); + response->inst_id); if (!inst) { - dprintk(VIDC_ERR, "Got a response for an inactive session\n"); + d_vpr_e("Got a response for an inactive session\n"); return; } + s_vpr_l(inst->sid, "handled: SESSION_END_DONE\n"); signal_session_msg_receipt(cmd, inst); show_stats(inst); put_inst(inst); @@ -2304,7 +2302,7 @@ struct vb2_buffer *msm_comm_get_vb_using_vidc_buffer( } else if (mbuf->vvb.vb2_buf.type == INPUT_MPLANE) { port = INPUT_PORT; } else { - dprintk(VIDC_ERR, "%s: invalid type %d\n", + s_vpr_e(inst->sid, "%s: invalid type %d\n", __func__, mbuf->vvb.vb2_buf.type); return NULL; } @@ -2313,7 +2311,7 @@ struct vb2_buffer *msm_comm_get_vb_using_vidc_buffer( found = false; q = &inst->bufq[port].vb2_bufq; if (!q->streaming) { - dprintk(VIDC_ERR, "port %d is not streaming", port); + s_vpr_e(inst->sid, "port %d is not streaming", port); goto unlock; } list_for_each_entry(vb, &q->queued_list, queued_entry) { @@ -2342,7 +2340,7 @@ int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst, u32 i, port; if (!inst || !mbuf) { - dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", + d_vpr_e("%s: invalid params %pK %pK\n", __func__, inst, mbuf); return -EINVAL; } @@ -2376,7 +2374,7 @@ int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst, } vb2_buffer_done(vb2, VB2_BUF_STATE_DONE); } else { - dprintk(VIDC_ERR, "%s: port %d is not streaming\n", + s_vpr_e(inst->sid, "%s: port %d is not streaming\n", __func__, port); } mutex_unlock(&inst->bufq[port].lock); @@ -2416,21 +2414,20 @@ static void handle_ebd(enum hal_command_response cmd, void *data) struct v4l2_ctrl *ctrl; if (!response) { - dprintk(VIDC_ERR, "Invalid response from vidc_hal\n"); + d_vpr_e("Invalid response from vidc_hal\n"); return; } - inst = get_inst(get_vidc_core(response->device_id), - response->session_id); + response->inst_id); if (!inst) { - dprintk(VIDC_ERR, "Got a response for an inactive session\n"); + d_vpr_e("Got a response for an inactive session\n"); return; } empty_buf_done = (struct vidc_hal_ebd *)&response->input_done; /* If this is internal EOS buffer, handle it in driver */ if (is_eos_buffer(inst, empty_buf_done->packet_buffer)) { - dprintk(VIDC_HIGH, "Received EOS buffer 0x%x\n", + s_vpr_h(inst->sid, "Received EOS buffer 0x%x\n", empty_buf_done->packet_buffer); goto exit; } @@ -2441,7 +2438,7 @@ static void handle_ebd(enum hal_command_response cmd, void *data) mbuf = msm_comm_get_buffer_using_device_planes(inst, INPUT_MPLANE, planes); if (!mbuf || !kref_get_mbuf(inst, mbuf)) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: data_addr %x, extradata_addr %x not found\n", __func__, planes[0], planes[1]); goto exit; @@ -2451,10 +2448,9 @@ static void handle_ebd(enum hal_command_response cmd, void *data) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); if (ctrl->val && empty_buf_done->offset + empty_buf_done->filled_len < vb->planes[0].length) { - dprintk(VIDC_HIGH, - "%s: %x : addr (%#x): offset (%d) + filled_len (%d) < length (%d)\n", - __func__, hash32_ptr(inst->session), - empty_buf_done->packet_buffer, + s_vpr_h(inst->sid, + "%s: addr (%#x): offset (%d) + filled_len (%d) < length (%d)\n", + __func__, empty_buf_done->packet_buffer, empty_buf_done->offset, empty_buf_done->filled_len, vb->planes[0].length); @@ -2465,18 +2461,18 @@ static void handle_ebd(enum hal_command_response cmd, void *data) mbuf->flags &= ~MSM_VIDC_FLAG_QUEUED; vb->planes[0].bytesused = response->input_done.filled_len; if (vb->planes[0].bytesused > vb->planes[0].length) - dprintk(VIDC_LOW, "bytesused overflow length\n"); + s_vpr_l(inst->sid, "bytesused overflow length\n"); vb->planes[0].data_offset = response->input_done.offset; if (vb->planes[0].data_offset > vb->planes[0].length) - dprintk(VIDC_LOW, "data_offset overflow length\n"); + s_vpr_l(inst->sid, "data_offset overflow length\n"); if (empty_buf_done->status == VIDC_ERR_NOT_SUPPORTED) { - dprintk(VIDC_LOW, "Failed : Unsupported input stream\n"); + s_vpr_l(inst->sid, "Failed : Unsupported input stream\n"); mbuf->vvb.flags |= V4L2_BUF_INPUT_UNSUPPORTED; } if (empty_buf_done->status == VIDC_ERR_BITSTREAM_ERR) { - dprintk(VIDC_LOW, "Failed : Corrupted input stream\n"); + s_vpr_l(inst->sid, "Failed : Corrupted input stream\n"); mbuf->vvb.flags |= V4L2_BUF_FLAG_DATA_CORRUPT; } @@ -2502,6 +2498,7 @@ static void handle_ebd(enum hal_command_response cmd, void *data) kref_put_mbuf(mbuf); exit: put_inst(inst); + s_vpr_l(inst->sid, "handled: SESSION_ETB_DONE\n"); } static int handle_multi_stream_buffers(struct msm_vidc_inst *inst, @@ -2516,7 +2513,7 @@ static int handle_multi_stream_buffers(struct msm_vidc_inst *inst, smem = &binfo->smem; if (smem && dev_addr == smem->device_addr) { if (binfo->buffer_ownership == DRIVER) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "FW returned same buffer: %x\n", dev_addr); break; @@ -2529,7 +2526,7 @@ static int handle_multi_stream_buffers(struct msm_vidc_inst *inst, mutex_unlock(&inst->outputbufs.lock); if (!found) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to find output buffer in queued list: %x\n", dev_addr); } @@ -2559,14 +2556,14 @@ static void handle_fbd(enum hal_command_response cmd, void *data) struct v4l2_format *f; if (!response) { - dprintk(VIDC_ERR, "Invalid response from vidc_hal\n"); + d_vpr_e("Invalid response from vidc_hal\n"); return; } inst = get_inst(get_vidc_core(response->device_id), - response->session_id); + response->inst_id); if (!inst) { - dprintk(VIDC_ERR, "Got a response for an inactive session\n"); + d_vpr_e("Got a response for an inactive session\n"); return; } @@ -2579,7 +2576,7 @@ static void handle_fbd(enum hal_command_response cmd, void *data) mbuf = msm_comm_get_buffer_using_device_planes(inst, OUTPUT_MPLANE, planes); if (!mbuf || !kref_get_mbuf(inst, mbuf)) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: data_addr %x, extradata_addr %x not found\n", __func__, planes[0], planes[1]); goto exit; @@ -2587,7 +2584,7 @@ static void handle_fbd(enum hal_command_response cmd, void *data) } else { if (handle_multi_stream_buffers(inst, fill_buf_done->packet_buffer1)) - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed : Output buffer not found %pa\n", &fill_buf_done->packet_buffer1); goto exit; @@ -2597,8 +2594,8 @@ static void handle_fbd(enum hal_command_response cmd, void *data) if (fill_buf_done->buffer_type == HAL_BUFFER_OUTPUT2 && fill_buf_done->flags1 & HAL_BUFFERFLAG_READONLY) { - dprintk(VIDC_ERR, - "%s: Read only buffer not allowed for OPB\n", __func__); + s_vpr_e(inst->sid, "%s: Read only buffer not allowed for OPB\n", + __func__); goto exit; } @@ -2606,16 +2603,14 @@ static void handle_fbd(enum hal_command_response cmd, void *data) fill_buf_done->filled_len1 = 0; vb->planes[0].bytesused = fill_buf_done->filled_len1; if (vb->planes[0].bytesused > vb->planes[0].length) - dprintk(VIDC_LOW, - "fbd:Overflow bytesused = %d; length = %d\n", + s_vpr_l(inst->sid, "fbd:Overflow bytesused = %d; length = %d\n", vb->planes[0].bytesused, vb->planes[0].length); vb->planes[0].data_offset = fill_buf_done->offset1; if (vb->planes[0].data_offset > vb->planes[0].length) - dprintk(VIDC_LOW, + s_vpr_l(inst->sid, "fbd:Overflow data_offset = %d; length = %d\n", - vb->planes[0].data_offset, - vb->planes[0].length); + vb->planes[0].data_offset, vb->planes[0].length); time_usec = fill_buf_done->timestamp_hi; time_usec = (time_usec << 32) | fill_buf_done->timestamp_lo; @@ -2623,7 +2618,7 @@ static void handle_fbd(enum hal_command_response cmd, void *data) vb->timestamp = (time_usec * NSEC_PER_USEC); msm_comm_store_input_tag(&inst->fbd_data, vb->index, - fill_buf_done->input_tag, fill_buf_done->input_tag2); + fill_buf_done->input_tag, fill_buf_done->input_tag2, inst->sid); if (inst->session_type == MSM_VIDC_ENCODER) { if (inst->max_filled_len < fill_buf_done->filled_len1) @@ -2680,11 +2675,11 @@ static void handle_fbd(enum hal_command_response cmd, void *data) exit: put_inst(inst); + s_vpr_l(inst->sid, "handled: SESSION_FTB_DONE\n"); } void handle_cmd_response(enum hal_command_response cmd, void *data) { - dprintk(VIDC_LOW, "Command response = %d\n", cmd); switch (cmd) { case HAL_SYS_INIT_DONE: handle_sys_init_done(cmd, data); @@ -2743,7 +2738,7 @@ void handle_cmd_response(enum hal_command_response cmd, void *data) handle_session_unregister_buffer_done(cmd, data); break; default: - dprintk(VIDC_LOW, "response unhandled: %d\n", cmd); + d_vpr_l("response unhandled: %d\n", cmd); break; } } @@ -2786,8 +2781,7 @@ static bool is_thermal_permissible(struct msm_vidc_core *core) return true; if (msm_vidc_thermal_mitigation_disabled) { - dprintk(VIDC_HIGH, - "Thermal mitigation not enabled. debugfs %d\n", + d_vpr_h("Thermal mitigation not enabled. debugfs %d\n", msm_vidc_thermal_mitigation_disabled); return true; } @@ -2796,12 +2790,11 @@ static bool is_thermal_permissible(struct msm_vidc_core *core) freq = core->curr_freq; is_turbo = is_core_turbo(core, freq); - dprintk(VIDC_HIGH, - "Core freq %ld Thermal level %d Turbo mode %d\n", + d_vpr_h("Core freq %ld Thermal level %d Turbo mode %d\n", freq, tl, is_turbo); if (is_turbo && tl >= VIDC_THERMAL_LOW) { - dprintk(VIDC_ERR, + d_vpr_e( "Video session not allowed. Turbo mode %d Thermal level %d\n", is_turbo, tl); return false; @@ -2840,18 +2833,17 @@ static int msm_comm_session_abort(struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; abort_completion = SESSION_MSG_INDEX(HAL_SESSION_ABORT_DONE); - dprintk(VIDC_ERR, "%s: inst %pK session %x\n", __func__, - inst, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, "%s: inst %pK\n", __func__, inst); rc = call_hfi_op(hdev, session_abort, (void *)inst->session); if (rc) { - dprintk(VIDC_ERR, - "%s session_abort failed rc: %d\n", __func__, rc); + s_vpr_e(inst->sid, + "%s: session_abort failed rc: %d\n", __func__, rc); goto exit; } rc = wait_for_completion_timeout( @@ -2859,8 +2851,7 @@ static int msm_comm_session_abort(struct msm_vidc_inst *inst) msecs_to_jiffies( inst->core->resources.msm_vidc_hw_rsp_timeout)); if (!rc) { - dprintk(VIDC_ERR, "%s: inst %pK session %x abort timed out\n", - __func__, inst, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, "%s: session abort timed out\n", __func__); msm_comm_generate_sys_error(inst); rc = -EBUSY; } else { @@ -2876,7 +2867,7 @@ static void handle_thermal_event(struct msm_vidc_core *core) struct msm_vidc_inst *inst; if (!core || !core->device) { - dprintk(VIDC_ERR, "%s Invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, core); return; } mutex_lock(&core->lock); @@ -2887,18 +2878,17 @@ static void handle_thermal_event(struct msm_vidc_core *core) mutex_unlock(&core->lock); if (inst->state >= MSM_VIDC_OPEN_DONE && inst->state < MSM_VIDC_CLOSE_DONE) { - dprintk(VIDC_ERR, "%s: abort inst %pK\n", + s_vpr_e(inst->sid, "%s: abort inst %pK\n", __func__, inst); rc = msm_comm_session_abort(inst); if (rc) { - dprintk(VIDC_ERR, - "%s session_abort failed rc: %d\n", + s_vpr_e(inst->sid, + "%s: session_abort failed rc: %d\n", __func__, rc); goto err_sess_abort; } change_inst_state(inst, MSM_VIDC_CORE_INVALID); - dprintk(VIDC_ERR, - "%s Send sys error for inst %pK\n", + s_vpr_e(inst->sid, "%s: Send sys error for inst %pK\n", __func__, inst); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); @@ -2920,29 +2910,29 @@ void msm_comm_handle_thermal_event(void) list_for_each_entry(core, &vidc_driver->cores, list) { if (!is_thermal_permissible(core)) { - dprintk(VIDC_ERR, - "Thermal level critical, stop all active sessions!\n"); + d_vpr_e( + "Thermal level critical, stop active sessions\n"); handle_thermal_event(core); } } } -int msm_comm_check_core_init(struct msm_vidc_core *core) +int msm_comm_check_core_init(struct msm_vidc_core *core, u32 sid) { int rc = 0; mutex_lock(&core->lock); if (core->state >= VIDC_CORE_INIT_DONE) { - dprintk(VIDC_HIGH, "Video core: %d is already in state: %d\n", + s_vpr_h(sid, "Video core: %d is already in state: %d\n", core->id, core->state); goto exit; } - dprintk(VIDC_HIGH, "Waiting for SYS_INIT_DONE\n"); + s_vpr_h(sid, "Waiting for SYS_INIT_DONE\n"); rc = wait_for_completion_timeout( &core->completions[SYS_MSG_INDEX(HAL_SYS_INIT_DONE)], msecs_to_jiffies(core->resources.msm_vidc_hw_rsp_timeout)); if (!rc) { - dprintk(VIDC_ERR, "%s: Wait interrupted or timed out: %d\n", + s_vpr_e(sid, "%s: Wait interrupted or timed out: %d\n", __func__, SYS_MSG_INDEX(HAL_SYS_INIT_DONE)); rc = -EIO; goto exit; @@ -2950,7 +2940,7 @@ int msm_comm_check_core_init(struct msm_vidc_core *core) core->state = VIDC_CORE_INIT_DONE; rc = 0; } - dprintk(VIDC_HIGH, "SYS_INIT_DONE!!!\n"); + s_vpr_h(sid, "SYS_INIT_DONE!!!\n"); exit: mutex_unlock(&core->lock); return rc; @@ -2960,9 +2950,9 @@ static int msm_comm_init_core_done(struct msm_vidc_inst *inst) { int rc = 0; - rc = msm_comm_check_core_init(inst->core); + rc = msm_comm_check_core_init(inst->core, inst->sid); if (rc) { - dprintk(VIDC_ERR, "%s - failed to initialize core\n", __func__); + d_vpr_e("%s: failed to initialize core\n", __func__); msm_comm_generate_sys_error(inst); return rc; } @@ -2983,14 +2973,14 @@ static int msm_comm_init_core(struct msm_vidc_inst *inst) hdev = core->device; mutex_lock(&core->lock); if (core->state >= VIDC_CORE_INIT) { - dprintk(VIDC_HIGH, "Video core: %d is already in state: %d\n", + s_vpr_h(inst->sid, "Video core: %d is already in state: %d\n", core->id, core->state); goto core_already_inited; } - dprintk(VIDC_HIGH, "%s: core %pK\n", __func__, core); + s_vpr_h(inst->sid, "%s: core %pK\n", __func__, core); rc = call_hfi_op(hdev, core_init, hdev->hfi_device_data); if (rc) { - dprintk(VIDC_ERR, "Failed to init core, id = %d\n", + s_vpr_e(inst->sid, "Failed to init core, id = %d\n", core->id); goto fail_core_init; } @@ -3004,11 +2994,11 @@ static int msm_comm_init_core(struct msm_vidc_inst *inst) core->resources.max_secure_inst_count ? core->resources.max_secure_inst_count : core->resources.max_inst_count; - dprintk(VIDC_HIGH, "%s: codecs count %d, max inst count %d\n", + s_vpr_h(inst->sid, "%s: codecs count %d, max inst count %d\n", __func__, core->resources.codecs_count, core->resources.max_inst_count); if (!core->resources.codecs || !core->resources.codecs_count) { - dprintk(VIDC_ERR, "%s: invalid codecs\n", __func__); + s_vpr_e(inst->sid, "%s: invalid codecs\n", __func__); rc = -EINVAL; goto fail_core_init; } @@ -3016,14 +3006,14 @@ static int msm_comm_init_core(struct msm_vidc_inst *inst) core->capabilities = kcalloc(core->resources.codecs_count, sizeof(struct msm_vidc_capability), GFP_KERNEL); if (!core->capabilities) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: failed to allocate capabilities\n", __func__); rc = -ENOMEM; goto fail_core_init; } } else { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: capabilities memory is expected to be freed\n", __func__); } @@ -3035,13 +3025,13 @@ static int msm_comm_init_core(struct msm_vidc_inst *inst) } rc = msm_vidc_capabilities(core); if (rc) { - dprintk(VIDC_ERR, - "%s: default capabilities failed\n", __func__); + s_vpr_e(inst->sid, + "%s: default capabilities failed\n", __func__); kfree(core->capabilities); core->capabilities = NULL; goto fail_core_init; } - dprintk(VIDC_HIGH, "%s: done\n", __func__); + s_vpr_h(inst->sid, "%s: done\n", __func__); core_already_inited: change_inst_state(inst, MSM_VIDC_CORE_INIT); mutex_unlock(&core->lock); @@ -3061,7 +3051,7 @@ static int msm_vidc_deinit_core(struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } @@ -3070,7 +3060,7 @@ static int msm_vidc_deinit_core(struct msm_vidc_inst *inst) mutex_lock(&core->lock); if (core->state == VIDC_CORE_UNINIT) { - dprintk(VIDC_HIGH, "Video core: %d is already in state: %d\n", + s_vpr_h(inst->sid, "Video core: %d is already in state: %d\n", core->id, core->state); goto core_already_uninited; } @@ -3093,7 +3083,7 @@ static int msm_vidc_deinit_core(struct msm_vidc_inst *inst) msecs_to_jiffies(core->state == VIDC_CORE_INIT_DONE ? core->resources.msm_vidc_firmware_unload_delay : 0)); - dprintk(VIDC_HIGH, "firmware unload delayed by %u ms\n", + s_vpr_h(inst->sid, "firmware unload delayed by %u ms\n", core->state == VIDC_CORE_INIT_DONE ? core->resources.msm_vidc_firmware_unload_delay : 0); } @@ -3115,11 +3105,15 @@ static int msm_comm_session_init_done(int flipped_state, { int rc; - dprintk(VIDC_HIGH, "inst %pK: waiting for session init done\n", inst); + if (!inst) { + d_vpr_e("Invalid parameter %s\n", __func__); + return -EINVAL; + } + s_vpr_h(inst->sid, "waiting for session init done\n"); rc = wait_for_state(inst, flipped_state, MSM_VIDC_OPEN_DONE, HAL_SESSION_INIT_DONE); if (rc) { - dprintk(VIDC_ERR, "Session init failed for inst %pK\n", inst); + s_vpr_e(inst->sid, "Session init failed for inst %pK\n", inst); msm_comm_generate_sys_error(inst); return rc; } @@ -3136,13 +3130,13 @@ static int msm_comm_session_init(int flipped_state, struct v4l2_format *f; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } hdev = inst->core->device; if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_OPEN)) { - dprintk(VIDC_HIGH, "inst: %pK is already in state: %d\n", + s_vpr_h(inst->sid, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -3155,24 +3149,25 @@ static int msm_comm_session_init(int flipped_state, } else if (inst->session_type == MSM_VIDC_CVP) { fourcc = V4L2_PIX_FMT_CVP; } else { - dprintk(VIDC_ERR, "Invalid session\n"); + s_vpr_e(inst->sid, "Invalid session\n"); return -EINVAL; } rc = msm_comm_init_clocks_and_bus_data(inst); if (rc) { - dprintk(VIDC_ERR, "Failed to initialize clocks and bus data\n"); + s_vpr_e(inst->sid, + "Failed to initialize clocks and bus data\n"); goto exit; } - dprintk(VIDC_HIGH, "%s: inst %pK\n", __func__, inst); + s_vpr_h(inst->sid, "%s: inst %pK\n", __func__, inst); rc = call_hfi_op(hdev, session_init, hdev->hfi_device_data, - inst, get_hal_domain(inst->session_type), - get_hal_codec(fourcc), - &inst->session); + inst, get_hal_domain(inst->session_type, inst->sid), + get_hal_codec(fourcc, inst->sid), + &inst->session, inst->sid); if (rc || !inst->session) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to call session init for: %pK, %pK, %d, %d\n", inst->core->device, inst, inst->session_type, fourcc); @@ -3182,7 +3177,7 @@ static int msm_comm_session_init(int flipped_state, rc = msm_vidc_calculate_buffer_counts(inst); if (rc) { - dprintk(VIDC_ERR, "Failed to initialize buff counts\n"); + s_vpr_e(inst->sid, "Failed to initialize buff counts\n"); goto exit; } change_inst_state(inst, MSM_VIDC_OPEN); @@ -3198,8 +3193,8 @@ static void msm_vidc_print_running_insts(struct msm_vidc_core *core) struct v4l2_format *out_f; struct v4l2_format *inp_f; - dprintk(VIDC_ERR, "Running instances:\n"); - dprintk(VIDC_ERR, "%4s|%4s|%4s|%4s|%4s|%4s\n", + d_vpr_e("Running instances:\n"); + d_vpr_e("%4s|%4s|%4s|%4s|%4s|%4s\n", "type", "w", "h", "fps", "opr", "prop"); mutex_lock(&core->lock); @@ -3224,7 +3219,7 @@ static void msm_vidc_print_running_insts(struct msm_vidc_core *core) else op_rate = temp->clk_data.frame_rate >> 16; - dprintk(VIDC_ERR, "%4d|%4d|%4d|%4d|%4d|%4s\n", + s_vpr_e(temp->sid, "%4d|%4d|%4d|%4d|%4d|%4s\n", temp->session_type, max(out_f->fmt.pix_mp.width, inp_f->fmt.pix_mp.width), @@ -3247,17 +3242,17 @@ static int msm_vidc_load_resources(int flipped_state, enum load_calc_quirks quirks = LOAD_ADMISSION_CONTROL; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } if (inst->state == MSM_VIDC_CORE_INVALID) { - dprintk(VIDC_ERR, - "%s: inst %pK is in invalid state\n", __func__, inst); + s_vpr_e(inst->sid, "%s: inst %pK is in invalid state\n", + __func__, inst); return -EINVAL; } if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_LOAD_RESOURCES)) { - dprintk(VIDC_HIGH, "inst: %pK is already in state: %d\n", - inst, inst->state); + s_vpr_h(inst->sid, "inst: %pK is already in state: %d\n", + inst, inst->state); goto exit; } core = inst->core; @@ -3270,7 +3265,7 @@ static int msm_vidc_load_resources(int flipped_state, inst->capability.cap[CAP_MBS_PER_FRAME].max; if (num_mbs_per_sec > max_load_adj) { - dprintk(VIDC_ERR, "HW is overloaded, needed: %d max: %d\n", + s_vpr_e(inst->sid, "HW is overloaded, needed: %d max: %d\n", num_mbs_per_sec, max_load_adj); msm_vidc_print_running_insts(core); msm_comm_kill_session(inst); @@ -3278,11 +3273,10 @@ static int msm_vidc_load_resources(int flipped_state, } hdev = core->device; - dprintk(VIDC_HIGH, "%s: inst %pK\n", __func__, inst); + s_vpr_h(inst->sid, "%s: inst %pK\n", __func__, inst); rc = call_hfi_op(hdev, session_load_res, (void *) inst->session); if (rc) { - dprintk(VIDC_ERR, - "Failed to send load resources\n"); + s_vpr_e(inst->sid, "Failed to send load resources\n"); goto exit; } change_inst_state(inst, MSM_VIDC_LOAD_RESOURCES); @@ -3296,26 +3290,24 @@ static int msm_vidc_start(int flipped_state, struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } if (inst->state == MSM_VIDC_CORE_INVALID) { - dprintk(VIDC_ERR, - "%s: inst %pK is in invalid\n", __func__, inst); + s_vpr_e(inst->sid, "%s: inst %pK is in invalid\n", + __func__, inst); return -EINVAL; } if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_START)) { - dprintk(VIDC_HIGH, - "inst: %pK is already in state: %d\n", + s_vpr_h(inst->sid, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } hdev = inst->core->device; - dprintk(VIDC_HIGH, "%s: inst %pK\n", __func__, inst); + s_vpr_h(inst->sid, "%s: inst %pK\n", __func__, inst); rc = call_hfi_op(hdev, session_start, (void *) inst->session); if (rc) { - dprintk(VIDC_ERR, - "Failed to send start\n"); + s_vpr_e(inst->sid, "Failed to send start\n"); goto exit; } change_inst_state(inst, MSM_VIDC_START); @@ -3329,25 +3321,24 @@ static int msm_vidc_stop(int flipped_state, struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } if (inst->state == MSM_VIDC_CORE_INVALID) { - dprintk(VIDC_ERR, - "%s: inst %pK is in invalid state\n", __func__, inst); + s_vpr_e(inst->sid, "%s: inst %pK is in invalid state\n", + __func__, inst); return -EINVAL; } if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_STOP)) { - dprintk(VIDC_HIGH, - "inst: %pK is already in state: %d\n", + s_vpr_h(inst->sid, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } hdev = inst->core->device; - dprintk(VIDC_HIGH, "%s: inst %pK\n", __func__, inst); + s_vpr_h(inst->sid, "%s: inst %pK\n", __func__, inst); rc = call_hfi_op(hdev, session_stop, (void *) inst->session); if (rc) { - dprintk(VIDC_ERR, "%s: inst %pK session_stop failed\n", + s_vpr_e(inst->sid, "%s: inst %pK session_stop failed\n", __func__, inst); goto exit; } @@ -3362,26 +3353,24 @@ static int msm_vidc_release_res(int flipped_state, struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } if (inst->state == MSM_VIDC_CORE_INVALID) { - dprintk(VIDC_ERR, - "%s: inst %pK is in invalid state\n", __func__, inst); + s_vpr_e(inst->sid, "%s: inst %pK is in invalid state\n", + __func__, inst); return -EINVAL; } if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_RELEASE_RESOURCES)) { - dprintk(VIDC_HIGH, - "inst: %pK is already in state: %d\n", + s_vpr_h(inst->sid, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } hdev = inst->core->device; - dprintk(VIDC_HIGH, "%s: inst %pK\n", __func__, inst); + s_vpr_h(inst->sid, "%s: inst %pK\n", __func__, inst); rc = call_hfi_op(hdev, session_release_res, (void *) inst->session); if (rc) { - dprintk(VIDC_ERR, - "Failed to send release resources\n"); + s_vpr_e(inst->sid, "Failed to send release resources\n"); goto exit; } change_inst_state(inst, MSM_VIDC_RELEASE_RESOURCES); @@ -3396,21 +3385,19 @@ static int msm_comm_session_close(int flipped_state, struct hfi_device *hdev; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_CLOSE)) { - dprintk(VIDC_HIGH, - "inst: %pK is already in state: %d\n", - inst, inst->state); + s_vpr_h(inst->sid, "inst: %pK is already in state: %d\n", + inst, inst->state); goto exit; } hdev = inst->core->device; - dprintk(VIDC_HIGH, "%s: inst %pK\n", __func__, inst); + s_vpr_h(inst->sid, "%s: inst %pK\n", __func__, inst); rc = call_hfi_op(hdev, session_end, (void *) inst->session); if (rc) { - dprintk(VIDC_ERR, - "Failed to send close\n"); + s_vpr_e(inst->sid, "Failed to send close\n"); goto exit; } change_inst_state(inst, MSM_VIDC_CLOSE); @@ -3426,21 +3413,20 @@ int msm_comm_suspend(int core_id) core = get_vidc_core(core_id); if (!core) { - dprintk(VIDC_ERR, - "%s: Failed to find core for core_id = %d\n", + d_vpr_e("%s: Failed to find core for core_id = %d\n", __func__, core_id); return -EINVAL; } hdev = (struct hfi_device *)core->device; if (!hdev) { - dprintk(VIDC_ERR, "%s Invalid device handle\n", __func__); + d_vpr_e("%s: Invalid device handle\n", __func__); return -EINVAL; } rc = call_hfi_op(hdev, suspend, hdev->hfi_device_data); if (rc) - dprintk(VIDC_ERR, "Failed to suspend\n"); + d_vpr_e("Failed to suspend\n"); return rc; } @@ -3470,13 +3456,13 @@ int msm_comm_reset_bufreqs(struct msm_vidc_inst *inst, enum hal_buffer buf_type) struct hal_buffer_requirements *bufreqs; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } bufreqs = get_buff_req_buffer(inst, buf_type); if (!bufreqs) { - dprintk(VIDC_ERR, "%s: invalid buf type %d\n", + s_vpr_e(inst->sid, "%s: invalid buf type %d\n", __func__, buf_type); return -EINVAL; } @@ -3497,11 +3483,11 @@ struct hal_buffer_requirements *get_buff_req_buffer( if (inst->buff_req.buffer[i].buffer_type == buffer_type) return &inst->buff_req.buffer[i]; } - dprintk(VIDC_ERR, "Failed to get buff req for : %x", buffer_type); + s_vpr_e(inst->sid, "Failed to get buff req for : %x", buffer_type); return NULL; } -u32 msm_comm_convert_color_fmt(u32 v4l2_fmt) +u32 msm_comm_convert_color_fmt(u32 v4l2_fmt, u32 sid) { switch (v4l2_fmt) { case V4L2_PIX_FMT_NV12: @@ -3517,14 +3503,14 @@ u32 msm_comm_convert_color_fmt(u32 v4l2_fmt) case V4L2_PIX_FMT_NV12_TP10_UBWC: return COLOR_FMT_NV12_BPP10_UBWC; default: - dprintk(VIDC_ERR, + s_vpr_e(sid, "Invalid v4l2 color fmt FMT : %x, Set default(NV12)", v4l2_fmt); return COLOR_FMT_NV12; } } -static u32 get_hfi_buffer(int hal_buffer) +static u32 get_hfi_buffer(int hal_buffer, u32 sid) { u32 buffer; @@ -3563,8 +3549,7 @@ static u32 get_hfi_buffer(int hal_buffer) buffer = HFI_BUFFER_INTERNAL_PERSIST_1; break; default: - dprintk(VIDC_ERR, "Invalid buffer: %#x\n", - hal_buffer); + s_vpr_e(sid, "Invalid buffer: %#x\n", hal_buffer); buffer = 0; break; } @@ -3589,16 +3574,16 @@ static int set_dpb_only_buffers(struct msm_vidc_inst *inst, /* For DPB buffers, Always use min count */ num_buffers = fmt->count_min; - hfi_fmt = msm_comm_convert_color_fmt(inst->clk_data.dpb_fourcc); + hfi_fmt = msm_comm_convert_color_fmt(inst->clk_data.dpb_fourcc, + inst->sid); f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; buffer_size = VENUS_BUFFER_SIZE(hfi_fmt, f->fmt.pix_mp.width, f->fmt.pix_mp.height); - dprintk(VIDC_HIGH, - "output: num = %d, size = %d\n", + s_vpr_h(inst->sid, "output: num = %d, size = %d\n", num_buffers, buffer_size); - b.buffer_type = get_hfi_buffer(buffer_type); + b.buffer_type = get_hfi_buffer(buffer_type, inst->sid); if (!b.buffer_type) return -EINVAL; b.buffer_size = buffer_size; @@ -3608,17 +3593,16 @@ static int set_dpb_only_buffers(struct msm_vidc_inst *inst, if (f->fmt.pix_mp.num_planes == 1 || !f->fmt.pix_mp.plane_fmt[1].sizeimage) { - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "This extradata buffer not required, buffer_type: %x\n", buffer_type); } else { - dprintk(VIDC_HIGH, - "extradata: num = 1, size = %d\n", + s_vpr_h(inst->sid, "extradata: num = 1, size = %d\n", f->fmt.pix_mp.plane_fmt[1].sizeimage); inst->dpb_extra_binfo = NULL; inst->dpb_extra_binfo = kzalloc(sizeof(*binfo), GFP_KERNEL); if (!inst->dpb_extra_binfo) { - dprintk(VIDC_ERR, "Out of memory\n"); + s_vpr_e(inst->sid, "%s: Out of memory\n", __func__); rc = -ENOMEM; goto fail_kzalloc; } @@ -3626,7 +3610,7 @@ static int set_dpb_only_buffers(struct msm_vidc_inst *inst, f->fmt.pix_mp.plane_fmt[1].sizeimage, 1, smem_flags, buffer_type, 0, &inst->dpb_extra_binfo->smem); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to allocate output memory\n"); goto err_no_mem; } @@ -3639,7 +3623,7 @@ static int set_dpb_only_buffers(struct msm_vidc_inst *inst, for (i = 0; i < num_buffers; i++) { binfo = kzalloc(sizeof(*binfo), GFP_KERNEL); if (!binfo) { - dprintk(VIDC_ERR, "Out of memory\n"); + s_vpr_e(inst->sid, "Out of memory\n"); rc = -ENOMEM; goto fail_kzalloc; } @@ -3647,13 +3631,13 @@ static int set_dpb_only_buffers(struct msm_vidc_inst *inst, buffer_size, 1, smem_flags, buffer_type, 0, &binfo->smem); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to allocate output memory\n"); goto err_no_mem; } binfo->buffer_type = buffer_type; binfo->buffer_ownership = DRIVER; - dprintk(VIDC_HIGH, "Output buffer address: %#x\n", + s_vpr_h(inst->sid, "Output buffer address: %#x\n", binfo->smem.device_addr); if (inst->buffer_mode_set[OUTPUT_PORT] == @@ -3672,8 +3656,8 @@ static int set_dpb_only_buffers(struct msm_vidc_inst *inst, rc = call_hfi_op(hdev, session_set_buffers, (void *) inst->session, &buffer_info); if (rc) { - dprintk(VIDC_ERR, - "%s : session_set_buffers failed\n", + s_vpr_e(inst->sid, + "%s: session_set_buffers failed\n", __func__); goto fail_set_buffers; } @@ -3720,7 +3704,8 @@ static int set_internal_buf_on_fw(struct msm_vidc_inst *inst, int rc = 0; if (!inst || !inst->core || !inst->core->device || !handle) { - dprintk(VIDC_ERR, "%s - invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, inst, handle); return -EINVAL; } @@ -3730,16 +3715,15 @@ static int set_internal_buf_on_fw(struct msm_vidc_inst *inst, buffer_info.buffer_type = buffer_type; buffer_info.num_buffers = 1; buffer_info.align_device_addr = handle->device_addr; - dprintk(VIDC_HIGH, "%s %s buffer : %x\n", - reuse ? "Reusing" : "Allocated", - get_buffer_name(buffer_type), - buffer_info.align_device_addr); + s_vpr_h(inst->sid, "%s %s buffer : %x\n", + reuse ? "Reusing" : "Allocated", + get_buffer_name(buffer_type), + buffer_info.align_device_addr); rc = call_hfi_op(hdev, session_set_buffers, (void *) inst->session, &buffer_info); if (rc) { - dprintk(VIDC_ERR, - "vidc_hal_session_set_buffers failed\n"); + s_vpr_e(inst->sid, "vidc_hal_session_set_buffers failed\n"); return rc; } return 0; @@ -3753,7 +3737,8 @@ static bool reuse_internal_buffers(struct msm_vidc_inst *inst, bool reused = false; if (!inst || !buf_list) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, inst, buf_list); return false; } @@ -3776,7 +3761,7 @@ static bool reuse_internal_buffers(struct msm_vidc_inst *inst, rc = set_internal_buf_on_fw(inst, buffer_type, &buf->smem, true); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: session_set_buffers failed\n", __func__); reused = false; @@ -3784,7 +3769,7 @@ static bool reuse_internal_buffers(struct msm_vidc_inst *inst, } } reused = true; - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "Re-using internal buffer type : %d\n", buffer_type); } mutex_unlock(&buf_list->lock); @@ -3812,7 +3797,7 @@ static int allocate_and_set_internal_bufs(struct msm_vidc_inst *inst, for (i = 0; i < internal_bufreq->buffer_count_actual; i++) { binfo = kzalloc(sizeof(*binfo), GFP_KERNEL); if (!binfo) { - dprintk(VIDC_ERR, "Out of memory\n"); + s_vpr_e(inst->sid, "%s: Out of memory\n", __func__); rc = -ENOMEM; goto fail_kzalloc; } @@ -3820,7 +3805,7 @@ static int allocate_and_set_internal_bufs(struct msm_vidc_inst *inst, 1, smem_flags, internal_bufreq->buffer_type, 0, &binfo->smem); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to allocate scratch memory\n"); goto err_no_mem; } @@ -3854,13 +3839,13 @@ static int set_internal_buffers(struct msm_vidc_inst *inst, internal_buf = get_buff_req_buffer(inst, buffer_type); if (!internal_buf) { - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "This internal buffer not required, buffer_type: %x\n", buffer_type); return 0; } - dprintk(VIDC_HIGH, "Buffer type %s: num = %d, size = %d\n", + s_vpr_h(inst->sid, "Buffer type %s: num = %d, size = %d\n", get_buffer_name(buffer_type), internal_buf->buffer_count_actual, internal_buf->buffer_size); @@ -3881,25 +3866,23 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state) int flipped_state; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params %pK", __func__, inst); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } - dprintk(VIDC_HIGH, - "Trying to move inst: %pK (%#x) from: %#x to %#x\n", - inst, hash32_ptr(inst->session), inst->state, state); + s_vpr_h(inst->sid, "Trying to move inst: %pK from: %#x to %#x\n", + inst, inst->state, state); mutex_lock(&inst->sync_lock); if (inst->state == MSM_VIDC_CORE_INVALID) { - dprintk(VIDC_ERR, "%s: inst %pK is in invalid\n", + s_vpr_e(inst->sid, "%s: inst %pK is in invalid\n", __func__, inst); rc = -EINVAL; goto exit; } flipped_state = get_flipped_state(inst->state, state); - dprintk(VIDC_HIGH, - "inst: %pK (%#x) flipped_state = %#x\n", - inst, hash32_ptr(inst->session), flipped_state); + s_vpr_h(inst->sid, "inst: %pK flipped_state = %#x\n", + inst, flipped_state); switch (flipped_state) { case MSM_VIDC_CORE_UNINIT_DONE: case MSM_VIDC_CORE_INIT: @@ -3941,7 +3924,7 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state) HAL_SESSION_STOP_DONE); if (rc || state <= get_flipped_state(inst->state, state)) break; - dprintk(VIDC_HIGH, "Moving to Stop Done state\n"); + s_vpr_h(inst->sid, "Moving to Stop Done state\n"); case MSM_VIDC_RELEASE_RESOURCES: rc = msm_vidc_release_res(flipped_state, inst); if (rc || state <= get_flipped_state(inst->state, state)) @@ -3952,8 +3935,7 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state) HAL_SESSION_RELEASE_RESOURCE_DONE); if (rc || state <= get_flipped_state(inst->state, state)) break; - dprintk(VIDC_HIGH, - "Moving to release resources done state\n"); + s_vpr_h(inst->sid, "Moving to release resources done state\n"); case MSM_VIDC_CLOSE: rc = msm_comm_session_close(flipped_state, inst); if (rc || state <= get_flipped_state(inst->state, state)) @@ -3966,12 +3948,12 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state) msm_comm_session_clean(inst); case MSM_VIDC_CORE_UNINIT: case MSM_VIDC_CORE_INVALID: - dprintk(VIDC_HIGH, "Sending core uninit\n"); + s_vpr_h(inst->sid, "Sending core uninit\n"); rc = msm_vidc_deinit_core(inst); if (rc || state == get_flipped_state(inst->state, state)) break; default: - dprintk(VIDC_ERR, "State not recognized\n"); + s_vpr_e(inst->sid, "State not recognized\n"); rc = -EINVAL; break; } @@ -3980,9 +3962,8 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state) mutex_unlock(&inst->sync_lock); if (rc) { - dprintk(VIDC_ERR, - "Failed to move from state: %d to %d\n", - inst->state, state); + s_vpr_e(inst->sid, "Failed to move from state: %d to %d\n", + inst->state, state); msm_comm_kill_session(inst); } else { trace_msm_vidc_common_state_change((void *)inst, @@ -3999,7 +3980,7 @@ int msm_vidc_send_pending_eos_buffers(struct msm_vidc_inst *inst) int rc = 0; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + d_vpr_e("%s: Invalid arguments\n", __func__); return -EINVAL; } @@ -4015,7 +3996,7 @@ int msm_vidc_send_pending_eos_buffers(struct msm_vidc_inst *inst) data.timestamp = 0; data.extradata_addr = 0; data.extradata_size = 0; - dprintk(VIDC_HIGH, "Queueing EOS buffer 0x%x\n", + s_vpr_h(inst->sid, "Queueing EOS buffer 0x%x\n", data.device_addr); hdev = inst->core->device; @@ -4036,7 +4017,8 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd) int which_cmd = 0, flags = 0, rc = 0; if (!inst || !inst->core || !cmd) { - dprintk(VIDC_ERR, "%s invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, inst, cmd); return -EINVAL; } core = inst->core; @@ -4055,8 +4037,7 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd) case V4L2_CMD_FLUSH: rc = msm_comm_flush(inst, flags); if (rc) { - dprintk(VIDC_ERR, - "Failed to flush buffers: %d\n", rc); + s_vpr_e(inst->sid, "Failed to flush buffers: %d\n", rc); } break; case V4L2_CMD_SESSION_CONTINUE: @@ -4071,14 +4052,14 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd) u32 smem_flags = SMEM_UNCACHED; if (inst->state != MSM_VIDC_START_DONE) { - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "Inst = %pK is not ready for EOS\n", inst); break; } binfo = kzalloc(sizeof(*binfo), GFP_KERNEL); if (!binfo) { - dprintk(VIDC_ERR, "%s: Out of memory\n", __func__); + s_vpr_e(inst->sid, "%s: Out of memory\n", __func__); rc = -ENOMEM; break; } @@ -4091,7 +4072,7 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd) HAL_BUFFER_INPUT, 0, &binfo->smem); if (rc) { kfree(binfo); - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to allocate output memory\n"); rc = -ENOMEM; break; @@ -4103,7 +4084,7 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd) rc = msm_vidc_send_pending_eos_buffers(inst); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed pending_eos_buffers sending\n"); list_del(&binfo->list); kfree(binfo); @@ -4112,7 +4093,7 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd) break; } default: - dprintk(VIDC_ERR, "Unknown Command %d\n", which_cmd); + s_vpr_e(inst->sid, "Unknown Command %d\n", which_cmd); rc = -ENOTSUPP; break; } @@ -4125,7 +4106,8 @@ static int msm_comm_preprocess(struct msm_vidc_inst *inst, int rc = 0; if (!inst || !mbuf) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, inst, mbuf); return -EINVAL; } @@ -4139,7 +4121,7 @@ static int msm_comm_preprocess(struct msm_vidc_inst *inst, rc = msm_vidc_cvp_preprocess(inst, mbuf); if (rc) { - dprintk(VIDC_ERR, "%s: cvp preprocess failed\n", + s_vpr_e(inst->sid, "%s: cvp preprocess failed\n", __func__); return rc; } @@ -4157,7 +4139,7 @@ static void populate_frame_data(struct vidc_frame_data *data, u32 itag = 0, itag2 = 0; if (!inst || !mbuf || !data) { - dprintk(VIDC_ERR, "%s: invalid params %pK %pK %pK\n", + d_vpr_e("%s: invalid params %pK %pK %pK\n", __func__, inst, mbuf, data); return; } @@ -4189,7 +4171,7 @@ static void populate_frame_data(struct vidc_frame_data *data, data->flags |= HAL_BUFFERFLAG_CVPMETADATA_SKIP; msm_comm_fetch_input_tag(&inst->etb_data, vb->index, - &itag, &itag2); + &itag, &itag2, inst->sid); data->input_tag = itag; f = &inst->fmts[INPUT_PORT].v4l2_fmt; @@ -4229,7 +4211,7 @@ int msm_comm_num_queued_bufs(struct msm_vidc_inst *inst, u32 type) struct msm_vidc_buffer *mbuf; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return 0; } @@ -4252,7 +4234,7 @@ static int num_pending_qbufs(struct msm_vidc_inst *inst, u32 type) struct msm_vidc_buffer *mbuf; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return 0; } @@ -4279,7 +4261,7 @@ static int msm_comm_qbuf_to_hfi(struct msm_vidc_inst *inst, struct vidc_frame_data frame_data = {0}; if (!inst || !inst->core || !inst->core->device || !mbuf) { - dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + d_vpr_e("%s: Invalid arguments\n", __func__); return -EINVAL; } hdev = inst->core->device; @@ -4295,12 +4277,12 @@ static int msm_comm_qbuf_to_hfi(struct msm_vidc_inst *inst, e = MSM_VIDC_DEBUGFS_EVENT_FTB; rc = call_hfi_op(hdev, session_ftb, inst->session, &frame_data); } else { - dprintk(VIDC_ERR, "%s: invalid qbuf type %d:\n", __func__, + s_vpr_e(inst->sid, "%s: invalid qbuf type %d:\n", __func__, mbuf->vvb.vb2_buf.type); rc = -EINVAL; } if (rc) { - dprintk(VIDC_ERR, "%s: Failed to qbuf: %d\n", __func__, rc); + s_vpr_e(inst->sid, "%s: Failed to qbuf: %d\n", __func__, rc); goto err_bad_input; } mbuf->flags |= MSM_VIDC_FLAG_QUEUED; @@ -4320,24 +4302,23 @@ void msm_vidc_batch_handler(struct work_struct *work) struct msm_vidc_inst *inst; inst = container_of(work, struct msm_vidc_inst, batch_work.work); - inst = get_inst(get_vidc_core(MSM_VIDC_CORE_VENUS), inst); if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return; } if (inst->state == MSM_VIDC_CORE_INVALID) { - dprintk(VIDC_ERR, "%s: invalid state\n", __func__); + s_vpr_e(inst->sid, "%s: invalid state\n", __func__); goto exit; } - dprintk(VIDC_HIGH, "%s: %x: queue pending batch buffers\n", - __func__, hash32_ptr(inst->session)); + s_vpr_h(inst->sid, "%s: queue pending batch buffers\n", + __func__); rc = msm_comm_qbufs_batch(inst, NULL); if (rc) - dprintk(VIDC_ERR, "%s: batch qbufs failed\n", __func__); + s_vpr_e(inst->sid, "%s: batch qbufs failed\n", __func__); exit: put_inst(inst); @@ -4356,7 +4337,7 @@ static int msm_comm_qbuf_superframe_to_hfi(struct msm_vidc_inst *inst, bool skip_allowed = false; if (!inst || !inst->core || !inst->core->device || !mbuf) { - dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + d_vpr_e("%s: Invalid arguments\n", __func__); return -EINVAL; } hdev = inst->core->device; @@ -4368,23 +4349,24 @@ static int msm_comm_qbuf_superframe_to_hfi(struct msm_vidc_inst *inst, ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); superframe_count = ctrl->val; if (superframe_count > VIDC_SUPERFRAME_MAX) { - dprintk(VIDC_ERR, "%s: wrong superframe count %d, max %d\n", + s_vpr_e(inst->sid, "%s: wrong superframe count %d, max %d\n", __func__, superframe_count, VIDC_SUPERFRAME_MAX); return -EINVAL; } ts_delta_us = 1000000 / (inst->clk_data.frame_rate >> 16); f = &inst->fmts[INPUT_PORT].v4l2_fmt; - hfi_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat); + hfi_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat, + inst->sid); frame_size = VENUS_BUFFER_SIZE(hfi_fmt, f->fmt.pix_mp.width, f->fmt.pix_mp.height); if (frame_size * superframe_count != mbuf->vvb.vb2_buf.planes[0].length) { - dprintk(VIDC_ERR, - "%s: %#x : invalid superframe length, pxlfmt %#x wxh %dx%d framesize %d count %d length %d\n", - __func__, hash32_ptr(inst->session), - f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, - f->fmt.pix_mp.height, frame_size, superframe_count, + s_vpr_e(inst->sid, + "%s: invalid superframe length, pxlfmt %#x wxh %dx%d framesize %d count %d length %d\n", + __func__, f->fmt.pix_mp.pixelformat, + f->fmt.pix_mp.width, f->fmt.pix_mp.height, + frame_size, superframe_count, mbuf->vvb.vb2_buf.planes[0].length); return -EINVAL; } @@ -4401,7 +4383,7 @@ static int msm_comm_qbuf_superframe_to_hfi(struct msm_vidc_inst *inst, frames[0].flags &= ~HAL_BUFFERFLAG_EOS; frames[0].flags &= ~HAL_BUFFERFLAG_CVPMETADATA_SKIP; if (frames[0].flags) - dprintk(VIDC_ERR, "%s: invalid flags %#x\n", + s_vpr_e(inst->sid, "%s: invalid flags %#x\n", __func__, frames[0].flags); frames[0].flags = 0; @@ -4437,7 +4419,7 @@ static int msm_comm_qbuf_superframe_to_hfi(struct msm_vidc_inst *inst, rc = call_hfi_op(hdev, session_process_batch, inst->session, num_etbs, frames, 0, NULL); if (rc) { - dprintk(VIDC_ERR, "%s: Failed to qbuf: %d\n", __func__, rc); + s_vpr_e(inst->sid, "%s: Failed to qbuf: %d\n", __func__, rc); return rc; } /* update mbuf flags */ @@ -4454,23 +4436,24 @@ static int msm_comm_qbuf_in_rbr(struct msm_vidc_inst *inst, int rc = 0; if (!inst || !mbuf) { - dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + d_vpr_e("%s: Invalid arguments\n", __func__); return -EINVAL; } if (inst->state == MSM_VIDC_CORE_INVALID) { - dprintk(VIDC_ERR, "%s: inst is in bad state\n", __func__); + s_vpr_e(inst->sid, "%s: inst is in bad state\n", __func__); return -EINVAL; } rc = msm_comm_scale_clocks_and_bus(inst, 0); if (rc) - dprintk(VIDC_ERR, "%s: scale clock failed\n", __func__); + s_vpr_e(inst->sid, "%s: scale clock failed\n", __func__); print_vidc_buffer(VIDC_HIGH|VIDC_PERF, "qbuf in rbr", inst, mbuf); rc = msm_comm_qbuf_to_hfi(inst, mbuf); if (rc) - dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", __func__, rc); + s_vpr_e(inst->sid, + "%s: Failed qbuf to hfi: %d\n", __func__, rc); return rc; } @@ -4482,12 +4465,12 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) int do_bw_calc = 0; if (!inst || !mbuf) { - dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + d_vpr_e("%s: Invalid arguments\n", __func__); return -EINVAL; } if (inst->state == MSM_VIDC_CORE_INVALID) { - dprintk(VIDC_ERR, "%s: inst is in bad state\n", __func__); + s_vpr_e(inst->sid, "%s: inst is in bad state\n", __func__); return -EINVAL; } @@ -4504,7 +4487,7 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) do_bw_calc = mbuf->vvb.vb2_buf.type == INPUT_MPLANE; rc = msm_comm_scale_clocks_and_bus(inst, do_bw_calc); if (rc) - dprintk(VIDC_ERR, "%s: scale clock & bw failed\n", __func__); + s_vpr_e(inst->sid, "%s: scale clock & bw failed\n", __func__); print_vidc_buffer(VIDC_HIGH|VIDC_PERF, "qbuf", inst, mbuf); ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); @@ -4513,7 +4496,8 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) else rc = msm_comm_qbuf_to_hfi(inst, mbuf); if (rc) - dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", __func__, rc); + s_vpr_e(inst->sid, "%s: Failed qbuf to hfi: %d\n", + __func__, rc); return rc; } @@ -4525,12 +4509,12 @@ int msm_comm_qbufs(struct msm_vidc_inst *inst) bool found; if (!inst) { - dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + d_vpr_e("%s: Invalid arguments\n", __func__); return -EINVAL; } if (inst->state != MSM_VIDC_START_DONE) { - dprintk(VIDC_HIGH, "%s: inst not in start state: %d\n", + s_vpr_h(inst->sid, "%s: inst not in start state: %d\n", __func__, inst->state); return 0; } @@ -4547,21 +4531,21 @@ int msm_comm_qbufs(struct msm_vidc_inst *inst) } mutex_unlock(&inst->registeredbufs.lock); if (!found) { - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "%s: no more deferred qbufs\n", __func__); break; } /* do not call msm_comm_qbuf() under registerbufs lock */ if (!kref_get_mbuf(inst, mbuf)) { - dprintk(VIDC_ERR, "%s: mbuf not found\n", __func__); + s_vpr_e(inst->sid, "%s: mbuf not found\n", __func__); rc = -EINVAL; break; } rc = msm_comm_qbuf(inst, mbuf); kref_put_mbuf(mbuf); if (rc) { - dprintk(VIDC_ERR, "%s: failed qbuf\n", __func__); + s_vpr_e(inst->sid, "%s: failed qbuf\n", __func__); break; } } while (found); @@ -4579,7 +4563,7 @@ int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, do_bw_calc = mbuf ? mbuf->vvb.vb2_buf.type == INPUT_MPLANE : 0; rc = msm_comm_scale_clocks_and_bus(inst, do_bw_calc); if (rc) - dprintk(VIDC_ERR, "%s: scale clock & bw failed\n", __func__); + s_vpr_e(inst->sid, "%s: scale clock & bw failed\n", __func__); mutex_lock(&inst->registeredbufs.lock); list_for_each_entry(buf, &inst->registeredbufs.list, list) { @@ -4596,7 +4580,7 @@ int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, print_vidc_buffer(VIDC_HIGH|VIDC_PERF, "batch-qbuf", inst, buf); rc = msm_comm_qbuf_to_hfi(inst, buf); if (rc) { - dprintk(VIDC_ERR, "%s: Failed batch qbuf to hfi: %d\n", + s_vpr_e(inst->sid, "%s: Failed batch qbuf to hfi: %d\n", __func__, rc); break; } @@ -4624,12 +4608,12 @@ int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst, u32 count = 0; if (!inst || !inst->core || !mbuf) { - dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + d_vpr_e("%s: Invalid arguments\n", __func__); return -EINVAL; } if (inst->state == MSM_VIDC_CORE_INVALID) { - dprintk(VIDC_ERR, "%s: inst is in bad state\n", __func__); + s_vpr_e(inst->sid, "%s: inst is in bad state\n", __func__); return -EINVAL; } @@ -4662,7 +4646,8 @@ int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst, rc = msm_comm_qbufs_batch(inst, mbuf); if (rc) - dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", + s_vpr_e(inst->sid, + "%s: Failed qbuf to hfi: %d\n", __func__, rc); return rc; @@ -4674,7 +4659,7 @@ int schedule_batch_work(struct msm_vidc_inst *inst) struct msm_vidc_platform_resources *res; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + d_vpr_e("%s: Invalid arguments\n", __func__); return -EINVAL; } core = inst->core; @@ -4690,7 +4675,7 @@ int schedule_batch_work(struct msm_vidc_inst *inst) int cancel_batch_work(struct msm_vidc_inst *inst) { if (!inst) { - dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + d_vpr_e("%s: Invalid arguments\n", __func__); return -EINVAL; } cancel_delayed_work(&inst->batch_work); @@ -4720,8 +4705,9 @@ int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst) if (inst->buffer_size_calculators) { rc = inst->buffer_size_calculators(inst); if (rc) - dprintk(VIDC_ERR, - "Failed calculating internal buffer sizes: %d", rc); + s_vpr_e(inst->sid, + "Failed calculating internal buffer sizes: %d", + rc); } /* @@ -4731,7 +4717,7 @@ int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst) if (rc) { rc = msm_comm_try_get_buff_req(inst, &hprop); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed getting buffer requirements: %d", rc); return rc; } @@ -4770,15 +4756,15 @@ int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst) } } - dprintk(VIDC_HIGH, "Buffer requirements :\n"); - dprintk(VIDC_HIGH, "%15s %8s %8s %8s %8s %8s\n", + s_vpr_h(inst->sid, "Buffer requirements :\n"); + s_vpr_h(inst->sid, "%15s %8s %8s %8s %8s %8s\n", "buffer type", "count", "mincount_host", "mincount_fw", "size", "alignment"); for (i = 0; i < HAL_BUFFER_MAX; i++) { struct hal_buffer_requirements req = inst->buff_req.buffer[i]; if (req.buffer_type != HAL_BUFFER_NONE) { - dprintk(VIDC_HIGH, "%15s %8d %8d %8d %8d %8d\n", + s_vpr_h(inst->sid, "%15s %8d %8d %8d %8d %8d\n", get_buffer_name(req.buffer_type), req.buffer_count_actual, req.buffer_count_min_host, @@ -4797,7 +4783,7 @@ int msm_comm_try_get_buff_req(struct msm_vidc_inst *inst, struct getprop_buf *buf; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } @@ -4812,9 +4798,9 @@ int msm_comm_try_get_buff_req(struct msm_vidc_inst *inst, * is enough check to have. */ - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "In Wrong state to call Buf Req: Inst %pK or Core %pK\n", - inst, inst->core); + inst, inst->core); rc = -EAGAIN; mutex_unlock(&inst->sync_lock); goto exit; @@ -4823,7 +4809,7 @@ int msm_comm_try_get_buff_req(struct msm_vidc_inst *inst, rc = call_hfi_op(hdev, session_get_buf_req, inst->session); if (rc) { - dprintk(VIDC_ERR, "Can't query hardware for property: %d\n", + s_vpr_e(inst->sid, "Can't query hardware for property: %d\n", rc); goto exit; } @@ -4833,7 +4819,7 @@ int msm_comm_try_get_buff_req(struct msm_vidc_inst *inst, msecs_to_jiffies( inst->core->resources.msm_vidc_hw_rsp_timeout)); if (!rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: Wait interrupted or timed out [%pK]: %d\n", __func__, inst, SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO)); @@ -4854,7 +4840,7 @@ int msm_comm_try_get_buff_req(struct msm_vidc_inst *inst, list_del(&buf->list); kfree(buf); } else { - dprintk(VIDC_ERR, "%s getprop list empty\n", __func__); + s_vpr_e(inst->sid, "%s: getprop list empty\n", __func__); rc = -EINVAL; } mutex_unlock(&inst->pending_getpropq.lock); @@ -4873,13 +4859,12 @@ int msm_comm_release_dpb_only_buffers(struct msm_vidc_inst *inst, struct hfi_device *hdev; if (!inst) { - dprintk(VIDC_ERR, - "Invalid instance pointer = %pK\n", inst); + d_vpr_e("Invalid instance pointer = %pK\n", inst); return -EINVAL; } mutex_lock(&inst->outputbufs.lock); if (list_empty(&inst->outputbufs.list)) { - dprintk(VIDC_HIGH, "%s - No OUTPUT buffers allocated\n", + s_vpr_h(inst->sid, "%s: No OUTPUT buffers allocated\n", __func__); mutex_unlock(&inst->outputbufs.lock); return 0; @@ -4888,13 +4873,12 @@ int msm_comm_release_dpb_only_buffers(struct msm_vidc_inst *inst, core = inst->core; if (!core) { - dprintk(VIDC_ERR, - "Invalid core pointer = %pK\n", core); + s_vpr_e(inst->sid, "Invalid core pointer\n"); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); + s_vpr_e(inst->sid, "Invalid device pointer\n"); return -EINVAL; } mutex_lock(&inst->outputbufs.lock); @@ -4902,7 +4886,7 @@ int msm_comm_release_dpb_only_buffers(struct msm_vidc_inst *inst, handle = &buf->smem; if ((buf->buffer_ownership == FIRMWARE) && !force_release) { - dprintk(VIDC_HIGH, "DPB is with f/w. Can't free it\n"); + s_vpr_h(inst->sid, "DPB is with f/w. Can't free it\n"); /* * mark this buffer to avoid sending it to video h/w * again, this buffer belongs to old resolution and @@ -4922,7 +4906,7 @@ int msm_comm_release_dpb_only_buffers(struct msm_vidc_inst *inst, rc = call_hfi_op(hdev, session_release_buffers, (void *)inst->session, &buffer_info); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Rel output buf fail:%x, %d\n", buffer_info.align_device_addr, buffer_info.buffer_size); @@ -4952,7 +4936,7 @@ static enum hal_buffer scratch_buf_sufficient(struct msm_vidc_inst *inst, int count = 0; if (!inst) { - dprintk(VIDC_ERR, "%s - invalid param\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); goto not_sufficient; } @@ -4973,7 +4957,7 @@ static enum hal_buffer scratch_buf_sufficient(struct msm_vidc_inst *inst, if (count != bufreq->buffer_count_actual) goto not_sufficient; - dprintk(VIDC_HIGH, + s_vpr_h(inst->sid, "Existing scratch buffer is sufficient for buffer type %#x\n", buffer_type); @@ -4995,19 +4979,17 @@ int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst, enum hal_buffer sufficiency = HAL_BUFFER_NONE; if (!inst) { - dprintk(VIDC_ERR, - "Invalid instance pointer = %pK\n", inst); + d_vpr_e("Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { - dprintk(VIDC_ERR, - "Invalid core pointer = %pK\n", core); + s_vpr_e(inst->sid, "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); + s_vpr_e(inst->sid, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } @@ -5037,13 +5019,12 @@ int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst, rc = wait_for_sess_signal_receipt(inst, HAL_SESSION_RELEASE_BUFFER_DONE); if (rc) - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: wait for signal failed, rc %d\n", __func__, rc); mutex_lock(&inst->scratchbufs.lock); } else { - dprintk(VIDC_ERR, - "Rel scrtch buf fail:%x, %d\n", + s_vpr_e(inst->sid, "Rel scrtch buf fail:%x, %d\n", buffer_info.align_device_addr, buffer_info.buffer_size); } @@ -5066,8 +5047,7 @@ void msm_comm_release_eos_buffers(struct msm_vidc_inst *inst) struct eos_buf *buf, *next; if (!inst) { - dprintk(VIDC_ERR, - "Invalid instance pointer = %pK\n", inst); + d_vpr_e("Invalid instance pointer = %pK\n", inst); return; } @@ -5087,8 +5067,7 @@ int msm_comm_release_recon_buffers(struct msm_vidc_inst *inst) struct recon_buf *buf, *next; if (!inst) { - dprintk(VIDC_ERR, - "Invalid instance pointer = %pK\n", inst); + d_vpr_e("Invalid instance pointer = %pK\n", inst); return -EINVAL; } @@ -5114,19 +5093,17 @@ int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst) { - dprintk(VIDC_ERR, - "Invalid instance pointer = %pK\n", inst); + d_vpr_e("Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { - dprintk(VIDC_ERR, - "Invalid core pointer = %pK\n", core); + s_vpr_e(inst->sid, "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); + s_vpr_e(inst->sid, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } @@ -5146,13 +5123,12 @@ int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst) rc = wait_for_sess_signal_receipt(inst, HAL_SESSION_RELEASE_BUFFER_DONE); if (rc) - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: wait for signal failed, rc %d\n", __func__, rc); mutex_lock(&inst->persistbufs.lock); } else { - dprintk(VIDC_ERR, - "Rel prst buf fail:%x, %d\n", + s_vpr_e(inst->sid, "Rel prst buf fail:%x, %d\n", buffer_info.align_device_addr, buffer_info.buffer_size); } @@ -5173,26 +5149,25 @@ int msm_comm_set_buffer_count(struct msm_vidc_inst *inst, struct hfi_buffer_count_actual buf_count; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } hdev = inst->core->device; - buf_count.buffer_type = get_hfi_buffer(type); + buf_count.buffer_type = get_hfi_buffer(type, inst->sid); buf_count.buffer_count_actual = act_count; buf_count.buffer_count_min_host = host_count; /* set total superframe buffers count */ ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); if (ctrl->val) buf_count.buffer_count_actual = act_count * ctrl->val; - dprintk(VIDC_HIGH, "%s: %x : hal_buffer %d min_host %d actual %d\n", - __func__, hash32_ptr(inst->session), type, - host_count, act_count); + s_vpr_h(inst->sid, "%s: hal_buffer %d min_host %d actual %d\n", + __func__, type, host_count, act_count); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL, &buf_count, sizeof(buf_count)); if (rc) - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to set actual buffer count %d for buffer type %d\n", act_count, type); return rc; @@ -5204,7 +5179,7 @@ int msm_comm_set_dpb_only_buffers(struct msm_vidc_inst *inst) bool force_release = true; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } @@ -5212,7 +5187,7 @@ int msm_comm_set_dpb_only_buffers(struct msm_vidc_inst *inst) force_release = false; if (msm_comm_release_dpb_only_buffers(inst, force_release)) - dprintk(VIDC_ERR, "Failed to release output buffers\n"); + s_vpr_e(inst->sid, "Failed to release output buffers\n"); rc = set_dpb_only_buffers(inst, HAL_BUFFER_OUTPUT); if (rc) @@ -5228,12 +5203,12 @@ int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst) int rc = 0; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } if (msm_comm_release_scratch_buffers(inst, true)) - dprintk(VIDC_ERR, "Failed to release scratch buffers\n"); + s_vpr_e(inst->sid, "Failed to release scratch buffers\n"); rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH, &inst->scratchbufs); @@ -5264,13 +5239,13 @@ int msm_comm_set_recon_buffers(struct msm_vidc_inst *inst) struct msm_vidc_list *buf_list = &inst->refbufs; if (!inst) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } if (inst->session_type != MSM_VIDC_ENCODER && inst->session_type != MSM_VIDC_DECODER) { - dprintk(VIDC_HIGH, "Recon buffs not req for cvp\n"); + s_vpr_h(inst->sid, "Recon buffs not req for cvp\n"); return 0; } @@ -5281,7 +5256,7 @@ int msm_comm_set_recon_buffers(struct msm_vidc_inst *inst) for (i = 0; i < bufcount; i++) { binfo = kzalloc(sizeof(*binfo), GFP_KERNEL); if (!binfo) { - dprintk(VIDC_ERR, "Out of memory\n"); + s_vpr_e(inst->sid, "%s: Out of memory\n", __func__); rc = -ENOMEM; goto fail_kzalloc; } @@ -5301,7 +5276,7 @@ int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst) int rc = 0; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } @@ -5339,13 +5314,12 @@ static void msm_comm_flush_in_invalid_state(struct msm_vidc_inst *inst) struct vb2_buffer, queued_entry); if (vb->state == VB2_BUF_STATE_ACTIVE) { vb->planes[0].bytesused = 0; - print_vb2_buffer(VIDC_ERR, "flush in invalid", - inst, vb); + print_vb2_buffer("flush in invalid", inst, vb); vb2_buffer_done(vb, VB2_BUF_STATE_DONE); } else { - dprintk(VIDC_ERR, - "%s VB is in state %d not in ACTIVE state\n" - , __func__, vb->state); + s_vpr_e(inst->sid, + "%s: VB is in state %d not in ACTIVE state\n", + __func__, vb->state); } } mutex_unlock(&inst->bufq[port].lock); @@ -5364,13 +5338,12 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) struct hfi_device *hdev; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, - "Invalid params, inst %pK\n", inst); + d_vpr_e("invalid params %pK\n", inst); return -EINVAL; } if (inst->state < MSM_VIDC_OPEN_DONE) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Invalid state to call flush, inst %pK, state %#x\n", inst, inst->state); return -EINVAL; @@ -5383,15 +5356,14 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) op_flush = !!(flags & V4L2_CMD_FLUSH_CAPTURE); if (ip_flush && !op_flush) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Input only flush not supported, making it flush all\n"); op_flush = true; goto exit; } if ((inst->in_flush && ip_flush) || (inst->out_flush && op_flush)) { - dprintk(VIDC_ERR, "%s: %x : Already in flush\n", - __func__, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, "%s: Already in flush\n", __func__); goto exit; } @@ -5399,9 +5371,8 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) cancel_batch_work(inst); if (inst->state == MSM_VIDC_CORE_INVALID) { - dprintk(VIDC_ERR, - "Core %pK and inst %pK are in bad state\n", - core, inst); + s_vpr_e(inst->sid, "Core %pK and inst %pK are in bad state\n", + core, inst); msm_comm_flush_in_invalid_state(inst); goto exit; } @@ -5454,17 +5425,17 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) hdev = inst->core->device; if (ip_flush) { - dprintk(VIDC_HIGH, "Send flush on all ports to firmware\n"); + s_vpr_h(inst->sid, "Send flush on all ports to firmware\n"); rc = call_hfi_op(hdev, session_flush, inst->session, HAL_FLUSH_ALL); } else { - dprintk(VIDC_HIGH, "Send flush on output port to firmware\n"); + s_vpr_h(inst->sid, "Send flush on output port to firmware\n"); rc = call_hfi_op(hdev, session_flush, inst->session, HAL_FLUSH_OUTPUT); } mutex_unlock(&inst->flush_lock); if (rc) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Sending flush to firmware failed, flush out all buffers\n"); msm_comm_flush_in_invalid_state(inst); /* disable in_flush & out_flush */ @@ -5481,7 +5452,7 @@ int msm_vidc_noc_error_info(struct msm_vidc_core *core) struct hfi_device *hdev; if (!core || !core->device) { - dprintk(VIDC_ERR, "%s: Invalid parameters: %pK\n", + d_vpr_e("%s: Invalid parameters: %pK\n", __func__, core); return -EINVAL; } @@ -5502,7 +5473,7 @@ int msm_vidc_trigger_ssr(struct msm_vidc_core *core, enum hal_ssr_trigger_type type) { if (!core) { - dprintk(VIDC_ERR, "%s: Invalid parameters\n", __func__); + d_vpr_e("%s: Invalid parameters\n", __func__); return -EINVAL; } core->ssr_type = type; @@ -5518,15 +5489,14 @@ void msm_vidc_ssr_handler(struct work_struct *work) core = container_of(work, struct msm_vidc_core, ssr_work); if (!core || !core->device) { - dprintk(VIDC_ERR, "%s: Invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, core); return; } hdev = core->device; mutex_lock(&core->lock); if (core->state == VIDC_CORE_INIT_DONE) { - dprintk(VIDC_ERR, "%s: ssr type %d\n", __func__, - core->ssr_type); + d_vpr_e("%s: ssr type %d\n", __func__, core->ssr_type); /* * In current implementation user-initiated SSR triggers * a fatal error from hardware. However, there is no way @@ -5537,13 +5507,11 @@ void msm_vidc_ssr_handler(struct work_struct *work) rc = call_hfi_op(hdev, core_trigger_ssr, hdev->hfi_device_data, core->ssr_type); if (rc) { - dprintk(VIDC_ERR, "%s: trigger_ssr failed\n", - __func__); + d_vpr_e("%s: trigger_ssr failed\n", __func__); core->trigger_ssr = false; } } else { - dprintk(VIDC_ERR, "%s: video core %pK not initialized\n", - __func__, core); + d_vpr_e("%s: video core not initialized\n", __func__); } mutex_unlock(&core->lock); } @@ -5555,13 +5523,13 @@ static int msm_vidc_check_mbpf_supported(struct msm_vidc_inst *inst) struct msm_vidc_inst *temp; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } core = inst->core; if (!core->resources.max_mbpf) { - dprintk(VIDC_HIGH, "%s: max mbpf not available\n", + s_vpr_h(inst->sid, "%s: max mbpf not available\n", __func__); return 0; } @@ -5603,10 +5571,9 @@ static int msm_vidc_check_mbps_supported(struct msm_vidc_inst *inst) num_mbs_per_sec += msm_comm_get_device_load(inst->core, MSM_VIDC_ENCODER, quirks); if (num_mbs_per_sec > max_load_adj) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "H/W is overloaded. needed: %d max: %d\n", - num_mbs_per_sec, - max_load_adj); + num_mbs_per_sec, max_load_adj); msm_vidc_print_running_insts(inst->core); return -EBUSY; } @@ -5625,7 +5592,7 @@ int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst) if (is_image_session(inst)) { ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE); if (ctrl->val > 0) { - dprintk(VIDC_HIGH, "Skip scaling check for HEIC\n"); + s_vpr_h(inst->sid, "Skip scaling check for HEIC\n"); return 0; } } @@ -5638,11 +5605,9 @@ int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst) output_width = f->fmt.pix_mp.width; if (!input_height || !input_width || !output_height || !output_width) { - dprintk(VIDC_ERR, - "Invalid : Input height = %d width = %d", + s_vpr_e(inst->sid, "Invalid : Input height = %d width = %d", input_height, input_width); - dprintk(VIDC_ERR, - " output height = %d width = %d\n", + s_vpr_e(inst->sid, " output height = %d width = %d\n", output_height, output_width); return -ENOTSUPP; } @@ -5654,14 +5619,14 @@ int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst) if (input_width * input_height != output_width * output_height) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: scaling is not supported (%dx%d != %dx%d)\n", __func__, input_width, input_height, output_width, output_height); return -ENOTSUPP; } - dprintk(VIDC_HIGH, "%s: supported WxH = %dx%d\n", + s_vpr_h(inst->sid, "%s: supported WxH = %dx%d\n", __func__, input_width, input_height); return 0; } @@ -5673,14 +5638,14 @@ int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst) if (input_height > output_height) { if (input_height > x_min * output_height) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Unsupported height min height %d vs %d\n", input_height / x_min, output_height); return -ENOTSUPP; } } else { if (output_height > x_max * input_height) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Unsupported height max height %d vs %d\n", x_max * input_height, output_height); return -ENOTSUPP; @@ -5688,14 +5653,14 @@ int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst) } if (input_width > output_width) { if (input_width > y_min * output_width) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Unsupported width min width %d vs %d\n", input_width / y_min, output_width); return -ENOTSUPP; } } else { if (output_width > y_max * input_width) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Unsupported width max width %d vs %d\n", y_max * input_width, output_width); return -ENOTSUPP; @@ -5715,18 +5680,19 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) u32 mbpf_max; struct v4l2_format *f; struct v4l2_ctrl *ctrl = NULL; + u32 sid; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s: Invalid parameter\n", __func__); + d_vpr_e("%s: Invalid parameter\n", __func__); return -EINVAL; } capability = &inst->capability; hdev = inst->core->device; core = inst->core; + sid = inst->sid; rc = msm_vidc_check_mbps_supported(inst); if (rc) { - dprintk(VIDC_ERR, - "%s: Hardware is overloaded\n", __func__); + s_vpr_e(sid, "%s: Hardware is overloaded\n", __func__); return rc; } @@ -5735,7 +5701,7 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) return rc; if (!is_thermal_permissible(core)) { - dprintk(VIDC_ERR, + s_vpr_e(sid, "Thermal level critical, stop all active sessions!\n"); return -ENOTSUPP; } @@ -5772,8 +5738,7 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) if (is_image_session(inst)) { if (is_secure_session(inst)) { - dprintk(VIDC_ERR, - "Secure image encode isn't supported!\n"); + s_vpr_e(sid, "Secure image encode isn't supported!\n"); return -ENOTSUPP; } @@ -5815,10 +5780,9 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) if (inst->session_type == MSM_VIDC_ENCODER && (input_width % 2 != 0 || input_height % 2 != 0 || output_width % 2 != 0 || output_height % 2 != 0)) { - dprintk(VIDC_ERR, + s_vpr_e(sid, "Height and Width should be even numbers for NV12\n"); - dprintk(VIDC_ERR, - "Input WxH = (%u)x(%u), Output WxH = (%u)x(%u)\n", + s_vpr_e(sid, "Input WxH = (%u)x(%u), Output WxH = (%u)x(%u)\n", input_width, input_height, output_width, output_height); rc = -ENOTSUPP; @@ -5830,14 +5794,14 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) if (!rc) { if (output_width < width_min || output_height < height_min) { - dprintk(VIDC_ERR, - "Unsupported WxH = (%u)x(%u), min supported is - (%u)x(%u)\n", + s_vpr_e(sid, + "Unsupported WxH (%u)x(%u), min supported is (%u)x(%u)\n", output_width, output_height, width_min, height_min); rc = -ENOTSUPP; } if (!rc && output_width > width_max) { - dprintk(VIDC_ERR, + s_vpr_e(sid, "Unsupported width = %u supported max width = %u\n", output_width, width_max); rc = -ENOTSUPP; @@ -5845,10 +5809,10 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) if (!rc && output_height * output_width > width_max * height_max) { - dprintk(VIDC_ERR, - "Unsupported WxH = (%u)x(%u), max supported is - (%u)x(%u)\n", - output_width, output_height, - width_max, height_max); + s_vpr_e(sid, + "Unsupported WxH = (%u)x(%u), max supported is (%u)x(%u)\n", + output_width, output_height, + width_max, height_max); rc = -ENOTSUPP; } /* Image size max capability has equal width and height, @@ -5857,7 +5821,7 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) if (!rc && !is_image_session(inst) && NUM_MBS_PER_FRAME(input_width, input_height) > mbpf_max) { - dprintk(VIDC_ERR, "Unsupported mbpf %d, max %d\n", + s_vpr_e(sid, "Unsupported mbpf %d, max %d\n", NUM_MBS_PER_FRAME(input_width, input_height), mbpf_max); rc = -ENOTSUPP; @@ -5868,16 +5832,16 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) output_height > INTERLACE_HEIGHT_MAX || (NUM_MBS_PER_FRAME(output_height, output_width) > INTERLACE_MB_PER_FRAME_MAX))) { - dprintk(VIDC_ERR, - "Unsupported interlace WxH = (%u)x(%u), max supported is - (%u)x(%u)\n", + s_vpr_e(sid, + "Unsupported interlace WxH = (%u)x(%u), max supported is (%u)x(%u)\n", output_width, output_height, - INTERLACE_WIDTH_MAX, INTERLACE_HEIGHT_MAX); + INTERLACE_WIDTH_MAX, + INTERLACE_HEIGHT_MAX); rc = -ENOTSUPP; } } if (rc) { - dprintk(VIDC_ERR, - "%s: Resolution unsupported\n", __func__); + s_vpr_e(sid, "%s: Resolution unsupported\n", __func__); } return rc; } @@ -5888,11 +5852,11 @@ void msm_comm_generate_session_error(struct msm_vidc_inst *inst) struct msm_vidc_cb_cmd_done response = {0}; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); + d_vpr_e("%s: invalid input parameters\n", __func__); return; } - dprintk(VIDC_ERR, "%s: inst %pK\n", __func__, inst); - response.session_id = inst; + s_vpr_e(inst->sid, "%s: inst %pK\n", __func__, inst); + response.inst_id = inst; response.status = VIDC_ERR_FAIL; handle_session_error(cmd, (void *)&response); } @@ -5904,10 +5868,10 @@ void msm_comm_generate_sys_error(struct msm_vidc_inst *inst) struct msm_vidc_cb_cmd_done response = {0}; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); + d_vpr_e("%s: invalid input parameters\n", __func__); return; } - dprintk(VIDC_ERR, "%s: inst %pK\n", __func__, inst); + s_vpr_e(inst->sid, "%s: inst %pK\n", __func__, inst); core = inst->core; response.device_id = (u32) core->id; handle_sys_error(cmd, (void *) &response); @@ -5919,16 +5883,16 @@ int msm_comm_kill_session(struct msm_vidc_inst *inst) int rc = 0; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); + d_vpr_e("%s: invalid input parameters\n", __func__); return -EINVAL; } else if (!inst->session) { - dprintk(VIDC_ERR, "%s: no session to kill for inst %pK\n", + s_vpr_e(inst->sid, "%s: no session to kill for inst %pK\n", __func__, inst); return 0; } - dprintk(VIDC_ERR, "%s: inst %pK, session %x state %d\n", __func__, - inst, hash32_ptr(inst->session), inst->state); + s_vpr_e(inst->sid, "%s: inst %pK, state %d\n", __func__, + inst, inst->state); /* * We're internally forcibly killing the session, if fw is aware of * the session send session_abort to firmware to clean up and release @@ -5939,9 +5903,9 @@ int msm_comm_kill_session(struct msm_vidc_inst *inst) inst->state == MSM_VIDC_CORE_INVALID) { rc = msm_comm_session_abort(inst); if (rc) { - dprintk(VIDC_ERR, - "%s: inst %pK session %x abort failed\n", - __func__, inst, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, + "%s: inst %pK session abort failed\n", + __func__, inst); change_inst_state(inst, MSM_VIDC_CORE_INVALID); } } @@ -5949,8 +5913,8 @@ int msm_comm_kill_session(struct msm_vidc_inst *inst) change_inst_state(inst, MSM_VIDC_CLOSE_DONE); msm_comm_session_clean(inst); - dprintk(VIDC_ERR, "%s: inst %pK session %x handled\n", __func__, - inst, hash32_ptr(inst->session)); + s_vpr_e(inst->sid, "%s: inst %pK handled\n", __func__, + inst); return rc; } @@ -5961,23 +5925,23 @@ int msm_comm_smem_alloc(struct msm_vidc_inst *inst, int rc = 0; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst); + d_vpr_e("%s: invalid inst: %pK\n", __func__, inst); return -EINVAL; } rc = msm_smem_alloc(size, align, flags, buffer_type, map_kernel, &(inst->core->resources), inst->session_type, - smem); + smem, inst->sid); return rc; } void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *mem) { if (!inst || !inst->core || !mem) { - dprintk(VIDC_ERR, - "%s: invalid params: %pK %pK\n", __func__, inst, mem); + d_vpr_e("%s: invalid params: %pK %pK\n", + __func__, inst, mem); return; } - msm_smem_free(mem); + msm_smem_free(mem, inst->sid); } void msm_vidc_fw_unload_handler(struct work_struct *work) @@ -5988,8 +5952,7 @@ void msm_vidc_fw_unload_handler(struct work_struct *work) core = container_of(work, struct msm_vidc_core, fw_unload_work.work); if (!core || !core->device) { - dprintk(VIDC_ERR, "%s - invalid work or core handle\n", - __func__); + d_vpr_e("%s: invalid work or core handle\n", __func__); return; } @@ -5999,12 +5962,11 @@ void msm_vidc_fw_unload_handler(struct work_struct *work) if (list_empty(&core->instances) && core->state != VIDC_CORE_UNINIT) { if (core->state > VIDC_CORE_INIT) { - dprintk(VIDC_HIGH, "Calling vidc_hal_core_release\n"); + d_vpr_h("Calling vidc_hal_core_release\n"); rc = call_hfi_op(hdev, core_release, hdev->hfi_device_data); if (rc) { - dprintk(VIDC_ERR, - "Failed to release core, id = %d\n", + d_vpr_e("Failed to release core, id = %d\n", core->id); mutex_unlock(&core->lock); return; @@ -6026,24 +5988,24 @@ int msm_comm_set_color_format(struct msm_vidc_inst *inst, struct hfi_device *hdev; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s - invalid param\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } hdev = inst->core->device; - format = msm_comm_get_hfi_uncompressed(fourcc); - hfi_fmt.buffer_type = get_hfi_buffer(buffer_type); + format = msm_comm_get_hfi_uncompressed(fourcc, inst->sid); + hfi_fmt.buffer_type = get_hfi_buffer(buffer_type, inst->sid); hfi_fmt.format = format; - + s_vpr_h(inst->sid, "buffer_type %#x, format %#x\n", + hfi_fmt.buffer_type, hfi_fmt.format); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT, &hfi_fmt, sizeof(hfi_fmt)); if (rc) - dprintk(VIDC_ERR, - "Failed to set input color format\n"); + s_vpr_e(inst->sid, "Failed to set input color format\n"); else - dprintk(VIDC_HIGH, "Setting uncompressed colorformat to %#x\n", + s_vpr_h(inst->sid, "Setting uncompressed colorformat to %#x\n", format); return rc; @@ -6059,8 +6021,7 @@ void msm_comm_print_inst_info(struct msm_vidc_inst *inst) struct v4l2_format *f; if (!inst) { - dprintk(VIDC_ERR, "%s - invalid param %pK\n", - __func__, inst); + d_vpr_e("%s: invalid params\n", __func__); return; } @@ -6068,7 +6029,7 @@ void msm_comm_print_inst_info(struct msm_vidc_inst *inst) port = is_decode ? INPUT_PORT : OUTPUT_PORT; is_secure = inst->flags & VIDC_SECURE; f = &inst->fmts[port].v4l2_fmt; - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s session, %s, Codec type: %s HxW: %d x %d fps: %d bitrate: %d bit-depth: %s\n", is_decode ? "Decode" : "Encode", is_secure ? "Secure" : "Non-Secure", @@ -6076,36 +6037,34 @@ void msm_comm_print_inst_info(struct msm_vidc_inst *inst) f->fmt.pix_mp.height, f->fmt.pix_mp.width, inst->clk_data.frame_rate >> 16, inst->prop.bitrate, !inst->bit_depth ? "8" : "10"); - - dprintk(VIDC_ERR, - "---Buffer details for inst: %pK of type: %d---\n", + s_vpr_e(inst->sid, "---Buffer details for inst: %pK of type: %d---\n", inst, inst->session_type); mutex_lock(&inst->registeredbufs.lock); - dprintk(VIDC_ERR, "registered buffer list:\n"); + s_vpr_e(inst->sid, "registered buffer list:\n"); list_for_each_entry(mbuf, &inst->registeredbufs.list, list) print_vidc_buffer(VIDC_ERR, "buf", inst, mbuf); mutex_unlock(&inst->registeredbufs.lock); mutex_lock(&inst->scratchbufs.lock); - dprintk(VIDC_ERR, "scratch buffer list:\n"); + s_vpr_e(inst->sid, "scratch buffer list:\n"); list_for_each_entry(buf, &inst->scratchbufs.list, list) - dprintk(VIDC_ERR, "type: %d addr: %x size: %u\n", + s_vpr_e(inst->sid, "type: %d addr: %x size: %u\n", buf->buffer_type, buf->smem.device_addr, buf->smem.size); mutex_unlock(&inst->scratchbufs.lock); mutex_lock(&inst->persistbufs.lock); - dprintk(VIDC_ERR, "persist buffer list:\n"); + s_vpr_e(inst->sid, "persist buffer list:\n"); list_for_each_entry(buf, &inst->persistbufs.list, list) - dprintk(VIDC_ERR, "type: %d addr: %x size: %u\n", + s_vpr_e(inst->sid, "type: %d addr: %x size: %u\n", buf->buffer_type, buf->smem.device_addr, buf->smem.size); mutex_unlock(&inst->persistbufs.lock); mutex_lock(&inst->outputbufs.lock); - dprintk(VIDC_ERR, "dpb buffer list:\n"); + s_vpr_e(inst->sid, "dpb buffer list:\n"); list_for_each_entry(buf, &inst->outputbufs.list, list) - dprintk(VIDC_ERR, "type: %d addr: %x size: %u\n", + s_vpr_e(inst->sid, "type: %d addr: %x size: %u\n", buf->buffer_type, buf->smem.device_addr, buf->smem.size); mutex_unlock(&inst->outputbufs.lock); @@ -6123,18 +6082,17 @@ int msm_comm_session_continue(void *instance) mutex_lock(&inst->lock); if (inst->state >= MSM_VIDC_RELEASE_RESOURCES_DONE || inst->state < MSM_VIDC_START_DONE) { - dprintk(VIDC_HIGH, - "Inst %pK : Not in valid state to call %s\n", + s_vpr_h(inst->sid, "Inst %pK : Not in valid state to call %s\n", inst, __func__); goto sess_continue_fail; } if (inst->session_type == MSM_VIDC_DECODER && inst->in_reconfig) { - dprintk(VIDC_HIGH, "send session_continue\n"); + s_vpr_h(inst->sid, "send session_continue\n"); rc = call_hfi_op(hdev, session_continue, (void *)inst->session); if (rc) { - dprintk(VIDC_ERR, - "failed to send session_continue\n"); + s_vpr_e(inst->sid, + "failed to send session_continue\n"); rc = -EINVAL; goto sess_continue_fail; } @@ -6144,18 +6102,17 @@ int msm_comm_session_continue(void *instance) HAL_VIDEO_DECODER_SECONDARY) { rc = msm_comm_queue_dpb_only_buffers(inst); if (rc) { - dprintk(VIDC_ERR, - "Failed to queue output buffers: %d\n", - rc); + s_vpr_e(inst->sid, + "Failed to queue output buffers\n"); goto sess_continue_fail; } } } else if (inst->session_type == MSM_VIDC_ENCODER) { - dprintk(VIDC_HIGH, - "session_continue not supported for encoder"); + s_vpr_h(inst->sid, + "session_continue not supported for encoder"); } else { - dprintk(VIDC_ERR, - "session_continue called in wrong state for decoder"); + s_vpr_e(inst->sid, + "session_continue called in wrong state for decoder"); } sess_continue_fail: @@ -6174,20 +6131,20 @@ void print_vidc_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, vb2 = &mbuf->vvb.vb2_buf; if (vb2->num_planes == 1) - dprintk(tag, - "%s: %s: %x : idx %2d fd %d off %d daddr %x size %d filled %d flags 0x%x ts %lld refcnt %d mflags 0x%x\n", + dprintk(tag, inst->sid, + "%s: %s: idx %2d fd %d off %d daddr %x size %d filled %d flags 0x%x ts %lld refcnt %d mflags 0x%x\n", str, vb2->type == INPUT_MPLANE ? - "OUTPUT" : "CAPTURE", hash32_ptr(inst->session), + "OUTPUT" : "CAPTURE", vb2->index, vb2->planes[0].m.fd, vb2->planes[0].data_offset, mbuf->smem[0].device_addr, vb2->planes[0].length, vb2->planes[0].bytesused, mbuf->vvb.flags, mbuf->vvb.vb2_buf.timestamp, mbuf->smem[0].refcount, mbuf->flags); else - dprintk(tag, - "%s: %s: %x : idx %2d fd %d off %d daddr %x size %d filled %d flags 0x%x ts %lld refcnt %d mflags 0x%x, extradata: fd %d off %d daddr %x size %d filled %d refcnt %d\n", + dprintk(tag, inst->sid, + "%s: %s: idx %2d fd %d off %d daddr %x size %d filled %d flags 0x%x ts %lld refcnt %d mflags 0x%x, extradata: fd %d off %d daddr %x size %d filled %d refcnt %d\n", str, vb2->type == INPUT_MPLANE ? - "OUTPUT" : "CAPTURE", hash32_ptr(inst->session), + "OUTPUT" : "CAPTURE", vb2->index, vb2->planes[0].m.fd, vb2->planes[0].data_offset, mbuf->smem[0].device_addr, vb2->planes[0].length, vb2->planes[0].bytesused, @@ -6198,29 +6155,23 @@ void print_vidc_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, vb2->planes[1].bytesused, mbuf->smem[1].refcount); } -void print_vb2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, +void print_vb2_buffer(const char *str, struct msm_vidc_inst *inst, struct vb2_buffer *vb2) { - if (!(tag & msm_vidc_debug) || !inst || !vb2) - return; - if ((tag & VIDC_PERF) && - !(tag & VIDC_HIGH) && - (inst->session_type != MSM_VIDC_DECODER)) + if (!inst || !vb2) return; if (vb2->num_planes == 1) - dprintk(tag, - "%s: %s: %x : idx %2d fd %d off %d size %d filled %d\n", - str, vb2->type == INPUT_MPLANE ? - "OUTPUT" : "CAPTURE", hash32_ptr(inst->session), + s_vpr_e(inst->sid, + "%s: %s: idx %2d fd %d off %d size %d filled %d\n", + str, vb2->type == INPUT_MPLANE ? "OUTPUT" : "CAPTURE", vb2->index, vb2->planes[0].m.fd, vb2->planes[0].data_offset, vb2->planes[0].length, vb2->planes[0].bytesused); else - dprintk(tag, - "%s: %s: %x : idx %2d fd %d off %d size %d filled %d, extradata: fd %d off %d size %d filled %d\n", - str, vb2->type == INPUT_MPLANE ? - "OUTPUT" : "CAPTURE", hash32_ptr(inst->session), + s_vpr_e(inst->sid, + "%s: %s: idx %2d fd %d off %d size %d filled %d, extradata: fd %d off %d size %d filled %d\n", + str, vb2->type == INPUT_MPLANE ? "OUTPUT" : "CAPTURE", vb2->index, vb2->planes[0].m.fd, vb2->planes[0].data_offset, vb2->planes[0].length, vb2->planes[0].bytesused, vb2->planes[1].m.fd, @@ -6228,43 +6179,13 @@ void print_vb2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, vb2->planes[1].bytesused); } -void print_v4l2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, - struct v4l2_buffer *v4l2) -{ - if (!(tag & msm_vidc_debug) || !inst || !v4l2) - return; - - if (v4l2->length == 1) - dprintk(tag, - "%s: %s: %x : idx %2d fd %d off %d size %d filled %d\n", - str, v4l2->type == INPUT_MPLANE ? - "OUTPUT" : "CAPTURE", hash32_ptr(inst->session), - v4l2->index, v4l2->m.planes[0].m.fd, - v4l2->m.planes[0].data_offset, - v4l2->m.planes[0].length, - v4l2->m.planes[0].bytesused); - else - dprintk(tag, - "%s: %s: %x : idx %2d fd %d off %d size %d filled %d, extradata: fd %d off %d size %d filled %d\n", - str, v4l2->type == INPUT_MPLANE ? - "OUTPUT" : "CAPTURE", hash32_ptr(inst->session), - v4l2->index, v4l2->m.planes[0].m.fd, - v4l2->m.planes[0].data_offset, - v4l2->m.planes[0].length, - v4l2->m.planes[0].bytesused, - v4l2->m.planes[1].m.fd, - v4l2->m.planes[1].data_offset, - v4l2->m.planes[1].length, - v4l2->m.planes[1].bytesused); -} - bool msm_comm_compare_vb2_plane(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf, struct vb2_buffer *vb2, u32 i) { struct vb2_buffer *vb; if (!inst || !mbuf || !vb2) { - dprintk(VIDC_ERR, "%s: invalid params, %pK %pK %pK\n", + d_vpr_e("%s: invalid params, %pK %pK %pK\n", __func__, inst, mbuf, vb2); return false; } @@ -6285,7 +6206,7 @@ bool msm_comm_compare_vb2_planes(struct msm_vidc_inst *inst, struct vb2_buffer *vb; if (!inst || !mbuf || !vb2) { - dprintk(VIDC_ERR, "%s: invalid params, %pK %pK %pK\n", + d_vpr_e("%s: invalid params, %pK %pK %pK\n", __func__, inst, mbuf, vb2); return false; } @@ -6307,7 +6228,7 @@ bool msm_comm_compare_dma_plane(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf, unsigned long *dma_planes, u32 i) { if (!inst || !mbuf || !dma_planes) { - dprintk(VIDC_ERR, "%s: invalid params, %pK %pK %pK\n", + d_vpr_e("%s: invalid params, %pK %pK %pK\n", __func__, inst, mbuf, dma_planes); return false; } @@ -6325,7 +6246,7 @@ bool msm_comm_compare_dma_planes(struct msm_vidc_inst *inst, struct vb2_buffer *vb; if (!inst || !mbuf || !dma_planes) { - dprintk(VIDC_ERR, "%s: invalid params, %pK %pK %pK\n", + d_vpr_e("%s: invalid params, %pK %pK %pK\n", __func__, inst, mbuf, dma_planes); return false; } @@ -6340,11 +6261,11 @@ bool msm_comm_compare_dma_planes(struct msm_vidc_inst *inst, } -bool msm_comm_compare_device_plane(struct msm_vidc_buffer *mbuf, +bool msm_comm_compare_device_plane(u32 sid, struct msm_vidc_buffer *mbuf, u32 type, u32 *planes, u32 i) { if (!mbuf || !planes) { - dprintk(VIDC_ERR, "%s: invalid params, %pK %pK\n", + s_vpr_e(sid, "%s: invalid params, %pK %pK\n", __func__, mbuf, planes); return false; } @@ -6356,7 +6277,7 @@ bool msm_comm_compare_device_plane(struct msm_vidc_buffer *mbuf, return false; } -bool msm_comm_compare_device_planes(struct msm_vidc_buffer *mbuf, +bool msm_comm_compare_device_planes(u32 sid, struct msm_vidc_buffer *mbuf, u32 type, u32 *planes) { unsigned int i = 0; @@ -6365,7 +6286,7 @@ bool msm_comm_compare_device_planes(struct msm_vidc_buffer *mbuf, return false; for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) { - if (!msm_comm_compare_device_plane(mbuf, type, planes, i)) + if (!msm_comm_compare_device_plane(sid, mbuf, type, planes, i)) return false; } @@ -6381,14 +6302,15 @@ struct msm_vidc_buffer *msm_comm_get_buffer_using_device_planes( mutex_lock(&inst->registeredbufs.lock); found = false; list_for_each_entry(mbuf, &inst->registeredbufs.list, list) { - if (msm_comm_compare_device_planes(mbuf, type, planes)) { + if (msm_comm_compare_device_planes(inst->sid, mbuf, + type, planes)) { found = true; break; } } mutex_unlock(&inst->registeredbufs.lock); if (!found) { - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "%s: data_addr %x, extradata_addr %x not found\n", __func__, planes[0], planes[1]); mbuf = NULL; @@ -6404,7 +6326,7 @@ int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst, u32 port; if (!inst || !mbuf) { - dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", + d_vpr_e("%s: invalid params %pK %pK\n", __func__, inst, mbuf); return -EINVAL; } @@ -6428,7 +6350,7 @@ int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst, vb->planes[0].bytesused = 0; vb2_buffer_done(vb, VB2_BUF_STATE_DONE); } else { - dprintk(VIDC_ERR, "%s: port %d is not streaming\n", + s_vpr_e(inst->sid, "%s: port %d is not streaming\n", __func__, port); } mutex_unlock(&inst->bufq[port].lock); @@ -6445,7 +6367,7 @@ int msm_comm_qbuf_cache_operations(struct msm_vidc_inst *inst, bool skip; if (!inst || !mbuf) { - dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", + d_vpr_e("%s: invalid params %pK %pK\n", __func__, inst, mbuf); return -EINVAL; } @@ -6494,7 +6416,7 @@ int msm_comm_qbuf_cache_operations(struct msm_vidc_inst *inst, if (!skip) { rc = msm_smem_cache_operations(mbuf->smem[i].dma_buf, - cache_op, offset, size); + cache_op, offset, size, inst->sid); if (rc) print_vidc_buffer(VIDC_ERR, "qbuf cache ops failed", inst, mbuf); @@ -6513,7 +6435,7 @@ int msm_comm_dqbuf_cache_operations(struct msm_vidc_inst *inst, bool skip; if (!inst || !mbuf) { - dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", + d_vpr_e("%s: invalid params %pK %pK\n", __func__, inst, mbuf); return -EINVAL; } @@ -6557,7 +6479,7 @@ int msm_comm_dqbuf_cache_operations(struct msm_vidc_inst *inst, if (!skip) { rc = msm_smem_cache_operations(mbuf->smem[i].dma_buf, - cache_op, offset, size); + cache_op, offset, size, inst->sid); if (rc) print_vidc_buffer(VIDC_ERR, "dqbuf cache ops failed", inst, mbuf); @@ -6579,7 +6501,8 @@ struct msm_vidc_buffer *msm_comm_get_vidc_buffer(struct msm_vidc_inst *inst, unsigned int i; if (!inst || !vb2) { - dprintk(VIDC_ERR, "%s: invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, inst, vb2); return NULL; } @@ -6589,10 +6512,11 @@ struct msm_vidc_buffer *msm_comm_get_vidc_buffer(struct msm_vidc_inst *inst, * to be same across the processes (duplicate fds). */ dma_planes[i] = (unsigned long)msm_smem_get_dma_buf( - vb2->planes[i].m.fd); + vb2->planes[i].m.fd, inst->sid); if (!dma_planes[i]) return NULL; - msm_smem_put_dma_buf((struct dma_buf *)dma_planes[i]); + msm_smem_put_dma_buf((struct dma_buf *)dma_planes[i], + inst->sid); } mutex_lock(&inst->registeredbufs.lock); @@ -6623,7 +6547,7 @@ struct msm_vidc_buffer *msm_comm_get_vidc_buffer(struct msm_vidc_inst *inst, /* this is new vb2_buffer */ mbuf = kzalloc(sizeof(struct msm_vidc_buffer), GFP_KERNEL); if (!mbuf) { - dprintk(VIDC_ERR, "%s: alloc msm_vidc_buffer failed\n", + s_vpr_e(inst->sid, "%s: alloc msm_vidc_buffer failed\n", __func__); rc = -ENOMEM; goto exit; @@ -6645,13 +6569,13 @@ struct msm_vidc_buffer *msm_comm_get_vidc_buffer(struct msm_vidc_inst *inst, mbuf->smem[i].size = vb->planes[i].length; rc = inst->smem_ops->smem_map_dma_buf(inst, &mbuf->smem[i]); if (rc) { - dprintk(VIDC_ERR, "%s: map failed.\n", __func__); + s_vpr_e(inst->sid, "%s: map failed.\n", __func__); goto exit; } /* increase refcount as we get both fbd and rbr */ rc = inst->smem_ops->smem_map_dma_buf(inst, &mbuf->smem[i]); if (rc) { - dprintk(VIDC_ERR, "%s: map failed..\n", __func__); + s_vpr_e(inst->sid, "%s: map failed..\n", __func__); goto exit; } } @@ -6708,7 +6632,7 @@ struct msm_vidc_buffer *msm_comm_get_vidc_buffer(struct msm_vidc_inst *inst, return mbuf; exit: - dprintk(VIDC_ERR, "%s: rc %d\n", __func__, rc); + s_vpr_e(inst->sid, "%s: %d\n", __func__, rc); msm_comm_unmap_vidc_buffer(inst, mbuf); if (!found) kref_put_mbuf(mbuf); @@ -6725,7 +6649,7 @@ void msm_comm_put_vidc_buffer(struct msm_vidc_inst *inst, unsigned int i = 0; if (!inst || !mbuf) { - dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", + d_vpr_e("%s: invalid params %pK %pK\n", __func__, inst, mbuf); return; } @@ -6835,7 +6759,7 @@ void handle_release_buffer_reference(struct msm_vidc_inst *inst, */ found = false; list_for_each_entry(temp, &inst->registeredbufs.list, list) { - if (msm_comm_compare_device_plane(temp, + if (msm_comm_compare_device_plane(inst->sid, temp, OUTPUT_MPLANE, planes, 0)) { mbuf = temp; found = true; @@ -6882,12 +6806,12 @@ int msm_comm_unmap_vidc_buffer(struct msm_vidc_inst *inst, unsigned int i; if (!inst || !mbuf) { - dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", + d_vpr_e("%s: invalid params %pK %pK\n", __func__, inst, mbuf); return -EINVAL; } if (mbuf->vvb.vb2_buf.num_planes > VIDEO_MAX_PLANES) { - dprintk(VIDC_ERR, "%s: invalid num_planes %d\n", __func__, + s_vpr_e(inst->sid, "%s: invalid num_planes %d\n", __func__, mbuf->vvb.vb2_buf.num_planes); return -EINVAL; } @@ -6951,8 +6875,7 @@ struct msm_vidc_client_data *msm_comm_store_client_data( struct msm_vidc_client_data *data = NULL, *temp = NULL; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params %pK %un", - __func__, inst, itag); + d_vpr_e("%s: invalid params\n", __func__); return NULL; } @@ -6966,7 +6889,7 @@ struct msm_vidc_client_data *msm_comm_store_client_data( if (!data) { data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) { - dprintk(VIDC_ERR, "No memory avilable - tag data"); + s_vpr_e(inst->sid, "%s: No memory avilable", __func__); goto exit; } INIT_LIST_HEAD(&data->list); @@ -6996,7 +6919,7 @@ void msm_comm_fetch_client_data(struct msm_vidc_inst *inst, bool remove, bool found_itag = false, found_itag2 = false; if (!inst || !otag || !otag2) { - dprintk(VIDC_ERR, "%s: invalid params %pK %x %x\n", + d_vpr_e("%s: invalid params %pK %x %x\n", __func__, inst, otag, otag2); return; } @@ -7026,8 +6949,8 @@ void msm_comm_fetch_client_data(struct msm_vidc_inst *inst, bool remove, mutex_unlock(&inst->client_data.lock); if (!found_itag || !found_itag2) { - dprintk(VIDC_ERR, "%s: %x: client data not found - %u, %u\n", - __func__, hash32_ptr(inst->session), itag, itag2); + s_vpr_e(inst->sid, "%s: client data not found - %u, %u\n", + __func__, itag, itag2); } } @@ -7036,8 +6959,7 @@ void msm_comm_release_client_data(struct msm_vidc_inst *inst, bool remove) struct msm_vidc_client_data *temp, *next; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params %pK\n", - __func__, inst); + d_vpr_e("%s: invalid params\n", __func__); return; } @@ -7053,14 +6975,13 @@ void msm_comm_release_client_data(struct msm_vidc_inst *inst, bool remove) } void msm_comm_store_input_tag(struct msm_vidc_list *data_list, - u32 index, u32 itag, u32 itag2) + u32 index, u32 itag, u32 itag2, u32 sid) { struct msm_vidc_buf_data *pdata = NULL; bool found = false; if (!data_list) { - dprintk(VIDC_ERR, "%s: invalid params %pK\n", - __func__, data_list); + s_vpr_e(sid, "%s: invalid params\n", __func__); return; } @@ -7077,7 +6998,7 @@ void msm_comm_store_input_tag(struct msm_vidc_list *data_list, if (!found) { pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) { - dprintk(VIDC_ERR, "%s: malloc failure.\n", __func__); + s_vpr_e(sid, "%s: malloc failure.\n", __func__); goto exit; } pdata->index = index; @@ -7091,13 +7012,13 @@ void msm_comm_store_input_tag(struct msm_vidc_list *data_list, } int msm_comm_fetch_input_tag(struct msm_vidc_list *data_list, - u32 index, u32 *itag, u32 *itag2) + u32 index, u32 *itag, u32 *itag2, u32 sid) { struct msm_vidc_buf_data *pdata = NULL; int rc = 0; if (!data_list || !itag || !itag2) { - dprintk(VIDC_ERR, "%s: invalid params %pK %pK %pK\n", + s_vpr_e(sid, "%s: invalid params %pK %pK %pK\n", __func__, data_list, itag, itag2); return -EINVAL; } @@ -7123,8 +7044,7 @@ int msm_comm_release_input_tag(struct msm_vidc_inst *inst) struct msm_vidc_buf_data *pdata, *next; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params %pK\n", - __func__, inst); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -7158,7 +7078,7 @@ int msm_comm_set_color_format_constraints(struct msm_vidc_inst *inst, u32 hfi_fmt; if (!inst || !inst->core || !inst->core->device) { - dprintk(VIDC_ERR, "%s - invalid param\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } @@ -7170,16 +7090,16 @@ int msm_comm_set_color_format_constraints(struct msm_vidc_inst *inst, pconstraint = kzalloc(size, GFP_KERNEL); if (!pconstraint) { - dprintk(VIDC_ERR, "No memory cannot alloc constrain\n"); + s_vpr_e(inst->sid, "No memory cannot alloc constrain\n"); rc = -ENOMEM; goto exit; } - hfi_fmt = msm_comm_convert_color_fmt(pix_constraint->fourcc); - pconstraint->buffer_type = get_hfi_buffer(buffer_type); + hfi_fmt = msm_comm_convert_color_fmt(pix_constraint->fourcc, inst->sid); + pconstraint->buffer_type = get_hfi_buffer(buffer_type, inst->sid); pconstraint->num_planes = pix_constraint->num_planes; //set Y plan constraints - dprintk(VIDC_HIGH, "Set Y plan constraints.\n"); + s_vpr_h(inst->sid, "Set Y plan constraints.\n"); pconstraint->rg_plane_format[0].stride_multiples = VENUS_Y_STRIDE(hfi_fmt, 1); pconstraint->rg_plane_format[0].max_stride = @@ -7190,7 +7110,7 @@ int msm_comm_set_color_format_constraints(struct msm_vidc_inst *inst, pix_constraint->y_buffer_alignment; //set UV plan constraints - dprintk(VIDC_HIGH, "Set UV plan constraints.\n"); + s_vpr_h(inst->sid, "Set UV plan constraints.\n"); pconstraint->rg_plane_format[1].stride_multiples = VENUS_UV_STRIDE(hfi_fmt, 1); pconstraint->rg_plane_format[1].max_stride = @@ -7207,10 +7127,10 @@ int msm_comm_set_color_format_constraints(struct msm_vidc_inst *inst, pconstraint, size); if (rc) - dprintk(VIDC_ERR, + s_vpr_e(inst->sid, "Failed to set input color format constraint\n"); else - dprintk(VIDC_HIGH, "Set color format constraint success\n"); + s_vpr_h(inst->sid, "Set color format constraint success\n"); exit: if (!pconstraint) @@ -7274,7 +7194,7 @@ bool msm_comm_check_for_inst_overload(struct msm_vidc_core *core) if (instance_count > core->resources.max_inst_count || secure_instance_count > core->resources.max_secure_inst_count) { overload = true; - dprintk(VIDC_ERR, + d_vpr_e( "%s: inst_count:%u max_inst:%u sec_inst_count:%u max_sec_inst:%u\n", __func__, instance_count, core->resources.max_inst_count, secure_instance_count, @@ -7291,7 +7211,7 @@ int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, int buf_cnt = 1, fps, window_start; if (!inst || !inst->core || !frame_data) { - dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__); + d_vpr_e("%s: Invalid arguments\n", __func__); return -EINVAL; } @@ -7327,7 +7247,7 @@ int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, if(!temp) { pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) { - dprintk(VIDC_ERR, "%s: malloc failure.\n", __func__); + s_vpr_e(inst->sid, "%s: malloc failure.\n", __func__); mutex_unlock(&inst->window_data.lock); return -ENOMEM; } @@ -7342,7 +7262,7 @@ int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, bitrate = DIV_ROUND_UP(((u64)bitrate * 8 * fps), window_size); if (bitrate > max_br) { - dprintk(VIDC_PERF, + s_vpr_p(inst->sid, "Unsupported bitrate %u max %u, window size %u [%u,%u]", bitrate, max_br, window_size, window_start, inst->count.etb); @@ -7356,8 +7276,7 @@ void msm_comm_clear_window_data(struct msm_vidc_inst *inst) struct msm_vidc_window_data *pdata; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params %pK\n", - __func__, inst); + d_vpr_e("%s: invalid params\n", __func__); return; } @@ -7373,8 +7292,7 @@ void msm_comm_release_window_data(struct msm_vidc_inst *inst) struct msm_vidc_window_data *pdata, *next; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid params %pK\n", - __func__, inst); + d_vpr_e("%s: invalid params\n", __func__); return; } diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 45172d170cf4..882b97a93eb3 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -69,12 +69,12 @@ static inline struct v4l2_ctrl *get_ctrl(struct msm_vidc_inst *inst, if (inst->ctrls[i]->id == id) return inst->ctrls[i]; } - dprintk(VIDC_ERR, "%s: control id (%#x) not found\n", __func__, id); + s_vpr_e(inst->sid, "%s: control id (%#x) not found\n", __func__, id); MSM_VIDC_ERROR(true); return inst->ctrls[0]; } -static inline void update_ctrl(struct v4l2_ctrl *ctrl, s32 val) +static inline void update_ctrl(struct v4l2_ctrl *ctrl, s32 val, u32 sid) { switch (ctrl->type) { case V4L2_CTRL_TYPE_INTEGER: @@ -83,7 +83,7 @@ static inline void update_ctrl(struct v4l2_ctrl *ctrl, s32 val) ctrl->elems * ctrl->elem_size); break; default: - dprintk(VIDC_ERR, "unhandled control type"); + s_vpr_e(sid, "unhandled control type"); } } @@ -172,15 +172,15 @@ enum hal_buffer get_hal_buffer_type(unsigned int type, unsigned int plane_num); void put_inst(struct msm_vidc_inst *inst); struct msm_vidc_inst *get_inst(struct msm_vidc_core *core, - void *session_id); + void *inst_id); void change_inst_state(struct msm_vidc_inst *inst, enum instance_state state); struct msm_vidc_core *get_vidc_core(int core_id); const struct msm_vidc_format_desc *msm_comm_get_pixel_fmt_index( - const struct msm_vidc_format_desc fmt[], int size, int index); + const struct msm_vidc_format_desc fmt[], int size, int index, u32 sid); struct msm_vidc_format_desc *msm_comm_get_pixel_fmt_fourcc( - struct msm_vidc_format_desc fmt[], int size, int fourcc); + struct msm_vidc_format_desc fmt[], int size, int fourcc, u32 sid); struct msm_vidc_format_constraint *msm_comm_get_pixel_fmt_constraints( - struct msm_vidc_format_constraint fmt[], int size, int fourcc); + struct msm_vidc_format_constraint fmt[], int size, int fourcc, u32 sid); int msm_comm_set_color_format_constraints(struct msm_vidc_inst *inst, enum hal_buffer buffer_type, struct msm_vidc_format_constraint *pix_constraint); @@ -232,9 +232,9 @@ int msm_comm_smem_alloc(struct msm_vidc_inst *inst, size_t size, u32 align, void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *smem); int msm_comm_smem_cache_operations(struct msm_vidc_inst *inst, struct msm_smem *mem, enum smem_cache_ops cache_ops); -enum hal_video_codec get_hal_codec(int fourcc); -enum hal_domain get_hal_domain(int session_type); -int msm_comm_check_core_init(struct msm_vidc_core *core); +enum hal_video_codec get_hal_codec(int fourcc, u32 sid); +enum hal_domain get_hal_domain(int session_type, u32 sid); +int msm_comm_check_core_init(struct msm_vidc_core *core, u32 sid); int msm_comm_get_inst_load(struct msm_vidc_inst *inst, enum load_calc_quirks quirks); int msm_comm_get_inst_load_per_core(struct msm_vidc_inst *inst, @@ -253,15 +253,15 @@ int msm_comm_ctrl_deinit(struct msm_vidc_inst *inst); void msm_comm_cleanup_internal_buffers(struct msm_vidc_inst *inst); bool msm_comm_turbo_session(struct msm_vidc_inst *inst); void msm_comm_print_inst_info(struct msm_vidc_inst *inst); -int msm_comm_v4l2_to_hfi(int id, int value); -int msm_comm_hfi_to_v4l2(int id, int value); -int msm_comm_get_v4l2_profile(int fourcc, int profile); -int msm_comm_get_v4l2_level(int fourcc, int level); +int msm_comm_v4l2_to_hfi(int id, int value, u32 sid); +int msm_comm_hfi_to_v4l2(int id, int value, u32 sid); +int msm_comm_get_v4l2_profile(int fourcc, int profile, u32 sid); +int msm_comm_get_v4l2_level(int fourcc, int level, u32 sid); int msm_comm_session_continue(void *instance); int msm_vidc_send_pending_eos_buffers(struct msm_vidc_inst *inst); enum hal_uncompressed_format msm_comm_get_hal_uncompressed(int fourcc); -u32 msm_comm_get_hfi_uncompressed(int fourcc); -u32 msm_comm_convert_color_fmt(u32 v4l2_fmt); +u32 msm_comm_get_hfi_uncompressed(int fourcc, u32 sid); +u32 msm_comm_convert_color_fmt(u32 v4l2_fmt, u32 sid); struct vb2_buffer *msm_comm_get_vb_using_vidc_buffer( struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); struct msm_vidc_buffer *msm_comm_get_buffer_using_device_planes( @@ -286,9 +286,9 @@ bool msm_comm_compare_vb2_plane(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf, struct vb2_buffer *vb2, u32 i); bool msm_comm_compare_vb2_planes(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf, struct vb2_buffer *vb2); -bool msm_comm_compare_device_plane(struct msm_vidc_buffer *mbuf, +bool msm_comm_compare_device_plane(u32 sid, struct msm_vidc_buffer *mbuf, u32 type, u32 *planes, u32 i); -bool msm_comm_compare_device_planes(struct msm_vidc_buffer *mbuf, +bool msm_comm_compare_device_planes(u32 sid, struct msm_vidc_buffer *mbuf, u32 type, u32 *planes); int msm_comm_qbuf_cache_operations(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); @@ -296,16 +296,14 @@ int msm_comm_dqbuf_cache_operations(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); void print_vidc_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); -void print_vb2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, +void print_vb2_buffer(const char *str, struct msm_vidc_inst *inst, struct vb2_buffer *vb2); -void print_v4l2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, - struct v4l2_buffer *v4l2); void kref_put_mbuf(struct msm_vidc_buffer *mbuf); bool kref_get_mbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); void msm_comm_store_input_tag(struct msm_vidc_list *data_list, - u32 index, u32 itag, u32 itag2); + u32 index, u32 itag, u32 itag2, u32 sid); int msm_comm_fetch_input_tag(struct msm_vidc_list *data_list, - u32 index, u32 *itag, u32 *itag2); + u32 index, u32 *itag, u32 *itag2, u32 sid); int msm_comm_release_input_tag(struct msm_vidc_inst *inst); struct msm_vidc_client_data *msm_comm_store_client_data( struct msm_vidc_inst *inst, u32 itag); diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index 7312b7dbb11f..14492f3610cc 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -58,13 +58,13 @@ static ssize_t core_info_read(struct file *file, char __user *buf, ssize_t len = 0; if (!core || !core->device) { - dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core); + d_vpr_e("%s: invalid params %pK\n", __func__, core); return 0; } dbuf = kzalloc(MAX_DBG_BUF_SIZE, GFP_KERNEL); if (!dbuf) { - dprintk(VIDC_ERR, "%s: Allocation failed!\n", __func__); + d_vpr_e("%s: Allocation failed!\n", __func__); return -ENOMEM; } cur = dbuf; @@ -77,7 +77,7 @@ static ssize_t core_info_read(struct file *file, char __user *buf, cur += write_str(cur, end - cur, "Core state: %d\n", core->state); rc = call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data, &fw_info); if (rc) { - dprintk(VIDC_ERR, "Failed to read FW info\n"); + d_vpr_e("Failed to read FW info\n"); goto err_fw_info; } @@ -130,14 +130,14 @@ static ssize_t trigger_ssr_write(struct file *filp, const char __user *buf, size = count; if (copy_from_user(kbuf, buf, size)) { - dprintk(VIDC_ERR, "%s User memory fault\n", __func__); + d_vpr_e("%s: User memory fault\n", __func__); rc = -EFAULT; goto exit; } rc = kstrtoul(kbuf, 0, &ssr_trigger_val); if (rc) { - dprintk(VIDC_ERR, "returning error err %d\n", rc); + d_vpr_e("returning error err %d\n", rc); rc = -EINVAL; } else { msm_vidc_trigger_ssr(core, ssr_trigger_val); @@ -161,28 +161,27 @@ static ssize_t debug_level_write(struct file *filp, const char __user *buf, /* filter partial writes and invalid commands */ if (*ppos != 0 || count >= sizeof(kbuf) || count == 0) { - dprintk(VIDC_ERR, "returning error - pos %d, count %d\n", - *ppos, count); + d_vpr_e("returning error - pos %d, count %d\n", *ppos, count); rc = -EINVAL; } rc = simple_write_to_buffer(kbuf, sizeof(kbuf) - 1, ppos, buf, count); if (rc < 0) { - dprintk(VIDC_ERR, "%s User memory fault\n", __func__); + d_vpr_e("%s: User memory fault\n", __func__); rc = -EFAULT; goto exit; } rc = kstrtoint(kbuf, 0, &msm_vidc_debug); if (rc) { - dprintk(VIDC_ERR, "returning error err %d\n", rc); + d_vpr_e("returning error err %d\n", rc); rc = -EINVAL; goto exit; } core->resources.msm_vidc_hw_rsp_timeout = ((msm_vidc_debug & 0xFF) > (VIDC_ERR | VIDC_HIGH)) ? 1500 : 1000; rc = count; - dprintk(VIDC_HIGH, "debug timeout updated to - %d\n", + d_vpr_h("debug timeout updated to - %d\n", core->resources.msm_vidc_hw_rsp_timeout); exit: @@ -220,7 +219,7 @@ struct dentry *msm_vidc_debugfs_init_drv(void) struct dentry *f = debugfs_create_##__type(__name, 0644, \ dir, __value); \ if (IS_ERR_OR_NULL(f)) { \ - dprintk(VIDC_ERR, "Failed creating debugfs file '%pd/%s'\n", \ + d_vpr_e("Failed creating debugfs file '%pd/%s'\n", \ dir, __name); \ f = NULL; \ } \ @@ -261,28 +260,28 @@ struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core, char debugfs_name[MAX_DEBUGFS_NAME]; if (!core) { - dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core); + d_vpr_e("%s: invalid params\n", __func__); goto failed_create_dir; } snprintf(debugfs_name, MAX_DEBUGFS_NAME, "core%d", core->id); dir = debugfs_create_dir(debugfs_name, parent); if (!dir) { - dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n"); + d_vpr_e("Failed to create debugfs for msm_vidc\n"); goto failed_create_dir; } if (!debugfs_create_file("info", 0444, dir, core, &core_info_fops)) { - dprintk(VIDC_ERR, "debugfs_create_file: fail\n"); + d_vpr_e("debugfs_create_file: fail\n"); goto failed_create_dir; } if (!debugfs_create_file("trigger_ssr", 0200, dir, core, &ssr_fops)) { - dprintk(VIDC_ERR, "debugfs_create_file: fail\n"); + d_vpr_e("debugfs_create_file: fail\n"); goto failed_create_dir; } if (!debugfs_create_file("debug_level", 0644, parent, core, &debug_level_fops)) { - dprintk(VIDC_ERR, "debugfs_create_file: fail\n"); + d_vpr_e("debugfs_create_file: fail\n"); goto failed_create_dir; } failed_create_dir: @@ -291,7 +290,7 @@ struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core, static int inst_info_open(struct inode *inode, struct file *file) { - dprintk(VIDC_LOW, "Open inode ptr: %pK\n", inode->i_private); + d_vpr_l("Open inode ptr: %pK\n", inode->i_private); file->private_data = inode->i_private; return 0; } @@ -303,7 +302,7 @@ static int publish_unreleased_reference(struct msm_vidc_inst *inst, char *cur = *dbuf; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid param\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -350,7 +349,7 @@ static ssize_t inst_info_read(struct file *file, char __user *buf, struct v4l2_format *f; if (!idata || !idata->core || !idata->inst) { - dprintk(VIDC_ERR, "%s: Invalid params\n", __func__); + d_vpr_e("%s: invalid params %pK\n", __func__, idata); return 0; } @@ -367,13 +366,13 @@ static ssize_t inst_info_read(struct file *file, char __user *buf, mutex_unlock(&core->lock); if (!inst) { - dprintk(VIDC_ERR, "%s: Instance has become obsolete", __func__); + d_vpr_e("%s: Instance has become obsolete", __func__); return 0; } dbuf = kzalloc(MAX_DBG_BUF_SIZE, GFP_KERNEL); if (!dbuf) { - dprintk(VIDC_ERR, "%s: Allocation failed!\n", __func__); + s_vpr_e(inst->sid, "%s: Allocation failed!\n", __func__); len = -ENOMEM; goto failed_alloc; } @@ -453,7 +452,7 @@ static ssize_t inst_info_read(struct file *file, char __user *buf, static int inst_info_release(struct inode *inode, struct file *file) { - dprintk(VIDC_LOW, "Release inode ptr: %pK\n", inode->i_private); + d_vpr_l("Release inode ptr: %pK\n", inode->i_private); file->private_data = NULL; return 0; } @@ -472,14 +471,14 @@ struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst, struct core_inst_pair *idata = NULL; if (!inst) { - dprintk(VIDC_ERR, "Invalid params, inst: %pK\n", inst); + d_vpr_e("%s: invalid params\n", __func__); goto exit; } snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%p", inst); idata = kzalloc(sizeof(struct core_inst_pair), GFP_KERNEL); if (!idata) { - dprintk(VIDC_ERR, "%s: Allocation failed!\n", __func__); + s_vpr_e(inst->sid, "%s: Allocation failed!\n", __func__); goto exit; } @@ -488,14 +487,14 @@ struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst, dir = debugfs_create_dir(debugfs_name, parent); if (!dir) { - dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n"); + s_vpr_e(inst->sid, "Failed to create debugfs for msm_vidc\n"); goto failed_create_dir; } info = debugfs_create_file("info", 0444, dir, idata, &inst_info_fops); if (!info) { - dprintk(VIDC_ERR, "debugfs_create_file: fail\n"); + s_vpr_e(inst->sid, "debugfs_create_file: fail\n"); goto failed_create_file; } @@ -521,7 +520,7 @@ void msm_vidc_debugfs_deinit_inst(struct msm_vidc_inst *inst) dentry = inst->debugfs_root; if (dentry->d_inode) { - dprintk(VIDC_LOW, "Destroy %pK\n", dentry->d_inode->i_private); + s_vpr_l(inst->sid, "Destroy %pK\n", dentry->d_inode->i_private); kfree(dentry->d_inode->i_private); dentry->d_inode->i_private = NULL; } @@ -553,10 +552,10 @@ void msm_vidc_debugfs_update(struct msm_vidc_inst *inst, inst->count.ftb, inst->count.fbd); if (inst->count.ebd && inst->count.ebd == inst->count.etb) { toc(inst, FRAME_PROCESSING); - dprintk(VIDC_PERF, "EBD: FW needs input buffers\n"); + s_vpr_p(inst->sid, "EBD: FW needs input buffers\n"); } if (inst->count.ftb == inst->count.fbd) - dprintk(VIDC_PERF, "EBD: FW needs output buffers\n"); + s_vpr_p(inst->sid, "EBD: FW needs output buffers\n"); break; case MSM_VIDC_DEBUGFS_EVENT_FTB: { inst->count.ftb++; @@ -578,13 +577,13 @@ void msm_vidc_debugfs_update(struct msm_vidc_inst *inst, if (inst->count.fbd && inst->count.fbd == inst->count.ftb) { toc(inst, FRAME_PROCESSING); - dprintk(VIDC_PERF, "FBD: FW needs output buffers\n"); + s_vpr_p(inst->sid, "FBD: FW needs output buffers\n"); } if (inst->count.etb == inst->count.ebd) - dprintk(VIDC_PERF, "FBD: FW needs input buffers\n"); + s_vpr_p(inst->sid, "FBD: FW needs input buffers\n"); break; default: - dprintk(VIDC_ERR, "Invalid state in debugfs: %d\n", e); + s_vpr_e(inst->sid, "Invalid state in debugfs: %d\n", e); break; } } diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index a28151c2c430..ddbc9d60b948 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -23,7 +23,8 @@ #define VIDC_DBG_SESSION_RATELIMIT_INTERVAL (1 * HZ) #define VIDC_DBG_SESSION_RATELIMIT_BURST 6 -#define VIDC_DBG_TAG VIDC_DBG_LABEL ": %4s: " +#define VIDC_DBG_TAG VIDC_DBG_LABEL ": %6s: %8x: " +#define DEFAULT_SID ((u32)-1) /* To enable messages OR these values and * echo the result to debugfs file. @@ -68,7 +69,7 @@ extern bool msm_vidc_syscache_disable; extern bool msm_vidc_lossless_encode; extern bool msm_vidc_cvp_usage; -#define dprintk(__level, __fmt, ...) \ +#define dprintk(__level, sid, __fmt, ...) \ do { \ if (msm_vidc_debug & __level) { \ if (msm_vidc_debug & VIDC_FTRACE) { \ @@ -77,6 +78,7 @@ extern bool msm_vidc_cvp_usage; MAX_TRACER_LOG_LENGTH, \ VIDC_DBG_TAG __fmt, \ get_debug_level_str(__level), \ + sid, \ ##__VA_ARGS__); \ trace_msm_vidc_printf(trace_logbuf, \ log_length); \ @@ -84,11 +86,34 @@ extern bool msm_vidc_cvp_usage; if (msm_vidc_debug & VIDC_PRINTK) { \ pr_info(VIDC_DBG_TAG __fmt, \ get_debug_level_str(__level), \ + sid, \ ##__VA_ARGS__); \ } \ } \ } while (0) +#define s_vpr_e(sid, __fmt, ...) dprintk(VIDC_ERR, sid, __fmt, ##__VA_ARGS__) +#define s_vpr_h(sid, __fmt, ...) dprintk(VIDC_HIGH, sid, __fmt, ##__VA_ARGS__) +#define s_vpr_l(sid, __fmt, ...) dprintk(VIDC_LOW, sid, __fmt, ##__VA_ARGS__) +#define s_vpr_p(sid, __fmt, ...) dprintk(VIDC_PERF, sid, __fmt, ##__VA_ARGS__) +#define s_vpr_t(sid, __fmt, ...) dprintk(VIDC_PKT, sid, __fmt, ##__VA_ARGS__) +#define s_vpr_b(sid, __fmt, ...) dprintk(VIDC_BUS, sid, __fmt, ##__VA_ARGS__) +#define s_vpr_hp(sid, __fmt, ...) \ + dprintk(VIDC_HIGH|VIDC_PERF, sid, __fmt, ##__VA_ARGS__) + +#define d_vpr_e(__fmt, ...) \ + dprintk(VIDC_ERR, DEFAULT_SID, __fmt, ##__VA_ARGS__) +#define d_vpr_h(__fmt, ...) \ + dprintk(VIDC_HIGH, DEFAULT_SID, __fmt, ##__VA_ARGS__) +#define d_vpr_l(__fmt, ...) \ + dprintk(VIDC_LOW, DEFAULT_SID, __fmt, ##__VA_ARGS__) +#define d_vpr_p(__fmt, ...) \ + dprintk(VIDC_PERF, DEFAULT_SID, __fmt, ##__VA_ARGS__) +#define d_vpr_t(__fmt, ...) \ + dprintk(VIDC_PKT, DEFAULT_SID, __fmt, ##__VA_ARGS__) +#define d_vpr_b(__fmt, ...) \ + dprintk(VIDC_BUS, DEFAULT_SID, __fmt, ##__VA_ARGS__) + #define dprintk_firmware(__level, __fmt, ...) \ do { \ if (__level & FW_FTRACE) { \ @@ -111,13 +136,13 @@ extern bool msm_vidc_cvp_usage; #define dprintk_ratelimit(__level, __fmt, arg...) \ do { \ if (msm_vidc_check_ratelimit()) { \ - dprintk(__level, __fmt, arg); \ + dprintk(__level, DEFAULT_SID, __fmt, arg); \ } \ } while (0) #define MSM_VIDC_ERROR(value) \ do { if (value) \ - dprintk(VIDC_ERR, "BugOn"); \ + d_vpr_e("BugOn"); \ BUG_ON(value); \ } while (0) @@ -136,20 +161,20 @@ static inline char *get_debug_level_str(int level) { switch (level) { case VIDC_ERR: - return "err"; + return "err "; case VIDC_HIGH|VIDC_PERF: case VIDC_HIGH: return "high"; case VIDC_LOW: - return "low"; + return "low "; case VIDC_PERF: return "perf"; case VIDC_PKT: - return "pkt"; + return "pkt "; case VIDC_BUS: - return "bus"; + return "bus "; default: - return "???"; + return "????"; } } @@ -192,15 +217,14 @@ static inline void show_stats(struct msm_vidc_inst *i) if (i->debug.pdata[x].name[0] && (msm_vidc_debug & VIDC_PERF)) { if (i->debug.samples) { - dprintk(VIDC_PERF, "%s averaged %d ms/sample\n", + s_vpr_p(i->sid, "%s averaged %d ms/sample\n", i->debug.pdata[x].name, i->debug.pdata[x].cumulative / i->debug.samples); } - dprintk(VIDC_PERF, "%s Samples: %d\n", - i->debug.pdata[x].name, - i->debug.samples); + s_vpr_p(i->sid, "%s Samples: %d\n", + i->debug.pdata[x].name, i->debug.samples); } } } diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 822d9c392d67..610df5a0c1a3 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -419,6 +419,7 @@ struct clock_data { }; struct vidc_bus_vote_data { + u32 sid; enum hal_domain domain; enum hal_video_codec codec; enum hal_uncompressed_format color_formats[2]; @@ -509,6 +510,7 @@ struct msm_vidc_inst { struct msm_vidc_core *core; enum session_type session_type; void *session; + u32 sid; struct msm_cvp_external *cvp; struct session_prop prop; enum instance_state state; @@ -620,18 +622,19 @@ struct msm_vidc_cvp_buffer { void msm_comm_handle_thermal_event(void); int msm_smem_alloc(size_t size, u32 align, u32 flags, enum hal_buffer buffer_type, int map_kernel, - void *res, u32 session_type, struct msm_smem *smem); -int msm_smem_free(struct msm_smem *smem); + void *res, u32 session_type, struct msm_smem *smem, u32 sid); +int msm_smem_free(struct msm_smem *smem, u32 sid); struct context_bank_info *msm_smem_get_context_bank(u32 session_type, bool is_secure, struct msm_vidc_platform_resources *res, - enum hal_buffer buffer_type); + enum hal_buffer buffer_type, u32 sid); int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem); int msm_smem_unmap_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem); -struct dma_buf *msm_smem_get_dma_buf(int fd); -void msm_smem_put_dma_buf(void *dma_buf); +struct dma_buf *msm_smem_get_dma_buf(int fd, u32 sid); +void msm_smem_put_dma_buf(void *dma_buf, u32 sid); int msm_smem_cache_operations(struct dma_buf *dbuf, - enum smem_cache_ops cache_op, unsigned long offset, unsigned long size); + enum smem_cache_ops cache_op, unsigned long offset, + unsigned long size, u32 sid); void msm_vidc_fw_unload_handler(struct work_struct *work); void msm_vidc_ssr_handler(struct work_struct *work); /* diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 0fb3af904f17..29ca3b195f73 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1126,8 +1126,7 @@ static int msm_vidc_read_efuse( base = devm_ioremap(dev, (efuse_data[i]).start_address, (efuse_data[i]).size); if (!base) { - dprintk(VIDC_ERR, - "failed efuse ioremap: res->start %#x, size %d\n", + d_vpr_e("failed efuse: start %#x, size %d\n", (efuse_data[i]).start_address, (efuse_data[i]).size); return -EINVAL; @@ -1138,8 +1137,7 @@ static int msm_vidc_read_efuse( data->sku_version = (efuse & (efuse_data[i]).mask) >> (efuse_data[i]).shift; - dprintk(VIDC_HIGH, - "efuse 0x%x, platform version 0x%x\n", + d_vpr_h("efuse 0x%x, platform version 0x%x\n", efuse, data->sku_version); devm_iounmap(dev, base); @@ -1186,10 +1184,9 @@ void *vidc_get_drv_data(struct device *dev) } else if (!strcmp(match->compatible, "qcom,kona-vidc")) { ddr_type = of_fdt_get_ddrtype(); if (ddr_type == -ENOENT) { - dprintk(VIDC_ERR, - "Failed to get ddr type, use LPDDR5\n"); + d_vpr_e("Failed to get ddr type, use LPDDR5\n"); } - dprintk(VIDC_HIGH, "DDR Type %x\n", ddr_type); + d_vpr_h("DDR Type %x\n", ddr_type); if (driver_data->ubwc_config && (ddr_type == DDR_TYPE_LPDDR4 || diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 067637053422..8ecadde92f6e 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -33,15 +33,13 @@ static size_t get_u32_array_num_elements(struct device_node *np, size_t num_elements = 0; if (!of_get_property(np, name, &len)) { - dprintk(VIDC_ERR, "Failed to read %s from device tree\n", - name); + d_vpr_e("Failed to read %s from device tree\n", name); goto fail_read; } num_elements = len / sizeof(u32); if (num_elements <= 0) { - dprintk(VIDC_ERR, "%s not specified in device tree\n", - name); + d_vpr_e("%s not specified in device tree\n", name); goto fail_read; } return num_elements; @@ -143,7 +141,7 @@ static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res) * qcom,reg-presets is an optional property. It likely won't be * present if we don't have any register settings to program */ - dprintk(VIDC_HIGH, "qcom,reg-presets not found\n"); + d_vpr_h("reg-presets not found\n"); return 0; } @@ -153,29 +151,26 @@ static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res) reg_set->count /= sizeof(*reg_set->reg_tbl) / sizeof(u32); if (!reg_set->count) { - dprintk(VIDC_HIGH, "no elements in reg set\n"); + d_vpr_h("no elements in reg set\n"); return rc; } reg_set->reg_tbl = devm_kzalloc(&pdev->dev, reg_set->count * sizeof(*(reg_set->reg_tbl)), GFP_KERNEL); if (!reg_set->reg_tbl) { - dprintk(VIDC_ERR, "%s Failed to alloc register table\n", - __func__); + d_vpr_e("%s: Failed to alloc register table\n", __func__); return -ENOMEM; } if (of_property_read_u32_array(pdev->dev.of_node, "qcom,reg-presets", (u32 *)reg_set->reg_tbl, reg_set->count * 2)) { - dprintk(VIDC_ERR, "Failed to read register table\n"); + d_vpr_e("Failed to read register table\n"); msm_vidc_free_reg_table(res); return -EINVAL; } for (i = 0; i < reg_set->count; i++) { - dprintk(VIDC_HIGH, - "reg = %x, value = %x\n", - reg_set->reg_tbl[i].reg, - reg_set->reg_tbl[i].value + d_vpr_h("reg = %x, value = %x\n", + reg_set->reg_tbl[i].reg, reg_set->reg_tbl[i].value ); } return rc; @@ -192,7 +187,7 @@ static int msm_vidc_load_qdss_table(struct msm_vidc_platform_resources *res) * qcom,qdss-presets is an optional property. It likely won't be * present if we don't have any register settings to program */ - dprintk(VIDC_HIGH, "qcom,qdss-presets not found\n"); + d_vpr_h("qdss-presets not found\n"); return rc; } @@ -202,7 +197,7 @@ static int msm_vidc_load_qdss_table(struct msm_vidc_platform_resources *res) qdss_addr_set->count /= sizeof(*qdss_addr_set->addr_tbl) / sizeof(u32); if (!qdss_addr_set->count) { - dprintk(VIDC_HIGH, "no elements in qdss reg set\n"); + d_vpr_h("no elements in qdss reg set\n"); return rc; } @@ -210,8 +205,7 @@ static int msm_vidc_load_qdss_table(struct msm_vidc_platform_resources *res) qdss_addr_set->count * sizeof(*qdss_addr_set->addr_tbl), GFP_KERNEL); if (!qdss_addr_set->addr_tbl) { - dprintk(VIDC_ERR, "%s Failed to alloc register table\n", - __func__); + d_vpr_e("%s: Failed to alloc register table\n", __func__); rc = -ENOMEM; goto err_qdss_addr_tbl; } @@ -219,14 +213,14 @@ static int msm_vidc_load_qdss_table(struct msm_vidc_platform_resources *res) rc = of_property_read_u32_array(pdev->dev.of_node, "qcom,qdss-presets", (u32 *)qdss_addr_set->addr_tbl, qdss_addr_set->count * 2); if (rc) { - dprintk(VIDC_ERR, "Failed to read qdss address table\n"); + d_vpr_e("Failed to read qdss address table\n"); msm_vidc_free_qdss_addr_table(res); rc = -EINVAL; goto err_qdss_addr_tbl; } for (i = 0; i < qdss_addr_set->count; i++) { - dprintk(VIDC_HIGH, "qdss addr = %x, value = %x\n", + d_vpr_h("qdss addr = %x, value = %x\n", qdss_addr_set->addr_tbl[i].start, qdss_addr_set->addr_tbl[i].size); } @@ -243,21 +237,20 @@ static int msm_vidc_load_subcache_info(struct msm_vidc_platform_resources *res) num_subcaches = of_property_count_strings(pdev->dev.of_node, "cache-slice-names"); if (num_subcaches <= 0) { - dprintk(VIDC_HIGH, "No subcaches found\n"); + d_vpr_h("No subcaches found\n"); goto err_load_subcache_table_fail; } subcaches->subcache_tbl = devm_kzalloc(&pdev->dev, sizeof(*subcaches->subcache_tbl) * num_subcaches, GFP_KERNEL); if (!subcaches->subcache_tbl) { - dprintk(VIDC_ERR, - "Failed to allocate memory for subcache tbl\n"); + d_vpr_e("Failed to allocate memory for subcache tbl\n"); rc = -ENOMEM; goto err_load_subcache_table_fail; } subcaches->count = num_subcaches; - dprintk(VIDC_HIGH, "Found %d subcaches\n", num_subcaches); + d_vpr_h("Found %d subcaches\n", num_subcaches); for (c = 0; c < num_subcaches; ++c) { struct subcache_info *vsc = &res->subcache_set.subcache_tbl[c]; @@ -303,26 +296,26 @@ int msm_vidc_load_u32_table(struct platform_device *pdev, u32 *ptbl = NULL; if (!of_find_property(of_node, table_name, NULL)) { - dprintk(VIDC_HIGH, "%s not found\n", table_name); + d_vpr_h("%s not found\n", table_name); return 0; } num_elemts = get_u32_array_num_elements(of_node, table_name); if (!num_elemts) { - dprintk(VIDC_ERR, "no elements in %s\n", table_name); + d_vpr_e("no elements in %s\n", table_name); return 0; } num_elemts /= struct_size / sizeof(u32); ptbl = devm_kzalloc(&pdev->dev, num_elemts * struct_size, GFP_KERNEL); if (!ptbl) { - dprintk(VIDC_ERR, "Failed to alloc table %s\n", table_name); + d_vpr_e("Failed to alloc table %s\n", table_name); return -ENOMEM; } if (of_property_read_u32_array(of_node, table_name, ptbl, num_elemts * struct_size / sizeof(u32))) { - dprintk(VIDC_ERR, "Failed to read %s\n", table_name); + d_vpr_e("Failed to read %s\n", table_name); return -EINVAL; } @@ -350,7 +343,7 @@ static int msm_vidc_load_allowed_clocks_table( if (!of_find_property(pdev->dev.of_node, "qcom,allowed-clock-rates", NULL)) { - dprintk(VIDC_HIGH, "qcom,allowed-clock-rates not found\n"); + d_vpr_h("allowed-clock-rates not found\n"); return 0; } @@ -360,8 +353,7 @@ static int msm_vidc_load_allowed_clocks_table( (u32 **)&res->allowed_clks_tbl, &res->allowed_clks_tbl_size); if (rc) { - dprintk(VIDC_ERR, - "%s: failed to read allowed clocks table\n", __func__); + d_vpr_e("%s: failed to read allowed clocks table\n", __func__); return rc; } @@ -391,7 +383,7 @@ static int msm_vidc_populate_bus(struct device *dev, temp_table = krealloc(buses->bus_tbl, sizeof(*temp_table) * (buses->count + 1), GFP_KERNEL); if (!temp_table) { - dprintk(VIDC_ERR, "%s: Failed to allocate memory", __func__); + d_vpr_e("%s: Failed to allocate memory", __func__); rc = -ENOMEM; goto err_bus; } @@ -403,7 +395,7 @@ static int msm_vidc_populate_bus(struct device *dev, rc = of_property_read_string(dev->of_node, "label", &temp_name); if (rc) { - dprintk(VIDC_ERR, "'label' not found in node\n"); + d_vpr_e("'label' not found in node\n"); goto err_bus; } /* need a non-const version of name, hence copying it over */ @@ -416,13 +408,13 @@ static int msm_vidc_populate_bus(struct device *dev, rc = of_property_read_u32(dev->of_node, "qcom,bus-master", &bus->master); if (rc) { - dprintk(VIDC_ERR, "'qcom,bus-master' not found in node\n"); + d_vpr_e("'bus-master' not found in node\n"); goto err_bus; } rc = of_property_read_u32(dev->of_node, "qcom,bus-slave", &bus->slave); if (rc) { - dprintk(VIDC_ERR, "'qcom,bus-slave' not found in node\n"); + d_vpr_e("'bus-slave' not found in node\n"); goto err_bus; } @@ -436,8 +428,7 @@ static int msm_vidc_populate_bus(struct device *dev, range, ARRAY_SIZE(range)); if (rc) { rc = 0; - dprintk(VIDC_HIGH, - "'qcom,range' not found defaulting to <0 INT_MAX>\n"); + d_vpr_h("'bus-range' not found defaulting to <0 INT_MAX>\n"); range[0] = 0; range[1] = INT_MAX; } @@ -447,7 +438,7 @@ static int msm_vidc_populate_bus(struct device *dev, buses->count++; bus->dev = dev; - dprintk(VIDC_HIGH, "Found bus %s [%d->%d] with mode %s\n", + d_vpr_h("Found bus %s [%d->%d] with mode %s\n", bus->name, bus->master, bus->slave, bus->mode); err_bus: return rc; @@ -467,7 +458,7 @@ static int msm_vidc_load_buffer_usage_table( * likely won't be present if the core doesn't support content * protection */ - dprintk(VIDC_HIGH, "buffer-type-tz-usage-table not found\n"); + d_vpr_h("buffer-type-tz-usage-table not found\n"); return 0; } @@ -476,7 +467,7 @@ static int msm_vidc_load_buffer_usage_table( buffer_usage_set->count /= sizeof(*buffer_usage_set->buffer_usage_tbl) / sizeof(u32); if (!buffer_usage_set->count) { - dprintk(VIDC_HIGH, "no elements in buffer usage set\n"); + d_vpr_h("no elements in buffer usage set\n"); return 0; } @@ -485,7 +476,7 @@ static int msm_vidc_load_buffer_usage_table( sizeof(*buffer_usage_set->buffer_usage_tbl), GFP_KERNEL); if (!buffer_usage_set->buffer_usage_tbl) { - dprintk(VIDC_ERR, "%s Failed to alloc buffer usage table\n", + d_vpr_e("%s: Failed to alloc buffer usage table\n", __func__); rc = -ENOMEM; goto err_load_buf_usage; @@ -497,7 +488,7 @@ static int msm_vidc_load_buffer_usage_table( buffer_usage_set->count * sizeof(*buffer_usage_set->buffer_usage_tbl) / sizeof(u32)); if (rc) { - dprintk(VIDC_ERR, "Failed to read buffer usage table\n"); + d_vpr_e("Failed to read buffer usage table\n"); goto err_load_buf_usage; } @@ -542,8 +533,7 @@ static int msm_vidc_load_regulator_table( if (!regulators->regulator_tbl) { rc = -ENOMEM; - dprintk(VIDC_ERR, - "Failed to alloc memory for regulator table\n"); + d_vpr_e("Failed to alloc memory for regulator table\n"); goto err_reg_tbl_alloc; } @@ -565,8 +555,8 @@ static int msm_vidc_load_regulator_table( regulator_node = of_parse_phandle(domains_parent_node, domains_property->name, 0); if (IS_ERR(regulator_node)) { - dprintk(VIDC_ERR, "%s is not a phandle\n", - domains_property->name); + d_vpr_e("%s is not a phandle\n", + domains_property->name); continue; } regulators->count++; @@ -577,8 +567,7 @@ static int msm_vidc_load_regulator_table( (supply - domains_property->name) + 1, GFP_KERNEL); if (!rinfo->name) { rc = -ENOMEM; - dprintk(VIDC_ERR, - "Failed to alloc memory for regulator name\n"); + d_vpr_e("Failed to alloc memory for regulator name\n"); goto err_reg_name_alloc; } strlcpy(rinfo->name, domains_property->name, @@ -587,13 +576,13 @@ static int msm_vidc_load_regulator_table( rinfo->has_hw_power_collapse = of_property_read_bool( regulator_node, "qcom,support-hw-trigger"); - dprintk(VIDC_HIGH, "Found regulator %s: h/w collapse = %s\n", + d_vpr_h("Found regulator %s: h/w collapse = %s\n", rinfo->name, rinfo->has_hw_power_collapse ? "yes" : "no"); } if (!regulators->count) - dprintk(VIDC_HIGH, "No regulators found"); + d_vpr_h("No regulators found"); return 0; @@ -614,7 +603,7 @@ static int msm_vidc_load_clock_table( num_clocks = of_property_count_strings(pdev->dev.of_node, "clock-names"); if (num_clocks <= 0) { - dprintk(VIDC_HIGH, "No clocks found\n"); + d_vpr_h("No clocks found\n"); clocks->count = 0; rc = 0; goto err_load_clk_table_fail; @@ -623,7 +612,7 @@ static int msm_vidc_load_clock_table( clock_props = devm_kzalloc(&pdev->dev, num_clocks * sizeof(*clock_props), GFP_KERNEL); if (!clock_props) { - dprintk(VIDC_ERR, "No memory to read clock properties\n"); + d_vpr_e("No memory to read clock properties\n"); rc = -ENOMEM; goto err_load_clk_table_fail; } @@ -632,20 +621,20 @@ static int msm_vidc_load_clock_table( "qcom,clock-configs", clock_props, num_clocks); if (rc) { - dprintk(VIDC_ERR, "Failed to read clock properties: %d\n", rc); + d_vpr_e("Failed to read clock properties: %d\n", rc); goto err_load_clk_prop_fail; } clocks->clock_tbl = devm_kzalloc(&pdev->dev, sizeof(*clocks->clock_tbl) * num_clocks, GFP_KERNEL); if (!clocks->clock_tbl) { - dprintk(VIDC_ERR, "Failed to allocate memory for clock tbl\n"); + d_vpr_e("Failed to allocate memory for clock tbl\n"); rc = -ENOMEM; goto err_load_clk_prop_fail; } clocks->count = num_clocks; - dprintk(VIDC_HIGH, "Found %d clocks\n", num_clocks); + d_vpr_h("Found %d clocks\n", num_clocks); for (c = 0; c < num_clocks; ++c) { struct clock_info *vc = &res->clock_set.clock_tbl[c]; @@ -664,7 +653,7 @@ static int msm_vidc_load_clock_table( else vc->has_mem_retention = false; - dprintk(VIDC_HIGH, "Found clock %s: scale-able = %s\n", vc->name, + d_vpr_h("Found clock %s: scale-able = %s\n", vc->name, vc->has_scaling ? "yes" : "no"); } @@ -686,7 +675,7 @@ static int msm_vidc_load_reset_table( num_clocks = of_property_count_strings(pdev->dev.of_node, "reset-names"); if (num_clocks <= 0) { - dprintk(VIDC_HIGH, "No reset clocks found\n"); + d_vpr_h("No reset clocks found\n"); rst->count = 0; return 0; } @@ -697,7 +686,7 @@ static int msm_vidc_load_reset_table( return -ENOMEM; rst->count = num_clocks; - dprintk(VIDC_HIGH, "Found %d reset clocks\n", num_clocks); + d_vpr_h("Found %d reset clocks\n", num_clocks); for (c = 0; c < num_clocks; ++c) { struct reset_info *rc = &res->reset_set.reset_tbl[c]; @@ -719,13 +708,12 @@ static int msm_decide_dt_node( rc = of_property_read_u32(pdev->dev.of_node, "sku-index", &sku_index); if (rc) { - dprintk(VIDC_HIGH, "'sku_index' not found in node\n"); + d_vpr_h("'sku_index' not found in node\n"); return 0; } if (sku_index != res->sku_version) { - dprintk(VIDC_HIGH, - "Failed to parser dt: sku_index %d res->sku_version - %d\n", + d_vpr_h("Failed to parse dt: sku_index %d sku_version %d\n", sku_index, res->sku_version); return -EINVAL; } @@ -755,7 +743,7 @@ int read_platform_resources_from_drv_data( int rc = 0; if (!core || !core->platform_data) { - dprintk(VIDC_ERR, "%s Invalid data\n", __func__); + d_vpr_e("%s: Invalid data\n", __func__); return -ENOENT; } platform_data = core->platform_data; @@ -772,7 +760,7 @@ int read_platform_resources_from_drv_data( res->fw_name = "venus"; - dprintk(VIDC_HIGH, "Firmware filename: %s\n", res->fw_name); + d_vpr_h("Firmware filename: %s\n", res->fw_name); res->max_load = find_key_value(platform_data, "qcom,max-hw-load"); @@ -863,25 +851,23 @@ static int msm_vidc_populate_cx_ipeak_context( if (IS_ERR(res->cx_ipeak_context)) { rc = PTR_ERR(res->cx_ipeak_context); if (rc == -EPROBE_DEFER) - dprintk(VIDC_HIGH, - "cx-ipeak register failed. Deferring probe!"); + d_vpr_h("cx-ipeak register failed. Deferring probe!"); else - dprintk(VIDC_ERR, - "cx-ipeak register failed. rc: %d", rc); + d_vpr_e("cx-ipeak register failed. rc: %d", rc); res->cx_ipeak_context = NULL; return rc; } if (res->cx_ipeak_context) - dprintk(VIDC_HIGH, "cx-ipeak register successful"); + d_vpr_h("cx-ipeak register successful"); else - dprintk(VIDC_HIGH, "cx-ipeak register not implemented"); + d_vpr_h("cx-ipeak register not implemented"); of_property_read_u32(pdev->dev.of_node, "qcom,clock-freq-threshold", &res->clk_freq_threshold); - dprintk(VIDC_HIGH, "cx ipeak threshold frequency = %u\n", + d_vpr_h("cx ipeak threshold frequency = %u\n", res->clk_freq_threshold); return rc; @@ -896,7 +882,7 @@ int read_platform_resources_from_dt( uint32_t firmware_base = 0; if (!pdev->dev.of_node) { - dprintk(VIDC_ERR, "DT node not found\n"); + d_vpr_e("DT node not found\n"); return -ENOENT; } @@ -918,63 +904,57 @@ int read_platform_resources_from_dt( rc = msm_vidc_load_subcache_info(res); if (rc) - dprintk(VIDC_ERR, "Failed to load subcache info: %d\n", rc); + d_vpr_e("Failed to load subcache info: %d\n", rc); rc = msm_vidc_load_qdss_table(res); if (rc) - dprintk(VIDC_ERR, "Failed to load qdss reg table: %d\n", rc); + d_vpr_e("Failed to load qdss reg table: %d\n", rc); rc = msm_vidc_load_reg_table(res); if (rc) { - dprintk(VIDC_ERR, "Failed to load reg table: %d\n", rc); + d_vpr_e("Failed to load reg table: %d\n", rc); goto err_load_reg_table; } rc = msm_vidc_load_buffer_usage_table(res); if (rc) { - dprintk(VIDC_ERR, - "Failed to load buffer usage table: %d\n", rc); + d_vpr_e("Failed to load buffer usage table: %d\n", rc); goto err_load_buffer_usage_table; } rc = msm_vidc_load_regulator_table(res); if (rc) { - dprintk(VIDC_ERR, "Failed to load list of regulators %d\n", rc); + d_vpr_e("Failed to load list of regulators %d\n", rc); goto err_load_regulator_table; } rc = msm_vidc_load_clock_table(res); if (rc) { - dprintk(VIDC_ERR, - "Failed to load clock table: %d\n", rc); + d_vpr_e("Failed to load clock table: %d\n", rc); goto err_load_clock_table; } rc = msm_vidc_load_allowed_clocks_table(res); if (rc) { - dprintk(VIDC_ERR, - "Failed to load allowed clocks table: %d\n", rc); + d_vpr_e("Failed to load allowed clocks table: %d\n", rc); goto err_load_allowed_clocks_table; } rc = msm_vidc_load_reset_table(res); if (rc) { - dprintk(VIDC_ERR, - "Failed to load reset table: %d\n", rc); + d_vpr_e("Failed to load reset table: %d\n", rc); goto err_load_reset_table; } rc = msm_vidc_populate_legacy_context_bank(res); if (rc) { - dprintk(VIDC_ERR, - "Failed to setup context banks %d\n", rc); + d_vpr_e("Failed to setup context banks %d\n", rc); goto err_setup_legacy_cb; } rc = msm_vidc_populate_cx_ipeak_context(res); if (rc) { - dprintk(VIDC_ERR, - "Failed to setup cx-ipeak %d\n", rc); + d_vpr_e("Failed to setup cx-ipeak %d\n", rc); goto err_register_cx_ipeak; } @@ -1004,15 +984,14 @@ static int msm_vidc_setup_context_bank(struct msm_vidc_platform_resources *res, struct bus_type *bus; if (!dev || !cb || !res) { - dprintk(VIDC_ERR, - "%s: Invalid Input params\n", __func__); + d_vpr_e("%s: Invalid Input params\n", __func__); return -EINVAL; } cb->dev = dev; bus = cb->dev->bus; if (IS_ERR_OR_NULL(bus)) { - dprintk(VIDC_ERR, "%s - failed to get bus type\n", __func__); + d_vpr_e("%s: failed to get bus type\n", __func__); rc = PTR_ERR(bus) ? PTR_ERR(bus) : -ENODEV; goto remove_cb; } @@ -1030,9 +1009,9 @@ static int msm_vidc_setup_context_bank(struct msm_vidc_platform_resources *res, dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); dma_set_seg_boundary(dev, DMA_BIT_MASK(64)); - dprintk(VIDC_HIGH, "Attached %s and created mapping\n", dev_name(dev)); - dprintk(VIDC_HIGH, - "Context bank name:%s, buffer_type: %#x, is_secure: %d, address range start: %#x, size: %#x, dev: %pK, domain: %pK", + d_vpr_h("Attached %s and created mapping\n", dev_name(dev)); + d_vpr_h( + "Context bank: %s, buffer_type: %#x, is_secure: %d, address range start: %#x, size: %#x, dev: %pK, domain: %pK", cb->name, cb->buffer_type, cb->is_secure, cb->addr_range.start, cb->addr_range.size, cb->dev, cb->domain); @@ -1047,7 +1026,7 @@ int msm_vidc_smmu_fault_handler(struct iommu_domain *domain, struct msm_vidc_inst *inst; if (!domain || !core) { - dprintk(VIDC_ERR, "%s - invalid param %pK %pK\n", + d_vpr_e("%s: invalid params %pK %pK\n", __func__, domain, core); return -EINVAL; } @@ -1061,7 +1040,7 @@ int msm_vidc_smmu_fault_handler(struct iommu_domain *domain, } } - dprintk(VIDC_ERR, "%s - faulting address: %lx\n", __func__, iova); + d_vpr_e("%s: faulting address: %lx\n", __func__, iova); mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { @@ -1086,14 +1065,14 @@ static int msm_vidc_populate_context_bank(struct device *dev, struct device_node *np = NULL; if (!dev || !core) { - dprintk(VIDC_ERR, "%s - invalid inputs\n", __func__); + d_vpr_e("%s: invalid inputs\n", __func__); return -EINVAL; } np = dev->of_node; cb = devm_kzalloc(dev, sizeof(*cb), GFP_KERNEL); if (!cb) { - dprintk(VIDC_ERR, "%s - Failed to allocate cb\n", __func__); + d_vpr_e("%s: Failed to allocate cb\n", __func__); return -ENOMEM; } @@ -1102,40 +1081,37 @@ static int msm_vidc_populate_context_bank(struct device *dev, rc = of_property_read_string(np, "label", &cb->name); if (rc) { - dprintk(VIDC_HIGH, - "Failed to read cb label from device tree\n"); + d_vpr_h("Failed to read cb label from device tree\n"); rc = 0; } - dprintk(VIDC_HIGH, "%s: context bank has name %s\n", __func__, cb->name); + d_vpr_h("%s: context bank has name %s\n", __func__, cb->name); rc = of_property_read_u32_array(np, "virtual-addr-pool", (u32 *)&cb->addr_range, 2); if (rc) { - dprintk(VIDC_ERR, - "Could not read addr pool for context bank : %s %d\n", + d_vpr_e("Could not read addr pool: context bank: %s %d\n", cb->name, rc); goto err_setup_cb; } cb->is_secure = of_property_read_bool(np, "qcom,secure-context-bank"); - dprintk(VIDC_HIGH, "context bank %s : secure = %d\n", + d_vpr_h("context bank %s: secure = %d\n", cb->name, cb->is_secure); /* setup buffer type for each sub device*/ rc = of_property_read_u32(np, "buffer-types", &cb->buffer_type); if (rc) { - dprintk(VIDC_ERR, "failed to load buffer_type info %d\n", rc); + d_vpr_e("failed to load buffer_type info %d\n", rc); rc = -ENOENT; goto err_setup_cb; } - dprintk(VIDC_HIGH, - "context bank %s address start = %x address size = %x buffer_type = %x\n", + d_vpr_h("context bank %s address start %x size %x buffer_type %x\n", cb->name, cb->addr_range.start, cb->addr_range.size, cb->buffer_type); rc = msm_vidc_setup_context_bank(&core->resources, cb, dev); if (rc) { - dprintk(VIDC_ERR, "Cannot setup context bank %d\n", rc); + d_vpr_e("Cannot setup context bank %d\n", rc); goto err_setup_cb; } @@ -1160,7 +1136,7 @@ static int msm_vidc_populate_legacy_context_bank( struct context_bank_info *cb; if (!res || !res->pdev) { - dprintk(VIDC_ERR, "%s - invalid inputs\n", __func__); + d_vpr_e("%s: invalid inputs\n", __func__); return -EINVAL; } pdev = res->pdev; @@ -1168,8 +1144,7 @@ static int msm_vidc_populate_legacy_context_bank( domains_parent_node = of_find_node_by_name(pdev->dev.of_node, "qcom,vidc-iommu-domains"); if (!domains_parent_node) { - dprintk(VIDC_HIGH, - "%s legacy iommu domains not present\n", __func__); + d_vpr_h("%s: legacy iommu domains not present\n", __func__); return 0; } @@ -1178,8 +1153,7 @@ static int msm_vidc_populate_legacy_context_bank( domains_child_node) { cb = devm_kzalloc(&pdev->dev, sizeof(*cb), GFP_KERNEL); if (!cb) { - dprintk(VIDC_ERR, - "%s - Failed to allocate cb\n", __func__); + d_vpr_e("%s: Failed to allocate cb\n", __func__); return -ENOMEM; } INIT_LIST_HEAD(&cb->list); @@ -1188,24 +1162,21 @@ static int msm_vidc_populate_legacy_context_bank( ctx_node = of_parse_phandle(domains_child_node, "qcom,vidc-domain-phandle", 0); if (!ctx_node) { - dprintk(VIDC_ERR, - "%s Unable to parse pHandle\n", __func__); + d_vpr_e("%s: Unable to parse pHandle\n", __func__); rc = -EBADHANDLE; goto err_setup_cb; } rc = of_property_read_string(ctx_node, "label", &(cb->name)); if (rc) { - dprintk(VIDC_ERR, - "%s Could not find label\n", __func__); + d_vpr_e("%s: Could not find label\n", __func__); goto err_setup_cb; } rc = of_property_read_u32_array(ctx_node, "qcom,virtual-addr-pool", (u32 *)&cb->addr_range, 2); if (rc) { - dprintk(VIDC_ERR, - "%s Could not read addr pool for group : %s (%d)\n", + d_vpr_e("%s: Could not read addr pool: %s (%d)\n", __func__, cb->name, rc); goto err_setup_cb; } @@ -1216,28 +1187,27 @@ static int msm_vidc_populate_legacy_context_bank( rc = of_property_read_u32(domains_child_node, "qcom,vidc-buffer-types", &cb->buffer_type); if (rc) { - dprintk(VIDC_ERR, - "%s Could not read buffer type (%d)\n", + d_vpr_e("%s: Could not read buffer type (%d)\n", __func__, rc); goto err_setup_cb; } cb->dev = msm_iommu_get_ctx(cb->name); if (IS_ERR_OR_NULL(cb->dev)) { - dprintk(VIDC_ERR, "%s could not get device for cb %s\n", - __func__, cb->name); + d_vpr_e("%s: could not get device for cb %s\n", + __func__, cb->name); rc = -ENOENT; goto err_setup_cb; } rc = msm_vidc_setup_context_bank(res, cb, cb->dev); if (rc) { - dprintk(VIDC_ERR, "Cannot setup context bank %d\n", rc); + d_vpr_e("Cannot setup context bank %d\n", rc); goto err_setup_cb; } - dprintk(VIDC_HIGH, - "%s: context bank %s secure %d addr start = %#x addr size = %#x buffer_type = %#x\n", - __func__, cb->name, cb->is_secure, cb->addr_range.start, + d_vpr_h( + "context bank %s secure %d addr start = %#x size = %#x buffer_type = %#x\n", + cb->name, cb->is_secure, cb->addr_range.start, cb->addr_range.size, cb->buffer_type); } return rc; @@ -1253,26 +1223,26 @@ int read_context_bank_resources_from_dt(struct platform_device *pdev) int rc = 0; if (!pdev) { - dprintk(VIDC_ERR, "Invalid platform device\n"); + d_vpr_e("Invalid platform device\n"); return -EINVAL; } else if (!pdev->dev.parent) { - dprintk(VIDC_ERR, "Failed to find a parent for %s\n", - dev_name(&pdev->dev)); + d_vpr_e("Failed to find a parent for %s\n", + dev_name(&pdev->dev)); return -ENODEV; } core = dev_get_drvdata(pdev->dev.parent); if (!core) { - dprintk(VIDC_ERR, "Failed to find cookie in parent device %s", + d_vpr_e("Failed to find cookie in parent device %s", dev_name(pdev->dev.parent)); return -EINVAL; } rc = msm_vidc_populate_context_bank(&pdev->dev, core); if (rc) - dprintk(VIDC_ERR, "Failed to probe context bank\n"); + d_vpr_e("Failed to probe context bank\n"); else - dprintk(VIDC_HIGH, "Successfully probed context bank\n"); + d_vpr_h("Successfully probed context bank\n"); return rc; } @@ -1282,18 +1252,18 @@ int read_bus_resources_from_dt(struct platform_device *pdev) struct msm_vidc_core *core; if (!pdev) { - dprintk(VIDC_ERR, "Invalid platform device\n"); + d_vpr_e("Invalid platform device\n"); return -EINVAL; } else if (!pdev->dev.parent) { - dprintk(VIDC_ERR, "Failed to find a parent for %s\n", - dev_name(&pdev->dev)); + d_vpr_e("Failed to find a parent for %s\n", + dev_name(&pdev->dev)); return -ENODEV; } core = dev_get_drvdata(pdev->dev.parent); if (!core) { - dprintk(VIDC_ERR, "Failed to find cookie in parent device %s", - dev_name(pdev->dev.parent)); + d_vpr_e("Failed to find cookie in parent device %s", + dev_name(pdev->dev.parent)); return -EINVAL; } @@ -1305,17 +1275,17 @@ int read_mem_cdsp_resources_from_dt(struct platform_device *pdev) struct msm_vidc_core *core; if (!pdev) { - dprintk(VIDC_ERR, "%s: invalid platform device\n", __func__); + d_vpr_e("%s: invalid platform device\n", __func__); return -EINVAL; } else if (!pdev->dev.parent) { - dprintk(VIDC_ERR, "Failed to find a parent for %s\n", + d_vpr_e("Failed to find a parent for %s\n", dev_name(&pdev->dev)); return -ENODEV; } core = dev_get_drvdata(pdev->dev.parent); if (!core) { - dprintk(VIDC_ERR, "Failed to find cookie in parent device %s", + d_vpr_e("Failed to find cookie in parent device %s", dev_name(pdev->dev.parent)); return -EINVAL; } diff --git a/msm/vidc/vidc_hfi.c b/msm/vidc/vidc_hfi.c index 11ea53019f63..111965e6e457 100644 --- a/msm/vidc/vidc_hfi.c +++ b/msm/vidc/vidc_hfi.c @@ -16,7 +16,7 @@ struct hfi_device *vidc_hfi_initialize(enum msm_vidc_hfi_type hfi_type, hdev = kzalloc(sizeof(struct hfi_device), GFP_KERNEL); if (!hdev) { - dprintk(VIDC_ERR, "%s: failed to allocate hdev\n", __func__); + d_vpr_e("%s: failed to allocate hdev\n", __func__); return NULL; } @@ -25,13 +25,13 @@ struct hfi_device *vidc_hfi_initialize(enum msm_vidc_hfi_type hfi_type, rc = venus_hfi_initialize(hdev, device_id, res, callback); break; default: - dprintk(VIDC_ERR, "Unsupported host-firmware interface\n"); + d_vpr_e("Unsupported host-firmware interface\n"); goto err_hfi_init; } if (rc) { if (rc != -EPROBE_DEFER) - dprintk(VIDC_ERR, "%s device init failed rc = %d", + d_vpr_e("%s: device init failed rc = %d", __func__, rc); goto err_hfi_init; } @@ -47,7 +47,7 @@ void vidc_hfi_deinitialize(enum msm_vidc_hfi_type hfi_type, struct hfi_device *hdev) { if (!hdev) { - dprintk(VIDC_ERR, "%s invalid device %pK", __func__, hdev); + d_vpr_e("%s: invalid device %pK", __func__, hdev); return; } @@ -56,7 +56,7 @@ void vidc_hfi_deinitialize(enum msm_vidc_hfi_type hfi_type, venus_hfi_delete_device(hdev->hfi_device_data); break; default: - dprintk(VIDC_ERR, "Unsupported host-firmware interface\n"); + d_vpr_e("Unsupported host-firmware interface\n"); } kfree(hdev); diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index 1d30ed804205..3d1f9ae383cc 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -370,31 +370,31 @@ struct hfi_uncompressed_plane_actual_constraints_info { struct hfi_cmd_sys_session_abort_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; }; struct hfi_cmd_session_load_resources_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; }; struct hfi_cmd_session_start_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; }; struct hfi_cmd_session_stop_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; }; struct hfi_cmd_session_empty_buffer_compressed_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 time_stamp_hi; u32 time_stamp_lo; u32 flags; @@ -412,7 +412,7 @@ struct hfi_cmd_session_empty_buffer_compressed_packet { struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 view_id; u32 time_stamp_hi; u32 time_stamp_lo; @@ -449,7 +449,7 @@ struct hfi_cmd_session_empty_buffer_uncompressed_plane2_packet { struct hfi_cmd_session_fill_buffer_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 stream_id; u32 offset; u32 alloc_len; @@ -463,26 +463,26 @@ struct hfi_cmd_session_fill_buffer_packet { struct hfi_cmd_session_flush_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 flush_type; }; struct hfi_cmd_session_suspend_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; }; struct hfi_cmd_session_resume_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; }; struct hfi_cmd_session_get_property_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 num_properties; u32 rg_property_data[1]; }; @@ -490,7 +490,7 @@ struct hfi_cmd_session_get_property_packet { struct hfi_cmd_session_release_buffer_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 buffer_type; u32 buffer_size; u32 extra_data_size; @@ -502,13 +502,13 @@ struct hfi_cmd_session_release_buffer_packet { struct hfi_cmd_session_release_resources_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; }; struct hfi_msg_sys_session_abort_done_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 error_type; }; @@ -522,42 +522,42 @@ struct hfi_msg_sys_property_info_packet { struct hfi_msg_session_load_resources_done_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 error_type; }; struct hfi_msg_session_start_done_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 error_type; }; struct hfi_msg_session_stop_done_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 error_type; }; struct hfi_msg_session_suspend_done_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 error_type; }; struct hfi_msg_session_resume_done_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 error_type; }; struct hfi_msg_session_flush_done_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 error_type; u32 flush_type; }; @@ -581,7 +581,7 @@ struct hfi_frame_cr_stats_type { struct hfi_msg_session_empty_buffer_done_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 error_type; u32 offset; u32 filled_len; @@ -597,7 +597,7 @@ struct hfi_msg_session_empty_buffer_done_packet { struct hfi_msg_session_fill_buffer_done_compressed_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 time_stamp_hi; u32 time_stamp_lo; u32 error_type; @@ -619,7 +619,7 @@ struct hfi_msg_session_fill_buffer_done_compressed_packet { struct hfi_msg_session_fbd_uncompressed_plane0_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 stream_id; u32 view_id; u32 error_type; @@ -666,7 +666,7 @@ struct hfi_msg_session_fill_buffer_done_uncompressed_plane2_packet { struct hfi_msg_session_property_info_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 num_properties; u32 rg_property_data[1]; }; @@ -674,14 +674,14 @@ struct hfi_msg_session_property_info_packet { struct hfi_msg_session_release_resources_done_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 error_type; }; struct hfi_msg_session_release_buffers_done_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 error_type; u32 num_buffers; u32 rg_buffer_info[1]; @@ -690,7 +690,7 @@ struct hfi_msg_session_release_buffers_done_packet { struct hfi_msg_session_register_buffers_done_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 client_data; u32 error_type; }; @@ -698,7 +698,7 @@ struct hfi_msg_session_register_buffers_done_packet { struct hfi_msg_session_unregister_buffers_done_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 client_data; u32 error_type; }; @@ -806,7 +806,7 @@ struct hfi_extradata_recovery_point_sei_payload { struct hfi_cmd_session_continue_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; }; enum session_flags { @@ -815,11 +815,12 @@ enum session_flags { struct hal_session { struct list_head list; - void *session_id; + void *inst_id; bool is_decoder; enum hal_video_codec codec; enum hal_domain domain; u32 flags; + u32 sid; }; struct hal_device_data { diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 86ce8e48ea1b..e0e5b5d4eab0 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -577,7 +577,7 @@ struct vidc_hal_sys_init_done { struct msm_vidc_cb_cmd_done { u32 device_id; - void *session_id; + void *inst_id; enum vidc_status status; u32 size; union { @@ -609,7 +609,7 @@ struct hal_index_extradata_input_crop_payload { struct msm_vidc_cb_event { u32 device_id; - void *session_id; + void *inst_id; enum vidc_status status; u32 height; u32 width; @@ -628,7 +628,7 @@ struct msm_vidc_cb_event { struct msm_vidc_cb_data_done { u32 device_id; - void *session_id; + void *inst_id; enum vidc_status status; u32 size; union { @@ -689,9 +689,9 @@ struct hfi_device { int (*core_init)(void *device); int (*core_release)(void *device); int (*core_trigger_ssr)(void *device, enum hal_ssr_trigger_type); - int (*session_init)(void *device, void *session_id, + int (*session_init)(void *device, void *inst_id, enum hal_domain session_type, enum hal_video_codec codec_type, - void **new_session); + void **new_session, u32 sid); int (*session_end)(void *session); int (*session_abort)(void *session); int (*session_set_buffers)(void *sess, @@ -718,9 +718,9 @@ struct hfi_device { void *pdata, u32 size); int (*session_pause)(void *sess); int (*session_resume)(void *sess); - int (*scale_clocks)(void *dev, u32 freq); + int (*scale_clocks)(void *dev, u32 freq, u32 sid); int (*vote_bus)(void *dev, unsigned long bw_ddr, - unsigned long bw_llcc); + unsigned long bw_llcc, u32 sid); int (*get_fw_info)(void *dev, struct hal_fw_info *fw_info); int (*session_clean)(void *sess); int (*get_core_capabilities)(void *dev); @@ -739,9 +739,6 @@ struct hfi_device *vidc_hfi_initialize(enum msm_vidc_hfi_type hfi_type, hfi_cmd_response_callback callback); void vidc_hfi_deinitialize(enum msm_vidc_hfi_type hfi_type, struct hfi_device *hdev); -u32 vidc_get_hfi_domain(enum hal_domain hal_domain); -u32 vidc_get_hfi_codec(enum hal_video_codec hal_codec); -enum hal_domain vidc_get_hal_domain(u32 hfi_domain); -enum hal_video_codec vidc_get_hal_codec(u32 hfi_codec); - +u32 vidc_get_hfi_domain(enum hal_domain hal_domain, u32 sid); +u32 vidc_get_hfi_codec(enum hal_video_codec hal_codec, u32 sid); #endif /*__VIDC_HFI_API_H__ */ diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index 2b96d5645a5e..f345fdf475f6 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -834,7 +834,7 @@ struct vidc_hal_msg_pkt_hdr { struct vidc_hal_session_cmd_pkt { u32 size; u32 packet_type; - u32 session_id; + u32 sid; }; struct hfi_packet_header { @@ -885,7 +885,7 @@ struct hfi_cmd_sys_get_property_packet { struct hfi_cmd_sys_session_init_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 session_domain; u32 session_codec; }; @@ -893,7 +893,7 @@ struct hfi_cmd_sys_session_init_packet { struct hfi_cmd_sys_session_end_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; }; struct hfi_cmd_sys_set_buffers_packet { @@ -927,7 +927,7 @@ struct hfi_cmd_sys_set_ubwc_config_packet_type { struct hfi_cmd_session_set_property_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 num_properties; u32 rg_property_data[1]; }; @@ -935,7 +935,7 @@ struct hfi_cmd_session_set_property_packet { struct hfi_cmd_session_set_buffers_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 buffer_type; u32 buffer_size; u32 extra_data_size; @@ -953,7 +953,7 @@ struct hfi_buffer_mapping_type { struct hfi_cmd_session_register_buffers_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 client_data; u32 response_req; u32 num_buffers; @@ -963,7 +963,7 @@ struct hfi_cmd_session_register_buffers_packet { struct hfi_cmd_session_unregister_buffers_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 client_data; u32 response_req; u32 num_buffers; @@ -973,7 +973,7 @@ struct hfi_cmd_session_unregister_buffers_packet { struct hfi_cmd_session_sync_process_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 sync_id; u32 rg_data[1]; }; @@ -981,7 +981,7 @@ struct hfi_cmd_session_sync_process_packet { struct hfi_msg_event_notify_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 event_id; u32 event_data1; u32 event_data2; @@ -1018,7 +1018,7 @@ struct hfi_msg_sys_release_resource_done_packet { struct hfi_msg_sys_session_init_done_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 error_type; u32 num_properties; u32 rg_property_data[1]; @@ -1027,7 +1027,7 @@ struct hfi_msg_sys_session_init_done_packet { struct hfi_msg_sys_session_end_done_packet { u32 size; u32 packet_type; - u32 session_id; + u32 sid; u32 error_type; }; From 2548b43adb80b4f59de2b5addfccdf810d22ea22 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 4 Sep 2019 01:11:59 +0530 Subject: [PATCH 156/452] msm: vidc: print session and codec type in dprintk [1] Maintain log_ctxt cookie to track debug information. [2] Print codec type and session type by default in logs. Change-Id: I6c01f3238ba868fdc525f5c60f58545a07bdef3a Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vdec.c | 3 +- msm/vidc/msm_venc.c | 3 +- msm/vidc/msm_vidc.c | 17 ++++-- msm/vidc/msm_vidc_debug.c | 105 ++++++++++++++++++++++++++++++++++++++ msm/vidc/msm_vidc_debug.h | 21 ++++++-- 5 files changed, 140 insertions(+), 9 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index edc8d26a9182..3d2560049267 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -657,7 +657,8 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) "%s: session not supported\n", __func__); goto err_invalid_fmt; } - + update_log_ctxt(inst->sid, inst->session_type, + mplane->pixelformat); memcpy(f, &fmt->v4l2_fmt, sizeof(struct v4l2_format)); } diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 3dc2bc192faf..488778080468 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1323,7 +1323,8 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) "%s: session not supported\n", __func__); goto exit; } - + update_log_ctxt(inst->sid, inst->session_type, + mplane->pixelformat); memcpy(f, &fmt->v4l2_fmt, sizeof(struct v4l2_format)); } else if (f->type == INPUT_MPLANE) { fmt = &inst->fmts[INPUT_PORT]; diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index aa4128ff365d..f72719a38d88 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1528,10 +1528,17 @@ void *msm_vidc_open(int core_id, int session_type) rc = -ENOMEM; goto err_invalid_core; } - inst->sid = hash32_ptr(inst); + mutex_lock(&core->lock); + rc = get_sid(&inst->sid, session_type); + mutex_unlock(&core->lock); + if (rc) { + d_vpr_e("Total instances count reached to max value\n"); + goto err_invalid_sid; + } pr_info(VIDC_DBG_TAG "Opening video instance: %pK, %d\n", - "high", inst->sid, inst, session_type); + "high", inst->sid, get_codec_name(inst->sid), + inst, session_type); mutex_init(&inst->sync_lock); mutex_init(&inst->bufq[OUTPUT_PORT].lock); mutex_init(&inst->bufq[INPUT_PORT].lock); @@ -1668,6 +1675,8 @@ void *msm_vidc_open(int core_id, int session_type) DEINIT_MSM_VIDC_LIST(&inst->fbd_data); DEINIT_MSM_VIDC_LIST(&inst->window_data); +err_invalid_sid: + put_sid(inst->sid); kfree(inst); inst = NULL; err_invalid_core: @@ -1803,7 +1812,9 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) msm_vidc_debugfs_deinit_inst(inst); pr_info(VIDC_DBG_TAG "Closed video instance: %pK\n", - "high", inst->sid, inst); + "high", inst->sid, get_codec_name(inst->sid), + inst); + put_sid(inst->sid); kfree(inst); return 0; } diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index 14492f3610cc..6be7fd301782 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -30,6 +30,8 @@ bool msm_vidc_cvp_usage = true; atomic_read(&__binfo->ref_count) >= 2 ? "video driver" : "firmware";\ }) +static struct log_cookie ctxt[MAX_SUPPORTED_INSTANCES]; + struct core_inst_pair { struct msm_vidc_core *core; struct msm_vidc_inst *inst; @@ -596,3 +598,106 @@ int msm_vidc_check_ratelimit(void) return __ratelimit(&_rs); } +/** + * get_sid() must be called under "&core->lock" + * to avoid race condition in occurring empty slot. + */ +int get_sid(u32 *sid, u32 session_type) +{ + int i; + + for (i = 0; i < MAX_SUPPORTED_INSTANCES; i++) { + if (!ctxt[i].used) { + ctxt[i].used = 1; + *sid = i+1; + update_log_ctxt(*sid, session_type, 0); + break; + } + } + + return (i == MAX_SUPPORTED_INSTANCES); +} + +void put_sid(u32 sid) +{ + if (!sid || sid > MAX_SUPPORTED_INSTANCES) { + d_vpr_e("%s: invalid sid %#x\n", + __func__, sid); + return; + } + if (ctxt[sid-1].used) + ctxt[sid-1].used = 0; +} + +inline void update_log_ctxt(u32 sid, u32 session_type, u32 fourcc) +{ + const char *codec; + char type; + + if (!sid || sid > MAX_SUPPORTED_INSTANCES) { + d_vpr_e("%s: invalid sid %#x\n", + __func__, sid); + } + + switch (fourcc) { + case V4L2_PIX_FMT_H264: + case V4L2_PIX_FMT_H264_NO_SC: + codec = "h264"; + break; + case V4L2_PIX_FMT_H264_MVC: + codec = " mvc"; + break; + case V4L2_PIX_FMT_MPEG1: + codec = "mpg1"; + break; + case V4L2_PIX_FMT_MPEG2: + codec = "mpg2"; + break; + case V4L2_PIX_FMT_VP8: + codec = " vp8"; + break; + case V4L2_PIX_FMT_VP9: + codec = " vp9"; + break; + case V4L2_PIX_FMT_HEVC: + codec = "h265"; + break; + case V4L2_PIX_FMT_TME: + codec = " tme"; + break; + case V4L2_PIX_FMT_CVP: + codec = " cvp"; + break; + default: + codec = "...."; + break; + } + + switch (session_type) { + case MSM_VIDC_ENCODER: + type = 'e'; + break; + case MSM_VIDC_DECODER: + type = 'd'; + break; + case MSM_VIDC_CVP: + type = 'c'; + default: + type = '.'; + break; + } + + ctxt[sid-1].session_type = session_type; + ctxt[sid-1].codec_type = fourcc; + memcpy(&ctxt[sid-1].name, codec, 4); + ctxt[sid-1].name[4] = type; + ctxt[sid-1].name[5] = '\0'; +} + +char *get_codec_name(u32 sid) +{ + if (!sid || sid > MAX_SUPPORTED_INSTANCES) + return "....."; + + return ctxt[sid-1].name; +} diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index ddbc9d60b948..a3b2c99b0471 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -23,7 +23,8 @@ #define VIDC_DBG_SESSION_RATELIMIT_INTERVAL (1 * HZ) #define VIDC_DBG_SESSION_RATELIMIT_BURST 6 -#define VIDC_DBG_TAG VIDC_DBG_LABEL ": %6s: %8x: " +#define VIDC_DBG_TAG VIDC_DBG_LABEL ": %6s: %08x: %5s: " +#define FW_DBG_TAG VIDC_DBG_LABEL ": %6s: " #define DEFAULT_SID ((u32)-1) /* To enable messages OR these values and @@ -69,6 +70,13 @@ extern bool msm_vidc_syscache_disable; extern bool msm_vidc_lossless_encode; extern bool msm_vidc_cvp_usage; +struct log_cookie { + u32 used; + u32 session_type; + u32 codec_type; + char name[20]; +}; + #define dprintk(__level, sid, __fmt, ...) \ do { \ if (msm_vidc_debug & __level) { \ @@ -79,6 +87,7 @@ extern bool msm_vidc_cvp_usage; VIDC_DBG_TAG __fmt, \ get_debug_level_str(__level), \ sid, \ + get_codec_name(sid), \ ##__VA_ARGS__); \ trace_msm_vidc_printf(trace_logbuf, \ log_length); \ @@ -87,6 +96,7 @@ extern bool msm_vidc_cvp_usage; pr_info(VIDC_DBG_TAG __fmt, \ get_debug_level_str(__level), \ sid, \ + get_codec_name(sid), \ ##__VA_ARGS__); \ } \ } \ @@ -120,14 +130,14 @@ extern bool msm_vidc_cvp_usage; char trace_logbuf[MAX_TRACER_LOG_LENGTH]; \ int log_length = snprintf(trace_logbuf, \ MAX_TRACER_LOG_LENGTH, \ - VIDC_DBG_TAG __fmt, \ + FW_DBG_TAG __fmt, \ "fw", \ ##__VA_ARGS__); \ trace_msm_vidc_printf(trace_logbuf, \ log_length); \ } \ if (__level & FW_PRINTK) { \ - pr_info(VIDC_DBG_TAG __fmt, \ + pr_info(FW_DBG_TAG __fmt, \ "fw", \ ##__VA_ARGS__); \ } \ @@ -146,7 +156,6 @@ extern bool msm_vidc_cvp_usage; BUG_ON(value); \ } while (0) - struct dentry *msm_vidc_debugfs_init_drv(void); struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core, struct dentry *parent); @@ -156,6 +165,10 @@ void msm_vidc_debugfs_deinit_inst(struct msm_vidc_inst *inst); void msm_vidc_debugfs_update(struct msm_vidc_inst *inst, enum msm_vidc_debugfs_event e); int msm_vidc_check_ratelimit(void); +int get_sid(u32 *sid, u32 session_type); +void update_log_ctxt(u32 sid, u32 session_type, u32 fourcc); +char *get_codec_name(u32 sid); +void put_sid(u32 sid); static inline char *get_debug_level_str(int level) { From 7960c3b3a989340709b81116e6f410bdd5c149b0 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Wed, 4 Sep 2019 11:02:27 -0700 Subject: [PATCH 157/452] msm: vidc: Raise insufficient event for interlacing change Raise an insufficient event whenever there is a change reported from interlace to progressive and vice versa so that driver can set appropriate work/route mode. CRs-Fixed: 2444064 Change-Id: Ic78867a2b51aa22de5dfeeb4b806014e2f0f23e6 Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_common.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index cef7372396c6..d0199371bde7 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1644,6 +1644,16 @@ static void handle_event_change(enum hal_command_response cmd, void *data) inst->colour_space == MSM_VIDC_BT2020))) event_fields_changed = true; + /* + * Check for a change from progressive to interlace + * and vice versa + */ + if ((event_notify->pic_struct == MSM_VIDC_PIC_STRUCT_MAYBE_INTERLACED && + inst->pic_struct == MSM_VIDC_PIC_STRUCT_PROGRESSIVE) || + (event_notify->pic_struct == MSM_VIDC_PIC_STRUCT_PROGRESSIVE && + inst->pic_struct == MSM_VIDC_PIC_STRUCT_MAYBE_INTERLACED)) + event_fields_changed = true; + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; event_fields_changed |= (f->fmt.pix_mp.height != event_notify->height); From 6f422178aa2c69466e27e475c02d245673d78187 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Mon, 12 Aug 2019 16:54:01 -0700 Subject: [PATCH 158/452] msm: vidc: Add support to CVP skip ratio Introduced CVP skip ratio property to indicate the number of buffers skipped for CVP processing. This serves as a hint to Video firmware to know the number of frames for which CVP metadata has to be reused from earlier frame to which CVP metadata was sent Change-Id: I58ad5daf9a9c6ae7a0aa48e3bd1d60e7dc9229e6 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_cvp_external.c | 17 ++++++++++-- msm/vidc/msm_venc.c | 54 +++++++++++++++++++++++++++++++++++++ msm/vidc/msm_venc.h | 1 + msm/vidc/msm_vidc.c | 29 ++++++++++++++++++++ msm/vidc/msm_vidc_common.c | 29 ++++++++++++++++++++ msm/vidc/msm_vidc_common.h | 2 ++ msm/vidc/vidc_hfi_helper.h | 6 +++++ 7 files changed, 136 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index 5fb23bbe1c5a..fe64b227d812 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -869,9 +869,10 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, struct cvp_kmd_arg *arg; struct msm_cvp_dme_frame_packet *frame; const u32 fps_max = CVP_FRAME_RATE_MAX; - u32 fps, operating_rate, skip_framecount; + u32 fps, operating_rate, skip_framecount, capture_rate, cvp_rate; bool skipframe = false; bool first_frame = false; + bool fps_data_changed = false; if (!inst || !inst->cvp || !inst->cvp->arg || !mbuf) { d_vpr_e("%s: invalid params %pK %pK\n", @@ -896,6 +897,7 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, cvp->operating_rate != inst->clk_data.operating_rate) { /* update cvp parameters */ cvp->framecount = 0; + fps_data_changed = true; cvp->frame_rate = inst->clk_data.frame_rate; cvp->operating_rate = inst->clk_data.operating_rate; rc = msm_cvp_set_clocks_and_bus(inst); @@ -929,9 +931,12 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, * fps <= 960: 0, 16, 32, 48 .. are not skipped */ fps = roundup(fps, fps_max); + cvp_rate = fps_max << 16; skip_framecount = fps / fps_max; skipframe = cvp->framecount % skip_framecount; - } + } else + cvp_rate = fps << 16; + if (skipframe) { print_cvp_buffer(VIDC_LOW, "input frame with skipflag", inst, &cvp->fullres_buffer); @@ -940,6 +945,14 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, mbuf->vvb.flags |= V4L2_BUF_FLAG_CVPMETADATA_SKIP; return 0; } + capture_rate = fps << 16; + if (fps_data_changed) { + rc = msm_comm_set_cvp_skip_ratio(inst, capture_rate, cvp_rate); + if (rc) { + s_vpr_e(inst->sid,"Setting CVP skip ratio failed"); + goto error; + } + } memset(arg, 0, sizeof(struct cvp_kmd_arg)); arg->type = CVP_KMD_SEND_CMD_PKT; diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 488778080468..26452da8c3e8 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -956,6 +956,24 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = 0, .step = 1, }, + { + .id = V4L2_CID_MPEG_VIDC_CAPTURE_FRAME_RATE, + .name = "Capture Frame Rate", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = (MINIMUM_FPS << 16), + .maximum = (MAXIMUM_FPS << 16), + .default_value = (DEFAULT_FPS << 16), + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_CVP_FRAME_RATE, + .name = "CVP Frame Rate", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = (MINIMUM_FPS << 16), + .maximum = (MAXIMUM_FPS << 16), + .default_value = (DEFAULT_FPS << 16), + .step = 1, + }, }; #define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls) @@ -1810,6 +1828,16 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) s_vpr_e(sid, "%s: set flip failed\n", __func__); } break; + case V4L2_CID_MPEG_VIDC_CVP_FRAME_RATE: + if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_set_cvp_skipratio(inst); + if (rc) + s_vpr_e(sid, + "%s: set cvp skip ratio failed\n", + __func__); + } + break; + case V4L2_CID_MPEG_VIDC_CAPTURE_FRAME_RATE: case V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY: case V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE: case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER: @@ -2087,6 +2115,9 @@ int msm_venc_set_operating_rate(struct msm_vidc_inst *inst) d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } + if (!inst->core->resources.cvp_internal) + return 0; + hdev = inst->core->device; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE); @@ -4212,6 +4243,29 @@ int msm_venc_set_lossless(struct msm_vidc_inst *inst) return rc; } +int msm_venc_set_cvp_skipratio(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct v4l2_ctrl *capture_rate_ctrl; + struct v4l2_ctrl *cvp_rate_ctrl; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params %pK\n", __func__, inst); + return -EINVAL; + } + if (!msm_vidc_cvp_usage || !inst->core->resources.cvp_external) + return 0; + + capture_rate_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_CAPTURE_FRAME_RATE); + cvp_rate_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_CVP_FRAME_RATE); + + rc = msm_comm_set_cvp_skip_ratio(inst, + capture_rate_ctrl->val, cvp_rate_ctrl->val); + if (rc) + s_vpr_e(inst->sid, "Failed to set cvp skip ratio\n"); + + return rc; +} int handle_all_intra_restrictions(struct msm_vidc_inst *inst) { diff --git a/msm/vidc/msm_venc.h b/msm/vidc/msm_venc.h index f9e8d227b37a..e13b2cc3536e 100644 --- a/msm/vidc/msm_venc.h +++ b/msm/vidc/msm_venc.h @@ -41,6 +41,7 @@ int msm_venc_check_dynamic_flip_constraints(struct msm_vidc_inst *inst); int msm_venc_set_dynamic_flip(struct msm_vidc_inst *inst); int msm_venc_set_lossless(struct msm_vidc_inst *inst); int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst); +int msm_venc_set_cvp_skipratio(struct msm_vidc_inst *inst); int handle_all_intra_restrictions(struct msm_vidc_inst *inst); int check_blur_restrictions(struct msm_vidc_inst *inst); #endif diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index f72719a38d88..a4e35c7f7977 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -837,6 +837,35 @@ static bool msm_vidc_set_cvp_metadata(struct msm_vidc_inst *inst) { s_vpr_e(inst->sid, "%s: set CVP extradata failed\n", __func__); return false; } + + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_KK_CVP) { + u32 cap_rate = 0; + u32 cvp_rate = 0; + u32 oprate = 0; + u32 fps_max = CVP_FRAME_RATE_MAX << 16; + + if (inst->clk_data.operating_rate == INT_MAX) + oprate = fps_max; + else + oprate = inst->clk_data.operating_rate; + + cap_rate = max(inst->clk_data.frame_rate, oprate); + if (cap_rate > fps_max) { + cap_rate = roundup(cap_rate, fps_max); + cvp_rate = fps_max; + } + else + cvp_rate = cap_rate; + rc = msm_comm_set_cvp_skip_ratio(inst, cap_rate, cvp_rate); + } + else if(inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) + rc = msm_venc_set_cvp_skipratio(inst); + + if (rc) { + s_vpr_e(inst->sid, + "%s: set CVP skip ratio controls failed\n", __func__); + return false; + } return true; } diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index d1f57b0e8700..973b9fdf7dbb 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7176,6 +7176,35 @@ int msm_comm_set_extradata(struct msm_vidc_inst *inst, return rc; } +int msm_comm_set_cvp_skip_ratio(struct msm_vidc_inst *inst, + uint32_t capture_rate, uint32_t cvp_rate) +{ + int rc = 0; + struct hfi_cvp_skip_ratio cvp_data; + struct hfi_device *hdev; + u32 integral_part, fractional_part, skip_ratio; + + hdev = inst->core->device; + + skip_ratio = 0; + integral_part = ((capture_rate / cvp_rate) << 16); + fractional_part = capture_rate % cvp_rate; + if (fractional_part) { + fractional_part = (fractional_part * 100) / cvp_rate; + skip_ratio = integral_part | ((fractional_part << 16)/100) ; + } + else + skip_ratio = integral_part; + + cvp_data.cvp_skip_ratio = skip_ratio; + rc = call_hfi_op(hdev, session_set_property, (void *) + inst->session, HFI_PROPERTY_CONFIG_CVP_SKIP_RATIO, &cvp_data, + sizeof(cvp_data)); + + return rc; +} + + bool msm_comm_check_for_inst_overload(struct msm_vidc_core *core) { u32 instance_count = 0; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 882b97a93eb3..db1fc943c9e4 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -327,4 +327,6 @@ int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, struct vidc_frame_data *frame_data); void msm_comm_clear_window_data(struct msm_vidc_inst *inst); void msm_comm_release_window_data(struct msm_vidc_inst *inst); +int msm_comm_set_cvp_skip_ratio(struct msm_vidc_inst *inst, + uint32_t capture_rate, uint32_t cvp_rate); #endif diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index f345fdf475f6..3dfc8c1ddb68 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -387,6 +387,8 @@ struct hfi_buffer_info { (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x014) #define HFI_PROPERTY_CONFIG_HEIC_GRID_ENABLE \ (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x015) +#define HFI_PROPERTY_CONFIG_CVP_SKIP_RATIO \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x016) #define HFI_PROPERTY_PARAM_VPE_COMMON_START \ (HFI_DOMAIN_BASE_VPE + HFI_ARCH_COMMON_OFFSET + 0x7000) @@ -401,6 +403,10 @@ struct hfi_buffer_info { #define HFI_PROPERTY_CONFIG_VPE_FLIP \ (HFI_PROPERTY_CONFIG_VPE_COMMON_START + 0x001) +struct hfi_cvp_skip_ratio { + u32 cvp_skip_ratio; +}; + struct hfi_pic_struct { u32 progressive_only; }; From f74ea0c9efd722e52a1fb39aed440fd0ff6a3a91 Mon Sep 17 00:00:00 2001 From: Akshay Chandrashekhar Kalghatgi Date: Fri, 30 Aug 2019 13:13:38 -0700 Subject: [PATCH 159/452] msm: vidc: Enable secure CVP Enable external CVP processing on secure encoder. Correct vidc-CVP external function names according to naming conventions. Change-Id: I1b177ca28838f63faee474a82ba76e7655554989 Signed-off-by: Akshay Chandrashekhar Kalghatgi --- msm/vidc/msm_cvp_external.c | 114 +++++++++++++++++++++++++++--------- msm/vidc/msm_cvp_external.h | 10 +++- msm/vidc/msm_vidc.c | 1 - 3 files changed, 95 insertions(+), 30 deletions(-) diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index 5fb23bbe1c5a..1fb859b8335f 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -51,8 +51,7 @@ static int msm_cvp_get_version_info(struct msm_vidc_inst *inst) struct cvp_kmd_sys_property *prop_data; u32 version; - - if (!inst || !inst->cvp) { + if (!inst || !inst->cvp || !inst->cvp->arg) { d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } @@ -85,7 +84,7 @@ static int msm_cvp_set_priority(struct msm_vidc_inst *inst) struct cvp_kmd_sys_properties *props; struct cvp_kmd_sys_property *prop_array; - if (!inst || !inst->cvp) { + if (!inst || !inst->cvp || !inst->cvp->arg) { d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } @@ -113,6 +112,39 @@ static int msm_cvp_set_priority(struct msm_vidc_inst *inst) return 0; } +static int msm_cvp_set_secure_mode(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_cvp_external *cvp = NULL; + struct cvp_kmd_arg *arg = NULL; + struct cvp_kmd_sys_properties *props = NULL; + struct cvp_kmd_sys_property *prop_array = NULL; + + if (!inst || !inst->cvp || !inst->cvp->arg) { + d_vpr_e("%s: invalid params %pK\n", __func__, inst); + return -EINVAL; + } + cvp = inst->cvp; + arg = cvp->arg; + props = (struct cvp_kmd_sys_properties *)&arg->data.sys_properties; + prop_array = (struct cvp_kmd_sys_property *) + &arg->data.sys_properties.prop_data; + + memset(arg, 0, sizeof(struct cvp_kmd_arg)); + arg->type = CVP_KMD_SET_SYS_PROPERTY; + props->prop_num = 1; + prop_array[0].prop_type = CVP_KMD_PROP_SESSION_SECURITY; + prop_array[0].data = is_secure_session(inst); + s_vpr_h(inst->sid, "%s: %d\n", __func__, prop_array[0].data); + + rc = msm_cvp_private(cvp->priv, CVP_KMD_SET_SYS_PROPERTY, arg); + if (rc) { + s_vpr_e(inst->sid, "%s: failed, rc %d\n", __func__, rc); + return rc; + } + return rc; +} + static int msm_cvp_fill_planeinfo(struct msm_cvp_color_plane_info *plane_info, u32 color_fmt, u32 width, u32 height, u32 sid) { @@ -180,6 +212,18 @@ static int msm_cvp_fill_planeinfo(struct msm_cvp_color_plane_info *plane_info, return rc; } +static u32 msm_cvp_get_secure_flag_for_buffer_type(u32 buf_type) +{ + switch (buf_type) { + case MSM_VIDC_CVP_INPUT_BUF: + return ION_FLAG_SECURE | ION_FLAG_CP_PIXEL; + case MSM_VIDC_CVP_OUTPUT_BUF: + return 0; + default: + return ION_FLAG_SECURE | ION_FLAG_CP_NON_PIXEL; + } +} + static int msm_cvp_free_buffer(struct msm_vidc_inst *inst, struct msm_cvp_buf *buffer) { @@ -221,8 +265,12 @@ static int msm_cvp_allocate_buffer(struct msm_vidc_inst *inst, heap_mask = ION_HEAP(ION_SYSTEM_HEAP_ID); if (inst->flags & VIDC_SECURE) { - ion_flags = ION_FLAG_SECURE | ION_FLAG_CP_NON_PIXEL; - heap_mask = ION_HEAP(ION_SECURE_HEAP_ID); + ion_flags = msm_cvp_get_secure_flag_for_buffer_type( + buffer->buf_type); + if (ion_flags & ION_FLAG_SECURE) { + heap_mask = ION_HEAP(ION_SECURE_HEAP_ID); + kernel_map = false; + } } dbuf = ion_alloc(buffer->size, heap_mask, ion_flags); @@ -266,7 +314,7 @@ static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst) struct cvp_kmd_request_power power; const u32 fps_max = CVP_FRAME_RATE_MAX; - if (!inst || !inst->cvp) { + if (!inst || !inst->cvp || !inst->cvp->arg) { d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } @@ -417,6 +465,7 @@ static int msm_cvp_init_downscale_buffers(struct msm_vidc_inst *inst) cvp->src_buffer.size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, cvp->ds_width, cvp->ds_height); + cvp->src_buffer.buf_type = MSM_VIDC_CVP_INPUT_BUF; rc = msm_cvp_allocate_buffer(inst, &cvp->src_buffer, false); if (rc) { print_cvp_buffer(VIDC_ERR, @@ -428,6 +477,7 @@ static int msm_cvp_init_downscale_buffers(struct msm_vidc_inst *inst) inst, &cvp->src_buffer); cvp->ref_buffer.size = cvp->src_buffer.size; + cvp->ref_buffer.buf_type = MSM_VIDC_CVP_INPUT_BUF; rc = msm_cvp_allocate_buffer(inst, &cvp->ref_buffer, false); if (rc) { print_cvp_buffer(VIDC_ERR, @@ -487,6 +537,7 @@ static int msm_cvp_init_context_buffers(struct msm_vidc_inst *inst) s_vpr_h(inst->sid, "%s:\n", __func__); cvp->context_buffer.size = HFI_DME_FRAME_CONTEXT_BUFFER_SIZE; + cvp->context_buffer.buf_type = MSM_VIDC_CVP_CONTEXT_BUF; rc = msm_cvp_allocate_buffer(inst, &cvp->context_buffer, false); if (rc) { print_cvp_buffer(VIDC_ERR, @@ -498,6 +549,7 @@ static int msm_cvp_init_context_buffers(struct msm_vidc_inst *inst) inst, &cvp->context_buffer); cvp->refcontext_buffer.size = cvp->context_buffer.size; + cvp->refcontext_buffer.buf_type = MSM_VIDC_CVP_CONTEXT_BUF; rc = msm_cvp_allocate_buffer(inst, &cvp->refcontext_buffer, false); if (rc) { print_cvp_buffer(VIDC_ERR, @@ -604,6 +656,7 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst) cvp = inst->cvp; cvp->persist2_buffer.size = HFI_DME_INTERNAL_PERSIST_2_BUFFER_SIZE; + cvp->persist2_buffer.buf_type = MSM_VIDC_CVP_PERSIST_BUF; rc = msm_cvp_allocate_buffer(inst, &cvp->persist2_buffer, false); if (rc) { print_cvp_buffer(VIDC_ERR, @@ -616,6 +669,7 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst) /* allocate one output buffer for internal use */ cvp->output_buffer.size = HFI_DME_OUTPUT_BUFFER_SIZE; + cvp->output_buffer.buf_type = MSM_VIDC_CVP_OUTPUT_BUF; rc = msm_cvp_allocate_buffer(inst, &cvp->output_buffer, true); if (rc) { print_cvp_buffer(VIDC_ERR, @@ -797,7 +851,7 @@ static int msm_cvp_reference_management(struct msm_vidc_inst *inst) return rc; } -static int msm_vidc_cvp_session_start(struct msm_vidc_inst *inst) +static int msm_cvp_session_start(struct msm_vidc_inst *inst) { int rc = 0; struct msm_cvp_external *cvp = NULL; @@ -827,7 +881,7 @@ static int msm_vidc_cvp_session_start(struct msm_vidc_inst *inst) return rc; } -static int msm_vidc_cvp_session_stop(struct msm_vidc_inst *inst) +static int msm_cvp_session_stop(struct msm_vidc_inst *inst) { int rc = 0; struct msm_cvp_external *cvp = NULL; @@ -1039,7 +1093,7 @@ int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst, return rc; } -static int msm_vidc_cvp_session_delete(struct msm_vidc_inst *inst) +static int msm_cvp_session_delete(struct msm_vidc_inst *inst) { int rc = 0; struct msm_cvp_external *cvp = NULL; @@ -1094,7 +1148,7 @@ static int msm_cvp_mem_deinit(struct msm_vidc_inst *inst) return rc; } -static int msm_vidc_cvp_deinit(struct msm_vidc_inst *inst) +static int msm_cvp_deinit(struct msm_vidc_inst *inst) { int rc = 0; @@ -1103,18 +1157,18 @@ static int msm_vidc_cvp_deinit(struct msm_vidc_inst *inst) return -EINVAL; } - rc = msm_vidc_cvp_session_stop(inst); + rc = msm_cvp_session_stop(inst); if (rc) { s_vpr_e(inst->sid, "%s: cvp stop failed with error %d\n", __func__, rc); } - msm_vidc_cvp_session_delete(inst); + msm_cvp_session_delete(inst); return rc; } -static int msm_vidc_cvp_close(struct msm_vidc_inst *inst) +static int msm_cvp_session_close(struct msm_vidc_inst *inst) { int rc = 0; struct msm_cvp_external *cvp; @@ -1146,14 +1200,14 @@ int msm_vidc_cvp_unprepare_preprocess(struct msm_vidc_inst *inst) return 0; } - msm_vidc_cvp_deinit(inst); - msm_vidc_cvp_close(inst); + msm_cvp_deinit(inst); + msm_cvp_session_close(inst); msm_cvp_mem_deinit(inst); return 0; } -static int msm_vidc_cvp_session_create(struct msm_vidc_inst *inst) +static int msm_cvp_session_create(struct msm_vidc_inst *inst) { int rc = 0; struct msm_cvp_external *cvp = NULL; @@ -1183,7 +1237,7 @@ static int msm_vidc_cvp_session_create(struct msm_vidc_inst *inst) return rc; } -static int msm_vidc_cvp_getsessioninfo(struct msm_vidc_inst *inst) +static int msm_cvp_get_sessioninfo(struct msm_vidc_inst *inst) { int rc = 0; struct msm_cvp_external *cvp; @@ -1215,11 +1269,11 @@ static int msm_vidc_cvp_getsessioninfo(struct msm_vidc_inst *inst) return rc; error: - msm_vidc_cvp_deinit(inst); + msm_cvp_deinit(inst); return rc; } -static int msm_vidc_cvp_dme_basic_config(struct msm_vidc_inst *inst) +static int msm_cvp_dme_basic_config(struct msm_vidc_inst *inst) { int rc = 0; struct msm_cvp_external *cvp; @@ -1341,7 +1395,7 @@ static int msm_cvp_mem_init(struct msm_vidc_inst *inst) return rc; } -static int msm_vidc_cvp_open(struct msm_vidc_inst *inst) +static int msm_cvp_session_open(struct msm_vidc_inst *inst) { int rc = 0; struct msm_cvp_external *cvp; @@ -1363,19 +1417,23 @@ static int msm_vidc_cvp_open(struct msm_vidc_inst *inst) return rc; } -static int msm_vidc_cvp_init(struct msm_vidc_inst *inst) +static int msm_cvp_init(struct msm_vidc_inst *inst) { int rc; + rc = msm_cvp_set_secure_mode(inst); + if (rc) + goto error; + rc = msm_cvp_set_priority(inst); if (rc) goto error; - rc = msm_vidc_cvp_session_create(inst); + rc = msm_cvp_session_create(inst); if (rc) return rc; - rc = msm_vidc_cvp_getsessioninfo(inst); + rc = msm_cvp_get_sessioninfo(inst); if (rc) return rc; @@ -1383,7 +1441,7 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst) if (rc) goto error; - rc = msm_vidc_cvp_dme_basic_config(inst); + rc = msm_cvp_dme_basic_config(inst); if (rc) goto error; @@ -1391,14 +1449,14 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst) if (rc) goto error; - rc = msm_vidc_cvp_session_start(inst); + rc = msm_cvp_session_start(inst); if (rc) goto error; return 0; error: - msm_vidc_cvp_deinit(inst); + msm_cvp_deinit(inst); return rc; } @@ -1415,11 +1473,11 @@ int msm_vidc_cvp_prepare_preprocess(struct msm_vidc_inst *inst) if (rc) return rc; - rc = msm_vidc_cvp_open(inst); + rc = msm_cvp_session_open(inst); if (rc) return rc; - rc = msm_vidc_cvp_init(inst); + rc = msm_cvp_init(inst); if (rc) return rc; diff --git a/msm/vidc/msm_cvp_external.h b/msm/vidc/msm_cvp_external.h index b0f14c8127d2..eb33fc0ef7e2 100644 --- a/msm/vidc/msm_cvp_external.h +++ b/msm/vidc/msm_cvp_external.h @@ -155,11 +155,19 @@ struct msm_cvp_dme_basic_config_packet { u32 ransac_threshold; }; +enum msm_vidc_cvp_buf_type { + MSM_VIDC_CVP_INPUT_BUF = 1, + MSM_VIDC_CVP_OUTPUT_BUF, + MSM_VIDC_CVP_PERSIST_BUF, + MSM_VIDC_CVP_CONTEXT_BUF +}; + struct msm_cvp_buf { u32 index; - int fd; u32 size; u32 offset; + u32 buf_type; + int fd; struct dma_buf *dbuf; void *kvaddr; }; diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index f72719a38d88..ee48108efbf1 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -766,7 +766,6 @@ bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst) inst->rc_type != RATE_CONTROL_OFF && inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ && !inst->clk_data.is_legacy_cbr && - !is_secure_session(inst) && !superframe_enable->val) { s_vpr_h(inst->sid, "%s: cvp allowed\n", __func__); allowed = true; From bba6fe37af6afdf89abb7a7461ecaa5c30cc4e65 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 4 Sep 2019 11:38:34 +0530 Subject: [PATCH 160/452] msm: vidc: print session specific logs based on logmask print logs based on logmask set on debugfs entry (/d/msm_vidc/debug_level) [1] 0xx -> print logs for all session type [2] 1xx -> print only encoder logs [3] 2xx -> print only decoder logs [4] 4xx -> print only cvp logs Change-Id: I8e01ee9c8b80a50b178ea87bf25d7ef25401f67a Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_debug.c | 33 ++++++++++++++++++++++++++++++--- msm/vidc/msm_vidc_debug.h | 10 +++++++--- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index 6be7fd301782..e5a1bc0deee3 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -600,7 +600,7 @@ int msm_vidc_check_ratelimit(void) /** * get_sid() must be called under "&core->lock" - * to avoid race condition in occurring empty slot. + * to avoid race condition at occupying empty slot. */ int get_sid(u32 *sid, u32 session_type) { @@ -633,6 +633,7 @@ inline void update_log_ctxt(u32 sid, u32 session_type, u32 fourcc) { const char *codec; char type; + u32 s_type = 0; if (!sid || sid > MAX_SUPPORTED_INSTANCES) { d_vpr_e("%s: invalid sid %#x\n", @@ -676,28 +677,54 @@ inline void update_log_ctxt(u32 sid, u32 session_type, u32 fourcc) switch (session_type) { case MSM_VIDC_ENCODER: type = 'e'; + s_type = VIDC_ENCODER; break; case MSM_VIDC_DECODER: type = 'd'; + s_type = VIDC_DECODER; break; case MSM_VIDC_CVP: type = 'c'; + s_type = VIDC_CVP; default: type = '.'; break; } - ctxt[sid-1].session_type = session_type; + ctxt[sid-1].session_type = s_type; ctxt[sid-1].codec_type = fourcc; memcpy(&ctxt[sid-1].name, codec, 4); ctxt[sid-1].name[4] = type; ctxt[sid-1].name[5] = '\0'; } -char *get_codec_name(u32 sid) +inline char *get_codec_name(u32 sid) { if (!sid || sid > MAX_SUPPORTED_INSTANCES) return "....."; return ctxt[sid-1].name; } + +/** + * 0xx -> allow prints for all sessions + * 1xx -> allow only encoder prints + * 2xx -> allow only decoder prints + * 4xx -> allow only cvp prints + */ +inline bool is_print_allowed(u32 sid, u32 level) +{ + if (!(msm_vidc_debug & level)) + return false; + + if (!((msm_vidc_debug >> 8) & 0xF)) + return true; + + if (!sid || sid > MAX_SUPPORTED_INSTANCES) + return true; + + if (ctxt[sid-1].session_type & msm_vidc_debug) + return true; + + return false; +} diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index a3b2c99b0471..89a0f8df0663 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -40,6 +40,9 @@ enum vidc_msg_prio { VIDC_PERF = 0x00000008, VIDC_PKT = 0x00000010, VIDC_BUS = 0x00000020, + VIDC_ENCODER = 0x00000100, + VIDC_DECODER = 0x00000200, + VIDC_CVP = 0x00000400, VIDC_PRINTK = 0x00001000, VIDC_FTRACE = 0x00002000, FW_LOW = 0x00010000, @@ -79,7 +82,7 @@ struct log_cookie { #define dprintk(__level, sid, __fmt, ...) \ do { \ - if (msm_vidc_debug & __level) { \ + if (is_print_allowed(sid, __level)) { \ if (msm_vidc_debug & VIDC_FTRACE) { \ char trace_logbuf[MAX_TRACER_LOG_LENGTH]; \ int log_length = snprintf(trace_logbuf, \ @@ -167,8 +170,9 @@ void msm_vidc_debugfs_update(struct msm_vidc_inst *inst, int msm_vidc_check_ratelimit(void); int get_sid(u32 *sid, u32 session_type); void update_log_ctxt(u32 sid, u32 session_type, u32 fourcc); -char *get_codec_name(u32 sid); -void put_sid(u32 sid); +inline char *get_codec_name(u32 sid); +inline void put_sid(u32 sid); +inline bool is_print_allowed(u32 sid, u32 level); static inline char *get_debug_level_str(int level) { From 530762b1be86223ff89df0d4c7f2c55046d570a1 Mon Sep 17 00:00:00 2001 From: Shivendra Kakrania Date: Wed, 31 Jul 2019 17:33:38 -0700 Subject: [PATCH 161/452] msm: vidc: Enable error recovery by default Error recovery is enabled by default & it will get triggered for all sys error reported by video firmware. For debugging purpose it can be disabled as: 1. disable error recovery for noc error: echo 1 > /d/msm_vidc/disable_err_recovery 2. disable error recovery for non-noc error: echo 2 > /d/msm_vidc/disable_err_recovery 3. disable error recovery for all cases echo 3 > /d/msm_vidc/disable_err_recovery Change-Id: Ie260485842704d3e278ded8c6d1722bc19c80f6f Signed-off-by: Shivendra Kakrania --- msm/vidc/msm_vidc_common.c | 8 ++++++-- msm/vidc/msm_vidc_debug.c | 5 ++++- msm/vidc/msm_vidc_debug.h | 6 ++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 238c359e29d6..60f8d6e79d84 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2231,8 +2231,12 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) /* handle the hw error before core released to get full debug info */ msm_vidc_handle_hw_error(core); - if (response->status == VIDC_ERR_NOC_ERROR) { - d_vpr_e("Got NOC error"); + if ((response->status == VIDC_ERR_NOC_ERROR && + (msm_vidc_err_recovery_disable & + VIDC_DISABLE_NOC_ERR_RECOV)) || + (msm_vidc_err_recovery_disable & + VIDC_DISABLE_NON_NOC_ERR_RECOV)) { + d_vpr_e("Got unrecoverable video fw error"); MSM_VIDC_ERROR(true); } diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index 6be7fd301782..a9d9d6bf73bb 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -23,6 +23,7 @@ bool msm_vidc_thermal_mitigation_disabled = !true; int msm_vidc_clock_voting = !1; bool msm_vidc_syscache_disable = !true; bool msm_vidc_cvp_usage = true; +int msm_vidc_err_recovery_disable = !1; #define MAX_DBG_BUF_SIZE 4096 @@ -239,7 +240,9 @@ struct dentry *msm_vidc_debugfs_init_drv(void) &msm_vidc_syscache_disable) && __debugfs_create(bool, "cvp_usage", &msm_vidc_cvp_usage) && __debugfs_create(bool, "lossless_encoding", - &msm_vidc_lossless_encode); + &msm_vidc_lossless_encode) && + __debugfs_create(u32, "disable_err_recovery", + &msm_vidc_err_recovery_disable); #undef __debugfs_create diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index a3b2c99b0471..8186e545313d 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -61,6 +61,11 @@ enum msm_vidc_debugfs_event { MSM_VIDC_DEBUGFS_EVENT_FBD, }; +enum vidc_err_recovery_disable { + VIDC_DISABLE_NOC_ERR_RECOV = 0x0001, + VIDC_DISABLE_NON_NOC_ERR_RECOV = 0x0002 +}; + extern int msm_vidc_debug; extern int msm_vidc_fw_debug_mode; extern bool msm_vidc_fw_coverage; @@ -69,6 +74,7 @@ extern int msm_vidc_clock_voting; extern bool msm_vidc_syscache_disable; extern bool msm_vidc_lossless_encode; extern bool msm_vidc_cvp_usage; +extern int msm_vidc_err_recovery_disable; struct log_cookie { u32 used; From 09e8935f10f7ad7aeab20771185a72709ba2015c Mon Sep 17 00:00:00 2001 From: Karthikeyan Periasamy Date: Tue, 24 Sep 2019 17:22:07 -0700 Subject: [PATCH 162/452] msm: vidc: Lahaina bringup - Stage I Bring all the missing changes from Kona aa56c67 msm: vidc: Set fps to 1 for image encode sessions bc60bd6 msm: vidc: Add support of level 6.1 to VP9 decoder 349732b msm: vidc: update LTRUse maximum limit 9d3a015 msm-vidc: calculate buffer size based on 512x512 for heic 46e2095 msm: vidc: Update Kona Profile Level Capabilities ad8cd1c msm: vidc: delete v4l2 controls after queue release ea1efd0 msm: vidc: Initialize core ops for bengal VPU version 533aa1c msm: vidc: don't skip set ctrl for the same value e52cd53 msm: vidc: use macro to get/set fields 92344f3 msm: vidc: Add new hfi file for AR50 lite 1931ba3 msm: vidc: Update bitrate constraint check 733ea29 msm: vidc: Add bengal specific functions 81b07d4 msm: vidc: Update control capabilities at SESSION_INIT stage f3e9363 msm: vidc: deprecate firmware buffer requirement property 557ca13 msm: vidc: Update VSP cycle count calculation 7ff089a msm: vidc: fix kw issues b9733c7 msm: vidc: Add config files for bengal 1b0c12b msm: vidc: Allow all-intra encoding in CBR_CFR 3ca1cf0 msm: vidc: Add platform specific data a16c617 msm_vidc: venc: update HEIF output buffer count 622514e msm: vidc: fix extradata none parsing issue 1f61e2c msm: vidc: Update mb/frame resolution to 4096x2304 16ffe6b msm: vidc: add dynamic support of frame quality 46f2efd msm-vidc: return unknown ctrl for internal cvp client 043315f msm: vidc: add support for dpb_buffer_count payload Change-Id: Iee095078d8cd558ea030e65e8d1895b4c7d78948 Signed-off-by: Karthikeyan Periasamy --- config/bengalvid.conf | 1 + config/bengalvidconf.h | 6 + msm/Makefile | 1 + msm/vidc/hfi_ar50_lt.c | 238 ++++++++++++++++++++++++ msm/vidc/hfi_common.c | 18 +- msm/vidc/hfi_common.h | 9 + msm/vidc/hfi_response_handler.c | 51 ++--- msm/vidc/msm_cvp_external.c | 3 +- msm/vidc/msm_cvp_internal.c | 12 +- msm/vidc/msm_venc.c | 106 +++++++++-- msm/vidc/msm_venc.h | 2 + msm/vidc/msm_vidc.c | 27 +-- msm/vidc/msm_vidc_buffer_calculations.c | 14 ++ msm/vidc/msm_vidc_clocks.c | 87 ++++++--- msm/vidc/msm_vidc_common.c | 184 +++++++++--------- msm/vidc/msm_vidc_common.h | 14 ++ msm/vidc/msm_vidc_debug.c | 2 +- msm/vidc/msm_vidc_internal.h | 9 +- msm/vidc/msm_vidc_platform.c | 227 ++++++++++++++++++++-- msm/vidc/vidc_hfi.h | 2 + msm/vidc/vidc_hfi_api.h | 19 +- msm/vidc/vidc_hfi_helper.h | 8 + 22 files changed, 826 insertions(+), 214 deletions(-) create mode 100644 config/bengalvid.conf create mode 100644 config/bengalvidconf.h create mode 100644 msm/vidc/hfi_ar50_lt.c diff --git a/config/bengalvid.conf b/config/bengalvid.conf new file mode 100644 index 000000000000..efb4eedfb73e --- /dev/null +++ b/config/bengalvid.conf @@ -0,0 +1 @@ +export CONFIG_MSM_VIDC_V4L2=y diff --git a/config/bengalvidconf.h b/config/bengalvidconf.h new file mode 100644 index 000000000000..78d6c57a6920 --- /dev/null +++ b/config/bengalvidconf.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#define CONFIG_MSM_VIDC_V4L2 1 diff --git a/msm/Makefile b/msm/Makefile index d16933a7f464..df7f6020801b 100644 --- a/msm/Makefile +++ b/msm/Makefile @@ -16,6 +16,7 @@ msm-vidc-objs := vidc/msm_v4l2_vidc.o \ vidc/msm_vidc_res_parse.o \ vidc/hfi_common.o \ vidc/hfi_ar50.o \ + vidc/hfi_ar50_lt.o \ vidc/hfi_iris1.o \ vidc/hfi_iris2.o \ vidc/hfi_response_handler.o \ diff --git a/msm/vidc/hfi_ar50_lt.c b/msm/vidc/hfi_ar50_lt.c new file mode 100644 index 000000000000..e39a7cd0885f --- /dev/null +++ b/msm/vidc/hfi_ar50_lt.c @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include "msm_vidc_debug.h" +#include "hfi_common.h" + +#define VIDC_CPU_BASE_OFFS_AR50_LT 0x000A0000 +#define VIDEO_GCC_BASE_OFFS_AR50_LT 0x00000000 +#define VIDEO_CC_BASE_OFFS_AR50_LT 0x00100000 + +#define VIDC_CPU_CS_BASE_OFFS_AR50_LT (VIDC_CPU_BASE_OFFS_AR50_LT) +#define VIDC_CPU_IC_BASE_OFFS_AR50_LT (VIDC_CPU_BASE_OFFS_AR50_LT) + +#define VIDC_CPU_CS_A2HSOFTINTCLR_AR50_LT (VIDC_CPU_CS_BASE_OFFS_AR50_LT + 0x1C) +#define VIDC_CPU_CS_VMIMSG_AR50_LTi (VIDC_CPU_CS_BASE_OFFS_AR50_LT + 0x34) +#define VIDC_CPU_CS_VMIMSGAG0_AR50_LT (VIDC_CPU_CS_BASE_OFFS_AR50_LT + 0x38) +#define VIDC_CPU_CS_VMIMSGAG1_AR50_LT (VIDC_CPU_CS_BASE_OFFS_AR50_LT + 0x3C) +#define VIDC_CPU_CS_VMIMSGAG2_AR50_LT (VIDC_CPU_CS_BASE_OFFS_AR50_LT + 0x40) +#define VIDC_CPU_CS_VMIMSGAG3_AR50_LT (VIDC_CPU_CS_BASE_OFFS_AR50_LT + 0x44) +#define VIDC_CPU_CS_SCIACMD_AR50_LT (VIDC_CPU_CS_BASE_OFFS_AR50_LT + 0x48) + +/* HFI_CTRL_STATUS */ +#define VIDC_CPU_CS_SCIACMDARG0_AR50_LT (VIDC_CPU_CS_BASE_OFFS_AR50_LT + 0x4C) +#define VIDC_CPU_CS_SCIACMDARG0_BMSK_AR50_LT 0xff +#define VIDC_CPU_CS_SCIACMDARG0_SHFT_AR50_LT 0x0 +#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_AR50_LT 0xfe +#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_SHFT_AR50_LT 0x1 +#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_BMSK_AR50_LT 0x1 +#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_SHFT_AR50_LT 0x0 +#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY_AR50_LT 0x100 +#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK_AR50_LT 0x40000000 + +/* HFI_QTBL_INFO */ +#define VIDC_CPU_CS_SCIACMDARG1_AR50_LT (VIDC_CPU_CS_BASE_OFFS_AR50_LT + 0x50) + +/* HFI_QTBL_ADDR */ +#define VIDC_CPU_CS_SCIACMDARG2_AR50_LT (VIDC_CPU_CS_BASE_OFFS_AR50_LT + 0x54) + +/* HFI_VERSION_INFO */ +#define VIDC_CPU_CS_SCIACMDARG3_AR50_LT (VIDC_CPU_CS_BASE_OFFS_AR50_LT + 0x58) + +/* VIDC_SFR_ADDR */ +#define VIDC_CPU_CS_SCIBCMD_AR50_LT (VIDC_CPU_CS_BASE_OFFS_AR50_LT + 0x5C) + +/* VIDC_MMAP_ADDR */ +#define VIDC_CPU_CS_SCIBCMDARG0_AR50_LT (VIDC_CPU_CS_BASE_OFFS_AR50_LT + 0x60) + +/* VIDC_UC_REGION_ADDR */ +#define VIDC_CPU_CS_SCIBARG1_AR50_LT (VIDC_CPU_CS_BASE_OFFS_AR50_LT + 0x64) + +/* VIDC_UC_REGION_ADDR */ +#define VIDC_CPU_CS_SCIBARG2_AR50_LT (VIDC_CPU_CS_BASE_OFFS_AR50_LT + 0x68) + +#define VIDC_CPU_IC_SOFTINT_AR50_LT (VIDC_CPU_IC_BASE_OFFS_AR50_LT + 0x150) +#define VIDC_CPU_IC_SOFTINT_H2A_BMSK_AR50_LT 0x8000 +#define VIDC_CPU_IC_SOFTINT_H2A_SHFT_AR50_LT 0x1 + +/* + * -------------------------------------------------------------------------- + * MODULE: vidc_wrapper + * -------------------------------------------------------------------------- + */ +#define VIDC_WRAPPER_BASE_OFFS_AR50_LT 0x000B0000 + +#define VIDC_WRAPPER_HW_VERSION_AR50_LT (VIDC_WRAPPER_BASE_OFFS_AR50_LT + 0x00) +#define VIDC_WRAPPER_HW_VERSION_MAJOR_VERSION_MASK_AR50_LT 0x78000000 +#define VIDC_WRAPPER_HW_VERSION_MAJOR_VERSION_SHIFT_AR50_LT 28 +#define VIDC_WRAPPER_HW_VERSION_MINOR_VERSION_MASK_AR50_LT 0xFFF0000 +#define VIDC_WRAPPER_HW_VERSION_MINOR_VERSION_SHIFT_AR50_LT 16 +#define VIDC_WRAPPER_HW_VERSION_STEP_VERSION_MASK_AR50_LT 0xFFFF + +#define VIDC_WRAPPER_CLOCK_CONFIG_AR50_LT (VIDC_WRAPPER_BASE_OFFS_AR50_LT + 0x04) + +#define VIDC_WRAPPER_INTR_STATUS_AR50_LT (VIDC_WRAPPER_BASE_OFFS_AR50_LT + 0x0C) +#define VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK_AR50_LT 0x10 +#define VIDC_WRAPPER_INTR_STATUS_A2HWD_SHFT_AR50_LT 0x4 +#define VIDC_WRAPPER_INTR_STATUS_A2H_BMSK_AR50_LT 0x4 +#define VIDC_WRAPPER_INTR_STATUS_A2H_SHFT_AR50_LT 0x2 + +#define VIDC_WRAPPER_INTR_MASK_AR50_LT (VIDC_WRAPPER_BASE_OFFS_AR50_LT + 0x10) +#define VIDC_WRAPPER_INTR_MASK_A2HWD_BMSK_AR50_LT 0x10 +#define VIDC_WRAPPER_INTR_MASK_A2HWD_SHFT_AR50_LT 0x4 +#define VIDC_WRAPPER_INTR_MASK_A2HVCODEC_BMSK_AR50_LT 0x8 +#define VIDC_WRAPPER_INTR_MASK_A2HCPU_BMSK_AR50_LT 0x4 +#define VIDC_WRAPPER_INTR_MASK_A2HCPU_SHFT_AR50_LT 0x2 + +#define VIDC_WRAPPER_INTR_CLEAR_AR50_LT (VIDC_WRAPPER_BASE_OFFS_AR50_LT + 0x14) +#define VIDC_WRAPPER_INTR_CLEAR_A2HWD_BMSK_AR50_LT 0x10 +#define VIDC_WRAPPER_INTR_CLEAR_A2HWD_SHFT_AR50_LT 0x4 +#define VIDC_WRAPPER_INTR_CLEAR_A2H_BMSK_AR50_LT 0x4 +#define VIDC_WRAPPER_INTR_CLEAR_A2H_SHFT_AR50_LT 0x2 + +#define VIDC_CTRL_INIT_AR50_LT VIDC_CPU_CS_SCIACMD_AR50_LT + +#define VIDC_CTRL_STATUS_AR50_LT VIDC_CPU_CS_SCIACMDARG0_AR50_LT +#define VIDC_CTRL_ERROR_STATUS__M_AR50_LT \ + VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_AR50_LT +#define VIDC_CTRL_INIT_IDLE_MSG_BMSK_AR50_LT \ + VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK_AR50_LT +#define VIDC_CTRL_STATUS_PC_READY_AR50_LT \ + VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY_AR50_LT + +#define VIDC_QTBL_INFO_AR50_LT VIDC_CPU_CS_SCIACMDARG1_AR50_LT +#define VIDC_QTBL_ADDR_AR50_LT VIDC_CPU_CS_SCIACMDARG2_AR50_LT +#define VIDC_VERSION_INFO_AR50_LT VIDC_CPU_CS_SCIACMDARG3_AR50_LT + +#define VIDC_SFR_ADDR_AR50_LT VIDC_CPU_CS_SCIBCMD_AR50_LT +#define VIDC_MMAP_ADDR_AR50_LT VIDC_CPU_CS_SCIBCMDARG0_AR50_LT +#define VIDC_UC_REGION_ADDR_AR50_LT VIDC_CPU_CS_SCIBARG1_AR50_LT +#define VIDC_UC_REGION_SIZE_AR50_LT VIDC_CPU_CS_SCIBARG2_AR50_LT + +void __interrupt_init_ar50_lt(struct venus_hfi_device *device, u32 sid) +{ + __write_register(device, VIDC_WRAPPER_INTR_MASK_AR50_LT, + VIDC_WRAPPER_INTR_MASK_A2HVCODEC_BMSK_AR50_LT, sid); +} + +void __setup_ucregion_memory_map_ar50_lt(struct venus_hfi_device *device, u32 sid) +{ + __write_register(device, VIDC_UC_REGION_ADDR_AR50_LT, + (u32)device->iface_q_table.align_device_addr, sid); + __write_register(device, VIDC_UC_REGION_SIZE_AR50_LT, SHARED_QSIZE, sid); + __write_register(device, VIDC_QTBL_ADDR_AR50_LT, + (u32)device->iface_q_table.align_device_addr, sid); + __write_register(device, VIDC_QTBL_INFO_AR50_LT, 0x01, sid); + if (device->sfr.align_device_addr) + __write_register(device, VIDC_SFR_ADDR_AR50_LT, + (u32)device->sfr.align_device_addr, sid); + if (device->qdss.align_device_addr) + __write_register(device, VIDC_MMAP_ADDR_AR50_LT, + (u32)device->qdss.align_device_addr, sid); +} + +void __power_off_ar50_lt(struct venus_hfi_device *device) +{ + if (!device->power_enabled) + return; + + if (!(device->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK_AR50_LT)) + disable_irq_nosync(device->hal_data->irq); + device->intr_status = 0; + + __disable_unprepare_clks(device); + if (__disable_regulators(device)) + d_vpr_e("Failed to disable regulators\n"); + + if (__unvote_buses(device, DEFAULT_SID)) + d_vpr_e("Failed to unvote for buses\n"); + device->power_enabled = false; +} + +int __prepare_pc_ar50_lt(struct venus_hfi_device *device) +{ + int rc = 0; + u32 wfi_status = 0, idle_status = 0, pc_ready = 0; + u32 ctrl_status = 0; + + ctrl_status = __read_register(device, VIDC_CTRL_STATUS_AR50_LT, DEFAULT_SID); + pc_ready = ctrl_status & VIDC_CTRL_STATUS_PC_READY_AR50_LT; + idle_status = ctrl_status & BIT(30); + + if (pc_ready) { + d_vpr_l("Already in pc_ready state\n"); + return 0; + } + rc = __prepare_pc(device); + if (rc) { + d_vpr_e("Failed __prepare_pc %d\n", rc); + goto skip_power_off; + } + return rc; + +skip_power_off: + d_vpr_e("Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n", + wfi_status, idle_status, pc_ready, ctrl_status); + return -EAGAIN; +} + +void __raise_interrupt_ar50_lt(struct venus_hfi_device *device, u32 sid) +{ + __write_register(device, VIDC_CPU_IC_SOFTINT_AR50_LT, + VIDC_CPU_IC_SOFTINT_H2A_SHFT_AR50_LT, sid); +} + +void __core_clear_interrupt_ar50_lt(struct venus_hfi_device *device) +{ + u32 intr_status = 0, mask = 0; + + if (!device) { + d_vpr_e("%s: NULL device\n", __func__); + return; + } + + intr_status = __read_register(device, VIDC_WRAPPER_INTR_STATUS_AR50_LT, DEFAULT_SID); + mask = (VIDC_WRAPPER_INTR_STATUS_A2H_BMSK_AR50_LT | + VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK_AR50_LT | + VIDC_CTRL_INIT_IDLE_MSG_BMSK_AR50_LT); + + if (intr_status & mask) { + device->intr_status |= intr_status; + device->reg_count++; + d_vpr_l( + "INTERRUPT for device: %pK: times: %d interrupt_status: %d\n", + device, device->reg_count, intr_status); + } else { + device->spur_count++; + } + + __write_register(device, VIDC_CPU_CS_A2HSOFTINTCLR_AR50_LT, 1, DEFAULT_SID); + __write_register(device, VIDC_WRAPPER_INTR_CLEAR_AR50_LT, intr_status, DEFAULT_SID); +} + +int __boot_firmware_ar50_lt(struct venus_hfi_device *device, u32 sid) +{ + int rc = 0; + u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 1000; + + ctrl_init_val = BIT(0); + + __write_register(device, VIDC_CTRL_INIT_AR50_LT, ctrl_init_val, sid); + while (!ctrl_status && count < max_tries) { + ctrl_status = __read_register(device, VIDC_CTRL_STATUS_AR50_LT, sid); + if ((ctrl_status & VIDC_CTRL_ERROR_STATUS__M_AR50_LT) == 0x4) { + s_vpr_e(sid, "invalid setting for UC_REGION\n"); + break; + } + usleep_range(50, 100); + count++; + } + + if (count >= max_tries) { + s_vpr_e(sid, "Error booting up vidc firmware\n"); + rc = -ETIME; + } + return rc; +} diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 162db79feff3..61a84c954c39 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -133,6 +133,20 @@ struct venus_hfi_vpu_ops vpu4_ops = { .boot_firmware = __boot_firmware_common, }; +struct venus_hfi_vpu_ops ar50_lite_ops = { + .interrupt_init = __interrupt_init_ar50_lt, + .setup_ucregion_memmap = __setup_ucregion_memory_map_ar50_lt, + .clock_config_on_enable = NULL, + .reset_ahb2axi_bridge = NULL, + .power_off = __power_off_ar50_lt, + .prepare_pc = __prepare_pc_ar50_lt, + .raise_interrupt = __raise_interrupt_ar50_lt, + .watchdog = __watchdog_common, + .noc_error_info = __noc_error_info_common, + .core_clear_interrupt = __core_clear_interrupt_ar50_lt, + .boot_firmware = __boot_firmware_ar50_lt, +}; + struct venus_hfi_vpu_ops iris1_ops = { .interrupt_init = __interrupt_init_iris1, .setup_ucregion_memmap = __setup_ucregion_memory_map_iris1, @@ -1039,7 +1053,7 @@ static int __vote_buses(struct venus_hfi_device *device, bus->range[0], bus->range[1]); if (TRIVIAL_BW_CHANGE(bw_kbps, bw_prev) && bw_prev) { - s_vpr_p(sid, "Skip voting bus %s to %llu bps", + s_vpr_l(sid, "Skip voting bus %s to %llu bps", bus->name, bw_kbps * 1000); continue; } @@ -4773,6 +4787,8 @@ void __init_venus_ops(struct venus_hfi_device *device) { if (device->res->vpu_ver == VPU_VERSION_AR50) device->vpu_ops = &vpu4_ops; + else if (device->res->vpu_ver == VPU_VERSION_AR50_LITE) + device->vpu_ops = &ar50_lite_ops; else if (device->res->vpu_ver == VPU_VERSION_IRIS1) device->vpu_ops = &iris1_ops; else diff --git a/msm/vidc/hfi_common.h b/msm/vidc/hfi_common.h index 500d73091a2a..2ac3802aab1e 100644 --- a/msm/vidc/hfi_common.h +++ b/msm/vidc/hfi_common.h @@ -321,4 +321,13 @@ void __noc_error_info_iris2(struct venus_hfi_device *device); void __core_clear_interrupt_iris2(struct venus_hfi_device *device); int __boot_firmware_iris2(struct venus_hfi_device *device, u32 sid); +/* AR50_LITE specific */ +void __interrupt_init_ar50_lt(struct venus_hfi_device *device, u32 sid); +void __setup_ucregion_memory_map_ar50_lt(struct venus_hfi_device *device, u32 sid); +void __power_off_ar50_lt(struct venus_hfi_device *device); +int __prepare_pc_ar50_lt(struct venus_hfi_device *device); +void __raise_interrupt_ar50_lt(struct venus_hfi_device *device, u32 sid); +void __core_clear_interrupt_ar50_lt(struct venus_hfi_device *device); +int __boot_firmware_ar50_lt(struct venus_hfi_device *device, u32 sid); + #endif diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index 81d833dc3920..c46b15ff9983 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -109,8 +109,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, struct hfi_profile_level *profile_level; struct hfi_bit_depth *pixel_depth; struct hfi_pic_struct *pic_struct; - struct hfi_buffer_requirements *buf_req; - struct hfi_index_extradata_input_crop_payload *crop_info; + struct hfi_dpb_counts *dpb_counts; u32 rem_size,entropy_mode = 0; u8 *data_ptr; int prop_id; @@ -263,13 +262,6 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, hfi_buffer_requirements))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); - buf_req = - (struct hfi_buffer_requirements *) - data_ptr; - event_notify.capture_buf_count = - buf_req->buffer_count_min; - s_vpr_hp(sid, "Capture Count : 0x%x\n", - event_notify.capture_buf_count); data_ptr += sizeof(struct hfi_buffer_requirements); rem_size -= @@ -280,26 +272,39 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, hfi_index_extradata_input_crop_payload))) return -E2BIG; data_ptr = data_ptr + sizeof(u32); - crop_info = (struct - hfi_index_extradata_input_crop_payload *) - data_ptr; - event_notify.crop_data.left = crop_info->left; - event_notify.crop_data.top = crop_info->top; - event_notify.crop_data.width = crop_info->width; - event_notify.crop_data.height = - crop_info->height; - s_vpr_h(sid, - "CROP info : Left = %d Top = %d\n", - crop_info->left, crop_info->top); - s_vpr_h(sid, - "CROP info : Width = %d Height = %d\n", - crop_info->width, crop_info->height); data_ptr += sizeof(struct hfi_index_extradata_input_crop_payload); rem_size -= sizeof(struct hfi_index_extradata_input_crop_payload); break; + case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS: + if (!validate_pkt_size(rem_size, sizeof(struct + hfi_dpb_counts))) + return -E2BIG; + data_ptr = data_ptr + sizeof(u32); + dpb_counts = (struct hfi_dpb_counts *) data_ptr; + event_notify.max_dpb_count = + dpb_counts->max_dpb_count; + event_notify.max_ref_frames = + dpb_counts->max_ref_frames; + event_notify.max_dec_buffering = + dpb_counts->max_dec_buffering; + event_notify.max_reorder_frames = + dpb_counts->max_reorder_frames; + event_notify.fw_min_cnt = + dpb_counts->fw_min_cnt; + s_vpr_h(sid, + "FW DPB counts: dpb %d ref %d buff %d reorder %d fw_min_cnt %d\n", + dpb_counts->max_dpb_count, + dpb_counts->max_ref_frames, + dpb_counts->max_dec_buffering, + dpb_counts->max_reorder_frames, + dpb_counts->fw_min_cnt); + data_ptr += + sizeof(struct hfi_dpb_counts); + rem_size -= sizeof(struct hfi_dpb_counts); + break; default: s_vpr_e(sid, "%s: cmd: %#x not supported\n", __func__, prop_id); diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index e6b133889496..74b2e8971b65 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -755,7 +755,8 @@ static int msm_cvp_prepare_extradata(struct msm_vidc_inst *inst, found_end = true; break; } - e_hdr += e_hdr->size; + e_hdr = (struct msm_vidc_extradata_header *) + ((char *)e_hdr + e_hdr->size); } if (!found_end) { s_vpr_e(inst->sid, "%s: extradata_none not found\n", __func__); diff --git a/msm/vidc/msm_cvp_internal.c b/msm/vidc/msm_cvp_internal.c index f0788d9ba41d..36a74ded11b7 100644 --- a/msm/vidc/msm_cvp_internal.c +++ b/msm/vidc/msm_cvp_internal.c @@ -106,8 +106,8 @@ void handle_session_register_buffer_done(enum hal_command_response cmd, v4l2_event_queue_fh(&inst->event_handler, &event); exit: - put_inst(inst); s_vpr_l(inst->sid, "handled: SESSION_REGISTER_BUFFER_DONE\n"); + put_inst(inst); } void handle_session_unregister_buffer_done(enum hal_command_response cmd, @@ -170,8 +170,8 @@ void handle_session_unregister_buffer_done(enum hal_command_response cmd, kfree(cbuf); cbuf = NULL; exit: - put_inst(inst); s_vpr_l(inst->sid, "handled: SESSION_UNREGISTER_BUFFER_DONE\n"); + put_inst(inst); } static void print_cvp_cycles(struct msm_vidc_inst *inst) @@ -510,11 +510,11 @@ int msm_vidc_cvp(struct msm_vidc_inst *inst, struct msm_vidc_arg *arg) static struct msm_vidc_ctrl msm_cvp_ctrls[] = { { - .id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE, - .name = "Secure mode", - .type = V4L2_CTRL_TYPE_BUTTON, + .id = V4L2_CID_MPEG_VIDEO_UNKNOWN, + .name = "Invalid control", + .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, - .maximum = 1, + .maximum = 0, .default_value = 0, .step = 1, .menu_skip_mask = 0, diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 26452da8c3e8..f02cbba6de0b 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -219,7 +219,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .name = "Image grid size", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, - .maximum = 512, + .maximum = HEIC_GRID_DIMENSION, .default_value = 0, .step = 1, .qmenu = NULL, @@ -531,7 +531,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .name = "H264 Use LTR", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, - .maximum = (MAX_LTR_FRAME_COUNT - 1), + .maximum = ((1 << MAX_LTR_FRAME_COUNT) - 1), .default_value = 0, .step = 1, .qmenu = NULL, @@ -1041,17 +1041,17 @@ struct msm_vidc_format_constraint enc_pix_format_constraints[] = { { .fourcc = V4L2_PIX_FMT_NV12_512, .num_planes = 2, - .y_max_stride = 8192, + .y_max_stride = 16384, .y_buffer_alignment = 512, - .uv_max_stride = 8192, + .uv_max_stride = 16384, .uv_buffer_alignment = 256, }, { .fourcc = V4L2_PIX_FMT_NV12, .num_planes = 2, - .y_max_stride = 8192, + .y_max_stride = 16384, .y_buffer_alignment = 512, - .uv_max_stride = 8192, + .uv_max_stride = 16384, .uv_buffer_alignment = 256, }, { @@ -1557,6 +1557,8 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) rc = msm_venc_resolve_rate_control(inst, ctrl); if (rc) s_vpr_e(sid, "%s: set bitrate mode failed\n", __func__); + if (inst->state < MSM_VIDC_LOAD_RESOURCES) + msm_vidc_calculate_buffer_counts(inst); break; } case V4L2_CID_MPEG_VIDEO_BITRATE: @@ -1570,6 +1572,12 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE: inst->clk_data.frame_rate = ctrl->val; + /* For HEIC image encode, set fps to 1 */ + if (is_grid_session(inst)) { + s_vpr_h(sid, "%s: set fps to 1 for HEIC\n", + __func__); + inst->clk_data.frame_rate = 1 << 16; + } if (inst->state < MSM_VIDC_LOAD_RESOURCES) msm_vidc_calculate_buffer_counts(inst); if (inst->state == MSM_VIDC_START_DONE) { @@ -1615,7 +1623,6 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) inst->flags &= ~VIDC_TURBO; if (ctrl->val == INT_MAX) inst->flags |= VIDC_TURBO; - if (inst->state < MSM_VIDC_LOAD_RESOURCES) msm_vidc_calculate_buffer_counts(inst); if (inst->state == MSM_VIDC_START_DONE) { @@ -1837,9 +1844,24 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) __func__); } break; - case V4L2_CID_MPEG_VIDC_CAPTURE_FRAME_RATE: case V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY: + if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_set_frame_quality(inst); + if (rc) + s_vpr_e(sid, + "%s: set frame quality failed\n", + __func__); + } + break; case V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE: + /* For HEIC image encode, set fps to 1 */ + if (ctrl->val) { + s_vpr_h(sid, "%s: set fps to 1 for HEIC\n", + __func__); + inst->clk_data.frame_rate = 1 << 16; + } + break; + case V4L2_CID_MPEG_VIDC_CAPTURE_FRAME_RATE: case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER: case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: case V4L2_CID_ROTATE: @@ -1920,6 +1942,11 @@ int msm_venc_set_frame_size(struct msm_vidc_inst *inst) frame_sz.buffer_type = HFI_BUFFER_OUTPUT; frame_sz.width = f->fmt.pix_mp.width; frame_sz.height = f->fmt.pix_mp.height; + /* firmware needs grid size in output where as + * client sends out full resolution in output port */ + if (is_grid_session(inst)) { + frame_sz.width = frame_sz.height = HEIC_GRID_DIMENSION; + } s_vpr_h(inst->sid, "%s: output %d %d\n", __func__, frame_sz.width, frame_sz.height); rc = call_hfi_op(hdev, session_set_property, inst->session, @@ -2925,13 +2952,12 @@ static void set_heif_preconditions(struct msm_vidc_inst *inst) return; } -int msm_venc_set_image_properties(struct msm_vidc_inst *inst) +int msm_venc_set_frame_quality(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; struct v4l2_ctrl *ctrl; struct hfi_heic_frame_quality frame_quality; - struct hfi_heic_grid_enable grid_enable; if (!inst || !inst->core) { d_vpr_e("%s: invalid params %pK\n", __func__, inst); @@ -2953,6 +2979,25 @@ int msm_venc_set_image_properties(struct msm_vidc_inst *inst) if (rc) s_vpr_e(inst->sid, "%s: set frame quality failed\n", __func__); + return rc; +} + +int msm_venc_set_image_grid(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl; + struct hfi_heic_grid_enable grid_enable; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params %pK\n", __func__, inst); + return -EINVAL; + } + hdev = inst->core->device; + + if (inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) + return 0; + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE); /* Need a change in HFI if we want to pass size */ @@ -2969,9 +3014,37 @@ int msm_venc_set_image_properties(struct msm_vidc_inst *inst) if (rc) s_vpr_e(inst->sid, "%s: set grid enable failed\n", __func__); + return rc; +} + +int msm_venc_set_image_properties(struct msm_vidc_inst *inst) +{ + int rc = 0; + + if (!inst) { + d_vpr_e("%s: invalid params %pK\n", __func__, inst); + return -EINVAL; + } + + if (inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) + return 0; + + rc = msm_venc_set_frame_quality(inst); + if (rc) { + s_vpr_e(inst->sid, + "%s: set image property failed\n", __func__); + return rc; + } + + rc = msm_venc_set_image_grid(inst); + if (rc) { + s_vpr_e(inst->sid, + "%s: set image property failed\n", __func__); + return rc; + } + set_all_intra_preconditions(inst); set_heif_preconditions(inst); - return rc; } @@ -3003,6 +3076,8 @@ int msm_venc_set_entropy_mode(struct msm_vidc_inst *inst) sizeof(entropy)); if (rc) s_vpr_e(inst->sid, "%s: set property failed\n", __func__); + else + inst->entropy_mode = entropy.entropy_mode; return rc; } @@ -4308,12 +4383,19 @@ int handle_all_intra_restrictions(struct msm_vidc_inst *inst) return -ENOTSUPP; } + /* CBR_CFR is one of the advertised rc mode for HEVC encoding. + * However, all-intra is intended for quality bitstream. Hence, + * fallback to VBR RC mode if client needs all-intra encoding. + */ + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) + inst->rc_type = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR; + /* check supported bit rate mode and frame rate */ capability = &inst->capability; n_fps = inst->clk_data.frame_rate >> 16; fps_max = capability->cap[CAP_ALLINTRA_MAX_FPS].max; s_vpr_h(inst->sid, "%s: rc_type %u, fps %u, fps_max %u\n", - inst->rc_type, n_fps, fps_max); + __func__, inst->rc_type, n_fps, fps_max); if ((inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR && inst->rc_type != RATE_CONTROL_OFF && inst->rc_type != RATE_CONTROL_LOSSLESS) || diff --git a/msm/vidc/msm_venc.h b/msm/vidc/msm_venc.h index e13b2cc3536e..a9ff51824eba 100644 --- a/msm/vidc/msm_venc.h +++ b/msm/vidc/msm_venc.h @@ -44,4 +44,6 @@ int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst); int msm_venc_set_cvp_skipratio(struct msm_vidc_inst *inst); int handle_all_intra_restrictions(struct msm_vidc_inst *inst); int check_blur_restrictions(struct msm_vidc_inst *inst); +int msm_venc_set_frame_quality(struct msm_vidc_inst *inst); +int msm_venc_set_image_grid(struct msm_vidc_inst *inst); #endif diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index f3281010fa11..ad80a317c02c 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -352,20 +352,22 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) } for (i = 0; i < b->length; i++) { - b->m.planes[i].m.fd = b->m.planes[i].reserved[0]; - b->m.planes[i].data_offset = b->m.planes[i].reserved[1]; + b->m.planes[i].m.fd = + b->m.planes[i].reserved[MSM_VIDC_BUFFER_FD]; + b->m.planes[i].data_offset = + b->m.planes[i].reserved[MSM_VIDC_DATA_OFFSET]; } /* Compression ratio is valid only for Encoder YUV buffers. */ if (inst->session_type == MSM_VIDC_ENCODER && b->type == INPUT_MPLANE) { - cr = b->m.planes[0].reserved[2]; + cr = b->m.planes[0].reserved[MSM_VIDC_COMP_RATIO]; msm_comm_update_input_cr(inst, b->index, cr); } if (b->type == INPUT_MPLANE) { client_data = msm_comm_store_client_data(inst, - b->m.planes[0].reserved[3]); + b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_1]); if (!client_data) { s_vpr_e(inst->sid, "%s: failed to store client data\n", __func__); @@ -425,8 +427,10 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) } for (i = 0; i < b->length; i++) { - b->m.planes[i].reserved[0] = b->m.planes[i].m.fd; - b->m.planes[i].reserved[1] = b->m.planes[i].data_offset; + b->m.planes[i].reserved[MSM_VIDC_BUFFER_FD] = + b->m.planes[i].m.fd; + b->m.planes[i].reserved[MSM_VIDC_DATA_OFFSET] = + b->m.planes[i].data_offset; } /** * Flush handling: @@ -453,8 +457,8 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) !(b->flags & V4L2_BUF_FLAG_CODECCONFIG); msm_comm_fetch_client_data(inst, remove, input_tag, input_tag2, - &b->m.planes[0].reserved[3], - &b->m.planes[0].reserved[4]); + &b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_1], + &b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_2]); } } @@ -1604,6 +1608,7 @@ void *msm_vidc_open(int core_id, int session_type) inst->dpb_extra_binfo = NULL; inst->all_intra = false; inst->max_filled_len = 0; + inst->entropy_mode = HFI_H264_ENTROPY_CABAC; for (i = SESSION_MSG_INDEX(SESSION_MSG_START); i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) { @@ -1805,6 +1810,9 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) core = inst->core; + for (i = 0; i < MAX_PORT_NUM; i++) + vb2_queue_release(&inst->bufq[i].vb2_bufq); + mutex_lock(&core->lock); /* inst->list lives in core->instances */ list_del(&inst->list); @@ -1815,9 +1823,6 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) v4l2_fh_del(&inst->event_handler); v4l2_fh_exit(&inst->event_handler); - for (i = 0; i < MAX_PORT_NUM; i++) - vb2_queue_release(&inst->bufq[i].vb2_bufq); - DEINIT_MSM_VIDC_LIST(&inst->scratchbufs); DEINIT_MSM_VIDC_LIST(&inst->persistbufs); DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq); diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 72d252395274..27730fc67c3e 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -35,6 +35,9 @@ /* extra output buffers for encoder HFR usecase */ #define HFR_ENC_TOTAL_OUTPUT_BUFFERS 12 +/* extra output buffers for encoder HEIF usecase */ +#define HEIF_ENC_TOTAL_OUTPUT_BUFFERS 12 + #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_WIDTH 32 #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_HEIGHT 8 #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_UV_TILE_WIDTH 16 @@ -833,6 +836,13 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) if (!is_realtime_session(inst) || is_thumbnail_session(inst)) return extra_output_count; + /* For HEIF, we are increasing buffer count */ + if (is_image_session(inst)) { + extra_output_count = (HEIF_ENC_TOTAL_OUTPUT_BUFFERS - + MIN_ENC_OUTPUT_BUFFERS); + return extra_output_count; + } + /* * Batch mode and HFR not supported for resolution greater than * UHD. Hence extra buffers are not required. @@ -970,6 +980,10 @@ u32 msm_vidc_calculate_enc_output_frame_size(struct msm_vidc_inst *inst) * For resolution > 4k : YUVsize / 4 * Initially frame_size = YUVsize * 2; */ + + if (is_grid_session(inst)) { + f->fmt.pix_mp.width = f->fmt.pix_mp.height = HEIC_GRID_DIMENSION; + } width = ALIGN(f->fmt.pix_mp.width, BUFFER_ALIGNMENT_SIZE(32)); height = ALIGN(f->fmt.pix_mp.height, BUFFER_ALIGNMENT_SIZE(32)); mbs_per_frame = NUM_MBS_PER_FRAME(width, height); diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index b30a21285186..6b81e6e10690 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -505,7 +505,7 @@ static unsigned long msm_vidc_max_freq(struct msm_vidc_core *core, u32 sid) allowed_clks_tbl = core->resources.allowed_clks_tbl; freq = allowed_clks_tbl[0].clock_rate; - s_vpr_p(sid, "Max rate = %lu\n", freq); + s_vpr_l(sid, "Max rate = %lu\n", freq); return freq; } @@ -724,11 +724,10 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, u32 vpp_cycles_per_mb; u32 mbs_per_second; struct msm_vidc_core *core = NULL; - int i = 0; - struct allowed_clock_rates_table *allowed_clks_tbl = NULL; - u64 rate = 0, fps; + u32 fps; struct clock_data *dcvs = NULL; - u32 operating_rate, vsp_factor_num = 10, vsp_factor_den = 5; + u32 operating_rate, vsp_factor_num = 1, vsp_factor_den = 1; + u32 base_cycles = 0; core = inst->core; dcvs = &inst->clk_data; @@ -763,18 +762,34 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, if (inst->clk_data.work_route > 1) vpp_cycles += vpp_cycles / 100; - vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; - + /* VSP */ /* bitrate is based on fps, scale it using operating rate */ operating_rate = inst->clk_data.operating_rate >> 16; if (operating_rate > (inst->clk_data.frame_rate >> 16) && (inst->clk_data.frame_rate >> 16)) { - vsp_factor_num *= operating_rate; - vsp_factor_den *= inst->clk_data.frame_rate >> 16; + vsp_factor_num = operating_rate; + vsp_factor_den = inst->clk_data.frame_rate >> 16; } - vsp_cycles += ((u64)inst->clk_data.bitrate * vsp_factor_num) / + vsp_cycles = ((u64)inst->clk_data.bitrate * vsp_factor_num) / vsp_factor_den; + + base_cycles = inst->clk_data.entry->vsp_cycles; + if (inst->entropy_mode == HFI_H264_ENTROPY_CABAC) { + vsp_cycles = (vsp_cycles * 135) / 100; + } else { + base_cycles = 0; + vsp_cycles = vsp_cycles / 2; + /* VSP FW Overhead 1.05 */ + vsp_cycles = (vsp_cycles * 21) / 20; + } + + if (inst->clk_data.work_mode == HFI_WORKMODE_1) + vsp_cycles = vsp_cycles * 3; + + vsp_cycles += mbs_per_second * base_cycles; + } else if (inst->session_type == MSM_VIDC_DECODER) { + /* VPP */ vpp_cycles = mbs_per_second * inst->clk_data.entry->vpp_cycles / inst->clk_data.work_route; /* 21 / 20 is minimum overhead factor */ @@ -783,10 +798,23 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, if (inst->clk_data.work_route > 1) vpp_cycles += vpp_cycles * 59 / 1000; - vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; + /* VSP */ + base_cycles = inst->clk_data.entry->vsp_cycles; + vsp_cycles = fps * filled_len * 8; + if (inst->entropy_mode == HFI_H264_ENTROPY_CABAC) { + vsp_cycles = (vsp_cycles * 135) / 100; + } else { + base_cycles = 0; + vsp_cycles = vsp_cycles / 2; + /* VSP FW Overhead 1.05 */ + vsp_cycles = vsp_cycles * 21 / 20; + } + + if (inst->clk_data.work_mode == HFI_WORKMODE_1) + vsp_cycles = vsp_cycles * 3; + + vsp_cycles += mbs_per_second * base_cycles; - /* vsp perf is about 0.5 bits/cycle */ - vsp_cycles += ((fps * filled_len * 8) * 10) / 5; } else { s_vpr_e(inst->sid, "%s: Unknown session type\n", __func__); return msm_vidc_max_freq(inst->core, inst->sid); @@ -795,16 +823,6 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, freq = max(vpp_cycles, vsp_cycles); freq = max(freq, fw_cycles); - allowed_clks_tbl = core->resources.allowed_clks_tbl; - for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) { - rate = allowed_clks_tbl[i].clock_rate; - if (rate >= freq) - break; - } - - if (i < 0) - i = 0; - s_vpr_p(inst->sid, "%s: inst %pK: filled len %d required freq %llu\n", __func__, inst, filled_len, freq); @@ -864,7 +882,7 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid) freq_core_max = max_t(unsigned long, freq_core_1, freq_core_2); if (msm_vidc_clock_voting) { - s_vpr_p(sid, "msm_vidc_clock_voting %d\n", + s_vpr_l(sid, "msm_vidc_clock_voting %d\n", msm_vidc_clock_voting); freq_core_max = msm_vidc_clock_voting; decrement = false; @@ -947,17 +965,19 @@ int msm_comm_scale_clocks(struct msm_vidc_inst *inst) return 0; } - if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW || is_turbo || - msm_vidc_clock_voting) { + if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW || is_turbo) { inst->clk_data.min_freq = msm_vidc_max_freq(inst->core, inst->sid); inst->clk_data.dcvs_flags = 0; + } else if (msm_vidc_clock_voting) { + inst->clk_data.min_freq = msm_vidc_clock_voting; + inst->clk_data.dcvs_flags = 0; } else { freq = call_core_op(inst->core, calc_freq, inst, filled_len); inst->clk_data.min_freq = freq; - /* update dcvs flags */ msm_dcvs_scale_clocks(inst, freq); } + msm_vidc_set_clocks(inst->core, inst->sid); return 0; @@ -1616,7 +1636,10 @@ int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) return -EINVAL; } - if (cur_inst_load + core_load <= max_freq) { + /* Power saving always disabled for HEIF image sessions */ + if (is_image_session(inst)) + msm_vidc_power_save_mode_enable(inst, false); + else if (cur_inst_load + core_load <= max_freq) { if (mbpf > max_hq_mbpf || mbps > max_hq_mbps) enable = true; msm_vidc_power_save_mode_enable(inst, enable); @@ -1662,12 +1685,16 @@ int msm_vidc_decide_core_and_power_mode_iris2(struct msm_vidc_inst *inst) void msm_vidc_init_core_clk_ops(struct msm_vidc_core *core) { + uint32_t vpu; + if (!core) return; - if (core->platform_data->vpu_ver == VPU_VERSION_AR50) + vpu = core->platform_data->vpu_ver; + + if (vpu == VPU_VERSION_AR50 || vpu == VPU_VERSION_AR50_LITE) core->core_ops = &core_ops_ar50; - else if (core->platform_data->vpu_ver == VPU_VERSION_IRIS1) + else if (vpu == VPU_VERSION_IRIS1) core->core_ops = &core_ops_iris1; else core->core_ops = &core_ops_iris2; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 60f8d6e79d84..f7affacbb3c7 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -636,6 +636,7 @@ int msm_comm_ctrl_init(struct msm_vidc_inst *inst, } ctrl->flags |= drv_ctrls[idx].flags; + ctrl->flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; inst->ctrls[idx] = ctrl; } inst->num_ctrls = num_ctrls; @@ -1252,8 +1253,8 @@ static void handle_session_release_buf_done(enum hal_command_response cmd, else s_vpr_e(inst->sid, "Invalid inst cmd response: %d\n", cmd); - put_inst(inst); s_vpr_l(inst->sid, "handled: SESSION_RELEASE_BUFFER_DONE\n"); + put_inst(inst); } static void handle_sys_release_res_done( @@ -1455,15 +1456,18 @@ static void msm_vidc_comm_update_ctrl_limits(struct msm_vidc_inst *inst) V4L2_CID_MPEG_VIDEO_B_FRAMES, &inst->capability.cap[CAP_BFRAME]); } + msm_vidc_comm_update_ctrl(inst, + V4L2_CID_MPEG_VIDEO_H264_LEVEL, + &inst->capability.cap[CAP_H264_LEVEL]); + msm_vidc_comm_update_ctrl(inst, + V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, + &inst->capability.cap[CAP_HEVC_LEVEL]); } static void handle_session_init_done(enum hal_command_response cmd, void *data) { struct msm_vidc_cb_cmd_done *response = data; struct msm_vidc_inst *inst = NULL; - struct msm_vidc_capability *capability = NULL; - struct msm_vidc_core *core; - u32 i, codec; if (!response) { d_vpr_e("Failed to get valid response for session init\n"); @@ -1490,6 +1494,32 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data) return; } + s_vpr_l(inst->sid, "handled: SESSION_INIT_DONE\n"); + signal_session_msg_receipt(cmd, inst); + put_inst(inst); + return; + +error: + if (response->status == VIDC_ERR_MAX_CLIENTS) + msm_comm_generate_max_clients_error(inst); + else + msm_comm_generate_session_error(inst); + + signal_session_msg_receipt(cmd, inst); + put_inst(inst); +} + +static int msm_comm_update_capabilities(struct msm_vidc_inst *inst) +{ + struct msm_vidc_core *core; + struct msm_vidc_capability *capability = NULL; + u32 i, codec; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid parameters\n", __func__); + return -EINVAL; + } + core = inst->core; codec = get_v4l2_codec(inst); @@ -1507,7 +1537,7 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data) "%s: capabilities not found for domain %#x codec %#x\n", __func__, get_hal_domain(inst->session_type, inst->sid), get_hal_codec(codec, inst->sid)); - goto error; + return -EINVAL; } s_vpr_h(inst->sid, "%s: capabilities for domain %#x codec %#x\n", @@ -1569,19 +1599,7 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data) msm_vidc_comm_update_ctrl_limits(inst); - s_vpr_l(inst->sid, "handled: SESSION_INIT_DONE\n"); - signal_session_msg_receipt(cmd, inst); - put_inst(inst); - return; - -error: - if (response->status == VIDC_ERR_MAX_CLIENTS) - msm_comm_generate_max_clients_error(inst); - else - msm_comm_generate_session_error(inst); - - signal_session_msg_receipt(cmd, inst); - put_inst(inst); + return 0; } static void msm_vidc_queue_rbr_event(struct msm_vidc_inst *inst, @@ -1670,6 +1688,8 @@ static void handle_event_change(enum hal_command_response cmd, void *data) if (event_fields_changed) { event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT; } else { + inst->entropy_mode = event_notify->entropy_mode; + s_vpr_h(inst->sid, "seq: No parameter change continue session\n"); rc = call_hfi_op(hdev, session_continue, @@ -1719,30 +1739,17 @@ static void handle_event_change(enum hal_command_response cmd, void *data) * codecs except HEVC * event data is now as follows: * u32 *ptr = seq_changed_event.u.data; - * ptr[0] = height - * ptr[1] = width - * ptr[2] = bit depth - * ptr[3] = pic struct (progressive or interlaced) - * ptr[4] = colour space - * ptr[5] = crop_data(top) - * ptr[6] = crop_data(left) - * ptr[7] = crop_data(height) - * ptr[8] = crop_data(width) - * ptr[9] = profile - * ptr[10] = level + * ptr[MSM_VIDC_HEIGHT] = height + * ptr[MSM_VIDC_WIDTH] = width + * ptr[MSM_VIDC_BIT_DEPTH] = bit depth + * ptr[MSM_VIDC_PIC_STRUCT] = pic struct (progressive or interlaced) + * ptr[MSM_VIDC_COLOR_SPACE] = colour space + * ptr[MSM_VIDC_FW_MIN_COUNT] = fw min count */ inst->profile = event_notify->profile; inst->level = event_notify->level; inst->entropy_mode = event_notify->entropy_mode; - inst->prop.crop_info.left = - event_notify->crop_data.left; - inst->prop.crop_info.top = - event_notify->crop_data.top; - inst->prop.crop_info.height = - event_notify->crop_data.height; - inst->prop.crop_info.width = - event_notify->crop_data.width; /* HW returns progressive_only flag in pic_struct. */ inst->pic_struct = event_notify->pic_struct ? @@ -1751,33 +1758,23 @@ static void handle_event_change(enum hal_command_response cmd, void *data) inst->colour_space = event_notify->colour_space; ptr = (u32 *)seq_changed_event.u.data; - ptr[0] = event_notify->height; - ptr[1] = event_notify->width; - ptr[2] = event_notify->bit_depth; - ptr[3] = event_notify->pic_struct; - ptr[4] = event_notify->colour_space; - ptr[5] = event_notify->crop_data.top; - ptr[6] = event_notify->crop_data.left; - ptr[7] = event_notify->crop_data.height; - ptr[8] = event_notify->crop_data.width; - ptr[9] = msm_comm_get_v4l2_profile(codec, - event_notify->profile, inst->sid); - ptr[10] = msm_comm_get_v4l2_level(codec, - event_notify->level, inst->sid); + ptr[MSM_VIDC_HEIGHT] = event_notify->height; + ptr[MSM_VIDC_WIDTH] = event_notify->width; + ptr[MSM_VIDC_BIT_DEPTH] = event_notify->bit_depth; + ptr[MSM_VIDC_PIC_STRUCT] = event_notify->pic_struct; + ptr[MSM_VIDC_COLOR_SPACE] = event_notify->colour_space; + ptr[MSM_VIDC_FW_MIN_COUNT] = event_notify->fw_min_cnt; - s_vpr_h(inst->sid, - "seq: height = %u width = %u profile = %u level = %u\n", - event_notify->height, event_notify->width, ptr[9], ptr[10]); + s_vpr_h(inst->sid, "seq: height = %u width = %u\n", + event_notify->height, event_notify->width); s_vpr_h(inst->sid, "seq: bit_depth = %u pic_struct = %u colour_space = %u\n", event_notify->bit_depth, event_notify->pic_struct, event_notify->colour_space); - s_vpr_h(inst->sid, - "seq: CROP top = %u left = %u Height = %u Width = %u\n", - event_notify->crop_data.top, event_notify->crop_data.left, - event_notify->crop_data.height, event_notify->crop_data.width); + s_vpr_h(inst->sid, "seq: fw_min_count = %u\n", + event_notify->fw_min_cnt); mutex_lock(&inst->lock); inst->in_reconfig = true; @@ -1803,7 +1800,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data) msm_dcvs_try_enable(inst); extra_buff_count = msm_vidc_get_extra_buff_count(inst, HAL_BUFFER_OUTPUT); - fmt->count_min = event_notify->capture_buf_count; + fmt->count_min = event_notify->fw_min_cnt; fmt->count_min_host = fmt->count_min + extra_buff_count; s_vpr_h(inst->sid, "seq: hal buffer[%d] count: min %d min_host %d\n", @@ -1893,8 +1890,8 @@ static void handle_load_resource_done(enum hal_command_response cmd, void *data) msm_comm_generate_session_error(inst); } - put_inst(inst); s_vpr_l(inst->sid, "handled: SESSION_LOAD_RESOURCE_DONE\n"); + put_inst(inst); } static void handle_start_done(enum hal_command_response cmd, void *data) @@ -2110,8 +2107,8 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) exit: mutex_unlock(&inst->flush_lock); - put_inst(inst); s_vpr_l(inst->sid, "handled: SESSION_FLUSH_DONE\n"); + put_inst(inst); } static void handle_session_error(enum hal_command_response cmd, void *data) @@ -2160,8 +2157,8 @@ static void handle_session_error(enum hal_command_response cmd, void *data) /* change state before sending error to client */ change_inst_state(inst, MSM_VIDC_CORE_INVALID); msm_vidc_queue_v4l2_event(inst, event); - put_inst(inst); s_vpr_l(inst->sid, "handled: SESSION_ERROR\n"); + put_inst(inst); } static void msm_comm_clean_notify_client(struct msm_vidc_core *core) @@ -2511,8 +2508,8 @@ static void handle_ebd(enum hal_command_response cmd, void *data) msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_EBD); kref_put_mbuf(mbuf); exit: - put_inst(inst); s_vpr_l(inst->sid, "handled: SESSION_ETB_DONE\n"); + put_inst(inst); } static int handle_multi_stream_buffers(struct msm_vidc_inst *inst, @@ -2688,8 +2685,8 @@ static void handle_fbd(enum hal_command_response cmd, void *data) kref_put_mbuf(mbuf); exit: - put_inst(inst); s_vpr_l(inst->sid, "handled: SESSION_FTB_DONE\n"); + put_inst(inst); } void handle_cmd_response(enum hal_command_response cmd, void *data) @@ -3179,7 +3176,6 @@ static int msm_comm_session_init(int flipped_state, inst, get_hal_domain(inst->session_type, inst->sid), get_hal_codec(fourcc, inst->sid), &inst->session, inst->sid); - if (rc || !inst->session) { s_vpr_e(inst->sid, "Failed to call session init for: %pK, %pK, %d, %d\n", @@ -3188,7 +3184,11 @@ static int msm_comm_session_init(int flipped_state, rc = -EINVAL; goto exit; } - + rc = msm_comm_update_capabilities(inst); + if (rc) { + s_vpr_e(inst->sid, "Failed to update capabilities\n"); + goto exit; + } rc = msm_vidc_calculate_buffer_counts(inst); if (rc) { s_vpr_e(inst->sid, "Failed to initialize buff counts\n"); @@ -5600,15 +5600,10 @@ int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst) u32 x_min, x_max, y_min, y_max; u32 input_height, input_width, output_height, output_width; struct v4l2_format *f; - struct v4l2_ctrl *ctrl = NULL; - /* Grid get_ctrl allowed for encode session only */ - if (is_image_session(inst)) { - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE); - if (ctrl->val > 0) { - s_vpr_h(inst->sid, "Skip scaling check for HEIC\n"); - return 0; - } + if (is_grid_session(inst)) { + s_vpr_h(inst->sid, "Skip scaling check for HEIC\n"); + return 0; } f = &inst->fmts[INPUT_PORT].v4l2_fmt; @@ -5693,7 +5688,6 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) u32 width_min, width_max, height_min, height_max; u32 mbpf_max; struct v4l2_format *f; - struct v4l2_ctrl *ctrl = NULL; u32 sid; if (!inst || !inst->core || !inst->core->device) { @@ -5756,8 +5750,7 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) return -ENOTSUPP; } - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE); - if (ctrl->val > 0) { + if (is_grid_session(inst)) { if (inst->fmts[INPUT_PORT].v4l2_fmt.fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12 && inst->fmts[INPUT_PORT].v4l2_fmt.fmt.pix_mp.pixelformat != @@ -7250,7 +7243,8 @@ int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, struct vidc_frame_data *frame_data) { struct msm_vidc_window_data *pdata, *temp = NULL; - u32 bitrate, max_br, window_size; + u32 frame_size, window_size, window_buffer; + u32 max_avg_frame_size, max_frame_size; int buf_cnt = 1, fps, window_start; if (!inst || !inst->core || !frame_data) { @@ -7259,25 +7253,31 @@ int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, } if (!inst->core->resources.avsync_window_size || + inst->entropy_mode == HFI_H264_ENTROPY_CAVLC || !frame_data->filled_len) return 0; fps = inst->clk_data.frame_rate >> 16; - max_br = MAX_BITRATE_DECODER_CAVLC; - if (inst->entropy_mode == HFI_H264_ENTROPY_CABAC) - max_br = inst->clk_data.work_mode == HFI_WORKMODE_2 ? - MAX_BITRATE_DECODER_2STAGE_CABAC : - MAX_BITRATE_DECODER_1STAGE_CABAC; window_size = inst->core->resources.avsync_window_size * fps; - window_size = DIV_ROUND_UP(window_size, 1000); + window_size = DIV_ROUND_CLOSEST(window_size, 1000); + window_buffer = inst->clk_data.work_mode == HFI_WORKMODE_2 ? 2 : 0; - bitrate = frame_data->filled_len; + max_frame_size = + inst->core->resources.allowed_clks_tbl[0].clock_rate / fps - + inst->clk_data.entry->vsp_cycles * + msm_vidc_get_mbs_per_frame(inst); + max_avg_frame_size = (u64)max_frame_size * 100 * + (window_size + window_buffer) / (window_size * 135); + max_frame_size = (u64)max_frame_size * 100 * + (1 + window_buffer) / 135; + + frame_size = frame_data->filled_len; window_start = inst->count.etb; mutex_lock(&inst->window_data.lock); list_for_each_entry(pdata, &inst->window_data.list, list) { if (buf_cnt < window_size && pdata->frame_size) { - bitrate += pdata->frame_size; + frame_size += pdata->frame_size; window_start = pdata->etb_count; buf_cnt++; } else { @@ -7303,13 +7303,19 @@ int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, list_add(&pdata->list, &inst->window_data.list); mutex_unlock(&inst->window_data.lock); - bitrate = DIV_ROUND_UP(((u64)bitrate * 8 * fps), window_size); - if (bitrate > max_br) { + frame_size = DIV_ROUND_UP((frame_size * 8), window_size); + if (frame_size > max_avg_frame_size) { s_vpr_p(inst->sid, - "Unsupported bitrate %u max %u, window size %u [%u,%u]", - bitrate, max_br, window_size, + "Unsupported avg frame size %u max %u, window size %u [%u,%u]", + frame_size, max_avg_frame_size, window_size, window_start, inst->count.etb); } + if (frame_data->filled_len * 8 > max_frame_size) { + s_vpr_p(inst->sid, + "Unsupported frame size(bit) %u max %u [%u]", + frame_data->filled_len * 8, max_frame_size, + inst->count.etb); + } return 0; } diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index db1fc943c9e4..df6cfdacfa94 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -65,6 +65,10 @@ static inline struct v4l2_ctrl *get_ctrl(struct msm_vidc_inst *inst, { int i; + if (inst->session_type == MSM_VIDC_CVP && + inst->core->resources.cvp_internal) + return inst->ctrls[0]; + for (i = 0; i < inst->num_ctrls; i++) { if (inst->ctrls[i]->id == id) return inst->ctrls[i]; @@ -106,6 +110,16 @@ static inline bool is_image_session(struct msm_vidc_inst *inst) inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ; } +static inline bool is_grid_session(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *ctrl = NULL; + if (inst->session_type == MSM_VIDC_ENCODER && + get_v4l2_codec(inst) == V4L2_PIX_FMT_HEVC) { + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE); + return (ctrl->val > 0); + } + return 0; +} static inline bool is_realtime_session(struct msm_vidc_inst *inst) { struct v4l2_ctrl *ctrl; diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index a1f067958070..ce5b520219ff 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -11,7 +11,7 @@ #include int msm_vidc_debug = VIDC_ERR | VIDC_PRINTK | - FW_HIGH | FW_ERROR | FW_FATAL | FW_FTRACE; + FW_ERROR | FW_FATAL | FW_FTRACE; EXPORT_SYMBOL(msm_vidc_debug); bool msm_vidc_lossless_encode = !true; diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 610df5a0c1a3..31b9ce82ed04 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -271,6 +271,7 @@ enum vpu_version { VPU_VERSION_AR50 = 1, VPU_VERSION_IRIS1, VPU_VERSION_IRIS2, + VPU_VERSION_AR50_LITE, }; struct msm_vidc_ubwc_config_data { @@ -345,15 +346,7 @@ struct msm_video_device { struct video_device vdev; }; -struct session_crop { - u32 left; - u32 top; - u32 width; - u32 height; -}; - struct session_prop { - struct session_crop crop_info; u32 fps; u32 bitrate; bool bframe_changed; diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 29ca3b195f73..2900e9917768 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -78,15 +78,15 @@ static struct msm_vidc_codec_data lito_codec_data[] = { /* Update with Kona data */ static struct msm_vidc_codec_data kona_codec_data[] = { - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 0, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 0, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 0, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), - CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 25, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 25, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 25, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 25, 540, 540), + CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 25, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 25, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 25, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 25, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 25, 200, 200), }; /* Update with SM6150 data */ @@ -102,6 +102,18 @@ static struct msm_vidc_codec_data sm6150_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 50, 200, 200), }; +static struct msm_vidc_codec_data bengal_codec_data[] = { + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 125, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 125, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), + CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 50, 200, 200), +}; + /* Update with 855 data */ static struct msm_vidc_codec_data sm8150_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 0, 675, 320), @@ -151,6 +163,12 @@ static struct msm_vidc_codec_data sdm670_codec_data[] = { HAL_VIDEO_CODEC_VP8 | HAL_VIDEO_CODEC_VP9 | \ HAL_VIDEO_CODEC_MPEG2) +static struct msm_vidc_codec bengal_codecs[] = { + /* {domain, codec} */ + {DEC, H264}, {DEC, HEVC}, {DEC, VP9}, + {ENC, H264}, {ENC, HEVC}, +}; + static struct msm_vidc_codec default_codecs[] = { /* {domain, codec} */ {DEC, H264}, {DEC, HEVC}, {DEC, VP8}, {DEC, VP9}, {DEC, MPEG2}, @@ -162,7 +180,7 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 5760, 1, 1920}, {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 5760, 1, 1080}, /* ((5760 * 2880) / 256) */ - {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 64800, 1, 34560}, + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 64800, 1, 8160}, /* ((4096x2160)/256)@90fps */ {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 3110400, 1, 2073600}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 480, 1, 30}, @@ -191,8 +209,8 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { /* VP8 specific */ {CAP_FRAME_WIDTH, ENC|DEC, VP8, 96, 4096, 1, 1920}, {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 96, 4096, 1, 1080}, - /* (4096 * 2160) / 256 */ - {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 36, 34560, 1, 8160}, + /* (4096 * 2304) / 256 */ + {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 36, 36864, 1, 8160}, /* (4096 * 2160) / 256) * 30*/ {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 36, 1036800, 1, 244800}, {CAP_FRAMERATE, ENC|DEC, VP8, 1, 30, 1, 30}, @@ -212,8 +230,8 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { /* Secure usecase specific */ {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1080}, - /* (4096 * 2160) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 34560, 1, 34560}, + /* (4096 * 2304) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 36864, 1, 8160}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, /* Batch Mode Decode */ @@ -221,19 +239,38 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { /* (1920 * 1080) / 256 */ {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, + /* All intra encoding usecase specific */ + {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 240, 1, 30}, + /* Image specific */ {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 1, 8192}, {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192}, + + /* Level for AVC and HEVC encoder specific */ + {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_6_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_6_0}, + {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_6, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_6}, + + /* Level for AVC, HEVC and VP9 decoder specific */ + {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_6_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0}, + {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5}, }; static struct msm_vidc_codec_capability lito_capabilities_v1[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value} */ {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1080}, - /* ((4096 * 2160) / 256) */ - {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 34560, 1, 34560}, + /* ((4096 * 2304) / 256) */ + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 36864, 1, 8160}, /* 4K@30 decode + 1080@30 encode */ {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 1281600, 1, 2073600}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 240, 1, 30}, @@ -283,8 +320,8 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { /* Secure usecase specific */ {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1080}, - /* (4096 * 2160) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 34560, 1, 34560}, + /* (4096 * 2304) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 36864, 1, 8160}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, /* Batch Mode Decode */ @@ -292,11 +329,63 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { /* (1920 * 1080) / 256 */ {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, + /* All intra encoding usecase specific */ + {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 240, 1, 30}, + /* Image specific */ {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 1, 8192}, {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192}, + + /* Level for AVC and HEVC encoder specific */ + {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_6_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_6_0}, + {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_6, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_6}, + + /* Level for AVC, HEVC and VP9 decoder specific */ + {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_6_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0}, + {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5}, +}; + +static struct msm_vidc_codec_capability bengal_capabilities[] = { + /* {cap_type, domains, codecs, min, max, step_size, default_value} */ + {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 1920, 1, 1080}, + /* ((1920 * 1080) / 256) */ + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 8160, 1, 34560}, + /* 1080@30 decode + 1080@30 encode */ + {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 486000, 1, 243000}, + {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 120, 1, 30}, + {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, + {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, + {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, + {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 4, 1, 0}, + /* ((1920 * 1088) / 256) * 30 fps */ + {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, + 0, 244800, 1, 244800}, + {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, + {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + + /* 10 slices */ + {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_SLICE_MB, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, + + /* Secure usecase specific */ + {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 1920, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 1920, 1, 1080}, + /* (1920 * 1088) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 8160, 1, 34560}, + {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, }; static struct msm_vidc_codec_capability kona_capabilities[] = { @@ -377,8 +466,24 @@ static struct msm_vidc_codec_capability kona_capabilities[] = { /* Image specific */ {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 1, 8192}, - {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 16384, 1, 16384}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 16384, 1, 16384}, + + /* Level for AVC and HEVC encoder specific */ + {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_6_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_6_0}, + {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_6, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_6}, + + /* Level for AVC, HEVC and VP9 decoder specific */ + {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_6_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0}, + {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5}, }; /* @@ -706,6 +811,65 @@ static struct msm_vidc_common_data sm6150_common_data[] = { }, }; +static struct msm_vidc_common_data bengal_common_data[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 5, + }, + { + .key = "qcom,max-hw-load", + .value = 1216800, + }, + { + .key = "qcom,max-hq-mbs-per-frame", + .value = 8160, + }, + { + .key = "qcom,max-hq-mbs-per-sec", + .value = 244800, /* 1920 x 1088 @ 30 fps */ + }, + { + .key = "qcom,max-b-frame-mbs-per-frame", + .value = 8160, + }, + { + .key = "qcom,max-b-frame-mbs-per-sec", + .value = 489600, + }, + { + .key = "qcom,power-collapse-delay", + .value = 1500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, + { + .key = "qcom,fw-cycles", + .value = 733003, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 225975, + }, +}; + static struct msm_vidc_common_data sm8150_common_data[] = { { .key = "qcom,never-unload-fw", @@ -1035,6 +1199,25 @@ static struct msm_vidc_platform_data sm6150_data = { .ubwc_config = 0x0, }; +static struct msm_vidc_platform_data bengal_data = { + .codec_data = bengal_codec_data, + .codec_data_length = ARRAY_SIZE(bengal_codec_data), + .common_data = bengal_common_data, + .common_data_length = ARRAY_SIZE(bengal_common_data), + .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, + .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, + .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, + .efuse_data = NULL, + .efuse_data_length = 0, + .sku_version = 0, + .vpu_ver = VPU_VERSION_AR50_LITE, + .ubwc_config = 0x0, + .codecs = bengal_codecs, + .codecs_count = ARRAY_SIZE(bengal_codecs), + .codec_caps = bengal_capabilities, + .codec_caps_count = ARRAY_SIZE(bengal_capabilities), +}; + static struct msm_vidc_platform_data sm8150_data = { .codec_data = sm8150_codec_data, .codec_data_length = ARRAY_SIZE(sm8150_codec_data), @@ -1105,6 +1288,10 @@ static const struct of_device_id msm_vidc_dt_match[] = { .compatible = "qcom,sdm670-vidc", .data = &sdm670_data, }, + { + .compatible = "qcom,bengal-vidc", + .data = &bengal_data, + }, {}, }; diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index 3d1f9ae383cc..76cfb7e0924f 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -157,6 +157,8 @@ struct hfi_extradata_header { (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00C) #define HFI_PROPERTY_PARAM_VDEC_THUMBNAIL_MODE \ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00D) +#define HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00E) #define HFI_PROPERTY_PARAM_VDEC_TIMESTAMP_EXTRADATA \ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x013) #define HFI_PROPERTY_PARAM_VDEC_INTERLACE_VIDEO_EXTRADATA \ diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index e0e5b5d4eab0..ee2bb6614785 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -286,6 +286,8 @@ enum hal_capability { CAP_HEVC_IMAGE_FRAME_HEIGHT, CAP_HEIC_IMAGE_FRAME_WIDTH, CAP_HEIC_IMAGE_FRAME_HEIGHT, + CAP_H264_LEVEL, + CAP_HEVC_LEVEL, CAP_MAX, }; @@ -597,16 +599,6 @@ struct msm_vidc_cb_cmd_done { } data; }; -struct hal_index_extradata_input_crop_payload { - u32 size; - u32 version; - u32 port_index; - u32 left; - u32 top; - u32 width; - u32 height; -}; - struct msm_vidc_cb_event { u32 device_id; void *inst_id; @@ -622,8 +614,11 @@ struct msm_vidc_cb_event { u32 profile; u32 level; u32 entropy_mode; - u32 capture_buf_count; - struct hal_index_extradata_input_crop_payload crop_data; + u32 max_dpb_count; + u32 max_ref_frames; + u32 max_dec_buffering; + u32 max_reorder_frames; + u32 fw_min_cnt; }; struct msm_vidc_cb_data_done { diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index 3dfc8c1ddb68..02c3619333a1 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -587,6 +587,14 @@ struct hfi_profile_level { u32 level; }; +struct hfi_dpb_counts { + u32 max_dpb_count; + u32 max_ref_frames; + u32 max_dec_buffering; + u32 max_reorder_frames; + u32 fw_min_cnt; +}; + struct hfi_profile_level_supported { u32 profile_count; struct hfi_profile_level rg_profile_level[1]; From 17ff6ba65ab174316f1a5423c75e4d6f225eafef Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Tue, 8 Oct 2019 15:57:12 -0700 Subject: [PATCH 163/452] msm: vidc: add userspace interface header files Add userspace interface header files for userspace to access video driver functionalities. Change-Id: I1919f9025e87f15da06a0428d95077372aec603e Signed-off-by: Maheshwar Ajja --- Makefile | 5 + include/Kbuild | 2 + include/uapi/Kbuild | 3 + include/uapi/media/Kbuild | 4 + include/uapi/media/msm_media_info.h | 1355 +++++++++++++++++++++++++++ include/uapi/media/msm_vidc_utils.h | 614 ++++++++++++ 6 files changed, 1983 insertions(+) create mode 100644 include/Kbuild create mode 100644 include/uapi/Kbuild create mode 100644 include/uapi/media/Kbuild create mode 100644 include/uapi/media/msm_media_info.h create mode 100644 include/uapi/media/msm_vidc_utils.h diff --git a/Makefile b/Makefile index 0fcf3f6df3da..988acbbe6653 100644 --- a/Makefile +++ b/Makefile @@ -18,4 +18,9 @@ ifeq ($(CONFIG_ARCH_LITO), y) LINUXINCLUDE += -include $(srctree)/techpack/video/config/litovidconf.h endif +LINUXINCLUDE += -I$(srctree)/techpack/video/include \ + -I$(srctree)/techpack/video/include/uapi + +USERINCLUDE += -I$(srctree)/techpack/video/include/uapi + obj-y +=msm/ diff --git a/include/Kbuild b/include/Kbuild new file mode 100644 index 000000000000..bab1145bc7a7 --- /dev/null +++ b/include/Kbuild @@ -0,0 +1,2 @@ +# Top-level Makefile calls into asm-$(ARCH) +# List only non-arch directories below diff --git a/include/uapi/Kbuild b/include/uapi/Kbuild new file mode 100644 index 000000000000..469cb04b044f --- /dev/null +++ b/include/uapi/Kbuild @@ -0,0 +1,3 @@ +# include all directories below + +header-y += media/ diff --git a/include/uapi/media/Kbuild b/include/uapi/media/Kbuild new file mode 100644 index 000000000000..e9b80bb01fd6 --- /dev/null +++ b/include/uapi/media/Kbuild @@ -0,0 +1,4 @@ +# include header files + +header-y += msm_media_info.h +header-y += msm_vidc_utils.h diff --git a/include/uapi/media/msm_media_info.h b/include/uapi/media/msm_media_info.h new file mode 100644 index 000000000000..309a17bde02d --- /dev/null +++ b/include/uapi/media/msm_media_info.h @@ -0,0 +1,1355 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#ifndef __MSM_MEDIA_INFO_H__ +#define __MSM_MEDIA_INFO_H__ + +/* Width and Height should be multiple of 16 */ +#define INTERLACE_WIDTH_MAX 1920 +#define INTERLACE_HEIGHT_MAX 1920 +#define INTERLACE_MB_PER_FRAME_MAX ((1920*1088)/256) + +#ifndef MSM_MEDIA_ALIGN +#define MSM_MEDIA_ALIGN(__sz, __align) (((__align) & ((__align) - 1)) ?\ + ((((__sz) + (__align) - 1) / (__align)) * (__align)) :\ + (((__sz) + (__align) - 1) & (~((__align) - 1)))) +#endif + +#ifndef MSM_MEDIA_ROUNDUP +#define MSM_MEDIA_ROUNDUP(__sz, __r) (((__sz) + ((__r) - 1)) / (__r)) +#endif + +enum color_fmts { + /* Venus NV12: + * YUV 4:2:0 image with a plane of 8 bit Y samples followed + * by an interleaved U/V plane containing 8 bit 2x2 subsampled + * colour difference samples. + * + * <-------- Y/UV_Stride --------> + * <------- Width -------> + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . ^ ^ + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . Height | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | Y_Scanlines + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * U V U V U V U V U V U V . . . . ^ + * U V U V U V U V U V U V . . . . | + * U V U V U V U V U V U V . . . . | + * U V U V U V U V U V U V . . . . UV_Scanlines + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . . . --> Buffer size alignment + * + * Y_Stride : Width aligned to 512 + * UV_Stride : Width aligned to 512 + * Y_Scanlines: Height aligned to 512 + * UV_Scanlines: Height/2 aligned to 256 + * Total size = align(Y_Stride * Y_Scanlines + * + UV_Stride * UV_Scanlines, 4096) + */ + COLOR_FMT_NV12, + /* Venus NV21: + * YUV 4:2:0 image with a plane of 8 bit Y samples followed + * by an interleaved V/U plane containing 8 bit 2x2 subsampled + * colour difference samples. + * + * <-------- Y/UV_Stride --------> + * <------- Width -------> + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . ^ ^ + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . Height | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | Y_Scanlines + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * V U V U V U V U V U V U . . . . ^ + * V U V U V U V U V U V U . . . . | + * V U V U V U V U V U V U . . . . | + * V U V U V U V U V U V U . . . . UV_Scanlines + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . . . --> Padding & Buffer size alignment + * + * Y_Stride : Width aligned to 512 + * UV_Stride : Width aligned to 512 + * Y_Scanlines: Height aligned to 512 + * UV_Scanlines: Height/2 aligned to 256 + * Total size = align(Y_Stride * Y_Scanlines + * + UV_Stride * UV_Scanlines, 4096) + */ + COLOR_FMT_NV21, + /* + * The buffer can be of 2 types: + * (1) Venus NV12 UBWC Progressive + * (2) Venus NV12 UBWC Interlaced + * + * (1) Venus NV12 UBWC Progressive Buffer Format: + * Compressed Macro-tile format for NV12. + * Contains 4 planes in the following order - + * (A) Y_Meta_Plane + * (B) Y_UBWC_Plane + * (C) UV_Meta_Plane + * (D) UV_UBWC_Plane + * + * Y_Meta_Plane consists of meta information to decode compressed + * tile data in Y_UBWC_Plane. + * Y_UBWC_Plane consists of Y data in compressed macro-tile format. + * UBWC decoder block will use the Y_Meta_Plane data together with + * Y_UBWC_Plane data to produce loss-less uncompressed 8 bit Y samples. + * + * UV_Meta_Plane consists of meta information to decode compressed + * tile data in UV_UBWC_Plane. + * UV_UBWC_Plane consists of UV data in compressed macro-tile format. + * UBWC decoder block will use UV_Meta_Plane data together with + * UV_UBWC_Plane data to produce loss-less uncompressed 8 bit 2x2 + * subsampled color difference samples. + * + * Each tile in Y_UBWC_Plane/UV_UBWC_Plane is independently decodable + * and randomly accessible. There is no dependency between tiles. + * + * <----- Y_Meta_Stride ----> + * <-------- Width ------> + * M M M M M M M M M M M M . . ^ ^ + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . Height | + * M M M M M M M M M M M M . . | Meta_Y_Scanlines + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . V | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . V + * <--Compressed tile Y Stride---> + * <------- Width -------> + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . ^ ^ + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . Height | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | Macro_tile_Y_Scanlines + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . . . V + * <----- UV_Meta_Stride ----> + * M M M M M M M M M M M M . . ^ + * M M M M M M M M M M M M . . | + * M M M M M M M M M M M M . . | + * M M M M M M M M M M M M . . M_UV_Scanlines + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * <--Compressed tile UV Stride---> + * U* V* U* V* U* V* U* V* . . . . ^ + * U* V* U* V* U* V* U* V* . . . . | + * U* V* U* V* U* V* U* V* . . . . | + * U* V* U* V* U* V* U* V* . . . . UV_Scanlines + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * + * Y_Stride = align(Width, 128) + * UV_Stride = align(Width, 128) + * Y_Scanlines = align(Height, 32) + * UV_Scanlines = align(Height/2, 32) + * Y_UBWC_Plane_size = align(Y_Stride * Y_Scanlines, 4096) + * UV_UBWC_Plane_size = align(UV_Stride * UV_Scanlines, 4096) + * Y_Meta_Stride = align(roundup(Width, Y_TileWidth), 64) + * Y_Meta_Scanlines = align(roundup(Height, Y_TileHeight), 16) + * Y_Meta_Plane_size = align(Y_Meta_Stride * Y_Meta_Scanlines, 4096) + * UV_Meta_Stride = align(roundup(Width, UV_TileWidth), 64) + * UV_Meta_Scanlines = align(roundup(Height, UV_TileHeight), 16) + * UV_Meta_Plane_size = align(UV_Meta_Stride * UV_Meta_Scanlines, 4096) + * + * Total size = align( Y_UBWC_Plane_size + UV_UBWC_Plane_size + + * Y_Meta_Plane_size + UV_Meta_Plane_size, 4096) + * + * + * (2) Venus NV12 UBWC Interlaced Buffer Format: + * Compressed Macro-tile format for NV12 interlaced. + * Contains 8 planes in the following order - + * (A) Y_Meta_Top_Field_Plane + * (B) Y_UBWC_Top_Field_Plane + * (C) UV_Meta_Top_Field_Plane + * (D) UV_UBWC_Top_Field_Plane + * (E) Y_Meta_Bottom_Field_Plane + * (F) Y_UBWC_Bottom_Field_Plane + * (G) UV_Meta_Bottom_Field_Plane + * (H) UV_UBWC_Bottom_Field_Plane + * Y_Meta_Top_Field_Plane consists of meta information to decode + * compressed tile data for Y_UBWC_Top_Field_Plane. + * Y_UBWC_Top_Field_Plane consists of Y data in compressed macro-tile + * format for top field of an interlaced frame. + * UBWC decoder block will use the Y_Meta_Top_Field_Plane data together + * with Y_UBWC_Top_Field_Plane data to produce loss-less uncompressed + * 8 bit Y samples for top field of an interlaced frame. + * + * UV_Meta_Top_Field_Plane consists of meta information to decode + * compressed tile data in UV_UBWC_Top_Field_Plane. + * UV_UBWC_Top_Field_Plane consists of UV data in compressed macro-tile + * format for top field of an interlaced frame. + * UBWC decoder block will use UV_Meta_Top_Field_Plane data together + * with UV_UBWC_Top_Field_Plane data to produce loss-less uncompressed + * 8 bit subsampled color difference samples for top field of an + * interlaced frame. + * + * Each tile in Y_UBWC_Top_Field_Plane/UV_UBWC_Top_Field_Plane is + * independently decodable and randomly accessible. There is no + * dependency between tiles. + * + * Y_Meta_Bottom_Field_Plane consists of meta information to decode + * compressed tile data for Y_UBWC_Bottom_Field_Plane. + * Y_UBWC_Bottom_Field_Plane consists of Y data in compressed macro-tile + * format for bottom field of an interlaced frame. + * UBWC decoder block will use the Y_Meta_Bottom_Field_Plane data + * together with Y_UBWC_Bottom_Field_Plane data to produce loss-less + * uncompressed 8 bit Y samples for bottom field of an interlaced frame. + * + * UV_Meta_Bottom_Field_Plane consists of meta information to decode + * compressed tile data in UV_UBWC_Bottom_Field_Plane. + * UV_UBWC_Bottom_Field_Plane consists of UV data in compressed + * macro-tile format for bottom field of an interlaced frame. + * UBWC decoder block will use UV_Meta_Bottom_Field_Plane data together + * with UV_UBWC_Bottom_Field_Plane data to produce loss-less + * uncompressed 8 bit subsampled color difference samples for bottom + * field of an interlaced frame. + * + * Each tile in Y_UBWC_Bottom_Field_Plane/UV_UBWC_Bottom_Field_Plane is + * independently decodable and randomly accessible. There is no + * dependency between tiles. + * + * <-----Y_TF_Meta_Stride----> + * <-------- Width ------> + * M M M M M M M M M M M M . . ^ ^ + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . Half_height | + * M M M M M M M M M M M M . . | Meta_Y_TF_Scanlines + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . V | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . V + * <-Compressed tile Y_TF Stride-> + * <------- Width -------> + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . ^ ^ + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . Half_height | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | Macro_tile_Y_TF_Scanlines + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . . . V + * <----UV_TF_Meta_Stride----> + * M M M M M M M M M M M M . . ^ + * M M M M M M M M M M M M . . | + * M M M M M M M M M M M M . . | + * M M M M M M M M M M M M . . M_UV_TF_Scanlines + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * <-Compressed tile UV_TF Stride-> + * U* V* U* V* U* V* U* V* . . . . ^ + * U* V* U* V* U* V* U* V* . . . . | + * U* V* U* V* U* V* U* V* . . . . | + * U* V* U* V* U* V* U* V* . . . . UV_TF_Scanlines + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * <-----Y_BF_Meta_Stride----> + * <-------- Width ------> + * M M M M M M M M M M M M . . ^ ^ + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . Half_height | + * M M M M M M M M M M M M . . | Meta_Y_BF_Scanlines + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . V | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . V + * <-Compressed tile Y_BF Stride-> + * <------- Width -------> + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . ^ ^ + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . Half_height | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | Macro_tile_Y_BF_Scanlines + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . . . V + * <----UV_BF_Meta_Stride----> + * M M M M M M M M M M M M . . ^ + * M M M M M M M M M M M M . . | + * M M M M M M M M M M M M . . | + * M M M M M M M M M M M M . . M_UV_BF_Scanlines + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * <-Compressed tile UV_BF Stride-> + * U* V* U* V* U* V* U* V* . . . . ^ + * U* V* U* V* U* V* U* V* . . . . | + * U* V* U* V* U* V* U* V* . . . . | + * U* V* U* V* U* V* U* V* . . . . UV_BF_Scanlines + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * + * Half_height = (Height+1)>>1 + * Y_TF_Stride = align(Width, 128) + * UV_TF_Stride = align(Width, 128) + * Y_TF_Scanlines = align(Half_height, 32) + * UV_TF_Scanlines = align((Half_height+1)/2, 32) + * Y_UBWC_TF_Plane_size = align(Y_TF_Stride * Y_TF_Scanlines, 4096) + * UV_UBWC_TF_Plane_size = align(UV_TF_Stride * UV_TF_Scanlines, 4096) + * Y_TF_Meta_Stride = align(roundup(Width, Y_TileWidth), 64) + * Y_TF_Meta_Scanlines = align(roundup(Half_height, Y_TileHeight), 16) + * Y_TF_Meta_Plane_size = + * align(Y_TF_Meta_Stride * Y_TF_Meta_Scanlines, 4096) + * UV_TF_Meta_Stride = align(roundup(Width, UV_TileWidth), 64) + * UV_TF_Meta_Scanlines = align(roundup(Half_height, UV_TileHeight), 16) + * UV_TF_Meta_Plane_size = + * align(UV_TF_Meta_Stride * UV_TF_Meta_Scanlines, 4096) + * Y_BF_Stride = align(Width, 128) + * UV_BF_Stride = align(Width, 128) + * Y_BF_Scanlines = align(Half_height, 32) + * UV_BF_Scanlines = align((Half_height+1)/2, 32) + * Y_UBWC_BF_Plane_size = align(Y_BF_Stride * Y_BF_Scanlines, 4096) + * UV_UBWC_BF_Plane_size = align(UV_BF_Stride * UV_BF_Scanlines, 4096) + * Y_BF_Meta_Stride = align(roundup(Width, Y_TileWidth), 64) + * Y_BF_Meta_Scanlines = align(roundup(Half_height, Y_TileHeight), 16) + * Y_BF_Meta_Plane_size = + * align(Y_BF_Meta_Stride * Y_BF_Meta_Scanlines, 4096) + * UV_BF_Meta_Stride = align(roundup(Width, UV_TileWidth), 64) + * UV_BF_Meta_Scanlines = align(roundup(Half_height, UV_TileHeight), 16) + * UV_BF_Meta_Plane_size = + * align(UV_BF_Meta_Stride * UV_BF_Meta_Scanlines, 4096) + * + * Total size = align( Y_UBWC_TF_Plane_size + UV_UBWC_TF_Plane_size + + * Y_TF_Meta_Plane_size + UV_TF_Meta_Plane_size + + * Y_UBWC_BF_Plane_size + UV_UBWC_BF_Plane_size + + * Y_BF_Meta_Plane_size + UV_BF_Meta_Plane_size +, 4096) + */ + COLOR_FMT_NV12_UBWC, + /* Venus NV12 10-bit UBWC: + * Compressed Macro-tile format for NV12. + * Contains 4 planes in the following order - + * (A) Y_Meta_Plane + * (B) Y_UBWC_Plane + * (C) UV_Meta_Plane + * (D) UV_UBWC_Plane + * + * Y_Meta_Plane consists of meta information to decode compressed + * tile data in Y_UBWC_Plane. + * Y_UBWC_Plane consists of Y data in compressed macro-tile format. + * UBWC decoder block will use the Y_Meta_Plane data together with + * Y_UBWC_Plane data to produce loss-less uncompressed 10 bit Y samples. + * + * UV_Meta_Plane consists of meta information to decode compressed + * tile data in UV_UBWC_Plane. + * UV_UBWC_Plane consists of UV data in compressed macro-tile format. + * UBWC decoder block will use UV_Meta_Plane data together with + * UV_UBWC_Plane data to produce loss-less uncompressed 10 bit 2x2 + * subsampled color difference samples. + * + * Each tile in Y_UBWC_Plane/UV_UBWC_Plane is independently decodable + * and randomly accessible. There is no dependency between tiles. + * + * <----- Y_Meta_Stride -----> + * <-------- Width ------> + * M M M M M M M M M M M M . . ^ ^ + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . Height | + * M M M M M M M M M M M M . . | Meta_Y_Scanlines + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . V | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . V + * <--Compressed tile Y Stride---> + * <------- Width -------> + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . ^ ^ + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . Height | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | Macro_tile_Y_Scanlines + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . . . V + * <----- UV_Meta_Stride ----> + * M M M M M M M M M M M M . . ^ + * M M M M M M M M M M M M . . | + * M M M M M M M M M M M M . . | + * M M M M M M M M M M M M . . M_UV_Scanlines + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * <--Compressed tile UV Stride---> + * U* V* U* V* U* V* U* V* . . . . ^ + * U* V* U* V* U* V* U* V* . . . . | + * U* V* U* V* U* V* U* V* . . . . | + * U* V* U* V* U* V* U* V* . . . . UV_Scanlines + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * + * + * Y_Stride = align(Width * 4/3, 256) + * UV_Stride = align(Width * 4/3, 256) + * Y_Scanlines = align(Height, 32) + * UV_Scanlines = align(Height/2, 16) + * Y_UBWC_Plane_Size = align(Y_Stride * Y_Scanlines, 4096) + * UV_UBWC_Plane_Size = align(UV_Stride * UV_Scanlines, 4096) + * Y_Meta_Stride = align(roundup(Width, Y_TileWidth), 64) + * Y_Meta_Scanlines = align(roundup(Height, Y_TileHeight), 16) + * Y_Meta_Plane_size = align(Y_Meta_Stride * Y_Meta_Scanlines, 4096) + * UV_Meta_Stride = align(roundup(Width, UV_TileWidth), 64) + * UV_Meta_Scanlines = align(roundup(Height, UV_TileHeight), 16) + * UV_Meta_Plane_size = align(UV_Meta_Stride * UV_Meta_Scanlines, 4096) + * + * Total size = align(Y_UBWC_Plane_size + UV_UBWC_Plane_size + + * Y_Meta_Plane_size + UV_Meta_Plane_size, 4096) + */ + COLOR_FMT_NV12_BPP10_UBWC, + /* Venus RGBA8888 format: + * Contains 1 plane in the following order - + * (A) RGBA plane + * + * <-------- RGB_Stride --------> + * <------- Width -------> + * R R R R R R R R R R R R . . . . ^ ^ + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . Height | + * R R R R R R R R R R R R . . . . | RGB_Scanlines + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * + * RGB_Stride = align(Width * 4, 128) + * RGB_Scanlines = align(Height, 32) + * RGB_Plane_size = align(RGB_Stride * RGB_Scanlines, 4096) + * + * Total size = align(RGB_Plane_size , 4096) + */ + COLOR_FMT_RGBA8888, + /* Venus RGBA8888 UBWC format: + * Contains 2 planes in the following order - + * (A) Meta plane + * (B) RGBA plane + * + * <--- RGB_Meta_Stride ----> + * <-------- Width ------> + * M M M M M M M M M M M M . . ^ ^ + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . Height | + * M M M M M M M M M M M M . . | Meta_RGB_Scanlines + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . V | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . V + * <-------- RGB_Stride --------> + * <------- Width -------> + * R R R R R R R R R R R R . . . . ^ ^ + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . Height | + * R R R R R R R R R R R R . . . . | RGB_Scanlines + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . . . V + * + * RGB_Stride = align(Width * 4, 256) + * RGB_Scanlines = align(Height, 16) + * RGB_Plane_size = align(RGB_Stride * RGB_Scanlines, 4096) + * RGB_Meta_Stride = align(roundup(Width, RGB_TileWidth), 64) + * RGB_Meta_Scanline = align(roundup(Height, RGB_TileHeight), 16) + * RGB_Meta_Plane_size = align(RGB_Meta_Stride * + * RGB_Meta_Scanlines, 4096) + * + * Total size = align(RGB_Meta_Plane_size + RGB_Plane_size, 4096) + */ + COLOR_FMT_RGBA8888_UBWC, + /* Venus RGBA1010102 UBWC format: + * Contains 2 planes in the following order - + * (A) Meta plane + * (B) RGBA plane + * + * <--- RGB_Meta_Stride ----> + * <-------- Width ------> + * M M M M M M M M M M M M . . ^ ^ + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . Height | + * M M M M M M M M M M M M . . | Meta_RGB_Scanlines + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . V | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . V + * <-------- RGB_Stride --------> + * <------- Width -------> + * R R R R R R R R R R R R . . . . ^ ^ + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . Height | + * R R R R R R R R R R R R . . . . | RGB_Scanlines + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . . . V + * + * RGB_Stride = align(Width * 4, 256) + * RGB_Scanlines = align(Height, 16) + * RGB_Plane_size = align(RGB_Stride * RGB_Scanlines, 4096) + * RGB_Meta_Stride = align(roundup(Width, RGB_TileWidth), 64) + * RGB_Meta_Scanline = align(roundup(Height, RGB_TileHeight), 16) + * RGB_Meta_Plane_size = align(RGB_Meta_Stride * + * RGB_Meta_Scanlines, 4096) + * + * Total size = align(RGB_Meta_Plane_size + RGB_Plane_size, 4096) + */ + COLOR_FMT_RGBA1010102_UBWC, + /* Venus RGB565 UBWC format: + * Contains 2 planes in the following order - + * (A) Meta plane + * (B) RGB plane + * + * <--- RGB_Meta_Stride ----> + * <-------- Width ------> + * M M M M M M M M M M M M . . ^ ^ + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . Height | + * M M M M M M M M M M M M . . | Meta_RGB_Scanlines + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . V | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . V + * <-------- RGB_Stride --------> + * <------- Width -------> + * R R R R R R R R R R R R . . . . ^ ^ + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . Height | + * R R R R R R R R R R R R . . . . | RGB_Scanlines + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . . . V + * + * RGB_Stride = align(Width * 2, 256) + * RGB_Scanlines = align(Height, 16) + * RGB_Plane_size = align(RGB_Stride * RGB_Scanlines, 4096) + * RGB_Meta_Stride = align(roundup(Width, RGB_TileWidth), 64) + * RGB_Meta_Scanline = align(roundup(Height, RGB_TileHeight), 16) + * RGB_Meta_Plane_size = align(RGB_Meta_Stride * + * RGB_Meta_Scanlines, 4096) + * + * Total size = align(RGB_Meta_Plane_size + RGB_Plane_size, 4096) + */ + COLOR_FMT_RGB565_UBWC, + /* P010 UBWC: + * Compressed Macro-tile format for NV12. + * Contains 4 planes in the following order - + * (A) Y_Meta_Plane + * (B) Y_UBWC_Plane + * (C) UV_Meta_Plane + * (D) UV_UBWC_Plane + * + * Y_Meta_Plane consists of meta information to decode compressed + * tile data in Y_UBWC_Plane. + * Y_UBWC_Plane consists of Y data in compressed macro-tile format. + * UBWC decoder block will use the Y_Meta_Plane data together with + * Y_UBWC_Plane data to produce loss-less uncompressed 10 bit Y samples. + * + * UV_Meta_Plane consists of meta information to decode compressed + * tile data in UV_UBWC_Plane. + * UV_UBWC_Plane consists of UV data in compressed macro-tile format. + * UBWC decoder block will use UV_Meta_Plane data together with + * UV_UBWC_Plane data to produce loss-less uncompressed 10 bit 2x2 + * subsampled color difference samples. + * + * Each tile in Y_UBWC_Plane/UV_UBWC_Plane is independently decodable + * and randomly accessible. There is no dependency between tiles. + * + * <----- Y_Meta_Stride -----> + * <-------- Width ------> + * M M M M M M M M M M M M . . ^ ^ + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . Height | + * M M M M M M M M M M M M . . | Meta_Y_Scanlines + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . V | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . V + * <--Compressed tile Y Stride---> + * <------- Width -------> + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . ^ ^ + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . Height | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | Macro_tile_Y_Scanlines + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . . . V + * <----- UV_Meta_Stride ----> + * M M M M M M M M M M M M . . ^ + * M M M M M M M M M M M M . . | + * M M M M M M M M M M M M . . | + * M M M M M M M M M M M M . . M_UV_Scanlines + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * <--Compressed tile UV Stride---> + * U* V* U* V* U* V* U* V* . . . . ^ + * U* V* U* V* U* V* U* V* . . . . | + * U* V* U* V* U* V* U* V* . . . . | + * U* V* U* V* U* V* U* V* . . . . UV_Scanlines + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * + * + * Y_Stride = align(Width * 2, 256) + * UV_Stride = align(Width * 2, 256) + * Y_Scanlines = align(Height, 16) + * UV_Scanlines = align(Height/2, 16) + * Y_UBWC_Plane_Size = align(Y_Stride * Y_Scanlines, 4096) + * UV_UBWC_Plane_Size = align(UV_Stride * UV_Scanlines, 4096) + * Y_Meta_Stride = align(roundup(Width, Y_TileWidth), 64) + * Y_Meta_Scanlines = align(roundup(Height, Y_TileHeight), 16) + * Y_Meta_Plane_size = align(Y_Meta_Stride * Y_Meta_Scanlines, 4096) + * UV_Meta_Stride = align(roundup(Width, UV_TileWidth), 64) + * UV_Meta_Scanlines = align(roundup(Height, UV_TileHeight), 16) + * UV_Meta_Plane_size = align(UV_Meta_Stride * UV_Meta_Scanlines, 4096) + * + * Total size = align(Y_UBWC_Plane_size + UV_UBWC_Plane_size + + * Y_Meta_Plane_size + UV_Meta_Plane_size, 4096) + */ + COLOR_FMT_P010_UBWC, + /* Venus P010: + * YUV 4:2:0 image with a plane of 10 bit Y samples followed + * by an interleaved U/V plane containing 10 bit 2x2 subsampled + * colour difference samples. + * + * <-------- Y/UV_Stride --------> + * <------- Width -------> + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . ^ ^ + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . Height | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | Y_Scanlines + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * U V U V U V U V U V U V . . . . ^ + * U V U V U V U V U V U V . . . . | + * U V U V U V U V U V U V . . . . | + * U V U V U V U V U V U V . . . . UV_Scanlines + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . . . --> Buffer size alignment + * + * Y_Stride : Width * 2 aligned to 256 + * UV_Stride : Width * 2 aligned to 256 + * Y_Scanlines: Height aligned to 32 + * UV_Scanlines: Height/2 aligned to 16 + * Total size = align(Y_Stride * Y_Scanlines + * + UV_Stride * UV_Scanlines, 4096) + */ + COLOR_FMT_P010, + /* Venus NV12_512: + * YUV 4:2:0 image with a plane of 8 bit Y samples followed + * by an interleaved U/V plane containing 8 bit 2x2 subsampled + * colour difference samples. + * + * <-------- Y/UV_Stride --------> + * <------- Width -------> + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . ^ ^ + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . Height | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | Y_Scanlines + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * U V U V U V U V U V U V . . . . ^ + * U V U V U V U V U V U V . . . . | + * U V U V U V U V U V U V . . . . | + * U V U V U V U V U V U V . . . . UV_Scanlines + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . . . --> Buffer size alignment + * + * Y_Stride : Width aligned to 512 + * UV_Stride : Width aligned to 512 + * Y_Scanlines: Height aligned to 512 + * UV_Scanlines: Height/2 aligned to 256 + * Total size = align((Y_Stride * Y_Scanlines + * + UV_Stride * UV_Scanlines), 4096) + */ + COLOR_FMT_NV12_512, +}; + +/* + * Function arguments: + * @color_fmt + * @width + * Progressive: width + * Interlaced: width + */ +static inline unsigned int VENUS_Y_STRIDE(unsigned int color_fmt, + unsigned int width) +{ + unsigned int alignment, stride = 0; + + if (!width) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_NV12: + case COLOR_FMT_NV21: + case COLOR_FMT_NV12_512: + alignment = 512; + stride = MSM_MEDIA_ALIGN(width, alignment); + break; + case COLOR_FMT_NV12_UBWC: + alignment = 128; + stride = MSM_MEDIA_ALIGN(width, alignment); + break; + case COLOR_FMT_NV12_BPP10_UBWC: + alignment = 256; + stride = MSM_MEDIA_ALIGN(width, 192); + stride = MSM_MEDIA_ALIGN(stride * 4/3, alignment); + break; + case COLOR_FMT_P010_UBWC: + case COLOR_FMT_P010: + alignment = 256; + stride = MSM_MEDIA_ALIGN(width * 2, alignment); + break; + default: + break; + } +invalid_input: + return stride; +} + +/* + * Function arguments: + * @color_fmt + * @width + * Progressive: width + * Interlaced: width + */ +static inline unsigned int VENUS_UV_STRIDE(unsigned int color_fmt, + unsigned int width) +{ + unsigned int alignment, stride = 0; + + if (!width) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_NV21: + case COLOR_FMT_NV12: + case COLOR_FMT_NV12_512: + alignment = 512; + stride = MSM_MEDIA_ALIGN(width, alignment); + break; + case COLOR_FMT_NV12_UBWC: + alignment = 128; + stride = MSM_MEDIA_ALIGN(width, alignment); + break; + case COLOR_FMT_NV12_BPP10_UBWC: + alignment = 256; + stride = MSM_MEDIA_ALIGN(width, 192); + stride = MSM_MEDIA_ALIGN(stride * 4/3, alignment); + break; + case COLOR_FMT_P010_UBWC: + case COLOR_FMT_P010: + alignment = 256; + stride = MSM_MEDIA_ALIGN(width * 2, alignment); + break; + default: + break; + } +invalid_input: + return stride; +} + +/* + * Function arguments: + * @color_fmt + * @height + * Progressive: height + * Interlaced: (height+1)>>1 + */ +static inline unsigned int VENUS_Y_SCANLINES(unsigned int color_fmt, + unsigned int height) +{ + unsigned int alignment, sclines = 0; + + if (!height) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_NV12: + case COLOR_FMT_NV21: + case COLOR_FMT_NV12_512: + alignment = 512; + break; + case COLOR_FMT_NV12_UBWC: + case COLOR_FMT_P010: + alignment = 32; + break; + case COLOR_FMT_NV12_BPP10_UBWC: + case COLOR_FMT_P010_UBWC: + alignment = 16; + break; + default: + return 0; + } + sclines = MSM_MEDIA_ALIGN(height, alignment); +invalid_input: + return sclines; +} + +/* + * Function arguments: + * @color_fmt + * @height + * Progressive: height + * Interlaced: (height+1)>>1 + */ +static inline unsigned int VENUS_UV_SCANLINES(unsigned int color_fmt, + unsigned int height) +{ + unsigned int alignment, sclines = 0; + + if (!height) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_NV21: + case COLOR_FMT_NV12: + case COLOR_FMT_NV12_512: + alignment = 256; + break; + case COLOR_FMT_NV12_BPP10_UBWC: + case COLOR_FMT_P010_UBWC: + case COLOR_FMT_P010: + alignment = 16; + break; + case COLOR_FMT_NV12_UBWC: + alignment = 32; + break; + default: + goto invalid_input; + } + + sclines = MSM_MEDIA_ALIGN((height+1)>>1, alignment); + +invalid_input: + return sclines; +} + +/* + * Function arguments: + * @color_fmt + * @width + * Progressive: width + * Interlaced: width + */ +static inline unsigned int VENUS_Y_META_STRIDE(unsigned int color_fmt, + unsigned int width) +{ + int y_tile_width = 0, y_meta_stride = 0; + + if (!width) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_NV12_UBWC: + case COLOR_FMT_P010_UBWC: + y_tile_width = 32; + break; + case COLOR_FMT_NV12_BPP10_UBWC: + y_tile_width = 48; + break; + default: + goto invalid_input; + } + + y_meta_stride = MSM_MEDIA_ROUNDUP(width, y_tile_width); + y_meta_stride = MSM_MEDIA_ALIGN(y_meta_stride, 64); + +invalid_input: + return y_meta_stride; +} + +/* + * Function arguments: + * @color_fmt + * @height + * Progressive: height + * Interlaced: (height+1)>>1 + */ +static inline unsigned int VENUS_Y_META_SCANLINES(unsigned int color_fmt, + unsigned int height) +{ + int y_tile_height = 0, y_meta_scanlines = 0; + + if (!height) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_NV12_UBWC: + y_tile_height = 8; + break; + case COLOR_FMT_NV12_BPP10_UBWC: + case COLOR_FMT_P010_UBWC: + y_tile_height = 4; + break; + default: + goto invalid_input; + } + + y_meta_scanlines = MSM_MEDIA_ROUNDUP(height, y_tile_height); + y_meta_scanlines = MSM_MEDIA_ALIGN(y_meta_scanlines, 16); + +invalid_input: + return y_meta_scanlines; +} + +/* + * Function arguments: + * @color_fmt + * @width + * Progressive: width + * Interlaced: width + */ +static inline unsigned int VENUS_UV_META_STRIDE(unsigned int color_fmt, + unsigned int width) +{ + int uv_tile_width = 0, uv_meta_stride = 0; + + if (!width) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_NV12_UBWC: + case COLOR_FMT_P010_UBWC: + uv_tile_width = 16; + break; + case COLOR_FMT_NV12_BPP10_UBWC: + uv_tile_width = 24; + break; + default: + goto invalid_input; + } + + uv_meta_stride = MSM_MEDIA_ROUNDUP((width+1)>>1, uv_tile_width); + uv_meta_stride = MSM_MEDIA_ALIGN(uv_meta_stride, 64); + +invalid_input: + return uv_meta_stride; +} + +/* + * Function arguments: + * @color_fmt + * @height + * Progressive: height + * Interlaced: (height+1)>>1 + */ +static inline unsigned int VENUS_UV_META_SCANLINES(unsigned int color_fmt, + unsigned int height) +{ + int uv_tile_height = 0, uv_meta_scanlines = 0; + + if (!height) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_NV12_UBWC: + uv_tile_height = 8; + break; + case COLOR_FMT_NV12_BPP10_UBWC: + case COLOR_FMT_P010_UBWC: + uv_tile_height = 4; + break; + default: + goto invalid_input; + } + + uv_meta_scanlines = MSM_MEDIA_ROUNDUP((height+1)>>1, uv_tile_height); + uv_meta_scanlines = MSM_MEDIA_ALIGN(uv_meta_scanlines, 16); + +invalid_input: + return uv_meta_scanlines; +} + +static inline unsigned int VENUS_RGB_STRIDE(unsigned int color_fmt, + unsigned int width) +{ + unsigned int alignment = 0, stride = 0, bpp = 4; + + if (!width) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_RGBA8888: + alignment = 128; + break; + case COLOR_FMT_RGB565_UBWC: + alignment = 256; + bpp = 2; + break; + case COLOR_FMT_RGBA8888_UBWC: + case COLOR_FMT_RGBA1010102_UBWC: + alignment = 256; + break; + default: + goto invalid_input; + } + + stride = MSM_MEDIA_ALIGN(width * bpp, alignment); + +invalid_input: + return stride; +} + +static inline unsigned int VENUS_RGB_SCANLINES(unsigned int color_fmt, + unsigned int height) +{ + unsigned int alignment = 0, scanlines = 0; + + if (!height) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_RGBA8888: + alignment = 32; + break; + case COLOR_FMT_RGBA8888_UBWC: + case COLOR_FMT_RGBA1010102_UBWC: + case COLOR_FMT_RGB565_UBWC: + alignment = 16; + break; + default: + goto invalid_input; + } + + scanlines = MSM_MEDIA_ALIGN(height, alignment); + +invalid_input: + return scanlines; +} + +static inline unsigned int VENUS_RGB_META_STRIDE(unsigned int color_fmt, + unsigned int width) +{ + int rgb_tile_width = 0, rgb_meta_stride = 0; + + if (!width) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_RGBA8888_UBWC: + case COLOR_FMT_RGBA1010102_UBWC: + case COLOR_FMT_RGB565_UBWC: + rgb_tile_width = 16; + break; + default: + goto invalid_input; + } + + rgb_meta_stride = MSM_MEDIA_ROUNDUP(width, rgb_tile_width); + rgb_meta_stride = MSM_MEDIA_ALIGN(rgb_meta_stride, 64); + +invalid_input: + return rgb_meta_stride; +} + +static inline unsigned int VENUS_RGB_META_SCANLINES(unsigned int color_fmt, + unsigned int height) +{ + int rgb_tile_height = 0, rgb_meta_scanlines = 0; + + if (!height) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_RGBA8888_UBWC: + case COLOR_FMT_RGBA1010102_UBWC: + case COLOR_FMT_RGB565_UBWC: + rgb_tile_height = 4; + break; + default: + goto invalid_input; + } + + rgb_meta_scanlines = MSM_MEDIA_ROUNDUP(height, rgb_tile_height); + rgb_meta_scanlines = MSM_MEDIA_ALIGN(rgb_meta_scanlines, 16); + +invalid_input: + return rgb_meta_scanlines; +} + +/* + * Function arguments: + * @color_fmt + * @width + * Progressive: width + * Interlaced: width + * @height + * Progressive: height + * Interlaced: height + */ +static inline unsigned int VENUS_BUFFER_SIZE(unsigned int color_fmt, + unsigned int width, unsigned int height) +{ + unsigned int size = 0; + unsigned int y_plane, uv_plane, y_stride, + uv_stride, y_sclines, uv_sclines; + unsigned int y_ubwc_plane = 0, uv_ubwc_plane = 0; + unsigned int y_meta_stride = 0, y_meta_scanlines = 0; + unsigned int uv_meta_stride = 0, uv_meta_scanlines = 0; + unsigned int y_meta_plane = 0, uv_meta_plane = 0; + unsigned int rgb_stride = 0, rgb_scanlines = 0; + unsigned int rgb_plane = 0, rgb_ubwc_plane = 0, rgb_meta_plane = 0; + unsigned int rgb_meta_stride = 0, rgb_meta_scanlines = 0; + + if (!width || !height) + goto invalid_input; + + y_stride = VENUS_Y_STRIDE(color_fmt, width); + uv_stride = VENUS_UV_STRIDE(color_fmt, width); + y_sclines = VENUS_Y_SCANLINES(color_fmt, height); + uv_sclines = VENUS_UV_SCANLINES(color_fmt, height); + rgb_stride = VENUS_RGB_STRIDE(color_fmt, width); + rgb_scanlines = VENUS_RGB_SCANLINES(color_fmt, height); + + switch (color_fmt) { + case COLOR_FMT_NV21: + case COLOR_FMT_NV12: + case COLOR_FMT_P010: + case COLOR_FMT_NV12_512: + y_plane = y_stride * y_sclines; + uv_plane = uv_stride * uv_sclines; + size = y_plane + uv_plane; + break; + case COLOR_FMT_NV12_UBWC: + y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width); + uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width); + if (width <= INTERLACE_WIDTH_MAX && + height <= INTERLACE_HEIGHT_MAX && + (height * width) / 256 <= INTERLACE_MB_PER_FRAME_MAX) { + y_sclines = + VENUS_Y_SCANLINES(color_fmt, (height+1)>>1); + y_ubwc_plane = + MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096); + uv_sclines = + VENUS_UV_SCANLINES(color_fmt, (height+1)>>1); + uv_ubwc_plane = + MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096); + y_meta_scanlines = + VENUS_Y_META_SCANLINES(color_fmt, (height+1)>>1); + y_meta_plane = MSM_MEDIA_ALIGN( + y_meta_stride * y_meta_scanlines, 4096); + uv_meta_scanlines = + VENUS_UV_META_SCANLINES(color_fmt, (height+1)>>1); + uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride * + uv_meta_scanlines, 4096); + size = (y_ubwc_plane + uv_ubwc_plane + y_meta_plane + + uv_meta_plane)*2; + } else { + y_sclines = VENUS_Y_SCANLINES(color_fmt, height); + y_ubwc_plane = + MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096); + uv_sclines = VENUS_UV_SCANLINES(color_fmt, height); + uv_ubwc_plane = + MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096); + y_meta_scanlines = + VENUS_Y_META_SCANLINES(color_fmt, height); + y_meta_plane = MSM_MEDIA_ALIGN( + y_meta_stride * y_meta_scanlines, 4096); + uv_meta_scanlines = + VENUS_UV_META_SCANLINES(color_fmt, height); + uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride * + uv_meta_scanlines, 4096); + size = (y_ubwc_plane + uv_ubwc_plane + y_meta_plane + + uv_meta_plane); + } + break; + case COLOR_FMT_NV12_BPP10_UBWC: + y_ubwc_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096); + uv_ubwc_plane = MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096); + y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width); + y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height); + y_meta_plane = MSM_MEDIA_ALIGN( + y_meta_stride * y_meta_scanlines, 4096); + uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width); + uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height); + uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride * + uv_meta_scanlines, 4096); + + size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + + uv_meta_plane; + break; + case COLOR_FMT_P010_UBWC: + y_ubwc_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096); + uv_ubwc_plane = MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096); + y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width); + y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height); + y_meta_plane = MSM_MEDIA_ALIGN( + y_meta_stride * y_meta_scanlines, 4096); + uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width); + uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height); + uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride * + uv_meta_scanlines, 4096); + + size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + + uv_meta_plane; + break; + case COLOR_FMT_RGBA8888: + rgb_plane = MSM_MEDIA_ALIGN(rgb_stride * rgb_scanlines, 4096); + size = rgb_plane; + break; + case COLOR_FMT_RGBA8888_UBWC: + case COLOR_FMT_RGBA1010102_UBWC: + case COLOR_FMT_RGB565_UBWC: + rgb_ubwc_plane = MSM_MEDIA_ALIGN(rgb_stride * rgb_scanlines, + 4096); + rgb_meta_stride = VENUS_RGB_META_STRIDE(color_fmt, width); + rgb_meta_scanlines = VENUS_RGB_META_SCANLINES(color_fmt, + height); + rgb_meta_plane = MSM_MEDIA_ALIGN(rgb_meta_stride * + rgb_meta_scanlines, 4096); + size = rgb_ubwc_plane + rgb_meta_plane; + break; + default: + break; + } +invalid_input: + return MSM_MEDIA_ALIGN(size, 4096); +} + +static inline unsigned int VENUS_BUFFER_SIZE_USED(unsigned int color_fmt, + unsigned int width, unsigned int height, unsigned int interlace) +{ + unsigned int size = 0; + unsigned int y_stride, uv_stride, y_sclines, uv_sclines; + unsigned int y_ubwc_plane = 0, uv_ubwc_plane = 0; + unsigned int y_meta_stride = 0, y_meta_scanlines = 0; + unsigned int uv_meta_stride = 0, uv_meta_scanlines = 0; + unsigned int y_meta_plane = 0, uv_meta_plane = 0; + + if (!width || !height) + goto invalid_input; + + if (!interlace && color_fmt == COLOR_FMT_NV12_UBWC) { + y_stride = VENUS_Y_STRIDE(color_fmt, width); + uv_stride = VENUS_UV_STRIDE(color_fmt, width); + y_sclines = VENUS_Y_SCANLINES(color_fmt, height); + y_ubwc_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096); + uv_sclines = VENUS_UV_SCANLINES(color_fmt, height); + uv_ubwc_plane = MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096); + y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width); + y_meta_scanlines = + VENUS_Y_META_SCANLINES(color_fmt, height); + y_meta_plane = MSM_MEDIA_ALIGN( + y_meta_stride * y_meta_scanlines, 4096); + uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width); + uv_meta_scanlines = + VENUS_UV_META_SCANLINES(color_fmt, height); + uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride * + uv_meta_scanlines, 4096); + size = (y_ubwc_plane + uv_ubwc_plane + y_meta_plane + + uv_meta_plane); + size = MSM_MEDIA_ALIGN(size, 4096); + } else { + size = VENUS_BUFFER_SIZE(color_fmt, width, height); + } +invalid_input: + return size; +} + +#endif diff --git a/include/uapi/media/msm_vidc_utils.h b/include/uapi/media/msm_vidc_utils.h new file mode 100644 index 000000000000..a02c174b60c3 --- /dev/null +++ b/include/uapi/media/msm_vidc_utils.h @@ -0,0 +1,614 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#ifndef __MSM_VIDC_UTILS_H__ +#define __MSM_VIDC_UTILS_H__ + +#include +#include + +/* vendor color format start */ +/* UBWC 8-bit Y/CbCr 4:2:0 */ +#define V4L2_PIX_FMT_NV12_UBWC v4l2_fourcc('Q', '1', '2', '8') +/* NV12_512 8-bit Y/CbCr 4:2:0 */ +#define V4L2_PIX_FMT_NV12_512 v4l2_fourcc('Q', '5', '1', '2') +/* NV12 10-bit Y/CbCr 4:2:0 */ +#define V4L2_PIX_FMT_NV12_P010_UBWC v4l2_fourcc('Q', '1', '2', 'B') +/* UBWC 10-bit Y/CbCr 4:2:0 */ +#define V4L2_PIX_FMT_NV12_TP10_UBWC v4l2_fourcc('Q', '1', '2', 'A') +#define V4L2_PIX_FMT_RGBA8888_UBWC v4l2_fourcc('Q', 'R', 'G', 'B') +#define V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS \ + v4l2_fourcc('Q', 'P', '1', '0') /* Y/CbCr 4:2:0 P10 Venus*/ +/* vendor color format end */ + +/* Vendor buffer flags start */ +#define V4L2_BUF_FLAG_CODECCONFIG 0x01000000 +#define V4L2_BUF_FLAG_END_OF_SUBFRAME 0x02000000 +#define V4L2_BUF_FLAG_DATA_CORRUPT 0x04000000 +#define V4L2_BUF_INPUT_UNSUPPORTED 0x08000000 +#define V4L2_BUF_FLAG_EOS 0x10000000 +#define V4L2_BUF_FLAG_READONLY 0x20000000 +#define V4L2_BUF_FLAG_PERF_MODE 0x40000000 +#define V4L2_BUF_FLAG_CVPMETADATA_SKIP 0x80000000 +/* Vendor buffer flags end */ + +/* Vendor commands start */ +#define V4L2_CMD_FLUSH (4) +/* flags for flush cmd */ +#define V4L2_CMD_FLUSH_OUTPUT (1 << 0) +#define V4L2_CMD_FLUSH_CAPTURE (1 << 1) +/* Vendor commands end */ + +/* Vendor events start */ +#define V4L2_EVENT_MSM_VIDC_START \ + (V4L2_EVENT_PRIVATE_START + 0x00001000) +#define V4L2_EVENT_MSM_VIDC_FLUSH_DONE \ + (V4L2_EVENT_MSM_VIDC_START + 1) +#define V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT \ + (V4L2_EVENT_MSM_VIDC_START + 2) +#define V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT \ + (V4L2_EVENT_MSM_VIDC_START + 3) +#define V4L2_EVENT_MSM_VIDC_SYS_ERROR \ + (V4L2_EVENT_MSM_VIDC_START + 5) +#define V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE \ + (V4L2_EVENT_MSM_VIDC_START + 6) +#define V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER \ + (V4L2_EVENT_MSM_VIDC_START + 7) +#define V4L2_EVENT_MSM_VIDC_HW_OVERLOAD \ + (V4L2_EVENT_MSM_VIDC_START + 8) +#define V4L2_EVENT_MSM_VIDC_MAX_CLIENTS \ + (V4L2_EVENT_MSM_VIDC_START + 9) +#define V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED \ + (V4L2_EVENT_MSM_VIDC_START + 10) +/* Vendor events end */ + +/* missing v4l2 entries start */ +enum v4l2_mpeg_vidc_video_bitrate_mode { + V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR = + V4L2_MPEG_VIDEO_BITRATE_MODE_CBR + 1, + V4L2_MPEG_VIDEO_BITRATE_MODE_MBR, + V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR, + V4L2_MPEG_VIDEO_BITRATE_MODE_CQ, +}; + +enum v4l2_mpeg_vidc_video_h264_profile { + V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH = + V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH + 1, +}; + +enum v4l2_mpeg_vidc_video_h264_level { + V4L2_MPEG_VIDEO_H264_LEVEL_5_2 = V4L2_MPEG_VIDEO_H264_LEVEL_5_1 + 1, + V4L2_MPEG_VIDEO_H264_LEVEL_6_0, + V4L2_MPEG_VIDEO_H264_LEVEL_6_1, + V4L2_MPEG_VIDEO_H264_LEVEL_6_2, +}; +/* missing v4l2 entries end */ + +/* vendor controls start */ +#define V4L2_CID_MPEG_MSM_VIDC_BASE (V4L2_CTRL_CLASS_MPEG | 0x2000) + +#define V4L2_MPEG_MSM_VIDC_DISABLE 0 +#define V4L2_MPEG_MSM_VIDC_ENABLE 1 + +#define V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE+0) +enum v4l2_mpeg_vidc_video_pictype_dec_mode { + V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_I = 1, + V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_P = 2, + V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_B = 4, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE+2) +enum v4l2_mpeg_vidc_video_stream_format { + V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES = 0, + V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH = 4, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER \ + (V4L2_CID_MPEG_MSM_VIDC_BASE+3) +#define V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM \ + (V4L2_CID_MPEG_MSM_VIDC_BASE+13) +#define V4L2_CID_MPEG_VIDC_VIDEO_AU_DELIMITER \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 14) +#define V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 15) +#define V4L2_CID_MPEG_VIDC_VIDEO_SECURE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE+16) +#define V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 17) +enum v4l2_mpeg_vidc_extradata { + EXTRADATA_NONE = 0, + EXTRADATA_DEFAULT = 1, + EXTRADATA_ADVANCED = 2, + EXTRADATA_ENC_INPUT_ROI = 4, + EXTRADATA_ENC_INPUT_HDR10PLUS = 8, + EXTRADATA_ENC_INPUT_CVP = 16, +}; +#define V4L2_CID_MPEG_VIDC_VIDEO_VUI_TIMING_INFO \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 19) +#define V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 20) +enum v4l2_mpeg_vidc_video_vp8_profile_level { + V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED, + V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0, + V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1, + V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_2, + V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3, +}; +#define V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL \ + (V4L2_CID_MPEG_MSM_VIDC_BASE+23) +enum v4l2_mpeg_vidc_video_mpeg2_level { + V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_0 = 0, + V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_1 = 1, + V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_2 = 2, + V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_3 = 3, +}; +#define V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE+24) +enum v4l2_mpeg_vidc_video_mpeg2_profile { + V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_SIMPLE = 0, + V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_MAIN = 1, + V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_HIGH = 2, +}; +#define V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 27) +#define V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 28) +#define V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 29) +#define V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 38) +#define V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 39) +#define V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 47) +#define V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 52) +#define V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 53) +#define V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 55) +#define V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 56) +#define V4L2_CID_MPEG_VIDC_VIDEO_BLUR_DIMENSIONS \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 57) +#define V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 60) +#define V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 61) +#define V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 62) +#define V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 63) +#define V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 67) +enum v4l2_mpeg_vidc_video_vp9_level { + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_UNUSED = 0, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_1 = 1, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_11 = 2, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_2 = 3, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_21 = 4, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_3 = 5, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_31 = 6, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_4 = 7, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_41 = 8, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_5 = 9, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_51 = 10, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6 = 11, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_61 = 12, +}; +#define V4L2_CID_MPEG_VIDC_VIDEO_DYN_QP \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 108) +#define V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_8BIT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 109) +#define V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_10BIT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 110) +#define V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_CUSTOM_MATRIX \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 114) +#define V4L2_CID_MPEG_VIDC_VENC_HDR_INFO \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 116) +#define V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 117) +#define V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 118) +#define V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 119) +#define V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 131) +#define V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 120) +enum v4l2_mpeg_vidc_video_hevc_max_hier_coding_layer { + V4L2_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER_0 = 0, + V4L2_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER_1 = 1, + V4L2_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER_2 = 2, + V4L2_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER_3 = 3, + V4L2_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER_4 = 4, + V4L2_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER_5 = 5, + V4L2_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER_6 = 6, +}; +#define V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 121) +#define V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 122) +#define V4L2_CID_MPEG_VIDC_VENC_RC_TIMESTAMP_DISABLE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 123) +#define V4L2_CID_MPEG_VIDC_SUPERFRAME \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 124) +#define V4L2_CID_MPEG_VIDC_CAPTURE_FRAME_RATE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 125) +#define V4L2_CID_MPEG_VIDC_CVP_FRAME_RATE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 126) +#define V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 127) +enum v4l2_mpeg_vidc_video_stream_output_mode { + V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY = 0, + V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY = 1, +}; +#define V4L2_CID_MPEG_VIDC_VIDEO_UNKNOWN \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 0xFFF) +/* vendor controls end */ + +#define MSM_VIDC_EXTRADATA_NONE 0x00000000 +struct msm_vidc_extradata_header { + __u32 size; + __u32 version; /** Keeping binary compatibility */ + __u32 port_index; /* with firmware and OpenMAX IL **/ + __u32 type; /* msm_vidc_extradata_type */ + __u32 data_size; + __u32 data[1]; +}; + +/* msm_vidc_interlace_type */ +#define MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE 0x01 +#define MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST 0x02 +#define MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST 0x04 +#define MSM_VIDC_INTERLACE_FRAME_TOPFIELDFIRST 0x08 +#define MSM_VIDC_INTERLACE_FRAME_BOTTOMFIELDFIRST 0x10 +#define MSM_VIDC_INTERLACE_FRAME_MBAFF 0x20 +/* Color formats */ +#define MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12 0x2 +#define MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12_UBWC 0x8002 +#define MSM_VIDC_EXTRADATA_INTERLACE_VIDEO 0x00000002 +struct msm_vidc_interlace_payload { + __u32 format; /* Interlace format */ + __u32 color_format; +}; + +#define MSM_VIDC_EXTRADATA_FRAME_RATE 0x00000007 +struct msm_vidc_framerate_payload { + __u32 frame_rate; /*In Q16 format */ +}; + +#define MSM_VIDC_EXTRADATA_TIMESTAMP 0x00000005 +struct msm_vidc_ts_payload { + __u32 timestamp_lo; + __u32 timestamp_hi; +}; + +#define MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB 0x7F100001 +struct msm_vidc_concealmb_payload { + __u32 num_mbs; +}; + + +#define MSM_VIDC_FRAME_RECONSTRUCTION_INCORRECT 0x0 +#define MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT 0x01 +#define MSM_VIDC_FRAME_RECONSTRUCTION_APPROXIMATELY_CORRECT 0x02 +#define MSM_VIDC_EXTRADATA_RECOVERY_POINT_SEI 0x00000009 +struct msm_vidc_recoverysei_payload { + __u32 flags; +}; + +#define MSM_VIDC_EXTRADATA_ASPECT_RATIO 0x7F100003 +struct msm_vidc_aspect_ratio_payload { + __u32 size; + __u32 version; + __u32 port_index; + __u32 aspect_width; + __u32 aspect_height; +}; + +struct msm_vidc_misr_info { + __u32 misr_set; + __u32 misr_dpb_luma[8]; + __u32 misr_dpb_chroma[8]; + __u32 misr_opb_luma[8]; + __u32 misr_opb_chroma[8]; +}; +#define MSM_VIDC_EXTRADATA_OUTPUT_CROP 0x0700000F +struct msm_vidc_output_crop_payload { + __u32 size; + __u32 version; + __u32 port_index; + __u32 left; + __u32 top; + __u32 display_width; + __u32 display_height; + __u32 width; + __u32 height; + __u32 frame_num; + __u32 bit_depth_y; + __u32 bit_depth_c; + struct msm_vidc_misr_info misr_info[2]; +}; + +#define MSM_VIDC_EXTRADATA_INDEX 0x7F100002 +struct msm_vidc_extradata_index { + __u32 type; + union { + struct msm_vidc_aspect_ratio_payload aspect_ratio; + }; +}; + +#define MSM_VIDC_EXTRADATA_PANSCAN_WINDOW 0x00000008 +struct msm_vidc_panscan_window { + __u32 panscan_height_offset; + __u32 panscan_width_offset; + __u32 panscan_window_width; + __u32 panscan_window_height; +}; + +struct msm_vidc_panscan_window_payload { + __u32 num_panscan_windows; + struct msm_vidc_panscan_window wnd[1]; +}; + +#define MSM_VIDC_USERDATA_TYPE_FRAME 0x1 +#define MSM_VIDC_USERDATA_TYPE_TOP_FIELD 0x2 +#define MSM_VIDC_USERDATA_TYPE_BOTTOM_FIELD 0x3 +#define MSM_VIDC_EXTRADATA_STREAM_USERDATA 0x0000000E +struct msm_vidc_stream_userdata_payload { + __u32 type; + __u32 data[1]; +}; + +#define MSM_VIDC_EXTRADATA_FRAME_QP 0x0000000F +struct msm_vidc_frame_qp_payload { + __u32 frame_qp; + __u32 qp_sum; + __u32 skip_qp_sum; + __u32 skip_num_blocks; + __u32 total_num_blocks; +}; + +#define MSM_VIDC_EXTRADATA_FRAME_BITS_INFO 0x00000010 +struct msm_vidc_frame_bits_info_payload { + __u32 frame_bits; + __u32 header_bits; +}; + +#define MSM_VIDC_EXTRADATA_S3D_FRAME_PACKING 0x00000006 +struct msm_vidc_s3d_frame_packing_payload { + __u32 fpa_id; + __u32 cancel_flag; + __u32 fpa_type; + __u32 quin_cunx_flag; + __u32 content_interprtation_type; + __u32 spatial_flipping_flag; + __u32 frame0_flipped_flag; + __u32 field_views_flag; + __u32 current_frame_is_frame0_flag; + __u32 frame0_self_contained_flag; + __u32 frame1_self_contained_flag; + __u32 frame0_graid_pos_x; + __u32 frame0_graid_pos_y; + __u32 frame1_graid_pos_x; + __u32 frame1_graid_pos_y; + __u32 fpa_reserved_byte; + __u32 fpa_repetition_period; + __u32 fpa_extension_flag; +}; + +#define MSM_VIDC_EXTRADATA_ROI_QP 0x00000013 +struct msm_vidc_roi_deltaqp_payload { + __u32 b_roi_info; /*Enable/Disable*/ + __u32 mbi_info_size; /*Size of QP data*/ + __u32 data[1]; +}; + +#define MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI 0x00000015 +struct msm_vidc_mastering_display_colour_sei_payload { + __u32 nDisplayPrimariesX[3]; + __u32 nDisplayPrimariesY[3]; + __u32 nWhitePointX; + __u32 nWhitePointY; + __u32 nMaxDisplayMasteringLuminance; + __u32 nMinDisplayMasteringLuminance; +}; + +#define MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI 0x00000016 +struct msm_vidc_content_light_level_sei_payload { + __u32 nMaxContentLight; + __u32 nMaxPicAverageLight; +}; + +#define MSM_VIDC_EXTRADATA_HDR10PLUS_METADATA 0x0000001A +struct msm_vidc_hdr10plus_metadata_payload { + __u32 size; + __u32 data[1]; +}; + +#define MSM_VIDC_EXTRADATA_CVP_METADATA 0x0000001B +struct msm_vidc_enc_cvp_metadata_payload { + __u32 data[256]; +}; + +/* video_format */ +#define MSM_VIDC_COMPONENT 0 +#define MSM_VIDC_PAL 1 +#define MSM_VIDC_NTSC 2 +#define MSM_VIDC_SECAM 3 +#define MSM_VIDC_MAC 4 +#define MSM_VIDC_UNSPECIFIED_FORMAT 5 +#define MSM_VIDC_RESERVED_1_FORMAT 6 +#define MSM_VIDC_RESERVED_2_FORMAT 7 + +/* See colour_primaries of ISO/IEC 14496 for significance */ +/* color_primaries values */ +#define MSM_VIDC_RESERVED_1 0 +#define MSM_VIDC_BT709_5 1 +#define MSM_VIDC_UNSPECIFIED 2 +#define MSM_VIDC_RESERVED_2 3 +#define MSM_VIDC_BT470_6_M 4 +#define MSM_VIDC_BT601_6_625 5 +#define MSM_VIDC_BT470_6_BG MSM_VIDC_BT601_6_625 +#define MSM_VIDC_BT601_6_525 6 +#define MSM_VIDC_SMPTE_240M 7 +#define MSM_VIDC_GENERIC_FILM 8 +#define MSM_VIDC_BT2020 9 + +/* matrix_coeffs values */ +#define MSM_VIDC_MATRIX_RGB 0 +#define MSM_VIDC_MATRIX_BT_709_5 1 +#define MSM_VIDC_MATRIX_UNSPECIFIED 2 +#define MSM_VIDC_MATRIX_RESERVED 3 +#define MSM_VIDC_MATRIX_FCC_47 4 +#define MSM_VIDC_MATRIX_601_6_625 5 +#define MSM_VIDC_MATRIX_BT470_BG MSM_VIDC_MATRIX_601_6_625 +#define MSM_VIDC_MATRIX_601_6_525 6 +#define MSM_VIDC_MATRIX_SMPTE_170M MSM_VIDC_MATRIX_601_6_525 +#define MSM_VIDC_MATRIX_SMPTE_240M 7 +#define MSM_VIDC_MATRIX_Y_CG_CO 8 +#define MSM_VIDC_MATRIX_BT_2020 9 +#define MSM_VIDC_MATRIX_BT_2020_CONST 10 + +/* transfer_char values */ +#define MSM_VIDC_TRANSFER_RESERVED_1 0 +#define MSM_VIDC_TRANSFER_BT709_5 1 +#define MSM_VIDC_TRANSFER_UNSPECIFIED 2 +#define MSM_VIDC_TRANSFER_RESERVED_2 3 +#define MSM_VIDC_TRANSFER_BT_470_6_M 4 +#define MSM_VIDC_TRANSFER_BT_470_6_BG 5 +#define MSM_VIDC_TRANSFER_601_6_625 6 +#define MSM_VIDC_TRANSFER_601_6_525 MSM_VIDC_TRANSFER_601_6_625 +#define MSM_VIDC_TRANSFER_SMPTE_240M 7 +#define MSM_VIDC_TRANSFER_LINEAR 8 +#define MSM_VIDC_TRANSFER_LOG_100_1 9 +#define MSM_VIDC_TRANSFER_LOG_100_SQRT10_1 10 +#define MSM_VIDC_TRANSFER_IEC_61966 11 +#define MSM_VIDC_TRANSFER_BT_1361 12 +#define MSM_VIDC_TRANSFER_SRGB 13 +#define MSM_VIDC_TRANSFER_BT_2020_10 14 +#define MSM_VIDC_TRANSFER_BT_2020_12 15 +#define MSM_VIDC_TRANSFER_SMPTE_ST2084 16 +#define MSM_VIDC_TRANSFER_SMPTE_ST428_1 17 +#define MSM_VIDC_TRANSFER_HLG 18 + +#define MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO 0x7F100006 +struct msm_vidc_vui_display_info_payload { + __u32 video_signal_present_flag; + __u32 video_format; + __u32 bit_depth_y; + __u32 bit_depth_c; + __u32 video_full_range_flag; + __u32 color_description_present_flag; + __u32 color_primaries; + __u32 transfer_char; + __u32 matrix_coeffs; + __u32 chroma_location_info_present_flag; + __u32 chroma_format_idc; + __u32 separate_color_plane_flag; + __u32 chroma_sample_loc_type_top_field; + __u32 chroma_sample_loc_type_bottom_field; +}; + +#define MSM_VIDC_EXTRADATA_HDR_HIST 0x7F100008 +struct msm_vidc_extradata_hdr_hist_payload { + __u32 value_count[1024]; +}; + +#define MSM_VIDC_EXTRADATA_MPEG2_SEQDISP 0x0000000D +struct msm_vidc_mpeg2_seqdisp_payload { + __u32 video_format; + __u32 color_descp; + __u32 color_primaries; + __u32 transfer_char; + __u32 matrix_coeffs; + __u32 disp_width; + __u32 disp_height; +}; + +/* VPx color_space values */ +#define MSM_VIDC_CS_UNKNOWN 0 +#define MSM_VIDC_CS_BT_601 1 +#define MSM_VIDC_CS_BT_709 2 +#define MSM_VIDC_CS_SMPTE_170 3 +#define MSM_VIDC_CS_SMPTE_240 4 +#define MSM_VIDC_CS_BT_2020 5 +#define MSM_VIDC_CS_RESERVED 6 +#define MSM_VIDC_CS_RGB 7 +#define MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO 0x00000014 +struct msm_vidc_vpx_colorspace_payload { + __u32 color_space; + __u32 yuv_range_flag; + __u32 sumsampling_x; + __u32 sumsampling_y; +}; + +#define MSM_VIDC_EXTRADATA_METADATA_LTRINFO 0x7F100004 +/* Don't use the #define below. It is to bypass checkpatch */ +#define LTRINFO MSM_VIDC_EXTRADATA_METADATA_LTRINFO +struct msm_vidc_metadata_ltr_payload { + __u32 ltr_use_mark; +}; + +/* ptr[2]: event_notify: pixel_depth */ +#define MSM_VIDC_BIT_DEPTH_8 0 +#define MSM_VIDC_BIT_DEPTH_10 1 +#define MSM_VIDC_BIT_DEPTH_UNSUPPORTED 0XFFFFFFFF + +/* ptr[3]: event_notify: pic_struct */ +#define MSM_VIDC_PIC_STRUCT_MAYBE_INTERLACED 0x0 +#define MSM_VIDC_PIC_STRUCT_PROGRESSIVE 0x1 + +/*default when layer ID isn't specified*/ +#define MSM_VIDC_ALL_LAYER_ID 0xFF + +static inline unsigned int VENUS_EXTRADATA_SIZE(int width, int height) +{ + (void)height; + (void)width; + + /* + * In the future, calculate the size based on the w/h but just + * hardcode it for now since 16K satisfies all current usecases. + */ + return 16 * 1024; +} + +/* V4L2_CID_MPEG_VIDC_VENC_HDR_INFO payload index */ +enum msm_vidc_hdr_info_types { + MSM_VIDC_RGB_PRIMARY_00, + MSM_VIDC_RGB_PRIMARY_01, + MSM_VIDC_RGB_PRIMARY_10, + MSM_VIDC_RGB_PRIMARY_11, + MSM_VIDC_RGB_PRIMARY_20, + MSM_VIDC_RGB_PRIMARY_21, + MSM_VIDC_WHITEPOINT_X, + MSM_VIDC_WHITEPOINT_Y, + MSM_VIDC_MAX_DISP_LUM, + MSM_VIDC_MIN_DISP_LUM, + MSM_VIDC_RGB_MAX_CLL, + MSM_VIDC_RGB_MAX_FLL, +}; + +enum msm_vidc_plane_reserved_field_types { + MSM_VIDC_BUFFER_FD, + MSM_VIDC_DATA_OFFSET, + MSM_VIDC_COMP_RATIO, + MSM_VIDC_INPUT_TAG_1, + MSM_VIDC_INPUT_TAG_2, +}; + +enum msm_vidc_cb_event_types { + MSM_VIDC_HEIGHT, + MSM_VIDC_WIDTH, + MSM_VIDC_BIT_DEPTH, + MSM_VIDC_PIC_STRUCT, + MSM_VIDC_COLOR_SPACE, + MSM_VIDC_FW_MIN_COUNT, +}; +#endif From 2c2d48f5b66a072a3713032a6e44043ba6a9d50b Mon Sep 17 00:00:00 2001 From: Karthikeyan Periasamy Date: Wed, 23 Oct 2019 12:48:31 -0700 Subject: [PATCH 164/452] msm: vidc: fix the compilation in lahaina - Made the changes in video module to compile successfully. - Removed cvp and v4l2 private files. Change-Id: Iaf5f29d6042a87d5b96b1fa4abb985ee3e592f0e Signed-off-by: Karthikeyan Periasamy --- Makefile | 4 +- config/konavidconf.h | 2 +- msm/Makefile | 3 - msm/vidc/hfi_common.c | 476 +--------- msm/vidc/hfi_common.h | 17 +- msm/vidc/hfi_iris1.c | 11 +- msm/vidc/hfi_iris2.c | 2 - msm/vidc/hfi_packetization.c | 75 -- msm/vidc/hfi_packetization.h | 7 - msm/vidc/hfi_response_handler.c | 67 -- msm/vidc/msm_cvp_external.c | 1499 ------------------------------- msm/vidc/msm_cvp_external.h | 202 ----- msm/vidc/msm_cvp_internal.c | 623 ------------- msm/vidc/msm_cvp_internal.h | 25 - msm/vidc/msm_smem.c | 9 +- msm/vidc/msm_v4l2_private.c | 224 ----- msm/vidc/msm_v4l2_private.h | 14 - msm/vidc/msm_v4l2_vidc.c | 51 +- msm/vidc/msm_vdec.c | 4 +- msm/vidc/msm_venc.c | 27 +- msm/vidc/msm_vidc.c | 206 +---- msm/vidc/msm_vidc.h | 18 +- msm/vidc/msm_vidc_bus_iris1.c | 8 - msm/vidc/msm_vidc_bus_iris2.c | 8 - msm/vidc/msm_vidc_clocks.c | 28 +- msm/vidc/msm_vidc_common.c | 91 -- msm/vidc/msm_vidc_common.h | 5 - msm/vidc/msm_vidc_debug.c | 190 +++- msm/vidc/msm_vidc_debug.h | 77 +- msm/vidc/msm_vidc_internal.h | 22 - msm/vidc/msm_vidc_platform.c | 32 - msm/vidc/msm_vidc_res_parse.c | 60 -- msm/vidc/msm_vidc_resources.h | 3 - msm/vidc/vidc_hfi.c | 1 - msm/vidc/vidc_hfi.h | 32 - msm/vidc/vidc_hfi_api.h | 34 - msm/vidc/vidc_hfi_helper.h | 26 +- 37 files changed, 298 insertions(+), 3885 deletions(-) delete mode 100644 msm/vidc/msm_cvp_external.c delete mode 100644 msm/vidc/msm_cvp_external.h delete mode 100644 msm/vidc/msm_cvp_internal.c delete mode 100644 msm/vidc/msm_cvp_internal.h delete mode 100644 msm/vidc/msm_v4l2_private.c delete mode 100644 msm/vidc/msm_v4l2_private.h diff --git a/Makefile b/Makefile index 988acbbe6653..cbe215e1a9b6 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ # SPDX-License-Identifier: GPL-2.0-only # auto-detect subdirs -ifeq ($(CONFIG_ARCH_KONA), y) +ifeq ($(CONFIG_ARCH_LAHAINA), y) include $(srctree)/techpack/video/config/konavid.conf endif -ifeq ($(CONFIG_ARCH_KONA), y) +ifeq ($(CONFIG_ARCH_LAHAINA), y) LINUXINCLUDE += -include $(srctree)/techpack/video/config/konavidconf.h endif diff --git a/config/konavidconf.h b/config/konavidconf.h index da305d52ecd1..78d6c57a6920 100644 --- a/config/konavidconf.h +++ b/config/konavidconf.h @@ -3,4 +3,4 @@ * Copyright (c) 2019, The Linux Foundation. All rights reserved. */ -#define CONFIG_MSM_VIDC_V4L2 1 +#define CONFIG_MSM_VIDC_V4L2 1 diff --git a/msm/Makefile b/msm/Makefile index df7f6020801b..b9d8a7171758 100644 --- a/msm/Makefile +++ b/msm/Makefile @@ -3,14 +3,11 @@ ccflags-y += -I$(srctree)/techpack/video/msm/vidc/ \ -I$(srctree)/drivers/devfreq/ msm-vidc-objs := vidc/msm_v4l2_vidc.o \ - vidc/msm_v4l2_private.o \ vidc/msm_vidc_platform.o \ vidc/msm_vidc_common.o \ vidc/msm_vidc.o \ vidc/msm_vdec.o \ vidc/msm_venc.o \ - vidc/msm_cvp_internal.o \ - vidc/msm_cvp_external.o \ vidc/msm_smem.o \ vidc/msm_vidc_debug.o \ vidc/msm_vidc_res_parse.o \ diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 61a84c954c39..83202257e9f6 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -3,35 +3,7 @@ * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "hfi_packetization.h" -#include "msm_vidc_debug.h" #include "hfi_common.h" -#include "hfi_io_common.h" #define FIRMWARE_SIZE 0X00A00000 #define REG_ADDR_OFFSET_BITMASK 0x000FFFFF @@ -304,147 +276,11 @@ static void __sim_modify_cmd_packet(u8 *packet, struct venus_hfi_device *device) } break; } - case HFI_CMD_SESSION_REGISTER_BUFFERS: - { - struct hfi_cmd_session_register_buffers_packet *pkt = - (struct hfi_cmd_session_register_buffers_packet *) - packet; - struct hfi_buffer_mapping_type *buf = - (struct hfi_buffer_mapping_type *)pkt->buffer; - for (i = 0; i < pkt->num_buffers; i++) - buf[i].device_addr -= fw_bias; - break; - } default: break; } } -static int __dsp_send_hfi_queue(struct venus_hfi_device *device) -{ - int rc; - - if (!device->res->cvp_internal) - return 0; - - if (!device->dsp_iface_q_table.mem_data.dma_handle) { - d_vpr_e("%s: invalid dsm_handle\n", __func__); - return -EINVAL; - } - - if (device->dsp_flags & DSP_INIT) { - d_vpr_h("%s: dsp already inited\n", __func__); - return 0; - } - - d_vpr_h("%s: hfi queue %#llx size %d\n", - __func__, device->dsp_iface_q_table.mem_data.dma_handle, - device->dsp_iface_q_table.mem_data.size); - rc = fastcvpd_video_send_cmd_hfi_queue( - (phys_addr_t *)device->dsp_iface_q_table.mem_data.dma_handle, - device->dsp_iface_q_table.mem_data.size); - if (rc) { - d_vpr_e("%s: dsp init failed\n", __func__); - return rc; - } - - device->dsp_flags |= DSP_INIT; - d_vpr_h("%s: dsp inited\n", __func__); - return rc; -} - -static int __dsp_suspend(struct venus_hfi_device *device, bool force, u32 flags) -{ - int rc; - struct hal_session *temp; - - if (!device->res->cvp_internal) - return 0; - - if (!(device->dsp_flags & DSP_INIT)) - return 0; - - if (device->dsp_flags & DSP_SUSPEND) - return 0; - - list_for_each_entry(temp, &device->sess_head, list) { - /* if forceful suspend, don't check session pause info */ - if (force) - continue; - if (temp->domain == HAL_VIDEO_DOMAIN_CVP) { - /* don't suspend if cvp session is not paused */ - if (!(temp->flags & SESSION_PAUSE)) { - s_vpr_h(temp->sid, - "%s: cvp session not paused\n", - __func__); - return -EBUSY; - } - } - } - - d_vpr_h("%s: suspend dsp\n", __func__); - rc = fastcvpd_video_suspend(flags); - if (rc) { - d_vpr_e("%s: dsp suspend failed with error %d\n", - __func__, rc); - return -EINVAL; - } - - device->dsp_flags |= DSP_SUSPEND; - d_vpr_h("%s: dsp suspended\n", __func__); - return 0; -} - -static int __dsp_resume(struct venus_hfi_device *device, u32 flags) -{ - int rc; - - if (!device->res->cvp_internal) - return 0; - - if (!(device->dsp_flags & DSP_SUSPEND)) { - d_vpr_h("%s: dsp not suspended\n", __func__); - return 0; - } - - d_vpr_h("%s: resume dsp\n", __func__); - rc = fastcvpd_video_resume(flags); - if (rc) { - d_vpr_e("%s: dsp resume failed with error %d\n", - __func__, rc); - return rc; - } - - device->dsp_flags &= ~DSP_SUSPEND; - d_vpr_h("%s: dsp resumed\n", __func__); - return rc; -} - -static int __dsp_shutdown(struct venus_hfi_device *device, u32 flags) -{ - int rc; - - if (!device->res->cvp_internal) - return 0; - - if (!(device->dsp_flags & DSP_INIT)) { - d_vpr_h("%s: dsp not inited\n", __func__); - return 0; - } - - d_vpr_h("%s: shutdown dsp\n", __func__); - rc = fastcvpd_video_shutdown(flags); - if (rc) { - d_vpr_e("%s: dsp shutdown failed with error %d\n", - __func__, rc); - WARN_ON(1); - } - - device->dsp_flags &= ~DSP_INIT; - d_vpr_h("%s: dsp shutdown successful\n", __func__); - return rc; -} - static int __session_pause(struct venus_hfi_device *device, struct hal_session *session) { @@ -458,7 +294,7 @@ static int __session_pause(struct venus_hfi_device *device, return 0; session->flags |= SESSION_PAUSE; - s_vpr_h(session->sid, "%s: cvp session paused\n", __func__); + s_vpr_h(session->sid, "%s: session paused\n", __func__); return rc; } @@ -476,7 +312,7 @@ static int __session_resume(struct venus_hfi_device *device, return 0; session->flags &= ~SESSION_PAUSE; - s_vpr_h(session->sid, "%s: cvp session resumed\n", __func__); + s_vpr_h(session->sid, "%s: session resumed\n", __func__); rc = __resume(device, session->sid); if (rc) { @@ -484,12 +320,6 @@ static int __session_resume(struct venus_hfi_device *device, goto exit; } - if (device->dsp_flags & DSP_SUSPEND) { - s_vpr_e(session->sid, "%s: dsp not resumed\n", __func__); - rc = -EINVAL; - goto exit; - } - exit: return rc; } @@ -1185,8 +1015,6 @@ static inline int __boot_firmware_common( u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 1000; ctrl_init_val = BIT(0); - if (device->res->cvp_internal) - ctrl_init_val |= BIT(1); __write_register(device, CTRL_INIT, ctrl_init_val, sid); while (!ctrl_status && count < max_tries) { @@ -1262,21 +1090,8 @@ static int __set_clk_rate(struct venus_hfi_device *device, struct clock_info *cl, u64 rate, u32 sid) { int rc = 0; - u64 threshold_freq = device->res->clk_freq_threshold; - struct cx_ipeak_client *ipeak = device->res->cx_ipeak_context; struct clk *clk = cl->clk; - if (ipeak && device->clk_freq < threshold_freq && rate >= threshold_freq) { - rc = cx_ipeak_update(ipeak, true); - if (rc) { - s_vpr_e(sid, "%s: cx_ipeak_update failed!\n", __func__); - return rc; - } - s_vpr_p(sid, - "cx_ipeak_update: up, clk freq = %lu rate = %lu threshold_freq = %lu\n", - device->clk_freq, rate, threshold_freq); - } - rc = clk_set_rate(clk, rate); if (rc) { s_vpr_e(sid, @@ -1285,19 +1100,6 @@ static int __set_clk_rate(struct venus_hfi_device *device, return rc; } - if (ipeak && device->clk_freq >= threshold_freq && rate < threshold_freq) { - rc = cx_ipeak_update(ipeak, false); - if (rc) { - s_vpr_e(sid, - "cx_ipeak_update failed! ipeak %pK\n", ipeak); - device->clk_freq = rate; - return rc; - } - s_vpr_p(sid, - "cx_ipeak_update: up, clk freq = %lu rate = %lu threshold_freq = %lu\n", - device->clk_freq, rate, threshold_freq); - } - device->clk_freq = rate; return rc; @@ -1535,138 +1337,6 @@ static void __set_queue_hdr_defaults(struct hfi_queue_header *q_hdr) q_hdr->qhdr_write_idx = 0x0; } -static void __interface_dsp_queues_release(struct venus_hfi_device *device) -{ - int i; - struct msm_smem *mem_data = &device->dsp_iface_q_table.mem_data; - struct context_bank_info *cb = mem_data->mapping_info.cb_info; - - if (!device->dsp_iface_q_table.align_virtual_addr) { - d_vpr_e("%s: already released\n", __func__); - return; - } - - dma_unmap_single_attrs(cb->dev, mem_data->device_addr, - mem_data->size, DMA_BIDIRECTIONAL, 0); - dma_free_coherent(device->res->mem_cdsp.dev, mem_data->size, - mem_data->kvaddr, mem_data->dma_handle); - - for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) { - device->dsp_iface_queues[i].q_hdr = NULL; - device->dsp_iface_queues[i].q_array.align_virtual_addr = NULL; - device->dsp_iface_queues[i].q_array.align_device_addr = 0; - } - device->dsp_iface_q_table.align_virtual_addr = NULL; - device->dsp_iface_q_table.align_device_addr = 0; -} - -static int __interface_dsp_queues_init(struct venus_hfi_device *dev) -{ - int rc = 0; - u32 i; - struct hfi_queue_table_header *q_tbl_hdr; - struct hfi_queue_header *q_hdr; - struct vidc_iface_q_info *iface_q; - int offset = 0; - phys_addr_t fw_bias = 0; - size_t q_size; - struct msm_smem *mem_data; - void *kvaddr; - dma_addr_t dma_handle; - dma_addr_t iova; - struct context_bank_info *cb; - - q_size = ALIGN(QUEUE_SIZE, SZ_1M); - mem_data = &dev->dsp_iface_q_table.mem_data; - - /* Allocate dsp queues from ADSP device memory */ - kvaddr = dma_alloc_coherent(dev->res->mem_cdsp.dev, q_size, - &dma_handle, GFP_KERNEL); - if (IS_ERR_OR_NULL(kvaddr)) { - d_vpr_e("%s: failed dma allocation\n", __func__); - goto fail_dma_alloc; - } - cb = msm_smem_get_context_bank(MSM_VIDC_UNKNOWN, 0, - dev->res, HAL_BUFFER_INTERNAL_CMD_QUEUE, DEFAULT_SID); - if (!cb) { - d_vpr_e("%s: failed to get context bank\n", __func__); - goto fail_dma_map; - } - iova = dma_map_single_attrs(cb->dev, phys_to_virt(dma_handle), - q_size, DMA_BIDIRECTIONAL, 0); - if (dma_mapping_error(cb->dev, iova)) { - d_vpr_e("%s: failed dma mapping\n", __func__); - goto fail_dma_map; - } - d_vpr_h("%s: kvaddr %pK dma_handle %#llx iova %#llx size %zd\n", - __func__, kvaddr, dma_handle, iova, q_size); - - memset(mem_data, 0, sizeof(struct msm_smem)); - mem_data->kvaddr = kvaddr; - mem_data->device_addr = iova; - mem_data->dma_handle = dma_handle; - mem_data->size = q_size; - mem_data->buffer_type = HAL_BUFFER_INTERNAL_CMD_QUEUE; - mem_data->mapping_info.cb_info = cb; - - if (!is_iommu_present(dev->res)) - fw_bias = dev->hal_data->firmware_base; - - dev->dsp_iface_q_table.align_virtual_addr = kvaddr; - dev->dsp_iface_q_table.align_device_addr = iova - fw_bias; - dev->dsp_iface_q_table.mem_size = VIDC_IFACEQ_TABLE_SIZE; - offset = dev->dsp_iface_q_table.mem_size; - - for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) { - iface_q = &dev->dsp_iface_queues[i]; - iface_q->q_array.align_device_addr = iova + offset - fw_bias; - iface_q->q_array.align_virtual_addr = - (void *)((char *)kvaddr + offset); - iface_q->q_array.mem_size = VIDC_IFACEQ_QUEUE_SIZE; - offset += iface_q->q_array.mem_size; - iface_q->q_hdr = VIDC_IFACEQ_GET_QHDR_START_ADDR( - dev->dsp_iface_q_table.align_virtual_addr, i); - __set_queue_hdr_defaults(iface_q->q_hdr); - } - - q_tbl_hdr = (struct hfi_queue_table_header *) - dev->dsp_iface_q_table.align_virtual_addr; - q_tbl_hdr->qtbl_version = 0; - q_tbl_hdr->device_addr = (void *)dev; - strlcpy(q_tbl_hdr->name, "msm_v4l2_vidc", sizeof(q_tbl_hdr->name)); - q_tbl_hdr->qtbl_size = VIDC_IFACEQ_TABLE_SIZE; - q_tbl_hdr->qtbl_qhdr0_offset = sizeof(struct hfi_queue_table_header); - q_tbl_hdr->qtbl_qhdr_size = sizeof(struct hfi_queue_header); - q_tbl_hdr->qtbl_num_q = VIDC_IFACEQ_NUMQ; - q_tbl_hdr->qtbl_num_active_q = VIDC_IFACEQ_NUMQ; - - iface_q = &dev->dsp_iface_queues[VIDC_IFACEQ_CMDQ_IDX]; - q_hdr = iface_q->q_hdr; - q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; - q_hdr->qhdr_type |= HFI_Q_ID_HOST_TO_CTRL_CMD_Q; - - iface_q = &dev->dsp_iface_queues[VIDC_IFACEQ_MSGQ_IDX]; - q_hdr = iface_q->q_hdr; - q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; - q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_MSG_Q; - - iface_q = &dev->dsp_iface_queues[VIDC_IFACEQ_DBGQ_IDX]; - q_hdr = iface_q->q_hdr; - q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; - q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q; - /* - * Set receive request to zero on debug queue as there is no - * need of interrupt from video hardware for debug messages - */ - q_hdr->qhdr_rx_req = 0; - return rc; - -fail_dma_map: - dma_free_coherent(dev->res->mem_cdsp.dev, q_size, kvaddr, dma_handle); -fail_dma_alloc: - return -ENOMEM; -} - static void __interface_queues_release(struct venus_hfi_device *device) { int i; @@ -1726,8 +1396,6 @@ static void __interface_queues_release(struct venus_hfi_device *device) device->mem_addr.align_virtual_addr = NULL; device->mem_addr.align_device_addr = 0; - if (device->res->cvp_internal) - __interface_dsp_queues_release(device); } static int __get_qdss_iommu_virtual_addr(struct venus_hfi_device *dev, @@ -1936,15 +1604,6 @@ static int __interface_queues_init(struct venus_hfi_device *dev) } } - - if (dev->res->cvp_internal) { - rc = __interface_dsp_queues_init(dev); - if (rc) { - d_vpr_e("dsp_queues_init failed\n"); - goto fail_alloc_queue; - } - } - call_venus_op(dev, setup_ucregion_memmap, dev, DEFAULT_SID); return 0; fail_alloc_queue: @@ -2084,15 +1743,10 @@ static int venus_hfi_core_init(void *device) __enable_subcaches(device, DEFAULT_SID); __set_subcaches(device, DEFAULT_SID); - __dsp_send_hfi_queue(device); __set_ubwc_config(device); if (dev->res->pm_qos_latency_us) { -#ifdef CONFIG_SMP - dev->qos.type = PM_QOS_REQ_AFFINE_IRQ; - dev->qos.irq = dev->hal_data->irq; -#endif pm_qos_add_request(&dev->qos, PM_QOS_CPU_DMA_LATENCY, dev->res->pm_qos_latency_us); } @@ -2127,7 +1781,6 @@ static int venus_hfi_core_release(void *dev) __resume(device, DEFAULT_SID); __set_state(device, VENUS_STATE_DEINIT); - __dsp_shutdown(device, 0); __unload_fw(device); @@ -2522,76 +2175,6 @@ static int venus_hfi_session_release_buffers(void *sess, return rc; } -static int venus_hfi_session_register_buffer(void *sess, - struct vidc_register_buffer *buffer) -{ - int rc = 0; - u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE]; - struct hfi_cmd_session_register_buffers_packet *pkt; - struct hal_session *session = sess; - struct venus_hfi_device *device = &venus_hfi_dev; - - if (!buffer) { - d_vpr_e("%s: invalid params\n", __func__); - return -EINVAL; - } - - mutex_lock(&device->lock); - if (!__is_session_valid(device, session, __func__)) { - rc = -EINVAL; - goto exit; - } - pkt = (struct hfi_cmd_session_register_buffers_packet *)packet; - rc = call_hfi_pkt_op(device, session_register_buffer, pkt, - session->sid, buffer); - if (rc) { - s_vpr_e(session->sid, - "%s: failed to create packet\n", __func__); - goto exit; - } - if (__iface_cmdq_write(device, pkt, session->sid)) - rc = -ENOTEMPTY; -exit: - mutex_unlock(&device->lock); - - return rc; -} - -static int venus_hfi_session_unregister_buffer(void *sess, - struct vidc_unregister_buffer *buffer) -{ - int rc = 0; - u8 packet[VIDC_IFACEQ_VAR_LARGE_PKT_SIZE]; - struct hfi_cmd_session_unregister_buffers_packet *pkt; - struct hal_session *session = sess; - struct venus_hfi_device *device = &venus_hfi_dev; - - if (!buffer) { - d_vpr_e("%s: invalid params\n", __func__); - return -EINVAL; - } - - mutex_lock(&device->lock); - if (!__is_session_valid(device, session, __func__)) { - rc = -EINVAL; - goto exit; - } - pkt = (struct hfi_cmd_session_unregister_buffers_packet *)packet; - rc = call_hfi_pkt_op(device, session_unregister_buffer, pkt, - session->sid, buffer); - if (rc) { - s_vpr_e(session->sid, - "%s: failed to create packet\n", __func__); - goto exit; - } - if (__iface_cmdq_write(device, pkt, session->sid)) - rc = -ENOTEMPTY; -exit: - mutex_unlock(&device->lock); - - return rc; -} - static int venus_hfi_session_load_res(void *sess) { struct hal_session *session = sess; @@ -3058,7 +2641,6 @@ static int __prepare_pc_common(struct venus_hfi_device *device) static int __power_collapse(struct venus_hfi_device *device, bool force) { int rc = 0; - u32 flags = 0; if (!device) { d_vpr_e("%s: invalid params\n", __func__); @@ -3074,12 +2656,6 @@ static int __power_collapse(struct venus_hfi_device *device, bool force) return -EINVAL; } - rc = __dsp_suspend(device, force, flags); - if (rc == -EBUSY) - goto exit; - else if (rc) - goto skip_power_off; - rc = call_venus_op(device, prepare_pc, device); if (rc) goto skip_power_off; @@ -3162,21 +2738,7 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) continue; } - if (pkt->packet_type == HFI_MSG_SYS_COV) { - struct hfi_msg_sys_coverage_packet *pkt = - (struct hfi_msg_sys_coverage_packet *) packet; - int stm_size = 0; - - SKIP_INVALID_PKT(pkt->size, - pkt->msg_size, sizeof(*pkt)); - - stm_size = stm_log_inv_ts(0, 0, - pkt->rg_msg_data, pkt->msg_size); - if (stm_size == 0) - d_vpr_e("In %s, stm_log returned size of 0\n", - __func__); - - } else if (pkt->packet_type == HFI_MSG_SYS_DEBUG) { + if (pkt->packet_type == HFI_MSG_SYS_DEBUG) { struct hfi_msg_sys_debug_packet *pkt = (struct hfi_msg_sys_debug_packet *) packet; @@ -3323,8 +2885,6 @@ static int __response_handler(struct venus_hfi_device *device) case HAL_SESSION_SET_PROP_DONE: case HAL_SESSION_GET_PROP_DONE: case HAL_SESSION_RELEASE_BUFFER_DONE: - case HAL_SESSION_REGISTER_BUFFER_DONE: - case HAL_SESSION_UNREGISTER_BUFFER_DONE: case HAL_SESSION_RELEASE_RESOURCE_DONE: case HAL_SESSION_PROPERTY_INFO: inst_id = &info->response.cmd.inst_id; @@ -3630,7 +3190,6 @@ static int __handle_reset_clk(struct msm_vidc_platform_resources *res, void __disable_unprepare_clks(struct venus_hfi_device *device) { struct clock_info *cl; - int rc = 0; if (!device) { d_vpr_e("%s: invalid params\n", __func__); @@ -3640,16 +3199,6 @@ void __disable_unprepare_clks(struct venus_hfi_device *device) venus_hfi_for_each_clock_reverse(device, cl) { d_vpr_h("Clock: %s disable and unprepare\n", cl->name); - rc = clk_set_flags(cl->clk, CLKFLAG_NORETAIN_PERIPH); - if (rc) { - d_vpr_e("Failed set flag NORETAIN_PERIPH %s\n", - cl->name); - } - rc = clk_set_flags(cl->clk, CLKFLAG_NORETAIN_MEM); - if (rc) { - d_vpr_e("Failed set flag NORETAIN_MEM %s\n", - cl->name); - } if (!__clk_is_enabled(cl->clk)) d_vpr_e("%s: clock %s already disabled\n", @@ -3717,17 +3266,6 @@ static inline int __prepare_enable_clks(struct venus_hfi_device *device, __set_clk_rate(device, cl, clk_round_rate(cl->clk, 0), sid); - rc = clk_set_flags(cl->clk, CLKFLAG_RETAIN_PERIPH); - if (rc) { - s_vpr_e(sid, "Failed set flag RETAIN_PERIPH %s\n", - cl->name); - } - rc = clk_set_flags(cl->clk, CLKFLAG_RETAIN_MEM); - if (rc) { - s_vpr_e(sid, "Failed set flag RETAIN_MEM %s\n", - cl->name); - } - if (__clk_is_enabled(cl->clk)) s_vpr_e(sid, "%s: clock %s already enabled\n", __func__, cl->name); @@ -4438,7 +3976,6 @@ static inline int __suspend(struct venus_hfi_device *device) static inline int __resume(struct venus_hfi_device *device, u32 sid) { int rc = 0; - u32 flags = 0; if (!device) { s_vpr_e(sid, "%s: invalid params\n", __func__); @@ -4483,10 +4020,6 @@ static inline int __resume(struct venus_hfi_device *device, u32 sid) } if (device->res->pm_qos_latency_us) { -#ifdef CONFIG_SMP - device->qos.type = PM_QOS_REQ_AFFINE_IRQ; - device->qos.irq = device->hal_data->irq; -#endif pm_qos_add_request(&device->qos, PM_QOS_CPU_DMA_LATENCY, device->res->pm_qos_latency_us); } @@ -4496,7 +4029,6 @@ static inline int __resume(struct venus_hfi_device *device, u32 sid) __enable_subcaches(device, sid); __set_subcaches(device, sid); - __dsp_resume(device, flags); s_vpr_h(sid, "Resumed from power collapse\n"); exit: @@ -4917,8 +4449,6 @@ static void venus_init_hfi_callbacks(struct hfi_device *hdev) hdev->session_clean = venus_hfi_session_clean; hdev->session_set_buffers = venus_hfi_session_set_buffers; hdev->session_release_buffers = venus_hfi_session_release_buffers; - hdev->session_register_buffer = venus_hfi_session_register_buffer; - hdev->session_unregister_buffer = venus_hfi_session_unregister_buffer; hdev->session_load_res = venus_hfi_session_load_res; hdev->session_release_res = venus_hfi_session_release_res; hdev->session_start = venus_hfi_session_start; diff --git a/msm/vidc/hfi_common.h b/msm/vidc/hfi_common.h index 2ac3802aab1e..5fedbd8a3792 100644 --- a/msm/vidc/hfi_common.h +++ b/msm/vidc/hfi_common.h @@ -7,18 +7,22 @@ #define __HFI_COMMON_H__ #include -#include -#include +#include #include -#include #include +#include +#include +#include +#include +#include #include "vidc_hfi_api.h" #include "vidc_hfi_helper.h" #include "vidc_hfi_api.h" #include "vidc_hfi.h" #include "msm_vidc_resources.h" -#include "hfi_packetization.h" #include "msm_vidc_bus.h" +#include "hfi_packetization.h" +#include "hfi_io_common.h" #define HFI_MASK_QHDR_TX_TYPE 0xFF000000 #define HFI_MASK_QHDR_RX_TYPE 0x00FF0000 @@ -216,11 +220,6 @@ struct venus_resources { struct msm_vidc_fw fw; }; -enum dsp_flag { - DSP_INIT = BIT(0), - DSP_SUSPEND = BIT(1), -}; - enum venus_hfi_state { VENUS_STATE_DEINIT = 1, VENUS_STATE_INIT, diff --git a/msm/vidc/hfi_iris1.c b/msm/vidc/hfi_iris1.c index b08eb68d9358..a8b8bc0aa88c 100644 --- a/msm/vidc/hfi_iris1.c +++ b/msm/vidc/hfi_iris1.c @@ -28,7 +28,7 @@ void __setup_ucregion_memory_map_iris1(struct venus_hfi_device *device, u32 sid) __write_register(device, QTBL_ADDR, (u32)device->iface_q_table.align_device_addr, sid); __write_register(device, QTBL_INFO, 0x01, sid); - if (device->sfr.align_device_addr, sid) + if (device->sfr.align_device_addr) __write_register(device, SFR_ADDR, (u32)device->sfr.align_device_addr, sid); if (device->qdss.align_device_addr) @@ -41,15 +41,6 @@ void __setup_ucregion_memory_map_iris1(struct venus_hfi_device *device, u32 sid) __write_register(device, HFI_DSP_UC_REGION_ADDR, (u32)device->iface_q_table.align_device_addr, sid); __write_register(device, HFI_DSP_UC_REGION_SIZE, SHARED_QSIZE, sid); - if (device->res->cvp_internal) { - /* initialize DSP QTBL & UCREGION with DSP queues */ - __write_register(device, HFI_DSP_QTBL_ADDR, - (u32)device->dsp_iface_q_table.align_device_addr, sid); - __write_register(device, HFI_DSP_UC_REGION_ADDR, - (u32)device->dsp_iface_q_table.align_device_addr, sid); - __write_register(device, HFI_DSP_UC_REGION_SIZE, - device->dsp_iface_q_table.mem_data.size, sid); - } } void __clock_config_on_enable_iris1(struct venus_hfi_device *device, u32 sid) diff --git a/msm/vidc/hfi_iris2.c b/msm/vidc/hfi_iris2.c index e6eb40cd8f17..e64d842d8661 100644 --- a/msm/vidc/hfi_iris2.c +++ b/msm/vidc/hfi_iris2.c @@ -389,8 +389,6 @@ int __boot_firmware_iris2(struct venus_hfi_device *device, u32 sid) u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 1000; ctrl_init_val = BIT(0); - if (device->res->cvp_internal) - ctrl_init_val |= BIT(1); __write_register(device, CTRL_INIT_IRIS2, ctrl_init_val, sid); while (!ctrl_status && count < max_tries) { diff --git a/msm/vidc/hfi_packetization.c b/msm/vidc/hfi_packetization.c index 27cd92c17c70..23a6a83ebce3 100644 --- a/msm/vidc/hfi_packetization.c +++ b/msm/vidc/hfi_packetization.c @@ -19,9 +19,6 @@ u32 vidc_get_hfi_domain(enum hal_domain hal_domain, u32 sid) case HAL_VIDEO_DOMAIN_DECODER: hfi_domain = HFI_VIDEO_DOMAIN_DECODER; break; - case HAL_VIDEO_DOMAIN_CVP: - hfi_domain = HFI_VIDEO_DOMAIN_CVP; - break; default: s_vpr_e(sid, "%s: invalid domain 0x%x\n", __func__, hal_domain); @@ -54,12 +51,6 @@ u32 vidc_get_hfi_codec(enum hal_video_codec hal_codec, u32 sid) case HAL_VIDEO_CODEC_VP9: hfi_codec = HFI_VIDEO_CODEC_VP9; break; - case HAL_VIDEO_CODEC_TME: - hfi_codec = HFI_VIDEO_CODEC_TME; - break; - case HAL_VIDEO_CODEC_CVP: - hfi_codec = HFI_VIDEO_CODEC_CVP; - break; default: s_vpr_h(sid, "%s: invalid codec 0x%x\n", __func__, hal_codec); @@ -465,70 +456,6 @@ int create_pkt_cmd_session_release_buffers( return rc; } -int create_pkt_cmd_session_register_buffer( - struct hfi_cmd_session_register_buffers_packet *pkt, - u32 sid, struct vidc_register_buffer *buffer) -{ - int rc = 0; - u32 i; - struct hfi_buffer_mapping_type *buf; - - if (!pkt) { - d_vpr_e("%s: invalid params %pK\n", __func__, pkt); - return -EINVAL; - } - pkt->packet_type = HFI_CMD_SESSION_REGISTER_BUFFERS; - pkt->sid = sid; - pkt->client_data = buffer->client_data; - pkt->response_req = buffer->response_required; - pkt->num_buffers = 1; - pkt->size = sizeof(struct hfi_cmd_session_register_buffers_packet) - - sizeof(u32) + (pkt->num_buffers * - sizeof(struct hfi_buffer_mapping_type)); - - buf = (struct hfi_buffer_mapping_type *)pkt->buffer; - for (i = 0; i < pkt->num_buffers; i++) { - buf->index = buffer->index; - buf->device_addr = buffer->device_addr; - buf->size = buffer->size; - buf++; - } - - return rc; -} - -int create_pkt_cmd_session_unregister_buffer( - struct hfi_cmd_session_unregister_buffers_packet *pkt, - u32 sid, struct vidc_unregister_buffer *buffer) -{ - int rc = 0; - u32 i; - struct hfi_buffer_mapping_type *buf; - - if (!pkt) { - d_vpr_e("%s: invalid params %pK\n", __func__, pkt); - return -EINVAL; - } - pkt->packet_type = HFI_CMD_SESSION_UNREGISTER_BUFFERS; - pkt->sid = sid; - pkt->client_data = buffer->client_data; - pkt->response_req = buffer->response_required; - pkt->num_buffers = 1; - pkt->size = sizeof(struct hfi_cmd_session_unregister_buffers_packet) - - sizeof(u32) + (pkt->num_buffers * - sizeof(struct hfi_buffer_mapping_type)); - - buf = (struct hfi_buffer_mapping_type *)pkt->buffer; - for (i = 0; i < pkt->num_buffers; i++) { - buf->index = buffer->index; - buf->device_addr = buffer->device_addr; - buf->size = buffer->size; - buf++; - } - - return rc; -} - int create_pkt_cmd_session_etb_decoder( struct hfi_cmd_session_empty_buffer_compressed_packet *pkt, u32 sid, struct vidc_frame_data *input_frame) @@ -774,8 +701,6 @@ static struct hfi_packetization_ops hfi_default = { .session_cmd = create_pkt_cmd_session_cmd, .session_set_buffers = create_pkt_cmd_session_set_buffers, .session_release_buffers = create_pkt_cmd_session_release_buffers, - .session_register_buffer = create_pkt_cmd_session_register_buffer, - .session_unregister_buffer = create_pkt_cmd_session_unregister_buffer, .session_etb_decoder = create_pkt_cmd_session_etb_decoder, .session_etb_encoder = create_pkt_cmd_session_etb_encoder, .session_ftb = create_pkt_cmd_session_ftb, diff --git a/msm/vidc/hfi_packetization.h b/msm/vidc/hfi_packetization.h index 95278637bd0b..5240bb16f259 100644 --- a/msm/vidc/hfi_packetization.h +++ b/msm/vidc/hfi_packetization.h @@ -5,7 +5,6 @@ #ifndef __HFI_PACKETIZATION_H__ #define __HFI_PACKETIZATION_H__ -#include #include "vidc_hfi_helper.h" #include "vidc_hfi.h" #include "vidc_hfi_api.h" @@ -50,12 +49,6 @@ struct hfi_packetization_ops { int (*session_release_buffers)( struct hfi_cmd_session_release_buffer_packet *pkt, u32 sid, struct vidc_buffer_addr_info *buffer_info); - int (*session_register_buffer)( - struct hfi_cmd_session_register_buffers_packet *pkt, - u32 sid, struct vidc_register_buffer *buffer); - int (*session_unregister_buffer)( - struct hfi_cmd_session_unregister_buffers_packet *pkt, - u32 sid, struct vidc_unregister_buffer *buffer); int (*session_etb_decoder)( struct hfi_cmd_session_empty_buffer_compressed_packet *pkt, u32 sid, struct vidc_frame_data *input_frame); diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index c46b15ff9983..92fcd791a1b2 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -4,12 +4,7 @@ */ #include -#include -#include -#include -#include #include -#include #include "vidc_hfi_helper.h" #include "msm_vidc_debug.h" #include "vidc_hfi.h" @@ -1001,60 +996,6 @@ static int hfi_process_session_rel_buf_done(u32 device_id, return 0; } -static int hfi_process_session_register_buffer_done(u32 device_id, - void *_pkt, - struct msm_vidc_cb_info *info) -{ - struct hfi_msg_session_register_buffers_done_packet *pkt = _pkt; - struct msm_vidc_cb_cmd_done cmd_done = {0}; - - if (!pkt || pkt->size < - sizeof(struct hfi_msg_session_register_buffers_done_packet)) { - d_vpr_e("%s: bad packet/packet size %d\n", - __func__, pkt ? pkt->size : 0); - return -E2BIG; - } - s_vpr_h(pkt->sid, "RECEIVED: SESSION_REGISTER_BUFFERS_DONE\n"); - - cmd_done.device_id = device_id; - cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done); - cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; - cmd_done.status = hfi_map_err_status(pkt->error_type); - cmd_done.data.regbuf.client_data = pkt->client_data; - - info->response_type = HAL_SESSION_REGISTER_BUFFER_DONE; - info->response.cmd = cmd_done; - - return 0; -} - -static int hfi_process_session_unregister_buffer_done(u32 device_id, - void *_pkt, - struct msm_vidc_cb_info *info) -{ - struct hfi_msg_session_unregister_buffers_done_packet *pkt = _pkt; - struct msm_vidc_cb_cmd_done cmd_done = {0}; - - if (!pkt || pkt->size < - sizeof(struct hfi_msg_session_unregister_buffers_done_packet)) { - d_vpr_e("%s: bad packet/packet size %d\n", - __func__, pkt ? pkt->size : 0); - return -E2BIG; - } - s_vpr_h(pkt->sid, "RECEIVED: SESSION_UNREGISTER_BUFFERS_DONE\n"); - - cmd_done.device_id = device_id; - cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done); - cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; - cmd_done.status = hfi_map_err_status(pkt->error_type); - cmd_done.data.unregbuf.client_data = pkt->client_data; - - info->response_type = HAL_SESSION_UNREGISTER_BUFFER_DONE; - info->response.cmd = cmd_done; - - return 0; -} - static int hfi_process_session_end_done(u32 device_id, void *_pkt, struct msm_vidc_cb_info *info) @@ -1248,14 +1189,6 @@ int hfi_process_msg_packet(u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr, case HFI_MSG_SESSION_RELEASE_BUFFERS_DONE: pkt_func = (pkt_func_def)hfi_process_session_rel_buf_done; break; - case HFI_MSG_SESSION_REGISTER_BUFFERS_DONE: - pkt_func = (pkt_func_def) - hfi_process_session_register_buffer_done; - break; - case HFI_MSG_SESSION_UNREGISTER_BUFFERS_DONE: - pkt_func = (pkt_func_def) - hfi_process_session_unregister_buffer_done; - break; case HFI_MSG_SYS_SESSION_ABORT_DONE: pkt_func = (pkt_func_def)hfi_process_session_abort_done; break; diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c deleted file mode 100644 index 74b2e8971b65..000000000000 --- a/msm/vidc/msm_cvp_external.c +++ /dev/null @@ -1,1499 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. - */ - -#include -#include "msm_cvp_external.h" -#include "msm_vidc_common.h" - -#define LOWER32(a) ((u32)((u64)a)) -#define UPPER32(a) ((u32)((u64)a >> 32)) - -static void print_cvp_buffer(u32 tag, const char *str, - struct msm_vidc_inst *inst, struct msm_cvp_buf *cbuf) -{ - struct msm_cvp_external *cvp; - - if (!(tag & msm_vidc_debug) || !inst || !inst->cvp || !cbuf) - return; - - cvp = inst->cvp; - dprintk(tag, inst->sid, - "%s: %x : idx %d fd %d size %d offset %d dbuf %pK kvaddr %pK\n", - str, cvp->sid, cbuf->index, cbuf->fd, cbuf->size, - cbuf->offset, cbuf->dbuf, cbuf->kvaddr); -} - -static int fill_cvp_buffer(struct msm_cvp_buffer_type *dst, - struct msm_cvp_buf *src, u32 sid) -{ - if (!dst || !src) { - s_vpr_e(sid, "%s: invalid params %pK %pK\n", - __func__, dst, src); - return -EINVAL; - } - - dst->buffer_addr = -1; - dst->reserved1 = LOWER32(src->dbuf); - dst->reserved2 = UPPER32(src->dbuf); - dst->size = src->size; - - return 0; -} - -static int msm_cvp_get_version_info(struct msm_vidc_inst *inst) -{ - int rc; - struct msm_cvp_external *cvp; - struct cvp_kmd_arg *arg; - struct cvp_kmd_sys_properties *sys_prop; - struct cvp_kmd_sys_property *prop_data; - u32 version; - - if (!inst || !inst->cvp || !inst->cvp->arg) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - arg = cvp->arg; - - memset(arg, 0, sizeof(struct cvp_kmd_arg)); - arg->type = CVP_KMD_GET_SYS_PROPERTY; - sys_prop = (struct cvp_kmd_sys_properties *)&arg->data.sys_properties; - sys_prop->prop_num = CVP_KMD_HFI_VERSION_PROP_NUMBER; - prop_data = (struct cvp_kmd_sys_property *) - &arg->data.sys_properties.prop_data; - prop_data->prop_type = CVP_KMD_HFI_VERSION_PROP_TYPE; - rc = msm_cvp_private(cvp->priv, CVP_KMD_GET_SYS_PROPERTY, arg); - if (rc) { - s_vpr_e(inst->sid, "%s: failed, rc %d\n", __func__, rc); - return rc; - } - version = prop_data->data; - s_vpr_h(inst->sid, "%s: version %#x\n", __func__, version); - - return 0; -} - -static int msm_cvp_set_priority(struct msm_vidc_inst *inst) -{ - int rc; - struct msm_cvp_external *cvp; - struct cvp_kmd_arg *arg; - struct cvp_kmd_sys_properties *props; - struct cvp_kmd_sys_property *prop_array; - - if (!inst || !inst->cvp || !inst->cvp->arg) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - arg = cvp->arg; - props = (struct cvp_kmd_sys_properties *)&arg->data.sys_properties; - prop_array = (struct cvp_kmd_sys_property *) - &arg->data.sys_properties.prop_data; - - memset(arg, 0, sizeof(struct cvp_kmd_arg)); - arg->type = CVP_KMD_SET_SYS_PROPERTY; - props->prop_num = 1; - prop_array[0].prop_type = CVP_KMD_PROP_SESSION_PRIORITY; - if (is_realtime_session(inst)) - prop_array[0].data = VIDEO_REALTIME; - else - prop_array[0].data = VIDEO_NONREALTIME; - s_vpr_h(inst->sid, "%s: %d\n", __func__, prop_array[0].data); - rc = msm_cvp_private(cvp->priv, CVP_KMD_SET_SYS_PROPERTY, arg); - if (rc) { - s_vpr_e(inst->sid, "%s: failed, rc %d\n", __func__, rc); - return rc; - } - - return 0; -} - -static int msm_cvp_set_secure_mode(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp = NULL; - struct cvp_kmd_arg *arg = NULL; - struct cvp_kmd_sys_properties *props = NULL; - struct cvp_kmd_sys_property *prop_array = NULL; - - if (!inst || !inst->cvp || !inst->cvp->arg) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - arg = cvp->arg; - props = (struct cvp_kmd_sys_properties *)&arg->data.sys_properties; - prop_array = (struct cvp_kmd_sys_property *) - &arg->data.sys_properties.prop_data; - - memset(arg, 0, sizeof(struct cvp_kmd_arg)); - arg->type = CVP_KMD_SET_SYS_PROPERTY; - props->prop_num = 1; - prop_array[0].prop_type = CVP_KMD_PROP_SESSION_SECURITY; - prop_array[0].data = is_secure_session(inst); - s_vpr_h(inst->sid, "%s: %d\n", __func__, prop_array[0].data); - - rc = msm_cvp_private(cvp->priv, CVP_KMD_SET_SYS_PROPERTY, arg); - if (rc) { - s_vpr_e(inst->sid, "%s: failed, rc %d\n", __func__, rc); - return rc; - } - return rc; -} - -static int msm_cvp_fill_planeinfo(struct msm_cvp_color_plane_info *plane_info, - u32 color_fmt, u32 width, u32 height, u32 sid) -{ - int rc = 0; - u32 y_stride, y_sclines, uv_stride, uv_sclines; - u32 y_meta_stride, y_meta_scalines; - u32 uv_meta_stride, uv_meta_sclines; - - switch (color_fmt) { - case COLOR_FMT_NV12: - case COLOR_FMT_P010: - case COLOR_FMT_NV12_512: - { - y_stride = VENUS_Y_STRIDE(color_fmt, width); - y_sclines = VENUS_Y_SCANLINES(color_fmt, height); - uv_stride = VENUS_UV_STRIDE(color_fmt, width); - uv_sclines = VENUS_UV_SCANLINES(color_fmt, height); - - plane_info->stride[HFI_COLOR_PLANE_METADATA] = 0; - plane_info->stride[HFI_COLOR_PLANE_PICDATA] = y_stride; - plane_info->stride[HFI_COLOR_PLANE_UV_META] = 0; - plane_info->stride[HFI_COLOR_PLANE_UV] = uv_stride; - plane_info->buf_size[HFI_COLOR_PLANE_METADATA] = 0; - plane_info->buf_size[HFI_COLOR_PLANE_PICDATA] = - y_stride * y_sclines; - plane_info->buf_size[HFI_COLOR_PLANE_UV_META] = 0; - plane_info->buf_size[HFI_COLOR_PLANE_UV] = - uv_stride * uv_sclines; - break; - } - case COLOR_FMT_NV12_UBWC: - case COLOR_FMT_NV12_BPP10_UBWC: - { - y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width); - y_meta_scalines = VENUS_Y_META_SCANLINES(color_fmt, height); - uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width); - uv_meta_sclines = VENUS_UV_META_SCANLINES(color_fmt, height); - - y_stride = VENUS_Y_STRIDE(color_fmt, width); - y_sclines = VENUS_Y_SCANLINES(color_fmt, height); - uv_stride = VENUS_UV_STRIDE(color_fmt, width); - uv_sclines = VENUS_UV_SCANLINES(color_fmt, height); - - plane_info->stride[HFI_COLOR_PLANE_METADATA] = y_meta_stride; - plane_info->stride[HFI_COLOR_PLANE_PICDATA] = y_stride; - plane_info->stride[HFI_COLOR_PLANE_UV_META] = uv_meta_stride; - plane_info->stride[HFI_COLOR_PLANE_UV] = uv_stride; - plane_info->buf_size[HFI_COLOR_PLANE_METADATA] = - MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scalines, 4096); - plane_info->buf_size[HFI_COLOR_PLANE_PICDATA] = - MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096); - plane_info->buf_size[HFI_COLOR_PLANE_UV_META] = - MSM_MEDIA_ALIGN(uv_meta_stride * uv_meta_sclines, 4096); - plane_info->buf_size[HFI_COLOR_PLANE_UV] = - MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096); - break; - } - default: - s_vpr_e(sid, "%s: invalid color_fmt %#x\n", - __func__, color_fmt); - rc = -EINVAL; - break; - } - - return rc; -} - -static u32 msm_cvp_get_secure_flag_for_buffer_type(u32 buf_type) -{ - switch (buf_type) { - case MSM_VIDC_CVP_INPUT_BUF: - return ION_FLAG_SECURE | ION_FLAG_CP_PIXEL; - case MSM_VIDC_CVP_OUTPUT_BUF: - return 0; - default: - return ION_FLAG_SECURE | ION_FLAG_CP_NON_PIXEL; - } -} - -static int msm_cvp_free_buffer(struct msm_vidc_inst *inst, - struct msm_cvp_buf *buffer) -{ - struct msm_cvp_external *cvp; - - if (!inst || !inst->cvp || !buffer) { - d_vpr_e("%s: invalid params %pK %pK\n", - __func__, inst, buffer); - return -EINVAL; - } - cvp = inst->cvp; - - if (buffer->kvaddr) { - dma_buf_vunmap(buffer->dbuf, buffer->kvaddr); - buffer->kvaddr = NULL; - } - if (buffer->dbuf) { - dma_buf_put(buffer->dbuf); - buffer->dbuf = NULL; - } - return 0; -} - -static int msm_cvp_allocate_buffer(struct msm_vidc_inst *inst, - struct msm_cvp_buf *buffer, bool kernel_map) -{ - int rc = 0; - struct msm_cvp_external *cvp; - int ion_flags = 0; - unsigned long heap_mask = 0; - struct dma_buf *dbuf; - - if (!inst || !inst->cvp || !buffer) { - d_vpr_e("%s: invalid params %pK %pK\n", - __func__, inst, buffer); - return -EINVAL; - } - cvp = inst->cvp; - - heap_mask = ION_HEAP(ION_SYSTEM_HEAP_ID); - if (inst->flags & VIDC_SECURE) { - ion_flags = msm_cvp_get_secure_flag_for_buffer_type( - buffer->buf_type); - if (ion_flags & ION_FLAG_SECURE) { - heap_mask = ION_HEAP(ION_SECURE_HEAP_ID); - kernel_map = false; - } - } - - dbuf = ion_alloc(buffer->size, heap_mask, ion_flags); - if (IS_ERR_OR_NULL(dbuf)) { - s_vpr_e(inst->sid, - "%s: failed to allocate, size %d heap_mask %#lx flags %d\n", - __func__, buffer->size, heap_mask, ion_flags); - rc = -ENOMEM; - goto error; - } - buffer->dbuf = dbuf; - buffer->fd = -1; - - if (kernel_map) { - buffer->kvaddr = dma_buf_vmap(dbuf); - if (!buffer->kvaddr) { - s_vpr_e(inst->sid, - "%s: dma_buf_vmap failed\n", __func__); - rc = -EINVAL; - goto error; - } - } else { - buffer->kvaddr = NULL; - } - buffer->index = cvp->buffer_idx++; - buffer->offset = 0; - - return 0; -error: - msm_cvp_free_buffer(inst, buffer); - return rc; -} - -static int msm_cvp_set_clocks_and_bus(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp; - struct cvp_kmd_arg *arg; - struct v4l2_format *fmt; - struct cvp_kmd_usecase_desc desc; - struct cvp_kmd_request_power power; - const u32 fps_max = CVP_FRAME_RATE_MAX; - - if (!inst || !inst->cvp || !inst->cvp->arg) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - arg = cvp->arg; - memset(&desc, 0, sizeof(struct cvp_kmd_usecase_desc)); - memset(&power, 0, sizeof(struct cvp_kmd_request_power)); - - fmt = &inst->fmts[INPUT_PORT].v4l2_fmt; - desc.fullres_width = cvp->width; - desc.fullres_height = cvp->height; - desc.downscale_width = cvp->ds_width; - desc.downscale_height = cvp->ds_height; - desc.is_downscale = cvp->downscale; - desc.fps = min(cvp->frame_rate >> 16, fps_max); - desc.op_rate = cvp->operating_rate >> 16; - desc.colorfmt = - msm_comm_convert_color_fmt(fmt->fmt.pix_mp.pixelformat, - inst->sid); - rc = msm_cvp_est_cycles(&desc, &power); - if (rc) { - s_vpr_e(inst->sid, "%s: estimate failed\n", __func__); - return rc; - } - s_vpr_h(inst->sid, "%s: core %d controller %d ddr bw %d\n", - __func__, power.clock_cycles_a, power.clock_cycles_b, - power.ddr_bw); - - memset(arg, 0, sizeof(struct cvp_kmd_arg)); - arg->type = CVP_KMD_REQUEST_POWER; - memcpy(&arg->data.req_power, &power, - sizeof(struct cvp_kmd_request_power)); - rc = msm_cvp_private(cvp->priv, CVP_KMD_REQUEST_POWER, arg); - if (rc) { - s_vpr_e(inst->sid, "%s: request_power failed with %d\n", - __func__, rc); - return rc; - } - - return rc; -} - -static int msm_cvp_init_downscale_resolution(struct msm_vidc_inst *inst) -{ - struct msm_cvp_external *cvp; - const u32 width_max = 1920; - u32 width, height, ds_width, ds_height, temp; - - if (!inst || !inst->cvp) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - - ds_width = cvp->width; - ds_height = cvp->height; - - if (!cvp->downscale) { - s_vpr_h(inst->sid, "%s: downscaling not enabled\n", __func__); - goto exit; - } - - /* Step 1) make width always the larger number */ - if (cvp->height > cvp->width) { - width = cvp->height; - height = cvp->width; - } else { - width = cvp->width; - height = cvp->height; - } - /* - * Step 2) Downscale width by 4 and round - * make sure width stays between 480 and 1920 - */ - ds_width = (width + 2) >> 2; - if (ds_width < 480) - ds_width = 480; - if (ds_width > width_max) - ds_width = width_max; - ds_height = (height * ds_width) / width; - if (ds_height < 128) - ds_height = 128; - - /* Step 3) do not downscale if width is less than 480 */ - if (width <= 480) - ds_width = width; - if (ds_width == width) - ds_height = height; - - /* Step 4) switch width and height if already switched */ - if (cvp->height > cvp->width) { - temp = ds_height; - ds_height = ds_width; - ds_width = temp; - } - -exit: - cvp->ds_width = ds_width; - cvp->ds_height = ds_height; - return 0; -} - -static void msm_cvp_deinit_downscale_buffers(struct msm_vidc_inst *inst) -{ - struct msm_cvp_external *cvp; - - if (!inst || !inst->cvp) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return; - } - cvp = inst->cvp; - s_vpr_h(inst->sid, "%s:\n", __func__); - - if (cvp->src_buffer.dbuf) { - print_cvp_buffer(VIDC_HIGH, "free: src_buffer", - inst, &cvp->src_buffer); - if (msm_cvp_free_buffer(inst, &cvp->src_buffer)) - print_cvp_buffer(VIDC_ERR, - "free failed: src_buffer", - inst, &cvp->src_buffer); - } - if (cvp->ref_buffer.dbuf) { - print_cvp_buffer(VIDC_HIGH, "free: ref_buffer", - inst, &cvp->ref_buffer); - if (msm_cvp_free_buffer(inst, &cvp->ref_buffer)) - print_cvp_buffer(VIDC_ERR, - "free failed: ref_buffer", - inst, &cvp->ref_buffer); - } -} - -static int msm_cvp_init_downscale_buffers(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp; - - if (!inst || !inst->cvp) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - - if (!cvp->downscale) { - s_vpr_h(inst->sid, "%s: downscaling not enabled\n", __func__); - return 0; - } - s_vpr_h(inst->sid, "%s:\n", __func__); - - cvp->src_buffer.size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, - cvp->ds_width, cvp->ds_height); - cvp->src_buffer.buf_type = MSM_VIDC_CVP_INPUT_BUF; - rc = msm_cvp_allocate_buffer(inst, &cvp->src_buffer, false); - if (rc) { - print_cvp_buffer(VIDC_ERR, - "allocate failed: src_buffer", - inst, &cvp->src_buffer); - goto error; - } - print_cvp_buffer(VIDC_HIGH, "alloc: src_buffer", - inst, &cvp->src_buffer); - - cvp->ref_buffer.size = cvp->src_buffer.size; - cvp->ref_buffer.buf_type = MSM_VIDC_CVP_INPUT_BUF; - rc = msm_cvp_allocate_buffer(inst, &cvp->ref_buffer, false); - if (rc) { - print_cvp_buffer(VIDC_ERR, - "allocate failed: ref_buffer", - inst, &cvp->ref_buffer); - goto error; - } - print_cvp_buffer(VIDC_HIGH, "alloc: ref_buffer", - inst, &cvp->ref_buffer); - - return rc; - -error: - msm_cvp_deinit_downscale_buffers(inst); - return rc; -} - -static void msm_cvp_deinit_context_buffers(struct msm_vidc_inst *inst) -{ - struct msm_cvp_external *cvp; - - if (!inst || !inst->cvp) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return; - } - cvp = inst->cvp; - s_vpr_h(inst->sid, "%s:\n", __func__); - - if (cvp->context_buffer.dbuf) { - print_cvp_buffer(VIDC_HIGH, "free: context_buffer", - inst, &cvp->context_buffer); - if (msm_cvp_free_buffer(inst, &cvp->context_buffer)) - print_cvp_buffer(VIDC_ERR, - "free failed: context_buffer", - inst, &cvp->context_buffer); - } - if (cvp->refcontext_buffer.dbuf) { - print_cvp_buffer(VIDC_HIGH, "free: refcontext_buffer", - inst, &cvp->refcontext_buffer); - if (msm_cvp_free_buffer(inst, &cvp->refcontext_buffer)) - print_cvp_buffer(VIDC_ERR, - "free failed: refcontext_buffer", - inst, &cvp->refcontext_buffer); - } -} - -static int msm_cvp_init_context_buffers(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp; - - if (!inst || !inst->cvp) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - s_vpr_h(inst->sid, "%s:\n", __func__); - - cvp->context_buffer.size = HFI_DME_FRAME_CONTEXT_BUFFER_SIZE; - cvp->context_buffer.buf_type = MSM_VIDC_CVP_CONTEXT_BUF; - rc = msm_cvp_allocate_buffer(inst, &cvp->context_buffer, false); - if (rc) { - print_cvp_buffer(VIDC_ERR, - "allocate failed: context_buffer", - inst, &cvp->context_buffer); - goto error; - } - print_cvp_buffer(VIDC_HIGH, "alloc: context_buffer", - inst, &cvp->context_buffer); - - cvp->refcontext_buffer.size = cvp->context_buffer.size; - cvp->refcontext_buffer.buf_type = MSM_VIDC_CVP_CONTEXT_BUF; - rc = msm_cvp_allocate_buffer(inst, &cvp->refcontext_buffer, false); - if (rc) { - print_cvp_buffer(VIDC_ERR, - "allocate failed: refcontext_buffer", - inst, &cvp->refcontext_buffer); - goto error; - } - print_cvp_buffer(VIDC_HIGH, "alloc: refcontext_buffer", - inst, &cvp->refcontext_buffer); - - return rc; - -error: - msm_cvp_deinit_context_buffers(inst); - return rc; -} - -static void msm_cvp_deinit_internal_buffers(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp; - - if (!inst || !inst->cvp) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return; - } - - cvp = inst->cvp; - s_vpr_h(inst->sid, "%s:\n", __func__); - - if (cvp->output_buffer.dbuf) { - print_cvp_buffer(VIDC_HIGH, "free: output_buffer", - inst, &cvp->output_buffer); - rc = msm_cvp_free_buffer(inst, &cvp->output_buffer); - if (rc) - print_cvp_buffer(VIDC_ERR, - "unregister failed: output_buffer", - inst, &cvp->output_buffer); - } - - if (cvp->persist2_buffer.dbuf) { - print_cvp_buffer(VIDC_HIGH, "free: persist2_buffer", - inst, &cvp->persist2_buffer); - rc = msm_cvp_free_buffer(inst, &cvp->persist2_buffer); - if (rc) - print_cvp_buffer(VIDC_ERR, - "free failed: persist2_buffer", - inst, &cvp->persist2_buffer); - } -} - -static int msm_cvp_set_persist_buffer(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp; - struct cvp_kmd_arg *arg; - struct msm_cvp_session_set_persist_buffers_packet persist2_packet = {0}; - - if (!inst || !inst->cvp || !inst->cvp->arg) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - arg = cvp->arg; - - persist2_packet.size = - sizeof(struct msm_cvp_session_set_persist_buffers_packet); - persist2_packet.packet_type = HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS; - persist2_packet.sid = cvp->sid; - persist2_packet.cvp_op = CVP_DME; - fill_cvp_buffer(&persist2_packet.persist2_buffer, - &cvp->persist2_buffer, inst->sid); - - memset(arg, 0, sizeof(struct cvp_kmd_arg)); - arg->type = CVP_KMD_HFI_PERSIST_CMD; - arg->buf_offset = offsetof( - struct msm_cvp_session_set_persist_buffers_packet, - persist1_buffer) / sizeof(u32); - arg->buf_num = (sizeof( - struct msm_cvp_session_set_persist_buffers_packet) - - (arg->buf_offset * sizeof(u32))) / - sizeof(struct msm_cvp_buffer_type); - memcpy(&(arg->data.pbuf_cmd), &persist2_packet, - sizeof(struct msm_cvp_session_set_persist_buffers_packet)); - rc = msm_cvp_private(cvp->priv, CVP_KMD_HFI_PERSIST_CMD, arg); - if (rc) { - print_cvp_buffer(VIDC_ERR, - "set failed: persist2_buffer", - inst, &cvp->persist2_buffer); - } - - return rc; -} - -static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp; - - if (!inst || !inst->cvp) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - - cvp->persist2_buffer.size = HFI_DME_INTERNAL_PERSIST_2_BUFFER_SIZE; - cvp->persist2_buffer.buf_type = MSM_VIDC_CVP_PERSIST_BUF; - rc = msm_cvp_allocate_buffer(inst, &cvp->persist2_buffer, false); - if (rc) { - print_cvp_buffer(VIDC_ERR, - "allocate failed: persist2_buffer", - inst, &cvp->persist2_buffer); - goto error; - } - print_cvp_buffer(VIDC_HIGH, "alloc: persist2_buffer", - inst, &cvp->persist2_buffer); - - /* allocate one output buffer for internal use */ - cvp->output_buffer.size = HFI_DME_OUTPUT_BUFFER_SIZE; - cvp->output_buffer.buf_type = MSM_VIDC_CVP_OUTPUT_BUF; - rc = msm_cvp_allocate_buffer(inst, &cvp->output_buffer, true); - if (rc) { - print_cvp_buffer(VIDC_ERR, - "allocate failed: output_buffer", - inst, &cvp->output_buffer); - goto error; - } - print_cvp_buffer(VIDC_HIGH, "alloc: output_buffer", - inst, &cvp->output_buffer); - - return rc; - -error: - msm_cvp_deinit_internal_buffers(inst); - return rc; -} - -static int msm_cvp_prepare_extradata(struct msm_vidc_inst *inst, - struct msm_vidc_buffer *mbuf) -{ - int rc = 0; - struct msm_cvp_external *cvp; - struct vb2_buffer *vb; - struct dma_buf *dbuf; - char *kvaddr = NULL; - struct msm_vidc_extradata_header *e_hdr; - bool input_extradata, found_end; - char *cvpframe = NULL; - u32 cvp_metadata_valid_flag = 0; - int nIsValid_offset = 232; - - if (!inst || !inst->cvp || !mbuf) { - d_vpr_e("%s: invalid params %pK %pK\n", - __func__, inst, mbuf); - return -EINVAL; - } - cvp = inst->cvp; - - vb = &mbuf->vvb.vb2_buf; - if (vb->num_planes <= 1) { - s_vpr_e(inst->sid, "%s: extradata plane not enabled\n", - __func__); - return -EINVAL; - } - - dbuf = dma_buf_get(vb->planes[1].m.fd); - if (!dbuf) { - s_vpr_e(inst->sid, "%s: dma_buf_get(%d) failed\n", - __func__, vb->planes[1].m.fd); - return -EINVAL; - } - if (dbuf->size < vb->planes[1].length) { - s_vpr_e(inst->sid, "%s: invalid size %d vs %d\n", __func__, - dbuf->size, vb->planes[1].length); - rc = -EINVAL; - goto error; - } - rc = dma_buf_begin_cpu_access(dbuf, DMA_BIDIRECTIONAL); - if (rc) { - s_vpr_e(inst->sid, "%s: begin_cpu_access failed\n", __func__); - goto error; - } - kvaddr = dma_buf_vmap(dbuf); - if (!kvaddr) { - s_vpr_e(inst->sid, "%s: dma_buf_vmap(%d) failed\n", - __func__, vb->planes[1].m.fd); - rc = -EINVAL; - goto error; - } - e_hdr = (struct msm_vidc_extradata_header *)((char *)kvaddr + - vb->planes[1].data_offset); - - input_extradata = - !!((inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_ROI) || - (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_HDR10PLUS)); - found_end = false; - while ((char *)e_hdr < (char *)(kvaddr + dbuf->size)) { - if (!input_extradata) { - found_end = true; - break; - } - if (e_hdr->type == MSM_VIDC_EXTRADATA_NONE) { - found_end = true; - break; - } - e_hdr = (struct msm_vidc_extradata_header *) - ((char *)e_hdr + e_hdr->size); - } - if (!found_end) { - s_vpr_e(inst->sid, "%s: extradata_none not found\n", __func__); - e_hdr = (struct msm_vidc_extradata_header *)((char *)kvaddr + - vb->planes[1].data_offset); - } - /* check if sufficient space available */ - if (((char *)e_hdr + sizeof(struct msm_vidc_extradata_header) + - sizeof(struct msm_vidc_enc_cvp_metadata_payload) + - sizeof(struct msm_vidc_extradata_header)) > - (kvaddr + dbuf->size)) { - s_vpr_e(inst->sid, - "%s: couldn't append extradata, (e_hdr[%pK] - kvaddr[%pK]) %#x, size %d\n", - __func__, e_hdr, kvaddr, (char *)e_hdr - (char *)kvaddr, - dbuf->size); - goto error; - } - if (cvp->metadata_available) { - cvp->metadata_available = false; - - /* copy payload */ - e_hdr->version = 0x00000001; - e_hdr->port_index = 1; - e_hdr->type = MSM_VIDC_EXTRADATA_CVP_METADATA; - e_hdr->data_size = - sizeof(struct msm_vidc_enc_cvp_metadata_payload); - e_hdr->size = sizeof(struct msm_vidc_extradata_header) + - e_hdr->data_size; - dma_buf_begin_cpu_access(cvp->output_buffer.dbuf, - DMA_BIDIRECTIONAL); - memcpy(e_hdr->data, cvp->output_buffer.kvaddr, - sizeof(struct msm_vidc_enc_cvp_metadata_payload)); - cvpframe = (char *) e_hdr->data; - cvp_metadata_valid_flag = *(u32*)(cvpframe + nIsValid_offset); - s_vpr_h(inst->sid, "CVP metadata nIsValid flag = %u frame: %u", - cvp_metadata_valid_flag, cvp->framecount); - dma_buf_end_cpu_access(cvp->output_buffer.dbuf, - DMA_BIDIRECTIONAL); - } - /* fill extradata none */ - e_hdr = (struct msm_vidc_extradata_header *) - ((char *)e_hdr + e_hdr->size); - e_hdr->version = 0x00000001; - e_hdr->port_index = 1; - e_hdr->type = MSM_VIDC_EXTRADATA_NONE; - e_hdr->data_size = 0; - e_hdr->size = sizeof(struct msm_vidc_extradata_header) + - e_hdr->data_size; - - dma_buf_vunmap(dbuf, kvaddr); - dma_buf_end_cpu_access(dbuf, DMA_BIDIRECTIONAL); - dma_buf_put(dbuf); - - return rc; - -error: - if (kvaddr) { - dma_buf_vunmap(dbuf, kvaddr); - dma_buf_end_cpu_access(dbuf, DMA_BIDIRECTIONAL); - } - if (dbuf) - dma_buf_put(dbuf); - - return rc; -} - -static int msm_cvp_reference_management(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp; - struct msm_cvp_buf temp; - - if (!inst || !inst->cvp) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - - /* swap context buffers */ - memcpy(&temp, &cvp->refcontext_buffer, sizeof(struct msm_cvp_buf)); - memcpy(&cvp->refcontext_buffer, &cvp->context_buffer, - sizeof(struct msm_cvp_buf)); - memcpy(&cvp->context_buffer, &temp, sizeof(struct msm_cvp_buf)); - - /* swap downscale buffers */ - if (cvp->downscale) { - memcpy(&temp, &cvp->ref_buffer, sizeof(struct msm_cvp_buf)); - memcpy(&cvp->ref_buffer, &cvp->src_buffer, - sizeof(struct msm_cvp_buf)); - memcpy(&cvp->src_buffer, &temp, sizeof(struct msm_cvp_buf)); - } - - return rc; -} - -static int msm_cvp_session_start(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp = NULL; - struct cvp_kmd_session_control *ctrl = NULL; - struct cvp_kmd_arg *arg = NULL; - - if (!inst || !inst->cvp || !inst->cvp->arg) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - arg = cvp->arg; - - memset(arg, 0, sizeof(struct cvp_kmd_arg)); - arg->type = CVP_KMD_SESSION_CONTROL; - ctrl = (struct cvp_kmd_session_control *)&arg->data.session_ctrl; - ctrl->ctrl_type = SESSION_START; - - rc = msm_cvp_private(cvp->priv, CVP_KMD_SESSION_CONTROL, arg); - if (rc) { - s_vpr_e(inst->sid, - "%s: CVP_KMD_SESSION_CONTROL failed, rc %d\n", - __func__, rc); - return rc; - } - - return rc; -} - -static int msm_cvp_session_stop(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp = NULL; - struct cvp_kmd_session_control *ctrl = NULL; - struct cvp_kmd_arg *arg = NULL; - - if (!inst || !inst->cvp || !inst->cvp->arg) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - - cvp = inst->cvp; - arg = cvp->arg; - - memset(arg, 0, sizeof(struct cvp_kmd_arg)); - - arg->type = CVP_KMD_SESSION_CONTROL; - - ctrl = (struct cvp_kmd_session_control *)&arg->data.session_ctrl; - ctrl->ctrl_type = SESSION_STOP; - - rc = msm_cvp_private(cvp->priv, CVP_KMD_SESSION_CONTROL, arg); - if (rc) { - s_vpr_e(inst->sid, - "%s: CVP_KMD_SESSION_CONTROL failed, rc %d\n", - __func__, rc); - return rc; - } - - return rc; -} - -static int msm_cvp_frame_process(struct msm_vidc_inst *inst, - struct msm_vidc_buffer *mbuf) -{ - int rc = 0; - struct msm_cvp_external *cvp; - struct vb2_buffer *vb; - struct cvp_kmd_arg *arg; - struct msm_cvp_dme_frame_packet *frame; - const u32 fps_max = CVP_FRAME_RATE_MAX; - u32 fps, operating_rate, skip_framecount, capture_rate, cvp_rate; - bool skipframe = false; - bool first_frame = false; - bool fps_data_changed = false; - - if (!inst || !inst->cvp || !inst->cvp->arg || !mbuf) { - d_vpr_e("%s: invalid params %pK %pK\n", - __func__, inst, mbuf); - return -EINVAL; - } - cvp = inst->cvp; - arg = cvp->arg; - - vb = &mbuf->vvb.vb2_buf; - cvp->fullres_buffer.index = vb->index; - cvp->fullres_buffer.fd = vb->planes[0].m.fd; - cvp->fullres_buffer.size = vb->planes[0].length; - cvp->fullres_buffer.offset = vb->planes[0].data_offset; - cvp->fullres_buffer.dbuf = mbuf->smem[0].dma_buf; - - if(!cvp->framecount) - first_frame = true; - - /* handle framerate or operarating rate changes dynamically */ - if (cvp->frame_rate != inst->clk_data.frame_rate || - cvp->operating_rate != inst->clk_data.operating_rate) { - /* update cvp parameters */ - cvp->framecount = 0; - fps_data_changed = true; - cvp->frame_rate = inst->clk_data.frame_rate; - cvp->operating_rate = inst->clk_data.operating_rate; - rc = msm_cvp_set_clocks_and_bus(inst); - if (rc) { - s_vpr_e(inst->sid, - "%s: unsupported dynamic changes %#x %#x\n", - __func__, cvp->frame_rate, cvp->operating_rate); - goto error; - } - } - - /* - * Special handling for operating rate INT_MAX, - * client's intention is not to skip cvp preprocess - * based on operating rate, skip logic can still be - * executed based on framerate though. - */ - if (cvp->operating_rate == INT_MAX) - operating_rate = fps_max << 16; - else - operating_rate = cvp->operating_rate; - - mbuf->vvb.flags &= ~V4L2_BUF_FLAG_CVPMETADATA_SKIP; - /* frame skip logic */ - fps = max(cvp->frame_rate, operating_rate) >> 16; - if (fps > fps_max) { - /* - * fps <= 120: 0, 2, 4, 6 .. are not skipped - * fps <= 180: 0, 3, 6, 9 .. are not skipped - * fps <= 240: 0, 4, 8, 12 .. are not skipped - * fps <= 960: 0, 16, 32, 48 .. are not skipped - */ - fps = roundup(fps, fps_max); - cvp_rate = fps_max << 16; - skip_framecount = fps / fps_max; - skipframe = cvp->framecount % skip_framecount; - } else - cvp_rate = fps << 16; - - if (skipframe) { - print_cvp_buffer(VIDC_LOW, "input frame with skipflag", - inst, &cvp->fullres_buffer); - cvp->framecount++; - cvp->metadata_available = false; - mbuf->vvb.flags |= V4L2_BUF_FLAG_CVPMETADATA_SKIP; - return 0; - } - capture_rate = fps << 16; - if (fps_data_changed) { - rc = msm_comm_set_cvp_skip_ratio(inst, capture_rate, cvp_rate); - if (rc) { - s_vpr_e(inst->sid,"Setting CVP skip ratio failed"); - goto error; - } - } - - memset(arg, 0, sizeof(struct cvp_kmd_arg)); - arg->type = CVP_KMD_SEND_CMD_PKT; - arg->buf_offset = offsetof(struct msm_cvp_dme_frame_packet, - fullres_srcbuffer) / sizeof(u32); - arg->buf_num = (sizeof(struct msm_cvp_dme_frame_packet) - - (arg->buf_offset * sizeof(u32))) / - sizeof(struct msm_cvp_buffer_type); - frame = (struct msm_cvp_dme_frame_packet *)&arg->data.hfi_pkt.pkt_data; - frame->size = sizeof(struct msm_cvp_dme_frame_packet); - frame->packet_type = HFI_CMD_SESSION_CVP_DME_FRAME; - frame->sid = cvp->sid; - if (first_frame) - frame->skip_mv_calc = 1; - else - frame->skip_mv_calc = 0; - frame->min_fpx_threshold = 2; - frame->enable_descriptor_lpf = 1; - frame->enable_ncc_subpel = 1; - frame->descmatch_threshold = 52; - frame->ncc_robustness_threshold = 0; - - fill_cvp_buffer(&frame->fullres_srcbuffer, - &cvp->fullres_buffer, inst->sid); - fill_cvp_buffer(&frame->videospatialtemporal_statsbuffer, - &cvp->output_buffer, inst->sid); - fill_cvp_buffer(&frame->src_buffer, &cvp->fullres_buffer, inst->sid); - if (cvp->downscale) { - fill_cvp_buffer(&frame->src_buffer, &cvp->src_buffer, - inst->sid); - fill_cvp_buffer(&frame->ref_buffer, &cvp->ref_buffer, - inst->sid); - } - fill_cvp_buffer(&frame->srcframe_contextbuffer, - &cvp->context_buffer, inst->sid); - fill_cvp_buffer(&frame->refframe_contextbuffer, - &cvp->refcontext_buffer, inst->sid); - - print_cvp_buffer(VIDC_LOW, "input frame", inst, &cvp->fullres_buffer); - rc = msm_cvp_private(cvp->priv, CVP_KMD_SEND_CMD_PKT, arg); - if (rc) { - print_cvp_buffer(VIDC_ERR, "send failed: input frame", - inst, &cvp->fullres_buffer); - goto error; - } - /* wait for frame done */ - arg->type = CVP_KMD_RECEIVE_MSG_PKT; - rc = msm_cvp_private(cvp->priv, CVP_KMD_RECEIVE_MSG_PKT, arg); - if (rc) { - print_cvp_buffer(VIDC_ERR, "wait failed: input frame", - inst, &cvp->fullres_buffer); - goto error; - } - cvp->framecount++; - cvp->metadata_available = true; - -error: - return rc; -} - -int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst, - struct msm_vidc_buffer *mbuf) -{ - int rc = 0; - struct msm_cvp_external *cvp; - - if (!inst || !inst->cvp || !mbuf) { - d_vpr_e("%s: invalid params %pK %pK\n", - __func__, inst, mbuf); - return -EINVAL; - } - if (inst->state != MSM_VIDC_START_DONE) { - s_vpr_e(inst->sid, "%s: invalid inst state %d\n", - __func__, inst->state); - return -EINVAL; - } - cvp = inst->cvp; - - rc = msm_cvp_frame_process(inst, mbuf); - if (rc) { - s_vpr_e(inst->sid, "%s: cvp process failed\n", __func__); - return rc; - } - - rc = msm_cvp_prepare_extradata(inst, mbuf); - if (rc) { - s_vpr_e(inst->sid, "%s: prepare extradata failed\n", __func__); - return rc; - } - - rc = msm_cvp_reference_management(inst); - if (rc) { - s_vpr_e(inst->sid, "%s: ref management failed\n", __func__); - return rc; - } - - return rc; -} - -static int msm_cvp_session_delete(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp = NULL; - struct cvp_kmd_session_control *ctrl = NULL; - struct cvp_kmd_arg *arg = NULL; - - if (!inst || !inst->cvp || !inst->cvp->arg) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - arg = cvp->arg; - - memset(arg, 0, sizeof(struct cvp_kmd_arg)); - arg->type = CVP_KMD_SESSION_CONTROL; - ctrl = (struct cvp_kmd_session_control *)&arg->data.session_ctrl; - ctrl->ctrl_type = SESSION_DELETE; - - rc = msm_cvp_private(cvp->priv, CVP_KMD_SESSION_CONTROL, arg); - if (rc) { - s_vpr_e(inst->sid, - "%s: CVP_KMD_SESSION_CONTROL failed, rc %d\n", - __func__, rc); - return rc; - } - - return rc; -} - -static int msm_cvp_mem_deinit(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp; - - if (!inst || !inst->cvp) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - - s_vpr_h(inst->sid, "%s: cvp session %#x\n", __func__, cvp->sid); - msm_cvp_deinit_internal_buffers(inst); - msm_cvp_deinit_context_buffers(inst); - msm_cvp_deinit_downscale_buffers(inst); - - cvp->priv = NULL; - kfree(cvp->arg); - cvp->arg = NULL; - kfree(inst->cvp); - inst->cvp = NULL; - - return rc; -} - -static int msm_cvp_deinit(struct msm_vidc_inst *inst) -{ - int rc = 0; - - if (!inst || !inst->cvp) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - - rc = msm_cvp_session_stop(inst); - if (rc) { - s_vpr_e(inst->sid, "%s: cvp stop failed with error %d\n", - __func__, rc); - } - - msm_cvp_session_delete(inst); - - return rc; -} - -static int msm_cvp_session_close(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp; - - if (!inst || !inst->cvp) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - - s_vpr_h(inst->sid, "%s: cvp session %#x\n", __func__, cvp->sid); - rc = msm_cvp_close(cvp->priv); - if (rc) { - s_vpr_e(inst->sid, "%s: cvp close failed with error %d\n", - __func__, rc); - } - - return rc; -} - -int msm_vidc_cvp_unprepare_preprocess(struct msm_vidc_inst *inst) -{ - if (!inst) { - d_vpr_e("%s: invalid params\n", __func__); - return -EINVAL; - } - if (!inst->cvp) { - s_vpr_h(inst->sid, "%s: cvp not enabled or closed\n", __func__); - return 0; - } - - msm_cvp_deinit(inst); - msm_cvp_session_close(inst); - msm_cvp_mem_deinit(inst); - - return 0; -} - -static int msm_cvp_session_create(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp = NULL; - struct cvp_kmd_session_control *ctrl = NULL; - struct cvp_kmd_arg *arg = NULL; - - if (!inst || !inst->cvp || !inst->cvp->arg) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - arg = cvp->arg; - - memset(arg, 0, sizeof(struct cvp_kmd_arg)); - arg->type = CVP_KMD_SESSION_CONTROL; - ctrl = (struct cvp_kmd_session_control *)&arg->data.session_ctrl; - ctrl->ctrl_type = SESSION_CREATE; - - rc = msm_cvp_private(cvp->priv, CVP_KMD_SESSION_CONTROL, arg); - if (rc) { - s_vpr_e(inst->sid, - "%s: CVP_KMD_SESSION_CONTROL failed, rc %d\n", - __func__, rc); - return rc; - } - - return rc; -} - -static int msm_cvp_get_sessioninfo(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp; - struct cvp_kmd_arg *arg; - - if (!inst || !inst->cvp || !inst->cvp->arg) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - arg = cvp->arg; - - memset(arg, 0, sizeof(struct cvp_kmd_arg)); - arg->type = CVP_KMD_GET_SESSION_INFO; - rc = msm_cvp_private(cvp->priv, CVP_KMD_GET_SESSION_INFO, arg); - if (rc) { - s_vpr_e(inst->sid, "%s: get_session_info failed\n", __func__); - goto error; - } - cvp->sid = arg->data.session.session_id; - s_vpr_h(inst->sid, "%s: cvp session id %#x\n", - __func__, cvp->sid); - - rc = msm_cvp_get_version_info(inst); - if (rc) { - s_vpr_e(inst->sid, "%s: get_version_info failed\n", __func__); - goto error; - } - return rc; - -error: - msm_cvp_deinit(inst); - return rc; -} - -static int msm_cvp_dme_basic_config(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp; - struct cvp_kmd_arg *arg; - struct msm_cvp_dme_basic_config_packet *dmecfg; - struct v4l2_format *fmt; - u32 color_fmt; - - if (!inst || !inst->cvp || !inst->cvp->arg) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - arg = cvp->arg; - - memset(arg, 0, sizeof(struct cvp_kmd_arg)); - arg->type = CVP_KMD_SEND_CMD_PKT; - dmecfg = (struct msm_cvp_dme_basic_config_packet *) - &arg->data.hfi_pkt.pkt_data; - dmecfg->size = sizeof(struct msm_cvp_dme_basic_config_packet); - dmecfg->packet_type = HFI_CMD_SESSION_CVP_DME_BASIC_CONFIG; - dmecfg->sid = cvp->sid; - /* source buffer format should be NV12_UBWC always */ - dmecfg->srcbuffer_format = HFI_COLOR_FORMAT_NV12_UBWC; - dmecfg->src_width = cvp->ds_width; - dmecfg->src_height = cvp->ds_height; - rc = msm_cvp_fill_planeinfo(&dmecfg->srcbuffer_planeinfo, - COLOR_FMT_NV12_UBWC, dmecfg->src_width, - dmecfg->src_height, inst->sid); - if (rc) - goto error; - - fmt = &inst->fmts[INPUT_PORT].v4l2_fmt; - color_fmt = - msm_comm_convert_color_fmt(fmt->fmt.pix_mp.pixelformat, - inst->sid); - dmecfg->fullresbuffer_format = msm_comm_get_hfi_uncompressed( - fmt->fmt.pix_mp.pixelformat, inst->sid); - dmecfg->fullres_width = cvp->width; - dmecfg->fullres_height = cvp->height; - rc = msm_cvp_fill_planeinfo(&dmecfg->fullresbuffer_planeinfo, - color_fmt, dmecfg->fullres_width, - dmecfg->fullres_height, inst->sid); - if (rc) - goto error; - dmecfg->ds_enable = cvp->downscale; - dmecfg->enable_lrme_robustness = 1; - dmecfg->enable_inlier_tracking = 1; - rc = msm_cvp_private(cvp->priv, CVP_KMD_SEND_CMD_PKT, arg); - if (rc) { - s_vpr_e(inst->sid, "%s: cvp configuration failed\n", __func__); - goto error; - } - -error: - return rc; -} - -static int msm_cvp_mem_init(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp; - struct v4l2_format *fmt; - - if (!inst) { - d_vpr_e("%s: invalid params\n", __func__); - return -EINVAL; - } - - inst->cvp = kzalloc(sizeof(struct msm_cvp_external), GFP_KERNEL); - if (!inst->cvp) { - s_vpr_e(inst->sid, "%s: failed to allocate\n", __func__); - return -ENOMEM; - } - cvp = inst->cvp; - - cvp->arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL); - if (!cvp->arg) { - kfree(inst->cvp); - inst->cvp = NULL; - return -ENOMEM; - } - - cvp->framecount = 0; - cvp->metadata_available = false; - fmt = &inst->fmts[INPUT_PORT].v4l2_fmt; - cvp->width = fmt->fmt.pix_mp.width; - cvp->height = fmt->fmt.pix_mp.height; - cvp->frame_rate = inst->clk_data.frame_rate; - cvp->operating_rate = inst->clk_data.operating_rate; - - /* enable downscale always */ - cvp->downscale = true; - rc = msm_cvp_init_downscale_resolution(inst); - if (rc) - goto error; - - s_vpr_h(inst->sid, - "%s: pixelformat %#x, wxh %dx%d downscale %d ds_wxh %dx%d fps %d op_rate %d\n", - __func__, fmt->fmt.pix_mp.pixelformat, - cvp->width, cvp->height, cvp->downscale, - cvp->ds_width, cvp->ds_height, - cvp->frame_rate >> 16, cvp->operating_rate >> 16); - - rc = msm_cvp_init_downscale_buffers(inst); - if (rc) - goto error; - rc = msm_cvp_init_internal_buffers(inst); - if (rc) - goto error; - rc = msm_cvp_init_context_buffers(inst); - if (rc) - goto error; - - return rc; - -error: - msm_cvp_mem_deinit(inst); - return rc; -} - -static int msm_cvp_session_open(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_cvp_external *cvp; - - if (!inst || !inst->cvp) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - cvp = inst->cvp; - - s_vpr_h(inst->sid, "%s: opening cvp\n", __func__); - cvp->priv = msm_cvp_open(0, MSM_VIDC_CVP); - if (!cvp->priv) { - s_vpr_e(inst->sid, - "%s: failed to open cvp session\n", __func__); - rc = -EINVAL; - } - - return rc; -} - -static int msm_cvp_init(struct msm_vidc_inst *inst) -{ - int rc; - - rc = msm_cvp_set_secure_mode(inst); - if (rc) - goto error; - - rc = msm_cvp_set_priority(inst); - if (rc) - goto error; - - rc = msm_cvp_session_create(inst); - if (rc) - return rc; - - rc = msm_cvp_get_sessioninfo(inst); - if (rc) - return rc; - - rc = msm_cvp_set_clocks_and_bus(inst); - if (rc) - goto error; - - rc = msm_cvp_dme_basic_config(inst); - if (rc) - goto error; - - rc = msm_cvp_set_persist_buffer(inst); - if (rc) - goto error; - - rc = msm_cvp_session_start(inst); - if (rc) - goto error; - - return 0; - -error: - msm_cvp_deinit(inst); - return rc; -} - -int msm_vidc_cvp_prepare_preprocess(struct msm_vidc_inst *inst) -{ - int rc; - - if (!inst) { - d_vpr_e("%s: invalid params\n", __func__); - return -EINVAL; - } - - rc = msm_cvp_mem_init(inst); - if (rc) - return rc; - - rc = msm_cvp_session_open(inst); - if (rc) - return rc; - - rc = msm_cvp_init(inst); - if (rc) - return rc; - - return 0; -} diff --git a/msm/vidc/msm_cvp_external.h b/msm/vidc/msm_cvp_external.h deleted file mode 100644 index eb33fc0ef7e2..000000000000 --- a/msm/vidc/msm_cvp_external.h +++ /dev/null @@ -1,202 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. - */ - -#ifndef _MSM_CVP_EXTERNAL_H_ -#define _MSM_CVP_EXTERNAL_H_ - -#include -#include -#include -#include "msm_vidc_internal.h" -#include "msm_vidc_debug.h" - -#define CVP_DME (24) - -#define HFI_COMMON_BASE (0) -#define HFI_VIDEO_DOMAIN_CVP (HFI_COMMON_BASE + 0x8) -#define HFI_DOMAIN_BASE_COMMON (HFI_COMMON_BASE + 0) -#define HFI_DOMAIN_BASE_CVP (HFI_COMMON_BASE + 0x04000000) -#define HFI_ARCH_COMMON_OFFSET (0) -#define HFI_CMD_START_OFFSET (0x00010000) -#define HFI_CMD_SESSION_CVP_START \ - (HFI_DOMAIN_BASE_CVP + HFI_ARCH_COMMON_OFFSET + \ - HFI_CMD_START_OFFSET + 0x1000) - -#define HFI_CMD_SESSION_CVP_DME_FRAME \ - (HFI_CMD_SESSION_CVP_START + 0x03A) -#define HFI_CMD_SESSION_CVP_DME_BASIC_CONFIG \ - (HFI_CMD_SESSION_CVP_START + 0x03B) -#define HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS \ - (HFI_CMD_SESSION_CVP_START + 0x04D) -#define HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS \ - (HFI_CMD_SESSION_CVP_START + 0x050) - -#define HFI_DME_OUTPUT_BUFFER_SIZE (256 * 4) -#define HFI_DME_INTERNAL_PERSIST_2_BUFFER_SIZE (512 * 1024) -#define HFI_DME_FRAME_CONTEXT_BUFFER_SIZE (64 * 1024) - -#define CVP_KMD_HFI_VERSION_PROP_TYPE (1) -#define CVP_KMD_HFI_VERSION_PROP_NUMBER (1) - -#define CVP_FRAME_RATE_MAX (60) - -static inline bool is_vidc_cvp_enabled(struct msm_vidc_inst *inst) -{ - return !!inst->cvp; -} - -enum HFI_COLOR_PLANE_TYPE { - HFI_COLOR_PLANE_METADATA, - HFI_COLOR_PLANE_PICDATA, - HFI_COLOR_PLANE_UV_META, - HFI_COLOR_PLANE_UV, - HFI_MAX_COLOR_PLANES -}; - -struct msm_cvp_color_plane_info { - u32 stride[HFI_MAX_COLOR_PLANES]; - u32 buf_size[HFI_MAX_COLOR_PLANES]; -}; - -struct msm_cvp_client_data { - u32 transactionid; - u32 client_data1; - u32 client_data2; - u32 kernel_data1; - u32 kernel_data2; - u32 reserved1; - u32 reserved2; -}; - -struct msm_cvp_buffer_type { - u32 buffer_addr; - u32 size; - u32 offset; - u32 flags; - u32 reserved1; - u32 reserved2; -}; - -struct msm_cvp_session_release_persist_buffers_packet { - u32 size; - u32 packet_type; - u32 sid; - struct msm_cvp_client_data client_data; - u32 cvp_op; - struct msm_cvp_buffer_type persist1_buffer; - struct msm_cvp_buffer_type persist2_buffer; -}; - -struct msm_cvp_session_set_persist_buffers_packet { - u32 size; - u32 packet_type; - u32 sid; - struct msm_cvp_client_data client_data; - u32 cvp_op; - struct msm_cvp_buffer_type persist1_buffer; - struct msm_cvp_buffer_type persist2_buffer; -}; - -struct msm_cvp_dme_frame_packet { - u32 size; - u32 packet_type; - u32 sid; - struct msm_cvp_client_data client_data; - u32 stream_idx; - u32 skip_mv_calc; - u32 min_fpx_threshold; - u32 enable_descriptor_lpf; - u32 enable_ncc_subpel; - u32 descmatch_threshold; - int ncc_robustness_threshold; - u32 reserved[8]; - u32 buf_marker; - struct msm_cvp_buffer_type fullres_srcbuffer; - struct msm_cvp_buffer_type src_buffer; - struct msm_cvp_buffer_type srcframe_contextbuffer; - struct msm_cvp_buffer_type prsp_buffer; - struct msm_cvp_buffer_type grid_buffer; - struct msm_cvp_buffer_type ref_buffer; - struct msm_cvp_buffer_type refframe_contextbuffer; - struct msm_cvp_buffer_type videospatialtemporal_statsbuffer; -}; - -struct msm_cvp_dme_basic_config_packet { - u32 size; - u32 packet_type; - u32 sid; - struct msm_cvp_client_data client_data; - u32 stream_idx; - u32 srcbuffer_format; - struct msm_cvp_color_plane_info srcbuffer_planeinfo; - u32 src_width; - u32 src_height; - u32 fullres_width; - u32 fullres_height; - u32 fullresbuffer_format; - struct msm_cvp_color_plane_info fullresbuffer_planeinfo; - u32 ds_enable; - u32 enable_lrme_robustness; - u32 enable_inlier_tracking; - u32 override_defaults; - s32 inlier_step; - s32 outlier_step; - s32 follow_globalmotion_step; - s32 nomv_conveyedinfo_step; - s32 invalid_transform_step; - s32 valid_transform_min_confidence_for_updates; - u32 min_inlier_weight_threshold; - u32 ncc_threshold; - u32 min_allowed_tar_var; - u32 meaningful_ncc_diff; - u32 robustness_distmap[8]; - u32 ransac_threshold; -}; - -enum msm_vidc_cvp_buf_type { - MSM_VIDC_CVP_INPUT_BUF = 1, - MSM_VIDC_CVP_OUTPUT_BUF, - MSM_VIDC_CVP_PERSIST_BUF, - MSM_VIDC_CVP_CONTEXT_BUF -}; - -struct msm_cvp_buf { - u32 index; - u32 size; - u32 offset; - u32 buf_type; - int fd; - struct dma_buf *dbuf; - void *kvaddr; -}; - -struct msm_cvp_external { - void *priv; - void *arg; - u32 sid; - u32 width; - u32 height; - u32 ds_width; - u32 ds_height; - u32 frame_rate; - u32 operating_rate; - bool downscale; - u32 framecount; - u32 buffer_idx; - bool metadata_available; - struct msm_cvp_buf fullres_buffer; - struct msm_cvp_buf src_buffer; - struct msm_cvp_buf ref_buffer; - struct msm_cvp_buf output_buffer; - struct msm_cvp_buf context_buffer; - struct msm_cvp_buf refcontext_buffer; - struct msm_cvp_buf persist2_buffer; -}; - -int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst, - struct msm_vidc_buffer *mbuf); -int msm_vidc_cvp_prepare_preprocess(struct msm_vidc_inst *inst); -int msm_vidc_cvp_unprepare_preprocess(struct msm_vidc_inst *inst); -#endif diff --git a/msm/vidc/msm_cvp_internal.c b/msm/vidc/msm_cvp_internal.c deleted file mode 100644 index 36a74ded11b7..000000000000 --- a/msm/vidc/msm_cvp_internal.c +++ /dev/null @@ -1,623 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. - */ - -#include "msm_cvp_internal.h" - -#define MSM_VIDC_NOMINAL_CYCLES (444 * 1000 * 1000) -#define MSM_VIDC_UHD60E_VPSS_CYCLES (111 * 1000 * 1000) -#define MSM_VIDC_UHD60E_ISE_CYCLES (175 * 1000 * 1000) -#define MAX_CVP_VPSS_CYCLES (MSM_VIDC_NOMINAL_CYCLES - \ - MSM_VIDC_UHD60E_VPSS_CYCLES) -#define MAX_CVP_ISE_CYCLES (MSM_VIDC_NOMINAL_CYCLES - \ - MSM_VIDC_UHD60E_ISE_CYCLES) - -static void print_client_buffer(u32 tag, const char *str, - struct msm_vidc_inst *inst, struct msm_cvp_buffer *cbuf) -{ - if (!(tag & msm_vidc_debug) || !inst || !cbuf) - return; - - dprintk(tag, inst->sid, - "%s: idx %2d fd %d off %d size %d type %d flags 0x%x\n", - str, cbuf->index, cbuf->fd, - cbuf->offset, cbuf->size, cbuf->type, cbuf->flags); -} - -static void print_cvp_buffer(u32 tag, const char *str, - struct msm_vidc_inst *inst, struct msm_vidc_cvp_buffer *cbuf) -{ - if (!(tag & msm_vidc_debug) || !inst || !cbuf) - return; - - dprintk(tag, inst->sid, - "%s: idx %2d fd %d off %d daddr %x size %d type %d flags 0x%x\n", - str, cbuf->buf.index, cbuf->buf.fd, - cbuf->buf.offset, cbuf->smem.device_addr, cbuf->buf.size, - cbuf->buf.type, cbuf->buf.flags); -} - -static enum hal_buffer get_hal_buftype(const char *str, - unsigned int type, u32 sid) -{ - enum hal_buffer buftype = HAL_BUFFER_NONE; - - if (type == MSM_CVP_BUFTYPE_INPUT) - buftype = HAL_BUFFER_INPUT; - else if (type == MSM_CVP_BUFTYPE_OUTPUT) - buftype = HAL_BUFFER_OUTPUT; - else if (type == MSM_CVP_BUFTYPE_INTERNAL_1) - buftype = HAL_BUFFER_INTERNAL_SCRATCH_1; - else if (type == MSM_CVP_BUFTYPE_INTERNAL_2) - buftype = HAL_BUFFER_INTERNAL_SCRATCH_1; - else - s_vpr_e(sid, "%s: unknown buffer type %#x\n", - str, type); - - return buftype; -} - -void handle_session_register_buffer_done(enum hal_command_response cmd, - void *resp) -{ - struct msm_vidc_cb_cmd_done *response = resp; - struct msm_vidc_inst *inst; - struct msm_vidc_cvp_buffer *cbuf; - struct v4l2_event event = {0}; - u32 *data; - bool found; - - if (!response) { - d_vpr_e("%s: invalid response\n", __func__); - return; - } - inst = get_inst(get_vidc_core(response->device_id), - response->inst_id); - if (!inst) { - d_vpr_e("%s: invalid session %pK\n", __func__, - response->inst_id); - return; - } - - mutex_lock(&inst->cvpbufs.lock); - found = false; - list_for_each_entry(cbuf, &inst->cvpbufs.list, list) { - if (response->data.regbuf.client_data == - cbuf->smem.device_addr) { - found = true; - break; - } - } - mutex_unlock(&inst->cvpbufs.lock); - if (!found) { - s_vpr_e(inst->sid, "%s: client_data %x not found\n", - __func__, response->data.regbuf.client_data); - goto exit; - } - print_cvp_buffer(VIDC_HIGH, "register_done", inst, cbuf); - - event.type = V4L2_EVENT_MSM_VIDC_REGISTER_BUFFER_DONE; - data = (u32 *)event.u.data; - data[0] = cbuf->buf.index; - data[1] = cbuf->buf.type; - data[2] = cbuf->buf.fd; - data[3] = cbuf->buf.offset; - v4l2_event_queue_fh(&inst->event_handler, &event); - -exit: - s_vpr_l(inst->sid, "handled: SESSION_REGISTER_BUFFER_DONE\n"); - put_inst(inst); -} - -void handle_session_unregister_buffer_done(enum hal_command_response cmd, - void *resp) -{ - int rc; - struct msm_vidc_cb_cmd_done *response = resp; - struct msm_vidc_inst *inst; - struct msm_vidc_cvp_buffer *cbuf, *dummy; - struct v4l2_event event = {0}; - u32 *data; - bool found; - - if (!response) { - d_vpr_e("%s: invalid response\n", __func__); - return; - } - inst = get_inst(get_vidc_core(response->device_id), - response->inst_id); - if (!inst) { - d_vpr_e("%s: invalid session %pK\n", __func__, - response->inst_id); - return; - } - - mutex_lock(&inst->cvpbufs.lock); - found = false; - list_for_each_entry_safe(cbuf, dummy, &inst->cvpbufs.list, list) { - if (response->data.unregbuf.client_data == - cbuf->smem.device_addr) { - found = true; - break; - } - } - mutex_unlock(&inst->cvpbufs.lock); - if (!found) { - s_vpr_e(inst->sid, "%s: client_data %x not found\n", - __func__, response->data.unregbuf.client_data); - goto exit; - } - print_cvp_buffer(VIDC_HIGH, "unregister_done", inst, cbuf); - - rc = inst->smem_ops->smem_unmap_dma_buf(inst, &cbuf->smem); - if (rc) { - print_cvp_buffer(VIDC_ERR, "unmap fail", inst, cbuf); - goto exit; - } - - event.type = V4L2_EVENT_MSM_VIDC_UNREGISTER_BUFFER_DONE; - data = (u32 *)event.u.data; - data[0] = cbuf->buf.index; - data[1] = cbuf->buf.type; - data[2] = cbuf->buf.fd; - data[3] = cbuf->buf.offset; - v4l2_event_queue_fh(&inst->event_handler, &event); - - mutex_lock(&inst->cvpbufs.lock); - list_del(&cbuf->list); - mutex_unlock(&inst->cvpbufs.lock); - kfree(cbuf); - cbuf = NULL; -exit: - s_vpr_l(inst->sid, "handled: SESSION_UNREGISTER_BUFFER_DONE\n"); - put_inst(inst); -} - -static void print_cvp_cycles(struct msm_vidc_inst *inst) -{ - struct msm_vidc_core *core; - struct msm_vidc_inst *temp; - - if (!inst || !inst->core) - return; - core = inst->core; - - mutex_lock(&core->lock); - list_for_each_entry(temp, &core->instances, list) { - if (temp->session_type == MSM_VIDC_CVP) { - s_vpr_e(temp->sid, "vpss %d ise %d\n", - temp->clk_data.vpss_cycles, - temp->clk_data.ise_cycles); - } - } - mutex_unlock(&core->lock); -} - -static bool msm_cvp_check_session_supported(struct msm_vidc_inst *inst, - u32 vpss_cycles, u32 ise_cycles) -{ - struct msm_vidc_core *core; - struct msm_vidc_inst *temp; - u32 total_vpss_cycles = 0; - u32 total_ise_cycles = 0; - - if (!inst || !inst->core) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return false; - } - core = inst->core; - - mutex_lock(&core->lock); - list_for_each_entry(temp, &core->instances, list) { - if (temp->session_type == MSM_VIDC_CVP) { - total_vpss_cycles += inst->clk_data.vpss_cycles; - total_ise_cycles += inst->clk_data.ise_cycles; - } - } - mutex_unlock(&core->lock); - - if ((total_vpss_cycles > MAX_CVP_VPSS_CYCLES) || - (total_ise_cycles > MAX_CVP_ISE_CYCLES)) - return false; - - return true; -} - -static int msm_cvp_scale_clocks_and_bus(struct msm_vidc_inst *inst) -{ - int rc = 0; - - if (!inst || !inst->core) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - - rc = msm_vidc_set_clocks(inst->core, inst->sid); - if (rc) { - s_vpr_e(inst->sid, "%s: failed set_clocks for inst %pK\n", - __func__, inst); - goto exit; - } - - rc = msm_comm_vote_bus(inst); - if (rc) { - s_vpr_e(inst->sid, - "%s: failed vote_bus for inst %pK\n", __func__, inst); - goto exit; - } - -exit: - return rc; -} - -static int msm_cvp_get_session_info(struct msm_vidc_inst *inst, - struct msm_cvp_session_info *session) -{ - int rc = 0; - - if (!inst || !inst->core || !session) { - d_vpr_e("%s: invalid params %pK %pK\n", - __func__, inst, session); - return -EINVAL; - } - - session->session_id = inst->sid; - s_vpr_h(inst->sid, "%s: id 0x%x\n", __func__, session->session_id); - - return rc; -} - -static int msm_cvp_request_power(struct msm_vidc_inst *inst, - struct msm_cvp_request_power *power) -{ - int rc = 0; - - if (!inst || !power) { - d_vpr_e("%s: invalid params %pK %pK\n", - __func__, inst, power); - return -EINVAL; - } - - s_vpr_h(inst->sid, - "%s: clock_cycles_a %d, clock_cycles_b %d, ddr_bw %d sys_cache_bw %d\n", - __func__, power->clock_cycles_a, power->clock_cycles_b, - power->ddr_bw, power->sys_cache_bw); - - rc = msm_cvp_check_session_supported(inst, power->clock_cycles_a, - power->clock_cycles_b); - if (!rc) { - s_vpr_e(inst->sid, "%s: rejected, cycles: vpss %d, ise %d\n", - __func__, power->clock_cycles_a, power->clock_cycles_b); - print_cvp_cycles(inst); - msm_comm_kill_session(inst); - return -EOVERFLOW; - } - - inst->clk_data.min_freq = max(power->clock_cycles_a, - power->clock_cycles_b); - /* convert client provided bps into kbps as expected by driver */ - inst->clk_data.ddr_bw = power->ddr_bw / 1000; - inst->clk_data.sys_cache_bw = power->sys_cache_bw / 1000; - rc = msm_cvp_scale_clocks_and_bus(inst); - if (rc) { - s_vpr_e(inst->sid, - "%s: failed to scale clocks and bus for inst %pK\n", - __func__, inst); - goto exit; - } - - if (!inst->clk_data.min_freq && !inst->clk_data.ddr_bw && - !inst->clk_data.sys_cache_bw) { - rc = msm_cvp_inst_pause(inst); - if (rc) { - s_vpr_e(inst->sid, "%s: failed to pause\n", __func__); - goto exit; - } - } else { - rc = msm_cvp_inst_resume(inst); - if (rc) { - s_vpr_e(inst->sid, "%s: failed to resume\n", __func__); - goto exit; - } - } - -exit: - return rc; -} - -static int msm_cvp_register_buffer(struct msm_vidc_inst *inst, - struct msm_cvp_buffer *buf) -{ - int rc = 0; - bool found; - struct hfi_device *hdev; - struct msm_vidc_cvp_buffer *cbuf; - struct vidc_register_buffer vbuf; - - if (!inst || !inst->core || !buf) { - d_vpr_e("%s: invalid params %pK %pK\n", - __func__, inst, buf); - return -EINVAL; - } - hdev = inst->core->device; - print_client_buffer(VIDC_HIGH, "register", inst, buf); - - mutex_lock(&inst->cvpbufs.lock); - found = false; - list_for_each_entry(cbuf, &inst->cvpbufs.list, list) { - if (cbuf->buf.index == buf->index && - cbuf->buf.fd == buf->fd && - cbuf->buf.offset == buf->offset) { - found = true; - break; - } - } - mutex_unlock(&inst->cvpbufs.lock); - if (found) { - print_client_buffer(VIDC_ERR, "duplicate", inst, buf); - return -EINVAL; - } - - cbuf = kzalloc(sizeof(struct msm_vidc_cvp_buffer), GFP_KERNEL); - if (!cbuf) { - s_vpr_e(inst->sid, "%s: cbuf alloc failed\n", __func__); - return -ENOMEM; - } - mutex_lock(&inst->cvpbufs.lock); - list_add_tail(&cbuf->list, &inst->cvpbufs.list); - mutex_unlock(&inst->cvpbufs.lock); - - memcpy(&cbuf->buf, buf, sizeof(struct msm_cvp_buffer)); - cbuf->smem.buffer_type = get_hal_buftype(__func__, buf->type, - inst->sid); - cbuf->smem.fd = buf->fd; - cbuf->smem.offset = buf->offset; - cbuf->smem.size = buf->size; - rc = inst->smem_ops->smem_map_dma_buf(inst, &cbuf->smem); - if (rc) { - print_client_buffer(VIDC_ERR, "map failed", inst, buf); - goto exit; - } - - memset(&vbuf, 0, sizeof(struct vidc_register_buffer)); - vbuf.index = buf->index; - vbuf.type = get_hal_buftype(__func__, buf->type, inst->sid); - vbuf.size = buf->size; - vbuf.device_addr = cbuf->smem.device_addr; - vbuf.client_data = cbuf->smem.device_addr; - vbuf.response_required = true; - rc = call_hfi_op(hdev, session_register_buffer, - (void *)inst->session, &vbuf); - if (rc) { - print_cvp_buffer(VIDC_ERR, "register failed", inst, cbuf); - goto exit; - } - return rc; - -exit: - if (cbuf->smem.device_addr) - inst->smem_ops->smem_unmap_dma_buf(inst, &cbuf->smem); - mutex_lock(&inst->cvpbufs.lock); - list_del(&cbuf->list); - mutex_unlock(&inst->cvpbufs.lock); - kfree(cbuf); - cbuf = NULL; - - return rc; -} - -static int msm_cvp_unregister_buffer(struct msm_vidc_inst *inst, - struct msm_cvp_buffer *buf) -{ - int rc = 0; - bool found; - struct hfi_device *hdev; - struct msm_vidc_cvp_buffer *cbuf; - struct vidc_unregister_buffer vbuf; - - if (!inst || !inst->core || !buf) { - d_vpr_e("%s: invalid params %pK %pK\n", - __func__, inst, buf); - return -EINVAL; - } - hdev = inst->core->device; - print_client_buffer(VIDC_HIGH, "unregister", inst, buf); - - mutex_lock(&inst->cvpbufs.lock); - found = false; - list_for_each_entry(cbuf, &inst->cvpbufs.list, list) { - if (cbuf->buf.index == buf->index && - cbuf->buf.fd == buf->fd && - cbuf->buf.offset == buf->offset) { - found = true; - break; - } - } - mutex_unlock(&inst->cvpbufs.lock); - if (!found) { - print_client_buffer(VIDC_ERR, "invalid", inst, buf); - return -EINVAL; - } - - memset(&vbuf, 0, sizeof(struct vidc_unregister_buffer)); - vbuf.index = cbuf->buf.index; - vbuf.type = get_hal_buftype(__func__, cbuf->buf.type, inst->sid); - vbuf.size = cbuf->buf.size; - vbuf.device_addr = cbuf->smem.device_addr; - vbuf.client_data = cbuf->smem.device_addr; - vbuf.response_required = true; - rc = call_hfi_op(hdev, session_unregister_buffer, - (void *)inst->session, &vbuf); - if (rc) - print_cvp_buffer(VIDC_ERR, "unregister failed", inst, cbuf); - - return rc; -} - -int msm_vidc_cvp(struct msm_vidc_inst *inst, struct msm_vidc_arg *arg) -{ - int rc = 0; - - if (!inst || !arg) { - d_vpr_e("%s: invalid args %pK %pK\n", - __func__, inst, arg); - return -EINVAL; - } - - switch (arg->type) { - case MSM_CVP_GET_SESSION_INFO: - { - struct msm_cvp_session_info *session = - (struct msm_cvp_session_info *)&arg->data.session; - - rc = msm_cvp_get_session_info(inst, session); - break; - } - case MSM_CVP_REQUEST_POWER: - { - struct msm_cvp_request_power *power = - (struct msm_cvp_request_power *)&arg->data.req_power; - - rc = msm_cvp_request_power(inst, power); - break; - } - case MSM_CVP_REGISTER_BUFFER: - { - struct msm_cvp_buffer *buf = - (struct msm_cvp_buffer *)&arg->data.regbuf; - - rc = msm_cvp_register_buffer(inst, buf); - break; - } - case MSM_CVP_UNREGISTER_BUFFER: - { - struct msm_cvp_buffer *buf = - (struct msm_cvp_buffer *)&arg->data.unregbuf; - - rc = msm_cvp_unregister_buffer(inst, buf); - break; - } - default: - s_vpr_e(inst->sid, "%s: unknown arg type 0x%x\n", - __func__, arg->type); - rc = -ENOTSUPP; - break; - } - - return rc; -} - -static struct msm_vidc_ctrl msm_cvp_ctrls[] = { - { - .id = V4L2_CID_MPEG_VIDEO_UNKNOWN, - .name = "Invalid control", - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 0, - .default_value = 0, - .step = 1, - .menu_skip_mask = 0, - .qmenu = NULL, - }, -}; - -int msm_cvp_ctrl_init(struct msm_vidc_inst *inst, - const struct v4l2_ctrl_ops *ctrl_ops) -{ - return msm_comm_ctrl_init(inst, msm_cvp_ctrls, - ARRAY_SIZE(msm_cvp_ctrls), ctrl_ops); -} - -int msm_cvp_inst_pause(struct msm_vidc_inst *inst) -{ - int rc; - struct hfi_device *hdev; - - if (!inst || !inst->core || !inst->core->device) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - hdev = inst->core->device; - - rc = call_hfi_op(hdev, session_pause, (void *)inst->session); - if (rc) - s_vpr_e(inst->sid, "%s: failed to pause\n", __func__); - - return rc; -} - -int msm_cvp_inst_resume(struct msm_vidc_inst *inst) -{ - int rc; - struct hfi_device *hdev; - - if (!inst || !inst->core || !inst->core->device) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - hdev = inst->core->device; - - rc = call_hfi_op(hdev, session_resume, (void *)inst->session); - if (rc) - s_vpr_e(inst->sid, "%s: failed to resume\n", __func__); - - return rc; -} - -int msm_cvp_inst_deinit(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct msm_vidc_cvp_buffer *cbuf, *temp; - - if (!inst || !inst->core) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - s_vpr_h(inst->sid, "%s: inst %pK\n", __func__, inst); - - rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE); - if (rc) - s_vpr_e(inst->sid, "%s: close failed\n", __func__); - - mutex_lock(&inst->cvpbufs.lock); - list_for_each_entry_safe(cbuf, temp, &inst->cvpbufs.list, list) { - print_cvp_buffer(VIDC_ERR, "unregistered", inst, cbuf); - rc = inst->smem_ops->smem_unmap_dma_buf(inst, &cbuf->smem); - if (rc) - s_vpr_e(inst->sid, "%s: unmap failed\n", __func__); - list_del(&cbuf->list); - kfree(cbuf); - } - mutex_unlock(&inst->cvpbufs.lock); - - inst->clk_data.min_freq = 0; - inst->clk_data.ddr_bw = 0; - inst->clk_data.sys_cache_bw = 0; - rc = msm_cvp_scale_clocks_and_bus(inst); - if (rc) - s_vpr_e(inst->sid, "%s: failed to scale_clocks_and_bus\n", - __func__); - - return rc; -} - -int msm_cvp_inst_init(struct msm_vidc_inst *inst) -{ - int rc = 0; - - if (!inst) { - d_vpr_e("%s: invalid params\n", __func__); - return -EINVAL; - } - - s_vpr_h(inst->sid, "%s: inst %pK\n", __func__, inst); - - /* set default frequency */ - inst->clk_data.core_id = VIDC_CORE_ID_2; - inst->clk_data.min_freq = 1000; - inst->clk_data.ddr_bw = 1000; - inst->clk_data.sys_cache_bw = 1000; - - return rc; -} diff --git a/msm/vidc/msm_cvp_internal.h b/msm/vidc/msm_cvp_internal.h deleted file mode 100644 index 1a6f4ce63476..000000000000 --- a/msm/vidc/msm_cvp_internal.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - */ - -#ifndef _MSM_CVP_INTERNAL_H_ -#define _MSM_CVP_INTERNAL_H_ - -#include "msm_vidc_internal.h" -#include "msm_vidc_common.h" -#include "msm_vidc_clocks.h" -#include "msm_vidc_debug.h" - -void handle_session_register_buffer_done(enum hal_command_response cmd, - void *resp); -void handle_session_unregister_buffer_done(enum hal_command_response cmd, - void *resp); -int msm_vidc_cvp(struct msm_vidc_inst *inst, struct msm_vidc_arg *arg); -int msm_cvp_inst_init(struct msm_vidc_inst *inst); -int msm_cvp_inst_deinit(struct msm_vidc_inst *inst); -int msm_cvp_inst_pause(struct msm_vidc_inst *inst); -int msm_cvp_inst_resume(struct msm_vidc_inst *inst); -int msm_cvp_ctrl_init(struct msm_vidc_inst *inst, - const struct v4l2_ctrl_ops *ctrl_ops); -#endif diff --git a/msm/vidc/msm_smem.c b/msm/vidc/msm_smem.c index 12f645981e37..a68b3493aff6 100644 --- a/msm/vidc/msm_smem.c +++ b/msm/vidc/msm_smem.c @@ -3,15 +3,8 @@ * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ -#include #include -#include -#include -#include -#include -#include -#include -#include +#include #include "msm_vidc.h" #include "msm_vidc_debug.h" #include "msm_vidc_resources.h" diff --git a/msm/vidc/msm_v4l2_private.c b/msm/vidc/msm_v4l2_private.c deleted file mode 100644 index 7155c2d42bc3..000000000000 --- a/msm/vidc/msm_v4l2_private.c +++ /dev/null @@ -1,224 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. - */ - -#include "msm_v4l2_private.h" - -static int convert_from_user(struct msm_vidc_arg *kp, unsigned long arg) -{ - int rc = 0; - int i; - struct msm_vidc_arg __user *up = compat_ptr(arg); - - if (!kp || !up) { - d_vpr_e("%s: invalid params%pK %pK\n", __func__, kp, up); - return -EINVAL; - } - - if (get_user(kp->type, &up->type)) - return -EFAULT; - - switch (kp->type) { - case MSM_CVP_GET_SESSION_INFO: - { - struct msm_cvp_session_info *k, *u; - - k = &kp->data.session; - u = &up->data.session; - if (get_user(k->session_id, &u->session_id)) - return -EFAULT; - for (i = 0; i < 10; i++) - if (get_user(k->reserved[i], &u->reserved[i])) - return -EFAULT; - break; - } - case MSM_CVP_REQUEST_POWER: - { - struct msm_cvp_request_power *k, *u; - - k = &kp->data.req_power; - u = &up->data.req_power; - if (get_user(k->clock_cycles_a, &u->clock_cycles_a) || - get_user(k->clock_cycles_b, &u->clock_cycles_b) || - get_user(k->ddr_bw, &u->ddr_bw) || - get_user(k->sys_cache_bw, &u->sys_cache_bw)) - return -EFAULT; - for (i = 0; i < 8; i++) - if (get_user(k->reserved[i], &u->reserved[i])) - return -EFAULT; - break; - } - case MSM_CVP_REGISTER_BUFFER: - { - struct msm_cvp_buffer *k, *u; - - k = &kp->data.regbuf; - u = &up->data.regbuf; - if (get_user(k->type, &u->type) || - get_user(k->index, &u->index) || - get_user(k->fd, &u->fd) || - get_user(k->size, &u->size) || - get_user(k->offset, &u->offset) || - get_user(k->pixelformat, &u->pixelformat) || - get_user(k->flags, &u->flags)) - return -EFAULT; - for (i = 0; i < 5; i++) - if (get_user(k->reserved[i], &u->reserved[i])) - return -EFAULT; - break; - } - case MSM_CVP_UNREGISTER_BUFFER: - { - struct msm_cvp_buffer *k, *u; - - k = &kp->data.unregbuf; - u = &up->data.unregbuf; - if (get_user(k->type, &u->type) || - get_user(k->index, &u->index) || - get_user(k->fd, &u->fd) || - get_user(k->size, &u->size) || - get_user(k->offset, &u->offset) || - get_user(k->pixelformat, &u->pixelformat) || - get_user(k->flags, &u->flags)) - return -EFAULT; - for (i = 0; i < 5; i++) - if (get_user(k->reserved[i], &u->reserved[i])) - return -EFAULT; - break; - } - default: - d_vpr_e("%s: unknown cmd type 0x%x\n", - __func__, kp->type); - rc = -EINVAL; - break; - } - - return rc; -} - -static int convert_to_user(struct msm_vidc_arg *kp, unsigned long arg) -{ - int rc = 0; - int i; - struct msm_vidc_arg __user *up = compat_ptr(arg); - - if (!kp || !up) { - d_vpr_e("%s: invalid params %pK %pK\n", __func__, kp, up); - return -EINVAL; - } - - if (put_user(kp->type, &up->type)) - return -EFAULT; - - switch (kp->type) { - case MSM_CVP_GET_SESSION_INFO: - { - struct msm_cvp_session_info *k, *u; - - k = &kp->data.session; - u = &up->data.session; - if (put_user(k->session_id, &u->session_id)) - return -EFAULT; - for (i = 0; i < 10; i++) - if (put_user(k->reserved[i], &u->reserved[i])) - return -EFAULT; - break; - } - case MSM_CVP_REQUEST_POWER: - { - struct msm_cvp_request_power *k, *u; - - k = &kp->data.req_power; - u = &up->data.req_power; - if (put_user(k->clock_cycles_a, &u->clock_cycles_a) || - put_user(k->clock_cycles_b, &u->clock_cycles_b) || - put_user(k->ddr_bw, &u->ddr_bw) || - put_user(k->sys_cache_bw, &u->sys_cache_bw)) - return -EFAULT; - for (i = 0; i < 8; i++) - if (put_user(k->reserved[i], &u->reserved[i])) - return -EFAULT; - break; - } - case MSM_CVP_REGISTER_BUFFER: - { - struct msm_cvp_buffer *k, *u; - - k = &kp->data.regbuf; - u = &up->data.regbuf; - if (put_user(k->type, &u->type) || - put_user(k->index, &u->index) || - put_user(k->fd, &u->fd) || - put_user(k->size, &u->size) || - put_user(k->offset, &u->offset) || - put_user(k->pixelformat, &u->pixelformat) || - put_user(k->flags, &u->flags)) - return -EFAULT; - for (i = 0; i < 5; i++) - if (put_user(k->reserved[i], &u->reserved[i])) - return -EFAULT; - break; - } - case MSM_CVP_UNREGISTER_BUFFER: - { - struct msm_cvp_buffer *k, *u; - - k = &kp->data.unregbuf; - u = &up->data.unregbuf; - if (put_user(k->type, &u->type) || - put_user(k->index, &u->index) || - put_user(k->fd, &u->fd) || - put_user(k->size, &u->size) || - put_user(k->offset, &u->offset) || - put_user(k->pixelformat, &u->pixelformat) || - put_user(k->flags, &u->flags)) - return -EFAULT; - for (i = 0; i < 5; i++) - if (put_user(k->reserved[i], &u->reserved[i])) - return -EFAULT; - break; - } - default: - d_vpr_e("%s: unknown cmd type 0x%x\n", __func__, kp->type); - rc = -EINVAL; - break; - } - - return rc; -} - -long msm_v4l2_private(struct file *filp, unsigned int cmd, unsigned long arg) -{ - int rc; - struct msm_vidc_inst *inst; - struct msm_vidc_arg karg; - - if (!filp || !filp->private_data) { - d_vpr_e("%s: invalid params %pK\n", __func__, filp); - return -EINVAL; - } - - inst = container_of(filp->private_data, struct msm_vidc_inst, - event_handler); - memset(&karg, 0, sizeof(struct msm_vidc_arg)); - - /* - * the arg points to user space memory and needs - * to be converted to kernel space before using it. - * Check do_video_ioctl() for more details. - */ - if (convert_from_user(&karg, arg)) - return -EFAULT; - - rc = msm_vidc_private((void *)inst, cmd, &karg); - if (rc) { - d_vpr_e("%s: failed cmd type %x\n", __func__, karg.type); - return -EINVAL; - } - - if (convert_to_user(&karg, arg)) - return -EFAULT; - - return rc; -} diff --git a/msm/vidc/msm_v4l2_private.h b/msm/vidc/msm_v4l2_private.h deleted file mode 100644 index 5f1602aca410..000000000000 --- a/msm/vidc/msm_v4l2_private.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. - */ - -#ifndef _MSM_V4L2_PRIVATE_H_ -#define _MSM_V4L2_PRIVATE_H_ - -#include -#include "msm_vidc_debug.h" - -long msm_v4l2_private(struct file *file, unsigned int cmd, unsigned long arg); - -#endif diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index 22a8683a0820..04597f06b449 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -3,18 +3,8 @@ * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ -#include -#include -#include -#include -#include #include #include -#include -#include -#include -#include -#include #include "msm_vidc.h" #include "msm_vidc_common.h" #include "msm_vidc_debug.h" @@ -22,7 +12,6 @@ #include "msm_vidc_res_parse.h" #include "msm_vidc_resources.h" #include "vidc_hfi_api.h" -#include "msm_v4l2_private.h" #include "msm_vidc_clocks.h" #define BASE_DEVICE_NUMBER 32 @@ -132,7 +121,8 @@ int msm_v4l2_reqbufs(struct file *file, void *fh, int msm_v4l2_qbuf(struct file *file, void *fh, struct v4l2_buffer *b) { - return msm_vidc_qbuf(get_vidc_inst(file, fh), b); + struct video_device *vdev = video_devdata(file); + return msm_vidc_qbuf(get_vidc_inst(file, fh), vdev->v4l2_dev->mdev, b); } int msm_v4l2_dqbuf(struct file *file, void *fh, @@ -207,19 +197,9 @@ static int msm_v4l2_queryctrl(struct file *file, void *fh, return msm_vidc_query_ctrl((void *)vidc_inst, ctrl); } -static long msm_v4l2_default(struct file *file, void *fh, - bool valid_prio, unsigned int cmd, void *arg) -{ - struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); - - return msm_vidc_private((void *)vidc_inst, cmd, arg); -} - - const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = { .vidioc_querycap = msm_v4l2_querycap, - .vidioc_enum_fmt_vid_cap_mplane = msm_v4l2_enum_fmt, - .vidioc_enum_fmt_vid_out_mplane = msm_v4l2_enum_fmt, + .vidioc_enum_fmt_vid_cap = msm_v4l2_enum_fmt, .vidioc_s_fmt_vid_cap_mplane = msm_v4l2_s_fmt, .vidioc_s_fmt_vid_out_mplane = msm_v4l2_s_fmt, .vidioc_g_fmt_vid_cap_mplane = msm_v4l2_g_fmt, @@ -237,7 +217,6 @@ const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = { .vidioc_decoder_cmd = msm_v4l2_decoder_cmd, .vidioc_encoder_cmd = msm_v4l2_encoder_cmd, .vidioc_enum_framesizes = msm_v4l2_enum_framesizes, - .vidioc_default = msm_v4l2_default, }; static const struct v4l2_ioctl_ops msm_v4l2_enc_ioctl_ops = { 0 }; @@ -255,7 +234,6 @@ static const struct v4l2_file_operations msm_v4l2_vidc_fops = { .open = msm_v4l2_open, .release = msm_v4l2_close, .unlocked_ioctl = video_ioctl2, - .compat_ioctl32 = msm_v4l2_private, .poll = msm_v4l2_poll, }; @@ -327,8 +305,6 @@ static ssize_t link_name_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "venus_dec"); else if (dev == &core->vdev[MSM_VIDC_ENCODER].vdev.dev) return snprintf(buf, PAGE_SIZE, "venus_enc"); - else if (dev == &core->vdev[MSM_VIDC_CVP].vdev.dev) - return snprintf(buf, PAGE_SIZE, "venus_cvp"); else return 0; else @@ -514,16 +490,6 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) goto err_enc; } - /* setup the cvp device */ - if (core->resources.cvp_internal) { - rc = msm_vidc_register_video_device(MSM_VIDC_CVP, - nr + 2, core, dev); - if (rc) { - d_vpr_e("Failed to register video CVP\n"); - goto err_cvp; - } - } - /* finish setting up the 'core' */ mutex_lock(&vidc_driver->lock); if (vidc_driver->num_cores + 1 > MSM_VIDC_CORES_MAX) { @@ -588,12 +554,6 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) err_core_workq: vidc_hfi_deinitialize(core->hfi_type, core->device); err_cores_exceeded: - if (core->resources.cvp_internal) { - device_remove_file(&core->vdev[MSM_VIDC_CVP].vdev.dev, - &dev_attr_link_name); - video_unregister_device(&core->vdev[MSM_VIDC_CVP].vdev); - } -err_cvp: device_remove_file(&core->vdev[MSM_VIDC_ENCODER].vdev.dev, &dev_attr_link_name); video_unregister_device(&core->vdev[MSM_VIDC_ENCODER].vdev); @@ -670,11 +630,6 @@ static int msm_vidc_remove(struct platform_device *pdev) if (core->vidc_core_workq) destroy_workqueue(core->vidc_core_workq); vidc_hfi_deinitialize(core->hfi_type, core->device); - if (core->resources.cvp_internal) { - device_remove_file(&core->vdev[MSM_VIDC_CVP].vdev.dev, - &dev_attr_link_name); - video_unregister_device(&core->vdev[MSM_VIDC_CVP].vdev); - } device_remove_file(&core->vdev[MSM_VIDC_ENCODER].vdev.dev, &dev_attr_link_name); video_unregister_device(&core->vdev[MSM_VIDC_ENCODER].vdev); diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 3d2560049267..2c168e6a2322 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -3,8 +3,6 @@ * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ -#include -#include #include "msm_vdec.h" #include "msm_vidc_internal.h" #include "msm_vidc_common.h" @@ -64,7 +62,7 @@ static const char *const mpeg2_level[] = { static struct msm_vidc_ctrl msm_vdec_ctrls[] = { { - .id = V4L2_CID_MPEG_VIDEO_UNKNOWN, + .id = V4L2_CID_MPEG_VIDC_VIDEO_UNKNOWN, .name = "Invalid control", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index f02cbba6de0b..832de37b9e07 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2,7 +2,6 @@ /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ -#include #include "msm_venc.h" #include "msm_vidc_internal.h" #include "msm_vidc_common.h" @@ -76,7 +75,7 @@ static const char *const mpeg_video_stream_format[] = { static struct msm_vidc_ctrl msm_venc_ctrls[] = { { - .id = V4L2_CID_MPEG_VIDEO_UNKNOWN, + .id = V4L2_CID_MPEG_VIDC_VIDEO_UNKNOWN, .name = "Invalid control", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, @@ -396,12 +395,12 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .name = "Slice Mode", .type = V4L2_CTRL_TYPE_MENU, .minimum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE, - .maximum = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES, + .maximum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES, .default_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE, .menu_skip_mask = ~( (1 << V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) | - (1 << V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) | - (1 << V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) + (1 << V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) | + (1 << V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) ), }, { @@ -911,15 +910,6 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { ), .qmenu = mpeg_video_stream_format, }, - { - .id = V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE, - .name = "CVP Disable", - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, - .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, - .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, - .step = 1, - }, { .id = V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER, .name = "Enable/Disable Native Recorder", @@ -1893,7 +1883,6 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY: case V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM: case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: - case V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE: case V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER: case V4L2_CID_MPEG_VIDC_VENC_RC_TIMESTAMP_DISABLE: case V4L2_CID_MPEG_VIDEO_VBV_DELAY: @@ -2142,8 +2131,6 @@ int msm_venc_set_operating_rate(struct msm_vidc_inst *inst) d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } - if (!inst->core->resources.cvp_internal) - return 0; hdev = inst->core->device; @@ -3129,10 +3116,10 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst) goto set_and_exit; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); - if (ctrl->val == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) { + if (ctrl->val == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) { temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB; slice_mode = HFI_MULTI_SLICE_BY_MB_COUNT; - } else if (ctrl->val == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) { + } else if (ctrl->val == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) { temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES; slice_mode = HFI_MULTI_SLICE_BY_BYTE_COUNT; } else { @@ -4328,7 +4315,7 @@ int msm_venc_set_cvp_skipratio(struct msm_vidc_inst *inst) d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } - if (!msm_vidc_cvp_usage || !inst->core->resources.cvp_external) + if (!msm_vidc_cvp_usage) return 0; capture_rate_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_CAPTURE_FRAME_RATE); diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index ad80a317c02c..85e401705f8d 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -3,24 +3,17 @@ * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ -#include -#include -#include #include "msm_vidc.h" #include "msm_vidc_internal.h" #include "msm_vidc_debug.h" #include "msm_vdec.h" #include "msm_venc.h" -#include "msm_cvp_internal.h" -#include "msm_cvp_external.h" #include "msm_vidc_common.h" -#include #include "vidc_hfi.h" #include "vidc_hfi_helper.h" #include "vidc_hfi_api.h" #include "msm_vidc_clocks.h" #include "msm_vidc_buffer_calculations.h" -#include #define MAX_EVENTS 30 @@ -324,7 +317,8 @@ int msm_vidc_release_buffer(void *instance, int type, unsigned int index) } EXPORT_SYMBOL(msm_vidc_release_buffer); -int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) +int msm_vidc_qbuf(void *instance, struct media_device *mdev, + struct v4l2_buffer *b) { struct msm_vidc_inst *inst = instance; struct msm_vidc_client_data *client_data = NULL; @@ -385,7 +379,7 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) } mutex_lock(&q->lock); - rc = vb2_qbuf(&q->vb2_bufq, b); + rc = vb2_qbuf(&q->vb2_bufq, mdev, b); mutex_unlock(&q->lock); if (rc) s_vpr_e(inst->sid, "Failed to qbuf, %d\n", rc); @@ -735,90 +729,6 @@ static int msm_vidc_set_properties(struct msm_vidc_inst *inst) return rc; } -bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst) -{ - bool allowed = false; - struct msm_vidc_core *core; - struct v4l2_ctrl *cvp_disable; - struct v4l2_ctrl *superframe_enable; - - if (!inst || !inst->core) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - goto exit; - } - core = inst->core; - - /* - * CVP enable if - * - platform support CVP external - * - client did not disable CVP forcefully - * - client may disable forcefully to save power - * - client did not enable CVP extradata - * - if enabled, client will give CVP extradata - * - rate control is not one of below modes - * - RATE_CONTROL_OFF - * - V4L2_MPEG_VIDEO_BITRATE_MODE_CQ - * - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR - * - not secure session - * - not superframe enabled - */ - cvp_disable = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE); - superframe_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); - - if (core->resources.cvp_external && !cvp_disable->val && - !(inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) && - inst->rc_type != RATE_CONTROL_OFF && - inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ && - !inst->clk_data.is_legacy_cbr && - !superframe_enable->val) { - s_vpr_h(inst->sid, "%s: cvp allowed\n", __func__); - allowed = true; - } else { - s_vpr_h(inst->sid, - "%s: cvp not allowed, cvp_external %d cvp_disable %d extradata %#x rc_type %d legacy_cbr %d secure %d superframe %d\n", - __func__, core->resources.cvp_external, - cvp_disable->val, inst->prop.extradata_ctrls, - inst->rc_type, inst->clk_data.is_legacy_cbr, - is_secure_session(inst), superframe_enable->val); - allowed = false; - } -exit: - return allowed; -} - -static int msm_vidc_prepare_preprocess(struct msm_vidc_inst *inst) -{ - int rc = 0; - - if (!inst) { - d_vpr_e("%s: invalid params\n", __func__); - return -EINVAL; - } - - if (!msm_vidc_cvp_usage) { - s_vpr_h(inst->sid, "%s: cvp usage disabled\n", __func__); - return 0; - } - - if (!is_vidc_cvp_allowed(inst)) { - s_vpr_h(inst->sid, "%s: cvp not allowed\n", __func__); - return 0; - } - - rc = msm_vidc_cvp_prepare_preprocess(inst); - if (rc) { - s_vpr_e(inst->sid, "%s: no cvp preprocessing\n", __func__); - goto exit; - } - s_vpr_h(inst->sid, "%s: kernel to kernel cvp enabled\n", __func__); - inst->prop.extradata_ctrls |= EXTRADATA_ENC_INPUT_KK_CVP; - -exit: - if (rc) - msm_vidc_cvp_unprepare_preprocess(inst); - return rc; -} - static bool msm_vidc_set_cvp_metadata(struct msm_vidc_inst *inst) { int rc = 0; @@ -829,8 +739,7 @@ static bool msm_vidc_set_cvp_metadata(struct msm_vidc_inst *inst) { return false; } - if ((inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) || - (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_KK_CVP)) + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) value = 0x1; s_vpr_h(inst->sid, "%s: CVP extradata %d\n", __func__, value); @@ -841,27 +750,7 @@ static bool msm_vidc_set_cvp_metadata(struct msm_vidc_inst *inst) { return false; } - if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_KK_CVP) { - u32 cap_rate = 0; - u32 cvp_rate = 0; - u32 oprate = 0; - u32 fps_max = CVP_FRAME_RATE_MAX << 16; - - if (inst->clk_data.operating_rate == INT_MAX) - oprate = fps_max; - else - oprate = inst->clk_data.operating_rate; - - cap_rate = max(inst->clk_data.frame_rate, oprate); - if (cap_rate > fps_max) { - cap_rate = roundup(cap_rate, fps_max); - cvp_rate = fps_max; - } - else - cvp_rate = cap_rate; - rc = msm_comm_set_cvp_skip_ratio(inst, cap_rate, cvp_rate); - } - else if(inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) + if(inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) rc = msm_venc_set_cvp_skipratio(inst); if (rc) { @@ -889,12 +778,6 @@ static inline int start_streaming(struct msm_vidc_inst *inst) } if (is_encode_session(inst)) { - rc = msm_vidc_prepare_preprocess(inst); - if (rc) { - s_vpr_e(inst->sid, "%s: no preprocessing\n", __func__); - /* ignore error */ - rc = 0; - } if (!(msm_vidc_set_cvp_metadata(inst))) goto fail_start; } @@ -1123,25 +1006,6 @@ static int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count) return rc; } -static int msm_vidc_unprepare_preprocess(struct msm_vidc_inst *inst) -{ - int rc = 0; - - if (!inst) { - d_vpr_e("%s: invalid params\n", __func__); - return -EINVAL; - } - - if (!is_vidc_cvp_enabled(inst)) - return 0; - - rc = msm_vidc_cvp_unprepare_preprocess(inst); - if (rc) - s_vpr_e(inst->sid, "%s: failed rc %d\n", __func__, rc); - - return rc; -} - static inline int stop_streaming(struct msm_vidc_inst *inst) { int rc = 0; @@ -1158,11 +1022,6 @@ static inline int stop_streaming(struct msm_vidc_inst *inst) inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (is_encode_session(inst)) { - rc = msm_vidc_unprepare_preprocess(inst); - if (rc) - s_vpr_e(inst->sid, - "%s: failed to unprepare preprocess\n", - __func__); inst->all_intra = false; } @@ -1404,35 +1263,6 @@ int msm_vidc_dqevent(void *inst, struct v4l2_event *event) } EXPORT_SYMBOL(msm_vidc_dqevent); -int msm_vidc_private(void *vidc_inst, unsigned int cmd, - struct msm_vidc_arg *arg) -{ - int rc = 0; - struct msm_vidc_inst *inst = (struct msm_vidc_inst *)vidc_inst; - - if (!inst || !arg) { - d_vpr_e("%s: invalid args\n", __func__); - return -EINVAL; - } - if (cmd != VIDIOC_VIDEO_CMD) { - s_vpr_e(inst->sid, - "%s: invalid private cmd %#x\n", __func__, cmd); - return -ENOIOCTLCMD; - } - - if (inst->session_type == MSM_VIDC_CVP) { - rc = msm_vidc_cvp(inst, arg); - } else { - s_vpr_e(inst->sid, - "%s: private cmd %#x not supported for session_type %d\n", - __func__, cmd, inst->session_type); - rc = -EINVAL; - } - - return rc; -} -EXPORT_SYMBOL(msm_vidc_private); - static int msm_vidc_try_set_ctrl(void *instance, struct v4l2_ctrl *ctrl) { struct msm_vidc_inst *inst = instance; @@ -1583,7 +1413,6 @@ void *msm_vidc_open(int core_id, int session_type) INIT_MSM_VIDC_LIST(&inst->pending_getpropq); INIT_MSM_VIDC_LIST(&inst->outputbufs); INIT_MSM_VIDC_LIST(&inst->registeredbufs); - INIT_MSM_VIDC_LIST(&inst->cvpbufs); INIT_MSM_VIDC_LIST(&inst->refbufs); INIT_MSM_VIDC_LIST(&inst->eosbufs); INIT_MSM_VIDC_LIST(&inst->client_data); @@ -1621,9 +1450,6 @@ void *msm_vidc_open(int core_id, int session_type) } else if (session_type == MSM_VIDC_ENCODER) { msm_venc_inst_init(inst); rc = msm_venc_ctrl_init(inst, &msm_vidc_ctrl_ops); - } else if (session_type == MSM_VIDC_CVP) { - msm_cvp_inst_init(inst); - rc = msm_cvp_ctrl_init(inst, &msm_vidc_ctrl_ops); } if (rc) { s_vpr_e(inst->sid, "Failed control initialization\n"); @@ -1667,15 +1493,6 @@ void *msm_vidc_open(int core_id, int session_type) inst->debugfs_root = msm_vidc_debugfs_init_inst(inst, core->debugfs_root); - if (inst->session_type == MSM_VIDC_CVP) { - rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE); - if (rc) { - s_vpr_e(inst->sid, - "Failed to move video instance to open done state\n"); - goto fail_init; - } - } - return inst; fail_init: mutex_lock(&core->lock); @@ -1699,7 +1516,6 @@ void *msm_vidc_open(int core_id, int session_type) DEINIT_MSM_VIDC_LIST(&inst->persistbufs); DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq); DEINIT_MSM_VIDC_LIST(&inst->outputbufs); - DEINIT_MSM_VIDC_LIST(&inst->cvpbufs); DEINIT_MSM_VIDC_LIST(&inst->registeredbufs); DEINIT_MSM_VIDC_LIST(&inst->eosbufs); DEINIT_MSM_VIDC_LIST(&inst->input_crs); @@ -1827,7 +1643,6 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) DEINIT_MSM_VIDC_LIST(&inst->persistbufs); DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq); DEINIT_MSM_VIDC_LIST(&inst->outputbufs); - DEINIT_MSM_VIDC_LIST(&inst->cvpbufs); DEINIT_MSM_VIDC_LIST(&inst->registeredbufs); DEINIT_MSM_VIDC_LIST(&inst->eosbufs); DEINIT_MSM_VIDC_LIST(&inst->input_crs); @@ -1878,17 +1693,6 @@ int msm_vidc_close(void *instance) if (rc) s_vpr_e(inst->sid, "Failed: move to rel resource done state\n"); - /* - * deinit instance after REL_RES_DONE to ensure hardware - * released all buffers. - */ - if (inst->session_type == MSM_VIDC_CVP) - msm_cvp_inst_deinit(inst); - - /* clean up preprocess if not done already */ - if (is_encode_session(inst)) - msm_vidc_unprepare_preprocess(inst); - msm_vidc_cleanup_instance(inst); rc = msm_comm_try_state(inst, MSM_VIDC_CORE_UNINIT); diff --git a/msm/vidc/msm_vidc.h b/msm/vidc/msm_vidc.h index 44ea7c257ce1..2bea95132f50 100644 --- a/msm/vidc/msm_vidc.h +++ b/msm/vidc/msm_vidc.h @@ -6,21 +6,13 @@ #ifndef _MSM_VIDC_H_ #define _MSM_VIDC_H_ -#include #include -#include #include -#include #include +#include #define HAL_BUFFER_MAX 0xe - -#define V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE \ - (V4L2_CID_MPEG_MSM_VIDC_BASE + 22) -enum v4l2_mpeg_vidc_video_decoder_multi_stream { - V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY = 0, - V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY = 1, -}; +#define CVP_FRAME_RATE_MAX (60) enum smem_type { SMEM_DMA = 1, @@ -91,7 +83,6 @@ enum core_id { enum session_type { MSM_VIDC_ENCODER = 0, MSM_VIDC_DECODER, - MSM_VIDC_CVP, MSM_VIDC_UNKNOWN, MSM_VIDC_MAX_DEVICES = MSM_VIDC_UNKNOWN, }; @@ -115,7 +106,8 @@ int msm_vidc_g_ctrl(void *instance, struct v4l2_control *a); int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b); int msm_vidc_release_buffer(void *instance, int buffer_type, unsigned int buffer_index); -int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b); +int msm_vidc_qbuf(void *instance, struct media_device *mdev, + struct v4l2_buffer *b); int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b); int msm_vidc_streamon(void *instance, enum v4l2_buf_type i); int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *ctrl); @@ -130,6 +122,4 @@ int msm_vidc_unsubscribe_event(void *instance, int msm_vidc_dqevent(void *instance, struct v4l2_event *event); int msm_vidc_g_crop(void *instance, struct v4l2_crop *a); int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize); -int msm_vidc_private(void *vidc_inst, unsigned int cmd, - struct msm_vidc_arg *arg); #endif diff --git a/msm/vidc/msm_vidc_bus_iris1.c b/msm/vidc/msm_vidc_bus_iris1.c index 91c1f6f2ec69..6115ad846685 100644 --- a/msm/vidc/msm_vidc_bus_iris1.c +++ b/msm/vidc/msm_vidc_bus_iris1.c @@ -73,11 +73,6 @@ static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d) return 0; } -static unsigned long __calculate_cvp(struct vidc_bus_vote_data *d) -{ - return 0; -} - static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) { /* @@ -628,9 +623,6 @@ static unsigned long __calculate(struct vidc_bus_vote_data *d) case HAL_VIDEO_DOMAIN_DECODER: value = __calculate_decoder(d); break; - case HAL_VIDEO_DOMAIN_CVP: - value = __calculate_cvp(d); - break; default: s_vpr_e(d->sid, "Unknown Domain %#x", d->domain); } diff --git a/msm/vidc/msm_vidc_bus_iris2.c b/msm/vidc/msm_vidc_bus_iris2.c index 0da868b57612..a197bda82b1f 100644 --- a/msm/vidc/msm_vidc_bus_iris2.c +++ b/msm/vidc/msm_vidc_bus_iris2.c @@ -11,11 +11,6 @@ static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d) return 0; } -static unsigned long __calculate_cvp(struct vidc_bus_vote_data *d) -{ - return 0; -} - static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) { /* @@ -530,9 +525,6 @@ static unsigned long __calculate(struct vidc_bus_vote_data *d) case HAL_VIDEO_DOMAIN_DECODER: value = __calculate_decoder(d); break; - case HAL_VIDEO_DOMAIN_CVP: - value = __calculate_cvp(d); - break; default: s_vpr_e(d->sid, "Unknown Domain %#x", d->domain); } diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 6b81e6e10690..da1f6002fa4e 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -280,8 +280,7 @@ int msm_comm_set_buses(struct msm_vidc_core *core, u32 sid) } mutex_unlock(&inst->registeredbufs.lock); - if ((!filled_len || !device_addr) && - (inst->session_type != MSM_VIDC_CVP)) { + if (!filled_len || !device_addr) { s_vpr_l(sid, "%s: no input\n", __func__); continue; } @@ -336,8 +335,7 @@ int msm_comm_vote_bus(struct msm_vidc_inst *inst) } mutex_unlock(&inst->registeredbufs.lock); - if ((!filled_len || !device_addr) && - (inst->session_type != MSM_VIDC_CVP)) { + if (!filled_len || !device_addr) { s_vpr_l(inst->sid, "%s: no input\n", __func__); return 0; } @@ -345,16 +343,12 @@ int msm_comm_vote_bus(struct msm_vidc_inst *inst) vote_data->sid = inst->sid; vote_data->domain = get_hal_domain(inst->session_type, inst->sid); vote_data->power_mode = 0; - if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW && - inst->session_type != MSM_VIDC_CVP) + if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW) vote_data->power_mode = VIDC_POWER_TURBO; if (msm_vidc_clock_voting || is_turbo || is_turbo_session(inst)) vote_data->power_mode = VIDC_POWER_TURBO; - if (inst->session_type == MSM_VIDC_CVP) { - vote_data->calc_bw_ddr= inst->clk_data.ddr_bw; - vote_data->calc_bw_llcc= inst->clk_data.sys_cache_bw; - } else if (vote_data->power_mode != VIDC_POWER_TURBO) { + if (vote_data->power_mode != VIDC_POWER_TURBO) { out_f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; inp_f = &inst->fmts[INPUT_PORT].v4l2_fmt; switch (inst->session_type) { @@ -364,9 +358,6 @@ int msm_comm_vote_bus(struct msm_vidc_inst *inst) case MSM_VIDC_ENCODER: codec = out_f->fmt.pix_mp.pixelformat; break; - case MSM_VIDC_CVP: - codec = V4L2_PIX_FMT_CVP; - break; default: s_vpr_e(inst->sid, "%s: invalid session_type %#x\n", __func__, inst->session_type); @@ -1042,11 +1033,6 @@ int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst) return -EINVAL; } - if (inst->session_type == MSM_VIDC_CVP) { - s_vpr_l(inst->sid, "%s: cvp session\n", __func__); - return 0; - } - count = inst->core->resources.codec_data_count; fourcc = get_v4l2_codec(inst); @@ -1171,7 +1157,6 @@ int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst) switch (codec) { case V4L2_PIX_FMT_VP8: - case V4L2_PIX_FMT_TME: pdata.video_work_route = 1; goto decision_done; } @@ -1188,7 +1173,7 @@ int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst) fps = inst->clk_data.frame_rate >> 16; mbps = NUM_MBS_PER_SEC(output_height, output_width, fps); if (slice_mode == - V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES || + V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES || (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR && mbps <= CBR_MB_LIMIT) || (inst->rc_type == @@ -1246,7 +1231,7 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) height = f->fmt.pix_mp.height; width = f->fmt.pix_mp.width; - if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES || + if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES || codec == V4L2_PIX_FMT_VP8 || is_legacy_cbr) { pdata.video_work_route = 1; } @@ -1381,7 +1366,6 @@ int msm_vidc_decide_work_mode_iris1(struct msm_vidc_inst *inst) switch (codec) { case V4L2_PIX_FMT_VP8: - case V4L2_PIX_FMT_TME: pdata.video_work_mode = HFI_WORKMODE_1; goto decision_done; } diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index f7affacbb3c7..04e8d9fb8fd8 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -3,20 +3,12 @@ * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ -#include -#include -#include -#include -#include #include -#include #include "msm_vidc_common.h" #include "vidc_hfi_api.h" #include "vidc_hfi.h" #include "msm_vidc_debug.h" #include "msm_vidc_clocks.h" -#include "msm_cvp_external.h" -#include "msm_cvp_internal.h" #include "msm_vidc_buffer_calculations.h" #define IS_ALREADY_IN_STATE(__p, __d) (\ @@ -31,8 +23,6 @@ static void handle_session_error(enum hal_command_response cmd, void *data); static void msm_vidc_print_running_insts(struct msm_vidc_core *core); -#define V4L2_H264_LEVEL_UNKNOWN V4L2_MPEG_VIDEO_H264_LEVEL_UNKNOWN -#define V4L2_HEVC_LEVEL_UNKNOWN V4L2_MPEG_VIDEO_HEVC_LEVEL_UNKNOWN #define V4L2_VP9_LEVEL_61 V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_61 int msm_comm_g_ctrl_for_id(struct msm_vidc_inst *inst, int id) @@ -161,8 +151,6 @@ int msm_comm_hfi_to_v4l2(int id, int value, u32 sid) return V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1; case HFI_HEVC_LEVEL_62: return V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2; - case HFI_LEVEL_UNKNOWN: - return V4L2_MPEG_VIDEO_HEVC_LEVEL_UNKNOWN; default: goto unknown_value; } @@ -292,8 +280,6 @@ static int h264_level_v4l2_to_hfi(int value, u32 sid) return HFI_H264_LEVEL_61; case V4L2_MPEG_VIDEO_H264_LEVEL_6_2: return HFI_H264_LEVEL_62; - case V4L2_MPEG_VIDEO_H264_LEVEL_UNKNOWN: - return HFI_LEVEL_UNKNOWN; default: goto unknown_value; } @@ -332,8 +318,6 @@ static int hevc_level_v4l2_to_hfi(int value, u32 sid) return HFI_HEVC_LEVEL_61; case V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2: return HFI_HEVC_LEVEL_62; - case V4L2_MPEG_VIDEO_HEVC_LEVEL_UNKNOWN: - return HFI_LEVEL_UNKNOWN; default: goto unknown_value; } @@ -858,9 +842,6 @@ enum hal_domain get_hal_domain(int session_type, u32 sid) case MSM_VIDC_DECODER: domain = HAL_VIDEO_DOMAIN_DECODER; break; - case MSM_VIDC_CVP: - domain = HAL_VIDEO_DOMAIN_CVP; - break; default: s_vpr_e(sid, "Wrong domain %d\n", session_type); domain = HAL_UNUSED_DOMAIN; @@ -897,12 +878,6 @@ enum hal_video_codec get_hal_codec(int fourcc, u32 sid) case V4L2_PIX_FMT_HEVC: codec = HAL_VIDEO_CODEC_HEVC; break; - case V4L2_PIX_FMT_TME: - codec = HAL_VIDEO_CODEC_TME; - break; - case V4L2_PIX_FMT_CVP: - codec = HAL_VIDEO_CODEC_CVP; - break; default: s_vpr_e(sid, "Wrong codec: %#x\n", fourcc); codec = HAL_UNUSED_CODEC; @@ -1439,14 +1414,7 @@ static int msm_vidc_comm_update_ctrl(struct msm_vidc_inst *inst, static void msm_vidc_comm_update_ctrl_limits(struct msm_vidc_inst *inst) { - struct v4l2_format *f; - if (inst->session_type == MSM_VIDC_ENCODER) { - f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; - if (get_hal_codec(f->fmt.pix_mp.pixelformat, - inst->sid) == - HAL_VIDEO_CODEC_TME) - return; msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE, &inst->capability.cap[CAP_BITRATE]); msm_vidc_comm_update_ctrl(inst, @@ -1487,13 +1455,6 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data) goto error; } - if (inst->session_type == MSM_VIDC_CVP) { - s_vpr_h(inst->sid, "%s: cvp session\n", __func__); - signal_session_msg_receipt(cmd, inst); - put_inst(inst); - return; - } - s_vpr_l(inst->sid, "handled: SESSION_INIT_DONE\n"); signal_session_msg_receipt(cmd, inst); put_inst(inst); @@ -2742,12 +2703,6 @@ void handle_cmd_response(enum hal_command_response cmd, void *data) case HAL_SESSION_RELEASE_BUFFER_DONE: handle_session_release_buf_done(cmd, data); break; - case HAL_SESSION_REGISTER_BUFFER_DONE: - handle_session_register_buffer_done(cmd, data); - break; - case HAL_SESSION_UNREGISTER_BUFFER_DONE: - handle_session_unregister_buffer_done(cmd, data); - break; default: d_vpr_l("response unhandled: %d\n", cmd); break; @@ -3157,8 +3112,6 @@ static int msm_comm_session_init(int flipped_state, } else if (inst->session_type == MSM_VIDC_ENCODER) { f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; fourcc = f->fmt.pix_mp.pixelformat; - } else if (inst->session_type == MSM_VIDC_CVP) { - fourcc = V4L2_PIX_FMT_CVP; } else { s_vpr_e(inst->sid, "Invalid session\n"); return -EINVAL; @@ -4054,11 +4007,6 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd) s_vpr_e(inst->sid, "Failed to flush buffers: %d\n", rc); } break; - case V4L2_CMD_SESSION_CONTINUE: - { - rc = msm_comm_session_continue(inst); - break; - } /* This case also for V4L2_ENC_CMD_STOP */ case V4L2_DEC_CMD_STOP: { @@ -4114,35 +4062,6 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd) return rc; } -static int msm_comm_preprocess(struct msm_vidc_inst *inst, - struct msm_vidc_buffer *mbuf) -{ - int rc = 0; - - if (!inst || !mbuf) { - d_vpr_e("%s: invalid params %pK %pK\n", - __func__, inst, mbuf); - return -EINVAL; - } - - /* preprocessing is allowed for encoder input buffer only */ - if (!is_encode_session(inst) || mbuf->vvb.vb2_buf.type != INPUT_MPLANE) - return 0; - - /* preprocessing is done using CVP module only */ - if (!is_vidc_cvp_enabled(inst)) - return 0; - - rc = msm_vidc_cvp_preprocess(inst, mbuf); - if (rc) { - s_vpr_e(inst->sid, "%s: cvp preprocess failed\n", - __func__); - return rc; - } - - return rc; -} - static void populate_frame_data(struct vidc_frame_data *data, struct msm_vidc_buffer *mbuf, struct msm_vidc_inst *inst) { @@ -4494,10 +4413,6 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) return 0; } - rc = msm_comm_preprocess(inst, mbuf); - if (rc) - return rc; - do_bw_calc = mbuf->vvb.vb2_buf.type == INPUT_MPLANE; rc = msm_comm_scale_clocks_and_bus(inst, do_bw_calc); if (rc) @@ -5257,12 +5172,6 @@ int msm_comm_set_recon_buffers(struct msm_vidc_inst *inst) return -EINVAL; } - if (inst->session_type != MSM_VIDC_ENCODER && - inst->session_type != MSM_VIDC_DECODER) { - s_vpr_h(inst->sid, "Recon buffs not req for cvp\n"); - return 0; - } - bufcount = inst->fmts[OUTPUT_PORT].count_actual; msm_comm_release_recon_buffers(inst); diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index df6cfdacfa94..818d361e9906 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -17,7 +17,6 @@ #define HEIC_GRID_DIMENSION 512 #define CBR_MB_LIMIT (((1280+15)/16)*((720+15)/16)*30) #define CBR_VFR_MB_LIMIT (((640+15)/16)*((480+15)/16)*30) -#define V4L2_CID_MPEG_VIDEO_UNKNOWN (V4L2_CID_MPEG_MSM_VIDC_BASE + 0xFFF) #define MAX_BITRATE_DECODER_CAVLC 220000000 #define MAX_BITRATE_DECODER_2STAGE_CABAC 200000000 #define MAX_BITRATE_DECODER_1STAGE_CABAC 70000000 @@ -65,10 +64,6 @@ static inline struct v4l2_ctrl *get_ctrl(struct msm_vidc_inst *inst, { int i; - if (inst->session_type == MSM_VIDC_CVP && - inst->core->resources.cvp_internal) - return inst->ctrls[0]; - for (i = 0; i < inst->num_ctrls; i++) { if (inst->ctrls[i]->id == id) return inst->ctrls[i]; diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index ce5b520219ff..2f6792f50675 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -666,12 +666,6 @@ inline void update_log_ctxt(u32 sid, u32 session_type, u32 fourcc) case V4L2_PIX_FMT_HEVC: codec = "h265"; break; - case V4L2_PIX_FMT_TME: - codec = " tme"; - break; - case V4L2_PIX_FMT_CVP: - codec = " cvp"; - break; default: codec = "...."; break; @@ -686,9 +680,6 @@ inline void update_log_ctxt(u32 sid, u32 session_type, u32 fourcc) type = 'd'; s_type = VIDC_DECODER; break; - case MSM_VIDC_CVP: - type = 'c'; - s_type = VIDC_CVP; default: type = '.'; break; @@ -713,7 +704,6 @@ inline char *get_codec_name(u32 sid) * 0xx -> allow prints for all sessions * 1xx -> allow only encoder prints * 2xx -> allow only decoder prints - * 4xx -> allow only cvp prints */ inline bool is_print_allowed(u32 sid, u32 level) { @@ -731,3 +721,183 @@ inline bool is_print_allowed(u32 sid, u32 level) return false; } + +/* Mock all the missing parts for successful compilation starts here */ +void trace_msm_smem_buffer_iommu_op_start(char *s, int i, int j, unsigned long k, + dma_addr_t iova, unsigned long l) +{ +} +void trace_msm_smem_buffer_iommu_op_end(char *s, int i, int j, unsigned long k, + dma_addr_t iova, unsigned long l) +{ +} +void trace_msm_smem_buffer_dma_op_start(char *s, u32 buffer_type, unsigned long heap_mask, + size_t size, u32 align, u32 flags, + int map_kernel) +{ +} +void trace_msm_smem_buffer_dma_op_end(char *s, u32 buffer_type, unsigned long heap_mask, + size_t size, u32 align, u32 flags, + int map_kernel) +{ +} +void trace_msm_v4l2_vidc_buffer_counter(char *s, int etb, int ebd, int ftb, int fbd) +{ +} +void trace_msm_v4l2_vidc_open_start(char *s) +{ + (void) s; +} +void trace_msm_v4l2_vidc_open_end(char *s) +{ + (void) s; +} +void trace_msm_v4l2_vidc_close_start(char *s) +{ + (void) s; +} +void trace_msm_v4l2_vidc_close_end(char *s) +{ + (void) s; +} +void trace_msm_vidc_common_state_change(void* inst, enum instance_state ins_state, int state) +{ + (void) inst; + (void) ins_state; + (void) state; +} + +void trace_msm_vidc_perf_clock_scale(const char *name, u32 freq) +{ + (void) name; + (void) freq; +} + +void trace_venus_hfi_var_done(u32 cp_start, u32 cp_size, + u32 cp_nonpixel_start, u32 cp_nonpixel_size) + +{ + (void) cp_start; + (void) cp_size; + (void) cp_nonpixel_start; + (void) cp_nonpixel_size; +} + +void trace_msm_v4l2_vidc_buffer_event_start(char *event_type, u32 device_addr, + int64_t timestamp, u32 alloc_len, + u32 filled_len, u32 offset) +{ + (void)event_type; + (void) device_addr; + (void) timestamp; + (void) alloc_len; + (void) filled_len; + (void) offset; +} + +void trace_msm_v4l2_vidc_buffer_event_end(char *event_type, u32 device_addr, + int64_t timestamp, u32 alloc_len, + u32 filled_len, u32 offset) +{ + (void) event_type; + (void) device_addr; + (void) timestamp; + (void) alloc_len; + (void) filled_len; + (void) offset; +} + +int +msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib) +{ + (void) cl; + (void) ab; + (void) ib; + + return 0; +} + +struct msm_bus_client_handle dummy_cl; +struct msm_bus_client_handle* +msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name, + bool active_only) +{ + (void) mas; + (void) slv; + (void) name; + (void) active_only; + + return &dummy_cl; +} + +void msm_bus_scale_unregister(struct msm_bus_client_handle *cl) +{ + (void) cl; +} + +void do_gettimeofday(struct timeval *__ddl_tv) +{ +} + +#ifndef CONFIG_VIDEOBUF2_CORE +void vb2_queue_release(struct vb2_queue *q) +{ + (void) q; +} + +int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) +{ + (void) q; + (void) req; + + return 0; +} + +int vb2_qbuf(struct vb2_queue *q, struct media_device *mdev, + struct v4l2_buffer *b) +{ + (void) q; + (void) mdev; + (void) b; + + return 0; +} + +int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking) +{ + (void) q; + (void) b; + (void) nonblocking; + + return 0; +} + +int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type) +{ + (void) q; + (void) type; + + return 0; +} + +int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) +{ + (void) q; + (void) type; + + return 0; +} + +int vb2_queue_init(struct vb2_queue *q) +{ + (void) q; + + return 0; +} + +void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) +{ + (void) vb; + (void) state; +} +#endif diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index c002662224a0..3dbb4d25aadd 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -7,9 +7,83 @@ #define __MSM_VIDC_DEBUG__ #include #include + +/* Mock all the missing parts for successful compilation starts here */ #include +#include +#include +#include #include "msm_vidc_internal.h" -#include "trace/events/msm_vidc_events.h" + +#define MAX_TRACER_LOG_LENGTH 128 + +#define trace_msm_vidc_printf(trace_logbuf, log_length) (void) log_length +#define trace_msm_v4l2_vidc_fw_load_start(s) +#define trace_msm_v4l2_vidc_fw_load_end(s) + +void trace_msm_v4l2_vidc_open_start(char *s); +void trace_msm_v4l2_vidc_open_end(char *s); +void trace_msm_v4l2_vidc_close_start(char *s); +void trace_msm_v4l2_vidc_close_end(char *s); +void trace_msm_vidc_common_state_change(void*, enum instance_state ins_state, int state); +void trace_msm_smem_buffer_iommu_op_start(char *s, int i, int j, unsigned long k, + dma_addr_t iova, unsigned long l); +void trace_msm_smem_buffer_iommu_op_end(char *s, int i, int j, unsigned long k, + dma_addr_t iova, unsigned long l); +void trace_msm_smem_buffer_dma_op_start(char *s, u32 buffer_type, unsigned long heap_mask, + size_t size, u32 align, u32 flags, + int map_kernel); +void trace_msm_smem_buffer_dma_op_end(char *s, u32 buffer_type, unsigned long heap_mask, + size_t size, u32 align, u32 flags, + int map_kernel); +void trace_msm_v4l2_vidc_buffer_counter(char *s, int etb, int ebd, int ftb, int fbd); +void trace_msm_vidc_perf_clock_scale(const char *name, u32 freq); +void trace_venus_hfi_var_done(u32 cp_start, u32 cp_size, + u32 cp_nonpixel_start, u32 cp_nonpixel_size); +void trace_msm_v4l2_vidc_buffer_event_start(char *event_type, u32 device_addr, + int64_t timestamp, u32 alloc_len, + u32 filled_len, u32 offset); +void trace_msm_v4l2_vidc_buffer_event_end(char *event_type, u32 device_addr, + int64_t timestamp, u32 alloc_len, + u32 filled_len, u32 offset); + +// void disable_irq_nosync(unsigned int irq); +// void enable_irq(unsigned int irq); + +struct msm_bus_client_handle { + char *name; + int mas; + int slv; + int first_hop; + // struct device *mas_dev; + u64 cur_act_ib; + u64 cur_act_ab; + u64 cur_dual_ib; + u64 cur_dual_ab; + bool active_only; +}; + +int msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib); +int msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib); +struct msm_bus_client_handle* msm_bus_scale_register(uint32_t mas, uint32_t slv, + char *name, bool active_only); +void msm_bus_scale_unregister(struct msm_bus_client_handle *cl); + +void do_gettimeofday(struct timeval *__ddl_tv); + +#ifndef CONFIG_VIDEOBUF2_CORE +int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req); +int vb2_qbuf(struct vb2_queue *q, struct media_device *mdev, + struct v4l2_buffer *b); +int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking); +int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type); +int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type); +int vb2_queue_init(struct vb2_queue *q); +void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state); +#endif + +#define SMEM_IMAGE_VERSION_TABLE 469 +/* Mock all the missing parts for successful compilation ends */ #ifndef VIDC_DBG_LABEL #define VIDC_DBG_LABEL "msm_vidc" @@ -42,7 +116,6 @@ enum vidc_msg_prio { VIDC_BUS = 0x00000020, VIDC_ENCODER = 0x00000100, VIDC_DECODER = 0x00000200, - VIDC_CVP = 0x00000400, VIDC_PRINTK = 0x00001000, VIDC_FTRACE = 0x00002000, FW_LOW = 0x00010000, diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 31b9ce82ed04..22102d76607e 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -6,16 +6,6 @@ #ifndef _MSM_VIDC_INTERNAL_H_ #define _MSM_VIDC_INTERNAL_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include @@ -58,10 +48,6 @@ #define INPUT_MPLANE V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE #define OUTPUT_MPLANE V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE -/* EXTRADATA_ENC_INPUT_KK_CVP is an extension of - v4l2_mpeg_vidc_extradata for internal usage. - This is needed to indicate internal kernel to kernel CVP usage. */ -#define EXTRADATA_ENC_INPUT_KK_CVP (1UL << 31) #define RATE_CONTROL_OFF (V4L2_MPEG_VIDEO_BITRATE_MODE_CQ + 1) #define RATE_CONTROL_LOSSLESS (V4L2_MPEG_VIDEO_BITRATE_MODE_CQ + 2) #define SYS_MSG_START HAL_SYS_INIT_DONE @@ -504,7 +490,6 @@ struct msm_vidc_inst { enum session_type session_type; void *session; u32 sid; - struct msm_cvp_external *cvp; struct session_prop prop; enum instance_state state; struct msm_vidc_format fmts[MAX_PORT_NUM]; @@ -517,7 +502,6 @@ struct msm_vidc_inst { struct msm_vidc_list refbufs; struct msm_vidc_list eosbufs; struct msm_vidc_list registeredbufs; - struct msm_vidc_list cvpbufs; struct msm_vidc_list etb_data; struct msm_vidc_list fbd_data; struct msm_vidc_list window_data; @@ -606,12 +590,6 @@ struct msm_vidc_buffer { enum msm_vidc_flags flags; }; -struct msm_vidc_cvp_buffer { - struct list_head list; - struct msm_smem smem; - struct msm_cvp_buffer buf; -}; - void msm_comm_handle_thermal_event(void); int msm_smem_alloc(size_t size, u32 align, u32 flags, enum hal_buffer buffer_type, int map_kernel, diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 2900e9917768..414d8c6a0dd8 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -3,17 +3,8 @@ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. */ -#include -#include -#include -#include -#include #include #include -#include -#include -#include -#include #include #include #include "msm_vidc_internal.h" @@ -68,7 +59,6 @@ static struct msm_vidc_codec_data lito_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 0, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 0, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 0, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 0, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 0, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 0, 200, 200), @@ -81,7 +71,6 @@ static struct msm_vidc_codec_data kona_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 25, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 25, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 25, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 25, 540, 540), CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 25, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 25, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 25, 200, 200), @@ -94,7 +83,6 @@ static struct msm_vidc_codec_data sm6150_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 125, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 50, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 50, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 50, 200, 200), @@ -106,7 +94,6 @@ static struct msm_vidc_codec_data bengal_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 125, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 50, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 50, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 50, 200, 200), @@ -119,7 +106,6 @@ static struct msm_vidc_codec_data sm8150_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 0, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 0, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 0, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 0, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 0, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 0, 200, 200), @@ -131,7 +117,6 @@ static struct msm_vidc_codec_data sdm845_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 125, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 50, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 50, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 50, 200, 200), @@ -143,7 +128,6 @@ static struct msm_vidc_codec_data sdm670_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 125, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_TME, MSM_VIDC_ENCODER, 0, 540, 540), CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 50, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 50, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 50, 200, 200), @@ -564,10 +548,6 @@ static struct msm_vidc_common_data lito_common_data_v0[] = { .key = "qcom,debug-timeout", .value = 0, }, - { - .key = "qcom,cvp-internal", - .value = 1, - }, { .key = "qcom,decode-batching", .value = 1, @@ -639,10 +619,6 @@ static struct msm_vidc_common_data lito_common_data_v1[] = { .key = "qcom,debug-timeout", .value = 0, }, - { - .key = "qcom,cvp-internal", - .value = 1, - }, { .key = "qcom,decode-batching", .value = 1, @@ -722,10 +698,6 @@ static struct msm_vidc_common_data kona_common_data[] = { .key = "qcom,debug-timeout", .value = 0, }, - { - .key = "qcom,cvp-external", - .value = 1, - }, { .key = "qcom,decode-batching", .value = 1, @@ -931,10 +903,6 @@ static struct msm_vidc_common_data sm8150_common_data[] = { .key = "qcom,debug-timeout", .value = 0, }, - { - .key = "qcom,cvp-internal", - .value = 1, - }, { .key = "qcom,decode-batching", .value = 1, diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 8ecadde92f6e..6bc9aa61ce95 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -3,15 +3,12 @@ * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ -#include #include #include -#include #include #include "msm_vidc_debug.h" #include "msm_vidc_resources.h" #include "msm_vidc_res_parse.h" -#include "soc/qcom/secure_buffer.h" enum clock_properties { CLOCK_PROP_HAS_SCALING = 1 << 0, @@ -109,13 +106,6 @@ static inline void msm_vidc_free_clock_table( res->clock_set.count = 0; } -static inline void msm_vidc_free_cx_ipeak_context( - struct msm_vidc_platform_resources *res) -{ - cx_ipeak_unregister(res->cx_ipeak_context); - res->cx_ipeak_context = NULL; -} - void msm_vidc_free_platform_resources( struct msm_vidc_platform_resources *res) { @@ -126,7 +116,6 @@ void msm_vidc_free_platform_resources( msm_vidc_free_qdss_addr_table(res); msm_vidc_free_bus_vectors(res); msm_vidc_free_buffer_usage_table(res); - msm_vidc_free_cx_ipeak_context(res); } static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res) @@ -805,10 +794,6 @@ int read_platform_resources_from_drv_data( "qcom,fw-unload-delay"); res->msm_vidc_hw_rsp_timeout = find_key_value(platform_data, "qcom,hw-resp-timeout"); - res->cvp_internal = find_key_value(platform_data, - "qcom,cvp-internal"); - res->cvp_external = find_key_value(platform_data, - "qcom,cvp-external"); res->non_fatal_pagefaults = find_key_value(platform_data, "qcom,domain-attr-non-fatal-faults"); res->cache_pagetables = find_key_value(platform_data, @@ -835,44 +820,6 @@ int read_platform_resources_from_drv_data( } -static int msm_vidc_populate_cx_ipeak_context( - struct msm_vidc_platform_resources *res) -{ - struct platform_device *pdev = res->pdev; - int rc = 0; - - if (of_find_property(pdev->dev.of_node, - "qcom,cx-ipeak-data", NULL)) - res->cx_ipeak_context = cx_ipeak_register( - pdev->dev.of_node, "qcom,cx-ipeak-data"); - else - return rc; - - if (IS_ERR(res->cx_ipeak_context)) { - rc = PTR_ERR(res->cx_ipeak_context); - if (rc == -EPROBE_DEFER) - d_vpr_h("cx-ipeak register failed. Deferring probe!"); - else - d_vpr_e("cx-ipeak register failed. rc: %d", rc); - - res->cx_ipeak_context = NULL; - return rc; - } - - if (res->cx_ipeak_context) - d_vpr_h("cx-ipeak register successful"); - else - d_vpr_h("cx-ipeak register not implemented"); - - of_property_read_u32(pdev->dev.of_node, - "qcom,clock-freq-threshold", - &res->clk_freq_threshold); - d_vpr_h("cx ipeak threshold frequency = %u\n", - res->clk_freq_threshold); - - return rc; -} - int read_platform_resources_from_dt( struct msm_vidc_platform_resources *res) { @@ -952,16 +899,9 @@ int read_platform_resources_from_dt( goto err_setup_legacy_cb; } - rc = msm_vidc_populate_cx_ipeak_context(res); - if (rc) { - d_vpr_e("Failed to setup cx-ipeak %d\n", rc); - goto err_register_cx_ipeak; - } return rc; -err_register_cx_ipeak: - msm_vidc_free_cx_ipeak_context(res); err_setup_legacy_cb: err_load_reset_table: msm_vidc_free_allowed_clocks_table(res); diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 443e07be14b1..3c1ecec57ea6 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -9,7 +9,6 @@ #include #include "msm_vidc.h" #include -#include "soc/qcom/cx_ipeak.h" #define MAX_BUFFER_TYPES 32 @@ -175,8 +174,6 @@ struct msm_vidc_platform_resources { int msm_vidc_hw_rsp_timeout; int msm_vidc_firmware_unload_delay; uint32_t msm_vidc_pwr_collapse_delay; - bool cvp_internal; - bool cvp_external; bool non_fatal_pagefaults; bool cache_pagetables; bool decode_batching; diff --git a/msm/vidc/vidc_hfi.c b/msm/vidc/vidc_hfi.c index 111965e6e457..959ac5e1fe53 100644 --- a/msm/vidc/vidc_hfi.c +++ b/msm/vidc/vidc_hfi.c @@ -2,7 +2,6 @@ /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ -#include #include "msm_vidc_debug.h" #include "vidc_hfi_api.h" #include "hfi_common.h" diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index 76cfb7e0924f..697fbbcd2575 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -325,14 +325,6 @@ struct hfi_uncompressed_plane_actual_constraints_info { #define HFI_CMD_SESSION_CONTINUE (HFI_CMD_SESSION_OX_START + 0x00D) #define HFI_CMD_SESSION_SYNC (HFI_CMD_SESSION_OX_START + 0x00E) -#define HFI_CMD_SESSION_CVP_START \ - (HFI_DOMAIN_BASE_CVP + HFI_ARCH_COMMON_OFFSET + \ - HFI_CMD_START_OFFSET + 0x1000) -#define HFI_CMD_SESSION_REGISTER_BUFFERS \ - (HFI_CMD_SESSION_CVP_START + 0x0A0) -#define HFI_CMD_SESSION_UNREGISTER_BUFFERS \ - (HFI_CMD_SESSION_CVP_START + 0x0A1) - #define HFI_MSG_SYS_OX_START \ (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_MSG_START_OFFSET + 0x0000) #define HFI_MSG_SYS_SESSION_ABORT_DONE (HFI_MSG_SYS_OX_START + 0x4) @@ -353,14 +345,6 @@ struct hfi_uncompressed_plane_actual_constraints_info { #define HFI_MSG_SESSION_RELEASE_BUFFERS_DONE \ (HFI_MSG_SESSION_OX_START + 0xC) -#define HFI_MSG_SESSION_CVP_START \ - (HFI_DOMAIN_BASE_CVP + HFI_ARCH_COMMON_OFFSET + \ - HFI_MSG_START_OFFSET + 0x1000) -#define HFI_MSG_SESSION_REGISTER_BUFFERS_DONE \ - (HFI_MSG_SESSION_CVP_START + 0x0A0) -#define HFI_MSG_SESSION_UNREGISTER_BUFFERS_DONE \ - (HFI_MSG_SESSION_CVP_START + 0x0A1) - #define VIDC_IFACEQ_MAX_PKT_SIZE 1024 #define VIDC_IFACEQ_MED_PKT_SIZE 768 #define VIDC_IFACEQ_MIN_PKT_SIZE 8 @@ -689,22 +673,6 @@ struct hfi_msg_session_release_buffers_done_packet { u32 rg_buffer_info[1]; }; -struct hfi_msg_session_register_buffers_done_packet { - u32 size; - u32 packet_type; - u32 sid; - u32 client_data; - u32 error_type; -}; - -struct hfi_msg_session_unregister_buffers_done_packet { - u32 size; - u32 packet_type; - u32 sid; - u32 client_data; - u32 error_type; -}; - struct hfi_extradata_mb_quantization_payload { u8 rg_mb_qp[1]; }; diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index ee2bb6614785..4231681f79b3 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -6,11 +6,6 @@ #ifndef __VIDC_HFI_API_H__ #define __VIDC_HFI_API_H__ -#include -#include -#include -#include -#include #include "msm_vidc.h" #include "msm_vidc_resources.h" @@ -90,7 +85,6 @@ enum hal_domain { HAL_VIDEO_DOMAIN_VPE = BIT(0), HAL_VIDEO_DOMAIN_ENCODER = BIT(1), HAL_VIDEO_DOMAIN_DECODER = BIT(2), - HAL_VIDEO_DOMAIN_CVP = BIT(3), HAL_UNUSED_DOMAIN = 0x10000000, }; @@ -132,8 +126,6 @@ enum hal_video_codec { HAL_VIDEO_CODEC_VP8 = 0x00001000, HAL_VIDEO_CODEC_HEVC = 0x00002000, HAL_VIDEO_CODEC_VP9 = 0x00004000, - HAL_VIDEO_CODEC_TME = 0x00008000, - HAL_VIDEO_CODEC_CVP = 0x00010000, HAL_VIDEO_CODEC_HEVC_HYBRID = 0x80000000, HAL_UNUSED_CODEC = 0x10000000, }; @@ -342,24 +334,6 @@ struct vidc_resource_hdr { void *resource_handle; }; -struct vidc_register_buffer { - enum hal_buffer type; - u32 index; - u32 size; - u32 device_addr; - u32 response_required; - u32 client_data; -}; - -struct vidc_unregister_buffer { - enum hal_buffer type; - u32 index; - u32 size; - u32 device_addr; - u32 response_required; - u32 client_data; -}; - struct vidc_buffer_addr_info { enum hal_buffer buffer_type; u32 buffer_size; @@ -493,8 +467,6 @@ enum hal_command_response { HAL_SESSION_SET_PROP_DONE, HAL_SESSION_GET_PROP_DONE, HAL_SESSION_RELEASE_BUFFER_DONE, - HAL_SESSION_REGISTER_BUFFER_DONE, - HAL_SESSION_UNREGISTER_BUFFER_DONE, HAL_SESSION_RELEASE_RESOURCE_DONE, HAL_SESSION_PROPERTY_INFO, HAL_SESSION_ERROR, @@ -592,8 +564,6 @@ struct msm_vidc_cb_cmd_done { struct vidc_hal_fbd fbd; struct vidc_hal_sys_init_done sys_init_done; struct hal_buffer_info buffer_info; - struct vidc_register_buffer regbuf; - struct vidc_unregister_buffer unregbuf; union hal_get_property property; enum hal_flush flush_type; } data; @@ -693,10 +663,6 @@ struct hfi_device { struct vidc_buffer_addr_info *buffer_info); int (*session_release_buffers)(void *sess, struct vidc_buffer_addr_info *buffer_info); - int (*session_register_buffer)(void *sess, - struct vidc_register_buffer *buffer); - int (*session_unregister_buffer)(void *sess, - struct vidc_unregister_buffer *buffer); int (*session_load_res)(void *sess); int (*session_release_res)(void *sess); int (*session_start)(void *sess); diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index 02c3619333a1..5231513650d0 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -6,21 +6,19 @@ #ifndef __H_VIDC_HFI_HELPER_H__ #define __H_VIDC_HFI_HELPER_H__ -#include #include + #define HFI_COMMON_BASE (0) #define HFI_OX_BASE (0x01000000) #define HFI_VIDEO_DOMAIN_ENCODER (HFI_COMMON_BASE + 0x1) #define HFI_VIDEO_DOMAIN_DECODER (HFI_COMMON_BASE + 0x2) #define HFI_VIDEO_DOMAIN_VPE (HFI_COMMON_BASE + 0x4) -#define HFI_VIDEO_DOMAIN_CVP (HFI_COMMON_BASE + 0x8) #define HFI_DOMAIN_BASE_COMMON (HFI_COMMON_BASE + 0) #define HFI_DOMAIN_BASE_VDEC (HFI_COMMON_BASE + 0x01000000) #define HFI_DOMAIN_BASE_VENC (HFI_COMMON_BASE + 0x02000000) #define HFI_DOMAIN_BASE_VPE (HFI_COMMON_BASE + 0x03000000) -#define HFI_DOMAIN_BASE_CVP (HFI_COMMON_BASE + 0x04000000) #define HFI_VIDEO_ARCH_OX (HFI_COMMON_BASE + 0x1) @@ -76,8 +74,6 @@ #define HFI_VIDEO_CODEC_VP8 0x00001000 #define HFI_VIDEO_CODEC_HEVC 0x00002000 #define HFI_VIDEO_CODEC_VP9 0x00004000 -#define HFI_VIDEO_CODEC_TME 0x00008000 -#define HFI_VIDEO_CODEC_CVP 0x00010000 #define HFI_PROFILE_UNKNOWN 0x00000000 #define HFI_LEVEL_UNKNOWN 0x00000000 @@ -964,26 +960,6 @@ struct hfi_buffer_mapping_type { u32 size; }; -struct hfi_cmd_session_register_buffers_packet { - u32 size; - u32 packet_type; - u32 sid; - u32 client_data; - u32 response_req; - u32 num_buffers; - struct hfi_buffer_mapping_type buffer[1]; -}; - -struct hfi_cmd_session_unregister_buffers_packet { - u32 size; - u32 packet_type; - u32 sid; - u32 client_data; - u32 response_req; - u32 num_buffers; - struct hfi_buffer_mapping_type buffer[1]; -}; - struct hfi_cmd_session_sync_process_packet { u32 size; u32 packet_type; From 3ef057136aae66f0d101fd538c0dc585fb896d95 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Thu, 24 Oct 2019 11:13:04 -0700 Subject: [PATCH 165/452] msm: vidc: Migrate to icc API to set bus bandwidth - msm-bus API is deprecated in favor of upstream interconnect API - Migrate all msm-bus functions to interconnect (icc) API - Remove msm-bus sub-device probing and parse interconnect fields from msm-vidc device tree Change-Id: Ibf08c52e001c5fde7e30d2aedbd3456a270f5b6c Signed-off-by: Mihir Ganu --- msm/vidc/hfi_common.c | 33 ++++---- msm/vidc/msm_v4l2_vidc.c | 9 --- msm/vidc/msm_vidc_bus.h | 2 +- msm/vidc/msm_vidc_debug.c | 28 ------- msm/vidc/msm_vidc_debug.h | 19 ----- msm/vidc/msm_vidc_internal.h | 1 + msm/vidc/msm_vidc_res_parse.c | 144 ++++++++++++++-------------------- msm/vidc/msm_vidc_resources.h | 8 +- 8 files changed, 77 insertions(+), 167 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 83202257e9f6..84c12622e100 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -824,15 +824,12 @@ static int __vote_bandwidth(struct bus_info *bus, unsigned long bw_kbps, u32 sid) { int rc = 0; - uint64_t ab = 0; - /* Bus Driver expects values in Bps */ - ab = bw_kbps * 1000; - s_vpr_p(sid, "Voting bus %s to ab %llu bps\n", bus->name, ab); - rc = msm_bus_scale_update_bw(bus->client, ab, 0); + s_vpr_p(sid, "Voting bus %s to ab %llu kbps\n", bus->name, bw_kbps); + rc = icc_set_bw(bus->path, kbps_to_icc(bw_kbps), 0); if (rc) s_vpr_e(sid, "Failed voting bus %s to ab %llu, rc=%d\n", - bus->name, ab, rc); + bus->name, bw_kbps, rc); return rc; } @@ -863,7 +860,7 @@ static int __vote_buses(struct venus_hfi_device *device, enum vidc_bus_type type; venus_hfi_for_each_bus(device, bus) { - if (bus && bus->client) { + if (bus && bus->path) { type = get_type_frm_name(bus->name); if (type == DDR) { @@ -3308,8 +3305,8 @@ static void __deinit_bus(struct venus_hfi_device *device) device->bus_vote = DEFAULT_BUS_VOTE; venus_hfi_for_each_bus_reverse(device, bus) { - msm_bus_scale_unregister(bus->client); - bus->client = NULL; + icc_put(bus->path); + bus->path = NULL; } } @@ -3322,21 +3319,21 @@ static int __init_bus(struct venus_hfi_device *device) return -EINVAL; venus_hfi_for_each_bus(device, bus) { - if (!strcmp(bus->mode, "msm-vidc-llcc")) { + if (!strcmp(bus->name, "venus-llcc")) { if (msm_vidc_syscache_disable) { - d_vpr_h("Skipping LLC bus init %s: %s\n", - bus->name, bus->mode); + d_vpr_h("Skipping LLC bus init: %s\n", + bus->name); continue; } } - bus->client = msm_bus_scale_register(bus->master, bus->slave, - bus->name, false); - if (IS_ERR_OR_NULL(bus->client)) { - rc = PTR_ERR(bus->client) ? - PTR_ERR(bus->client) : -EBADHANDLE; + bus->path = of_icc_get(bus->dev, bus->name); + if (IS_ERR_OR_NULL(bus->path)) { + rc = PTR_ERR(bus->path) ? + PTR_ERR(bus->path) : -EBADHANDLE; + d_vpr_e("Failed to register bus %s: %d\n", bus->name, rc); - bus->client = NULL; + bus->path = NULL; goto err_add_dev; } } diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index 04597f06b449..b91b61c4395f 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -404,7 +404,6 @@ static struct attribute_group msm_vidc_core_attr_group = { static const struct of_device_id msm_vidc_dt_match[] = { {.compatible = "qcom,msm-vidc"}, {.compatible = "qcom,msm-vidc,context-bank"}, - {.compatible = "qcom,msm-vidc,bus"}, {.compatible = "qcom,msm-vidc,mem-cdsp"}, {} }; @@ -581,11 +580,6 @@ static int msm_vidc_probe_context_bank(struct platform_device *pdev) return read_context_bank_resources_from_dt(pdev); } -static int msm_vidc_probe_bus(struct platform_device *pdev) -{ - return read_bus_resources_from_dt(pdev); -} - static int msm_vidc_probe(struct platform_device *pdev) { /* @@ -595,9 +589,6 @@ static int msm_vidc_probe(struct platform_device *pdev) */ if (of_device_is_compatible(pdev->dev.of_node, "qcom,msm-vidc")) { return msm_vidc_probe_vidc_device(pdev); - } else if (of_device_is_compatible(pdev->dev.of_node, - "qcom,msm-vidc,bus")) { - return msm_vidc_probe_bus(pdev); } else if (of_device_is_compatible(pdev->dev.of_node, "qcom,msm-vidc,context-bank")) { return msm_vidc_probe_context_bank(pdev); diff --git a/msm/vidc/msm_vidc_bus.h b/msm/vidc/msm_vidc_bus.h index 07a5371df699..bde59a0c53d1 100644 --- a/msm/vidc/msm_vidc_bus.h +++ b/msm/vidc/msm_vidc_bus.h @@ -194,7 +194,7 @@ static struct lut { }, }; -static inline u32 get_type_frm_name(char *name) +static inline u32 get_type_frm_name(const char *name) { if (!strcmp(name, "venus-llcc")) return LLCC; diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index 2f6792f50675..00c1bccfb7c5 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -807,34 +807,6 @@ void trace_msm_v4l2_vidc_buffer_event_end(char *event_type, u32 device_addr, (void) offset; } -int -msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib) -{ - (void) cl; - (void) ab; - (void) ib; - - return 0; -} - -struct msm_bus_client_handle dummy_cl; -struct msm_bus_client_handle* -msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name, - bool active_only) -{ - (void) mas; - (void) slv; - (void) name; - (void) active_only; - - return &dummy_cl; -} - -void msm_bus_scale_unregister(struct msm_bus_client_handle *cl) -{ - (void) cl; -} - void do_gettimeofday(struct timeval *__ddl_tv) { } diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index 3dbb4d25aadd..e8524f9789d8 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -50,25 +50,6 @@ void trace_msm_v4l2_vidc_buffer_event_end(char *event_type, u32 device_addr, // void disable_irq_nosync(unsigned int irq); // void enable_irq(unsigned int irq); -struct msm_bus_client_handle { - char *name; - int mas; - int slv; - int first_hop; - // struct device *mas_dev; - u64 cur_act_ib; - u64 cur_act_ab; - u64 cur_dual_ib; - u64 cur_dual_ab; - bool active_only; -}; - -int msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib); -int msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib); -struct msm_bus_client_handle* msm_bus_scale_register(uint32_t mas, uint32_t slv, - char *name, bool active_only); -void msm_bus_scale_unregister(struct msm_bus_client_handle *cl); - void do_gettimeofday(struct timeval *__ddl_tv); #ifndef CONFIG_VIDEOBUF2_CORE diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 22102d76607e..ffb44f46431b 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "msm_vidc.h" #include #include "vidc_hfi_api.h" diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 6bc9aa61ce95..12808c8ef847 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -69,10 +69,9 @@ static inline void msm_vidc_free_qdss_addr_table( res->qdss_addr_set.addr_tbl = NULL; } -static inline void msm_vidc_free_bus_vectors( +static inline void msm_vidc_free_bus_table( struct msm_vidc_platform_resources *res) { - kfree(res->bus_set.bus_tbl); res->bus_set.bus_tbl = NULL; res->bus_set.count = 0; } @@ -114,7 +113,7 @@ void msm_vidc_free_platform_resources( msm_vidc_free_allowed_clocks_table(res); msm_vidc_free_reg_table(res); msm_vidc_free_qdss_addr_table(res); - msm_vidc_free_bus_vectors(res); + msm_vidc_free_bus_table(res); msm_vidc_free_buffer_usage_table(res); } @@ -360,76 +359,64 @@ static int msm_vidc_populate_mem_cdsp(struct device *dev, return 0; } -static int msm_vidc_populate_bus(struct device *dev, - struct msm_vidc_platform_resources *res) +static int msm_vidc_load_bus_table(struct msm_vidc_platform_resources *res) { struct bus_set *buses = &res->bus_set; - const char *temp_name = NULL; - struct bus_info *bus = NULL, *temp_table; - u32 range[2]; - int rc = 0; + int c = 0, num_buses = 0, rc = 0; + u32 *bus_ranges = NULL; + struct platform_device *pdev = res->pdev; - temp_table = krealloc(buses->bus_tbl, sizeof(*temp_table) * - (buses->count + 1), GFP_KERNEL); - if (!temp_table) { - d_vpr_e("%s: Failed to allocate memory", __func__); + num_buses = of_property_count_strings(pdev->dev.of_node, + "interconnect-names"); + if (num_buses <= 0) { + d_vpr_e("No buses found\n"); + return -EINVAL; + } + + buses->count = num_buses; + d_vpr_h("Found %d bus interconnects\n", num_buses); + + bus_ranges = kzalloc(2 * num_buses * sizeof(*bus_ranges), GFP_KERNEL); + if (!bus_ranges) { + d_vpr_e("No memory to read bus ranges\n"); + return -ENOMEM; + } + + rc = of_property_read_u32_array(pdev->dev.of_node, + "qcom,bus-range-kbps", bus_ranges, + num_buses); + if (rc) { + d_vpr_e( + "Failed to read bus ranges: defaulting to <0 INT_MAX>\n"); + for (c = 0; c < num_buses; c++) { + bus_ranges[c * 2] = 0; + bus_ranges[c * 2 + 1] = INT_MAX; + } + } + + buses->bus_tbl = devm_kzalloc(&pdev->dev, num_buses * + sizeof(*buses->bus_tbl), GFP_KERNEL); + if (!buses->bus_tbl) { + d_vpr_e("No memory for bus table\n"); rc = -ENOMEM; - goto err_bus; + goto exit; } - buses->bus_tbl = temp_table; - bus = &buses->bus_tbl[buses->count]; + for (c = 0; c < num_buses; c++) { + struct bus_info *bus = &res->bus_set.bus_tbl[c]; - memset(bus, 0x0, sizeof(struct bus_info)); + of_property_read_string_index(pdev->dev.of_node, + "interconnect-names", c, &bus->name); - rc = of_property_read_string(dev->of_node, "label", &temp_name); - if (rc) { - d_vpr_e("'label' not found in node\n"); - goto err_bus; - } - /* need a non-const version of name, hence copying it over */ - bus->name = devm_kstrdup(dev, temp_name, GFP_KERNEL); - if (!bus->name) { - rc = -ENOMEM; - goto err_bus; + bus->dev = &pdev->dev; + bus->range[0] = bus_ranges[c * 2]; + bus->range[1] = bus_ranges[c * 2 + 1]; + + d_vpr_h("Found bus %s\n", bus->name); } - rc = of_property_read_u32(dev->of_node, "qcom,bus-master", - &bus->master); - if (rc) { - d_vpr_e("'bus-master' not found in node\n"); - goto err_bus; - } - - rc = of_property_read_u32(dev->of_node, "qcom,bus-slave", &bus->slave); - if (rc) { - d_vpr_e("'bus-slave' not found in node\n"); - goto err_bus; - } - - rc = of_property_read_string(dev->of_node, "qcom,mode", - &bus->mode); - - if (!rc && !strcmp(bus->mode, "performance")) - bus->is_prfm_mode = true; - - rc = of_property_read_u32_array(dev->of_node, "qcom,bus-range-kbps", - range, ARRAY_SIZE(range)); - if (rc) { - rc = 0; - d_vpr_h("'bus-range' not found defaulting to <0 INT_MAX>\n"); - range[0] = 0; - range[1] = INT_MAX; - } - - bus->range[0] = range[0]; /* min */ - bus->range[1] = range[1]; /* max */ - - buses->count++; - bus->dev = dev; - d_vpr_h("Found bus %s [%d->%d] with mode %s\n", - bus->name, bus->master, bus->slave, bus->mode); -err_bus: +exit: + kfree(bus_ranges); return rc; } @@ -875,6 +862,12 @@ int read_platform_resources_from_dt( goto err_load_regulator_table; } + rc = msm_vidc_load_bus_table(res); + if (rc) { + d_vpr_e("Failed to load bus table: %d\n", rc); + goto err_load_bus_table; + } + rc = msm_vidc_load_clock_table(res); if (rc) { d_vpr_e("Failed to load clock table: %d\n", rc); @@ -908,6 +901,8 @@ return rc; err_load_allowed_clocks_table: msm_vidc_free_clock_table(res); err_load_clock_table: + msm_vidc_free_bus_table(res); +err_load_bus_table: msm_vidc_free_regulator_table(res); err_load_regulator_table: msm_vidc_free_buffer_usage_table(res); @@ -1187,29 +1182,6 @@ int read_context_bank_resources_from_dt(struct platform_device *pdev) return rc; } -int read_bus_resources_from_dt(struct platform_device *pdev) -{ - struct msm_vidc_core *core; - - if (!pdev) { - d_vpr_e("Invalid platform device\n"); - return -EINVAL; - } else if (!pdev->dev.parent) { - d_vpr_e("Failed to find a parent for %s\n", - dev_name(&pdev->dev)); - return -ENODEV; - } - - core = dev_get_drvdata(pdev->dev.parent); - if (!core) { - d_vpr_e("Failed to find cookie in parent device %s", - dev_name(pdev->dev.parent)); - return -EINVAL; - } - - return msm_vidc_populate_bus(&pdev->dev, &core->resources); -} - int read_mem_cdsp_resources_from_dt(struct platform_device *pdev) { struct msm_vidc_core *core; diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 3c1ecec57ea6..a64575d189e7 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -77,14 +77,10 @@ struct clock_set { }; struct bus_info { - char *name; - int master; - int slave; + const char *name; unsigned int range[2]; struct device *dev; - struct msm_bus_client_handle *client; - bool is_prfm_mode; - const char *mode; + struct icc_path *path; }; struct bus_set { From 1ab80e3c13a5c39a1f60b9a99f83498b23625dc9 Mon Sep 17 00:00:00 2001 From: Karthikeyan Periasamy Date: Wed, 30 Oct 2019 13:34:59 -0700 Subject: [PATCH 166/452] msm: vidc: ar50 and iris1 no longer needed ar50 and iris1 are no longer used. Deleting the unused code pieces and files. Change-Id: I01fab64b5e3682338fc0ffab986e7807a74c37b5 Signed-off-by: Karthikeyan Periasamy --- msm/Makefile | 3 - msm/vidc/hfi_ar50.c | 13 - msm/vidc/hfi_common.c | 260 ++++---------- msm/vidc/hfi_common.h | 13 +- msm/vidc/hfi_iris1.c | 51 --- msm/vidc/msm_vidc_bus_iris1.c | 644 ---------------------------------- msm/vidc/msm_vidc_clocks.c | 405 +-------------------- 7 files changed, 79 insertions(+), 1310 deletions(-) delete mode 100644 msm/vidc/hfi_ar50.c delete mode 100644 msm/vidc/hfi_iris1.c delete mode 100644 msm/vidc/msm_vidc_bus_iris1.c diff --git a/msm/Makefile b/msm/Makefile index b9d8a7171758..db567398a19f 100644 --- a/msm/Makefile +++ b/msm/Makefile @@ -12,15 +12,12 @@ msm-vidc-objs := vidc/msm_v4l2_vidc.o \ vidc/msm_vidc_debug.o \ vidc/msm_vidc_res_parse.o \ vidc/hfi_common.o \ - vidc/hfi_ar50.o \ vidc/hfi_ar50_lt.o \ - vidc/hfi_iris1.o \ vidc/hfi_iris2.o \ vidc/hfi_response_handler.o \ vidc/hfi_packetization.o \ vidc/vidc_hfi.o \ vidc/msm_vidc_clocks.o \ - vidc/msm_vidc_bus_iris1.o \ vidc/msm_vidc_bus_iris2.o \ vidc/msm_vidc_buffer_calculations.o diff --git a/msm/vidc/hfi_ar50.c b/msm/vidc/hfi_ar50.c deleted file mode 100644 index 55f3f5ee9247..000000000000 --- a/msm/vidc/hfi_ar50.c +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. - */ - -#include "hfi_common.h" -#include "hfi_io_common.h" - -void __interrupt_init_ar50(struct venus_hfi_device *device, u32 sid) -{ - __write_register(device, WRAPPER_INTR_MASK, - WRAPPER_INTR_MASK_A2HVCODEC_BMSK, sid); -} diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 83202257e9f6..f47ca5b3c6ab 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -80,30 +80,8 @@ static int __disable_subcaches(struct venus_hfi_device *device, u32 sid); static int __power_collapse(struct venus_hfi_device *device, bool force); static int venus_hfi_noc_error_info(void *dev); static int __set_ubwc_config(struct venus_hfi_device *device); -static void __power_off_common(struct venus_hfi_device *device); -static int __prepare_pc_common(struct venus_hfi_device *device); -static void __raise_interrupt_common(struct venus_hfi_device *device, u32 sid); static bool __watchdog_common(u32 intr_status); static void __noc_error_info_common(struct venus_hfi_device *device); -static void __core_clear_interrupt_common(struct venus_hfi_device *device); -static inline int __boot_firmware_common( - struct venus_hfi_device *device, u32 sid); -static void __setup_ucregion_memory_map_common( - struct venus_hfi_device *device, u32 sid); - -struct venus_hfi_vpu_ops vpu4_ops = { - .interrupt_init = __interrupt_init_ar50, - .setup_ucregion_memmap = __setup_ucregion_memory_map_common, - .clock_config_on_enable = NULL, - .reset_ahb2axi_bridge = NULL, - .power_off = __power_off_common, - .prepare_pc = __prepare_pc_common, - .raise_interrupt = __raise_interrupt_common, - .watchdog = __watchdog_common, - .noc_error_info = __noc_error_info_common, - .core_clear_interrupt = __core_clear_interrupt_common, - .boot_firmware = __boot_firmware_common, -}; struct venus_hfi_vpu_ops ar50_lite_ops = { .interrupt_init = __interrupt_init_ar50_lt, @@ -119,20 +97,6 @@ struct venus_hfi_vpu_ops ar50_lite_ops = { .boot_firmware = __boot_firmware_ar50_lt, }; -struct venus_hfi_vpu_ops iris1_ops = { - .interrupt_init = __interrupt_init_iris1, - .setup_ucregion_memmap = __setup_ucregion_memory_map_iris1, - .clock_config_on_enable = __clock_config_on_enable_iris1, - .reset_ahb2axi_bridge = __reset_ahb2axi_bridge_common, - .power_off = __power_off_common, - .prepare_pc = __prepare_pc_common, - .raise_interrupt = __raise_interrupt_common, - .watchdog = __watchdog_common, - .noc_error_info = __noc_error_info_common, - .core_clear_interrupt = __core_clear_interrupt_common, - .boot_firmware = __boot_firmware_common, -}; - struct venus_hfi_vpu_ops iris2_ops = { .interrupt_init = __interrupt_init_iris2, .setup_ucregion_memmap = __setup_ucregion_memory_map_iris2, @@ -151,6 +115,70 @@ struct venus_hfi_vpu_ops iris2_ops = { * Utility function to enforce some of our assumptions. Spam calls to this * in hotspots in code to double check some of the assumptions that we hold. */ + +struct lut const *__lut(int width, int height, int fps) +{ + int frame_size = height * width, c = 0; + + do { + if (LUT[c].frame_size >= frame_size && LUT[c].frame_rate >= fps) + return &LUT[c]; + } while (++c < ARRAY_SIZE(LUT)); + + return &LUT[ARRAY_SIZE(LUT) - 1]; +} + +fp_t __compression_ratio(struct lut const *entry, int bpp) +{ + int c = 0; + + for (c = 0; c < COMPRESSION_RATIO_MAX; ++c) { + if (entry->compression_ratio[c].bpp == bpp) + return entry->compression_ratio[c].ratio; + } + + WARN(true, "Shouldn't be here, LUT possibly corrupted?\n"); + return FP_ZERO; /* impossible */ +} + + +void __dump(struct dump dump[], int len, u32 sid) +{ + int c = 0; + + for (c = 0; c < len; ++c) { + char format_line[128] = "", formatted_line[128] = ""; + + if (dump[c].val == DUMP_HEADER_MAGIC) { + snprintf(formatted_line, sizeof(formatted_line), "%s\n", + dump[c].key); + } else { + bool fp_format = !strcmp(dump[c].format, DUMP_FP_FMT); + + if (!fp_format) { + snprintf(format_line, sizeof(format_line), + " %-35s: %s\n", dump[c].key, + dump[c].format); + snprintf(formatted_line, sizeof(formatted_line), + format_line, dump[c].val); + } else { + size_t integer_part, fractional_part; + + integer_part = fp_int(dump[c].val); + fractional_part = fp_frac(dump[c].val); + snprintf(formatted_line, sizeof(formatted_line), + " %-35s: %zd + %zd/%zd\n", + dump[c].key, integer_part, + fractional_part, + fp_frac_base()); + + + } + } + s_vpr_b(sid, "%s", formatted_line); + } +} + static inline void __strict_check(struct venus_hfi_device *device) { msm_vidc_res_handle_fatal_hw_error(device->res, @@ -1008,34 +1036,6 @@ static int __tzbsp_set_video_state(enum tzbsp_video_state state, u32 sid) return 0; } -static inline int __boot_firmware_common( - struct venus_hfi_device *device, u32 sid) -{ - int rc = 0; - u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 1000; - - ctrl_init_val = BIT(0); - - __write_register(device, CTRL_INIT, ctrl_init_val, sid); - while (!ctrl_status && count < max_tries) { - ctrl_status = __read_register(device, CTRL_STATUS, sid); - if ((ctrl_status & CTRL_ERROR_STATUS__M) == 0x4) { - s_vpr_e(sid, "invalid setting for UC_REGION\n"); - break; - } - - usleep_range(50, 100); - count++; - } - - if (count >= max_tries) { - s_vpr_e(sid, "Error booting up vidc firmware\n"); - rc = -ETIME; - } - - return rc; -} - static int venus_hfi_suspend(void *dev) { int rc = 0; @@ -1232,12 +1232,6 @@ static int __iface_cmdq_write_relaxed(struct venus_hfi_device *device, return result; } -static void __raise_interrupt_common(struct venus_hfi_device *device, u32 sid) -{ - __write_register(device, CPU_IC_SOFTINT, - 1 << CPU_IC_SOFTINT_H2A_SHFT, sid); -} - static int __iface_cmdq_write(struct venus_hfi_device *device, void *pkt, u32 sid) { @@ -1449,23 +1443,6 @@ static int __get_qdss_iommu_virtual_addr(struct venus_hfi_device *dev, return rc; } -static void __setup_ucregion_memory_map_common(struct venus_hfi_device *device, - u32 sid) -{ - __write_register(device, UC_REGION_ADDR, - (u32)device->iface_q_table.align_device_addr, sid); - __write_register(device, UC_REGION_SIZE, SHARED_QSIZE, sid); - __write_register(device, QTBL_ADDR, - (u32)device->iface_q_table.align_device_addr, sid); - __write_register(device, QTBL_INFO, 0x01, sid); - if (device->sfr.align_device_addr) - __write_register(device, SFR_ADDR, - (u32)device->sfr.align_device_addr, sid); - if (device->qdss.align_device_addr) - __write_register(device, MMAP_ADDR, - (u32)device->qdss.align_device_addr, sid); -} - static int __interface_queues_init(struct venus_hfi_device *dev) { struct hfi_queue_table_header *q_tbl_hdr; @@ -1822,33 +1799,6 @@ static int __get_q_size(struct venus_hfi_device *dev, unsigned int q_index) return read_ptr - write_ptr; } -static void __core_clear_interrupt_common(struct venus_hfi_device *device) -{ - u32 intr_status = 0, mask = 0; - - if (!device) { - d_vpr_e("%s: NULL device\n", __func__); - return; - } - - intr_status = __read_register(device, WRAPPER_INTR_STATUS, DEFAULT_SID); - mask = (WRAPPER_INTR_STATUS_A2H_BMSK | - WRAPPER_INTR_STATUS_A2HWD_BMSK | - CTRL_INIT_IDLE_MSG_BMSK); - - if (intr_status & mask) { - device->intr_status |= intr_status; - device->reg_count++; - d_vpr_l("INTERRUPT: times: %d interrupt_status: %d\n", - device->reg_count, intr_status); - } else { - device->spur_count++; - } - - __write_register(device, CPU_CS_A2HSOFTINTCLR, 1, DEFAULT_SID); - __write_register(device, WRAPPER_INTR_CLEAR, intr_status, DEFAULT_SID); -} - static int venus_hfi_core_trigger_ssr(void *device, enum hal_ssr_trigger_type type) { @@ -2585,59 +2535,6 @@ static void venus_hfi_pm_handler(struct work_struct *work) } } -static int __prepare_pc_common(struct venus_hfi_device *device) -{ - int rc = 0; - u32 wfi_status = 0, idle_status = 0, pc_ready = 0; - u32 ctrl_status = 0; - int count = 0; - const int max_tries = 10; - - ctrl_status = __read_register(device, CTRL_STATUS, DEFAULT_SID); - pc_ready = ctrl_status & CTRL_STATUS_PC_READY; - idle_status = ctrl_status & BIT(30); - - if (pc_ready) { - d_vpr_h("Already in pc_ready state\n"); - return 0; - } - - wfi_status = BIT(0) & __read_register(device, - WRAPPER_CPU_STATUS, DEFAULT_SID); - if (!wfi_status || !idle_status) { - d_vpr_e("Skipping PC, wfi status not set\n"); - goto skip_power_off; - } - - rc = __prepare_pc(device); - if (rc) { - d_vpr_e("Failed __prepare_pc %d\n", rc); - goto skip_power_off; - } - - while (count < max_tries) { - wfi_status = BIT(0) & __read_register(device, - WRAPPER_CPU_STATUS, DEFAULT_SID); - ctrl_status = __read_register(device, CTRL_STATUS, DEFAULT_SID); - if (wfi_status && (ctrl_status & CTRL_STATUS_PC_READY)) - break; - usleep_range(150, 250); - count++; - } - - if (count == max_tries) { - d_vpr_e("Skip PC. Core is not in right state\n"); - goto skip_power_off; - } - - return rc; - -skip_power_off: - d_vpr_e("Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n", - wfi_status, idle_status, pc_ready, ctrl_status); - return -EAGAIN; -} - static int __power_collapse(struct venus_hfi_device *device, bool force) { int rc = 0; @@ -3918,27 +3815,6 @@ static int __venus_power_on(struct venus_hfi_device *device, u32 sid) return rc; } -static void __power_off_common(struct venus_hfi_device *device) -{ - if (!device->power_enabled) - return; - - if (!(device->intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK)) - disable_irq_nosync(device->hal_data->irq); - device->intr_status = 0; - - __disable_unprepare_clks(device); - if (call_venus_op(device, reset_ahb2axi_bridge, device, DEFAULT_SID)) - d_vpr_e("Failed to reset ahb2axi\n"); - - if (__disable_regulators(device)) - d_vpr_e("Failed to disable regulators\n"); - - if (__unvote_buses(device, DEFAULT_SID)) - d_vpr_e("Failed to unvote for buses\n"); - device->power_enabled = false; -} - static inline int __suspend(struct venus_hfi_device *device) { int rc = 0; @@ -4317,12 +4193,8 @@ static int __initialize_packetization(struct venus_hfi_device *device) void __init_venus_ops(struct venus_hfi_device *device) { - if (device->res->vpu_ver == VPU_VERSION_AR50) - device->vpu_ops = &vpu4_ops; - else if (device->res->vpu_ver == VPU_VERSION_AR50_LITE) - device->vpu_ops = &ar50_lite_ops; - else if (device->res->vpu_ver == VPU_VERSION_IRIS1) - device->vpu_ops = &iris1_ops; + if (device->res->vpu_ver == VPU_VERSION_AR50_LITE) + device->vpu_ops = &ar50_lite_ops; else device->vpu_ops = &iris2_ops; } diff --git a/msm/vidc/hfi_common.h b/msm/vidc/hfi_common.h index 5fedbd8a3792..94ba39ddd1f7 100644 --- a/msm/vidc/hfi_common.h +++ b/msm/vidc/hfi_common.h @@ -290,6 +290,10 @@ int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id, struct msm_vidc_platform_resources *res, hfi_cmd_response_callback callback); +struct lut const *__lut(int width, int height, int fps); +fp_t __compression_ratio(struct lut const *entry, int bpp); +void __dump(struct dump dump[], int len, u32 sid); + void __write_register(struct venus_hfi_device *device, u32 reg, u32 value, u32 sid); int __read_register(struct venus_hfi_device *device, u32 reg, u32 sid); @@ -299,15 +303,6 @@ int __unvote_buses(struct venus_hfi_device *device, u32 sid); int __reset_ahb2axi_bridge_common(struct venus_hfi_device *device, u32 sid); int __prepare_pc(struct venus_hfi_device *device); -/* AR50 specific */ -void __interrupt_init_ar50(struct venus_hfi_device *device, u32 sid); -/* IRIS1 specific */ -void __interrupt_init_iris1(struct venus_hfi_device *device, u32 sid); -void __setup_dsp_uc_memmap_iris1(struct venus_hfi_device *device); -void __clock_config_on_enable_iris1(struct venus_hfi_device *device, - u32 sid); -void __setup_ucregion_memory_map_iris1(struct venus_hfi_device *device, - u32 sid); /* IRIS2 specific */ void __interrupt_init_iris2(struct venus_hfi_device *device, u32 sid); void __setup_ucregion_memory_map_iris2(struct venus_hfi_device *device, diff --git a/msm/vidc/hfi_iris1.c b/msm/vidc/hfi_iris1.c deleted file mode 100644 index a8b8bc0aa88c..000000000000 --- a/msm/vidc/hfi_iris1.c +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. - */ - -#include "hfi_common.h" -#include "hfi_io_common.h" - -void __interrupt_init_iris1(struct venus_hfi_device *device, u32 sid) -{ - u32 mask_val = 0; - - /* All interrupts should be disabled initially 0x1F6 : Reset value */ - mask_val = __read_register(device, WRAPPER_INTR_MASK, sid); - - /* Write 0 to unmask CPU and WD interrupts */ - mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BMSK | - WRAPPER_INTR_MASK_A2HCPU_BMSK); - __write_register(device, WRAPPER_INTR_MASK, mask_val, sid); -} - -void __setup_ucregion_memory_map_iris1(struct venus_hfi_device *device, u32 sid) -{ - /* initialize CPU QTBL & UCREGION */ - __write_register(device, UC_REGION_ADDR, - (u32)device->iface_q_table.align_device_addr, sid); - __write_register(device, UC_REGION_SIZE, SHARED_QSIZE, sid); - __write_register(device, QTBL_ADDR, - (u32)device->iface_q_table.align_device_addr, sid); - __write_register(device, QTBL_INFO, 0x01, sid); - if (device->sfr.align_device_addr) - __write_register(device, SFR_ADDR, - (u32)device->sfr.align_device_addr, sid); - if (device->qdss.align_device_addr) - __write_register(device, MMAP_ADDR, - (u32)device->qdss.align_device_addr, sid); - - /* initialize DSP QTBL & UCREGION with CPU queues by default */ - __write_register(device, HFI_DSP_QTBL_ADDR, - (u32)device->iface_q_table.align_device_addr, sid); - __write_register(device, HFI_DSP_UC_REGION_ADDR, - (u32)device->iface_q_table.align_device_addr, sid); - __write_register(device, HFI_DSP_UC_REGION_SIZE, SHARED_QSIZE, sid); -} - -void __clock_config_on_enable_iris1(struct venus_hfi_device *device, u32 sid) -{ - __write_register(device, WRAPPER_CPU_CGC_DIS, 0, sid); - __write_register(device, WRAPPER_CPU_CLOCK_CONFIG, 0, sid); -} - diff --git a/msm/vidc/msm_vidc_bus_iris1.c b/msm/vidc/msm_vidc_bus_iris1.c deleted file mode 100644 index 6115ad846685..000000000000 --- a/msm/vidc/msm_vidc_bus_iris1.c +++ /dev/null @@ -1,644 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. - */ - -#include "msm_vidc_bus.h" -#include "msm_vidc_internal.h" - -struct lut const *__lut(int width, int height, int fps) -{ - int frame_size = height * width, c = 0; - - do { - if (LUT[c].frame_size >= frame_size && LUT[c].frame_rate >= fps) - return &LUT[c]; - } while (++c < ARRAY_SIZE(LUT)); - - return &LUT[ARRAY_SIZE(LUT) - 1]; -} - -fp_t __compression_ratio(struct lut const *entry, int bpp) -{ - int c = 0; - - for (c = 0; c < COMPRESSION_RATIO_MAX; ++c) { - if (entry->compression_ratio[c].bpp == bpp) - return entry->compression_ratio[c].ratio; - } - - WARN(true, "Shouldn't be here, LUT possibly corrupted?\n"); - return FP_ZERO; /* impossible */ -} - -void __dump(struct dump dump[], int len, u32 sid) -{ - int c = 0; - - for (c = 0; c < len; ++c) { - char format_line[128] = "", formatted_line[128] = ""; - - if (dump[c].val == DUMP_HEADER_MAGIC) { - snprintf(formatted_line, sizeof(formatted_line), "%s\n", - dump[c].key); - } else { - bool fp_format = !strcmp(dump[c].format, DUMP_FP_FMT); - - if (!fp_format) { - snprintf(format_line, sizeof(format_line), - " %-35s: %s\n", dump[c].key, - dump[c].format); - snprintf(formatted_line, sizeof(formatted_line), - format_line, dump[c].val); - } else { - size_t integer_part, fractional_part; - - integer_part = fp_int(dump[c].val); - fractional_part = fp_frac(dump[c].val); - snprintf(formatted_line, sizeof(formatted_line), - " %-35s: %zd + %zd/%zd\n", - dump[c].key, integer_part, - fractional_part, - fp_frac_base()); - - - } - } - s_vpr_b(sid, "%s", formatted_line); - } -} - -static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d) -{ - return 0; -} - -static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) -{ - /* - * XXX: Don't fool around with any of the hardcoded numbers unless you - * know /exactly/ what you're doing. Many of these numbers are - * measured heuristics and hardcoded numbers taken from the firmware. - */ - /* Decoder parameters */ - int width, height, lcu_size, fps, dpb_bpp; - bool unified_dpb_opb, dpb_compression_enabled = true, - opb_compression_enabled = false, - llc_ref_read_l2_cache_enabled = false, - llc_top_line_buf_enabled = false; - fp_t dpb_read_compression_factor, dpb_opb_scaling_ratio, - dpb_write_compression_factor, opb_write_compression_factor, - qsmmu_bw_overhead_factor; - bool is_h264_category = true; - - /* Derived parameters */ - int lcu_per_frame, collocated_bytes_per_lcu, tnbr_per_lcu; - unsigned long bitrate; - - fp_t bins_to_bit_factor, vsp_read_factor, vsp_write_factor, - dpb_factor, dpb_write_factor, - y_bw_no_ubwc_8bpp, y_bw_no_ubwc_10bpp, y_bw_10bpp_p010, - motion_vector_complexity = 0; - fp_t dpb_total = 0; - - /* Output parameters */ - struct { - fp_t vsp_read, vsp_write, collocated_read, collocated_write, - dpb_read, dpb_write, opb_read, opb_write, - line_buffer_read, line_buffer_write, - total; - } ddr = {0}; - - struct { - fp_t dpb_read, line_buffer_read, line_buffer_write, total; - } llc = {0}; - - unsigned long ret = 0; - unsigned int integer_part, frac_part; - - width = max(d->input_width, BASELINE_DIMENSIONS.width); - height = max(d->input_height, BASELINE_DIMENSIONS.height); - - fps = d->fps; - - lcu_size = d->lcu_size; - - dpb_bpp = d->num_formats >= 1 ? - __bpp(d->color_formats[0], d->sid) : INT_MAX; - - unified_dpb_opb = d->num_formats == 1; - - dpb_opb_scaling_ratio = fp_div(FP_INT(d->input_width * d->input_height), - FP_INT(d->output_width * d->output_height)); - - opb_compression_enabled = d->num_formats >= 2 && - __ubwc(d->color_formats[1]); - - /* - * convert q16 number into integer and fractional part upto 2 places. - * ex : 105752 / 65536 = 1.61; 1.61 in q16 = 105752; - * integer part = 105752 / 65536 = 1; - * reminder = 105752 - 1 * 65536 = 40216; - * fractional part = 40216 * 100 / 65536 = 61; - * now converto to fp(1, 61, 100) for below code. - */ - - integer_part = d->compression_ratio >> 16; - frac_part = - ((d->compression_ratio - (integer_part << 16)) * 100) >> 16; - - dpb_read_compression_factor = FP(integer_part, frac_part, 100); - - integer_part = d->complexity_factor >> 16; - frac_part = - ((d->complexity_factor - (integer_part << 16)) * 100) >> 16; - - motion_vector_complexity = FP(integer_part, frac_part, 100); - - dpb_write_compression_factor = dpb_read_compression_factor; - opb_write_compression_factor = opb_compression_enabled ? - dpb_write_compression_factor : FP_ONE; - - if (d->codec == HAL_VIDEO_CODEC_HEVC || - d->codec == HAL_VIDEO_CODEC_VP9) { - /* H264, VP8, MPEG2 use the same settings */ - /* HEVC, VP9 use the same setting */ - is_h264_category = false; - } - if (d->use_sys_cache) { - llc_ref_read_l2_cache_enabled = true; - if (is_h264_category) - llc_top_line_buf_enabled = true; - } - - /* Derived parameters setup */ - lcu_per_frame = DIV_ROUND_UP(width, lcu_size) * - DIV_ROUND_UP(height, lcu_size); - - bitrate = (d->bitrate + 1000000 - 1) / 1000000; - - bins_to_bit_factor = FP_INT(4); - vsp_write_factor = bins_to_bit_factor; - vsp_read_factor = bins_to_bit_factor + FP_INT(2); - - collocated_bytes_per_lcu = lcu_size == 16 ? 16 : - lcu_size == 32 ? 64 : 256; - - dpb_factor = FP(1, 50, 100); - dpb_write_factor = FP(1, 5, 100); - - tnbr_per_lcu = lcu_size == 16 ? 128 : - lcu_size == 32 ? 64 : 128; - - /* .... For DDR & LLC ...... */ - ddr.vsp_read = fp_div(fp_mult(FP_INT(bitrate), - vsp_read_factor), FP_INT(8)); - ddr.vsp_write = fp_div(fp_mult(FP_INT(bitrate), - vsp_write_factor), FP_INT(8)); - - ddr.collocated_read = fp_div(FP_INT(lcu_per_frame * - collocated_bytes_per_lcu * fps), FP_INT(bps(1))); - ddr.collocated_write = ddr.collocated_read; - - y_bw_no_ubwc_8bpp = fp_div(fp_mult( - FP_INT((int)(width * height)), FP_INT((int)fps)), - FP_INT(1000 * 1000)); - y_bw_no_ubwc_10bpp = fp_div(fp_mult(y_bw_no_ubwc_8bpp, FP_INT(256)), - FP_INT(192)); - y_bw_10bpp_p010 = y_bw_no_ubwc_8bpp * 2; - - ddr.dpb_read = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; - ddr.dpb_read = fp_div(fp_mult(ddr.dpb_read, - fp_mult(dpb_factor, motion_vector_complexity)), - dpb_read_compression_factor); - - ddr.dpb_write = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; - ddr.dpb_write = fp_div(fp_mult(ddr.dpb_write, - fp_mult(dpb_factor, dpb_write_factor)), - dpb_write_compression_factor); - - dpb_total = ddr.dpb_read + ddr.dpb_write; - - if (llc_ref_read_l2_cache_enabled) { - ddr.dpb_read = fp_div(ddr.dpb_read, is_h264_category ? - FP(1, 30, 100) : FP(1, 15, 100)); - llc.dpb_read = dpb_total - ddr.dpb_write - ddr.dpb_read; - } - - ddr.opb_read = FP_ZERO; - ddr.opb_write = unified_dpb_opb ? FP_ZERO : (dpb_bpp == 8 ? - y_bw_no_ubwc_8bpp : (opb_compression_enabled ? - y_bw_no_ubwc_10bpp : y_bw_10bpp_p010)); - ddr.opb_write = fp_div(fp_mult(dpb_factor, ddr.opb_write), - fp_mult(dpb_opb_scaling_ratio, opb_write_compression_factor)); - - ddr.line_buffer_read = FP_INT(tnbr_per_lcu * - lcu_per_frame * fps / bps(1)); - ddr.line_buffer_write = ddr.line_buffer_read; - if (llc_top_line_buf_enabled) { - llc.line_buffer_read = ddr.line_buffer_read; - llc.line_buffer_write = ddr.line_buffer_write; - ddr.line_buffer_write = ddr.line_buffer_read = FP_ZERO; - } - - ddr.total = ddr.vsp_read + ddr.vsp_write + - ddr.collocated_read + ddr.collocated_write + - ddr.dpb_read + ddr.dpb_write + - ddr.opb_read + ddr.opb_write + - ddr.line_buffer_read + ddr.line_buffer_write; - - qsmmu_bw_overhead_factor = FP(1, 3, 100); - - ddr.total = fp_mult(ddr.total, qsmmu_bw_overhead_factor); - llc.total = llc.dpb_read + llc.line_buffer_read + - llc.line_buffer_write + ddr.total; - - /* Dump all the variables for easier debugging */ - if (msm_vidc_debug & VIDC_BUS) { - struct dump dump[] = { - {"DECODER PARAMETERS", "", DUMP_HEADER_MAGIC}, - {"lcu size", "%d", lcu_size}, - {"dpb bitdepth", "%d", dpb_bpp}, - {"frame rate", "%d", fps}, - {"dpb/opb unified", "%d", unified_dpb_opb}, - {"dpb/opb downscaling ratio", DUMP_FP_FMT, - dpb_opb_scaling_ratio}, - {"dpb compression", "%d", dpb_compression_enabled}, - {"opb compression", "%d", opb_compression_enabled}, - {"dpb read compression factor", DUMP_FP_FMT, - dpb_read_compression_factor}, - {"dpb write compression factor", DUMP_FP_FMT, - dpb_write_compression_factor}, - {"frame width", "%d", width}, - {"frame height", "%d", height}, - {"llc ref read l2 cache enabled", "%d", - llc_ref_read_l2_cache_enabled}, - {"llc top line buf enabled", "%d", - llc_top_line_buf_enabled}, - - {"DERIVED PARAMETERS (1)", "", DUMP_HEADER_MAGIC}, - {"lcus/frame", "%d", lcu_per_frame}, - {"bitrate (Mbit/sec)", "%d", bitrate}, - {"bins to bit factor", DUMP_FP_FMT, bins_to_bit_factor}, - {"dpb write factor", DUMP_FP_FMT, dpb_write_factor}, - {"vsp read factor", DUMP_FP_FMT, vsp_read_factor}, - {"vsp write factor", DUMP_FP_FMT, vsp_write_factor}, - {"tnbr/lcu", "%d", tnbr_per_lcu}, - {"collocated bytes/LCU", "%d", collocated_bytes_per_lcu}, - {"bw for NV12 8bpc)", DUMP_FP_FMT, y_bw_no_ubwc_8bpp}, - {"bw for NV12 10bpc)", DUMP_FP_FMT, y_bw_no_ubwc_10bpp}, - - {"DERIVED PARAMETERS (2)", "", DUMP_HEADER_MAGIC}, - {"mv complexity", DUMP_FP_FMT, motion_vector_complexity}, - {"qsmmu_bw_overhead_factor", DUMP_FP_FMT, - qsmmu_bw_overhead_factor}, - - {"INTERMEDIATE DDR B/W", "", DUMP_HEADER_MAGIC}, - {"vsp read", DUMP_FP_FMT, ddr.vsp_read}, - {"vsp write", DUMP_FP_FMT, ddr.vsp_write}, - {"collocated read", DUMP_FP_FMT, ddr.collocated_read}, - {"collocated write", DUMP_FP_FMT, ddr.collocated_write}, - {"line buffer read", DUMP_FP_FMT, ddr.line_buffer_read}, - {"line buffer write", DUMP_FP_FMT, ddr.line_buffer_write}, - {"opb read", DUMP_FP_FMT, ddr.opb_read}, - {"opb write", DUMP_FP_FMT, ddr.opb_write}, - {"dpb read", DUMP_FP_FMT, ddr.dpb_read}, - {"dpb write", DUMP_FP_FMT, ddr.dpb_write}, - {"dpb total", DUMP_FP_FMT, dpb_total}, - {"INTERMEDIATE LLC B/W", "", DUMP_HEADER_MAGIC}, - {"llc dpb read", DUMP_FP_FMT, llc.dpb_read}, - {"llc line buffer read", DUMP_FP_FMT, llc.line_buffer_read}, - {"llc line buffer write", DUMP_FP_FMT, llc.line_buffer_write}, - - }; - __dump(dump, ARRAY_SIZE(dump), d->sid); - } - - d->calc_bw_ddr = kbps(fp_round(ddr.total)); - d->calc_bw_llcc = kbps(fp_round(llc.total)); - - return ret; -} - -static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) -{ - /* - * XXX: Don't fool around with any of the hardcoded numbers unless you - * know /exactly/ what you're doing. Many of these numbers are - * measured heuristics and hardcoded numbers taken from the firmware. - */ - /* Encoder Parameters */ - int width, height, fps, lcu_size, bitrate, lcu_per_frame, - collocated_bytes_per_lcu, tnbr_per_lcu, dpb_bpp, - original_color_format, vertical_tile_width; - bool work_mode_1, original_compression_enabled, - low_power, rotation, cropping_or_scaling, - b_frames_enabled = false, - llc_ref_chroma_cache_enabled = false, - llc_top_line_buf_enabled = false, - llc_vpss_rot_line_buf_enabled = false; - - fp_t bins_to_bit_factor, dpb_compression_factor, - original_compression_factor, - original_compression_factor_y, - y_bw_no_ubwc_8bpp, y_bw_no_ubwc_10bpp, y_bw_10bpp_p010, - input_compression_factor, - downscaling_ratio, - ref_y_read_bw_factor, ref_cbcr_read_bw_factor, - recon_write_bw_factor, mese_read_factor, - total_ref_read_crcb, - qsmmu_bw_overhead_factor; - fp_t integer_part, frac_part; - unsigned long ret = 0; - - /* Output parameters */ - struct { - fp_t vsp_read, vsp_write, collocated_read, collocated_write, - ref_read_y, ref_read_crcb, ref_write, - ref_write_overlap, orig_read, - line_buffer_read, line_buffer_write, - mese_read, mese_write, - total; - } ddr = {0}; - - struct { - fp_t ref_read_crcb, line_buffer, total; - } llc = {0}; - - /* Encoder Parameters setup */ - rotation = d->rotation; - cropping_or_scaling = false; - vertical_tile_width = 960; - recon_write_bw_factor = FP(1, 8, 100); - ref_y_read_bw_factor = FP(1, 30, 100); - ref_cbcr_read_bw_factor = FP(1, 50, 100); - - - /* Derived Parameters */ - fps = d->fps; - width = max(d->output_width, BASELINE_DIMENSIONS.width); - height = max(d->output_height, BASELINE_DIMENSIONS.height); - downscaling_ratio = fp_div(FP_INT(d->input_width * d->input_height), - FP_INT(d->output_width * d->output_height)); - downscaling_ratio = max(downscaling_ratio, FP_ONE); - bitrate = d->bitrate > 0 ? (d->bitrate + 1000000 - 1) / 1000000 : - __lut(width, height, fps)->bitrate; - lcu_size = d->lcu_size; - lcu_per_frame = DIV_ROUND_UP(width, lcu_size) * - DIV_ROUND_UP(height, lcu_size); - tnbr_per_lcu = 16; - - y_bw_no_ubwc_8bpp = fp_div(fp_mult( - FP_INT((int)(width * height)), FP_INT(fps)), - FP_INT(1000 * 1000)); - y_bw_no_ubwc_10bpp = fp_div(fp_mult(y_bw_no_ubwc_8bpp, - FP_INT(256)), FP_INT(192)); - y_bw_10bpp_p010 = y_bw_no_ubwc_8bpp * 2; - - b_frames_enabled = d->b_frames_enabled; - original_color_format = d->num_formats >= 1 ? - d->color_formats[0] : HAL_UNUSED_COLOR; - - dpb_bpp = d->num_formats >= 1 ? - __bpp(d->color_formats[0], d->sid) : INT_MAX; - - original_compression_enabled = __ubwc(original_color_format); - - work_mode_1 = d->work_mode == HFI_WORKMODE_1; - low_power = d->power_mode == VIDC_POWER_LOW; - bins_to_bit_factor = FP_INT(4); - - if (d->use_sys_cache) { - llc_ref_chroma_cache_enabled = true; - llc_top_line_buf_enabled = true, - llc_vpss_rot_line_buf_enabled = true; - } - - /* - * Convert Q16 number into Integer and Fractional part upto 2 places. - * Ex : 105752 / 65536 = 1.61; 1.61 in Q16 = 105752; - * Integer part = 105752 / 65536 = 1; - * Reminder = 105752 - 1 * 65536 = 40216; - * Fractional part = 40216 * 100 / 65536 = 61; - * Now converto to FP(1, 61, 100) for below code. - */ - - integer_part = d->compression_ratio >> 16; - frac_part = - ((d->compression_ratio - (integer_part * 65536)) * 100) >> 16; - - dpb_compression_factor = FP(integer_part, frac_part, 100); - - integer_part = d->input_cr >> 16; - frac_part = - ((d->input_cr - (integer_part * 65536)) * 100) >> 16; - - input_compression_factor = FP(integer_part, frac_part, 100); - - original_compression_factor = original_compression_factor_y = - !original_compression_enabled ? FP_ONE : - __compression_ratio(__lut(width, height, fps), dpb_bpp); - /* use input cr if it is valid (not 1), otherwise use lut */ - if (original_compression_enabled && - input_compression_factor != FP_ONE) { - original_compression_factor = input_compression_factor; - /* Luma usually has lower compression factor than Chroma, - * input cf is overall cf, add 1.08 factor for Luma cf - */ - original_compression_factor_y = - input_compression_factor > FP(1, 8, 100) ? - fp_div(input_compression_factor, FP(1, 8, 100)) : - input_compression_factor; - } - - mese_read_factor = fp_div(FP_INT((width * height * fps)/4), - original_compression_factor_y); - mese_read_factor = fp_div(fp_mult(mese_read_factor, FP(2, 53, 100)), - FP_INT(1000 * 1000)); - - ddr.vsp_read = fp_div(fp_mult(FP_INT(bitrate), bins_to_bit_factor), - FP_INT(8)); - ddr.vsp_write = ddr.vsp_read + fp_div(FP_INT(bitrate), FP_INT(8)); - - collocated_bytes_per_lcu = lcu_size == 16 ? 16 : - lcu_size == 32 ? 64 : 256; - - ddr.collocated_read = fp_div(FP_INT(lcu_per_frame * - collocated_bytes_per_lcu * fps), FP_INT(bps(1))); - - ddr.collocated_write = ddr.collocated_read; - - ddr.ref_read_y = ddr.ref_read_crcb = dpb_bpp == 8 ? - y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; - - if (width != vertical_tile_width) { - ddr.ref_read_y = fp_mult(ddr.ref_read_y, - ref_y_read_bw_factor); - } - - ddr.ref_read_y = fp_div(ddr.ref_read_y, dpb_compression_factor); - if (b_frames_enabled) - ddr.ref_read_y = fp_mult(ddr.ref_read_y, FP_INT(2)); - - ddr.ref_read_crcb = fp_mult(ddr.ref_read_crcb, FP(0, 50, 100)); - ddr.ref_read_crcb = fp_div(ddr.ref_read_crcb, dpb_compression_factor); - if (b_frames_enabled) - ddr.ref_read_crcb = fp_mult(ddr.ref_read_crcb, FP_INT(2)); - - if (llc_ref_chroma_cache_enabled) { - total_ref_read_crcb = ddr.ref_read_crcb; - ddr.ref_read_crcb = fp_div(ddr.ref_read_crcb, - ref_cbcr_read_bw_factor); - llc.ref_read_crcb = total_ref_read_crcb - ddr.ref_read_crcb; - } - - ddr.ref_write = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; - ddr.ref_write = fp_mult(ddr.ref_write, - (fp_div(FP(1, 50, 100), dpb_compression_factor))); - - ddr.ref_write_overlap = fp_div(fp_mult(ddr.ref_write, - (recon_write_bw_factor - FP_ONE)), - recon_write_bw_factor); - - ddr.orig_read = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : - (original_compression_enabled ? y_bw_no_ubwc_10bpp : - y_bw_10bpp_p010); - ddr.orig_read = fp_div(fp_mult(fp_mult(ddr.orig_read, FP(1, 50, 100)), - downscaling_ratio), original_compression_factor); - if (rotation == 90 || rotation == 270) - ddr.orig_read *= lcu_size == 32 ? (dpb_bpp == 8 ? 1 : 3) : 2; - - ddr.line_buffer_read = FP_INT(tnbr_per_lcu * lcu_per_frame * - fps / bps(1)); - - ddr.line_buffer_write = ddr.line_buffer_read; - if (llc_top_line_buf_enabled) { - llc.line_buffer = ddr.line_buffer_read + ddr.line_buffer_write; - ddr.line_buffer_read = ddr.line_buffer_write = FP_ZERO; - } - - ddr.mese_read = dpb_bpp == 8 ? y_bw_no_ubwc_8bpp : y_bw_no_ubwc_10bpp; - ddr.mese_read = fp_div(fp_mult(ddr.mese_read, FP(1, 37, 100)), - original_compression_factor_y) + mese_read_factor; - - ddr.mese_write = FP_INT((width * height)/512) + - fp_div(FP_INT((width * height)/4), - original_compression_factor_y) + - FP_INT((width * height)/128); - ddr.mese_write = fp_div(fp_mult(ddr.mese_write, FP_INT(fps)), - FP_INT(1000 * 1000)); - - ddr.total = ddr.vsp_read + ddr.vsp_write + - ddr.collocated_read + ddr.collocated_write + - ddr.ref_read_y + ddr.ref_read_crcb + - ddr.ref_write + ddr.ref_write_overlap + - ddr.orig_read + - ddr.line_buffer_read + ddr.line_buffer_write + - ddr.mese_read + ddr.mese_write; - - qsmmu_bw_overhead_factor = FP(1, 3, 100); - ddr.total = fp_mult(ddr.total, qsmmu_bw_overhead_factor); - llc.total = llc.ref_read_crcb + llc.line_buffer + ddr.total; - - if (msm_vidc_debug & VIDC_BUS) { - struct dump dump[] = { - {"ENCODER PARAMETERS", "", DUMP_HEADER_MAGIC}, - {"width", "%d", width}, - {"height", "%d", height}, - {"fps", "%d", fps}, - {"dpb bitdepth", "%d", dpb_bpp}, - {"input downscaling ratio", DUMP_FP_FMT, downscaling_ratio}, - {"rotation", "%d", rotation}, - {"cropping or scaling", "%d", cropping_or_scaling}, - {"low power mode", "%d", low_power}, - {"work Mode", "%d", work_mode_1}, - {"B frame enabled", "%d", b_frames_enabled}, - {"original frame format", "%#x", original_color_format}, - {"original compression enabled", "%d", - original_compression_enabled}, - {"dpb compression factor", DUMP_FP_FMT, - dpb_compression_factor}, - {"input compression factor", DUMP_FP_FMT, - input_compression_factor}, - {"llc ref chroma cache enabled", DUMP_FP_FMT, - llc_ref_chroma_cache_enabled}, - {"llc top line buf enabled", DUMP_FP_FMT, - llc_top_line_buf_enabled}, - {"llc vpss rot line buf enabled ", DUMP_FP_FMT, - llc_vpss_rot_line_buf_enabled}, - - {"DERIVED PARAMETERS", "", DUMP_HEADER_MAGIC}, - {"lcu size", "%d", lcu_size}, - {"bitrate (Mbit/sec)", "%lu", bitrate}, - {"bins to bit factor", DUMP_FP_FMT, bins_to_bit_factor}, - {"original compression factor", DUMP_FP_FMT, - original_compression_factor}, - {"original compression factor y", DUMP_FP_FMT, - original_compression_factor_y}, - {"mese read factor", DUMP_FP_FMT, - mese_read_factor}, - {"qsmmu_bw_overhead_factor", - DUMP_FP_FMT, qsmmu_bw_overhead_factor}, - {"bw for NV12 8bpc)", DUMP_FP_FMT, y_bw_no_ubwc_8bpp}, - {"bw for NV12 10bpc)", DUMP_FP_FMT, y_bw_no_ubwc_10bpp}, - - {"INTERMEDIATE B/W DDR", "", DUMP_HEADER_MAGIC}, - {"vsp read", DUMP_FP_FMT, ddr.vsp_read}, - {"vsp write", DUMP_FP_FMT, ddr.vsp_write}, - {"collocated read", DUMP_FP_FMT, ddr.collocated_read}, - {"collocated write", DUMP_FP_FMT, ddr.collocated_write}, - {"ref read y", DUMP_FP_FMT, ddr.ref_read_y}, - {"ref read crcb", DUMP_FP_FMT, ddr.ref_read_crcb}, - {"ref write", DUMP_FP_FMT, ddr.ref_write}, - {"ref write overlap", DUMP_FP_FMT, ddr.ref_write_overlap}, - {"original read", DUMP_FP_FMT, ddr.orig_read}, - {"line buffer read", DUMP_FP_FMT, ddr.line_buffer_read}, - {"line buffer write", DUMP_FP_FMT, ddr.line_buffer_write}, - {"mese read", DUMP_FP_FMT, ddr.mese_read}, - {"mese write", DUMP_FP_FMT, ddr.mese_write}, - {"INTERMEDIATE LLC B/W", "", DUMP_HEADER_MAGIC}, - {"llc ref read crcb", DUMP_FP_FMT, llc.ref_read_crcb}, - {"llc line buffer", DUMP_FP_FMT, llc.line_buffer}, - }; - __dump(dump, ARRAY_SIZE(dump), d->sid); - } - - d->calc_bw_ddr = kbps(fp_round(ddr.total)); - d->calc_bw_llcc = kbps(fp_round(llc.total)); - - return ret; -} - -static unsigned long __calculate(struct vidc_bus_vote_data *d) -{ - unsigned long value = 0; - - switch (d->domain) { - case HAL_VIDEO_DOMAIN_VPE: - value = __calculate_vpe(d); - break; - case HAL_VIDEO_DOMAIN_ENCODER: - value = __calculate_encoder(d); - break; - case HAL_VIDEO_DOMAIN_DECODER: - value = __calculate_decoder(d); - break; - default: - s_vpr_e(d->sid, "Unknown Domain %#x", d->domain); - } - - return value; -} - -int calc_bw_iris1(struct vidc_bus_vote_data *vidc_data) -{ - int ret = 0; - - if (!vidc_data) - return ret; - - ret = __calculate(vidc_data); - - return ret; -} - diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index da1f6002fa4e..a0fbdfd6bcec 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -16,30 +16,20 @@ #define MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO (1 << 16) #define MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO (5 << 16) -static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst); -static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, - u32 filled_len); -static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst, +static int msm_vidc_decide_work_mode_ar50_lt(struct msm_vidc_inst *inst); +static unsigned long msm_vidc_calc_freq_ar50_lt(struct msm_vidc_inst *inst, u32 filled_len); static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, u32 filled_len); -struct msm_vidc_core_ops core_ops_ar50 = { - .calc_freq = msm_vidc_calc_freq_ar50, +struct msm_vidc_core_ops core_ops_ar50_lt = { + .calc_freq = msm_vidc_calc_freq_ar50_lt, .decide_work_route = NULL, - .decide_work_mode = msm_vidc_decide_work_mode_ar50, + .decide_work_mode = msm_vidc_decide_work_mode_ar50_lt, .decide_core_and_power_mode = NULL, .calc_bw = NULL, }; -struct msm_vidc_core_ops core_ops_iris1 = { - .calc_freq = msm_vidc_calc_freq_iris1, - .decide_work_route = msm_vidc_decide_work_route_iris1, - .decide_work_mode = msm_vidc_decide_work_mode_iris1, - .decide_core_and_power_mode = msm_vidc_decide_core_and_power_mode_iris1, - .calc_bw = calc_bw_iris1, -}; - struct msm_vidc_core_ops core_ops_iris2 = { .calc_freq = msm_vidc_calc_freq_iris2, .decide_work_route = msm_vidc_decide_work_route_iris2, @@ -542,7 +532,7 @@ void msm_comm_update_input_cr(struct msm_vidc_inst *inst, mutex_unlock(&inst->input_crs.lock); } -static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, +static unsigned long msm_vidc_calc_freq_ar50_lt(struct msm_vidc_inst *inst, u32 filled_len) { u64 freq = 0, vpp_cycles = 0, vsp_cycles = 0; @@ -619,94 +609,6 @@ static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, return (unsigned long) freq; } -static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst, - u32 filled_len) -{ - u64 vsp_cycles = 0, vpp_cycles = 0, fw_cycles = 0, freq = 0; - u64 fw_vpp_cycles = 0; - u32 vpp_cycles_per_mb; - u32 mbs_per_second; - struct msm_vidc_core *core = NULL; - int i = 0; - struct allowed_clock_rates_table *allowed_clks_tbl = NULL; - u64 rate = 0, fps; - struct clock_data *dcvs = NULL; - u32 operating_rate, vsp_factor_num = 10, vsp_factor_den = 5; - - core = inst->core; - dcvs = &inst->clk_data; - - mbs_per_second = msm_comm_get_inst_load_per_core(inst, - LOAD_POWER); - - fps = msm_vidc_get_fps(inst); - - /* - * Calculate vpp, vsp, fw cycles separately for encoder and decoder. - * Even though, most part is common now, in future it may change - * between them. - */ - - fw_cycles = fps * inst->core->resources.fw_cycles; - fw_vpp_cycles = fps * inst->core->resources.fw_vpp_cycles; - - if (inst->session_type == MSM_VIDC_ENCODER) { - vpp_cycles_per_mb = inst->flags & VIDC_LOW_POWER ? - inst->clk_data.entry->low_power_cycles : - inst->clk_data.entry->vpp_cycles; - - vpp_cycles = mbs_per_second * vpp_cycles_per_mb / - inst->clk_data.work_route; - /* 21 / 20 is minimum overhead factor */ - vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles); - - vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; - - /* bitrate is based on fps, scale it using operating rate */ - operating_rate = inst->clk_data.operating_rate >> 16; - if (operating_rate > (inst->clk_data.frame_rate >> 16) && - (inst->clk_data.frame_rate >> 16)) { - vsp_factor_num *= operating_rate; - vsp_factor_den *= inst->clk_data.frame_rate >> 16; - } - vsp_cycles += ((u64)inst->clk_data.bitrate * vsp_factor_num) / - vsp_factor_den; - - } else if (inst->session_type == MSM_VIDC_DECODER) { - vpp_cycles = mbs_per_second * inst->clk_data.entry->vpp_cycles / - inst->clk_data.work_route; - /* 21 / 20 is minimum overhead factor */ - vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles); - - vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; - - /* vsp perf is about 0.5 bits/cycle */ - vsp_cycles += ((fps * filled_len * 8) * 10) / 5; - - } else { - s_vpr_e(inst->sid, "%s: Unknown session type\n", __func__); - return msm_vidc_max_freq(inst->core, inst->sid); - } - - freq = max(vpp_cycles, vsp_cycles); - freq = max(freq, fw_cycles); - - allowed_clks_tbl = core->resources.allowed_clks_tbl; - for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) { - rate = allowed_clks_tbl[i].clock_rate; - if (rate >= freq) - break; - } - - if (i < 0) - i = 0; - - s_vpr_p(inst->sid, "%s: inst %pK: filled len %d required freq %llu\n", - __func__, inst, filled_len, freq); - - return (unsigned long) freq; -} - static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, u32 filled_len) { @@ -1122,82 +1024,6 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) __func__); } -int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct hfi_device *hdev; - struct hfi_video_work_route pdata; - struct v4l2_format *f; - u32 codec; - - if (!inst || !inst->core || !inst->core->device) { - d_vpr_e("%s: Invalid args: Inst = %pK\n", - __func__, inst); - return -EINVAL; - } - - hdev = inst->core->device; - - pdata.video_work_route = 2; - codec = get_v4l2_codec(inst); - if (inst->session_type == MSM_VIDC_DECODER) { - switch (codec) { - case V4L2_PIX_FMT_MPEG2: - pdata.video_work_route = 1; - break; - case V4L2_PIX_FMT_H264: - if (inst->pic_struct != - MSM_VIDC_PIC_STRUCT_PROGRESSIVE) - pdata.video_work_route = 1; - break; - } - } else if (inst->session_type == MSM_VIDC_ENCODER) { - u32 slice_mode = 0; - u32 output_width, output_height, fps, mbps; - - switch (codec) { - case V4L2_PIX_FMT_VP8: - pdata.video_work_route = 1; - goto decision_done; - } - - if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) { - pdata.video_work_route = 2; - goto decision_done; - } - slice_mode = msm_comm_g_ctrl_for_id(inst, - V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); - f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; - output_height = f->fmt.pix_mp.height; - output_width = f->fmt.pix_mp.width; - fps = inst->clk_data.frame_rate >> 16; - mbps = NUM_MBS_PER_SEC(output_height, output_width, fps); - if (slice_mode == - V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES || - (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR && - mbps <= CBR_MB_LIMIT) || - (inst->rc_type == - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR && - mbps <= CBR_VFR_MB_LIMIT)) { - pdata.video_work_route = 1; - s_vpr_h(inst->sid, "Configured work route = 1"); - } - } else { - return -EINVAL; - } - -decision_done: - - inst->clk_data.work_route = pdata.video_work_route; - rc = call_hfi_op(hdev, session_set_property, - (void *)inst->session, HFI_PROPERTY_PARAM_WORK_ROUTE, - (void *)&pdata, sizeof(pdata)); - if (rc) - s_vpr_e(inst->sid, "Failed to configure work route\n"); - - return rc; -} - int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) { int rc = 0; @@ -1253,7 +1079,7 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) return rc; } -static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst) +static int msm_vidc_decide_work_mode_ar50_lt(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; @@ -1318,86 +1144,6 @@ static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst) return rc; } -int msm_vidc_decide_work_mode_iris1(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct hfi_device *hdev; - struct hfi_video_work_mode pdata; - struct hfi_enable latency; - u32 yuv_size = 0; - struct v4l2_format *f; - u32 codec; - - if (!inst || !inst->core || !inst->core->device) { - d_vpr_e("%s: Invalid args: Inst = %pK\n", - __func__, inst); - return -EINVAL; - } - - hdev = inst->core->device; - - if (inst->clk_data.low_latency_mode) { - pdata.video_work_mode = HFI_WORKMODE_1; - s_vpr_h(inst->sid, "Configured work mode = 1"); - goto decision_done; - } - - codec = get_v4l2_codec(inst); - if (inst->session_type == MSM_VIDC_DECODER) { - f = &inst->fmts[INPUT_PORT].v4l2_fmt; - pdata.video_work_mode = HFI_WORKMODE_2; - switch (codec) { - case V4L2_PIX_FMT_MPEG2: - pdata.video_work_mode = HFI_WORKMODE_1; - break; - case V4L2_PIX_FMT_H264: - case V4L2_PIX_FMT_HEVC: - case V4L2_PIX_FMT_VP8: - case V4L2_PIX_FMT_VP9: - yuv_size = f->fmt.pix_mp.height * f->fmt.pix_mp.width; - if ((inst->pic_struct != - MSM_VIDC_PIC_STRUCT_PROGRESSIVE) || - (yuv_size <= 1280 * 720)) - pdata.video_work_mode = HFI_WORKMODE_1; - break; - } - } else if (inst->session_type == MSM_VIDC_ENCODER) { - pdata.video_work_mode = HFI_WORKMODE_2; - - switch (codec) { - case V4L2_PIX_FMT_VP8: - pdata.video_work_mode = HFI_WORKMODE_1; - goto decision_done; - } - - } else { - return -EINVAL; - } - -decision_done: - - inst->clk_data.work_mode = pdata.video_work_mode; - rc = call_hfi_op(hdev, session_set_property, - (void *)inst->session, HFI_PROPERTY_PARAM_WORK_MODE, - (void *)&pdata, sizeof(pdata)); - if (rc) - s_vpr_e(inst->sid, "Failed to configure Work Mode %u\n", - pdata.video_work_mode); - - /* For WORK_MODE_1, set Low Latency mode by default to HW. */ - - if (inst->session_type == MSM_VIDC_ENCODER && - inst->clk_data.work_mode == HFI_WORKMODE_1) { - latency.enable = true; - rc = call_hfi_op(hdev, session_set_property, - (void *)inst->session, - HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE, - (void *)&latency, sizeof(latency)); - } - - return rc; -} - int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) { int rc = 0; @@ -1513,137 +1259,6 @@ static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, return rc; } -static int msm_vidc_move_core_to_power_save_mode(struct msm_vidc_core *core, - u32 core_id, u32 sid) -{ - struct msm_vidc_inst *inst = NULL; - - s_vpr_h(sid, "Core %d : Moving all inst to LP mode\n", core_id); - mutex_lock(&core->lock); - list_for_each_entry(inst, &core->instances, list) { - if (inst->clk_data.core_id == core_id && - inst->session_type == MSM_VIDC_ENCODER) - msm_vidc_power_save_mode_enable(inst, true); - } - mutex_unlock(&core->lock); - - return 0; -} - -static u32 get_core_load(struct msm_vidc_core *core, - u32 core_id, bool lp_mode, bool real_time) -{ - struct msm_vidc_inst *inst = NULL; - u32 current_inst_mbs_per_sec = 0, load = 0; - bool real_time_mode = false; - - mutex_lock(&core->lock); - list_for_each_entry(inst, &core->instances, list) { - u32 cycles, lp_cycles; - - real_time_mode = is_realtime_session(inst); - if (!(inst->clk_data.core_id & core_id)) - continue; - if (real_time_mode != real_time) - continue; - if (inst->session_type == MSM_VIDC_DECODER) { - cycles = lp_cycles = inst->clk_data.entry->vpp_cycles; - } else if (inst->session_type == MSM_VIDC_ENCODER) { - lp_mode |= inst->flags & VIDC_LOW_POWER; - if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) - lp_mode = false; - - cycles = lp_mode ? - inst->clk_data.entry->low_power_cycles : - inst->clk_data.entry->vpp_cycles; - } else { - continue; - } - current_inst_mbs_per_sec = msm_comm_get_inst_load_per_core(inst, - LOAD_POWER); - load += current_inst_mbs_per_sec * cycles / - inst->clk_data.work_route; - } - mutex_unlock(&core->lock); - - return load; -} - -int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) -{ - bool enable = false; - int rc = 0; - u32 core_load = 0, core_lp_load = 0; - u32 cur_inst_load = 0, cur_inst_lp_load = 0; - u32 mbpf, mbps, max_hq_mbpf, max_hq_mbps; - unsigned long max_freq, lp_cycles = 0; - struct msm_vidc_core *core; - - if (!inst || !inst->core || !inst->core->device) { - d_vpr_e("%s: Invalid args: Inst = %pK\n", - __func__, inst); - return -EINVAL; - } - - core = inst->core; - max_freq = msm_vidc_max_freq(inst->core, inst->sid); - inst->clk_data.core_id = 0; - - core_load = get_core_load(core, VIDC_CORE_ID_1, false, true); - core_lp_load = get_core_load(core, VIDC_CORE_ID_1, true, true); - - lp_cycles = inst->session_type == MSM_VIDC_ENCODER ? - inst->clk_data.entry->low_power_cycles : - inst->clk_data.entry->vpp_cycles; - - cur_inst_load = (msm_comm_get_inst_load(inst, LOAD_POWER) * - inst->clk_data.entry->vpp_cycles)/inst->clk_data.work_route; - - cur_inst_lp_load = (msm_comm_get_inst_load(inst, - LOAD_POWER) * lp_cycles)/inst->clk_data.work_route; - - mbpf = msm_vidc_get_mbs_per_frame(inst); - mbps = mbpf * msm_vidc_get_fps(inst); - max_hq_mbpf = core->resources.max_hq_mbs_per_frame; - max_hq_mbps = core->resources.max_hq_mbs_per_sec; - - s_vpr_h(inst->sid, "Core RT Load = %d LP Load = %d\n", - core_load, core_lp_load); - s_vpr_h(inst->sid, "Max Load = %lu\n", max_freq); - s_vpr_h(inst->sid, "Current Load = %d Current LP Load = %d\n", - cur_inst_load, cur_inst_lp_load); - - if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ && - (core_load > max_freq || core_lp_load > max_freq)) { - s_vpr_e(inst->sid, - "CQ session - Core cannot support this load\n"); - return -EINVAL; - } - - /* Power saving always disabled for HEIF image sessions */ - if (is_image_session(inst)) - msm_vidc_power_save_mode_enable(inst, false); - else if (cur_inst_load + core_load <= max_freq) { - if (mbpf > max_hq_mbpf || mbps > max_hq_mbps) - enable = true; - msm_vidc_power_save_mode_enable(inst, enable); - } else if (cur_inst_lp_load + core_load <= max_freq) { - msm_vidc_power_save_mode_enable(inst, true); - } else if (cur_inst_lp_load + core_lp_load <= max_freq) { - s_vpr_h(inst->sid, "Moved all inst's to LP"); - msm_vidc_move_core_to_power_save_mode(core, - VIDC_CORE_ID_1, inst->sid); - } else { - s_vpr_e(inst->sid, "Core cannot support this load\n"); - return -EINVAL; - } - - inst->clk_data.core_id = VIDC_CORE_ID_1; - rc = msm_comm_scale_clocks_and_bus(inst, 1); - msm_print_core_status(core, VIDC_CORE_ID_1, inst->sid); - return rc; -} - int msm_vidc_decide_core_and_power_mode_iris2(struct msm_vidc_inst *inst) { u32 mbpf, mbps, max_hq_mbpf, max_hq_mbps; @@ -1676,10 +1291,8 @@ void msm_vidc_init_core_clk_ops(struct msm_vidc_core *core) vpu = core->platform_data->vpu_ver; - if (vpu == VPU_VERSION_AR50 || vpu == VPU_VERSION_AR50_LITE) - core->core_ops = &core_ops_ar50; - else if (vpu == VPU_VERSION_IRIS1) - core->core_ops = &core_ops_iris1; + if (vpu == VPU_VERSION_AR50_LITE) + core->core_ops = &core_ops_ar50_lt; else core->core_ops = &core_ops_iris2; } From 0a49ec7e243bf2cebf25ad7a1394794495b2bff7 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Fri, 1 Nov 2019 11:19:01 -0700 Subject: [PATCH 167/452] msm: vidc: Initialize device_caps before device registration Initialize device_caps with device capabilities before video devices are registered, as required by V4L2 framework. Change-Id: I9fc037ae65d352b15d78eee979df30a24137dea8 Signed-off-by: Mihir Ganu --- msm/vidc/msm_v4l2_vidc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index 04597f06b449..86c921a4eee7 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -421,6 +421,9 @@ static int msm_vidc_register_video_device(enum session_type sess_type, core->vdev[sess_type].vdev.vfl_dir = VFL_DIR_M2M; core->vdev[sess_type].type = sess_type; core->vdev[sess_type].vdev.v4l2_dev = &core->v4l2_dev; + core->vdev[sess_type].vdev.device_caps = + V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE | + V4L2_CAP_STREAMING; rc = video_register_device(&core->vdev[sess_type].vdev, VFL_TYPE_GRABBER, nr); if (rc) { From 2ee4d803f6b5b5887f9c0dcf2f91799ccbf79335 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Fri, 8 Nov 2019 14:21:28 -0800 Subject: [PATCH 168/452] msm: vidc: Update Lahaina platform data Add Lahaina-specific platform data needed for driver probe and remove data for older platforms. Change-Id: I35e7711fd024467f0b6ce40aabdaf71f0c523e9a Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_platform.c | 889 +---------------------------------- 1 file changed, 16 insertions(+), 873 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 414d8c6a0dd8..100dbceea66f 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -54,20 +54,8 @@ static struct msm_vidc_codec_data default_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 125, 675, 320), }; -/* Update with lito data */ -static struct msm_vidc_codec_data lito_codec_data[] = { - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 0, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 0, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 0, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 0, 200, 200), -}; - -/* Update with Kona data */ -static struct msm_vidc_codec_data kona_codec_data[] = { +/* Update with Lahaina data */ +static struct msm_vidc_codec_data lahaina_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 25, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 25, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 25, 675, 320), @@ -78,18 +66,6 @@ static struct msm_vidc_codec_data kona_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 25, 200, 200), }; -/* Update with SM6150 data */ -static struct msm_vidc_codec_data sm6150_codec_data[] = { - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 50, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 50, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 50, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 50, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 50, 200, 200), -}; - static struct msm_vidc_codec_data bengal_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 125, 675, 320), @@ -101,40 +77,6 @@ static struct msm_vidc_codec_data bengal_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 50, 200, 200), }; -/* Update with 855 data */ -static struct msm_vidc_codec_data sm8150_codec_data[] = { - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 0, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 0, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 0, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 0, 200, 200), -}; - -static struct msm_vidc_codec_data sdm845_codec_data[] = { - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 50, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 50, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 50, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 50, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 50, 200, 200), -}; - -static struct msm_vidc_codec_data sdm670_codec_data[] = { - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 50, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 50, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 50, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 50, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 50, 200, 200), -}; - #define ENC HAL_VIDEO_DOMAIN_ENCODER #define DEC HAL_VIDEO_DOMAIN_DECODER #define H264 HAL_VIDEO_CODEC_H264 @@ -159,186 +101,6 @@ static struct msm_vidc_codec default_codecs[] = { {ENC, H264}, {ENC, HEVC}, {ENC, VP8}, }; -static struct msm_vidc_codec_capability lito_capabilities_v0[] = { - /* {cap_type, domains, codecs, min, max, step_size, default_value} */ - {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 5760, 1, 1920}, - {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 5760, 1, 1080}, - /* ((5760 * 2880) / 256) */ - {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 64800, 1, 8160}, - /* ((4096x2160)/256)@90fps */ - {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 3110400, 1, 2073600}, - {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 480, 1, 30}, - {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 200000000, 1, 20000000}, - {CAP_SCALE_X, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, - {CAP_SCALE_Y, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, - {CAP_SCALE_X, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, - {CAP_SCALE_Y, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, - {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, - {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, - {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 4, 1, 0}, - /* ((1920 * 1088) / 256) * 30 fps */ - {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, - 0, 244800, 1, 244800}, - {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, - {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, - {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, - {CAP_I_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 20}, - {CAP_P_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 40}, - {CAP_B_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 40}, - /* 10 slices */ - {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, - {CAP_SLICE_MB, ENC, H264|HEVC, 1, 10, 1, 10}, - {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, - - /* VP8 specific */ - {CAP_FRAME_WIDTH, ENC|DEC, VP8, 96, 4096, 1, 1920}, - {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 96, 4096, 1, 1080}, - /* (4096 * 2304) / 256 */ - {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 36, 36864, 1, 8160}, - /* (4096 * 2160) / 256) * 30*/ - {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 36, 1036800, 1, 244800}, - {CAP_FRAMERATE, ENC|DEC, VP8, 1, 30, 1, 30}, - {CAP_BITRATE, ENC, VP8, 1, 100000000, 1, 20000000}, - {CAP_BITRATE, DEC, VP8, 1, 100000000, 1, 20000000}, - - /* Mpeg2 decoder specific */ - {CAP_FRAME_WIDTH, DEC, MPEG2, 96, 1920, 1, 1920}, - {CAP_FRAME_HEIGHT, DEC, MPEG2, 96, 1920, 1, 1080}, - /* (1920 * 1088) / 256 */ - {CAP_MBS_PER_FRAME, DEC, MPEG2, 36, 8160, 1, 8160}, - /* ((1920 * 1088) / 256) * 30*/ - {CAP_MBS_PER_SECOND, DEC, MPEG2, 36, 244800, 1, 244800}, - {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, - {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, - - /* Secure usecase specific */ - {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1920}, - {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1080}, - /* (4096 * 2304) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 36864, 1, 8160}, - {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, - - /* Batch Mode Decode */ - {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 36, 8160, 1, 8160}, - /* (1920 * 1080) / 256 */ - {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, - - /* All intra encoding usecase specific */ - {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 240, 1, 30}, - - /* Image specific */ - {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 1, 8192}, - {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192}, - - /* Level for AVC and HEVC encoder specific */ - {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_6_0, 1, - V4L2_MPEG_VIDEO_H264_LEVEL_6_0}, - {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_6, 1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_6}, - - /* Level for AVC, HEVC and VP9 decoder specific */ - {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_6_1, 1, - V4L2_MPEG_VIDEO_H264_LEVEL_5_0}, - {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1, 1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5}, -}; - -static struct msm_vidc_codec_capability lito_capabilities_v1[] = { - /* {cap_type, domains, codecs, min, max, step_size, default_value} */ - {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1920}, - {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1080}, - /* ((4096 * 2304) / 256) */ - {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 36864, 1, 8160}, - /* 4K@30 decode + 1080@30 encode */ - {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 1281600, 1, 2073600}, - {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 240, 1, 30}, - {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 100000000, 1, 20000000}, - {CAP_SCALE_X, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, - {CAP_SCALE_Y, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, - {CAP_SCALE_X, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, - {CAP_SCALE_Y, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, - {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, - {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, - {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 4, 1, 0}, - /* ((1920 * 1088) / 256) * 30 fps */ - {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, - 0, 244800, 1, 244800}, - {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, - {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, - {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, - {CAP_I_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 20}, - {CAP_P_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 40}, - {CAP_B_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 40}, - /* 10 slices */ - {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, - {CAP_SLICE_MB, ENC, H264|HEVC, 1, 10, 1, 10}, - {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, - - /* VP8 specific */ - {CAP_FRAME_WIDTH, ENC|DEC, VP8, 96, 1920, 1, 1920}, - {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 96, 1920, 1, 1080}, - /* (1920 * 1088) / 256 */ - {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 36, 8160, 1, 8160}, - /* ((1920 * 1088) / 256) * 60*/ - {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 36, 489600, 1, 244800}, - {CAP_FRAMERATE, ENC|DEC, VP8, 1, 60, 1, 30}, - {CAP_BITRATE, ENC, VP8, 1, 40000000, 1, 20000000}, - {CAP_BITRATE, DEC, VP8, 1, 100000000, 1, 20000000}, - - /* Mpeg2 decoder specific */ - {CAP_FRAME_WIDTH, DEC, MPEG2, 96, 1920, 1, 1920}, - {CAP_FRAME_HEIGHT, DEC, MPEG2, 96, 1920, 1, 1080}, - /* (1920 * 1088) / 256 */ - {CAP_MBS_PER_FRAME, DEC, MPEG2, 36, 8160, 1, 8160}, - /* ((1920 * 1088) / 256) * 30*/ - {CAP_MBS_PER_SECOND, DEC, MPEG2, 36, 244800, 1, 244800}, - {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, - {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, - - /* Secure usecase specific */ - {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1920}, - {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 4096, 1, 1080}, - /* (4096 * 2304) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 36864, 1, 8160}, - {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, - - /* Batch Mode Decode */ - {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 36, 8160, 1, 8160}, - /* (1920 * 1080) / 256 */ - {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, - - /* All intra encoding usecase specific */ - {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 240, 1, 30}, - - /* Image specific */ - {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 1, 8192}, - {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192}, - - /* Level for AVC and HEVC encoder specific */ - {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_6_0, 1, - V4L2_MPEG_VIDEO_H264_LEVEL_6_0}, - {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_6, 1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_6}, - - /* Level for AVC, HEVC and VP9 decoder specific */ - {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_6_1, 1, - V4L2_MPEG_VIDEO_H264_LEVEL_5_0}, - {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1, 1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5}, -}; - static struct msm_vidc_codec_capability bengal_capabilities[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value} */ {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 1920, 1, 1920}, @@ -372,7 +134,7 @@ static struct msm_vidc_codec_capability bengal_capabilities[] = { {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, }; -static struct msm_vidc_codec_capability kona_capabilities[] = { +static struct msm_vidc_codec_capability lahaina_capabilities[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 8192, 1, 1920}, {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 8192, 1, 1080}, @@ -497,151 +259,7 @@ static struct msm_vidc_common_data default_common_data[] = { }, }; -/* Update with lito */ -static struct msm_vidc_common_data lito_common_data_v0[] = { - { - .key = "qcom,never-unload-fw", - .value = 1, - }, - { - .key = "qcom,sw-power-collapse", - .value = 1, - }, - { - .key = "qcom,domain-attr-non-fatal-faults", - .value = 1, - }, - { - .key = "qcom,max-secure-instances", - .value = 3, - }, - { - .key = "qcom,max-hw-load", - .value = 3110400,/* ((4096x2160)/256)@90fps */ - /* 4k@60 decode + 4k@30 encode */ - }, - { - .key = "qcom,max-hq-mbs-per-frame", - .value = 8160,/* ((1920x1088)/256) */ - }, - { - .key = "qcom,max-hq-mbs-per-sec", - .value = 244800,/* ((1920x1088)/256) MBs@30fps */ - }, - { - .key = "qcom,max-b-frame-mbs-per-frame", - .value = 8160,/* ((1920x1088)/256) */ - }, - { - .key = "qcom,max-b-frame-mbs-per-sec", - .value = 244800,/* ((1920x1088)/256) MBs@30fps */ - }, - { - .key = "qcom,power-collapse-delay", - .value = 1500, - }, - { - .key = "qcom,hw-resp-timeout", - .value = 1000, - }, - { - .key = "qcom,debug-timeout", - .value = 0, - }, - { - .key = "qcom,decode-batching", - .value = 1, - }, - { - .key = "qcom,batch-timeout", - .value = 200, - }, - { - .key = "qcom,dcvs", - .value = 1, - }, - { - .key = "qcom,fw-cycles", - .value = 760000, - }, - { - .key = "qcom,fw-vpp-cycles", - .value = 166667, - }, -}; - -static struct msm_vidc_common_data lito_common_data_v1[] = { - { - .key = "qcom,never-unload-fw", - .value = 1, - }, - { - .key = "qcom,sw-power-collapse", - .value = 1, - }, - { - .key = "qcom,domain-attr-non-fatal-faults", - .value = 1, - }, - { - .key = "qcom,max-secure-instances", - .value = 3, - }, - { - .key = "qcom,max-hw-load", - .value = 1281600,/* 4K@30 decode + 1080@30 encode */ - }, - { - .key = "qcom,max-hq-mbs-per-frame", - .value = 8160,/* ((1920x1088)/256) */ - }, - { - .key = "qcom,max-hq-mbs-per-sec", - .value = 244800,/* ((1920x1088)/256) MBs@30fps */ - }, - { - .key = "qcom,max-b-frame-mbs-per-frame", - .value = 8160,/* ((1920x1088)/256) */ - }, - { - .key = "qcom,max-b-frame-mbs-per-sec", - .value = 244800,/* ((1920x1088)/256) MBs@30fps */ - }, - { - .key = "qcom,power-collapse-delay", - .value = 1500, - }, - { - .key = "qcom,hw-resp-timeout", - .value = 1000, - }, - { - .key = "qcom,debug-timeout", - .value = 0, - }, - { - .key = "qcom,decode-batching", - .value = 1, - }, - { - .key = "qcom,batch-timeout", - .value = 200, - }, - { - .key = "qcom,dcvs", - .value = 1, - }, - { - .key = "qcom,fw-cycles", - .value = 760000, - }, - { - .key = "qcom,fw-vpp-cycles", - .value = 166667, - }, -}; - -static struct msm_vidc_common_data kona_common_data[] = { +static struct msm_vidc_common_data lahaina_common_data[] = { { .key = "qcom,never-unload-fw", .value = 1, @@ -724,65 +342,6 @@ static struct msm_vidc_common_data kona_common_data[] = { }, }; -static struct msm_vidc_common_data sm6150_common_data[] = { - { - .key = "qcom,never-unload-fw", - .value = 1, - }, - { - .key = "qcom,sw-power-collapse", - .value = 1, - }, - { - .key = "qcom,domain-attr-non-fatal-faults", - .value = 1, - }, - { - .key = "qcom,max-secure-instances", - .value = 5, - }, - { - .key = "qcom,max-hw-load", - .value = 1216800, - }, - { - .key = "qcom,max-hq-mbs-per-frame", - .value = 8160, - }, - { - .key = "qcom,max-hq-mbs-per-sec", - .value = 244800, /* 1920 x 1088 @ 30 fps */ - }, - { - .key = "qcom,max-b-frame-mbs-per-frame", - .value = 8160, - }, - { - .key = "qcom,max-b-frame-mbs-per-sec", - .value = 489600, - }, - { - .key = "qcom,power-collapse-delay", - .value = 1500, - }, - { - .key = "qcom,hw-resp-timeout", - .value = 1000, - }, - { - .key = "qcom,dcvs", - .value = 1, - }, - { - .key = "qcom,fw-cycles", - .value = 733003, - }, - { - .key = "qcom,fw-vpp-cycles", - .value = 225975, - }, -}; - static struct msm_vidc_common_data bengal_common_data[] = { { .key = "qcom,never-unload-fw", @@ -842,260 +401,8 @@ static struct msm_vidc_common_data bengal_common_data[] = { }, }; -static struct msm_vidc_common_data sm8150_common_data[] = { - { - .key = "qcom,never-unload-fw", - .value = 1, - }, - { - .key = "qcom,sw-power-collapse", - .value = 1, - }, - { - .key = "qcom,domain-attr-non-fatal-faults", - .value = 1, - }, - { - .key = "qcom,max-secure-instances", - .value = 2, /* - * As per design driver allows 3rd - * instance as well since the secure - * flags were updated later for the - * current instance. Hence total - * secure sessions would be - * max-secure-instances + 1. - */ - }, - { - .key = "qcom,max-hw-load", - .value = 3916800, /* - * 1920x1088/256 MBs@480fps. It is less - * any other usecases (ex: - * 3840x2160@120fps, 4096x2160@96ps, - * 7680x4320@30fps) - */ - }, - { - .key = "qcom,max-hq-mbs-per-frame", - .value = 8160, - }, - { - .key = "qcom,max-hq-mbs-per-sec", - .value = 244800, /* 1920 x 1088 @ 30 fps */ - }, - { - .key = "qcom,max-b-frame-mbs-per-frame", - .value = 8160, - }, - { - .key = "qcom,max-b-frame-mbs-per-sec", - .value = 489600, - }, - { - .key = "qcom,power-collapse-delay", - .value = 1500, - }, - { - .key = "qcom,hw-resp-timeout", - .value = 1000, - }, - { - .key = "qcom,debug-timeout", - .value = 0, - }, - { - .key = "qcom,decode-batching", - .value = 1, - }, - { - .key = "qcom,batch-timeout", - .value = 200, - }, - { - .key = "qcom,dcvs", - .value = 1, - }, - { - .key = "qcom,fw-cycles", - .value = 760000, - }, - { - .key = "qcom,fw-vpp-cycles", - .value = 166667, - }, -}; - -static struct msm_vidc_common_data sdm845_common_data[] = { - { - .key = "qcom,never-unload-fw", - .value = 1, - }, - { - .key = "qcom,sw-power-collapse", - .value = 1, - }, - { - .key = "qcom,domain-attr-non-fatal-faults", - .value = 1, - }, - { - .key = "qcom,domain-attr-cache-pagetables", - .value = 1, - }, - { - .key = "qcom,max-secure-instances", - .value = 5, - }, - { - .key = "qcom,max-hw-load", - .value = 3110400, /* 4096x2160@90 */ - }, - { - .key = "qcom,max-hq-mbs-per-frame", - .value = 8160, - }, - { - .key = "qcom,max-hq-mbs-per-sec", - .value = 244800, /* 1920 x 1088 @ 30 fps */ - }, - { - .key = "qcom,max-b-frame-mbs-per-frame", - .value = 8160, - }, - { - .key = "qcom,max-b-frame-mbs-per-sec", - .value = 489600, - }, - { - .key = "qcom,power-collapse-delay", - .value = 500, - }, - { - .key = "qcom,hw-resp-timeout", - .value = 250, - }, - { - .key = "qcom,debug-timeout", - .value = 0, - }, - { - .key = "qcom,dcvs", - .value = 1, - }, -}; - -static struct msm_vidc_common_data sdm670_common_data_v0[] = { - { - .key = "qcom,never-unload-fw", - .value = 1, - }, - { - .key = "qcom,sw-power-collapse", - .value = 1, - }, - { - .key = "qcom,domain-attr-non-fatal-faults", - .value = 1, - }, - { - .key = "qcom,max-secure-instances", - .value = 5, - }, - { - .key = "qcom,max-hw-load", - .value = 1944000, - }, - { - .key = "qcom,max-hq-mbs-per-frame", - .value = 8160, - }, - { - .key = "qcom,max-hq-mbs-per-sec", - .value = 244800, /* 1920 x 1088 @ 30 fps */ - }, - { - .key = "qcom,max-b-frame-mbs-per-frame", - .value = 8160, - }, - { - .key = "qcom,max-b-frame-mbs-per-sec", - .value = 489600, - }, - { - .key = "qcom,power-collapse-delay", - .value = 500, - }, - { - .key = "qcom,hw-resp-timeout", - .value = 250, - }, - { - .key = "qcom,dcvs", - .value = 1, - }, -}; - -static struct msm_vidc_common_data sdm670_common_data_v1[] = { - { - .key = "qcom,never-unload-fw", - .value = 1, - }, - { - .key = "qcom,sw-power-collapse", - .value = 1, - }, - { - .key = "qcom,domain-attr-non-fatal-faults", - .value = 1, - }, - { - .key = "qcom,max-secure-instances", - .value = 5, - }, - { - .key = "qcom,max-hw-load", - .value = 1216800, - }, - { - .key = "qcom,max-hq-mbs-per-frame", - .value = 8160, - }, - { - .key = "qcom,max-hq-mbs-per-sec", - .value = 244800, /* 1920 x 1088 @ 30 fps */ - }, - { - .key = "qcom,max-b-frame-mbs-per-frame", - .value = 8160, - }, - { - .key = "qcom,max-b-frame-mbs-per-sec", - .value = 489600, - }, - { - .key = "qcom,power-collapse-delay", - .value = 500, - }, - { - .key = "qcom,hw-resp-timeout", - .value = 250, - }, - { - .key = "qcom,dcvs", - .value = 1, - }, -}; - -static struct msm_vidc_efuse_data lito_efuse_data[] = { - EFUSE_ENTRY(0x00786008, 4, 0x00200000, 0x15, SKU_VERSION), -}; - -static struct msm_vidc_efuse_data sdm670_efuse_data[] = { - EFUSE_ENTRY(0x007801A0, 4, 0x00008000, 0x0f, SKU_VERSION), -}; - /* Default UBWC config for LPDDR5 */ -static struct msm_vidc_ubwc_config_data kona_ubwc_data[] = { +static struct msm_vidc_ubwc_config_data lahaina_ubwc_data[] = { UBWC_CONFIG(1, 1, 1, 0, 0, 0, 8, 32, 16, 0, 0), }; @@ -1114,30 +421,11 @@ static struct msm_vidc_platform_data default_data = { .ubwc_config = 0x0, }; -static struct msm_vidc_platform_data lito_data = { - .codec_data = lito_codec_data, - .codec_data_length = ARRAY_SIZE(lito_codec_data), - .common_data = lito_common_data_v0, - .common_data_length = ARRAY_SIZE(lito_common_data_v0), - .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, - .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, - .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, - .efuse_data = lito_efuse_data, - .efuse_data_length = ARRAY_SIZE(lito_efuse_data), - .sku_version = 0, - .vpu_ver = VPU_VERSION_IRIS1, - .ubwc_config = 0x0, - .codecs = default_codecs, - .codecs_count = ARRAY_SIZE(default_codecs), - .codec_caps = lito_capabilities_v0, - .codec_caps_count = ARRAY_SIZE(lito_capabilities_v0), -}; - -static struct msm_vidc_platform_data kona_data = { - .codec_data = kona_codec_data, - .codec_data_length = ARRAY_SIZE(kona_codec_data), - .common_data = kona_common_data, - .common_data_length = ARRAY_SIZE(kona_common_data), +static struct msm_vidc_platform_data lahaina_data = { + .codec_data = lahaina_codec_data, + .codec_data_length = ARRAY_SIZE(lahaina_codec_data), + .common_data = lahaina_common_data, + .common_data_length = ARRAY_SIZE(lahaina_common_data), .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, @@ -1145,26 +433,11 @@ static struct msm_vidc_platform_data kona_data = { .efuse_data_length = 0, .sku_version = 0, .vpu_ver = VPU_VERSION_IRIS2, - .ubwc_config = kona_ubwc_data, + .ubwc_config = lahaina_ubwc_data, .codecs = default_codecs, .codecs_count = ARRAY_SIZE(default_codecs), - .codec_caps = kona_capabilities, - .codec_caps_count = ARRAY_SIZE(kona_capabilities), -}; - -static struct msm_vidc_platform_data sm6150_data = { - .codec_data = sm6150_codec_data, - .codec_data_length = ARRAY_SIZE(sm6150_codec_data), - .common_data = sm6150_common_data, - .common_data_length = ARRAY_SIZE(sm6150_common_data), - .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, - .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, - .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, - .efuse_data = NULL, - .efuse_data_length = 0, - .sku_version = 0, - .vpu_ver = VPU_VERSION_AR50, - .ubwc_config = 0x0, + .codec_caps = lahaina_capabilities, + .codec_caps_count = ARRAY_SIZE(lahaina_capabilities), }; static struct msm_vidc_platform_data bengal_data = { @@ -1186,75 +459,10 @@ static struct msm_vidc_platform_data bengal_data = { .codec_caps_count = ARRAY_SIZE(bengal_capabilities), }; -static struct msm_vidc_platform_data sm8150_data = { - .codec_data = sm8150_codec_data, - .codec_data_length = ARRAY_SIZE(sm8150_codec_data), - .common_data = sm8150_common_data, - .common_data_length = ARRAY_SIZE(sm8150_common_data), - .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, - .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, - .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, - .efuse_data = NULL, - .efuse_data_length = 0, - .sku_version = 0, - .vpu_ver = VPU_VERSION_IRIS1, - .ubwc_config = 0x0, -}; - -static struct msm_vidc_platform_data sdm845_data = { - .codec_data = sdm845_codec_data, - .codec_data_length = ARRAY_SIZE(sdm845_codec_data), - .common_data = sdm845_common_data, - .common_data_length = ARRAY_SIZE(sdm845_common_data), - .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, - .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, - .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, - .efuse_data = NULL, - .efuse_data_length = 0, - .sku_version = 0, - .vpu_ver = VPU_VERSION_AR50, - .ubwc_config = 0x0, -}; - -static struct msm_vidc_platform_data sdm670_data = { - .codec_data = sdm670_codec_data, - .codec_data_length = ARRAY_SIZE(sdm670_codec_data), - .common_data = sdm670_common_data_v0, - .common_data_length = ARRAY_SIZE(sdm670_common_data_v0), - .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, - .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, - .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, - .efuse_data = sdm670_efuse_data, - .efuse_data_length = ARRAY_SIZE(sdm670_efuse_data), - .sku_version = 0, - .vpu_ver = VPU_VERSION_AR50, - .ubwc_config = 0x0, -}; - static const struct of_device_id msm_vidc_dt_match[] = { { - .compatible = "qcom,lito-vidc", - .data = &lito_data, - }, - { - .compatible = "qcom,kona-vidc", - .data = &kona_data, - }, - { - .compatible = "qcom,sm6150-vidc", - .data = &sm6150_data, - }, - { - .compatible = "qcom,sm8150-vidc", - .data = &sm8150_data, - }, - { - .compatible = "qcom,sdm845-vidc", - .data = &sdm845_data, - }, - { - .compatible = "qcom,sdm670-vidc", - .data = &sdm670_data, + .compatible = "qcom,lahaina-vidc", + .data = &lahaina_data, }, { .compatible = "qcom,bengal-vidc", @@ -1265,53 +473,11 @@ static const struct of_device_id msm_vidc_dt_match[] = { MODULE_DEVICE_TABLE(of, msm_vidc_dt_match); -static int msm_vidc_read_efuse( - struct msm_vidc_platform_data *data, struct device *dev) -{ - void __iomem *base; - uint32_t i; - struct msm_vidc_efuse_data *efuse_data = data->efuse_data; - uint32_t efuse_data_count = data->efuse_data_length; - - for (i = 0; i < efuse_data_count; i++) { - - switch ((efuse_data[i]).purpose) { - - case SKU_VERSION: - base = devm_ioremap(dev, (efuse_data[i]).start_address, - (efuse_data[i]).size); - if (!base) { - d_vpr_e("failed efuse: start %#x, size %d\n", - (efuse_data[i]).start_address, - (efuse_data[i]).size); - return -EINVAL; - } else { - u32 efuse = 0; - - efuse = readl_relaxed(base); - data->sku_version = - (efuse & (efuse_data[i]).mask) >> - (efuse_data[i]).shift; - d_vpr_h("efuse 0x%x, platform version 0x%x\n", - efuse, data->sku_version); - - devm_iounmap(dev, base); - } - break; - - default: - break; - } - } - return 0; -} - void *vidc_get_drv_data(struct device *dev) { struct msm_vidc_platform_data *driver_data = NULL; const struct of_device_id *match; uint32_t ddr_type = DDR_TYPE_LPDDR5; - int rc = 0; if (!IS_ENABLED(CONFIG_OF) || !dev->of_node) { driver_data = &default_data; @@ -1326,17 +492,7 @@ void *vidc_get_drv_data(struct device *dev) if (!of_find_property(dev->of_node, "sku-index", NULL) || !driver_data) { goto exit; - } else if (!strcmp(match->compatible, "qcom,sdm670-vidc")) { - rc = msm_vidc_read_efuse(driver_data, dev); - if (rc) - goto exit; - - if (driver_data->sku_version == SKU_VERSION_1) { - driver_data->common_data = sdm670_common_data_v1; - driver_data->common_data_length = - ARRAY_SIZE(sdm670_common_data_v1); - } - } else if (!strcmp(match->compatible, "qcom,kona-vidc")) { + } else if (!strcmp(match->compatible, "qcom,lahaina-vidc")) { ddr_type = of_fdt_get_ddrtype(); if (ddr_type == -ENOENT) { d_vpr_e("Failed to get ddr type, use LPDDR5\n"); @@ -1348,20 +504,7 @@ void *vidc_get_drv_data(struct device *dev) ddr_type == DDR_TYPE_LPDDR4X || ddr_type == DDR_TYPE_LPDDR4Y)) driver_data->ubwc_config->highest_bank_bit = 0xf; - } else if (!strcmp(match->compatible, "qcom,lito-vidc")) { - rc = msm_vidc_read_efuse(driver_data, dev); - if (rc) - goto exit; - - if (driver_data->sku_version == SKU_VERSION_1) { - driver_data->common_data = lito_common_data_v1; - driver_data->common_data_length = - ARRAY_SIZE(lito_common_data_v1); - driver_data->codec_caps = lito_capabilities_v1; - driver_data->codec_caps_count = ARRAY_SIZE(lito_capabilities_v1); - } } - exit: return driver_data; } From 50eabf78efdaa7541ab7f2eda32cc4f4ba53dcfa Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Wed, 13 Nov 2019 14:41:53 -0800 Subject: [PATCH 169/452] msm: vidc: change user include header files directory Current location is cleaning up all the existing header files in usr/include/media directory before installing video specific header files and hence change video specific header files location. Kbuild files are not required anymore so remove Kbuild files. Change-Id: I217d0652be9b2811ef1c6df64bf4143c9bcd1bd3 Signed-off-by: Maheshwar Ajja --- Makefile | 3 ++- include/Kbuild | 2 -- include/uapi/Kbuild | 3 --- include/uapi/media/Kbuild | 4 ---- include/uapi/{ => vidc}/media/msm_media_info.h | 0 include/uapi/{ => vidc}/media/msm_vidc_utils.h | 0 6 files changed, 2 insertions(+), 10 deletions(-) delete mode 100644 include/Kbuild delete mode 100644 include/uapi/Kbuild delete mode 100644 include/uapi/media/Kbuild rename include/uapi/{ => vidc}/media/msm_media_info.h (100%) rename include/uapi/{ => vidc}/media/msm_vidc_utils.h (100%) diff --git a/Makefile b/Makefile index cbe215e1a9b6..ef196427110e 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,8 @@ LINUXINCLUDE += -include $(srctree)/techpack/video/config/litovidconf.h endif LINUXINCLUDE += -I$(srctree)/techpack/video/include \ - -I$(srctree)/techpack/video/include/uapi + -I$(srctree)/techpack/video/include/uapi \ + -I$(srctree)/techpack/video/include/uapi/vidc USERINCLUDE += -I$(srctree)/techpack/video/include/uapi diff --git a/include/Kbuild b/include/Kbuild deleted file mode 100644 index bab1145bc7a7..000000000000 --- a/include/Kbuild +++ /dev/null @@ -1,2 +0,0 @@ -# Top-level Makefile calls into asm-$(ARCH) -# List only non-arch directories below diff --git a/include/uapi/Kbuild b/include/uapi/Kbuild deleted file mode 100644 index 469cb04b044f..000000000000 --- a/include/uapi/Kbuild +++ /dev/null @@ -1,3 +0,0 @@ -# include all directories below - -header-y += media/ diff --git a/include/uapi/media/Kbuild b/include/uapi/media/Kbuild deleted file mode 100644 index e9b80bb01fd6..000000000000 --- a/include/uapi/media/Kbuild +++ /dev/null @@ -1,4 +0,0 @@ -# include header files - -header-y += msm_media_info.h -header-y += msm_vidc_utils.h diff --git a/include/uapi/media/msm_media_info.h b/include/uapi/vidc/media/msm_media_info.h similarity index 100% rename from include/uapi/media/msm_media_info.h rename to include/uapi/vidc/media/msm_media_info.h diff --git a/include/uapi/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h similarity index 100% rename from include/uapi/media/msm_vidc_utils.h rename to include/uapi/vidc/media/msm_vidc_utils.h From 36e018e3ab660178d5ec096d333fa7c672da76ef Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Mon, 18 Nov 2019 15:18:20 -0800 Subject: [PATCH 170/452] msm: vidc: Initialize port format type Initialize port format type to avoid failure when g_fmt is called before s_fmt. Change-Id: I37758f6d8be766c75cc8bc97147312b3b0bb0915 Signed-off-by: Mihir Ganu --- msm/vidc/msm_vdec.c | 2 ++ msm/vidc/msm_venc.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 2c168e6a2322..f423d9c6f288 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -746,6 +746,7 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) inst->prop.extradata_ctrls = EXTRADATA_DEFAULT; f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + f->type = OUTPUT_MPLANE; f->fmt.pix_mp.height = DEFAULT_HEIGHT; f->fmt.pix_mp.width = DEFAULT_WIDTH; f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12_UBWC; @@ -767,6 +768,7 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) strlcpy(inst->fmts[OUTPUT_PORT].description, fmt_desc->description, sizeof(inst->fmts[OUTPUT_PORT].description)); f = &inst->fmts[INPUT_PORT].v4l2_fmt; + f->type = INPUT_MPLANE; f->fmt.pix_mp.height = DEFAULT_HEIGHT; f->fmt.pix_mp.width = DEFAULT_WIDTH; f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 832de37b9e07..6a6d52e9fb5f 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1108,6 +1108,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) return -EINVAL; } f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + f->type = OUTPUT_MPLANE; f->fmt.pix_mp.height = DEFAULT_HEIGHT; f->fmt.pix_mp.width = DEFAULT_WIDTH; f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; @@ -1127,6 +1128,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) strlcpy(inst->fmts[OUTPUT_PORT].description, fmt_desc->description, sizeof(inst->fmts[OUTPUT_PORT].description)); f = &inst->fmts[INPUT_PORT].v4l2_fmt; + f->type = INPUT_MPLANE; f->fmt.pix_mp.height = DEFAULT_HEIGHT; f->fmt.pix_mp.width = DEFAULT_WIDTH; f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12_UBWC; From ea8b192b844a907cda3795474e8004d5e6e7f2fc Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Tue, 19 Nov 2019 16:20:36 -0800 Subject: [PATCH 171/452] msm: vidc: disable compilation for gki gki needs video driver as module and hence compile video driver for qgki variant only. Change-Id: I6e25c5c7651e02df35c40ac1b27a8a61e3110530 Signed-off-by: Maheshwar Ajja --- config/konavid.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/konavid.conf b/config/konavid.conf index efb4eedfb73e..e43585c724ac 100644 --- a/config/konavid.conf +++ b/config/konavid.conf @@ -1 +1,3 @@ +ifeq ($(CONFIG_QGKI),y) export CONFIG_MSM_VIDC_V4L2=y +endif From 17ad9b8a4dd650e3641c50a57ed6cc1f6bd10434 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Mon, 25 Nov 2019 20:08:55 -0800 Subject: [PATCH 172/452] msm: vidc: Fix bus BW range parsing Parse both low and high ranges for each bus. Change-Id: I01fb35976cf128cfebe390bd0fc780422cfe91d5 Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_res_parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 12808c8ef847..ef7c487fe58d 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -384,7 +384,7 @@ static int msm_vidc_load_bus_table(struct msm_vidc_platform_resources *res) rc = of_property_read_u32_array(pdev->dev.of_node, "qcom,bus-range-kbps", bus_ranges, - num_buses); + num_buses * 2); if (rc) { d_vpr_e( "Failed to read bus ranges: defaulting to <0 INT_MAX>\n"); From d3f9e09c3951a15f8bcf31f05ce5ae3817704350 Mon Sep 17 00:00:00 2001 From: Rakshitha Shakamuri Date: Mon, 25 Nov 2019 12:20:20 -0800 Subject: [PATCH 173/452] msm: vidc: update internal buffers size h264d level 6 support needs update in internal buffer size. updated below buffers size - h264 decoder colocated motion vector buffer. - h264 decoder VPP command buffer. - h265 decoder VPP command buffer. Change-Id: I696e1046d585e209bd45fd4fa3f3e3e9d7527b03 Signed-off-by: Rakshitha Shakamuri --- msm/vidc/msm_vidc_buffer_calculations.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 27730fc67c3e..0ef0404ece2a 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -92,6 +92,7 @@ #define MAX_TILE_COLUMNS 32 /* 8K/256 */ +#define VPP_CMD_MAX_SIZE (1 << 20) #define NUM_HW_PIC_BUF 10 #define BIN_BUFFER_THRESHOLD (1280 * 736) #define H264D_MAX_SLICE 1800 @@ -1122,7 +1123,7 @@ static inline u32 hfi_iris2_h264d_comv_size(u32 width, u32 height, u32 comv_size = 0; u32 frame_width_in_mbs = ((width + 15) >> 4); u32 frame_height_in_mbs = ((height + 15) >> 4); - u32 col_mv_aligned_width = (frame_width_in_mbs << 6); + u32 col_mv_aligned_width = (frame_width_in_mbs << 7); u32 col_zero_aligned_width = (frame_width_in_mbs << 2); u32 col_zero_size = 0, size_colloc = 0; @@ -1157,11 +1158,15 @@ static inline u32 size_h264d_bse_cmd_buf(u32 height) static inline u32 size_h264d_vpp_cmd_buf(u32 height) { + u32 size = 0; u32 aligned_height = ALIGN(height, BUFFER_ALIGNMENT_SIZE(32)); - return min_t(u32, (((aligned_height + 15) >> 4) * 3 * 4), + size = min_t(u32, (((aligned_height + 15) >> 4) * 3 * 4), H264D_MAX_SLICE) * SIZE_H264D_VPP_CMD_PER_BUF; + if (size > VPP_CMD_MAX_SIZE) + size = VPP_CMD_MAX_SIZE; + return size; } static inline u32 hfi_iris2_h264d_non_comv_size(u32 width, u32 height) @@ -1258,7 +1263,8 @@ static inline u32 size_h265d_vpp_cmd_buf(u32 width, u32 height) size = ALIGN(size, 4); size = 2 * size * SIZE_H265D_VPP_CMD_PER_BUF; size = ALIGN(size, VENUS_DMA_ALIGNMENT); - + if (size > VPP_CMD_MAX_SIZE) + size = VPP_CMD_MAX_SIZE; return size; } From fc82551de5da7553f3e003733edfce2c7fc7c6f2 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Mon, 18 Nov 2019 17:02:13 -0800 Subject: [PATCH 174/452] msm: vidc: Migrate SCM calls Migrate secure world calls to upstream qcom_scm driver. Change-Id: I97fe0376bca265db9e2b851294c83f52e61c9544 Signed-off-by: Mihir Ganu --- msm/vidc/hfi_common.c | 55 ++++++++----------------------------------- msm/vidc/hfi_common.h | 2 +- 2 files changed, 11 insertions(+), 46 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 741cb974158e..728bf8b73e6c 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -13,7 +13,6 @@ static struct hal_device_data hal_ctxt; static struct venus_hfi_device venus_hfi_dev; -#define TZBSP_MEM_PROTECT_VIDEO_VAR 0x8 struct tzbsp_memprot { u32 cp_start; u32 cp_size; @@ -21,12 +20,6 @@ struct tzbsp_memprot { u32 cp_nonpixel_size; }; -struct tzbsp_resp { - int ret; -}; - -#define TZBSP_VIDEO_SET_STATE 0xa - /* Poll interval in uS */ #define POLL_INTERVAL_US 50 @@ -36,11 +29,6 @@ enum tzbsp_video_state { TZBSP_VIDEO_STATE_RESTORE_THRESHOLD = 2, }; -struct tzbsp_video_set_state_req { - u32 state; /* should be tzbsp_video_state enum value */ - u32 spare; /* reserved for future, should be zero */ -}; - const struct msm_vidc_bus_data DEFAULT_BUS_VOTE = { .total_bw_ddr = 0, .total_bw_llcc = 0, @@ -1005,23 +993,7 @@ static int __core_release_resource(struct venus_hfi_device *device, static int __tzbsp_set_video_state(enum tzbsp_video_state state, u32 sid) { - struct tzbsp_video_set_state_req cmd = {0}; - int tzbsp_rsp = 0; - int rc = 0; - struct scm_desc desc = {0}; - - desc.args[0] = cmd.state = state; - desc.args[1] = cmd.spare = 0; - desc.arginfo = SCM_ARGS(2); - - rc = scm_call2(SCM_SIP_FNID(SCM_SVC_BOOT, - TZBSP_VIDEO_SET_STATE), &desc); - tzbsp_rsp = desc.ret[0]; - - if (rc) { - s_vpr_e(sid, "Failed scm_call %d\n", rc); - return rc; - } + int tzbsp_rsp = qcom_scm_set_remote_state(state, 0); s_vpr_l(sid, "Set state %d, resp %d\n", state, tzbsp_rsp); if (tzbsp_rsp) { @@ -3403,10 +3375,8 @@ static void __deinit_resources(struct venus_hfi_device *device) static int __protect_cp_mem(struct venus_hfi_device *device) { struct tzbsp_memprot memprot; - unsigned int resp = 0; int rc = 0; struct context_bank_info *cb; - struct scm_desc desc = {0}; if (!device) return -EINVAL; @@ -3418,32 +3388,27 @@ static int __protect_cp_mem(struct venus_hfi_device *device) list_for_each_entry(cb, &device->res->context_banks, list) { if (!strcmp(cb->name, "venus_ns")) { - desc.args[1] = memprot.cp_size = - cb->addr_range.start; + memprot.cp_size = cb->addr_range.start; + d_vpr_h("%s: memprot.cp_size: %#x\n", __func__, memprot.cp_size); } if (!strcmp(cb->name, "venus_sec_non_pixel")) { - desc.args[2] = memprot.cp_nonpixel_start = - cb->addr_range.start; - desc.args[3] = memprot.cp_nonpixel_size = - cb->addr_range.size; + memprot.cp_nonpixel_start = cb->addr_range.start; + memprot.cp_nonpixel_size = cb->addr_range.size; + d_vpr_h("%s: cp_nonpixel_start: %#x size: %#x\n", __func__, memprot.cp_nonpixel_start, memprot.cp_nonpixel_size); } } - desc.arginfo = SCM_ARGS(4); - rc = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, - TZBSP_MEM_PROTECT_VIDEO_VAR), &desc); - resp = desc.ret[0]; + rc = qcom_scm_mem_protect_video(memprot.cp_start, memprot.cp_size, + memprot.cp_nonpixel_start, memprot.cp_nonpixel_size); - if (rc) { - d_vpr_e("Failed to protect memory(%d) response: %d\n", - rc, resp); - } + if (rc) + d_vpr_e("Failed to protect memory(%d)\n", rc); trace_venus_hfi_var_done( memprot.cp_start, memprot.cp_size, diff --git a/msm/vidc/hfi_common.h b/msm/vidc/hfi_common.h index 94ba39ddd1f7..2583db939fe4 100644 --- a/msm/vidc/hfi_common.h +++ b/msm/vidc/hfi_common.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include From bd3fc9ca56ba69e409aa7e6b21514358fe0e8384 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Mon, 25 Nov 2019 14:13:42 +0800 Subject: [PATCH 175/452] msm: vidc: fix memory leak when set color format When set color format constraints, one buffer is not correctly freed, fix it. Change-Id: Iad497f03981653a7f28524f1d9e4218f706dcca1 Signed-off-by: Qiwei Liu --- msm/vidc/msm_vidc_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 04e8d9fb8fd8..83fb1a831254 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7049,7 +7049,7 @@ int msm_comm_set_color_format_constraints(struct msm_vidc_inst *inst, s_vpr_h(inst->sid, "Set color format constraint success\n"); exit: - if (!pconstraint) + if (pconstraint) kfree(pconstraint); return rc; } From 1fc52e7df47652531a7eb034e1797d3fdaffc72d Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 23 Sep 2019 22:55:21 +0530 Subject: [PATCH 176/452] msm: vidc: enhance eos buffer handling Eos buffer is queued to firmware and its ref is maintained using eosbufs.list. Sometimes EOS request client sent even before port_reconfig. In that case requeing same buffer which is already with firmware at start_streaming. So during handle_ebd of 2nd eos buffer, it can't find the entry at eosbufs.list. So client closes the session. Always check, if buffer is already queued, then do not queue the same buffer again, during start_streaming after reconfig. Change-Id: If934d8ce357226dee78db15ccb7b3c57103d2f12 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_common.c | 5 +++++ msm/vidc/msm_vidc_internal.h | 1 + 2 files changed, 6 insertions(+) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 83fb1a831254..ea961fe27b94 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2363,6 +2363,7 @@ static bool is_eos_buffer(struct msm_vidc_inst *inst, u32 device_addr) list_for_each_entry_safe(temp, next, &inst->eosbufs.list, list) { if (temp->smem.device_addr == device_addr) { found = true; + temp->is_queued = 0; list_del(&temp->list); msm_comm_smem_free(inst, &temp->smem); kfree(temp); @@ -3953,6 +3954,9 @@ int msm_vidc_send_pending_eos_buffers(struct msm_vidc_inst *inst) mutex_lock(&inst->eosbufs.lock); list_for_each_entry_safe(binfo, temp, &inst->eosbufs.list, list) { + if (binfo->is_queued) + continue; + data.alloc_len = binfo->smem.size; data.device_addr = binfo->smem.device_addr; data.input_tag = 0; @@ -3969,6 +3973,7 @@ int msm_vidc_send_pending_eos_buffers(struct msm_vidc_inst *inst) rc = call_hfi_op(hdev, session_etb, inst->session, &data); + binfo->is_queued = 1; } mutex_unlock(&inst->eosbufs.lock); diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index ffb44f46431b..7f16fec6f21f 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -173,6 +173,7 @@ struct recon_buf { struct eos_buf { struct list_head list; struct msm_smem smem; + u32 is_queued; }; struct internal_buf { From b6bf411cd0f0c1c8de9fcc5d12f1e5f9af36bad5 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Thu, 26 Sep 2019 11:32:10 +0530 Subject: [PATCH 177/452] msm: vidc: venc: set signal_info to firmware always Currently setting signal_info, only if colorspace info is set properly. But sometimes client can set only range. So need to send signal_info always to firmware. Change-Id: I5282ec01b473485ec39f39abbf7160b9c5cc0256 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_venc.c | 30 ++++++++++++++++++++---------- msm/vidc/msm_vidc.c | 1 + msm/vidc/msm_vidc_internal.h | 2 ++ 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 6a6d52e9fb5f..f119d7cdb5e2 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1853,6 +1853,9 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) inst->clk_data.frame_rate = 1 << 16; } break; + case V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE: + inst->full_range = ctrl->val; + break; case V4L2_CID_MPEG_VIDC_CAPTURE_FRAME_RATE: case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER: case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: @@ -1872,7 +1875,6 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP: case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP: case V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE: - case V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE: case V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS: case V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS: case V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC: @@ -3611,16 +3613,24 @@ int msm_venc_set_video_signal_info(struct msm_vidc_inst *inst) ctrl_fr = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE); ctrl_tr = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS); ctrl_mc = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS); - if (ctrl_cs->val == MSM_VIDC_RESERVED_1) - return 0; - signal_info.enable = true; - signal_info.video_format = MSM_VIDC_NTSC; - signal_info.video_full_range = ctrl_fr->val; - signal_info.color_description = 1; - signal_info.color_primaries = ctrl_cs->val; - signal_info.transfer_characteristics = ctrl_tr->val; - signal_info.matrix_coeffs = ctrl_mc->val; + memset(&signal_info, 0, sizeof(struct hfi_video_signal_metadata)); + if (inst->full_range == COLOR_RANGE_UNSPECIFIED && + ctrl_cs->val == MSM_VIDC_RESERVED_1) + signal_info.enable = false; + else + signal_info.enable = true; + + if (signal_info.enable) { + signal_info.video_format = MSM_VIDC_NTSC; + signal_info.video_full_range = ctrl_fr->val; + if (ctrl_cs->val != MSM_VIDC_RESERVED_1) { + signal_info.color_description = 1; + signal_info.color_primaries = ctrl_cs->val; + signal_info.transfer_characteristics = ctrl_tr->val; + signal_info.matrix_coeffs = ctrl_mc->val; + } + } s_vpr_h(inst->sid, "%s: %d %d %d %d\n", __func__, signal_info.color_primaries, signal_info.video_full_range, diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 85e401705f8d..b6223678fcf2 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1438,6 +1438,7 @@ void *msm_vidc_open(int core_id, int session_type) inst->all_intra = false; inst->max_filled_len = 0; inst->entropy_mode = HFI_H264_ENTROPY_CABAC; + inst->full_range = COLOR_RANGE_UNSPECIFIED; for (i = SESSION_MSG_INDEX(SESSION_MSG_START); i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) { diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 7f16fec6f21f..486aed03fa74 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -44,6 +44,7 @@ #define DCVS_FTB_WINDOW 16 /* Superframe can have maximum of 32 frames */ #define VIDC_SUPERFRAME_MAX 32 +#define COLOR_RANGE_UNSPECIFIED (-1) #define V4L2_EVENT_VIDC_BASE 10 #define INPUT_MPLANE V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE @@ -553,6 +554,7 @@ struct msm_vidc_inst { bool all_intra; bool is_perf_eligible_session; u32 max_filled_len; + int full_range; }; extern struct msm_vidc_drv *vidc_driver; From 41d01ed1131c1b0c028d495fc6d30a8b80784f49 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 24 Sep 2019 12:11:33 -0700 Subject: [PATCH 178/452] msm: vidc: Update ddr type macro values Add new DDR type 5X and deprecate DDR type 4Y. Macro values also changed. CRs-Fixed: 2534324 Change-Id: I0412b4e624df9c377db18b635d2cde321fccf8d0 Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc_platform.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 100dbceea66f..c057ec1997ff 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -13,8 +13,8 @@ #define DDR_TYPE_LPDDR4 0x6 #define DDR_TYPE_LPDDR4X 0x7 -#define DDR_TYPE_LPDDR4Y 0x8 -#define DDR_TYPE_LPDDR5 0x9 +#define DDR_TYPE_LPDDR5 0x8 +#define DDR_TYPE_LPDDR5X 0x9 #define CODEC_ENTRY(n, p, vsp, vpp, lp) \ { \ @@ -501,8 +501,7 @@ void *vidc_get_drv_data(struct device *dev) if (driver_data->ubwc_config && (ddr_type == DDR_TYPE_LPDDR4 || - ddr_type == DDR_TYPE_LPDDR4X || - ddr_type == DDR_TYPE_LPDDR4Y)) + ddr_type == DDR_TYPE_LPDDR4X)) driver_data->ubwc_config->highest_bank_bit = 0xf; } exit: From d8fbf67e630f9c162f31bf3077ebe2fbc1fd13e3 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Fri, 20 Sep 2019 15:12:08 -0700 Subject: [PATCH 179/452] msm: vidc: Make sku index an optional property SKU index is not applicable for all targets. Hence no need to keep it mandatory. SKU related changes will happen only when the property is present otherwise will default to 0. Change-Id: I88076ea95bccd4130202c055e5c148d817dd302e Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc_platform.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index c057ec1997ff..0abfab9c6f01 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -480,6 +480,7 @@ void *vidc_get_drv_data(struct device *dev) uint32_t ddr_type = DDR_TYPE_LPDDR5; if (!IS_ENABLED(CONFIG_OF) || !dev->of_node) { + d_vpr_e("Using default_data\n"); driver_data = &default_data; goto exit; } @@ -489,20 +490,22 @@ void *vidc_get_drv_data(struct device *dev) if (match) driver_data = (struct msm_vidc_platform_data *)match->data; - if (!of_find_property(dev->of_node, "sku-index", NULL) || - !driver_data) { + if (!driver_data) goto exit; - } else if (!strcmp(match->compatible, "qcom,lahaina-vidc")) { + + if (!strcmp(match->compatible, "qcom,lahaina-vidc")) { ddr_type = of_fdt_get_ddrtype(); if (ddr_type == -ENOENT) { d_vpr_e("Failed to get ddr type, use LPDDR5\n"); } - d_vpr_h("DDR Type %x\n", ddr_type); if (driver_data->ubwc_config && (ddr_type == DDR_TYPE_LPDDR4 || ddr_type == DDR_TYPE_LPDDR4X)) driver_data->ubwc_config->highest_bank_bit = 0xf; + + d_vpr_h("DDR Type 0x%x hbb 0x%x\n", + ddr_type, driver_data->ubwc_config->highest_bank_bit); } exit: return driver_data; From 85b4a0682152ee07732bf35af767be2750184819 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Fri, 27 Sep 2019 11:18:57 -0700 Subject: [PATCH 180/452] msm: vidc: Modify DCVS scaling window DCVS scaling window should be equal to the additional buffers allocated for DCVS and independent of the buffer count required by Client and FW. CRs-Fixed: 2527739 Change-Id: I665a3d9792f44ea031d6c8d05d6e7a546a22f9a8 Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc_clocks.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index a0fbdfd6bcec..891081cd1764 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -450,26 +450,27 @@ static int msm_dcvs_scale_clocks(struct msm_vidc_inst *inst, * Limits : * min_threshold : Buffers required for reference by FW. * nom_threshold : Midpoint of Min and Max thresholds - * max_threshold : Total - Client extra buffers, allocated - * for it's smooth flow. - + * max_threshold : Min Threshold + DCVS extra buffers, allocated + * for smooth flow. * 1) When buffers outside FW are reaching client's extra buffers, * FW is slow and will impact pipeline, Increase clock. - * 2) When pending buffers with FW are same as FW requested, + * 2) When pending buffers with FW are less than FW requested, * pipeline has cushion to absorb FW slowness, Decrease clocks. - * 3) When buffers are equally distributed between FW and Client - * switch to NOM as this is the ideal steady state. + * 3) When DCVS has engaged(Inc or Dec) and pending buffers with FW + * transitions past the nom_threshold, switch to calculated load. + * This smoothens the clock transitions. * 4) Otherwise maintain previous Load config. */ - if (dcvs->dcvs_window < DCVS_DEC_EXTRA_OUTPUT_BUFFERS || - bufs_with_fw == dcvs->nom_threshold) { - dcvs->dcvs_flags = 0; - } else if (bufs_with_fw >= dcvs->max_threshold) { - dcvs->dcvs_flags |= MSM_VIDC_DCVS_INCR; + if (bufs_with_fw >= dcvs->max_threshold) { + dcvs->dcvs_flags = MSM_VIDC_DCVS_INCR; } else if (bufs_with_fw < dcvs->min_threshold) { - dcvs->dcvs_flags |= MSM_VIDC_DCVS_DECR; - } + dcvs->dcvs_flags = MSM_VIDC_DCVS_DECR; + } else if ((dcvs->dcvs_flags & MSM_VIDC_DCVS_DECR && + bufs_with_fw >= dcvs->nom_threshold) || + (dcvs->dcvs_flags & MSM_VIDC_DCVS_INCR && + bufs_with_fw <= dcvs->nom_threshold)) + dcvs->dcvs_flags = 0; s_vpr_p(inst->sid, "DCVS: bufs_with_fw %d Th[%d %d %d] Flag %#x\n", bufs_with_fw, dcvs->min_threshold, @@ -995,11 +996,12 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) dcvs->min_threshold = fmt->count_min; dcvs->max_threshold = - max(fmt->count_min, - (fmt->count_actual - DCVS_DEC_EXTRA_OUTPUT_BUFFERS)); + min((fmt->count_min + DCVS_DEC_EXTRA_OUTPUT_BUFFERS), + fmt->count_actual); dcvs->dcvs_window = - dcvs->max_threshold - dcvs->min_threshold; + dcvs->max_threshold < dcvs->min_threshold ? 0 : + dcvs->max_threshold - dcvs->min_threshold; dcvs->nom_threshold = dcvs->min_threshold + (dcvs->dcvs_window ? (dcvs->dcvs_window / 2) : 0); From 185f5585f13ce87abea6cbfdeb80baad51f48b8b Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 1 Oct 2019 16:18:23 -0700 Subject: [PATCH 181/452] msm: vidc: Increase hfr enc input buffers Increase total input buffers used for HFR cases. Required for smooth performance. Change-Id: Ia7dd49ead71239c2fb669e016d5e9fd2f94ca862 Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc_buffer_calculations.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 0ef0404ece2a..c714bbd58618 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -27,7 +27,7 @@ /* Encoder buffer count macros */ /* total input buffers for encoder HFR usecase */ -#define HFR_ENC_TOTAL_INPUT_BUFFERS 8 +#define HFR_ENC_TOTAL_INPUT_BUFFERS 16 /* minimum number of output buffers */ #define MIN_ENC_OUTPUT_BUFFERS 4 From 8830606bd6942e751cc077272812f9e34bcb54a1 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Fri, 27 Sep 2019 15:52:43 -0700 Subject: [PATCH 182/452] msm: vidc: Update encoder scratch1 size Update encoder scratch1 buffer size to match hfi ccb change for downscalar cases. Change-Id: I6d46227291d8ff3621a19c02940dd555f9103981 Signed-off-by: Darshana Patil --- msm/vidc/msm_vidc_buffer_calculations.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 0ef0404ece2a..f00bbae5b53c 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1594,6 +1594,7 @@ static inline u32 calculate_enc_scratch1_size(struct msm_vidc_inst *inst, u32 frame_num_lcu, linebuf_meta_recon_uv, topline_bufsize_fe_1stg_sao; u32 output_mv_bufsize = 0, temp_scratch_mv_bufsize = 0; u32 size, bit_depth, num_LCUMB; + u32 vpss_lineBufferSize_1 = 0; width_lcu_num = ((width)+(lcu_size)-1) / (lcu_size); height_lcu_num = ((height)+(lcu_size)-1) / (lcu_size); @@ -1701,7 +1702,9 @@ static inline u32 calculate_enc_scratch1_size(struct msm_vidc_inst *inst, override_buffer_size = ALIGN(override_buffer_size, VENUS_DMA_ALIGNMENT) * 2; ir_buffer_size = (((frame_num_lcu << 1) + 7) & (~7)) * 3; - vpss_line_buf = ((((max(width_coded, height_coded) + 3) >> 2) << 5) + 256) * 16; + vpss_lineBufferSize_1 = ((((8192) >> 2) << 5) * num_vpp_pipes) + 64; + vpss_line_buf = (((((max(width_coded, height_coded) + 3) >> 2) << 5) + + 256) * 16) + vpss_lineBufferSize_1; topline_bufsize_fe_1stg_sao = (16 * (width_coded >> 5)); topline_bufsize_fe_1stg_sao = ALIGN(topline_bufsize_fe_1stg_sao, VENUS_DMA_ALIGNMENT); From 9e9698a05ce4d1943f3073c8914674740501f43f Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Thu, 26 Sep 2019 17:46:57 -0700 Subject: [PATCH 183/452] msm: vidc: Fix to set correct profile levels to Video Firmware Avoid setting incorrect profile level to Video Firmware. Change-Id: I4f7af01fe77269758d7bcead383e284e995238a2 Signed-off-by: Akshata Sahukar Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_common.c | 6 ++++++ msm/vidc/msm_vidc_platform.c | 10 ++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index ea961fe27b94..ac91f707ec54 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1430,6 +1430,12 @@ static void msm_vidc_comm_update_ctrl_limits(struct msm_vidc_inst *inst) msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, &inst->capability.cap[CAP_HEVC_LEVEL]); + /* + * Default value of level is unknown, but since we are not + * using unknown value while updating level controls, we need + * to reinitialize inst->level to HFI unknown value. + */ + inst->level = HFI_LEVEL_UNKNOWN; } static void handle_session_init_done(enum hal_command_response cmd, void *data) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 0abfab9c6f01..b2e09823f74f 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -215,7 +215,13 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 16384, 1, 16384}, {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 16384, 1, 16384}, - /* Level for AVC and HEVC encoder specific */ + /* + * Level for AVC and HEVC encoder specific. + * Default for levels is UNKNOWN value. But if we use unknown + * value here to set as default, max value needs to be set to + * unknown as well, which creates a problem of allowing client + * to set higher level than supported. + */ {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, V4L2_MPEG_VIDEO_H264_LEVEL_6_0, 1, V4L2_MPEG_VIDEO_H264_LEVEL_6_0}, @@ -223,7 +229,7 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { V4L2_MPEG_VIDEO_HEVC_LEVEL_6, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_6}, - /* Level for AVC, HEVC and VP9 decoder specific */ + /* Level for AVC and HEVC decoder specific */ {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, V4L2_MPEG_VIDEO_H264_LEVEL_6_1, 1, V4L2_MPEG_VIDEO_H264_LEVEL_5_0}, From 8bb21b0ecf0e96a00fa4bff613ee68780a8b84af Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Tue, 1 Oct 2019 21:09:53 -0700 Subject: [PATCH 184/452] msm: vidc: Set CABAC as the default entropy mode Set CABAC as the default entropy mode for h264. Also, check profile settings to ensure that CABAC mode is set only for applicable profiles. Change-Id: Id5e67c1a7ac0862ea963312ebdaee58945bf8bc0 Signed-off-by: Mihir Ganu --- msm/vidc/msm_venc.c | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index f119d7cdb5e2..08e179a73654 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -249,7 +249,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .type = V4L2_CTRL_TYPE_MENU, .minimum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC, .maximum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC, - .default_value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC, + .default_value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC, .menu_skip_mask = ~( (1 << V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) | (1 << V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC) @@ -1856,12 +1856,16 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE: inst->full_range = ctrl->val; break; + case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: + inst->entropy_mode = msm_comm_v4l2_to_hfi( + V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, + ctrl->val, inst->sid); + break; case V4L2_CID_MPEG_VIDC_CAPTURE_FRAME_RATE: case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER: case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: case V4L2_CID_ROTATE: case V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT: - case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: @@ -3043,7 +3047,6 @@ int msm_venc_set_entropy_mode(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; - struct v4l2_ctrl *ctrl; struct hfi_h264_entropy_control entropy; if (!inst || !inst->core) { @@ -3055,10 +3058,7 @@ int msm_venc_set_entropy_mode(struct msm_vidc_inst *inst) if (get_v4l2_codec(inst) != V4L2_PIX_FMT_H264) return 0; - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE); - entropy.entropy_mode = msm_comm_v4l2_to_hfi( - V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, - ctrl->val, inst->sid); + entropy.entropy_mode = inst->entropy_mode; entropy.cabac_model = HFI_H264_CABAC_MODEL_2; s_vpr_h(inst->sid, "%s: %d\n", __func__, entropy.entropy_mode); @@ -3067,8 +3067,6 @@ int msm_venc_set_entropy_mode(struct msm_vidc_inst *inst) sizeof(entropy)); if (rc) s_vpr_e(inst->sid, "%s: set property failed\n", __func__); - else - inst->entropy_mode = entropy.entropy_mode; return rc; } @@ -4341,6 +4339,28 @@ int msm_venc_set_cvp_skipratio(struct msm_vidc_inst *inst) return rc; } +int msm_venc_update_entropy_mode(struct msm_vidc_inst *inst) +{ + if (!inst) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + if (get_v4l2_codec(inst) == V4L2_PIX_FMT_H264) { + if ((inst->profile == HFI_H264_PROFILE_BASELINE || + inst->profile == HFI_H264_PROFILE_CONSTRAINED_BASE) + && inst->entropy_mode == HFI_H264_ENTROPY_CABAC) { + inst->entropy_mode = HFI_H264_ENTROPY_CAVLC; + s_vpr_h(inst->sid, + "%s: profile %d entropy %d\n", + __func__, inst->profile, + inst->entropy_mode); + } + } + + return 0; +} + int handle_all_intra_restrictions(struct msm_vidc_inst *inst) { struct v4l2_ctrl *ctrl = NULL; @@ -4453,6 +4473,9 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) { int rc = 0; + rc = msm_venc_update_entropy_mode(inst); + if (rc) + goto exit; rc = handle_all_intra_restrictions(inst); if (rc) goto exit; From 16c8cdbaaf9b942e57e6cec1836bef634af1a50f Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 11 Oct 2019 21:25:05 +0530 Subject: [PATCH 185/452] msm: vidc: vdec: recalculate input buffer count for HFR Default buffer count will not be sufficient for HFR(fps > 480). So recalculate buffer count, if fps is updated before calling vidioc_reqbuf. Change-Id: Iec792892d283072f064c4148c65560b6a7e31d45 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vdec.c | 10 ++++++++++ msm/vidc/msm_vidc_buffer_calculations.c | 15 +++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index f423d9c6f288..4abe21d9f6b3 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -890,6 +890,16 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE: inst->clk_data.frame_rate = ctrl->val; + if (inst->state >= MSM_VIDC_LOAD_RESOURCES) + break; + /* Only recalculate buffer counts before buffers allocated */ + rc = msm_vidc_calculate_buffer_counts(inst); + if (rc) { + s_vpr_e(inst->sid, + "%s failed to calculate buffer count after set fps\n", + __func__); + return rc; + } break; case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA: if (ctrl->val == EXTRADATA_NONE) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 43089044611a..4fef8c9ac82c 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -19,6 +19,9 @@ /* total input buffers in case of decoder batch */ #define BATCH_DEC_TOTAL_INPUT_BUFFERS 6 +/* total input buffers for decoder HFR usecase (fps > 480) */ +#define HFR_DEC_TOTAL_MAX_INPUT_BUFFERS 24 + /* total input buffers for decoder HFR usecase */ #define HFR_DEC_TOTAL_INPUT_BUFFERS 12 @@ -745,6 +748,7 @@ static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst) unsigned int extra_input_count = 0; struct msm_vidc_core *core; struct v4l2_format *f; + int fps; if (!inst || !inst->core) { d_vpr_e("%s: invalid params %pK\n", __func__, inst); @@ -793,9 +797,16 @@ static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst) if (!is_secure_session(inst) && msm_comm_get_num_perf_sessions(inst) < MAX_PERF_ELIGIBLE_SESSIONS) { + fps = inst->clk_data.frame_rate >> 16; inst->is_perf_eligible_session = true; - extra_input_count = (HFR_DEC_TOTAL_INPUT_BUFFERS - - MIN_INPUT_BUFFERS); + if (fps > 480) + extra_input_count = + (HFR_DEC_TOTAL_MAX_INPUT_BUFFERS - + MIN_INPUT_BUFFERS); + else + extra_input_count = + (HFR_DEC_TOTAL_INPUT_BUFFERS - + MIN_INPUT_BUFFERS); } } else if (is_encode_session(inst)) { /* From 3498fb8bbca90b8ed4f467a790215d46c5e07a6d Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Mon, 14 Oct 2019 16:27:08 +0800 Subject: [PATCH 186/452] msm: venc: fix to skip mbpf checking for HEIF Fix to add condition to skip mbpf capability checking for HEIF image encoding. Change-Id: Ife323366b8c08040c3f6fab8a0d15b89fe6f6777 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_vidc_common.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index ac91f707ec54..f6facbfcc156 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5477,7 +5477,7 @@ static int msm_vidc_check_mbpf_supported(struct msm_vidc_inst *inst) if (is_thumbnail_session(temp)) continue; /* ignore HEIF sessions */ - if (is_image_session(temp)) + if (is_image_session(temp) || is_grid_session(temp)) continue; mbpf += NUM_MBS_PER_FRAME( temp->fmts[INPUT_PORT].v4l2_fmt.fmt.pix_mp.height, @@ -5745,7 +5745,8 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) /* Image size max capability has equal width and height, * hence, don't check mbpf for image sessions. */ - if (!rc && !is_image_session(inst) && + if (!rc && !(is_image_session(inst) || + is_grid_session(inst)) && NUM_MBS_PER_FRAME(input_width, input_height) > mbpf_max) { s_vpr_e(sid, "Unsupported mbpf %d, max %d\n", From a491b399dd47d62b024905ff3273d8da5657e265 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Tue, 15 Oct 2019 18:52:27 -0700 Subject: [PATCH 187/452] msm: venc: Disable input extradata plane for secure encoding For secure encoding case, there is no camera usage. Hence, by default make number of planes as 1. If any input requires extradata, client will enable it and driver will update number of planes. Change-Id: Id9afd0a286a53d5d4c6045ba58227f57a0a8e0ca Signed-off-by: Darshana Patil --- msm/vidc/msm_venc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 08e179a73654..596404906973 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1153,7 +1153,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) strlcpy(inst->fmts[INPUT_PORT].description, fmt_desc->description, sizeof(inst->fmts[INPUT_PORT].description)); inst->prop.bframe_changed = false; - inst->prop.extradata_ctrls = EXTRADATA_DEFAULT; + inst->prop.extradata_ctrls = EXTRADATA_NONE; inst->buffer_mode_set[INPUT_PORT] = HAL_BUFFER_MODE_DYNAMIC; inst->buffer_mode_set[OUTPUT_PORT] = HAL_BUFFER_MODE_STATIC; inst->clk_data.frame_rate = (DEFAULT_FPS << 16); @@ -1593,6 +1593,10 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) inst->flags &= ~VIDC_SECURE; if (ctrl->val) inst->flags |= VIDC_SECURE; + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + f->fmt.pix_mp.num_planes = 1; + s_vpr_h(sid, "%s: num planes %d for secure sessions\n", + __func__, f->fmt.pix_mp.num_planes); break; case V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME: if (inst->state == MSM_VIDC_START_DONE) { From 16e264d6fa9373cf90da311e18ae796bc27b103c Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Fri, 11 Oct 2019 15:30:49 +0530 Subject: [PATCH 188/452] msm: vidc: reject the buffer iova for incorrect mapping Reject the buffer device address mapping when the device address is mapped in secure context bank for a non-secure instance and for the converse as well. Change-Id: Ic2fc578acd23d3582b390b24cc9d829d49d00d4d Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_smem.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/msm/vidc/msm_smem.c b/msm/vidc/msm_smem.c index a68b3493aff6..622c9e205a9f 100644 --- a/msm/vidc/msm_smem.c +++ b/msm/vidc/msm_smem.c @@ -185,6 +185,7 @@ int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) unsigned long align = SZ_4K; struct dma_buf *dbuf; unsigned long ion_flags = 0; + u32 b_type = HAL_BUFFER_INPUT | HAL_BUFFER_OUTPUT | HAL_BUFFER_OUTPUT2; if (!inst || !smem) { d_vpr_e("%s: invalid params: %pK %pK\n", @@ -217,6 +218,14 @@ int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) if (ion_flags & ION_FLAG_SECURE) smem->flags |= SMEM_SECURE; + if ((smem->buffer_type & b_type) && + !!(smem->flags & SMEM_SECURE) ^ !!(inst->flags & VIDC_SECURE)) { + s_vpr_e(inst->sid, "Failed to map %s buffer with %s session\n", + smem->flags & SMEM_SECURE ? "secure" : "non-secure", + inst->flags & VIDC_SECURE ? "secure" : "non-secure"); + rc = -EINVAL; + goto exit; + } buffer_size = smem->size; rc = msm_dma_get_device_address(dbuf, align, &iova, &buffer_size, From 749c6aa9a9ab95c08bde8ac54a736a34bf1580b6 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Wed, 18 Dec 2019 14:21:34 -0800 Subject: [PATCH 189/452] msm: vidc: make video driver as module make changes in video driver to make it as module. Change-Id: I00788a1b72cc799f655b16e1bc6b7d6d6e0441f9 Signed-off-by: Maheshwar Ajja --- config/konavid.conf | 2 ++ msm/vidc/msm_v4l2_vidc.c | 1 + msm/vidc/msm_vidc_debug.c | 1 - msm/vidc/msm_vidc_platform.c | 7 +++---- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/config/konavid.conf b/config/konavid.conf index e43585c724ac..65eae99c590b 100644 --- a/config/konavid.conf +++ b/config/konavid.conf @@ -1,3 +1,5 @@ ifeq ($(CONFIG_QGKI),y) export CONFIG_MSM_VIDC_V4L2=y +else +export CONFIG_MSM_VIDC_V4L2=m endif diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index 1d5f2755a0e6..b97fc88b8d26 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -733,4 +733,5 @@ static void __exit msm_vidc_exit(void) module_init(msm_vidc_init); module_exit(msm_vidc_exit); +MODULE_SOFTDEP("pre: subsys-pil-tz"); MODULE_LICENSE("GPL v2"); diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index 00c1bccfb7c5..6628318482d1 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -8,7 +8,6 @@ #define MAX_DEBUG_LEVEL_STRING_LEN 15 #include "msm_vidc_debug.h" #include "vidc_hfi_api.h" -#include int msm_vidc_debug = VIDC_ERR | VIDC_PRINTK | FW_ERROR | FW_FATAL | FW_FTRACE; diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index b2e09823f74f..c136714cb8a3 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -6,7 +6,6 @@ #include #include #include -#include #include "msm_vidc_internal.h" #include "msm_vidc_debug.h" @@ -465,7 +464,7 @@ static struct msm_vidc_platform_data bengal_data = { .codec_caps_count = ARRAY_SIZE(bengal_capabilities), }; -static const struct of_device_id msm_vidc_dt_match[] = { +static const struct of_device_id msm_vidc_dt_device[] = { { .compatible = "qcom,lahaina-vidc", .data = &lahaina_data, @@ -477,7 +476,7 @@ static const struct of_device_id msm_vidc_dt_match[] = { {}, }; -MODULE_DEVICE_TABLE(of, msm_vidc_dt_match); +MODULE_DEVICE_TABLE(of, msm_vidc_dt_device); void *vidc_get_drv_data(struct device *dev) { @@ -491,7 +490,7 @@ void *vidc_get_drv_data(struct device *dev) goto exit; } - match = of_match_node(msm_vidc_dt_match, dev->of_node); + match = of_match_node(msm_vidc_dt_device, dev->of_node); if (match) driver_data = (struct msm_vidc_platform_data *)match->data; From e937ff6a5152e76aaca23b9a75f86e6eea607319 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Mon, 21 Oct 2019 13:44:32 -0700 Subject: [PATCH 190/452] msm: venc: Bump freq to next level for 1080p@480 Increase vpp cycles by 2% for 1080P@HSR480 encode usecase so that the video core runs at higher frequency(366Mhz) helping to achieve the desired performance. Change-Id: Id81abd36ab79067d52da9371d1dd5bdcfe622389 Signed-off-by: Darshana Patil --- msm/vidc/msm_vidc_clocks.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 891081cd1764..d975672d9159 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -655,6 +655,13 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, /* 1.01 is multi-pipe overhead */ if (inst->clk_data.work_route > 1) vpp_cycles += vpp_cycles / 100; + /* + * 1080p@480fps usecase needs exactly 338MHz + * without any margin left. Hence, adding 2 percent + * extra to bump it to next level (366MHz). + */ + if (fps == 480) + vpp_cycles += vpp_cycles * 2 / 100; /* VSP */ /* bitrate is based on fps, scale it using operating rate */ From 3f1571ff526ab4a5334c74f7f4c8714e8f232c3c Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Wed, 23 Oct 2019 15:26:51 -0700 Subject: [PATCH 191/452] msm: vidc: Update input buffer counts in set format Input buffer counts, ie Dec Bitstream and Enc Yuv, depend on input resolution. Hence they should be recalculated in set format. Stale values can result in excess memory usage. CRs-Fixed: 2548727 Change-Id: I57c87270a6613da290f14484897cef16e964e27a Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vdec.c | 13 +++++++++++++ msm/vidc/msm_venc.c | 8 ++++++++ 2 files changed, 21 insertions(+) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 4abe21d9f6b3..8f456dd31ad4 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -649,6 +649,19 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) mplane->plane_fmt[0].sizeimage = msm_vidc_calculate_dec_input_frame_size(inst); + /* Driver can recalculate buffer count only for + * only for bitstream port. Decoder YUV port reconfig + * should not overwrite the FW calculated buffer + * count. + */ + rc = msm_vidc_calculate_buffer_counts(inst); + if (rc) { + s_vpr_e(inst->sid, + "%s failed to calculate buffer count\n", + __func__); + return rc; + } + rc = msm_vidc_check_session_supported(inst); if (rc) { s_vpr_e(inst->sid, diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 596404906973..90dfb51d00c8 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1376,6 +1376,14 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) inst->bit_depth = MSM_VIDC_BIT_DEPTH_10; } + rc = msm_vidc_calculate_buffer_counts(inst); + if (rc) { + s_vpr_e(inst->sid, + "%s failed to calculate buffer count\n", + __func__); + return rc; + } + rc = msm_vidc_check_session_supported(inst); if (rc) { s_vpr_e(inst->sid, From 84b5664f362858988c4d3217f467f83a3c235799 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Wed, 23 Oct 2019 15:35:59 -0700 Subject: [PATCH 192/452] msm: venc: modify log messages for vbvdelay Modify log messages for vbvdelay. Change-Id: I3f1b9458d73dbd2a1f18d1f8d8896e51cd513a07 Signed-off-by: Darshana Patil --- msm/vidc/msm_venc.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 596404906973..e71f6a4125e6 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1900,11 +1900,11 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDEO_VBV_DELAY: case V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS: case V4L2_CID_MPEG_VIDC_SUPERFRAME: - s_vpr_h(sid, "Control set: ID : %x Val : %d\n", + s_vpr_h(sid, "Control set: ID : 0x%x Val : %d\n", ctrl->id, ctrl->val); break; default: - s_vpr_e(sid, "Unsupported index: %x\n", ctrl->id); + s_vpr_e(sid, "Unsupported index: 0x%x\n", ctrl->id); rc = -ENOTSUPP; break; } @@ -2588,15 +2588,13 @@ int msm_venc_set_vbv_delay(struct msm_vidc_inst *inst) set_vbv_delay: inst->clk_data.is_legacy_cbr = is_legacy_cbr; hrd_buf_size.vbv_hrd_buf_size = buf_size; - s_vpr_h(inst->sid, - "Set hrd_buf_size %d", hrd_buf_size.vbv_hrd_buf_size); + s_vpr_h(inst->sid, "%s: %d\n", __func__, hrd_buf_size.vbv_hrd_buf_size); rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_CONFIG_VENC_VBV_HRD_BUF_SIZE, (void *)&hrd_buf_size, sizeof(hrd_buf_size)); if (rc) { - s_vpr_e(inst->sid, "%s: set HRD_BUF_SIZE %u failed\n", - __func__, hrd_buf_size.vbv_hrd_buf_size); + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); } return rc; } From 2264ab291fcc7f7ad25260eb6d79ba69a5c36b19 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Wed, 16 Oct 2019 22:39:56 -0700 Subject: [PATCH 193/452] msm: vidc: Update Enc/Dec o/p and i/p buffer calculations -Fix to add 4 extra dcvs buffers at encoder input and decoder output side irrespective of fps and resolution. -Decrease total encoder input buffer count from 16 to 8 for non-hfr use-cases. -Increase total encoder output buffer count for hfr use-cases irrespective of resolution. Change-Id: I2fcda6e8c93bcc0df8c3168049ebf4a60e6bb5f1 Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_vidc_buffer_calculations.c | 71 ++++++++++++------------- msm/vidc/msm_vidc_buffer_calculations.h | 3 +- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 4fef8c9ac82c..cf4379993bbf 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -765,16 +765,15 @@ static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst) if (!is_realtime_session(inst) || is_thumbnail_session(inst)) return extra_input_count; - /* - * Batch mode and HFR not supported for resolution greater than - * UHD. Hence extra buffers are not required. - */ - f = &inst->fmts[INPUT_PORT].v4l2_fmt; - if (res_is_greater_than(f->fmt.pix_mp.width, f->fmt.pix_mp.height, - 4096, 2160)) - return extra_input_count; - if (is_decode_session(inst)) { + /* + * Batch mode and HFR not supported for resolution greater than + * UHD. Hence extra buffers are not required. + */ + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + if (res_is_greater_than(f->fmt.pix_mp.width, + f->fmt.pix_mp.height, 4096, 2160)) + goto exit; /* * Allocating 2 extra buffers, assuming current session is @@ -809,21 +808,21 @@ static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst) MIN_INPUT_BUFFERS); } } else if (is_encode_session(inst)) { - /* - * Both DCVS and HFR needs extra 4 buffers. Since all sessions - * are DCVS eligible, we do not need extra handling for HFR as - * we are making sure initial 4 sessions have extra 4 buffers. - * For the remaining non-perf sessions, no extra buffers are - * allocated and total number of buffers will be 4 with best - * effort performance. - */ + /* add 4 extra buffers for dcvs */ + if (core->resources.dcvs) + extra_input_count = DCVS_ENC_EXTRA_INPUT_BUFFERS; + + /* Increase buffer count for HFR usecase */ if (msm_comm_get_num_perf_sessions(inst) < - MAX_PERF_ELIGIBLE_SESSIONS) { + MAX_PERF_ELIGIBLE_SESSIONS && + msm_vidc_get_fps(inst) > 60) { inst->is_perf_eligible_session = true; extra_input_count = (HFR_ENC_TOTAL_INPUT_BUFFERS - MIN_INPUT_BUFFERS); } } + +exit: return extra_input_count; } @@ -849,22 +848,25 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) return extra_output_count; /* For HEIF, we are increasing buffer count */ - if (is_image_session(inst)) { + if (is_image_session(inst) || is_grid_session(inst)) { extra_output_count = (HEIF_ENC_TOTAL_OUTPUT_BUFFERS - MIN_ENC_OUTPUT_BUFFERS); return extra_output_count; } - /* - * Batch mode and HFR not supported for resolution greater than - * UHD. Hence extra buffers are not required. - */ - f = &inst->fmts[INPUT_PORT].v4l2_fmt; - if (res_is_greater_than(f->fmt.pix_mp.width, f->fmt.pix_mp.height, - 4096, 2160)) - return extra_output_count; - if (is_decode_session(inst)) { + /* add 4 extra buffers for dcvs */ + if (core->resources.dcvs) + extra_output_count = DCVS_DEC_EXTRA_OUTPUT_BUFFERS; + /* + * Batch mode and HFR not supported for resolution greater than + * UHD. Hence extra buffers are not required. + */ + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + if (res_is_greater_than(f->fmt.pix_mp.width, + f->fmt.pix_mp.height, 4096, 2160)) + goto exit; + /* * Minimum number of decoder output buffers is codec specific. * If platform supports decode batching ensure minimum 6 extra @@ -872,8 +874,6 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) */ if (core->resources.decode_batching) extra_output_count = BATCH_DEC_EXTRA_OUTPUT_BUFFERS; - else if (core->resources.dcvs) - extra_output_count = DCVS_DEC_EXTRA_OUTPUT_BUFFERS; } else if (is_encode_session(inst)) { /* * Batching and DCVS are based on input. We assume that encoder @@ -882,16 +882,15 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) * For HFR, we are increasing buffer count to avoid latency/perf * issue to re-cycle buffers. */ - if (msm_vidc_get_fps(inst) >= 120 && - !res_is_greater_than(f->fmt.pix_mp.width, - f->fmt.pix_mp.height, 1920, 1088) && - msm_comm_get_num_perf_sessions(inst) < - MAX_PERF_ELIGIBLE_SESSIONS) { + if (msm_comm_get_num_perf_sessions(inst) < + MAX_PERF_ELIGIBLE_SESSIONS && + msm_vidc_get_fps(inst) > 60) { inst->is_perf_eligible_session = true; extra_output_count = (HFR_ENC_TOTAL_OUTPUT_BUFFERS - MIN_ENC_OUTPUT_BUFFERS); - } + } } +exit: return extra_output_count; } diff --git a/msm/vidc/msm_vidc_buffer_calculations.h b/msm/vidc/msm_vidc_buffer_calculations.h index 7a6db350d5fa..2583a5e54b24 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.h +++ b/msm/vidc/msm_vidc_buffer_calculations.h @@ -6,8 +6,9 @@ #ifndef __H_MSM_VIDC_BUFFER_MEM_DEFS_H__ #define __H_MSM_VIDC_BUFFER_MEM_DEFS_H__ -/* extra o/p buffers in case of decoder dcvs */ +/* extra o/p buffers in case of dcvs */ #define DCVS_DEC_EXTRA_OUTPUT_BUFFERS 4 +#define DCVS_ENC_EXTRA_INPUT_BUFFERS DCVS_DEC_EXTRA_OUTPUT_BUFFERS struct msm_vidc_dec_buff_size_calculators { u32 (*calculate_scratch_size)(struct msm_vidc_inst *inst, u32 width, From f6dab215cdbc690e7ac4b39da68f9b7e48cd77ce Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Thu, 19 Sep 2019 14:05:02 +0530 Subject: [PATCH 194/452] msm: vidc: align capabilities to 32 considering hevc For hevc codec, LCU sizes are 32x32 or 64x64. Existing capabilities consider alignment with 16. Considering a hevc clip of dimension 4096x2160, the coded resolution becomes 4096x2176. Limiting the cap with 4096x2160 will break such usecase, hence keeping the capabilities considering 32-byte alignment. Change-Id: I505843878f177c63b88959f92ce3a7d5a06b996b Signed-off-by: Vikash Garodia Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_platform.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index b2e09823f74f..e17008159ab4 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -196,8 +196,8 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, /* Batch Mode Decode */ - {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 64, 34560, 1, 34560}, - /* (4096 * 2160) / 256 */ + {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 64, 34816, 1, 34816}, + /* (4096 * 2176) / 256 */ {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 120, 1, 120}, /* Lossless encoding usecase specific */ @@ -284,31 +284,31 @@ static struct msm_vidc_common_data lahaina_common_data[] = { }, { .key = "qcom,max-hw-load", - .value = 7776000, /* - * 7680x4320@60fps, 3840x2160@240fps - * Greater than 4096x2160@120fps, + .value = 7833600, /* + * 7680x4320@60fps, 3840x2176@240fps + * Greater than 4096x2176@120fps, * 8192x4320@48fps */ }, { .key = "qcom,max-mbpf", - .value = 172800, /* (8192x4320)/256 + (4096x2160)/256*/ + .value = 173056, /* (8192x4320)/256 + (4096x2176)/256*/ }, { .key = "qcom,max-hq-mbs-per-frame", - .value = 34560, /* 4096x2160 */ + .value = 34816, /* 4096x2176 */ }, { .key = "qcom,max-hq-mbs-per-sec", - .value = 1036800, /* 4096x2160@30fps */ + .value = 1044480, /* 4096x2176@30fps */ }, { .key = "qcom,max-b-frame-mbs-per-frame", - .value = 32400, /* 3840x2160/256 */ + .value = 32640, /* 3840x2176/256 */ }, { .key = "qcom,max-b-frame-mbs-per-sec", - .value = 1944000, /* 3840x2160/256 MBs@60fps */ + .value = 1958400, /* 3840x2176/256 MBs@60fps */ }, { .key = "qcom,power-collapse-delay", From 0867a4fbe9fd603131761cd142a33d4e830a08bc Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Wed, 25 Sep 2019 12:30:54 -0700 Subject: [PATCH 195/452] msm: vidc: Add support to H264 CABAC bitrate Update HEVC, VP8, and H264 CABAC supported bitrate ranges. And also, added support to distinguish between H264 CABAC and CAVLC bitrate. Change-Id: I8e37aa78dbbc7e26faf99b9c1c27cba5a3462cb8 Signed-off-by: Akshata Sahukar Signed-off-by: Mihir Ganu --- msm/vidc/msm_venc.c | 43 ++++++++++++++++++++++++++++-------- msm/vidc/msm_vidc_platform.c | 4 +++- msm/vidc/vidc_hfi_api.h | 1 + 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 596404906973..18cc7a81f727 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1498,6 +1498,29 @@ static int msm_venc_resolve_rate_control(struct msm_vidc_inst *inst, return 0; } +static int msm_venc_update_bitrate(struct msm_vidc_inst *inst) +{ + u32 cabac_max_bitrate = 0; + + if (!inst) { + d_vpr_e("%s: invalid params %pK\n", __func__); + return -EINVAL; + } + + if (get_v4l2_codec(inst) == V4L2_PIX_FMT_H264) { + cabac_max_bitrate = inst->capability.cap[CAP_CABAC_BITRATE].max; + if ((inst->clk_data.bitrate > cabac_max_bitrate) && + (inst->entropy_mode == HFI_H264_ENTROPY_CABAC)) { + s_vpr_h(inst->sid, + "%s: update bitrate %u to max allowed cabac bitrate %u\n", + __func__, inst->clk_data.bitrate, + cabac_max_bitrate); + inst->clk_data.bitrate = cabac_max_bitrate; + } + } + return 0; +} + int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) { int rc = 0; @@ -1556,6 +1579,10 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDEO_BITRATE: inst->clk_data.bitrate = ctrl->val; if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_update_bitrate(inst); + if (rc) + s_vpr_e(sid, "%s: Update bitrate failed\n", + __func__); rc = msm_venc_set_bitrate(inst); if (rc) s_vpr_e(sid, "%s: set bitrate failed\n", @@ -2638,7 +2665,6 @@ int msm_venc_set_bitrate(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; - struct v4l2_ctrl *ctrl; struct hfi_bitrate bitrate; struct hfi_enable enable; @@ -2664,8 +2690,7 @@ int msm_venc_set_bitrate(struct msm_vidc_inst *inst) return rc; } - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE); - bitrate.bit_rate = ctrl->val; + bitrate.bit_rate = inst->clk_data.bitrate; bitrate.layer_id = MSM_VIDC_ALL_LAYER_ID; s_vpr_h(inst->sid, "%s: %d\n", __func__, bitrate.bit_rate); rc = call_hfi_op(hdev, session_set_property, inst->session, @@ -2681,12 +2706,12 @@ int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst) { int rc = 0, i = 0; struct hfi_device *hdev; - struct v4l2_ctrl *bitrate = NULL; struct v4l2_ctrl *layer = NULL; struct v4l2_ctrl *max_layer = NULL; struct v4l2_ctrl *layer_br_ratios[MAX_HIER_CODING_LAYER] = {NULL}; struct hfi_bitrate layer_br; struct hfi_enable enable; + u32 bitrate; if (!inst || !inst->core) { d_vpr_e("%s: invalid params %pK\n", __func__, inst); @@ -2753,10 +2778,10 @@ int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst) goto error; } - bitrate = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE); + bitrate = inst->clk_data.bitrate; for (i = 0; i < layer->val; ++i) { layer_br.bit_rate = - bitrate->val * layer_br_ratios[i]->val / 100; + bitrate * layer_br_ratios[i]->val / 100; layer_br.layer_id = i; s_vpr_h(inst->sid, "%s: Bitrate for Layer[%u]: [%u]\n", __func__, layer_br.layer_id, layer_br.bit_rate); @@ -4478,6 +4503,9 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) int rc = 0; rc = msm_venc_update_entropy_mode(inst); + if (rc) + goto exit; + rc = msm_venc_update_bitrate(inst); if (rc) goto exit; rc = handle_all_intra_restrictions(inst); @@ -4505,9 +4533,6 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) if (rc) goto exit; rc = msm_venc_set_8x8_transform(inst); - if (rc) - goto exit; - rc = msm_venc_set_bitrate(inst); if (rc) goto exit; rc = msm_venc_set_entropy_mode(inst); diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index e17008159ab4..b253ba924227 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -144,6 +144,8 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 64, 7833600, 1, 7833600}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 960, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 220000000, 1, 20000000}, + {CAP_BITRATE, ENC, HEVC, 1, 160000000, 1, 20000000}, + {CAP_CABAC_BITRATE, ENC, H264, 1, 160000000, 1, 20000000}, {CAP_SCALE_X, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, {CAP_SCALE_Y, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, {CAP_SCALE_X, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, @@ -176,7 +178,7 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { {CAP_FRAMERATE, ENC, VP8, 1, 60, 1, 30}, {CAP_FRAMERATE, DEC, VP8, 1, 120, 1, 30}, {CAP_BITRATE, ENC, VP8, 1, 74000000, 1, 20000000}, - {CAP_BITRATE, DEC, VP8, 1, 220000000, 1, 20000000}, + {CAP_BITRATE, DEC, VP8, 1, 100000000, 1, 20000000}, /* Mpeg2 decoder specific */ {CAP_FRAME_WIDTH, DEC, MPEG2, 128, 1920, 1, 1920}, diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 4231681f79b3..9bc915b52388 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -239,6 +239,7 @@ enum hal_capability { CAP_SCALE_X, CAP_SCALE_Y, CAP_BITRATE, + CAP_CABAC_BITRATE, CAP_BFRAME, CAP_PEAKBITRATE, CAP_HIER_P_NUM_ENH_LAYERS, From f15e24f19f9d7559b412d46504c25b33f995c9e5 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Mon, 14 Oct 2019 18:28:55 +0800 Subject: [PATCH 196/452] msm: vidc: support ROI map type query Add new ioctl to query the supported ROI map type. Based on vpu version, report whether support 2-bit type ROI map, or 2-byte type ROI map. Change-Id: I6db970f5f36e4cc61365867c2a07d63aaf9365ea Signed-off-by: Qiwei Liu Signed-off-by: Mihir Ganu --- include/uapi/vidc/media/msm_vidc_utils.h | 15 +++++++++++++++ msm/vidc/msm_venc.c | 20 ++++++++++++++++++++ msm/vidc/msm_vidc.c | 13 +++++++++++++ 3 files changed, 48 insertions(+) diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index a02c174b60c3..d8ef6f851a7a 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -247,6 +247,13 @@ enum v4l2_mpeg_vidc_video_stream_output_mode { V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY = 0, V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY = 1, }; +#define V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 128) +enum v4l2_mpeg_vidc_video_roi_type { + V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_NONE = 0, + V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_2BIT = 1, + V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_2BYTE = 2, +}; #define V4L2_CID_MPEG_VIDC_VIDEO_UNKNOWN \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 0xFFF) /* vendor controls end */ @@ -409,6 +416,14 @@ struct msm_vidc_roi_deltaqp_payload { __u32 data[1]; }; +struct msm_vidc_roi_qp_payload { + __s32 upper_qp_offset; + __s32 lower_qp_offset; + __u32 b_roi_info; + __u32 mbi_info_size; + __u32 data[1]; +}; + #define MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI 0x00000015 struct msm_vidc_mastering_display_colour_sei_payload { __u32 nDisplayPrimariesX[3]; diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 2ef7c58efd3e..2fe6a03bd046 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -73,6 +73,12 @@ static const char *const mpeg_video_stream_format[] = { NULL }; +static const char *const roi_map_type[] = { + "None", + "2-bit", + "2-bit", +}; + static struct msm_vidc_ctrl msm_venc_ctrls[] = { { .id = V4L2_CID_MPEG_VIDC_VIDEO_UNKNOWN, @@ -964,6 +970,20 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = (DEFAULT_FPS << 16), .step = 1, }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE, + .name = "ROI Type", + .type = V4L2_CTRL_TYPE_MENU, + .minimum = V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_NONE, + .maximum = V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_2BYTE, + .default_value = V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_NONE, + .menu_skip_mask = ~( + (1 << V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_NONE) | + (1 << V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_2BIT) | + (1 << V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_2BYTE) + ), + .qmenu = roi_map_type, + }, }; #define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index b6223678fcf2..85f76f3f683f 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1348,6 +1348,19 @@ static int try_get_ctrl_for_instance(struct msm_vidc_inst *inst, case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA: ctrl->val = inst->prop.extradata_ctrls; break; + case V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE: + { + uint32_t vpu_ver; + + if (!inst->core || !inst->core->platform_data) + return -EINVAL; + vpu_ver = inst->core->platform_data->vpu_ver; + ctrl->val = (vpu_ver == VPU_VERSION_IRIS1 || + vpu_ver == VPU_VERSION_IRIS2) ? + V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_2BYTE : + V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_2BIT; + break; + } default: break; } From 0d502cfe4811efff1c5b9e5a968e52b13374549b Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Thu, 31 Oct 2019 14:32:36 +0530 Subject: [PATCH 197/452] msm: vidc: Update capabilities for bengal Update few capabilities like B-frames, Max-MB's, Codecs for bengal target. Change-Id: I52bdf3e03ed78915aa3ca218cad89b6da938a606 Signed-off-by: Manikanta Kanamarlapudi Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_platform.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index b253ba924227..92c62fde23db 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -69,11 +69,8 @@ static struct msm_vidc_codec_data lahaina_codec_data[] = { static struct msm_vidc_codec_data bengal_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 50, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 50, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 50, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 50, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 50, 200, 200), }; @@ -105,13 +102,12 @@ static struct msm_vidc_codec_capability bengal_capabilities[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value} */ {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 1920, 1, 1920}, {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 1920, 1, 1080}, - /* ((1920 * 1080) / 256) */ - {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 8160, 1, 34560}, + /* ((1920 * 1088) / 256) */ + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 8160, 1, 8160}, /* 1080@30 decode + 1080@30 encode */ {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 486000, 1, 243000}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 120, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, - {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 4, 1, 0}, /* ((1920 * 1088) / 256) * 30 fps */ @@ -119,7 +115,6 @@ static struct msm_vidc_codec_capability bengal_capabilities[] = { 0, 244800, 1, 244800}, {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, - {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, /* 10 slices */ {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, @@ -130,7 +125,7 @@ static struct msm_vidc_codec_capability bengal_capabilities[] = { {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 1920, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 1920, 1, 1080}, /* (1920 * 1088) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 8160, 1, 34560}, + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 8160, 1, 8160}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, }; From 923758b884626a19f2ed695d78ae439cb1ca06ac Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Wed, 6 Nov 2019 16:37:37 +0530 Subject: [PATCH 198/452] msm: vidc: Add check to avoid NULL ptr dereference Check ubwc_config for not being NULL before dereferencing. Change-Id: Ia4c87ea4a0e963b33165b0ea9a9c39339cc65832 Signed-off-by: Dikshita Agarwal --- msm/vidc/msm_vidc_platform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 92c62fde23db..a6a45f6d0ec0 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -508,7 +508,8 @@ void *vidc_get_drv_data(struct device *dev) driver_data->ubwc_config->highest_bank_bit = 0xf; d_vpr_h("DDR Type 0x%x hbb 0x%x\n", - ddr_type, driver_data->ubwc_config->highest_bank_bit); + ddr_type, driver_data->ubwc_config ? + driver_data->ubwc_config->highest_bank_bit : -1); } exit: return driver_data; From 73fa002b9bf59493c297a59da6533fee89ead0f9 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Mon, 18 Nov 2019 10:41:24 +0800 Subject: [PATCH 199/452] msm: venc: set perf mode for HEIC buffers 1. Set perf mode for image session buffers so that they will be processed quickly. 2. Set max frequency for any turbo sessions. Change-Id: Icf9b0af5cffcd395356783a9ff7a9421a309f52c Signed-off-by: Shi Zhongbo --- msm/vidc/msm_vidc.c | 6 ++++++ msm/vidc/msm_vidc_clocks.c | 8 +++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 85f76f3f683f..beda8bbe46bf 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -370,6 +370,12 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, msm_comm_store_input_tag(&inst->etb_data, b->index, client_data->id, 0, inst->sid); } + /* + * set perf mode for image session buffers so that + * they will be processed quickly + */ + if (is_grid_session(inst) && b->type == INPUT_MPLANE) + b->flags |= V4L2_BUF_FLAG_PERF_MODE; q = msm_comm_get_vb2q(inst, b->type); if (!q) { diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index d975672d9159..d3d45e319b3c 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -851,11 +851,8 @@ int msm_comm_scale_clocks(struct msm_vidc_inst *inst) if (temp->vvb.vb2_buf.type == INPUT_MPLANE) { filled_len = max(filled_len, temp->vvb.vb2_buf.planes[0].bytesused); - if (inst->session_type == MSM_VIDC_ENCODER && - (temp->vvb.flags & - V4L2_BUF_FLAG_PERF_MODE)) { + if (temp->vvb.flags & V4L2_BUF_FLAG_PERF_MODE) is_turbo = true; - } device_addr = temp->smem[0].device_addr; } } @@ -866,7 +863,8 @@ int msm_comm_scale_clocks(struct msm_vidc_inst *inst) return 0; } - if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW || is_turbo) { + if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW || is_turbo || + is_turbo_session(inst)) { inst->clk_data.min_freq = msm_vidc_max_freq(inst->core, inst->sid); inst->clk_data.dcvs_flags = 0; From abe5948313765506c59e681786fa8d9582fc6687 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 20 Nov 2019 11:51:50 +0530 Subject: [PATCH 200/452] msm: vdec: reduce decoder input buffer count for > 480fps case For HFR(like 960 fps) usecases requires higher buffer count-24. But due to framework change(277033), We don't need any addtional buffers for HFR usecases also. So reducing the count back to 12. Change-Id: Ia3669858cde0962275d00f31d2bbb7308a3ce983 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_buffer_calculations.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index cf4379993bbf..97b302903ccf 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -20,7 +20,7 @@ #define BATCH_DEC_TOTAL_INPUT_BUFFERS 6 /* total input buffers for decoder HFR usecase (fps > 480) */ -#define HFR_DEC_TOTAL_MAX_INPUT_BUFFERS 24 +#define MAX_HFR_DEC_TOTAL_INPUT_BUFFERS 12 /* total input buffers for decoder HFR usecase */ #define HFR_DEC_TOTAL_INPUT_BUFFERS 12 @@ -800,7 +800,7 @@ static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst) inst->is_perf_eligible_session = true; if (fps > 480) extra_input_count = - (HFR_DEC_TOTAL_MAX_INPUT_BUFFERS - + (MAX_HFR_DEC_TOTAL_INPUT_BUFFERS - MIN_INPUT_BUFFERS); else extra_input_count = From 18c386f2f55913658fcfbd235292ad7ff2975e4e Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 27 Nov 2019 11:56:16 +0530 Subject: [PATCH 201/452] msm: venc: increase output buffer size only for hevc 10 bit support is available only for hevc codec type. So increase encoder output buffer size(factor - 1.25) only for hevc. Change-Id: I49f6bccc074814d8c737f47fd82907a018ac169a Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_buffer_calculations.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index cf4379993bbf..f10ec687dc86 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1014,15 +1014,9 @@ u32 msm_vidc_calculate_enc_output_frame_size(struct msm_vidc_inst *inst) if (inst->rc_type == RATE_CONTROL_LOSSLESS) frame_size = (width * height * 9) >> 2; - /* - * In case of opaque color format bitdepth will be known - * with first ETB, buffers allocated already with 8 bit - * won't be sufficient for 10 bit - * calculate size considering 10-bit by default - * For 10-bit cases size = size * 1.25 - */ - frame_size *= 5; - frame_size /= 4; + /* multiply by 10/8 (1.25) to get size for 10 bit case */ + if (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_HEVC) + frame_size = frame_size + (frame_size >> 2); return ALIGN(frame_size, SZ_4K); } From 45a07678d1e3c360e314f9850b04140f6adef8c8 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Tue, 26 Nov 2019 10:57:19 +0800 Subject: [PATCH 202/452] msm: venc: use output resolution for vbv delay Fix to use output port resolution to determine vbv delay. Change-Id: Id6dc80f1349d0f5b10be2fa6343fb98816156f58 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_venc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 2fe6a03bd046..9440c9717fc1 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2596,7 +2596,7 @@ int msm_venc_set_vbv_delay(struct msm_vidc_inst *inst) } hdev = inst->core->device; - f = &inst->fmts[INPUT_PORT].v4l2_fmt; + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; codec = get_v4l2_codec(inst); height = f->fmt.pix_mp.height; width = f->fmt.pix_mp.width; From 2b6da92f885fb4e1e0e9993507f0d5e6d649682e Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Wed, 27 Nov 2019 13:54:10 +0800 Subject: [PATCH 203/452] msm: vidc: fix CSC coefficients Fix to use correct CSC coefficients for BT601 to BT709 CSC. Change-Id: I8365603fed10151db0efbea0058bb896c419c3f4 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_vidc_platform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index a6a45f6d0ec0..2f2e50beaab6 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -242,12 +242,12 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { * 3x3 transformation matrix coefficients in s4.9 fixed point format */ static u32 vpe_csc_custom_matrix_coeff[HAL_MAX_MATRIX_COEFFS] = { - 470, 8170, 8148, 0, 490, 50, 0, 34, 483 + 440, 8140, 8098, 0, 460, 52, 0, 34, 463 }; /* offset coefficients in s9 fixed point format */ static u32 vpe_csc_custom_bias_coeff[HAL_MAX_BIAS_COEFFS] = { - 34, 0, 4 + 53, 0, 4 }; /* clamping value for Y/U/V([min,max] for Y/U/V) */ From c4f845c6e4e745fdff6876c81e2d90936a26ddd5 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Fri, 13 Sep 2019 16:21:55 +0530 Subject: [PATCH 204/452] msm-vidc: add bw calculation for ar50LT Add bw calculation logic for ar50LT. Change-Id: I326a2d1999248cc189922cb124732e087ad9ff9e Signed-off-by: Dikshita Agarwal --- msm/Makefile | 1 + msm/vidc/msm_vidc_bus.h | 2 + msm/vidc/msm_vidc_bus_ar50lite.c | 303 +++++++++++++++++++++++++++++++ 3 files changed, 306 insertions(+) create mode 100644 msm/vidc/msm_vidc_bus_ar50lite.c diff --git a/msm/Makefile b/msm/Makefile index db567398a19f..6aeea18bb290 100644 --- a/msm/Makefile +++ b/msm/Makefile @@ -18,6 +18,7 @@ msm-vidc-objs := vidc/msm_v4l2_vidc.o \ vidc/hfi_packetization.o \ vidc/vidc_hfi.o \ vidc/msm_vidc_clocks.o \ + vidc/msm_vidc_bus_ar50lite.o\ vidc/msm_vidc_bus_iris2.o \ vidc/msm_vidc_buffer_calculations.o diff --git a/msm/vidc/msm_vidc_bus.h b/msm/vidc/msm_vidc_bus.h index bde59a0c53d1..2e91ddddddcd 100644 --- a/msm/vidc/msm_vidc_bus.h +++ b/msm/vidc/msm_vidc_bus.h @@ -218,6 +218,8 @@ struct msm_vidc_bus_data { unsigned long total_bw_llcc; }; +int calc_bw_ar50lt(struct vidc_bus_vote_data *vidc_data); + int calc_bw_iris1(struct vidc_bus_vote_data *vidc_data); int calc_bw_iris2(struct vidc_bus_vote_data *vidc_data); diff --git a/msm/vidc/msm_vidc_bus_ar50lite.c b/msm/vidc/msm_vidc_bus_ar50lite.c new file mode 100644 index 000000000000..e8ba859daada --- /dev/null +++ b/msm/vidc/msm_vidc_bus_ar50lite.c @@ -0,0 +1,303 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include "msm_vidc_bus.h" +#include "msm_vidc_internal.h" + +static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d) +{ + return 0; +} + +static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) +{ + /* Encoder Parameters */ + int width, height, fps, bitrate, lcu_size; + + /* Derived Parameter */ + int search_range, lcu_per_frame; + fp_t y_bw; + bool is_h264_category = true; + fp_t orig_read_factor, recon_write_factor, + ref_y_read_factor, ref_c_read_factor, lb_factor, + rest_factor, total_read_factor, total_write_factor, + total_factor, overhead_factor; + + /* Output parameters */ + fp_t orig_read, recon_write, + ref_y_read, ref_c_read, + lb_read, lb_write, + bse_read, bse_write, + total_read, total_write, + total; + + unsigned long ret = 0; + + /* Encoder Fixed Parameters */ + overhead_factor = FP(1, 3, 100); + orig_read_factor = FP(1, 50, 100); /* L + C */ + recon_write_factor = FP(1, 50, 100); /* L + C */ + ref_c_read_factor = FP(0, 75, 100); /* 1.5/2 ( 1.5 Cache efficiency )*/ + lb_factor = FP(1, 25, 100); /* Worst case : HEVC 720p = 1.25 */ + + fps = d->fps; + width = max(d->output_width, BASELINE_DIMENSIONS.width); + height = max(d->output_height, BASELINE_DIMENSIONS.height); + bitrate = d->bitrate > 0 ? (d->bitrate + 1000000 - 1) / 1000000 : + __lut(width, height, fps)->bitrate; + lcu_size = d->lcu_size; + + /* Derived Parameters Setup*/ + lcu_per_frame = DIV_ROUND_UP(width, lcu_size) * + DIV_ROUND_UP(height, lcu_size); + + if (d->codec == HAL_VIDEO_CODEC_HEVC || + d->codec == HAL_VIDEO_CODEC_VP9) { + /* H264, VP8, MPEG2 use the same settings */ + /* HEVC, VP9 use the same setting */ + is_h264_category = false; + } + + search_range = 48; + + y_bw = fp_mult(fp_mult(FP_INT(width), FP_INT(height)), FP_INT(fps)); + y_bw = fp_div(y_bw, FP_INT(1000000)); + + ref_y_read_factor = fp_div(FP_INT(search_range * 2), FP_INT(lcu_size)); + ref_y_read_factor = ref_y_read_factor + FP_INT(1); + + rest_factor = FP_INT(bitrate) + fp_div(FP_INT(bitrate), FP_INT(8)); + rest_factor = fp_div(rest_factor, y_bw); + + total_read_factor = fp_div(rest_factor, FP_INT(2)) + + fp_div(lb_factor, FP_INT(2)); + total_read_factor = total_read_factor + orig_read_factor + + ref_y_read_factor + ref_c_read_factor; + + total_write_factor = fp_div(rest_factor, FP_INT(2)) + + fp_div(lb_factor, FP_INT(2)); + total_write_factor = total_write_factor + recon_write_factor; + + total_factor = total_read_factor + total_write_factor; + + orig_read = fp_mult(y_bw, orig_read_factor); + recon_write = fp_mult(y_bw, recon_write_factor); + ref_y_read = fp_mult(y_bw, ref_y_read_factor); + ref_c_read = fp_mult(y_bw, ref_c_read_factor); + lb_read = fp_div(fp_mult(y_bw, lb_factor), FP_INT(2)); + lb_write = lb_read; + bse_read = fp_mult(y_bw, fp_div(rest_factor, FP_INT(2))); + bse_write = bse_read; + + total_read = orig_read + ref_y_read + ref_c_read + + lb_read + bse_read; + total_write = recon_write + lb_write + bse_write; + + total = total_read + total_write; + total = fp_mult(total, overhead_factor); + + if (msm_vidc_debug & VIDC_BUS) { + struct dump dump[] = { + {"ENCODER PARAMETERS", "", DUMP_HEADER_MAGIC}, + {"width", "%d", width}, + {"height", "%d", height}, + {"fps", "%d", fps}, + {"bitrate (Mbit/sec)", "%lu", bitrate}, + {"lcu size", "%d", lcu_size}, + + {"DERIVED PARAMETERS", "", DUMP_HEADER_MAGIC}, + {"lcu/frame", "%d", lcu_per_frame}, + {"Y BW", DUMP_FP_FMT, y_bw}, + {"search range", "%d", search_range}, + {"original read factor", DUMP_FP_FMT, orig_read_factor}, + {"recon write factor", DUMP_FP_FMT, recon_write_factor}, + {"ref read Y factor", DUMP_FP_FMT, ref_y_read_factor}, + {"ref read C factor", DUMP_FP_FMT, ref_c_read_factor}, + {"lb factor", DUMP_FP_FMT, lb_factor}, + {"rest factor", DUMP_FP_FMT, rest_factor}, + {"total_read_factor", DUMP_FP_FMT, total_read_factor}, + {"total_write_factor", DUMP_FP_FMT, total_write_factor}, + {"total_factor", DUMP_FP_FMT, total_factor}, + {"overhead_factor", DUMP_FP_FMT, overhead_factor}, + + {"INTERMEDIATE B/W DDR", "", DUMP_HEADER_MAGIC}, + {"orig read", DUMP_FP_FMT, orig_read}, + {"recon write", DUMP_FP_FMT, recon_write}, + {"ref read Y", DUMP_FP_FMT, ref_y_read}, + {"ref read C", DUMP_FP_FMT, ref_c_read}, + {"lb read", DUMP_FP_FMT, lb_read}, + {"lb write", DUMP_FP_FMT, lb_write}, + {"bse read", DUMP_FP_FMT, bse_read}, + {"bse write", DUMP_FP_FMT, bse_write}, + {"total read", DUMP_FP_FMT, total_read}, + {"total write", DUMP_FP_FMT, total_write}, + {"total", DUMP_FP_FMT, total}, + }; + __dump(dump, ARRAY_SIZE(dump), d->sid); + } + + + d->calc_bw_ddr = kbps(fp_round(total)); + + return ret; +} + +static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) +{ + /* Decoder parameters */ + int width, height, fps, bitrate, lcu_size; + + /* Derived parameters */ + int lcu_per_frame, motion_complexity; + fp_t y_bw; + bool is_h264_category = true; + fp_t recon_write_factor, ref_read_factor, lb_factor, + rest_factor, opb_factor, + total_read_factor, total_write_factor, + total_factor, overhead_factor; + + /* Output parameters */ + fp_t opb_write, recon_write, + ref_read, + lb_read, lb_write, + bse_read, bse_write, + total_read, total_write, + total; + + unsigned long ret = 0; + + /* Decoder Fixed Parameters */ + overhead_factor = FP(1, 3, 100); + recon_write_factor = FP(1, 50, 100); /* L + C */ + opb_factor = FP(1, 50, 100); /* L + C */ + lb_factor = FP(1, 13, 100); /* Worst case : H264 1080p = 1.125 */ + motion_complexity = 5; /* worst case complexity */ + + fps = d->fps; + width = max(d->output_width, BASELINE_DIMENSIONS.width); + height = max(d->output_height, BASELINE_DIMENSIONS.height); + bitrate = d->bitrate > 0 ? (d->bitrate + 1000000 - 1) / 1000000 : + __lut(width, height, fps)->bitrate; + lcu_size = d->lcu_size; + + /* Derived Parameters Setup*/ + lcu_per_frame = DIV_ROUND_UP(width, lcu_size) * + DIV_ROUND_UP(height, lcu_size); + + if (d->codec == HAL_VIDEO_CODEC_HEVC || + d->codec == HAL_VIDEO_CODEC_VP9) { + /* H264, VP8, MPEG2 use the same settings */ + /* HEVC, VP9 use the same setting */ + is_h264_category = false; + } + + y_bw = fp_mult(fp_mult(FP_INT(width), FP_INT(height)), FP_INT(fps)); + y_bw = fp_div(y_bw, FP_INT(1000000)); + + ref_read_factor = FP(1, 50, 100); /* L + C */ + ref_read_factor = fp_mult(ref_read_factor, FP_INT(motion_complexity)); + + rest_factor = FP_INT(bitrate) + fp_div(FP_INT(bitrate), FP_INT(8)); + rest_factor = fp_div(rest_factor, y_bw); + + total_read_factor = fp_div(rest_factor, FP_INT(2)) + + fp_div(lb_factor, FP_INT(2)); + total_read_factor = total_read_factor + ref_read_factor; + + total_write_factor = fp_div(rest_factor, FP_INT(2)); + total_write_factor = total_write_factor + + recon_write_factor + opb_factor; + + total_factor = total_read_factor + total_write_factor; + + recon_write = fp_mult(y_bw, recon_write_factor); + ref_read = fp_mult(y_bw, ref_read_factor); + lb_read = fp_div(fp_mult(y_bw, lb_factor), FP_INT(2)); + lb_write = lb_read; + bse_read = fp_div(fp_mult(y_bw, rest_factor), FP_INT(2)); + bse_write = bse_read; + opb_write = fp_mult(y_bw, opb_factor); + + total_read = ref_read + lb_read + bse_read; + total_write = recon_write + lb_write + bse_write + opb_write; + + total = total_read + total_write; + total = fp_mult(total, overhead_factor); + + if (msm_vidc_debug & VIDC_BUS) { + struct dump dump[] = { + {"DECODER PARAMETERS", "", DUMP_HEADER_MAGIC}, + {"width", "%d", width}, + {"height", "%d", height}, + {"fps", "%d", fps}, + {"bitrate (Mbit/sec)", "%lu", bitrate}, + {"lcu size", "%d", lcu_size}, + + {"DERIVED PARAMETERS", "", DUMP_HEADER_MAGIC}, + {"lcu/frame", "%d", lcu_per_frame}, + {"Y BW", DUMP_FP_FMT, y_bw}, + {"motion complexity", "%d", motion_complexity}, + {"recon write factor", DUMP_FP_FMT, recon_write_factor}, + {"ref_read_factor", DUMP_FP_FMT, ref_read_factor}, + {"lb factor", DUMP_FP_FMT, lb_factor}, + {"rest factor", DUMP_FP_FMT, rest_factor}, + {"opb factor", DUMP_FP_FMT, opb_factor}, + {"total_read_factor", DUMP_FP_FMT, total_read_factor}, + {"total_write_factor", DUMP_FP_FMT, total_write_factor}, + {"total_factor", DUMP_FP_FMT, total_factor}, + {"overhead_factor", DUMP_FP_FMT, overhead_factor}, + + {"INTERMEDIATE B/W DDR", "", DUMP_HEADER_MAGIC}, + {"recon write", DUMP_FP_FMT, recon_write}, + {"ref read", DUMP_FP_FMT, ref_read}, + {"lb read", DUMP_FP_FMT, lb_read}, + {"lb write", DUMP_FP_FMT, lb_write}, + {"bse read", DUMP_FP_FMT, bse_read}, + {"bse write", DUMP_FP_FMT, bse_write}, + {"opb write", DUMP_FP_FMT, opb_write}, + {"total read", DUMP_FP_FMT, total_read}, + {"total write", DUMP_FP_FMT, total_write}, + {"total", DUMP_FP_FMT, total}, + }; + __dump(dump, ARRAY_SIZE(dump), d->sid); + } + + d->calc_bw_ddr = kbps(fp_round(total)); + + return ret; +} + +static unsigned long __calculate(struct vidc_bus_vote_data *d) +{ + unsigned long value = 0; + + switch (d->domain) { + case HAL_VIDEO_DOMAIN_VPE: + value = __calculate_vpe(d); + break; + case HAL_VIDEO_DOMAIN_ENCODER: + value = __calculate_encoder(d); + break; + case HAL_VIDEO_DOMAIN_DECODER: + value = __calculate_decoder(d); + break; + default: + s_vpr_e(d->sid, "Unknown Domain %#x", d->domain); + } + + return value; +} + +int calc_bw_ar50lt(struct vidc_bus_vote_data *vidc_data) +{ + int ret = 0; + + if (!vidc_data) + return ret; + + ret = __calculate(vidc_data); + + return ret; +} From f0cfef24405b3f1872c7735e0fe56dae8514d477 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Wed, 27 Nov 2019 18:30:39 +0530 Subject: [PATCH 205/452] msm: vidc: Fix Power Collapse issue Driver is not polling for the PC Ready to be set and truning of the regulators/clocks. Fix the same. H2X Interrupt has to be enabled for every boot. CRs-Fixed: 2572953 Change-Id: Ib24b35dcebedf464bcd461718a18e732531ea4ce Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/hfi_ar50_lt.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/msm/vidc/hfi_ar50_lt.c b/msm/vidc/hfi_ar50_lt.c index e39a7cd0885f..f883cdfc8d26 100644 --- a/msm/vidc/hfi_ar50_lt.c +++ b/msm/vidc/hfi_ar50_lt.c @@ -53,6 +53,7 @@ /* VIDC_UC_REGION_ADDR */ #define VIDC_CPU_CS_SCIBARG2_AR50_LT (VIDC_CPU_CS_BASE_OFFS_AR50_LT + 0x68) +#define VIDC_CPU_IC_SOFTINT_EN_AR50_LT (VIDC_CPU_IC_BASE_OFFS_AR50_LT + 0x148) #define VIDC_CPU_IC_SOFTINT_AR50_LT (VIDC_CPU_IC_BASE_OFFS_AR50_LT + 0x150) #define VIDC_CPU_IC_SOFTINT_H2A_BMSK_AR50_LT 0x8000 #define VIDC_CPU_IC_SOFTINT_H2A_SHFT_AR50_LT 0x1 @@ -92,6 +93,15 @@ #define VIDC_WRAPPER_INTR_CLEAR_A2H_BMSK_AR50_LT 0x4 #define VIDC_WRAPPER_INTR_CLEAR_A2H_SHFT_AR50_LT 0x2 +/* + * -------------------------------------------------------------------------- + * MODULE: tz_wrapper + * -------------------------------------------------------------------------- + */ +#define VIDC_WRAPPER_TZ_BASE_OFFS 0x000C0000 +#define VIDC_WRAPPER_TZ_CPU_CLOCK_CONFIG (VIDC_WRAPPER_TZ_BASE_OFFS) +#define VIDC_WRAPPER_TZ_CPU_STATUS (VIDC_WRAPPER_TZ_BASE_OFFS + 0x10) + #define VIDC_CTRL_INIT_AR50_LT VIDC_CPU_CS_SCIACMD_AR50_LT #define VIDC_CTRL_STATUS_AR50_LT VIDC_CPU_CS_SCIACMDARG0_AR50_LT @@ -156,6 +166,7 @@ int __prepare_pc_ar50_lt(struct venus_hfi_device *device) int rc = 0; u32 wfi_status = 0, idle_status = 0, pc_ready = 0; u32 ctrl_status = 0; + u32 count = 0, max_tries = 10; ctrl_status = __read_register(device, VIDC_CTRL_STATUS_AR50_LT, DEFAULT_SID); pc_ready = ctrl_status & VIDC_CTRL_STATUS_PC_READY_AR50_LT; @@ -165,11 +176,37 @@ int __prepare_pc_ar50_lt(struct venus_hfi_device *device) d_vpr_l("Already in pc_ready state\n"); return 0; } + + wfi_status = BIT(0) & __read_register(device, + VIDC_WRAPPER_TZ_CPU_STATUS, DEFAULT_SID); + if (!wfi_status || !idle_status) { + d_vpr_e("Skipping PC, wfi status not set\n"); + goto skip_power_off; + } + rc = __prepare_pc(device); if (rc) { d_vpr_e("Failed __prepare_pc %d\n", rc); goto skip_power_off; } + + while (count < max_tries) { + wfi_status = BIT(0) & __read_register(device, + VIDC_WRAPPER_TZ_CPU_STATUS, DEFAULT_SID); + ctrl_status = __read_register(device, + VIDC_CTRL_STATUS_AR50_LT, DEFAULT_SID); + pc_ready = ctrl_status & VIDC_CTRL_STATUS_PC_READY_AR50_LT; + if (wfi_status && pc_ready) + break; + usleep_range(150, 250); + count++; + } + + if (count == max_tries) { + d_vpr_e("Skip PC. Core is not in right state\n"); + goto skip_power_off; + } + return rc; skip_power_off: @@ -234,5 +271,8 @@ int __boot_firmware_ar50_lt(struct venus_hfi_device *device, u32 sid) s_vpr_e(sid, "Error booting up vidc firmware\n"); rc = -ETIME; } + + /* Enable interrupt before sending commands to venus */ + __write_register(device, VIDC_CPU_IC_SOFTINT_EN_AR50_LT, 0x1, sid); return rc; } From a0e884a3b02a13a3864baed8b010cd7e851050ce Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Fri, 15 Nov 2019 16:13:31 +0800 Subject: [PATCH 206/452] msm: venc: set operating rate to 1 for HEIC Set operating rate to 1 by force for HEIC, so as to avoid overloads. Change-Id: If3f980e096c7e30368b9c6a280e78bbe1625e87a Signed-off-by: Shi Zhongbo --- msm/vidc/msm_venc.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 9440c9717fc1..c0c3c1d795fc 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1671,6 +1671,12 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: inst->clk_data.operating_rate = ctrl->val; + /* For HEIC image encode, set operating rate to 1 */ + if (is_grid_session(inst)) { + s_vpr_h(sid, "%s: set operating rate to 1 for HEIC\n", + __func__); + inst->clk_data.operating_rate = 1 << 16; + } inst->flags &= ~VIDC_TURBO; if (ctrl->val == INT_MAX) inst->flags |= VIDC_TURBO; @@ -1910,6 +1916,9 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) s_vpr_h(sid, "%s: set fps to 1 for HEIC\n", __func__); inst->clk_data.frame_rate = 1 << 16; + s_vpr_h(sid, "%s: set operating rate to 1 for HEIC\n", + __func__); + inst->clk_data.operating_rate = 1 << 16; } break; case V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE: @@ -2191,7 +2200,6 @@ int msm_venc_set_operating_rate(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; - struct v4l2_ctrl *ctrl; struct hfi_operating_rate op_rate; if (!inst || !inst->core) { @@ -2200,9 +2208,7 @@ int msm_venc_set_operating_rate(struct msm_vidc_inst *inst) } hdev = inst->core->device; - - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE); - op_rate.operating_rate = ctrl->val; + op_rate.operating_rate = inst->clk_data.operating_rate; s_vpr_h(inst->sid, "%s: %d\n", __func__, op_rate.operating_rate >> 16); rc = call_hfi_op(hdev, session_set_property, inst->session, From fb13af1aa4e82c33aa91082339bd62559ad0ebb7 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Tue, 12 Nov 2019 15:07:28 +0530 Subject: [PATCH 207/452] msm: vidc: Add video param capabilities Add heic & B-frame QP capabilities for bengal target. CRs-Fixed: 2558188 Change-Id: I3bfd4f2fc83792395e0a6bd9b4596d7823f92bc8 Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_platform.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 2f2e50beaab6..3e20e57dca95 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -115,6 +115,7 @@ static struct msm_vidc_codec_capability bengal_capabilities[] = { 0, 244800, 1, 244800}, {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, /* 10 slices */ {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, @@ -127,6 +128,12 @@ static struct msm_vidc_codec_capability bengal_capabilities[] = { /* (1920 * 1088) / 256 */ {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 8160, 1, 8160}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, + + /* Image specific */ + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 1, 8192}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192}, }; static struct msm_vidc_codec_capability lahaina_capabilities[] = { From 6fe257d27f92762447d8c7c338e641c589f0c01c Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Thu, 5 Dec 2019 11:16:46 +0800 Subject: [PATCH 208/452] msm: venc: fix custom matrix enablement Fix to set 7 instead of 1 to firmware to enable all custom bias, matrix and limit. Change-Id: Idd8bf0f6036ef2919855f379fffa51d5339eba1d Signed-off-by: Shi Zhongbo --- msm/vidc/msm_venc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index c0c3c1d795fc..1f25e4c65116 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1261,7 +1261,7 @@ static int msm_venc_set_csc(struct msm_vidc_inst *inst, vpe_csc.input_color_primaries = color_primaries; /* Custom bias, matrix & limit */ - vpe_csc.custom_matrix_enabled = custom_matrix; + vpe_csc.custom_matrix_enabled = custom_matrix ? 7 : 0; if (vpe_csc.custom_matrix_enabled && bias_coeff != NULL && csc_limit != NULL && csc_matrix != NULL) { From 57b101caf90671f9647d3a01ff81ce30d7ae3f4e Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Fri, 22 Nov 2019 15:01:11 +0530 Subject: [PATCH 209/452] msm: vidc: Update bitrate and frame-size capabilities Update max bitrate, min frame width & height. Add cabac bitrate capability. CRs-Fixed: 2572200 Change-Id: I41caf4100a2f018d295fb9d802eb8353f9e67168 Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_platform.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 3e20e57dca95..320addaeb03b 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -100,19 +100,20 @@ static struct msm_vidc_codec default_codecs[] = { static struct msm_vidc_codec_capability bengal_capabilities[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value} */ - {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 1920, 1, 1920}, - {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 1920, 1, 1080}, + {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1080}, /* ((1920 * 1088) / 256) */ - {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 8160, 1, 8160}, + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 8160, 1, 8160}, /* 1080@30 decode + 1080@30 encode */ - {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 486000, 1, 243000}, + {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 64, 486000, 1, 243000}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 120, 1, 30}, - {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, + {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 60000000, 1, 20000000}, {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 4, 1, 0}, /* ((1920 * 1088) / 256) * 30 fps */ {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, 0, 244800, 1, 244800}, + {CAP_CABAC_BITRATE, ENC, H264, 1, 60000000, 1, 20000000}, {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, @@ -123,11 +124,11 @@ static struct msm_vidc_codec_capability bengal_capabilities[] = { {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, /* Secure usecase specific */ - {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 96, 1920, 1, 1920}, - {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 96, 1920, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1080}, /* (1920 * 1088) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 8160, 1, 8160}, - {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 8160, 1, 8160}, + {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 35000000, 1, 20000000}, /* Image specific */ {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, From c7abb94cc3ce669baf6144a7b950715ffc03cf88 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 16 Oct 2019 11:38:37 +0530 Subject: [PATCH 210/452] msm: vidc: add 32 bit support in video driver The commit adds the following 1 Keep DMA mask aligned with api definition. 2 Replace the various division operations with 32 bit compatible modules. Change-Id: I7bc931ffd124ef2b0be8d2bec44fbebf29d4cfb3 Signed-off-by: Vikash Garodia Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_clocks.c | 26 +++++++++++++------------- msm/vidc/msm_vidc_common.c | 8 ++++---- msm/vidc/msm_vidc_res_parse.c | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index d3d45e319b3c..ba9440fc86d9 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -583,7 +583,7 @@ static unsigned long msm_vidc_calc_freq_ar50_lt(struct msm_vidc_inst *inst, vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles; /* 10 / 7 is overhead factor */ - vsp_cycles += ((fps * filled_len * 8) * 10) / 7; + vsp_cycles += div_u64((fps * filled_len * 8 * 10), 7); } else { s_vpr_e(inst->sid, "%s: Unknown session type\n", __func__); @@ -651,17 +651,17 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, if (msm_comm_g_ctrl_for_id(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES)) vpp_cycles += vpp_cycles / 4; /* 21 / 20 is minimum overhead factor */ - vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles); + vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles); /* 1.01 is multi-pipe overhead */ if (inst->clk_data.work_route > 1) - vpp_cycles += vpp_cycles / 100; + vpp_cycles += div_u64(vpp_cycles, 100); /* * 1080p@480fps usecase needs exactly 338MHz * without any margin left. Hence, adding 2 percent * extra to bump it to next level (366MHz). */ if (fps == 480) - vpp_cycles += vpp_cycles * 2 / 100; + vpp_cycles += div_u64(vpp_cycles * 2, 100); /* VSP */ /* bitrate is based on fps, scale it using operating rate */ @@ -671,17 +671,17 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, vsp_factor_num = operating_rate; vsp_factor_den = inst->clk_data.frame_rate >> 16; } - vsp_cycles = ((u64)inst->clk_data.bitrate * vsp_factor_num) / - vsp_factor_den; + vsp_cycles = div_u64(((u64)inst->clk_data.bitrate * + vsp_factor_num), vsp_factor_den); base_cycles = inst->clk_data.entry->vsp_cycles; if (inst->entropy_mode == HFI_H264_ENTROPY_CABAC) { - vsp_cycles = (vsp_cycles * 135) / 100; + vsp_cycles = div_u64(vsp_cycles * 135, 100); } else { base_cycles = 0; - vsp_cycles = vsp_cycles / 2; + vsp_cycles = div_u64(vsp_cycles, 2); /* VSP FW Overhead 1.05 */ - vsp_cycles = (vsp_cycles * 21) / 20; + vsp_cycles = div_u64(vsp_cycles * 21, 20); } if (inst->clk_data.work_mode == HFI_WORKMODE_1) @@ -697,18 +697,18 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles); /* 1.059 is multi-pipe overhead */ if (inst->clk_data.work_route > 1) - vpp_cycles += vpp_cycles * 59 / 1000; + vpp_cycles += div_u64(vpp_cycles * 59, 1000); /* VSP */ base_cycles = inst->clk_data.entry->vsp_cycles; vsp_cycles = fps * filled_len * 8; if (inst->entropy_mode == HFI_H264_ENTROPY_CABAC) { - vsp_cycles = (vsp_cycles * 135) / 100; + vsp_cycles = div_u64(vsp_cycles * 135, 100); } else { base_cycles = 0; - vsp_cycles = vsp_cycles / 2; + vsp_cycles = div_u64(vsp_cycles, 2); /* VSP FW Overhead 1.05 */ - vsp_cycles = vsp_cycles * 21 / 20; + vsp_cycles = div_u64(vsp_cycles * 21, 20); } if (inst->clk_data.work_mode == HFI_WORKMODE_1) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index f6facbfcc156..e822174d5083 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7187,10 +7187,10 @@ int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, inst->core->resources.allowed_clks_tbl[0].clock_rate / fps - inst->clk_data.entry->vsp_cycles * msm_vidc_get_mbs_per_frame(inst); - max_avg_frame_size = (u64)max_frame_size * 100 * - (window_size + window_buffer) / (window_size * 135); - max_frame_size = (u64)max_frame_size * 100 * - (1 + window_buffer) / 135; + max_avg_frame_size = div_u64((u64)max_frame_size * 100 * + (window_size + window_buffer), (window_size * 135)); + max_frame_size = div_u64((u64)max_frame_size * 100 * + (1 + window_buffer), 135); frame_size = frame_data->filled_len; window_start = inst->count.etb; diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index ef7c487fe58d..223343a00294 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -942,7 +942,7 @@ static int msm_vidc_setup_context_bank(struct msm_vidc_platform_resources *res, dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), GFP_KERNEL); dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); - dma_set_seg_boundary(dev, DMA_BIT_MASK(64)); + dma_set_seg_boundary(dev, (unsigned long)DMA_BIT_MASK(64)); d_vpr_h("Attached %s and created mapping\n", dev_name(dev)); d_vpr_h( From bcd5ad8e903c95c1f081e53a3daedcd8fb149df1 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 5 Nov 2019 15:11:46 -0800 Subject: [PATCH 211/452] msm: vidc: Update cycle count for vpx VPx cycle requirement is not same as CABAC. Hence update required as per system recommendation. CRs-Fixed: 2560714 Change-Id: If600bc9c4abb364dba5f807c944976be992567c9 Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc_clocks.c | 12 ++++++++++-- msm/vidc/msm_vidc_platform.c | 6 +++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index ba9440fc86d9..9ad69717600a 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -622,6 +622,7 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, struct clock_data *dcvs = NULL; u32 operating_rate, vsp_factor_num = 1, vsp_factor_den = 1; u32 base_cycles = 0; + u32 codec = 0; core = inst->core; dcvs = &inst->clk_data; @@ -674,8 +675,11 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, vsp_cycles = div_u64(((u64)inst->clk_data.bitrate * vsp_factor_num), vsp_factor_den); + codec = get_v4l2_codec(inst); base_cycles = inst->clk_data.entry->vsp_cycles; - if (inst->entropy_mode == HFI_H264_ENTROPY_CABAC) { + if (codec == V4L2_PIX_FMT_VP8 || codec == V4L2_PIX_FMT_VP9) { + vsp_cycles = div_u64(vsp_cycles * 170, 100); + } else if (inst->entropy_mode == HFI_H264_ENTROPY_CABAC) { vsp_cycles = div_u64(vsp_cycles * 135, 100); } else { base_cycles = 0; @@ -700,9 +704,13 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, vpp_cycles += div_u64(vpp_cycles * 59, 1000); /* VSP */ + codec = get_v4l2_codec(inst); base_cycles = inst->clk_data.entry->vsp_cycles; vsp_cycles = fps * filled_len * 8; - if (inst->entropy_mode == HFI_H264_ENTROPY_CABAC) { + + if (codec == V4L2_PIX_FMT_VP8 || codec == V4L2_PIX_FMT_VP9) { + vsp_cycles = div_u64(vsp_cycles * 170, 100); + } else if (inst->entropy_mode == HFI_H264_ENTROPY_CABAC) { vsp_cycles = div_u64(vsp_cycles * 135, 100); } else { base_cycles = 0; diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 320addaeb03b..29eed30e50db 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -58,12 +58,12 @@ static struct msm_vidc_codec_data default_codec_data[] = { static struct msm_vidc_codec_data lahaina_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 25, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 25, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 25, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 60, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 25, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 25, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 25, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 25, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 25, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 60, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 60, 200, 200), }; static struct msm_vidc_codec_data bengal_codec_data[] = { From a88ec175cd72790f07ef59c56c825e55b0f1a30f Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Wed, 13 Nov 2019 16:48:29 +0530 Subject: [PATCH 212/452] msm: vidc: update core ops for AR50LT bus calculation Update core ops to invoke calc_bw_ar50lt API to calculate bus bw requirement for ar50lt. Change-Id: I1c8e1766d9aa2f8ad44498587b171c2827759ddb Signed-off-by: Dikshita Agarwal Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_bus_ar50lite.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/msm/vidc/msm_vidc_bus_ar50lite.c b/msm/vidc/msm_vidc_bus_ar50lite.c index e8ba859daada..d98592703d6c 100644 --- a/msm/vidc/msm_vidc_bus_ar50lite.c +++ b/msm/vidc/msm_vidc_bus_ar50lite.c @@ -6,11 +6,6 @@ #include "msm_vidc_bus.h" #include "msm_vidc_internal.h" -static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d) -{ - return 0; -} - static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) { /* Encoder Parameters */ @@ -274,9 +269,6 @@ static unsigned long __calculate(struct vidc_bus_vote_data *d) unsigned long value = 0; switch (d->domain) { - case HAL_VIDEO_DOMAIN_VPE: - value = __calculate_vpe(d); - break; case HAL_VIDEO_DOMAIN_ENCODER: value = __calculate_encoder(d); break; From ea096260e8aff544b0dc9a4fb46f416b2bc98aeb Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Sat, 23 Nov 2019 22:42:14 +0530 Subject: [PATCH 213/452] msm: vidc: Fix core id value Add definition for decide_core_and_power_mode to fix the core id issue. Wrong core id results in incorrect clock values. CRs-Fixed: 2572953 Change-Id: I2219df71f555fb34a69146821997bab5fa8971a9 Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_clocks.c | 9 ++++++++- msm/vidc/msm_vidc_clocks.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 9ad69717600a..05347934e499 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -26,7 +26,8 @@ struct msm_vidc_core_ops core_ops_ar50_lt = { .calc_freq = msm_vidc_calc_freq_ar50_lt, .decide_work_route = NULL, .decide_work_mode = msm_vidc_decide_work_mode_ar50_lt, - .decide_core_and_power_mode = NULL, + .decide_core_and_power_mode = + msm_vidc_decide_core_and_power_mode_ar50lt, .calc_bw = NULL, }; @@ -1274,6 +1275,12 @@ static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, return rc; } +int msm_vidc_decide_core_and_power_mode_ar50lt(struct msm_vidc_inst *inst) +{ + inst->clk_data.core_id = VIDC_CORE_ID_1; + return 0; +} + int msm_vidc_decide_core_and_power_mode_iris2(struct msm_vidc_inst *inst) { u32 mbpf, mbps, max_hq_mbpf, max_hq_mbps; diff --git a/msm/vidc/msm_vidc_clocks.h b/msm/vidc/msm_vidc_clocks.h index 7a2be7e613b1..5d649ab9f301 100644 --- a/msm/vidc/msm_vidc_clocks.h +++ b/msm/vidc/msm_vidc_clocks.h @@ -25,6 +25,7 @@ int msm_vidc_decide_work_route_iris1(struct msm_vidc_inst *inst); int msm_vidc_decide_work_mode_iris1(struct msm_vidc_inst *inst); int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst); int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst); +int msm_vidc_decide_core_and_power_mode_ar50lt(struct msm_vidc_inst *inst); int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst); int msm_vidc_decide_core_and_power_mode_iris2(struct msm_vidc_inst *inst); void msm_print_core_status(struct msm_vidc_core *core, u32 core_id, u32 sid); From 7eb97316b0853ae717f6308904865bcce14f43ca Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Sun, 1 Dec 2019 15:08:15 +0530 Subject: [PATCH 214/452] msm: vidc: Update bengal Profile Level Capabilities Update HEVC Enc/Dec, AVC Enc/Dec profile level capabilities to align with PRD specifications. CRs-Fixed: 2578525 Change-Id: Iff81bcbffe7034a00cd5df9f3f6e35e9500d5c77 Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_platform.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 29eed30e50db..0a988d7d7460 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -135,6 +135,27 @@ static struct msm_vidc_codec_capability bengal_capabilities[] = { {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 1, 8192}, {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192}, + + /* Level for AVC and HEVC encoder specific. + * Default for levels is UNKNOWN value. But if we use unknown + * value here to set as default, max value needs to be set to + * unknown as well, which creates a problem of allowing client + * to set higher level than supported + */ + {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_1}, + {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1}, + + /* Level for AVC and HEVC decoder specific */ + {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_1}, + {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1}, }; static struct msm_vidc_codec_capability lahaina_capabilities[] = { From f1e149c74a29787097beb9ec5ab0897f365d080b Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 11 Dec 2019 11:02:13 +0530 Subject: [PATCH 215/452] msm: vidc: remove additional checks in response_handler possibility of OOB access on device->response_pkt in __response_handler. for e.x if msg queue contains 1000 messages and all 1000 were read and queue is empty. So __get_q_size api will return zero and _iface_msgq_read will go in an infinite loop, even if packet_count == max_packets. Change-Id: I3c0fb095feff0ba5d4d6dab65ed9d5111f1b6f05 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_common.c | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 728bf8b73e6c..28bfbab2498f 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -1740,34 +1740,6 @@ static int venus_hfi_core_release(void *dev) return rc; } -static int __get_q_size(struct venus_hfi_device *dev, unsigned int q_index) -{ - struct hfi_queue_header *queue; - struct vidc_iface_q_info *q_info; - u32 write_ptr, read_ptr; - - if (q_index >= VIDC_IFACEQ_NUMQ) { - d_vpr_e("Invalid q index: %d\n", q_index); - return -ENOENT; - } - - q_info = &dev->iface_queues[q_index]; - if (!q_info) { - d_vpr_e("cannot read shared Q's\n"); - return -ENOENT; - } - - queue = (struct hfi_queue_header *)q_info->q_hdr; - if (!queue) { - d_vpr_e("queue not present\n"); - return -ENOENT; - } - - write_ptr = (u32)queue->qhdr_write_idx; - read_ptr = (u32)queue->qhdr_read_idx; - return read_ptr - write_ptr; -} - static int venus_hfi_core_trigger_ssr(void *device, enum hal_ssr_trigger_type type) { @@ -2795,8 +2767,7 @@ static int __response_handler(struct venus_hfi_device *device) *inst_id = session->inst_id; } - if (packet_count >= max_packets && - __get_q_size(device, VIDC_IFACEQ_MSGQ_IDX)) { + if (packet_count >= max_packets) { d_vpr_e( "Too many packets in message queue to handle at once, deferring read\n"); break; From 05126a1245c61f2bd98ca61819b2723915fe85ea Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 13 Dec 2019 18:58:22 +0530 Subject: [PATCH 216/452] msm: vidc: avoid OOB write while accessing memory Exclude 4 bytes which holds the size of the buffer while calculating the actual buffer size to avoid OOB write. Change-Id: I965e78097a3680065aaf7609d35af1a42fc44824 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_common.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 28bfbab2498f..523475a9762a 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -2511,20 +2511,19 @@ static int __power_collapse(struct venus_hfi_device *device, bool force) return -EAGAIN; } -static void __process_sys_error(struct venus_hfi_device *device) +static void print_sfr_message(struct venus_hfi_device *device) { struct hfi_sfr_struct *vsfr = NULL; + u32 vsfr_size = 0; + void *p = NULL; vsfr = (struct hfi_sfr_struct *)device->sfr.align_virtual_addr; if (vsfr) { - void *p = memchr(vsfr->rg_data, '\0', vsfr->bufSize); - /* - * SFR isn't guaranteed to be NULL terminated - * since SYS_ERROR indicates that Venus is in the - * process of crashing. - */ + vsfr_size = vsfr->bufSize - sizeof(u32); + p = memchr(vsfr->rg_data, '\0', vsfr_size); + /* SFR isn't guaranteed to be NULL terminated */ if (p == NULL) - vsfr->rg_data[vsfr->bufSize - 1] = '\0'; + vsfr->rg_data[vsfr_size - 1] = '\0'; d_vpr_e("SFR Message from FW: %s\n", vsfr->rg_data); } @@ -2661,8 +2660,6 @@ static int __response_handler(struct venus_hfi_device *device) } if (call_venus_op(device, watchdog, device->intr_status)) { - struct hfi_sfr_struct *vsfr = (struct hfi_sfr_struct *) - device->sfr.align_virtual_addr; struct msm_vidc_cb_info info = { .response_type = HAL_SYS_WATCHDOG_TIMEOUT, .response.cmd = { @@ -2670,8 +2667,7 @@ static int __response_handler(struct venus_hfi_device *device) } }; - if (vsfr) - d_vpr_e("SFR Message from FW: %s\n", vsfr->rg_data); + print_sfr_message(device); d_vpr_e("Received watchdog timeout\n"); packets[packet_count++] = info; @@ -2695,7 +2691,7 @@ static int __response_handler(struct venus_hfi_device *device) /* Process the packet types that we're interested in */ switch (info->response_type) { case HAL_SYS_ERROR: - __process_sys_error(device); + print_sfr_message(device); break; case HAL_SYS_RELEASE_RESOURCE_DONE: d_vpr_h("Received SYS_RELEASE_RESOURCE\n"); From 946f83bbd4771d6141f9c30d56760db69641399f Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Fri, 15 Nov 2019 13:35:01 +0530 Subject: [PATCH 217/452] msm: vidc: Update clock cycles Update clock cycles of vsp and vpp required for per MB in bengal target. CRs-Fixed: 2558188 Change-Id: Ifa39458123dfe2b687b0865e119e23aaf5613713 Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_platform.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 0a988d7d7460..492a0fa4b5ee 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -67,11 +67,11 @@ static struct msm_vidc_codec_data lahaina_codec_data[] = { }; static struct msm_vidc_codec_data bengal_codec_data[] = { - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 125, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 50, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 50, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 50, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 0, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 0, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 0, 440, 440), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 0, 440, 440), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 0, 440, 440), }; #define ENC HAL_VIDEO_DOMAIN_ENCODER From e81728b7b659dca5b5c25e6c7bb7c588f91380a5 Mon Sep 17 00:00:00 2001 From: Malathi Gottam Date: Tue, 19 Nov 2019 20:20:59 +0530 Subject: [PATCH 218/452] msm: vidc: determine sku version based on ddr rank Based on the ddr rank info, sku version is set. Change-Id: I1823585553bad65462e047a5bebc6d93716c7703 Signed-off-by: Malathi Gottam Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_platform.c | 156 ++++++++++++++++++++++++++++++++--- 1 file changed, 144 insertions(+), 12 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 492a0fa4b5ee..d9491df8f6bc 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -98,14 +98,74 @@ static struct msm_vidc_codec default_codecs[] = { {ENC, H264}, {ENC, HEVC}, {ENC, VP8}, }; -static struct msm_vidc_codec_capability bengal_capabilities[] = { +static struct msm_vidc_codec_capability bengal_capabilities_v0[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value} */ {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1920}, {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1080}, /* ((1920 * 1088) / 256) */ {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 8160, 1, 8160}, /* 1080@30 decode + 1080@30 encode */ - {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 64, 486000, 1, 243000}, + {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 64, 489600, 1, 244800}, + {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 120, 1, 30}, + {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 60000000, 1, 20000000}, + {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, + {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 4, 1, 0}, + /* ((1920 * 1088) / 256) * 30 fps */ + {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, + 0, 244800, 1, 244800}, + {CAP_CABAC_BITRATE, ENC, H264, 1, 60000000, 1, 20000000}, + {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, + {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + + /* 10 slices */ + {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_SLICE_MB, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, + + /* Secure usecase specific */ + {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1080}, + /* (1920 * 1088) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 8160, 1, 8160}, + {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 35000000, 1, 20000000}, + + /* Image specific */ + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 1, 8192}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192}, + + /* Level for AVC and HEVC encoder specific. + * Default for levels is UNKNOWN value. But if we use unknown + * value here to set as default, max value needs to be set to + * unknown as well, which creates a problem of allowing client + * to set higher level than supported + */ + {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_1}, + {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1}, + + /* Level for AVC and HEVC decoder specific */ + {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_1}, + {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1}, +}; + +static struct msm_vidc_codec_capability bengal_capabilities_v1[] = { + /* {cap_type, domains, codecs, min, max, step_size, default_value} */ + {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1080}, + /* ((1920 * 1088) / 256) */ + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 8160, 1, 8160}, + /* 1920*1088 @30fps */ + {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 64, 244800, 1, 244800}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 120, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 60000000, 1, 20000000}, {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, @@ -374,7 +434,7 @@ static struct msm_vidc_common_data lahaina_common_data[] = { }, }; -static struct msm_vidc_common_data bengal_common_data[] = { +static struct msm_vidc_common_data bengal_common_data_v0[] = { { .key = "qcom,never-unload-fw", .value = 1, @@ -389,11 +449,11 @@ static struct msm_vidc_common_data bengal_common_data[] = { }, { .key = "qcom,max-secure-instances", - .value = 5, + .value = 3, }, { .key = "qcom,max-hw-load", - .value = 1216800, + .value = 489600, }, { .key = "qcom,max-hq-mbs-per-frame", @@ -404,12 +464,55 @@ static struct msm_vidc_common_data bengal_common_data[] = { .value = 244800, /* 1920 x 1088 @ 30 fps */ }, { - .key = "qcom,max-b-frame-mbs-per-frame", + .key = "qcom,power-collapse-delay", + .value = 1500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, + { + .key = "qcom,fw-cycles", + .value = 733003, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 225975, + }, +}; + +static struct msm_vidc_common_data bengal_common_data_v1[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 3, + }, + { + .key = "qcom,max-hw-load", + .value = 244800, + }, + { + .key = "qcom,max-hq-mbs-per-frame", .value = 8160, }, { - .key = "qcom,max-b-frame-mbs-per-sec", - .value = 489600, + .key = "qcom,max-hq-mbs-per-sec", + .value = 244800, /* 1920 x 1088 @ 30 fps */ }, { .key = "qcom,power-collapse-delay", @@ -475,8 +578,8 @@ static struct msm_vidc_platform_data lahaina_data = { static struct msm_vidc_platform_data bengal_data = { .codec_data = bengal_codec_data, .codec_data_length = ARRAY_SIZE(bengal_codec_data), - .common_data = bengal_common_data, - .common_data_length = ARRAY_SIZE(bengal_common_data), + .common_data = bengal_common_data_v0, + .common_data_length = ARRAY_SIZE(bengal_common_data_v0), .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, @@ -487,8 +590,8 @@ static struct msm_vidc_platform_data bengal_data = { .ubwc_config = 0x0, .codecs = bengal_codecs, .codecs_count = ARRAY_SIZE(bengal_codecs), - .codec_caps = bengal_capabilities, - .codec_caps_count = ARRAY_SIZE(bengal_capabilities), + .codec_caps = bengal_capabilities_v0, + .codec_caps_count = ARRAY_SIZE(bengal_capabilities_v0), }; static const struct of_device_id msm_vidc_dt_match[] = { @@ -505,11 +608,26 @@ static const struct of_device_id msm_vidc_dt_match[] = { MODULE_DEVICE_TABLE(of, msm_vidc_dt_match); +static int msm_vidc_read_rank( + struct msm_vidc_platform_data *data, struct device *dev) +{ + uint32_t num_ranks; + + num_ranks = 0; //TO-DO Read Rank API to be added + data->sku_version = SKU_VERSION_0; + + if (num_ranks == 1) + data->sku_version = SKU_VERSION_1; + + return 0; +} + void *vidc_get_drv_data(struct device *dev) { struct msm_vidc_platform_data *driver_data = NULL; const struct of_device_id *match; uint32_t ddr_type = DDR_TYPE_LPDDR5; + int rc = 0; if (!IS_ENABLED(CONFIG_OF) || !dev->of_node) { d_vpr_e("Using default_data\n"); @@ -539,6 +657,20 @@ void *vidc_get_drv_data(struct device *dev) d_vpr_h("DDR Type 0x%x hbb 0x%x\n", ddr_type, driver_data->ubwc_config ? driver_data->ubwc_config->highest_bank_bit : -1); + } else if (!strcmp(match->compatible, "qcom,bengal-vidc")) { + rc = msm_vidc_read_rank(driver_data, dev); + if (rc) { + d_vpr_e("Failed to get ddr rank, use Dual Rank DDR\n"); + goto exit; + } + if (driver_data->sku_version == SKU_VERSION_1) { + driver_data->common_data = bengal_common_data_v1; + driver_data->common_data_length = + ARRAY_SIZE(bengal_common_data_v1); + driver_data->codec_caps = bengal_capabilities_v1; + driver_data->codec_caps_count = + ARRAY_SIZE(bengal_capabilities_v1); + } } exit: return driver_data; From 720369dfcf81bbaad89c5453bb7e3beab4a958f6 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Thu, 26 Dec 2019 16:30:39 +0530 Subject: [PATCH 219/452] msm: vidc: ensure the validity of video buffer access During subsystem failure, the cause for failure is updated in a specific video buffer by the video firmware. Video firmware can even update the size of that specific buffer. To ensure the validity of that buffer access, check if the access is within the allocated size. CRs-Fixed: 2585811 Change-Id: I30b8bf2e9ba3699d229f4acc104f46566fcb60fa Signed-off-by: Vikash Garodia --- msm/vidc/hfi_common.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 523475a9762a..04799b26585d 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -2519,6 +2519,11 @@ static void print_sfr_message(struct venus_hfi_device *device) vsfr = (struct hfi_sfr_struct *)device->sfr.align_virtual_addr; if (vsfr) { + if (vsfr->bufSize != device->sfr.mem_size) { + d_vpr_e("Invalid SFR buf size %d actual %d\n", + vsfr->bufSize, device->sfr.mem_size); + return; + } vsfr_size = vsfr->bufSize - sizeof(u32); p = memchr(vsfr->rg_data, '\0', vsfr_size); /* SFR isn't guaranteed to be NULL terminated */ From 855ad95f050a24edd7662ef92a247bd612740f72 Mon Sep 17 00:00:00 2001 From: Karthikeyan Periasamy Date: Tue, 14 Jan 2020 16:17:55 -0800 Subject: [PATCH 220/452] msm: vidc: skip scaling check for decoder Scaling check is not required for decoder as clients may not set both input and output resolutions for decoder in which case input and output resolution will be different and scaling check fails if enabled. Change-Id: Iccdbad63bd8f975df4f57cad0250557119cf788d Signed-off-by: Karthikeyan Periasamy --- msm/vidc/msm_vidc_common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index e822174d5083..b987a280ccd7 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -5521,8 +5521,8 @@ int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst) u32 input_height, input_width, output_height, output_width; struct v4l2_format *f; - if (is_grid_session(inst)) { - s_vpr_h(inst->sid, "Skip scaling check for HEIC\n"); + if (is_grid_session(inst) || is_decode_session(inst)) { + s_vpr_h(inst->sid, "Skip scaling check\n"); return 0; } From 7faedc509cb50f5947431a871857e4b722acb489 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 20 Jan 2020 14:42:22 +0530 Subject: [PATCH 221/452] msm: vidc: reduce max_packets count to 480 Currently max_packets is configured as 1000, but max outstanding packets will not exceed more than 480(16 clients x 30 pkts/client). Change-Id: I8c074e08c959473c20450bc7d62486362ba81b47 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_common.c | 4 ++-- msm/vidc/msm_vidc_common.c | 5 ++--- msm/vidc/vidc_hfi_api.h | 12 +++++------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 04799b26585d..1e543970eed3 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include "hfi_common.h" @@ -40,7 +40,7 @@ const struct msm_vidc_bus_data DEFAULT_BUS_VOTE = { ((a) > (b) ? (a) - (b) < TRIVIAL_BW_THRESHOLD : \ (b) - (a) < TRIVIAL_BW_THRESHOLD) -const int max_packets = 1000; +const int max_packets = 480; /* 16 sessions x 30 packets */ static void venus_hfi_pm_handler(struct work_struct *work); static DECLARE_DELAYED_WORK(venus_hfi_pm_work, venus_hfi_pm_handler); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index b987a280ccd7..c31c560284c8 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -3440,9 +3440,8 @@ int msm_comm_reset_bufreqs(struct msm_vidc_inst *inst, enum hal_buffer buf_type) __func__, buf_type); return -EINVAL; } - bufreqs->buffer_size = bufreqs->buffer_region_size = - bufreqs->buffer_count_min = bufreqs->buffer_count_min_host = - bufreqs->buffer_count_actual = bufreqs->contiguous = + bufreqs->buffer_size = bufreqs->buffer_count_min = + bufreqs->buffer_count_min_host = bufreqs->buffer_count_actual = bufreqs->buffer_alignment = 0; return 0; diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 9bc915b52388..49ceaf871d82 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef __VIDC_HFI_API_H__ @@ -184,12 +184,10 @@ struct hal_intra_refresh { struct hal_buffer_requirements { enum hal_buffer buffer_type; u32 buffer_size; - u32 buffer_region_size; - u32 buffer_count_min; - u32 buffer_count_min_host; - u32 buffer_count_actual; - u32 contiguous; - u32 buffer_alignment; + u16 buffer_count_min; + u16 buffer_count_min_host; + u16 buffer_count_actual; + u16 buffer_alignment; }; enum hal_priority {/* Priority increases with number */ From cf94619546c561ce9dc02df213282730e1918a01 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Mon, 27 Jan 2020 15:20:46 -0800 Subject: [PATCH 222/452] msm: vidc: add vidioc_querymenu support Add support for vidioc_querymenu for userspace to query menu type controls. Change-Id: Idffb7e978e7f6eba9bf2744bcf87bafcd919decf Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_v4l2_vidc.c | 11 +++++++- msm/vidc/msm_vidc.c | 54 +++++++++++++++++++++++++++++++++++----- msm/vidc/msm_vidc.h | 3 ++- 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index b97fc88b8d26..1bf40ea95347 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -197,6 +197,14 @@ static int msm_v4l2_queryctrl(struct file *file, void *fh, return msm_vidc_query_ctrl((void *)vidc_inst, ctrl); } +static int msm_v4l2_querymenu(struct file *file, void *fh, + struct v4l2_querymenu *qmenu) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_query_menu((void *)vidc_inst, qmenu); +} + const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = { .vidioc_querycap = msm_v4l2_querycap, .vidioc_enum_fmt_vid_cap = msm_v4l2_enum_fmt, @@ -212,6 +220,7 @@ const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = { .vidioc_s_ctrl = msm_v4l2_s_ctrl, .vidioc_g_ctrl = msm_v4l2_g_ctrl, .vidioc_queryctrl = msm_v4l2_queryctrl, + .vidioc_querymenu = msm_v4l2_querymenu, .vidioc_subscribe_event = msm_v4l2_subscribe_event, .vidioc_unsubscribe_event = msm_v4l2_unsubscribe_event, .vidioc_decoder_cmd = msm_v4l2_decoder_cmd, diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index beda8bbe46bf..a44d0f99553b 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include "msm_vidc.h" @@ -137,22 +137,64 @@ int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *q_ctrl) } q_ctrl->minimum = ctrl->minimum; q_ctrl->maximum = ctrl->maximum; + q_ctrl->default_value = ctrl->default_value; /* remove tier info for HEVC level */ if (q_ctrl->id == V4L2_CID_MPEG_VIDEO_HEVC_LEVEL) { q_ctrl->minimum &= ~(0xF << 28); q_ctrl->maximum &= ~(0xF << 28); } - if (ctrl->type == V4L2_CTRL_TYPE_MENU) + if (ctrl->type == V4L2_CTRL_TYPE_MENU) { q_ctrl->flags = ~(ctrl->menu_skip_mask); - else + } else { q_ctrl->flags = 0; - - s_vpr_h(inst->sid, "query ctrl: %s: min %d, max %d, flags %#x\n", - ctrl->name, q_ctrl->minimum, q_ctrl->maximum, q_ctrl->flags); + q_ctrl->step = ctrl->step; + } + s_vpr_h(inst->sid, + "query ctrl: %s: min %d, max %d, default %d step %d flags %#x\n", + ctrl->name, q_ctrl->minimum, q_ctrl->maximum, + q_ctrl->default_value, q_ctrl->step, q_ctrl->flags); return rc; } EXPORT_SYMBOL(msm_vidc_query_ctrl); +int msm_vidc_query_menu(void *instance, struct v4l2_querymenu *qmenu) +{ + int rc = 0; + struct msm_vidc_inst *inst = instance; + struct v4l2_ctrl *ctrl; + + if (!inst || !qmenu) { + d_vpr_e("%s: invalid params %pK %pK\n", + __func__, inst, qmenu); + return -EINVAL; + } + + ctrl = v4l2_ctrl_find(&inst->ctrl_handler, qmenu->id); + if (!ctrl) { + s_vpr_e(inst->sid, "%s: get_ctrl failed for id %d\n", + __func__, qmenu->id); + return -EINVAL; + } + if (ctrl->type != V4L2_CTRL_TYPE_MENU) { + s_vpr_e(inst->sid, "%s: ctrl: %s: type (%d) is not MENU type\n", + __func__, ctrl->name, ctrl->type); + return -EINVAL; + } + if (qmenu->index < ctrl->minimum || qmenu->index > ctrl->maximum) + return -EINVAL; + + if (ctrl->menu_skip_mask & (1 << qmenu->index)) + rc = -EINVAL; + + s_vpr_h(inst->sid, + "%s: ctrl: %s: min %d, max %d, menu_skip_mask %#x, qmenu: id %d, index %d, %s\n", + __func__, ctrl->name, ctrl->minimum, ctrl->maximum, + ctrl->menu_skip_mask, qmenu->id, qmenu->index, + rc ? "not supported" : "supported"); + return rc; +} +EXPORT_SYMBOL(msm_vidc_query_menu); + int msm_vidc_s_fmt(void *instance, struct v4l2_format *f) { int rc = 0; diff --git a/msm/vidc/msm_vidc.h b/msm/vidc/msm_vidc.h index 2bea95132f50..d4d50a74f8fa 100644 --- a/msm/vidc/msm_vidc.h +++ b/msm/vidc/msm_vidc.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef _MSM_VIDC_H_ @@ -111,6 +111,7 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b); int msm_vidc_streamon(void *instance, enum v4l2_buf_type i); int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *ctrl); +int msm_vidc_query_menu(void *instance, struct v4l2_querymenu *qmenu); int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i); int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd); int msm_vidc_poll(void *instance, struct file *filp, From 167523e9ffb1cc01780c66f156c081e93b450c8d Mon Sep 17 00:00:00 2001 From: Akshay Chandrashekhar Kalghatgi Date: Fri, 10 Jan 2020 10:23:14 -0800 Subject: [PATCH 223/452] msm: vidc: Do not unhalt CVP Core Clock Configure CVP_VPU_WRAPPER_CORE_CLOCK_CONFIG register to unhalt AXI & VPU core clocks but not unhalt CVP core clock. Add a function to write a masked value to register. Change-Id: I8cb80b1823d091ac4eb705fd207afbd35bde86de Signed-off-by: Akshay Chandrashekhar Kalghatgi --- msm/vidc/hfi_common.c | 50 +++++++++++++++++++++++++++++++++-- msm/vidc/hfi_common.h | 4 ++- msm/vidc/msm_vidc_res_parse.c | 10 +++---- msm/vidc/msm_vidc_resources.h | 3 ++- 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 1e543970eed3..0a0d15796195 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -787,6 +787,51 @@ void __write_register(struct venus_hfi_device *device, wmb(); } +/* + * Argument mask is used to specify which bits to update. In case mask is 0x11, + * only bits 0 & 4 will be updated with corresponding bits from value. To update + * entire register with value, set mask = 0xFFFFFFFF. + */ +void __write_register_masked(struct venus_hfi_device *device, + u32 reg, u32 value, u32 mask, u32 sid) +{ + u32 prev_val, new_val; + u8 *base_addr; + + if (!device) { + s_vpr_e(sid, "%s: invalid params\n", __func__); + return; + } + + __strict_check(device); + + if (!device->power_enabled) { + s_vpr_e(sid, "%s: register write failed, power is off\n", + __func__); + msm_vidc_res_handle_fatal_hw_error(device->res, true); + return; + } + + base_addr = device->hal_data->register_base; + base_addr += reg; + + prev_val = readl_relaxed(base_addr); + /* + * Memory barrier to ensure register read is correct + */ + rmb(); + + new_val = (prev_val & ~mask) | (value & mask); + s_vpr_l(sid, + "Base addr: %pK, writing to: %#x, previous-value: %#x, value: %#x, mask: %#x, new-value: %#x...\n", + base_addr, reg, prev_val, value, mask, new_val); + writel_relaxed(new_val, base_addr); + /* + * Memory barrier to make sure value is written into the register. + */ + wmb(); +} + int __read_register(struct venus_hfi_device *device, u32 reg, u32 sid) { int rc = 0; @@ -831,8 +876,9 @@ static void __set_registers(struct venus_hfi_device *device, u32 sid) reg_set = &device->res->reg_set; for (i = 0; i < reg_set->count; i++) { - __write_register(device, reg_set->reg_tbl[i].reg, - reg_set->reg_tbl[i].value, sid); + __write_register_masked(device, reg_set->reg_tbl[i].reg, + reg_set->reg_tbl[i].value, + reg_set->reg_tbl[i].mask, sid); } } diff --git a/msm/vidc/hfi_common.h b/msm/vidc/hfi_common.h index 2583db939fe4..6043db6e7473 100644 --- a/msm/vidc/hfi_common.h +++ b/msm/vidc/hfi_common.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef __HFI_COMMON_H__ @@ -296,6 +296,8 @@ void __dump(struct dump dump[], int len, u32 sid); void __write_register(struct venus_hfi_device *device, u32 reg, u32 value, u32 sid); +void __write_register_masked(struct venus_hfi_device *device, + u32 reg, u32 value, u32 mask, u32 sid); int __read_register(struct venus_hfi_device *device, u32 reg, u32 sid); void __disable_unprepare_clks(struct venus_hfi_device *device); int __disable_regulators(struct venus_hfi_device *device); diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 223343a00294..27fe80f5b9d3 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -151,15 +151,15 @@ static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res) } if (of_property_read_u32_array(pdev->dev.of_node, "qcom,reg-presets", - (u32 *)reg_set->reg_tbl, reg_set->count * 2)) { + (u32 *)reg_set->reg_tbl, reg_set->count * 3)) { d_vpr_e("Failed to read register table\n"); msm_vidc_free_reg_table(res); return -EINVAL; } for (i = 0; i < reg_set->count; i++) { - d_vpr_h("reg = %x, value = %x\n", - reg_set->reg_tbl[i].reg, reg_set->reg_tbl[i].value - ); + d_vpr_h("reg = %#x, value = %#x, mask = %#x\n", + reg_set->reg_tbl[i].reg, reg_set->reg_tbl[i].value, + reg_set->reg_tbl[i].mask); } return rc; } diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index a64575d189e7..aa2fb29f16ce 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. */ #ifndef __MSM_VIDC_RESOURCES_H__ @@ -15,6 +15,7 @@ struct reg_value_pair { u32 reg; u32 value; + u32 mask; }; struct reg_set { From d33141e60c9d4f5b3869ff449d73b9451cbf410c Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 24 Jan 2020 20:06:15 +0530 Subject: [PATCH 224/452] msm: vidc: alter log printing sequence Low power flag is updated after calling msm_print_core_status. So it is printing "HQ" even for "LP" session. So changed api calling sequence. Change-Id: I1f88f3f3e1ca43f11c00359dbfaec5d2ff99ae89 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_clocks.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 05347934e499..4695efa82f24 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #include "msm_vidc_common.h" @@ -1285,9 +1285,9 @@ int msm_vidc_decide_core_and_power_mode_iris2(struct msm_vidc_inst *inst) { u32 mbpf, mbps, max_hq_mbpf, max_hq_mbps; bool enable = true; + int rc = 0; inst->clk_data.core_id = VIDC_CORE_ID_1; - msm_print_core_status(inst->core, VIDC_CORE_ID_1, inst->sid); /* Power saving always disabled for CQ and LOSSLESS RC modes. */ mbpf = msm_vidc_get_mbs_per_frame(inst); @@ -1301,7 +1301,10 @@ int msm_vidc_decide_core_and_power_mode_iris2(struct msm_vidc_inst *inst) (mbpf <= max_hq_mbpf && mbps <= max_hq_mbps)) enable = false; - return msm_vidc_power_save_mode_enable(inst, enable); + rc = msm_vidc_power_save_mode_enable(inst, enable); + msm_print_core_status(inst->core, VIDC_CORE_ID_1, inst->sid); + + return rc; } void msm_vidc_init_core_clk_ops(struct msm_vidc_core *core) From ac715becb77fc144277ac6caaabcc840c8d76e45 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 7 Feb 2020 22:30:50 +0530 Subject: [PATCH 225/452] msm: vidc: send mapped addr and size for ftrace buffer addr and size were not updated in "UNMAP" tracing. So added entries. Change-Id: I4ae5715263a3e1d21de88e4ff69baf8d74d75560 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_smem.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_smem.c b/msm/vidc/msm_smem.c index 622c9e205a9f..40871b70ff77 100644 --- a/msm/vidc/msm_smem.c +++ b/msm/vidc/msm_smem.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -122,6 +122,9 @@ static int msm_dma_put_device_address(u32 flags, enum hal_buffer buffer_type, u32 sid) { int rc = 0; + struct sg_table *table = NULL; + dma_addr_t iova; + unsigned long buffer_size; if (!mapping_info) { s_vpr_e(sid, "Invalid mapping_info\n"); @@ -135,7 +138,11 @@ static int msm_dma_put_device_address(u32 flags, return -EINVAL; } - trace_msm_smem_buffer_iommu_op_start("UNMAP", 0, 0, 0, 0, 0); + table = mapping_info->table; + iova = table->sgl->dma_address; + buffer_size = table->sgl->dma_length; + trace_msm_smem_buffer_iommu_op_start("UNMAP", 0, 0, + 0, iova, buffer_size); dma_buf_unmap_attachment(mapping_info->attach, mapping_info->table, DMA_BIDIRECTIONAL); dma_buf_detach(mapping_info->buf, mapping_info->attach); From b7ee67c040c49fd252b365994e3f4320692cb068 Mon Sep 17 00:00:00 2001 From: Amit Shekhar Date: Mon, 27 Jan 2020 14:31:18 -0800 Subject: [PATCH 226/452] msm: vidc: Fix input tag fetching condition For sub-frame encode sessions, input buffer done is received only after all sub-frames have been received. In these sub-frame encode cases, input tags are not fetched for sub-frame outputs for first input and buffers are dropped in HAL in absence of apt input tags. Limit buffer counter check from input tag fetch condition for decode sessions only. Change-Id: I8c584834369be921d8699da49cfa1fec65fb993d CRs-Fixed: 2547055 Signed-off-by: Amit Shekhar --- msm/vidc/msm_vidc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index a44d0f99553b..3c5327ae8290 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -483,7 +483,9 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) * fetch tag atleast 1 ETB is successfully processed after flush) */ if (b->type == OUTPUT_MPLANE && !inst->in_flush && - !inst->out_flush && inst->clk_data.buffer_counter) { + !inst->out_flush && + (inst->session_type == MSM_VIDC_ENCODER || + inst->clk_data.buffer_counter)) { rc = msm_comm_fetch_input_tag(&inst->fbd_data, b->index, &input_tag, &input_tag2, inst->sid); if (rc) { From 5f665189a2eba34083b73ecaf8e005d259de1400 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 30 Dec 2019 13:19:11 +0530 Subject: [PATCH 227/452] msm: vidc: refine decode batching logic 1. is_batching_allowed api is not considering platform check(core->resources.decode_batching). 2. increase both input & output buffers count if current session supports batching. Change-Id: Iabe7479b4664a78b637ee981d67c604f7d0d5d56 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vdec.c | 22 +++------------------- msm/vidc/msm_vidc.c | 10 +--------- msm/vidc/msm_vidc_buffer_calculations.c | 12 +++--------- msm/vidc/msm_vidc_common.c | 16 ++++++++++++---- 4 files changed, 19 insertions(+), 41 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 8f456dd31ad4..b0f5ee407747 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -673,15 +673,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) memcpy(f, &fmt->v4l2_fmt, sizeof(struct v4l2_format)); } - /* - * if batching enabled previously then you may chose - * to disable it based on recent configuration changes. - * if batching already disabled do not enable it again - * as sufficient extra buffers (required for batch mode - * on both ports) may not have been updated to client. - */ - if (inst->batch.enable) - inst->batch.enable = is_batching_allowed(inst); + inst->batch.enable = is_batching_allowed(inst); msm_dcvs_try_enable(inst); err_invalid_fmt: @@ -882,6 +874,7 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (ctrl->val) inst->flags |= VIDC_THUMBNAIL; + inst->batch.enable = is_batching_allowed(inst); rc = msm_vidc_calculate_buffer_counts(inst); if (rc) { s_vpr_e(inst->sid, @@ -903,16 +896,6 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE: inst->clk_data.frame_rate = ctrl->val; - if (inst->state >= MSM_VIDC_LOAD_RESOURCES) - break; - /* Only recalculate buffer counts before buffers allocated */ - rc = msm_vidc_calculate_buffer_counts(inst); - if (rc) { - s_vpr_e(inst->sid, - "%s failed to calculate buffer count after set fps\n", - __func__); - return rc; - } break; case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA: if (ctrl->val == EXTRADATA_NONE) @@ -938,6 +921,7 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE: inst->clk_data.low_latency_mode = !!ctrl->val; + inst->batch.enable = is_batching_allowed(inst); break; default: s_vpr_e(inst->sid, "Unknown control %#x\n", ctrl->id); diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index a44d0f99553b..22e63d9ed07b 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -913,15 +913,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) } } - /* - * if batching enabled previously then you may chose - * to disable it based on recent configuration changes. - * if batching already disabled do not enable it again - * as sufficient extra buffers (required for batch mode - * on both ports) may not have been updated to client. - */ - if (inst->batch.enable) - inst->batch.enable = is_batching_allowed(inst); + inst->batch.enable = is_batching_allowed(inst); s_vpr_hp(inst->sid, "%s: batching %s for inst %pK\n", __func__, inst->batch.enable ? "enabled" : "disabled", inst); diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 29c2c6fc3cd1..b8e4bc2e74c8 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #include "msm_vidc_debug.h" @@ -775,13 +775,7 @@ static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst) f->fmt.pix_mp.height, 4096, 2160)) goto exit; - /* - * Allocating 2 extra buffers, assuming current session is - * always batch eligible. Cannot rely on inst->batch.enable - * as it can be enabled/disabled based on clip fps etc. But - * decoder input can not be reallocated at run time. - */ - if (core->resources.decode_batching) + if (inst->batch.enable) extra_input_count = (BATCH_DEC_TOTAL_INPUT_BUFFERS - MIN_INPUT_BUFFERS); @@ -872,7 +866,7 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) * If platform supports decode batching ensure minimum 6 extra * output buffers. Else add 4 extra output buffers for DCVS. */ - if (core->resources.decode_batching) + if (inst->batch.enable) extra_output_count = BATCH_DEC_EXTRA_OUTPUT_BUFFERS; } else if (is_encode_session(inst)) { /* diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index c31c560284c8..a12a1037d2c7 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1760,9 +1760,8 @@ static void handle_event_change(enum hal_command_response cmd, void *data) "seq: V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT\n"); /* decide batching as configuration changed */ - if (inst->batch.enable) - inst->batch.enable = is_batching_allowed(inst); - s_vpr_hp(inst->sid, "seq : batching %s\n", __func__, + inst->batch.enable = is_batching_allowed(inst); + s_vpr_hp(inst->sid, "seq : batching %s\n", inst->batch.enable ? "enabled" : "disabled"); msm_dcvs_try_enable(inst); extra_buff_count = msm_vidc_get_extra_buff_count(inst, @@ -2790,7 +2789,16 @@ bool is_batching_allowed(struct msm_vidc_inst *inst) maxmbs = inst->capability.cap[CAP_BATCH_MAX_MB_PER_FRAME].max; maxfps = inst->capability.cap[CAP_BATCH_MAX_FPS].max; - return (is_single_session(inst, ignore_flags) && + /* + * if batching enabled previously then you may chose + * to disable it based on recent configuration changes. + * if batching already disabled do not enable it again + * as sufficient extra buffers (required for batch mode + * on both ports) may not have been updated to client. + */ + return (inst->batch.enable && + inst->core->resources.decode_batching && + is_single_session(inst, ignore_flags) && is_decode_session(inst) && !is_thumbnail_session(inst) && !inst->clk_data.low_latency_mode && From 8cace81134e17f528f3536236678a595e42f2fbe Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Wed, 12 Feb 2020 12:38:01 -0800 Subject: [PATCH 228/452] msm: vidc: Move buffer counts handling outside of driver Client should take care of buffer allocations for advanced use cases like HFR and HEIF. Driver will handle extra buffers only in bare minimum usecases like DCVS and decode batching. Change-Id: Id5ec012ba2620b47578173e8306f1700644f0b8c Signed-off-by: Darshana Patil --- msm/vidc/msm_vidc_buffer_calculations.c | 96 +------------------------ msm/vidc/msm_vidc_common.c | 21 ------ msm/vidc/msm_vidc_common.h | 3 +- 3 files changed, 2 insertions(+), 118 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index b8e4bc2e74c8..3fe3860eb7ef 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -12,35 +12,18 @@ /* minimum number of input buffers */ #define MIN_INPUT_BUFFERS 4 -/* Max number of PERF eligible sessions */ -#define MAX_PERF_ELIGIBLE_SESSIONS 4 /* Decoder buffer count macros */ /* total input buffers in case of decoder batch */ #define BATCH_DEC_TOTAL_INPUT_BUFFERS 6 -/* total input buffers for decoder HFR usecase (fps > 480) */ -#define MAX_HFR_DEC_TOTAL_INPUT_BUFFERS 12 - -/* total input buffers for decoder HFR usecase */ -#define HFR_DEC_TOTAL_INPUT_BUFFERS 12 - /* extra output buffers in case of decoder batch */ #define BATCH_DEC_EXTRA_OUTPUT_BUFFERS 6 /* Encoder buffer count macros */ -/* total input buffers for encoder HFR usecase */ -#define HFR_ENC_TOTAL_INPUT_BUFFERS 16 - /* minimum number of output buffers */ #define MIN_ENC_OUTPUT_BUFFERS 4 -/* extra output buffers for encoder HFR usecase */ -#define HFR_ENC_TOTAL_OUTPUT_BUFFERS 12 - -/* extra output buffers for encoder HEIF usecase */ -#define HEIF_ENC_TOTAL_OUTPUT_BUFFERS 12 - #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_WIDTH 32 #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_HEIGHT 8 #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_UV_TILE_WIDTH 16 @@ -747,8 +730,6 @@ static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst) { unsigned int extra_input_count = 0; struct msm_vidc_core *core; - struct v4l2_format *f; - int fps; if (!inst || !inst->core) { d_vpr_e("%s: invalid params %pK\n", __func__, inst); @@ -766,57 +747,15 @@ static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst) return extra_input_count; if (is_decode_session(inst)) { - /* - * Batch mode and HFR not supported for resolution greater than - * UHD. Hence extra buffers are not required. - */ - f = &inst->fmts[INPUT_PORT].v4l2_fmt; - if (res_is_greater_than(f->fmt.pix_mp.width, - f->fmt.pix_mp.height, 4096, 2160)) - goto exit; - + /* add 2 extra buffers for batching */ if (inst->batch.enable) extra_input_count = (BATCH_DEC_TOTAL_INPUT_BUFFERS - MIN_INPUT_BUFFERS); - - /* - * HFR decode session needs more buffers and we do not know - * whether a decode session is HFR or not until input buffers - * queued but by then input buffers are already allocated and - * we do not have option to increase input buffer count then. - * So have more buffers for initial 4 elgible sessions (and - * not for all sessions to avoid over memory usage issues). - */ - if (!is_secure_session(inst) && - msm_comm_get_num_perf_sessions(inst) < - MAX_PERF_ELIGIBLE_SESSIONS) { - fps = inst->clk_data.frame_rate >> 16; - inst->is_perf_eligible_session = true; - if (fps > 480) - extra_input_count = - (MAX_HFR_DEC_TOTAL_INPUT_BUFFERS - - MIN_INPUT_BUFFERS); - else - extra_input_count = - (HFR_DEC_TOTAL_INPUT_BUFFERS - - MIN_INPUT_BUFFERS); - } } else if (is_encode_session(inst)) { /* add 4 extra buffers for dcvs */ if (core->resources.dcvs) extra_input_count = DCVS_ENC_EXTRA_INPUT_BUFFERS; - - /* Increase buffer count for HFR usecase */ - if (msm_comm_get_num_perf_sessions(inst) < - MAX_PERF_ELIGIBLE_SESSIONS && - msm_vidc_get_fps(inst) > 60) { - inst->is_perf_eligible_session = true; - extra_input_count = (HFR_ENC_TOTAL_INPUT_BUFFERS - - MIN_INPUT_BUFFERS); - } } - -exit: return extra_input_count; } @@ -824,7 +763,6 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) { unsigned int extra_output_count = 0; struct msm_vidc_core *core; - struct v4l2_format *f; if (!inst || !inst->core) { d_vpr_e("%s: invalid params %pK\n", __func__, inst); @@ -841,26 +779,10 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) if (!is_realtime_session(inst) || is_thumbnail_session(inst)) return extra_output_count; - /* For HEIF, we are increasing buffer count */ - if (is_image_session(inst) || is_grid_session(inst)) { - extra_output_count = (HEIF_ENC_TOTAL_OUTPUT_BUFFERS - - MIN_ENC_OUTPUT_BUFFERS); - return extra_output_count; - } - if (is_decode_session(inst)) { /* add 4 extra buffers for dcvs */ if (core->resources.dcvs) extra_output_count = DCVS_DEC_EXTRA_OUTPUT_BUFFERS; - /* - * Batch mode and HFR not supported for resolution greater than - * UHD. Hence extra buffers are not required. - */ - f = &inst->fmts[INPUT_PORT].v4l2_fmt; - if (res_is_greater_than(f->fmt.pix_mp.width, - f->fmt.pix_mp.height, 4096, 2160)) - goto exit; - /* * Minimum number of decoder output buffers is codec specific. * If platform supports decode batching ensure minimum 6 extra @@ -868,23 +790,7 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) */ if (inst->batch.enable) extra_output_count = BATCH_DEC_EXTRA_OUTPUT_BUFFERS; - } else if (is_encode_session(inst)) { - /* - * Batching and DCVS are based on input. We assume that encoder - * output buffers can be re-cycled quickly. Hence it is assumed - * that output buffer count does not impact for DCVS/batching. - * For HFR, we are increasing buffer count to avoid latency/perf - * issue to re-cycle buffers. - */ - if (msm_comm_get_num_perf_sessions(inst) < - MAX_PERF_ELIGIBLE_SESSIONS && - msm_vidc_get_fps(inst) > 60) { - inst->is_perf_eligible_session = true; - extra_output_count = (HFR_ENC_TOTAL_OUTPUT_BUFFERS - - MIN_ENC_OUTPUT_BUFFERS); - } } -exit: return extra_output_count; } diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index a12a1037d2c7..f51f5d82ab82 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -708,27 +708,6 @@ bool is_single_session(struct msm_vidc_inst *inst, u32 ignore_flags) return single; } -int msm_comm_get_num_perf_sessions(struct msm_vidc_inst *inst) -{ - int count = 0; - struct msm_vidc_core *core; - struct msm_vidc_inst *temp; - - if (!inst || !inst->core) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - goto exit; - } - core = inst->core; - mutex_lock(&core->lock); - list_for_each_entry(temp, &core->instances, list) { - if (temp->is_perf_eligible_session) - count++; - } - mutex_unlock(&core->lock); -exit: - return count; -} - static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst, enum load_calc_quirks quirks) { diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 818d361e9906..39ec0fcd8a22 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef _MSM_VIDC_COMMON_H_ @@ -175,7 +175,6 @@ static inline int msm_comm_s_ctrl(struct msm_vidc_inst *inst, } bool is_single_session(struct msm_vidc_inst *inst, u32 ignore_flags); -int msm_comm_get_num_perf_sessions(struct msm_vidc_inst *inst); bool is_batching_allowed(struct msm_vidc_inst *inst); enum hal_buffer get_hal_buffer_type(unsigned int type, unsigned int plane_num); From 1cfa55008eb3984e7d04ba6a30e10b4089ce16a2 Mon Sep 17 00:00:00 2001 From: Rakshitha Shakamuri Date: Thu, 6 Feb 2020 19:09:43 +0530 Subject: [PATCH 229/452] msm: vidc: Align buffer size calculators with num_vpp_pipes Buffer size calculators are dependent on pipe configuration of the chipset. Ex: Kona has 4 pipes and lagoon has 1 pipe. Hence aligning the buffer size calculators based on chipset specific usage of pipes. Change-Id: I8bb19efc4a80c7e17d9db3cf7d5f1151191b502e Signed-off-by: Priyanka Gujjula Signed-off-by: Rakshitha Shakamuri --- msm/vidc/msm_vidc_buffer_calculations.c | 186 +++++++++++++----------- msm/vidc/msm_vidc_buffer_calculations.h | 10 +- msm/vidc/msm_vidc_internal.h | 3 +- msm/vidc/msm_vidc_platform.c | 5 +- 4 files changed, 111 insertions(+), 93 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 3fe3860eb7ef..558b0ccea280 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -60,7 +60,6 @@ #define VENUS_DMA_ALIGNMENT BUFFER_ALIGNMENT_SIZE(256) -#define NUM_OF_VPP_PIPES 4 #define MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 64 #define MAX_FE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE 64 #define MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE 64 @@ -125,10 +124,9 @@ #define SIZE_HW_PIC(sizePerBuf) \ (NUM_HW_PIC_BUF * sizePerBuf) -#define H264_CABAC_HDR_RATIO_HD_TOT_NUM 1 /* 0.25 */ -#define H264_CABAC_HDR_RATIO_HD_TOT_DEN 4 -#define H264_CABAC_RES_RATIO_HD_TOT_NUM 3 /* 0.75 */ -#define H264_CABAC_RES_RATIO_HD_TOT_DEN 4 +#define H264_CABAC_HDR_RATIO_HD_TOT 1 +#define H264_CABAC_RES_RATIO_HD_TOT 3 + /* * some content need more bin buffer, but limit buffer * size for high resolution @@ -182,10 +180,9 @@ #define SIZE_H265D_QP(width, height) SIZE_H264D_QP(width, height) -#define H265_CABAC_HDR_RATIO_HD_TOT_NUM 1 -#define H265_CABAC_HDR_RATIO_HD_TOT_DEN 2 -#define H265_CABAC_RES_RATIO_HD_TOT_NUM 1 -#define H265_CABAC_RES_RATIO_HD_TOT_DEN 2 +#define H265_CABAC_HDR_RATIO_HD_TOT 2 +#define H265_CABAC_RES_RATIO_HD_TOT 2 + /* * some content need more bin buffer, but limit buffer size * for high resolution @@ -278,31 +275,36 @@ static inline u32 calculate_mpeg2d_scratch_size(struct msm_vidc_inst *inst, u32 width, u32 height, bool is_interlaced); static inline u32 calculate_enc_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 work_mode, u32 lcu_size); + u32 width, u32 height, u32 work_mode, u32 lcu_size, u32 num_vpp_pipes); static inline u32 calculate_h264e_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 work_mode); + u32 width, u32 height, u32 work_mode, u32 num_vpp_pipes); static inline u32 calculate_h265e_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 work_mode); + u32 width, u32 height, u32 work_mode, u32 num_vpp_pipes); static inline u32 calculate_vp8e_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 work_mode); + u32 width, u32 height, u32 work_mode, u32 num_vpp_pipes); static inline u32 calculate_h264d_scratch1_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled); + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled, + u32 num_vpp_pipes); static inline u32 calculate_h265d_scratch1_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled); + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled, + u32 num_vpp_pipes); static inline u32 calculate_vp8d_scratch1_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled); + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled, + u32 num_vpp_pipes); static inline u32 calculate_vp9d_scratch1_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled); + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled, + u32 num_vpp_pipes); static inline u32 calculate_mpeg2d_scratch1_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled); + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled, + u32 num_vpp_pipes); static inline u32 calculate_h264e_scratch1_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 num_ref, bool ten_bit); + u32 width, u32 height, u32 num_ref, bool ten_bit, u32 num_vpp_pipes); static inline u32 calculate_h265e_scratch1_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 num_ref, bool ten_bit); + u32 width, u32 height, u32 num_ref, bool ten_bit, u32 num_vpp_pipes); static inline u32 calculate_vp8e_scratch1_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 num_ref, bool ten_bit); + u32 width, u32 height, u32 num_ref, bool ten_bit, u32 num_vpp_pipes); static inline u32 calculate_enc_scratch2_size(struct msm_vidc_inst *inst, u32 width, u32 height, u32 num_ref, bool ten_bit); @@ -369,14 +371,15 @@ static struct msm_vidc_enc_buff_size_calculators vp8e_calculators = { int msm_vidc_get_decoder_internal_buffer_sizes(struct msm_vidc_inst *inst) { struct msm_vidc_dec_buff_size_calculators *dec_calculators; - u32 width, height, i, out_min_count; + u32 width, height, i, out_min_count, num_vpp_pipes; struct v4l2_format *f; - if (!inst) { + if (!inst || !inst->core || !inst->core->platform_data) { d_vpr_e("%s: Instance is null!", __func__); return -EINVAL; } + num_vpp_pipes = inst->core->platform_data->num_vpp_pipes; f = &inst->fmts[INPUT_PORT].v4l2_fmt; switch (f->fmt.pix_mp.pixelformat) { case V4L2_PIX_FMT_H264: @@ -426,7 +429,8 @@ int msm_vidc_get_decoder_internal_buffer_sizes(struct msm_vidc_inst *inst) curr_req->buffer_size = dec_calculators->calculate_scratch1_size( inst, width, height, out_min_count, - is_secondary_output_mode(inst)); + is_secondary_output_mode(inst), + num_vpp_pipes); valid_buffer_type = true; } else if (curr_req->buffer_type == HAL_BUFFER_INTERNAL_PERSIST_1) { @@ -486,17 +490,18 @@ int msm_vidc_get_num_ref_frames(struct msm_vidc_inst *inst) int msm_vidc_get_encoder_internal_buffer_sizes(struct msm_vidc_inst *inst) { struct msm_vidc_enc_buff_size_calculators *enc_calculators; - u32 width, height, i, num_ref; + u32 width, height, i, num_ref, num_vpp_pipes; bool is_tenbit = false; int num_bframes; struct v4l2_ctrl *bframe; struct v4l2_format *f; - if (!inst) { + if (!inst || !inst->core || !inst->core->platform_data) { d_vpr_e("%s: Instance is null!", __func__); return -EINVAL; } + num_vpp_pipes = inst->core->platform_data->num_vpp_pipes; f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; switch (f->fmt.pix_mp.pixelformat) { case V4L2_PIX_FMT_H264: @@ -537,14 +542,15 @@ int msm_vidc_get_encoder_internal_buffer_sizes(struct msm_vidc_inst *inst) curr_req->buffer_size = enc_calculators->calculate_scratch_size( inst, width, height, - inst->clk_data.work_mode); + inst->clk_data.work_mode, + num_vpp_pipes); valid_buffer_type = true; } else if (curr_req->buffer_type == HAL_BUFFER_INTERNAL_SCRATCH_1) { curr_req->buffer_size = enc_calculators->calculate_scratch1_size( inst, width, height, num_ref, - is_tenbit); + is_tenbit, num_vpp_pipes); valid_buffer_type = true; } else if (curr_req->buffer_type == HAL_BUFFER_INTERNAL_SCRATCH_2) { @@ -987,7 +993,7 @@ u32 msm_vidc_calculate_enc_output_extra_size(struct msm_vidc_inst *inst) return ALIGN(size, SZ_4K); } -static inline u32 size_vpss_lb(u32 width, u32 height) +static inline u32 size_vpss_lb(u32 width, u32 height, u32 num_vpp_pipes) { u32 vpss_4tap_top_buffer_size, vpss_div2_top_buffer_size; u32 vpss_4tap_left_buffer_size, vpss_div2_left_buffer_size; @@ -1009,7 +1015,7 @@ static inline u32 size_vpss_lb(u32 width, u32 height) opb_lb_wr_llb_uv_buffer_size = opb_lb_wr_llb_y_buffer_size = ALIGN((ALIGN(height, 16) / 2) * 64, BUFFER_ALIGNMENT_SIZE(32)); - size = NUM_OF_VPP_PIPES * 2 * (vpss_4tap_top_buffer_size + + size = num_vpp_pipes * 2 * (vpss_4tap_top_buffer_size + vpss_div2_top_buffer_size) + 2 * (vpss_4tap_left_buffer_size + vpss_div2_left_buffer_size) + @@ -1073,7 +1079,8 @@ static inline u32 size_h264d_vpp_cmd_buf(u32 height) return size; } -static inline u32 hfi_iris2_h264d_non_comv_size(u32 width, u32 height) +static inline u32 hfi_iris2_h264d_non_comv_size(u32 width, u32 height, + u32 num_vpp_pipes) { u32 size; u32 size_bse, size_vpp; @@ -1088,11 +1095,11 @@ static inline u32 hfi_iris2_h264d_non_comv_size(u32 width, u32 height) ALIGN(SIZE_H264D_LB_FE_TOP_CTRL(width, height), VENUS_DMA_ALIGNMENT) + ALIGN(SIZE_H264D_LB_FE_LEFT_CTRL(width, height), - VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + VENUS_DMA_ALIGNMENT) * num_vpp_pipes + ALIGN(SIZE_H264D_LB_SE_TOP_CTRL(width, height), VENUS_DMA_ALIGNMENT) + ALIGN(SIZE_H264D_LB_SE_LEFT_CTRL(width, height), - VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + VENUS_DMA_ALIGNMENT) * num_vpp_pipes + ALIGN(SIZE_H264D_LB_PE_TOP_DATA(width, height), VENUS_DMA_ALIGNMENT) + ALIGN(SIZE_H264D_LB_VSP_TOP(width, height), @@ -1115,10 +1122,8 @@ static inline u32 size_h264d_hw_bin_buffer(u32 width, u32 height) ((BIN_BUFFER_THRESHOLD * 3) >> 1) : ((product * 3) >> 1); - size_bin_hdr = size_yuv * H264_CABAC_HDR_RATIO_HD_TOT_NUM / - H264_CABAC_HDR_RATIO_HD_TOT_DEN; - size_bin_res = size_yuv * H264_CABAC_RES_RATIO_HD_TOT_NUM / - H264_CABAC_RES_RATIO_HD_TOT_DEN; + size_bin_hdr = size_yuv * H264_CABAC_HDR_RATIO_HD_TOT; + size_bin_res = size_yuv * H264_CABAC_RES_RATIO_HD_TOT; size_bin_hdr = ALIGN(size_bin_hdr, VENUS_DMA_ALIGNMENT); size_bin_res = ALIGN(size_bin_res, VENUS_DMA_ALIGNMENT); size = size_bin_hdr + size_bin_res; @@ -1132,12 +1137,10 @@ static inline u32 calculate_h264d_scratch_size(struct msm_vidc_inst *inst, u32 aligned_height = ALIGN(height, BUFFER_ALIGNMENT_SIZE(16)); u32 size = 0; - if (!is_interlaced) { + if (!is_interlaced) size = size_h264d_hw_bin_buffer(aligned_width, aligned_height); - size = size * NUM_OF_VPP_PIPES; - } else { + else size = 0; - } return size; } @@ -1185,7 +1188,8 @@ static inline u32 hfi_iris2_h265d_comv_size(u32 width, u32 height, return size; } -static inline u32 hfi_iris2_h265d_non_comv_size(u32 width, u32 height) +static inline u32 hfi_iris2_h265d_non_comv_size(u32 width, u32 height, + u32 num_vpp_pipes) { u32 size_bse, size_vpp; u32 size = 0; @@ -1205,9 +1209,9 @@ static inline u32 hfi_iris2_h265d_non_comv_size(u32 width, u32 height) ALIGN(SIZE_H265D_LB_FE_TOP_CTRL(width, height), VENUS_DMA_ALIGNMENT) + ALIGN(SIZE_H265D_LB_FE_LEFT_CTRL(width, height), - VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + VENUS_DMA_ALIGNMENT) * num_vpp_pipes + ALIGN(SIZE_H265D_LB_SE_LEFT_CTRL(width, height), - VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + VENUS_DMA_ALIGNMENT) * num_vpp_pipes + ALIGN(SIZE_H265D_LB_SE_TOP_CTRL(width, height), VENUS_DMA_ALIGNMENT) + ALIGN(SIZE_H265D_LB_PE_TOP_DATA(width, height), @@ -1215,7 +1219,7 @@ static inline u32 hfi_iris2_h265d_non_comv_size(u32 width, u32 height) ALIGN(SIZE_H265D_LB_VSP_TOP(width, height), VENUS_DMA_ALIGNMENT) + ALIGN(SIZE_H265D_LB_VSP_LEFT(width, height), - VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + VENUS_DMA_ALIGNMENT) * num_vpp_pipes + ALIGN(SIZE_H265D_LB_RECON_DMA_METADATA_WR(width, height), VENUS_DMA_ALIGNMENT) * 4 + ALIGN(SIZE_H265D_QP(width, height), VENUS_DMA_ALIGNMENT); @@ -1233,10 +1237,8 @@ static inline u32 size_h265d_hw_bin_buffer(u32 width, u32 height) size_yuv = (product <= BIN_BUFFER_THRESHOLD) ? ((BIN_BUFFER_THRESHOLD * 3) >> 1) : ((product * 3) >> 1); - size_bin_hdr = size_yuv * H265_CABAC_HDR_RATIO_HD_TOT_NUM / - H265_CABAC_HDR_RATIO_HD_TOT_DEN; - size_bin_res = size_yuv * H265_CABAC_RES_RATIO_HD_TOT_NUM / - H265_CABAC_RES_RATIO_HD_TOT_DEN; + size_bin_hdr = size_yuv * H265_CABAC_HDR_RATIO_HD_TOT; + size_bin_res = size_yuv * H265_CABAC_RES_RATIO_HD_TOT; size_bin_hdr = ALIGN(size_bin_hdr, VENUS_DMA_ALIGNMENT); size_bin_res = ALIGN(size_bin_res, VENUS_DMA_ALIGNMENT); size = size_bin_hdr + size_bin_res; @@ -1251,12 +1253,10 @@ static inline u32 calculate_h265d_scratch_size(struct msm_vidc_inst *inst, u32 aligned_height = ALIGN(height, BUFFER_ALIGNMENT_SIZE(16)); u32 size = 0; - if (!is_interlaced) { + if (!is_interlaced) size = size_h265d_hw_bin_buffer(aligned_width, aligned_height); - size = size * NUM_OF_VPP_PIPES; - } else { + else size = 0; - } return size; } @@ -1299,7 +1299,7 @@ static inline u32 calculate_mpeg2d_scratch_size(struct msm_vidc_inst *inst, } static inline u32 calculate_enc_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 work_mode, u32 lcu_size) + u32 width, u32 height, u32 work_mode, u32 lcu_size, u32 num_vpp_pipes) { u32 aligned_width, aligned_height, bitstream_size; u32 total_bitbin_buffers = 0, size_singlePipe, bitbin_size = 0; @@ -1319,7 +1319,10 @@ static inline u32 calculate_enc_scratch_size(struct msm_vidc_inst *inst, bitstream_size = aligned_width * aligned_height * 3; bitbin_size = ALIGN(bitstream_size, VENUS_DMA_ALIGNMENT); } - size_singlePipe = bitbin_size / 2; + if (num_vpp_pipes > 2) + size_singlePipe = bitbin_size / 2; + else + size_singlePipe = bitbin_size; if (inst->rc_type == RATE_CONTROL_LOSSLESS) size_singlePipe <<= 1; size_singlePipe = ALIGN(size_singlePipe, VENUS_DMA_ALIGNMENT); @@ -1328,7 +1331,7 @@ static inline u32 calculate_enc_scratch_size(struct msm_vidc_inst *inst, padded_bin_size = ALIGN(size_singlePipe, VENUS_DMA_ALIGNMENT); size_singlePipe = sao_bin_buffer_size + padded_bin_size; size_singlePipe = ALIGN(size_singlePipe, VENUS_DMA_ALIGNMENT); - bitbin_size = size_singlePipe * NUM_OF_VPP_PIPES; + bitbin_size = size_singlePipe * num_vpp_pipes; size = ALIGN(bitbin_size, VENUS_DMA_ALIGNMENT) * total_bitbin_buffers + 512; @@ -1336,50 +1339,56 @@ static inline u32 calculate_enc_scratch_size(struct msm_vidc_inst *inst, } static inline u32 calculate_h264e_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 work_mode) + u32 width, u32 height, u32 work_mode, u32 num_vpp_pipes) { - return calculate_enc_scratch_size(inst, width, height, work_mode, 16); + return calculate_enc_scratch_size(inst, width, height, work_mode, 16, + num_vpp_pipes); } static inline u32 calculate_h265e_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 work_mode) + u32 width, u32 height, u32 work_mode, u32 num_vpp_pipes) { - return calculate_enc_scratch_size(inst, width, height, work_mode, 32); + return calculate_enc_scratch_size(inst, width, height, work_mode, 32, + num_vpp_pipes); } static inline u32 calculate_vp8e_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 work_mode) + u32 width, u32 height, u32 work_mode, u32 num_vpp_pipes) { - return calculate_enc_scratch_size(inst, width, height, work_mode, 16); + return calculate_enc_scratch_size(inst, width, height, work_mode, 16, + num_vpp_pipes); } static inline u32 calculate_h264d_scratch1_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled) + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled, + u32 num_vpp_pipes) { u32 co_mv_size = 0, nonco_mv_size = 0; u32 vpss_lb_size = 0; u32 size = 0; co_mv_size = hfi_iris2_h264d_comv_size(width, height, min_buf_count); - nonco_mv_size = hfi_iris2_h264d_non_comv_size(width, height); + nonco_mv_size = hfi_iris2_h264d_non_comv_size(width, height, + num_vpp_pipes); if (split_mode_enabled) - vpss_lb_size = size_vpss_lb(width, height); - + vpss_lb_size = size_vpss_lb(width, height, num_vpp_pipes); size = co_mv_size + nonco_mv_size + vpss_lb_size; return size; } static inline u32 calculate_h265d_scratch1_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled) + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled, + u32 num_vpp_pipes) { u32 co_mv_size = 0, nonco_mv_size = 0; u32 vpss_lb_size = 0; u32 size = 0; co_mv_size = hfi_iris2_h265d_comv_size(width, height, min_buf_count); - nonco_mv_size = hfi_iris2_h265d_non_comv_size(width, height); + nonco_mv_size = + hfi_iris2_h265d_non_comv_size(width, height, num_vpp_pipes); if (split_mode_enabled) - vpss_lb_size = size_vpss_lb(width, height); + vpss_lb_size = size_vpss_lb(width, height, num_vpp_pipes); size = co_mv_size + nonco_mv_size + vpss_lb_size + HDR10_HIST_EXTRADATA_SIZE; @@ -1393,16 +1402,17 @@ static inline u32 hfi_iris2_vp8d_comv_size(u32 width, u32 height, } static inline u32 calculate_vp8d_scratch1_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled) + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled, + u32 num_vpp_pipes) { u32 vpss_lb_size = 0; u32 size = 0; size = hfi_iris2_vp8d_comv_size(width, height, 0); size += ALIGN(SIZE_VPXD_LB_FE_LEFT_CTRL(width, height), - VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + VENUS_DMA_ALIGNMENT) * num_vpp_pipes + ALIGN(SIZE_VPXD_LB_SE_LEFT_CTRL(width, height), - VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + VENUS_DMA_ALIGNMENT) * num_vpp_pipes + ALIGN(SIZE_VP8D_LB_VSP_TOP(width, height), VENUS_DMA_ALIGNMENT) + ALIGN(SIZE_VPXD_LB_FE_TOP_CTRL(width, height), @@ -1416,22 +1426,23 @@ static inline u32 calculate_vp8d_scratch1_size(struct msm_vidc_inst *inst, ALIGN(SIZE_VP8D_LB_FE_TOP_DATA(width, height), VENUS_DMA_ALIGNMENT); if (split_mode_enabled) - vpss_lb_size = size_vpss_lb(width, height); + vpss_lb_size = size_vpss_lb(width, height, num_vpp_pipes); size += vpss_lb_size; return size; } static inline u32 calculate_vp9d_scratch1_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled) + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled, + u32 num_vpp_pipes) { u32 vpss_lb_size = 0; u32 size = 0; size = ALIGN(SIZE_VPXD_LB_FE_LEFT_CTRL(width, height), - VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + VENUS_DMA_ALIGNMENT) * num_vpp_pipes + ALIGN(SIZE_VPXD_LB_SE_LEFT_CTRL(width, height), - VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + VENUS_DMA_ALIGNMENT) * num_vpp_pipes + ALIGN(SIZE_VP9D_LB_VSP_TOP(width, height), VENUS_DMA_ALIGNMENT) + ALIGN(SIZE_VPXD_LB_FE_TOP_CTRL(width, height), @@ -1445,22 +1456,23 @@ static inline u32 calculate_vp9d_scratch1_size(struct msm_vidc_inst *inst, ALIGN(SIZE_VP9D_LB_FE_TOP_DATA(width, height), VENUS_DMA_ALIGNMENT); if (split_mode_enabled) - vpss_lb_size = size_vpss_lb(width, height); + vpss_lb_size = size_vpss_lb(width, height, num_vpp_pipes); size += vpss_lb_size + HDR10_HIST_EXTRADATA_SIZE; return size; } static inline u32 calculate_mpeg2d_scratch1_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled) + u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled, + u32 num_vpp_pipes) { u32 vpss_lb_size = 0; u32 size = 0; size = ALIGN(SIZE_VPXD_LB_FE_LEFT_CTRL(width, height), - VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + VENUS_DMA_ALIGNMENT) * num_vpp_pipes + ALIGN(SIZE_VPXD_LB_SE_LEFT_CTRL(width, height), - VENUS_DMA_ALIGNMENT) * NUM_OF_VPP_PIPES + + VENUS_DMA_ALIGNMENT) * num_vpp_pipes + ALIGN(SIZE_VP8D_LB_VSP_TOP(width, height), VENUS_DMA_ALIGNMENT) + ALIGN(SIZE_VPXD_LB_FE_TOP_CTRL(width, height), @@ -1474,7 +1486,7 @@ static inline u32 calculate_mpeg2d_scratch1_size(struct msm_vidc_inst *inst, ALIGN(SIZE_VP8D_LB_FE_TOP_DATA(width, height), VENUS_DMA_ALIGNMENT); if (split_mode_enabled) - vpss_lb_size = size_vpss_lb(width, height); + vpss_lb_size = size_vpss_lb(width, height, num_vpp_pipes); size += vpss_lb_size; return size; @@ -1630,27 +1642,27 @@ static inline u32 calculate_enc_scratch1_size(struct msm_vidc_inst *inst, } static inline u32 calculate_h264e_scratch1_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 num_ref, bool ten_bit) + u32 width, u32 height, u32 num_ref, bool ten_bit, u32 num_vpp_pipes) { return calculate_enc_scratch1_size(inst, width, height, 16, - num_ref, ten_bit, NUM_OF_VPP_PIPES, false); + num_ref, ten_bit, num_vpp_pipes, false); } static inline u32 calculate_h265e_scratch1_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 num_ref, bool ten_bit) + u32 width, u32 height, u32 num_ref, bool ten_bit, u32 num_vpp_pipes) { return calculate_enc_scratch1_size(inst, width, height, 32, - num_ref, ten_bit, NUM_OF_VPP_PIPES, true); + num_ref, ten_bit, num_vpp_pipes, true); } static inline u32 calculate_vp8e_scratch1_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 num_ref, bool ten_bit) + u32 width, u32 height, u32 num_ref, bool ten_bit, u32 num_vpp_pipes) { + (void)num_vpp_pipes; return calculate_enc_scratch1_size(inst, width, height, 16, num_ref, ten_bit, 1, false); } - static inline u32 hfi_ubwc_calc_metadata_plane_stride(u32 width, u32 metadata_stride_multi, u32 tile_width_pels) { diff --git a/msm/vidc/msm_vidc_buffer_calculations.h b/msm/vidc/msm_vidc_buffer_calculations.h index 2583a5e54b24..a94bc485e32b 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.h +++ b/msm/vidc/msm_vidc_buffer_calculations.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #ifndef __H_MSM_VIDC_BUFFER_MEM_DEFS_H__ @@ -14,15 +14,17 @@ struct msm_vidc_dec_buff_size_calculators { u32 (*calculate_scratch_size)(struct msm_vidc_inst *inst, u32 width, u32 height, bool is_interlaced); u32 (*calculate_scratch1_size)(struct msm_vidc_inst *inst, u32 width, - u32 height, u32 min_buf_count, bool split_mode_enabled); + u32 height, u32 min_buf_count, bool split_mode_enabled, + u32 num_vpp_pipes); u32 (*calculate_persist1_size)(void); }; struct msm_vidc_enc_buff_size_calculators { u32 (*calculate_scratch_size)(struct msm_vidc_inst *inst, u32 width, - u32 height, u32 work_mode); + u32 height, u32 work_mode, u32 num_vpp_pipes); u32 (*calculate_scratch1_size)(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 num_ref, bool ten_bit); + u32 width, u32 height, u32 num_ref, bool ten_bit, + u32 num_vpp_pipes); u32 (*calculate_scratch2_size)(struct msm_vidc_inst *inst, u32 width, u32 height, u32 num_ref, bool ten_bit); u32 (*calculate_persist_size)(void); diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 486aed03fa74..33bbd0b24e00 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef _MSM_VIDC_INTERNAL_H_ @@ -294,6 +294,7 @@ struct msm_vidc_platform_data { unsigned int efuse_data_length; unsigned int sku_version; uint32_t vpu_ver; + uint32_t num_vpp_pipes; struct msm_vidc_ubwc_config_data *ubwc_config; }; diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 92e120ba7628..9c71ba390339 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #include @@ -552,6 +552,7 @@ static struct msm_vidc_platform_data default_data = { .efuse_data_length = 0, .sku_version = 0, .vpu_ver = VPU_VERSION_IRIS2, + .num_vpp_pipes = 0x4, .ubwc_config = 0x0, }; @@ -567,6 +568,7 @@ static struct msm_vidc_platform_data lahaina_data = { .efuse_data_length = 0, .sku_version = 0, .vpu_ver = VPU_VERSION_IRIS2, + .num_vpp_pipes = 0x4, .ubwc_config = lahaina_ubwc_data, .codecs = default_codecs, .codecs_count = ARRAY_SIZE(default_codecs), @@ -586,6 +588,7 @@ static struct msm_vidc_platform_data bengal_data = { .efuse_data_length = 0, .sku_version = 0, .vpu_ver = VPU_VERSION_AR50_LITE, + .num_vpp_pipes = 0x1, .ubwc_config = 0x0, .codecs = bengal_codecs, .codecs_count = ARRAY_SIZE(bengal_codecs), From c638b9401e3e17e7bd22e7e6c2e625293c47ff9b Mon Sep 17 00:00:00 2001 From: Rakshitha Shakamuri Date: Thu, 20 Feb 2020 14:53:23 -0800 Subject: [PATCH 230/452] msm: vidc: Increase the persist buffer size for encoder on Lahaina Updated the HFI_IRIS2_ENC_PERSIST_SIZE parameter to be allocated by encoder ARP buffer. Change-Id: I09fa92d1f04348266f1fae71479c9b1c077556ae Signed-off-by: Rakshitha Shakamuri --- msm/vidc/msm_vidc_buffer_calculations.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 558b0ccea280..e6b5a38a60f8 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -245,12 +245,13 @@ #define QMATRIX_SIZE (sizeof(u32) * 128 + 256) #define MP2D_QPDUMP_SIZE 115200 -#define HFI_IRIS2_ENC_PERSIST_SIZE 102400 +#define HFI_VENUS_VPPSG_MAX_REGISTERS 2048 +#define HFI_IRIS2_ENC_PERSIST_SIZE \ + ((((HFI_VENUS_VPPSG_MAX_REGISTERS << 3) + 255) & (~255)) * 10) #define HFI_MAX_COL_FRAME 6 #define HFI_VENUS_VENC_TRE_WB_BUFF_SIZE (65 << 4) // bytes #define HFI_VENUS_VENC_DB_LINE_BUFF_PER_MB 512 -#define HFI_VENUS_VPPSG_MAX_REGISTERS 2048 #define HFI_VENUS_WIDTH_ALIGNMENT 128 #define HFI_VENUS_WIDTH_TEN_BIT_ALIGNMENT 192 #define HFI_VENUS_HEIGHT_ALIGNMENT 32 From 307e961aa9705909dc311fda0bfe2ca5bace898a Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 19 Feb 2020 18:25:30 +0530 Subject: [PATCH 231/452] msm: vidc: do not update operating rate during INT_MAX INT_MAX is an interface provided to client to configure video session in TURBO mode. When client configures the operating rate as INT_MAX, the rate at which the frames arrive at video driver does not change, so there is no need to update the operating rate. If the operating rate is updated, macroblocks/s for the session goes high. As a result, the session gets rejected as the clock is not sufficient for high mbs/s. Change-Id: Iaa48073a486ce6435664a6afb8a4c6ddd7b7f87d Signed-off-by: Vikash Garodia Signed-off-by: Rakshitha Shakamuri --- msm/vidc/msm_vdec.c | 5 +++-- msm/vidc/msm_venc.c | 11 ++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index b0f5ee407747..e677ebb99f40 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include "msm_vdec.h" @@ -914,10 +914,11 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY: break; case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: - inst->clk_data.operating_rate = ctrl->val; inst->flags &= ~VIDC_TURBO; if (ctrl->val == INT_MAX) inst->flags |= VIDC_TURBO; + else + inst->clk_data.operating_rate = ctrl->val; break; case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE: inst->clk_data.low_latency_mode = !!ctrl->val; diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 1f25e4c65116..536fd92ee82e 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include "msm_venc.h" #include "msm_vidc_internal.h" @@ -1670,16 +1670,17 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } break; case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: - inst->clk_data.operating_rate = ctrl->val; + inst->flags &= ~VIDC_TURBO; + if (ctrl->val == INT_MAX) + inst->flags |= VIDC_TURBO; + else + inst->clk_data.operating_rate = ctrl->val; /* For HEIC image encode, set operating rate to 1 */ if (is_grid_session(inst)) { s_vpr_h(sid, "%s: set operating rate to 1 for HEIC\n", __func__); inst->clk_data.operating_rate = 1 << 16; } - inst->flags &= ~VIDC_TURBO; - if (ctrl->val == INT_MAX) - inst->flags |= VIDC_TURBO; if (inst->state < MSM_VIDC_LOAD_RESOURCES) msm_vidc_calculate_buffer_counts(inst); if (inst->state == MSM_VIDC_START_DONE) { From 8af58f371e14477c3d7d3546d08b8a534b851b7f Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Mon, 24 Feb 2020 12:34:50 +0530 Subject: [PATCH 232/452] msm: vidc: update capability for quality mode Usecase like UHD encode is configured by driver in high quality mode. But video firmware overwrites the mode to performance mode. Update the quality configuration to make them inline with video firmware configuration. Change-Id: I6f432bbf889c01d0a9b1f91bfb3d2dd2b9351b5b Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_clocks.c | 6 +----- msm/vidc/msm_vidc_platform.c | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 4695efa82f24..a967e92d8fbf 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1289,16 +1289,12 @@ int msm_vidc_decide_core_and_power_mode_iris2(struct msm_vidc_inst *inst) inst->clk_data.core_id = VIDC_CORE_ID_1; - /* Power saving always disabled for CQ and LOSSLESS RC modes. */ mbpf = msm_vidc_get_mbs_per_frame(inst); mbps = mbpf * msm_vidc_get_fps(inst); max_hq_mbpf = inst->core->resources.max_hq_mbs_per_frame; max_hq_mbps = inst->core->resources.max_hq_mbs_per_sec; - if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ || - inst->rc_type == RATE_CONTROL_LOSSLESS || - inst->all_intra || - (mbpf <= max_hq_mbpf && mbps <= max_hq_mbps)) + if (mbpf <= max_hq_mbpf && mbps <= max_hq_mbps) enable = false; rc = msm_vidc_power_save_mode_enable(inst, enable); diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 9c71ba390339..244be41ac700 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -381,11 +381,11 @@ static struct msm_vidc_common_data lahaina_common_data[] = { }, { .key = "qcom,max-hq-mbs-per-frame", - .value = 34816, /* 4096x2176 */ + .value = 8160, /* ((1920x1088)/256) */ }, { .key = "qcom,max-hq-mbs-per-sec", - .value = 1044480, /* 4096x2176@30fps */ + .value = 489600, /* ((1920x1088)/256)@60fps */ }, { .key = "qcom,max-b-frame-mbs-per-frame", From f3511e846ed6e30cf21b323452b701be633f8c48 Mon Sep 17 00:00:00 2001 From: Rakshitha Shakamuri Date: Tue, 25 Feb 2020 11:57:32 -0800 Subject: [PATCH 233/452] msm: vidc: Update the persist buffer size for encoder on Lahaina Updated the HFI_IRIS2_ENC_PERSIST_SIZE parameter to use double the existing buffer size instead of calculating on HFI_VENUS_VPPSG_MAX_REGISTERS. Change-Id: I434e084db95082906638a4a288ed848f3bab89d3 Signed-off-by: Rakshitha Shakamuri --- msm/vidc/msm_vidc_buffer_calculations.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index e6b5a38a60f8..c3cbcfb5045c 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -245,13 +245,12 @@ #define QMATRIX_SIZE (sizeof(u32) * 128 + 256) #define MP2D_QPDUMP_SIZE 115200 -#define HFI_VENUS_VPPSG_MAX_REGISTERS 2048 -#define HFI_IRIS2_ENC_PERSIST_SIZE \ - ((((HFI_VENUS_VPPSG_MAX_REGISTERS << 3) + 255) & (~255)) * 10) +#define HFI_IRIS2_ENC_PERSIST_SIZE 204800 #define HFI_MAX_COL_FRAME 6 #define HFI_VENUS_VENC_TRE_WB_BUFF_SIZE (65 << 4) // bytes #define HFI_VENUS_VENC_DB_LINE_BUFF_PER_MB 512 +#define HFI_VENUS_VPPSG_MAX_REGISTERS 2048 #define HFI_VENUS_WIDTH_ALIGNMENT 128 #define HFI_VENUS_WIDTH_TEN_BIT_ALIGNMENT 192 #define HFI_VENUS_HEIGHT_ALIGNMENT 32 From 494d4b0e210a7cf38705471a0b484633037d92a4 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Thu, 27 Feb 2020 11:28:01 -0800 Subject: [PATCH 234/452] msm: vidc: Use sid to create instance debugfs directory Currently, instance pointer value is used to create an instance debugfs name. Using instance pointer causes multiple instances to have the same debugfs name when kptr restriction is applied. Use instance sid instead of pointer value to create a unique debugfs name during concurrencies. Also, use %pK instead of %p in other places. Change-Id: I098f641e9a548bcb8bf6d939422607cdc194adb3 Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_clocks.c | 2 +- msm/vidc/msm_vidc_debug.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index a967e92d8fbf..da9ff137d412 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -920,7 +920,7 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc) int msm_dcvs_try_enable(struct msm_vidc_inst *inst) { if (!inst || !inst->core) { - d_vpr_e("%s: Invalid args: %p\n", __func__, inst); + d_vpr_e("%s: Invalid args: %pK\n", __func__, inst); return -EINVAL; } diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index 6628318482d1..ccb0dc4ab6a8 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #define CREATE_TRACE_POINTS @@ -478,7 +478,7 @@ struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst, d_vpr_e("%s: invalid params\n", __func__); goto exit; } - snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%p", inst); + snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%d", inst->sid); idata = kzalloc(sizeof(struct core_inst_pair), GFP_KERNEL); if (!idata) { @@ -490,14 +490,14 @@ struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst, idata->inst = inst; dir = debugfs_create_dir(debugfs_name, parent); - if (!dir) { + if (IS_ERR_OR_NULL(dir)) { s_vpr_e(inst->sid, "Failed to create debugfs for msm_vidc\n"); goto failed_create_dir; } info = debugfs_create_file("info", 0444, dir, idata, &inst_info_fops); - if (!info) { + if (IS_ERR_OR_NULL(info)) { s_vpr_e(inst->sid, "debugfs_create_file: fail\n"); goto failed_create_file; } From 455cd2b148a7e330b49a7b46c1d67c79c7bada43 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 28 Feb 2020 17:42:40 +0530 Subject: [PATCH 235/452] msm: vidc: update input tag implementation In qbuf (input) store input_tag to etb_data list and send it to firmware in etb. Firmware will return input_tag in ftb_done, store it in fbd_data list and return the same when client does dqbuf (output). Change-Id: I3589e5a3017cac49000fc64191f9f756bc4011f4 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc.c | 50 +++----------- msm/vidc/msm_vidc_common.c | 122 ++++------------------------------- msm/vidc/msm_vidc_common.h | 7 +- msm/vidc/msm_vidc_internal.h | 7 -- 4 files changed, 23 insertions(+), 163 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 95a033d740b0..7173d008e920 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -363,7 +363,6 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, struct v4l2_buffer *b) { struct msm_vidc_inst *inst = instance; - struct msm_vidc_client_data *client_data = NULL; int rc = 0; unsigned int i = 0; struct buf_queue *q = NULL; @@ -402,16 +401,15 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, } if (b->type == INPUT_MPLANE) { - client_data = msm_comm_store_client_data(inst, - b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_1]); - if (!client_data) { - s_vpr_e(inst->sid, - "%s: failed to store client data\n", __func__); + rc = msm_comm_store_input_tag(&inst->etb_data, b->index, + b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_1], + 0, inst->sid); + if (rc) { + s_vpr_e(inst->sid, "Failed to store input tag"); return -EINVAL; } - msm_comm_store_input_tag(&inst->etb_data, b->index, - client_data->id, 0, inst->sid); } + /* * set perf mode for image session buffers so that * they will be processed quickly @@ -442,8 +440,6 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) int rc = 0; unsigned int i = 0; struct buf_queue *q = NULL; - u32 input_tag = 0, input_tag2 = 0; - bool remove; if (!inst || !b || !valid_v4l2_buffer(b, inst)) { d_vpr_e("%s: invalid params, %pK %pK\n", @@ -474,36 +470,15 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) b->m.planes[i].reserved[MSM_VIDC_DATA_OFFSET] = b->m.planes[i].data_offset; } - /** - * Flush handling: - * Don't fetch tag - if flush issued at input/output port. - * Fetch tag - if atleast 1 ebd received after flush. (Flush_done - * event may be notified to userspace even before client - * dequeus all buffers at FBD, to avoid this race condition - * fetch tag atleast 1 ETB is successfully processed after flush) - */ - if (b->type == OUTPUT_MPLANE && !inst->in_flush && - !inst->out_flush && - (inst->session_type == MSM_VIDC_ENCODER || - inst->clk_data.buffer_counter)) { + if (b->type == OUTPUT_MPLANE) { rc = msm_comm_fetch_input_tag(&inst->fbd_data, b->index, - &input_tag, &input_tag2, inst->sid); + &b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_1], + &b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_2], + inst->sid); if (rc) { s_vpr_e(inst->sid, "Failed to fetch input tag"); return -EINVAL; } - /** - * During flush input_tag & input_tag2 will be zero. - * Check before retrieving client data - */ - if (input_tag) { - remove = !(b->flags & V4L2_BUF_FLAG_END_OF_SUBFRAME) && - !(b->flags & V4L2_BUF_FLAG_CODECCONFIG); - msm_comm_fetch_client_data(inst, remove, - input_tag, input_tag2, - &b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_1], - &b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_2]); - } } return rc; @@ -1470,7 +1445,6 @@ void *msm_vidc_open(int core_id, int session_type) INIT_MSM_VIDC_LIST(&inst->registeredbufs); INIT_MSM_VIDC_LIST(&inst->refbufs); INIT_MSM_VIDC_LIST(&inst->eosbufs); - INIT_MSM_VIDC_LIST(&inst->client_data); INIT_MSM_VIDC_LIST(&inst->etb_data); INIT_MSM_VIDC_LIST(&inst->fbd_data); INIT_MSM_VIDC_LIST(&inst->window_data); @@ -1575,7 +1549,6 @@ void *msm_vidc_open(int core_id, int session_type) DEINIT_MSM_VIDC_LIST(&inst->registeredbufs); DEINIT_MSM_VIDC_LIST(&inst->eosbufs); DEINIT_MSM_VIDC_LIST(&inst->input_crs); - DEINIT_MSM_VIDC_LIST(&inst->client_data); DEINIT_MSM_VIDC_LIST(&inst->etb_data); DEINIT_MSM_VIDC_LIST(&inst->fbd_data); DEINIT_MSM_VIDC_LIST(&inst->window_data); @@ -1645,8 +1618,6 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst) if (msm_comm_release_input_tag(inst)) s_vpr_e(inst->sid, "Failed to release input_tag buffers\n"); - msm_comm_release_client_data(inst, true); - msm_comm_release_window_data(inst); msm_comm_release_eos_buffers(inst); @@ -1702,7 +1673,6 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) DEINIT_MSM_VIDC_LIST(&inst->registeredbufs); DEINIT_MSM_VIDC_LIST(&inst->eosbufs); DEINIT_MSM_VIDC_LIST(&inst->input_crs); - DEINIT_MSM_VIDC_LIST(&inst->client_data); DEINIT_MSM_VIDC_LIST(&inst->etb_data); DEINIT_MSM_VIDC_LIST(&inst->fbd_data); DEINIT_MSM_VIDC_LIST(&inst->window_data); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index f51f5d82ab82..d1d0a851aa4a 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2042,7 +2042,6 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) if (flush_type == HAL_FLUSH_ALL) { msm_comm_clear_window_data(inst); - msm_comm_release_client_data(inst, false); inst->clk_data.buffer_counter = 0; } @@ -2511,6 +2510,7 @@ static void handle_fbd(enum hal_command_response cmd, void *data) u64 time_usec = 0; u32 planes[VIDEO_MAX_PLANES] = {0}; struct v4l2_format *f; + int rc = 0; if (!response) { d_vpr_e("Invalid response from vidc_hal\n"); @@ -2574,8 +2574,11 @@ static void handle_fbd(enum hal_command_response cmd, void *data) vb->timestamp = (time_usec * NSEC_PER_USEC); - msm_comm_store_input_tag(&inst->fbd_data, vb->index, - fill_buf_done->input_tag, fill_buf_done->input_tag2, inst->sid); + rc = msm_comm_store_input_tag(&inst->fbd_data, vb->index, + fill_buf_done->input_tag, + fill_buf_done->input_tag2, inst->sid); + if (rc) + s_vpr_e(inst->sid, "Failed to store input tag"); if (inst->session_type == MSM_VIDC_ENCODER) { if (inst->max_filled_len < fill_buf_done->filled_len1) @@ -6783,120 +6786,16 @@ bool kref_get_mbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) return ret; } -struct msm_vidc_client_data *msm_comm_store_client_data( - struct msm_vidc_inst *inst, u32 itag) -{ - struct msm_vidc_client_data *data = NULL, *temp = NULL; - - if (!inst) { - d_vpr_e("%s: invalid params\n", __func__); - return NULL; - } - - mutex_lock(&inst->client_data.lock); - list_for_each_entry(temp, &inst->client_data.list, list) { - if (!temp->id) { - data = temp; - break; - } - } - if (!data) { - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) { - s_vpr_e(inst->sid, "%s: No memory avilable", __func__); - goto exit; - } - INIT_LIST_HEAD(&data->list); - list_add_tail(&data->list, &inst->client_data.list); - } - - /** - * Special handling, if etb_counter reaches to 2^32 - 1, - * then start next value from 1 not 0. - */ - if (!inst->etb_counter) - inst->etb_counter = 1; - - data->id = inst->etb_counter++; - data->input_tag = itag; - -exit: - mutex_unlock(&inst->client_data.lock); - - return data; -} - -void msm_comm_fetch_client_data(struct msm_vidc_inst *inst, bool remove, - u32 itag, u32 itag2, u32 *otag, u32 *otag2) -{ - struct msm_vidc_client_data *temp, *next; - bool found_itag = false, found_itag2 = false; - - if (!inst || !otag || !otag2) { - d_vpr_e("%s: invalid params %pK %x %x\n", - __func__, inst, otag, otag2); - return; - } - /** - * Some interlace clips, both BF & TF is available in single ETB buffer. - * In that case, firmware copies same input_tag value to both input_tag - * and input_tag2 at FBD. - */ - if (!itag2 || itag == itag2) - found_itag2 = true; - mutex_lock(&inst->client_data.lock); - list_for_each_entry_safe(temp, next, &inst->client_data.list, list) { - if (temp->id == itag) { - *otag = temp->input_tag; - found_itag = true; - if (remove) - temp->id = 0; - } else if (!found_itag2 && temp->id == itag2) { - *otag2 = temp->input_tag; - found_itag2 = true; - if (remove) - temp->id = 0; - } - if (found_itag && found_itag2) - break; - } - mutex_unlock(&inst->client_data.lock); - - if (!found_itag || !found_itag2) { - s_vpr_e(inst->sid, "%s: client data not found - %u, %u\n", - __func__, itag, itag2); - } -} - -void msm_comm_release_client_data(struct msm_vidc_inst *inst, bool remove) -{ - struct msm_vidc_client_data *temp, *next; - - if (!inst) { - d_vpr_e("%s: invalid params\n", __func__); - return; - } - - mutex_lock(&inst->client_data.lock); - list_for_each_entry_safe(temp, next, &inst->client_data.list, list) { - temp->id = 0; - if (remove) { - list_del(&temp->list); - kfree(temp); - } - } - mutex_unlock(&inst->client_data.lock); -} - -void msm_comm_store_input_tag(struct msm_vidc_list *data_list, +int msm_comm_store_input_tag(struct msm_vidc_list *data_list, u32 index, u32 itag, u32 itag2, u32 sid) { struct msm_vidc_buf_data *pdata = NULL; bool found = false; + int rc = 0; if (!data_list) { s_vpr_e(sid, "%s: invalid params\n", __func__); - return; + return -EINVAL; } mutex_lock(&data_list->lock); @@ -6913,6 +6812,7 @@ void msm_comm_store_input_tag(struct msm_vidc_list *data_list, pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) { s_vpr_e(sid, "%s: malloc failure.\n", __func__); + rc = -ENOMEM; goto exit; } pdata->index = index; @@ -6923,6 +6823,8 @@ void msm_comm_store_input_tag(struct msm_vidc_list *data_list, exit: mutex_unlock(&data_list->lock); + + return rc; } int msm_comm_fetch_input_tag(struct msm_vidc_list *data_list, diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 39ec0fcd8a22..79a83cd42b3b 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -308,16 +308,11 @@ void print_vb2_buffer(const char *str, struct msm_vidc_inst *inst, struct vb2_buffer *vb2); void kref_put_mbuf(struct msm_vidc_buffer *mbuf); bool kref_get_mbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); -void msm_comm_store_input_tag(struct msm_vidc_list *data_list, +int msm_comm_store_input_tag(struct msm_vidc_list *data_list, u32 index, u32 itag, u32 itag2, u32 sid); int msm_comm_fetch_input_tag(struct msm_vidc_list *data_list, u32 index, u32 *itag, u32 *itag2, u32 sid); int msm_comm_release_input_tag(struct msm_vidc_inst *inst); -struct msm_vidc_client_data *msm_comm_store_client_data( - struct msm_vidc_inst *inst, u32 itag); -void msm_comm_fetch_client_data(struct msm_vidc_inst *inst, bool remove, - u32 itag, u32 itag2, u32 *mdata, u32 *mtarget); -void msm_comm_release_client_data(struct msm_vidc_inst *inst, bool remove); int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst, diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 33bbd0b24e00..a3b8400cb1f9 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -204,12 +204,6 @@ struct msm_vidc_window_data { u32 etb_count; }; -struct msm_vidc_client_data { - struct list_head list; - u32 id; - u32 input_tag; -}; - struct msm_vidc_common_data { char key[128]; int value; @@ -530,7 +524,6 @@ struct msm_vidc_inst { enum multi_stream stream_output_mode; struct v4l2_ctrl **ctrls; u32 num_ctrls; - u32 etb_counter; int bit_depth; struct kref kref; bool in_flush; From 6134119508889617ac0af92d06d82257aae93cea Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Wed, 26 Feb 2020 10:46:28 -0800 Subject: [PATCH 236/452] msm: vidc: calculate decoder fps based on timestamps Calculate decoder framerate based on input buffer timestamps and maintain a sorted order list for timestamps and framerate in a sliding window of size 32. Send calculated framerate to client in every dqbuf output buffer. Use the maximum framerate available in the list for bandwidth and clockrate calculations. Change-Id: I5fa357645cb806bf97ccd30ed68bd784d526e233 Signed-off-by: Darshana Patil --- include/uapi/vidc/media/msm_vidc_utils.h | 3 +- msm/vidc/msm_vdec.c | 13 -- msm/vidc/msm_vidc.c | 27 ++++ msm/vidc/msm_vidc_common.c | 192 ++++++++++++++++++++++- msm/vidc/msm_vidc_common.h | 7 + msm/vidc/msm_vidc_internal.h | 8 + 6 files changed, 235 insertions(+), 15 deletions(-) diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index d8ef6f851a7a..538d6508e9f9 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #ifndef __MSM_VIDC_UTILS_H__ @@ -616,6 +616,7 @@ enum msm_vidc_plane_reserved_field_types { MSM_VIDC_COMP_RATIO, MSM_VIDC_INPUT_TAG_1, MSM_VIDC_INPUT_TAG_2, + MSM_VIDC_FRAMERATE, }; enum msm_vidc_cb_event_types { diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index e677ebb99f40..c535e3fe1347 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -357,16 +357,6 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .step = 1, .qmenu = NULL, }, - { - .id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE, - .name = "Frame Rate", - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = (MINIMUM_FPS << 16), - .maximum = (MAXIMUM_FPS << 16), - .default_value = (DEFAULT_FPS << 16), - .step = 1, - .qmenu = NULL, - }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY, .name = "Session Priority", @@ -894,9 +884,6 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) return -ENOTSUPP; } break; - case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE: - inst->clk_data.frame_rate = ctrl->val; - break; case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA: if (ctrl->val == EXTRADATA_NONE) inst->prop.extradata_ctrls = 0; diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 7173d008e920..0dc329929e9d 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -366,6 +366,7 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, int rc = 0; unsigned int i = 0; struct buf_queue *q = NULL; + u64 timestamp_us = 0; u32 cr = 0; if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) { @@ -417,6 +418,19 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, if (is_grid_session(inst) && b->type == INPUT_MPLANE) b->flags |= V4L2_BUF_FLAG_PERF_MODE; + if (is_decode_session(inst) && b->type == INPUT_MPLANE) { + if (inst->flush_timestamps) + msm_comm_release_timestamps(inst); + inst->flush_timestamps = false; + + timestamp_us = (u64)((b->timestamp.tv_sec * 1000000ULL) + + b->timestamp.tv_usec); + rc = msm_comm_store_timestamp(inst, timestamp_us); + if (rc) + return rc; + inst->clk_data.frame_rate = msm_comm_get_max_framerate(inst); + } + q = msm_comm_get_vb2q(inst, b->type); if (!q) { s_vpr_e(inst->sid, @@ -440,6 +454,7 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) int rc = 0; unsigned int i = 0; struct buf_queue *q = NULL; + u64 timestamp_us = 0; if (!inst || !b || !valid_v4l2_buffer(b, inst)) { d_vpr_e("%s: invalid params, %pK %pK\n", @@ -480,6 +495,13 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) return -EINVAL; } } + if (is_decode_session(inst) && b->type == OUTPUT_MPLANE) { + timestamp_us = (u64)((b->timestamp.tv_sec * 1000000ULL) + + b->timestamp.tv_usec); + b->m.planes[0].reserved[MSM_VIDC_FRAMERATE] = DEFAULT_FPS << 16; + msm_comm_fetch_framerate(inst, timestamp_us, + &b->m.planes[0].reserved[MSM_VIDC_FRAMERATE]); + } return rc; } @@ -1448,6 +1470,7 @@ void *msm_vidc_open(int core_id, int session_type) INIT_MSM_VIDC_LIST(&inst->etb_data); INIT_MSM_VIDC_LIST(&inst->fbd_data); INIT_MSM_VIDC_LIST(&inst->window_data); + INIT_MSM_VIDC_LIST(&inst->timestamps); INIT_DELAYED_WORK(&inst->batch_work, msm_vidc_batch_handler); kref_init(&inst->kref); @@ -1552,6 +1575,7 @@ void *msm_vidc_open(int core_id, int session_type) DEINIT_MSM_VIDC_LIST(&inst->etb_data); DEINIT_MSM_VIDC_LIST(&inst->fbd_data); DEINIT_MSM_VIDC_LIST(&inst->window_data); + DEINIT_MSM_VIDC_LIST(&inst->timestamps); err_invalid_sid: put_sid(inst->sid); @@ -1622,6 +1646,8 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst) msm_comm_release_eos_buffers(inst); + msm_comm_release_timestamps(inst); + if (msm_comm_release_dpb_only_buffers(inst, true)) s_vpr_e(inst->sid, "Failed to release output buffers\n"); @@ -1676,6 +1702,7 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) DEINIT_MSM_VIDC_LIST(&inst->etb_data); DEINIT_MSM_VIDC_LIST(&inst->fbd_data); DEINIT_MSM_VIDC_LIST(&inst->window_data); + DEINIT_MSM_VIDC_LIST(&inst->timestamps); mutex_destroy(&inst->sync_lock); mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index d1d0a851aa4a..e2be7fa36a57 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -24,6 +24,7 @@ static void handle_session_error(enum hal_command_response cmd, void *data); static void msm_vidc_print_running_insts(struct msm_vidc_core *core); #define V4L2_VP9_LEVEL_61 V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_61 +#define TIMESTAMPS_WINDOW_SIZE 32 int msm_comm_g_ctrl_for_id(struct msm_vidc_inst *inst, int id) { @@ -5364,8 +5365,20 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) /* disable in_flush & out_flush */ inst->in_flush = false; inst->out_flush = false; + goto exit; + } + /* + * Set inst->flush_timestamps to true when flush is issued + * Use this variable to clear timestamps list, everytime + * flush is issued, before adding the next buffer's timestamp + * to the list. + */ + if (is_decode_session(inst) && inst->in_flush) { + inst->flush_timestamps = true; + s_vpr_h(inst->sid, + "Setting flush variable to clear timestamp list: %d\n", + inst->flush_timestamps); } - exit: return rc; } @@ -7161,3 +7174,180 @@ void msm_comm_release_window_data(struct msm_vidc_inst *inst) } mutex_unlock(&inst->window_data.lock); } + +void msm_comm_release_timestamps(struct msm_vidc_inst *inst) +{ + struct msm_vidc_timestamps *node, *next; + + if (!inst) { + d_vpr_e("%s: invalid parameters\n", __func__); + return; + } + + mutex_lock(&inst->timestamps.lock); + list_for_each_entry_safe(node, next, &inst->timestamps.list, list) { + list_del(&node->list); + kfree(node); + } + INIT_LIST_HEAD(&inst->timestamps.list); + mutex_unlock(&inst->timestamps.lock); +} + +int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) +{ + struct msm_vidc_timestamps *entry, *node, *prev = NULL; + int count = 0; + int rc = 0; + bool inserted = false; + bool update_next = false; + + if (!inst) { + d_vpr_e("%s: invalid parameters\n", __func__); + return -EINVAL; + } + + mutex_lock(&inst->timestamps.lock); + list_for_each_entry(node, &inst->timestamps.list, list) { + count++; + /* Skip adding duplicate entries */ + if (node->timestamp_us == timestamp_us) { + s_vpr_e(inst->sid, "%s: skip ts duplicate entry %lld\n", + __func__, node->timestamp_us); + goto unlock; + } + } + + /* Maintain a sliding window of size 32 */ + entry = NULL; + if (count >= TIMESTAMPS_WINDOW_SIZE) { + entry = list_first_entry(&inst->timestamps.list, + struct msm_vidc_timestamps, list); + list_del_init(&entry->list); + } + if (!entry) { + entry = kzalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) { + s_vpr_e(inst->sid, "%s: ts malloc failure\n", + __func__); + rc = -ENOMEM; + goto unlock; + } + } + entry->timestamp_us = timestamp_us; + entry->framerate = DEFAULT_FPS << 16; + + /* add new entry into the list in sorted order */ + prev = NULL; + inserted = false; + list_for_each_entry(node, &inst->timestamps.list, list) { + if (entry->timestamp_us < node->timestamp_us) { + /* + * if prev available add entry next to prev else + * entry is first so add it at head. + */ + if (prev) + list_add(&entry->list, &prev->list); + else + list_add(&entry->list, &inst->timestamps.list); + inserted = true; + break; + } + prev = node; + } + + /* inserted will be false if list is empty */ + if (!inserted) + list_add_tail(&entry->list, &inst->timestamps.list); + + /* update framerate for both entry and entry->next (if any) */ + prev = NULL; + update_next = false; + list_for_each_entry(node, &inst->timestamps.list, list) { + if (update_next) { + node->framerate = msm_comm_calc_framerate(inst, + node->timestamp_us, prev->timestamp_us); + break; + } + if (node->timestamp_us == entry->timestamp_us) { + if (prev) + node->framerate = msm_comm_calc_framerate(inst, + node->timestamp_us, prev->timestamp_us); + update_next = true; + } + prev = node; + } + +unlock: + mutex_unlock(&inst->timestamps.lock); + return rc; +} + +u32 msm_comm_calc_framerate(struct msm_vidc_inst *inst, + u64 timestamp_us, u64 prev_ts) +{ + u32 framerate = DEFAULT_FPS << 16; + + if (timestamp_us <= prev_ts) { + s_vpr_e(inst->sid, "%s: invalid ts %lld, prev ts %lld\n", + __func__, timestamp_us, prev_ts); + return framerate; + } + framerate = (1000000 / (timestamp_us - prev_ts)) << 16; + return framerate; +} + +u32 msm_comm_get_max_framerate(struct msm_vidc_inst *inst) +{ + struct msm_vidc_timestamps *node; + u32 max_framerate = 1 << 16; + int count = 0; + + if (!inst) { + d_vpr_e("%s: invalid parameters\n", __func__); + return max_framerate; + } + + mutex_lock(&inst->timestamps.lock); + list_for_each_entry(node, &inst->timestamps.list, list) { + count++; + max_framerate = max_framerate < node->framerate ? + node->framerate : max_framerate; + } + s_vpr_l(inst->sid, "%s: fps %u, list size %d\n", + __func__, max_framerate, count); + mutex_unlock(&inst->timestamps.lock); + return max_framerate; +} + +int msm_comm_fetch_framerate(struct msm_vidc_inst *inst, + u64 timestamp_us, u32 *framerate) +{ + struct msm_vidc_timestamps *node; + bool found_fps = false; + u32 count = 0; + int rc = 0; + + if (!inst || !framerate) { + d_vpr_e("%s: invalid parameters\n", __func__); + return -EINVAL; + } + + mutex_lock(&inst->timestamps.lock); + list_for_each_entry(node, &inst->timestamps.list, list) { + count++; + if (timestamp_us == node->timestamp_us) { + *framerate = node->framerate; + found_fps = true; + break; + } + } + mutex_unlock(&inst->timestamps.lock); + + if (!found_fps) { + if (!inst->flush_timestamps) + s_vpr_e(inst->sid, "%s:ts %lld not found,listsize %d\n", + __func__, timestamp_us, count); + rc = -EINVAL; + } + return rc; +} diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 79a83cd42b3b..49e666b98ca6 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -332,4 +332,11 @@ void msm_comm_clear_window_data(struct msm_vidc_inst *inst); void msm_comm_release_window_data(struct msm_vidc_inst *inst); int msm_comm_set_cvp_skip_ratio(struct msm_vidc_inst *inst, uint32_t capture_rate, uint32_t cvp_rate); +int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us); +int msm_comm_fetch_framerate(struct msm_vidc_inst *inst, u64 timestamp_us, + u32 *framerate); +void msm_comm_release_timestamps(struct msm_vidc_inst *inst); +u32 msm_comm_get_max_framerate(struct msm_vidc_inst *inst); +u32 msm_comm_calc_framerate(struct msm_vidc_inst *inst, u64 timestamp_us, + u64 prev_ts); #endif diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index a3b8400cb1f9..cd2e27e156b7 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -232,6 +232,12 @@ struct msm_vidc_codec { enum hal_video_codec codec; }; +struct msm_vidc_timestamps { + struct list_head list; + u64 timestamp_us; + u32 framerate; +}; + enum efuse_purpose { SKU_VERSION = 0, }; @@ -504,6 +510,7 @@ struct msm_vidc_inst { struct msm_vidc_list fbd_data; struct msm_vidc_list window_data; struct msm_vidc_list client_data; + struct msm_vidc_list timestamps; struct buffer_requirements buff_req; struct vidc_frame_data superframe_data[VIDC_SUPERFRAME_MAX]; struct v4l2_ctrl_handler ctrl_handler; @@ -528,6 +535,7 @@ struct msm_vidc_inst { struct kref kref; bool in_flush; bool out_flush; + bool flush_timestamps; u32 pic_struct; u32 colour_space; u32 profile; From feb7dabc19e4a6ace41cf8b21e6ec889b0673854 Mon Sep 17 00:00:00 2001 From: Akshay Chandrashekhar Kalghatgi Date: Mon, 2 Mar 2020 13:16:25 -0800 Subject: [PATCH 237/452] msm: vidc: Get FW name from DT Get Video FW ELF image name from driver's DT entry. Change-Id: I95320f2b1bdf9ba9e8bb6264babc33c162da60e0 Signed-off-by: Akshay Chandrashekhar Kalghatgi --- msm/vidc/msm_vidc_res_parse.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 27fe80f5b9d3..95cf123ac8b1 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -117,6 +117,14 @@ void msm_vidc_free_platform_resources( msm_vidc_free_buffer_usage_table(res); } +static int msm_vidc_load_fw_name(struct msm_vidc_platform_resources *res) +{ + struct platform_device *pdev = res->pdev; + + return of_property_read_string_index(pdev->dev.of_node, + "vidc,firmware-name", 0, &res->fw_name); +} + static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res) { struct reg_set *reg_set; @@ -734,10 +742,6 @@ int read_platform_resources_from_drv_data( res->sku_version = platform_data->sku_version; - res->fw_name = "venus"; - - d_vpr_h("Firmware filename: %s\n", res->fw_name); - res->max_load = find_key_value(platform_data, "qcom,max-hw-load"); @@ -836,6 +840,11 @@ int read_platform_resources_from_dt( kres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); res->irq = kres ? kres->start : -1; + rc = msm_vidc_load_fw_name(res); + if (rc) + d_vpr_e("%s: failed to load fw name, rc %d, using default fw\n", + __func__, rc); + rc = msm_vidc_load_subcache_info(res); if (rc) d_vpr_e("Failed to load subcache info: %d\n", rc); From 5dbb3c9263f54c25289616f595e4974c3480dee7 Mon Sep 17 00:00:00 2001 From: Akshay Chandrashekhar Kalghatgi Date: Tue, 15 Oct 2019 09:17:09 -0700 Subject: [PATCH 238/452] msm: vidc: Add support to prefetch & drain memory Secure memory allocations take a long time. Use memory prefetch and drain operations to reduce allocation times. Change-Id: Iaa86a97d7a8b1d6eb1683d273ddb27ffe8d891ae Signed-off-by: Akshay Chandrashekhar Kalghatgi --- msm/vidc/msm_smem.c | 71 ++++++++++++++++++++++++++- msm/vidc/msm_vdec.c | 1 + msm/vidc/msm_vidc.c | 3 ++ msm/vidc/msm_vidc.h | 14 ++++++ msm/vidc/msm_vidc_common.c | 91 +++++++++++++++++++++++++++++++++++ msm/vidc/msm_vidc_common.h | 2 + msm/vidc/msm_vidc_internal.h | 6 +++ msm/vidc/msm_vidc_platform.c | 27 +++++++++++ msm/vidc/msm_vidc_res_parse.c | 9 ++++ msm/vidc/msm_vidc_resources.h | 4 ++ 10 files changed, 227 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_smem.c b/msm/vidc/msm_smem.c index 40871b70ff77..4d326ab0bea5 100644 --- a/msm/vidc/msm_smem.c +++ b/msm/vidc/msm_smem.c @@ -9,7 +9,6 @@ #include "msm_vidc_debug.h" #include "msm_vidc_resources.h" - static int msm_dma_get_device_address(struct dma_buf *dbuf, unsigned long align, dma_addr_t *iova, unsigned long *buffer_size, unsigned long flags, enum hal_buffer buffer_type, @@ -599,3 +598,73 @@ struct context_bank_info *msm_smem_get_context_bank(u32 session_type, return match; } +int msm_smem_memory_prefetch(struct msm_vidc_inst *inst) +{ + int i, rc = 0; + struct memory_regions *vidc_regions = NULL; + struct ion_prefetch_region ion_region[MEMORY_REGIONS_MAX]; + + if (!inst) { + d_vpr_e("%s: invalid parameters\n", __func__); + return -EINVAL; + } + + vidc_regions = &inst->regions; + if (vidc_regions->num_regions > MEMORY_REGIONS_MAX) { + s_vpr_e(inst->sid, "%s: invalid num_regions %d, max %d\n", + __func__, vidc_regions->num_regions, + MEMORY_REGIONS_MAX); + return -EINVAL; + } + + memset(ion_region, 0, sizeof(ion_region)); + for (i = 0; i < vidc_regions->num_regions; i++) { + ion_region[i].size = vidc_regions->region[i].size; + ion_region[i].vmid = vidc_regions->region[i].vmid; + } + + rc = msm_ion_heap_prefetch(ION_SECURE_HEAP_ID, ion_region, + vidc_regions->num_regions); + if (rc) + s_vpr_e(inst->sid, "%s: prefetch failed, ret: %d\n", + __func__, rc); + else + s_vpr_l(inst->sid, "%s: prefetch succeeded\n", __func__); + + return rc; +} + +int msm_smem_memory_drain(struct msm_vidc_inst *inst) +{ + int i, rc = 0; + struct memory_regions *vidc_regions = NULL; + struct ion_prefetch_region ion_region[MEMORY_REGIONS_MAX]; + + if (!inst) { + d_vpr_e("%s: invalid parameters\n", __func__); + return -EINVAL; + } + + vidc_regions = &inst->regions; + if (vidc_regions->num_regions > MEMORY_REGIONS_MAX) { + s_vpr_e(inst->sid, "%s: invalid num_regions %d, max %d\n", + __func__, vidc_regions->num_regions, + MEMORY_REGIONS_MAX); + return -EINVAL; + } + + memset(ion_region, 0, sizeof(ion_region)); + for (i = 0; i < vidc_regions->num_regions; i++) { + ion_region[i].size = vidc_regions->region[i].size; + ion_region[i].vmid = vidc_regions->region[i].vmid; + } + + rc = msm_ion_heap_drain(ION_SECURE_HEAP_ID, ion_region, + vidc_regions->num_regions); + if (rc) + s_vpr_e(inst->sid, "%s: drain failed, ret: %d\n", __func__, rc); + else + s_vpr_l(inst->sid, "%s: drain succeeded\n", __func__); + + return rc; +} diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index c535e3fe1347..37071bf5b1a8 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -883,6 +883,7 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) __func__); return -ENOTSUPP; } + msm_comm_memory_prefetch(inst); break; case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA: if (ctrl->val == EXTRADATA_NONE) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 0dc329929e9d..60fadec7452d 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1415,6 +1415,8 @@ static const struct v4l2_ctrl_ops msm_vidc_ctrl_ops = { static struct msm_vidc_inst_smem_ops msm_vidc_smem_ops = { .smem_map_dma_buf = msm_smem_map_dma_buf, .smem_unmap_dma_buf = msm_smem_unmap_dma_buf, + .smem_prefetch = msm_smem_memory_prefetch, + .smem_drain = msm_smem_memory_drain, }; void *msm_vidc_open(int core_id, int session_type) @@ -1756,6 +1758,7 @@ int msm_vidc_close(void *instance) } msm_comm_session_clean(inst); + msm_comm_memory_drain(inst); kref_put(&inst->kref, close_helper); return 0; diff --git a/msm/vidc/msm_vidc.h b/msm/vidc/msm_vidc.h index d4d50a74f8fa..92bd06426747 100644 --- a/msm/vidc/msm_vidc.h +++ b/msm/vidc/msm_vidc.h @@ -13,6 +13,7 @@ #define HAL_BUFFER_MAX 0xe #define CVP_FRAME_RATE_MAX (60) +#define MEMORY_REGIONS_MAX 30 enum smem_type { SMEM_DMA = 1, @@ -75,6 +76,19 @@ enum smem_cache_ops { SMEM_CACHE_CLEAN_INVALIDATE, }; +struct memory_regions { + u32 num_regions; + struct { + u64 size; + u32 vmid; + } region[MEMORY_REGIONS_MAX]; +}; + +enum memory_ops { + MEMORY_PREFETCH = 1, + MEMORY_DRAIN, +}; + enum core_id { MSM_VIDC_CORE_VENUS = 0, MSM_VIDC_CORE_Q6, diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index e2be7fa36a57..7cb8a1ef7792 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7351,3 +7351,94 @@ int msm_comm_fetch_framerate(struct msm_vidc_inst *inst, } return rc; } + +static int msm_comm_memory_regions_prepare(struct msm_vidc_inst *inst) +{ + u32 i = 0; + struct msm_vidc_platform_resources *res; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid parameters\n", __func__); + return -EINVAL; + } + res = &inst->core->resources; + + inst->regions.num_regions = res->prefetch_non_pix_buf_count + + res->prefetch_pix_buf_count; + if (inst->regions.num_regions > MEMORY_REGIONS_MAX) { + s_vpr_e(inst->sid, "%s: invalid num_regions: %d, max: %d\n", + __func__, inst->regions.num_regions, + MEMORY_REGIONS_MAX); + return -EINVAL; + } + + s_vpr_h(inst->sid, + "%s: preparing %d nonpixel memory regions of %ld bytes each and %d pixel memory regions of %ld bytes each\n", + __func__, res->prefetch_non_pix_buf_count, + res->prefetch_non_pix_buf_size, res->prefetch_pix_buf_count, + res->prefetch_pix_buf_size); + + for (i = 0; i < res->prefetch_non_pix_buf_count; i++) { + inst->regions.region[i].size = res->prefetch_non_pix_buf_size; + inst->regions.region[i].vmid = ION_FLAG_CP_NON_PIXEL; + } + + for (i = res->prefetch_non_pix_buf_count; + i < inst->regions.num_regions; i++) { + inst->regions.region[i].size = res->prefetch_pix_buf_size; + inst->regions.region[i].vmid = ION_FLAG_CP_PIXEL; + } + + return 0; +} + +int msm_comm_memory_prefetch(struct msm_vidc_inst *inst) +{ + int rc = 0; + + if (!inst || !inst->smem_ops) { + d_vpr_e("%s: invalid parameters\n", __func__); + return -EINVAL; + } + + if (inst->memory_ops & MEMORY_PREFETCH) { + s_vpr_h(inst->sid, "%s: prefetch done already\n", __func__); + return 0; + } + + rc = msm_comm_memory_regions_prepare(inst); + if (rc) + return rc; + + if (inst->regions.num_regions == 0) + return 0; + + rc = inst->smem_ops->smem_prefetch(inst); + if (rc) + return rc; + + inst->memory_ops |= MEMORY_PREFETCH; + + return rc; +} + +int msm_comm_memory_drain(struct msm_vidc_inst *inst) +{ + int rc = 0; + + if (!inst || !inst->smem_ops) { + d_vpr_e("%s: invalid parameters\n", __func__); + return -EINVAL; + } + + if (!(inst->memory_ops & MEMORY_PREFETCH)) + return 0; + + rc = inst->smem_ops->smem_drain(inst); + if (rc) + return rc; + + inst->memory_ops &= ~MEMORY_PREFETCH; + + return rc; +} diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 49e666b98ca6..234d0c58be95 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -339,4 +339,6 @@ void msm_comm_release_timestamps(struct msm_vidc_inst *inst); u32 msm_comm_get_max_framerate(struct msm_vidc_inst *inst); u32 msm_comm_calc_framerate(struct msm_vidc_inst *inst, u64 timestamp_us, u64 prev_ts); +int msm_comm_memory_prefetch(struct msm_vidc_inst *inst); +int msm_comm_memory_drain(struct msm_vidc_inst *inst); #endif diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index cd2e27e156b7..1ecea42a6521 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -485,6 +485,8 @@ struct msm_vidc_inst_smem_ops { struct msm_smem *smem); int (*smem_unmap_dma_buf)(struct msm_vidc_inst *inst, struct msm_smem *smem); + int (*smem_prefetch)(struct msm_vidc_inst *inst); + int (*smem_drain)(struct msm_vidc_inst *inst); }; struct msm_vidc_inst { @@ -552,6 +554,8 @@ struct msm_vidc_inst { struct batch_mode batch; struct delayed_work batch_work; struct msm_vidc_inst_smem_ops *smem_ops; + enum memory_ops memory_ops; + struct memory_regions regions; int (*buffer_size_calculators)(struct msm_vidc_inst *inst); bool all_intra; bool is_perf_eligible_session; @@ -612,6 +616,8 @@ void msm_smem_put_dma_buf(void *dma_buf, u32 sid); int msm_smem_cache_operations(struct dma_buf *dbuf, enum smem_cache_ops cache_op, unsigned long offset, unsigned long size, u32 sid); +int msm_smem_memory_prefetch(struct msm_vidc_inst *inst); +int msm_smem_memory_drain(struct msm_vidc_inst *inst); void msm_vidc_fw_unload_handler(struct work_struct *work); void msm_vidc_ssr_handler(struct work_struct *work); /* diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 244be41ac700..fea44112ab6f 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -431,6 +431,33 @@ static struct msm_vidc_common_data lahaina_common_data[] = { .key = "qcom,avsync-window-size", .value = 40, }, + { + .key = "qcom,prefetch_non_pix_buf_count", + .value = 1, + }, + { + .key = "qcom,prefetch_non_pix_buf_size", + /* + * Internal buffer size is calculated for secure decode session + * of resolution 4k (4096x2160) + * Internal buf size = calculate_scratch_size() + + * calculate_scratch1_size() + calculate_persist1_size() + * Take maximum between VP9 10bit, HEVC 10bit, AVC, MPEG2 secure + * decoder sessions + */ + .value = 209715200, + }, + { + .key = "qcom,prefetch_pix_buf_count", + .value = 18, + }, + { + .key = "qcom,prefetch_pix_buf_size", + /* + * Calculated by VENUS_BUFFER_SIZE for 4096x2160 UBWC + */ + .value = 13434880, + }, }; static struct msm_vidc_common_data bengal_common_data_v0[] = { diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 27fe80f5b9d3..3ced21df2fb5 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -771,6 +771,15 @@ int read_platform_resources_from_drv_data( res->max_secure_inst_count = find_key_value(platform_data, "qcom,max-secure-instances"); + res->prefetch_pix_buf_count = find_key_value(platform_data, + "qcom,prefetch_pix_buf_count"); + res->prefetch_pix_buf_size = find_key_value(platform_data, + "qcom,prefetch_pix_buf_size"); + res->prefetch_non_pix_buf_count = find_key_value(platform_data, + "qcom,prefetch_non_pix_buf_count"); + res->prefetch_non_pix_buf_size = find_key_value(platform_data, + "qcom,prefetch_non_pix_buf_size"); + res->slave_side_cp = find_key_value(platform_data, "qcom,slave-side-cp"); res->thermal_mitigable = find_key_value(platform_data, diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index aa2fb29f16ce..9d296e33d63d 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -168,6 +168,10 @@ struct msm_vidc_platform_resources { uint32_t pm_qos_latency_us; uint32_t max_inst_count; uint32_t max_secure_inst_count; + uint32_t prefetch_pix_buf_count; + uint32_t prefetch_pix_buf_size; + uint32_t prefetch_non_pix_buf_count; + uint32_t prefetch_non_pix_buf_size; int msm_vidc_hw_rsp_timeout; int msm_vidc_firmware_unload_delay; uint32_t msm_vidc_pwr_collapse_delay; From 20ebbed266caa8842a686b1f6ca3b1ca814251ef Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Wed, 11 Mar 2020 17:38:20 -0700 Subject: [PATCH 239/452] msm: vidc: Perform cache operations on all planes Perform cache operations on all planes including buffer extradata planes, since userspace may set cache flag on all planes. Change-Id: I9cc6060ec7fb2626b4885c7df7592abae99fb955 Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_common.c | 46 ++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 7cb8a1ef7792..aa0c47d323cd 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -6307,40 +6307,33 @@ int msm_comm_qbuf_cache_operations(struct msm_vidc_inst *inst, unsigned long offset, size; enum smem_cache_ops cache_op; - skip = true; + offset = vb->planes[i].data_offset; + size = vb->planes[i].length - offset; + cache_op = SMEM_CACHE_INVALIDATE; + skip = false; + if (inst->session_type == MSM_VIDC_DECODER) { if (vb->type == INPUT_MPLANE) { if (!i) { /* bitstream */ - skip = false; - offset = vb->planes[i].data_offset; size = vb->planes[i].bytesused; cache_op = SMEM_CACHE_CLEAN_INVALIDATE; } } else if (vb->type == OUTPUT_MPLANE) { if (!i) { /* yuv */ - skip = false; - offset = 0; - size = vb->planes[i].length; - cache_op = SMEM_CACHE_INVALIDATE; + /* all values are correct */ } } } else if (inst->session_type == MSM_VIDC_ENCODER) { if (vb->type == INPUT_MPLANE) { if (!i) { /* yuv */ - skip = false; - offset = vb->planes[i].data_offset; size = vb->planes[i].bytesused; cache_op = SMEM_CACHE_CLEAN_INVALIDATE; + } else { /* extradata */ + cache_op = SMEM_CACHE_CLEAN_INVALIDATE; } } else if (vb->type == OUTPUT_MPLANE) { - if (!i) { /* bitstream */ - skip = false; - offset = 0; - size = vb->planes[i].length; - if (inst->max_filled_len) - size = inst->max_filled_len; - cache_op = SMEM_CACHE_INVALIDATE; - } + if (!i && inst->max_filled_len) + size = inst->max_filled_len; } } @@ -6375,26 +6368,26 @@ int msm_comm_dqbuf_cache_operations(struct msm_vidc_inst *inst, unsigned long offset, size; enum smem_cache_ops cache_op; - skip = true; + offset = vb->planes[i].data_offset; + size = vb->planes[i].length - offset; + cache_op = SMEM_CACHE_INVALIDATE; + skip = false; + if (inst->session_type == MSM_VIDC_DECODER) { if (vb->type == INPUT_MPLANE) { - /* bitstream and extradata */ - /* we do not need cache operations */ + if (!i) /* bitstream */ + skip = true; } else if (vb->type == OUTPUT_MPLANE) { if (!i) { /* yuv */ - skip = false; - offset = vb->planes[i].data_offset; - size = vb->planes[i].bytesused; - cache_op = SMEM_CACHE_INVALIDATE; + /* All values are correct */ } } } else if (inst->session_type == MSM_VIDC_ENCODER) { if (vb->type == INPUT_MPLANE) { /* yuv and extradata */ - /* we do not need cache operations */ + skip = true; } else if (vb->type == OUTPUT_MPLANE) { if (!i) { /* bitstream */ - skip = false; /* * Include vp8e header bytes as well * by making offset equal to zero @@ -6402,7 +6395,6 @@ int msm_comm_dqbuf_cache_operations(struct msm_vidc_inst *inst, offset = 0; size = vb->planes[i].bytesused + vb->planes[i].data_offset; - cache_op = SMEM_CACHE_INVALIDATE; } } } From 972cddc45f7a71d85b11ce6d76b13c780958b3e4 Mon Sep 17 00:00:00 2001 From: Akshay Chandrashekhar Kalghatgi Date: Thu, 12 Mar 2020 17:20:52 -0700 Subject: [PATCH 240/452] msm: vidc: add check for prefetch memory sufficiency Check if the non-pix and pix prefetched memory is sufficient Change-Id: I71561959a3ed1e9acdb654650144f35656230345 Signed-off-by: Akshay Chandrashekhar Kalghatgi --- msm/vidc/msm_vidc.c | 2 ++ msm/vidc/msm_vidc_common.c | 55 ++++++++++++++++++++++++++++++++++++++ msm/vidc/msm_vidc_common.h | 1 + 3 files changed, 58 insertions(+) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 60fadec7452d..79fcbbfea408 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -885,6 +885,8 @@ static inline int start_streaming(struct msm_vidc_inst *inst) goto fail_start; } + msm_comm_check_prefetch_sufficient(inst); + rc = msm_comm_set_scratch_buffers(inst); if (rc) { s_vpr_e(inst->sid, "Failed to set scratch buffers: %d\n", rc); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index aa0c47d323cd..9ce78e0de404 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7434,3 +7434,58 @@ int msm_comm_memory_drain(struct msm_vidc_inst *inst) return rc; } + +int msm_comm_check_prefetch_sufficient(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct msm_vidc_platform_resources *res; + struct v4l2_plane_pix_format *fmt; + u32 i, internal_buf_sz = 0; + u32 prefetch_npix_sz = 0; + u32 prefetch_pix_sz = 0; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid parameters\n", __func__); + return -EINVAL; + } + res = &inst->core->resources; + fmt = inst->fmts[OUTPUT_PORT].v4l2_fmt.fmt.pix_mp.plane_fmt; + + if (!is_secure_session(inst) || !is_decode_session(inst)) + return rc; + + if (!(inst->memory_ops & MEMORY_PREFETCH)) + return -ENOMEM; + + prefetch_npix_sz = res->prefetch_non_pix_buf_count * + res->prefetch_non_pix_buf_size; + prefetch_pix_sz = res->prefetch_pix_buf_count * + res->prefetch_pix_buf_size; + + for (i = 0; i < HAL_BUFFER_MAX; i++) { + struct hal_buffer_requirements *req; + + req = &inst->buff_req.buffer[i]; + if (req->buffer_type == HAL_BUFFER_INTERNAL_SCRATCH || + req->buffer_type == HAL_BUFFER_INTERNAL_SCRATCH_1 || + req->buffer_type == HAL_BUFFER_INTERNAL_SCRATCH_2 || + req->buffer_type == HAL_BUFFER_INTERNAL_PERSIST || + req->buffer_type == HAL_BUFFER_INTERNAL_PERSIST_1) + internal_buf_sz += req->buffer_size; + } + + if (prefetch_npix_sz < internal_buf_sz) { + s_vpr_e(inst->sid, + "insufficient non-pix region prefetched %u, required %u", + internal_buf_sz, prefetch_npix_sz); + rc = -ENOMEM; + } + if (prefetch_pix_sz < fmt->sizeimage) { + s_vpr_e(inst->sid, + "insufficient pix region prefetched %u, required %u", + fmt->sizeimage, prefetch_pix_sz); + rc = -ENOMEM; + } + + return rc; +} diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 234d0c58be95..3c5c84093ed2 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -341,4 +341,5 @@ u32 msm_comm_calc_framerate(struct msm_vidc_inst *inst, u64 timestamp_us, u64 prev_ts); int msm_comm_memory_prefetch(struct msm_vidc_inst *inst); int msm_comm_memory_drain(struct msm_vidc_inst *inst); +int msm_comm_check_prefetch_sufficient(struct msm_vidc_inst *inst); #endif From 69f3ae926cb72982afc42909facdef42e8bf94bf Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Fri, 20 Mar 2020 20:25:34 -0700 Subject: [PATCH 241/452] msm: vidc: Use correct parameter types in callbacks Use correct types in callback functions to avoid kernel control flow integrity (kCFI) warnings. Change-Id: Ia84a3d10ebb83407b4ac2c6140daec35e0698bd5 Signed-off-by: Mihir Ganu --- msm/vidc/vidc_hfi_api.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 49ceaf871d82..8818ff3ada94 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -692,7 +692,8 @@ struct hfi_device { typedef void (*hfi_cmd_response_callback) (enum hal_command_response cmd, void *data); -typedef void (*msm_vidc_callback) (u32 response, void *callback); +typedef void (*msm_vidc_callback) (enum hal_command_response response, + void *callback); struct hfi_device *vidc_hfi_initialize(enum msm_vidc_hfi_type hfi_type, u32 device_id, struct msm_vidc_platform_resources *res, From 24de1903d9116466f078153d7d02e55f68ddda9c Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Fri, 20 Mar 2020 11:42:23 -0700 Subject: [PATCH 242/452] msm: vidc: mark few standard controls as custom controls Video driver extending few standard controls value and hence mark those controls as custom controls. Change-Id: I373ed21482bb577c4fc5c28fd011098963608f53 Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_vdec.c | 50 ++++++++++++++++++++++++++++++++-- msm/vidc/msm_venc.c | 56 ++++++++++++++++++++++++++++++++++---- msm/vidc/msm_vidc_common.c | 21 +++++++++++++- 3 files changed, 119 insertions(+), 8 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 37071bf5b1a8..5e2840d3999a 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -19,6 +19,52 @@ #define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8020010 #define MAX_VP9D_INST_COUNT 6 +static const char *const mpeg_video_h264_profile[] = { + "Baseline", + "Constrained Baseline", + "Main", + "Extended", + "High", + "High 10", + "High 422", + "High 444 Predictive", + "High 10 Intra", + "High 422 Intra", + "High 444 Intra", + "CAVLC 444 Intra", + "Scalable Baseline", + "Scalable High", + "Scalable High Intra", + "Stereo High", + "Multiview High", + "Constrained High", + NULL, +}; + +static const char *const mpeg_video_h264_level[] = { + "1", + "1b", + "1.1", + "1.2", + "1.3", + "2", + "2.1", + "2.2", + "3", + "3.1", + "3.2", + "4", + "4.1", + "4.2", + "5", + "5.1", + "5.2", + "6.0", + "6.1", + "6.2", + NULL, +}; + static const char *const vp8_profile_level[] = { "Unused", "0.0", @@ -134,7 +180,7 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) | (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH) ), - .qmenu = NULL, + .qmenu = mpeg_video_h264_profile, }, { .id = V4L2_CID_MPEG_VIDEO_H264_LEVEL, @@ -165,7 +211,7 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { (1 << V4L2_MPEG_VIDEO_H264_LEVEL_6_1) | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_6_2) ), - .qmenu = NULL, + .qmenu = mpeg_video_h264_level, }, { .id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 536fd92ee82e..0720144d9cac 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -46,15 +46,61 @@ #define MIN_NUM_ENC_CAPTURE_BUFFERS 5 static const char *const mpeg_video_rate_control[] = { - "VBR CFR", - "CBR CFR", - "MBR CFR", + "VBR", + "CBR", "CBR VFR", + "MBR", "MBR VFR", "CQ", NULL }; +static const char *const mpeg_video_h264_profile[] = { + "Baseline", + "Constrained Baseline", + "Main", + "Extended", + "High", + "High 10", + "High 422", + "High 444 Predictive", + "High 10 Intra", + "High 422 Intra", + "High 444 Intra", + "CAVLC 444 Intra", + "Scalable Baseline", + "Scalable High", + "Scalable High Intra", + "Stereo High", + "Multiview High", + "Constrained High", + NULL, +}; + +static const char *const mpeg_video_h264_level[] = { + "1", + "1b", + "1.1", + "1.2", + "1.3", + "2", + "2.1", + "2.2", + "3", + "3.1", + "3.2", + "4", + "4.1", + "4.2", + "5", + "5.1", + "5.2", + "6.0", + "6.1", + "6.2", + NULL, +}; + static const char *const vp8_profile_level[] = { "Unused", "0.0", @@ -275,7 +321,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) | (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH) ), - .qmenu = NULL, + .qmenu = mpeg_video_h264_profile, }, { .id = V4L2_CID_MPEG_VIDEO_H264_LEVEL, @@ -306,7 +352,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { (1 << V4L2_MPEG_VIDEO_H264_LEVEL_6_1) | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_6_2) ), - .qmenu = NULL, + .qmenu = mpeg_video_h264_level, }, { .id = V4L2_CID_MPEG_VIDEO_VP8_PROFILE, diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index aa0c47d323cd..e805808c611a 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -538,6 +538,25 @@ int msm_comm_get_v4l2_level(int fourcc, int level, u32 sid) } } +static bool is_priv_ctrl(u32 id) +{ + if (IS_PRIV_CTRL(id)) + return true; + + /* + * Treat below standard controls as private because + * we have added custom values to the controls + */ + switch (id) { + case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: + case V4L2_CID_MPEG_VIDEO_H264_PROFILE: + case V4L2_CID_MPEG_VIDEO_H264_LEVEL: + return true; + } + + return false; +} + int msm_comm_ctrl_init(struct msm_vidc_inst *inst, struct msm_vidc_ctrl *drv_ctrls, u32 num_ctrls, const struct v4l2_ctrl_ops *ctrl_ops) @@ -569,7 +588,7 @@ int msm_comm_ctrl_init(struct msm_vidc_inst *inst, for (; idx < (int) num_ctrls; idx++) { struct v4l2_ctrl *ctrl = NULL; - if (IS_PRIV_CTRL(drv_ctrls[idx].id)) { + if (is_priv_ctrl(drv_ctrls[idx].id)) { /*add private control*/ ctrl_cfg.def = drv_ctrls[idx].default_value; ctrl_cfg.flags = 0; From 8594905e54adc75a4f2387203ecec83e839e1781 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Tue, 24 Mar 2020 12:16:46 -0700 Subject: [PATCH 243/452] msm: vidc: Set encoder persist buffer to FW Set the allocated encoder persist buffer to firmware. Change-Id: I83fdf2dace76848e4a5ad4d8f3a85c9605b56cd0 Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_buffer_calculations.c | 1 + 1 file changed, 1 insertion(+) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index c3cbcfb5045c..a95227cf7be2 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -563,6 +563,7 @@ int msm_vidc_get_encoder_internal_buffer_sizes(struct msm_vidc_inst *inst) HAL_BUFFER_INTERNAL_PERSIST) { curr_req->buffer_size = enc_calculators->calculate_persist_size(); + valid_buffer_type = true; } if (valid_buffer_type) { From 0701e2bcefbeb43d1f8c60199bce2906bc530b4d Mon Sep 17 00:00:00 2001 From: Amit Shekhar Date: Wed, 25 Mar 2020 11:23:36 -0700 Subject: [PATCH 244/452] msm: vidc: Fix bitrate setting for CQ rc-mode sessions Currently, both bitrate and frame-quality can be set for a CQ rc-mode session. Adding additional check in driver to set only one of these. Change-Id: I1ea7b08cf8c7fe90e35aa57f570703e8cdf854e9 CRs-Fixed: 2615700 Signed-off-by: Amit Shekhar --- msm/vidc/msm_venc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 0720144d9cac..e5e2d9ff5b5d 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2753,6 +2753,9 @@ int msm_venc_set_bitrate(struct msm_vidc_inst *inst) } hdev = inst->core->device; + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) + return 0; + if (inst->layer_bitrate) { s_vpr_h(inst->sid, "%s: Layer bitrate is enabled\n", __func__); return 0; From 580131ac8b3d7993bafacb13d43ea8e5deb20edb Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 24 Mar 2020 13:53:31 -0700 Subject: [PATCH 245/452] msm: vidc: Update internal buffer size calculations Internal buffer size formulae updated to handle non-backward compatible changes in the Firmware. Change-Id: I324da7b698f216bd1bc1c3349cae51cdc4ec631a Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc_buffer_calculations.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index a95227cf7be2..0e251c0b8721 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -78,7 +78,7 @@ #define MAX_TILE_COLUMNS 32 /* 8K/256 */ #define VPP_CMD_MAX_SIZE (1 << 20) -#define NUM_HW_PIC_BUF 10 +#define NUM_HW_PIC_BUF 32 #define BIN_BUFFER_THRESHOLD (1280 * 736) #define H264D_MAX_SLICE 1800 #define SIZE_H264D_BUFTAB_T 256 // sizeof(h264d_buftab_t) aligned to 256 @@ -139,7 +139,7 @@ #define LCU_MAX_SIZE_PELS 64 #define LCU_MIN_SIZE_PELS 16 -#define H265D_MAX_SLICE 600 +#define H265D_MAX_SLICE 1200 #define SIZE_H265D_HW_PIC_T SIZE_H264D_HW_PIC_T #define SIZE_H265D_BSE_CMD_PER_BUF (16 * sizeof(u32)) #define SIZE_H265D_VPP_CMD_PER_BUF 256 @@ -232,7 +232,7 @@ #define VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO_DEN 2 #define VP8_NUM_FRAME_INFO_BUF (5 + 1) -#define VP9_NUM_FRAME_INFO_BUF (8 + 2 + 1 + 8) +#define VP9_NUM_FRAME_INFO_BUF (32) #define VP8_NUM_PROBABILITY_TABLE_BUF (VP8_NUM_FRAME_INFO_BUF) #define VP9_NUM_PROBABILITY_TABLE_BUF (VP9_NUM_FRAME_INFO_BUF + 4) #define VP8_PROB_TABLE_SIZE 3840 @@ -373,6 +373,7 @@ int msm_vidc_get_decoder_internal_buffer_sizes(struct msm_vidc_inst *inst) struct msm_vidc_dec_buff_size_calculators *dec_calculators; u32 width, height, i, out_min_count, num_vpp_pipes; struct v4l2_format *f; + u32 vpp_delay = 2 + 1; if (!inst || !inst->core || !inst->core->platform_data) { d_vpr_e("%s: Instance is null!", __func__); @@ -426,6 +427,8 @@ int msm_vidc_get_decoder_internal_buffer_sizes(struct msm_vidc_inst *inst) fmt = &inst->fmts[OUTPUT_PORT]; out_min_count = fmt->count_min; + out_min_count = + max(vpp_delay, out_min_count); curr_req->buffer_size = dec_calculators->calculate_scratch1_size( inst, width, height, out_min_count, @@ -1117,6 +1120,7 @@ static inline u32 size_h264d_hw_bin_buffer(u32 width, u32 height) u32 size_yuv, size_bin_hdr, size_bin_res; u32 size = 0; u32 product; + u32 delay = 2; product = width * height; size_yuv = (product <= BIN_BUFFER_THRESHOLD) ? @@ -1125,6 +1129,8 @@ static inline u32 size_h264d_hw_bin_buffer(u32 width, u32 height) size_bin_hdr = size_yuv * H264_CABAC_HDR_RATIO_HD_TOT; size_bin_res = size_yuv * H264_CABAC_RES_RATIO_HD_TOT; + size_bin_hdr = size_bin_hdr * (((((u32)(delay)) & 31) / 10) + 2) / 2; + size_bin_res = size_bin_res * (((((u32)(delay)) & 31) / 10) + 2) / 2; size_bin_hdr = ALIGN(size_bin_hdr, VENUS_DMA_ALIGNMENT); size_bin_res = ALIGN(size_bin_res, VENUS_DMA_ALIGNMENT); size = size_bin_hdr + size_bin_res; @@ -1233,6 +1239,7 @@ static inline u32 size_h265d_hw_bin_buffer(u32 width, u32 height) u32 size = 0; u32 size_yuv, size_bin_hdr, size_bin_res; u32 product; + u32 delay = 2; product = width * height; size_yuv = (product <= BIN_BUFFER_THRESHOLD) ? @@ -1240,6 +1247,8 @@ static inline u32 size_h265d_hw_bin_buffer(u32 width, u32 height) ((product * 3) >> 1); size_bin_hdr = size_yuv * H265_CABAC_HDR_RATIO_HD_TOT; size_bin_res = size_yuv * H265_CABAC_RES_RATIO_HD_TOT; + size_bin_hdr = size_bin_hdr * (((((u32)(delay)) & 31) / 10) + 2) / 2; + size_bin_res = size_bin_res * (((((u32)(delay)) & 31) / 10) + 2) / 2; size_bin_hdr = ALIGN(size_bin_hdr, VENUS_DMA_ALIGNMENT); size_bin_res = ALIGN(size_bin_res, VENUS_DMA_ALIGNMENT); size = size_bin_hdr + size_bin_res; From 328a5418c59a9385aa27bc53b88633c54202aa28 Mon Sep 17 00:00:00 2001 From: Amit Shekhar Date: Wed, 26 Feb 2020 10:57:42 -0800 Subject: [PATCH 246/452] msm: vidc: Remove b-frame enablement decision logic B-frame enablement decision logic has been moved to HAL interface. Hence, removing from kernel space. Change-Id: I24943f7facf172f5b9f30fbc67692fd866d490cd CRs-Fixed: 2615700 Signed-off-by: Amit Shekhar --- include/uapi/vidc/media/msm_vidc_utils.h | 2 - msm/vidc/msm_venc.c | 117 ----------------------- msm/vidc/msm_vidc_internal.h | 1 - 3 files changed, 120 deletions(-) diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index 538d6508e9f9..8269a44a999f 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -231,8 +231,6 @@ enum v4l2_mpeg_vidc_video_hevc_max_hier_coding_layer { }; #define V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 121) -#define V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER \ - (V4L2_CID_MPEG_MSM_VIDC_BASE + 122) #define V4L2_CID_MPEG_VIDC_VENC_RC_TIMESTAMP_DISABLE \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 123) #define V4L2_CID_MPEG_VIDC_SUPERFRAME \ diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 0720144d9cac..f7bf34ac773a 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -962,15 +962,6 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { ), .qmenu = mpeg_video_stream_format, }, - { - .id = V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER, - .name = "Enable/Disable Native Recorder", - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, - .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, - .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, - .step = 1, - }, { .id = V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS, .name = "Enable/Disable bitrate savings", @@ -1218,7 +1209,6 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) sizeof(inst->fmts[INPUT_PORT].name)); strlcpy(inst->fmts[INPUT_PORT].description, fmt_desc->description, sizeof(inst->fmts[INPUT_PORT].description)); - inst->prop.bframe_changed = false; inst->prop.extradata_ctrls = EXTRADATA_NONE; inst->buffer_mode_set[INPUT_PORT] = HAL_BUFFER_MODE_DYNAMIC; inst->buffer_mode_set[OUTPUT_PORT] = HAL_BUFFER_MODE_STATIC; @@ -2006,7 +1996,6 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY: case V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM: case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: - case V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER: case V4L2_CID_MPEG_VIDC_VENC_RC_TIMESTAMP_DISABLE: case V4L2_CID_MPEG_VIDEO_VBV_DELAY: case V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS: @@ -2330,95 +2319,6 @@ int msm_venc_set_idr_period(struct msm_vidc_inst *inst) return rc; } -void msm_venc_decide_bframe(struct msm_vidc_inst *inst) -{ - u32 width; - u32 height; - u32 num_mbs_per_frame, num_mbs_per_sec; - struct v4l2_ctrl *ctrl; - struct v4l2_ctrl *bframe_ctrl; - struct msm_vidc_platform_resources *res; - struct v4l2_format *f; - - res = &inst->core->resources; - f = &inst->fmts[INPUT_PORT].v4l2_fmt; - width = f->fmt.pix_mp.width; - height = f->fmt.pix_mp.height; - bframe_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); - num_mbs_per_frame = NUM_MBS_PER_FRAME(width, height); - if (num_mbs_per_frame > res->max_bframe_mbs_per_frame) - goto disable_bframe; - - num_mbs_per_sec = num_mbs_per_frame * - (inst->clk_data.frame_rate >> 16); - if (num_mbs_per_sec > res->max_bframe_mbs_per_sec) - goto disable_bframe; - - ctrl = get_ctrl(inst, - V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); - if (ctrl->val > 1) - goto disable_bframe; - - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); - if (ctrl->val) - goto disable_bframe; - - if (inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) - goto disable_bframe; - - if (get_v4l2_codec(inst) == V4L2_PIX_FMT_H264) { - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_PROFILE); - if ((ctrl->val != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) && - (ctrl->val != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) - goto disable_bframe; - } else if (get_v4l2_codec(inst) != V4L2_PIX_FMT_HEVC) - goto disable_bframe; - - if (inst->clk_data.low_latency_mode) - goto disable_bframe; - - if (!bframe_ctrl->val) { - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER); - if (ctrl->val) { - /* - * Native recorder is enabled and bframe is not enabled - * Hence, forcefully enable bframe - */ - inst->prop.bframe_changed = true; - update_ctrl(bframe_ctrl, MAX_NUM_B_FRAMES, inst->sid); - s_vpr_h(inst->sid, "Bframe is forcefully enabled\n"); - } else { - /* - * Native recorder is not enabled - * B-Frame is not enabled by client - */ - goto disable_bframe; - } - } - - /* do not enable bframe if superframe is enabled */ - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); - if (ctrl->val) - goto disable_bframe; - - s_vpr_h(inst->sid, "Bframe can be enabled!\n"); - - return; -disable_bframe: - if (bframe_ctrl->val) { - /* - * Client wanted to enable bframe but, - * conditions to enable are not met - * Hence, forcefully disable bframe - */ - inst->prop.bframe_changed = true; - update_ctrl(bframe_ctrl, 0, inst->sid); - s_vpr_h(inst->sid, "Bframe is forcefully disabled!\n"); - } else { - s_vpr_h(inst->sid, "Bframe is disabled\n"); - } -} - int msm_venc_set_adaptive_bframes(struct msm_vidc_inst *inst) { int rc = 0; @@ -2445,26 +2345,10 @@ int msm_venc_set_adaptive_bframes(struct msm_vidc_inst *inst) void msm_venc_adjust_gop_size(struct msm_vidc_inst *inst) { struct v4l2_ctrl *hier_ctrl; - struct v4l2_ctrl *bframe_ctrl; struct v4l2_ctrl *gop_size_ctrl; s32 val; gop_size_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_GOP_SIZE); - if (inst->prop.bframe_changed) { - /* - * BFrame size was explicitly change - * Hence, adjust GOP size accordingly - */ - bframe_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); - if (!bframe_ctrl->val) - /* Forcefully disabled */ - val = gop_size_ctrl->val * (1 + MAX_NUM_B_FRAMES); - else - /* Forcefully enabled */ - val = gop_size_ctrl->val / (1 + MAX_NUM_B_FRAMES); - - update_ctrl(gop_size_ctrl, val, inst->sid); - } /* * Layer encoding needs GOP size to be multiple of subgop size @@ -4674,7 +4558,6 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) rc = msm_venc_set_base_layer_priority_id(inst); if (rc) goto exit; - msm_venc_decide_bframe(inst); rc = msm_venc_set_idr_period(inst); if (rc) goto exit; diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 1ecea42a6521..0665157c59c3 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -339,7 +339,6 @@ struct msm_video_device { struct session_prop { u32 fps; u32 bitrate; - bool bframe_changed; u32 extradata_ctrls; }; From 86cdac94b77b9188884c4f2277ae439d3d506b25 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Mon, 30 Mar 2020 15:38:58 -0700 Subject: [PATCH 247/452] msm: vidc: enable timestamp reorder Enable timestamp reordering by using the calculated timestamps maintained in a sorted order and associate with output buffers. This would resolve the issue if the parser sends incorect timestamps. Change-Id: I870fd8ed25e05b8e86c677e79182e9c7785656a8 Signed-off-by: Darshana Patil --- msm/vidc/msm_vidc.c | 10 +---- msm/vidc/msm_vidc_common.c | 85 ++++++++++++++++++++++++------------ msm/vidc/msm_vidc_common.h | 4 +- msm/vidc/msm_vidc_internal.h | 1 + 4 files changed, 63 insertions(+), 37 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 60fadec7452d..d05f29cf3b63 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -454,7 +454,6 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) int rc = 0; unsigned int i = 0; struct buf_queue *q = NULL; - u64 timestamp_us = 0; if (!inst || !b || !valid_v4l2_buffer(b, inst)) { d_vpr_e("%s: invalid params, %pK %pK\n", @@ -495,13 +494,8 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) return -EINVAL; } } - if (is_decode_session(inst) && b->type == OUTPUT_MPLANE) { - timestamp_us = (u64)((b->timestamp.tv_sec * 1000000ULL) + - b->timestamp.tv_usec); - b->m.planes[0].reserved[MSM_VIDC_FRAMERATE] = DEFAULT_FPS << 16; - msm_comm_fetch_framerate(inst, timestamp_us, - &b->m.planes[0].reserved[MSM_VIDC_FRAMERATE]); - } + if (is_decode_session(inst) && b->type == OUTPUT_MPLANE) + msm_comm_fetch_ts_framerate(inst, b); return rc; } diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index aa0c47d323cd..30ce2038098c 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7188,6 +7188,7 @@ void msm_comm_release_timestamps(struct msm_vidc_inst *inst) int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) { struct msm_vidc_timestamps *entry, *node, *prev = NULL; + struct msm_vidc_timestamps *duplicate; int count = 0; int rc = 0; bool inserted = false; @@ -7199,22 +7200,25 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) } mutex_lock(&inst->timestamps.lock); + duplicate = NULL; list_for_each_entry(node, &inst->timestamps.list, list) { count++; - /* Skip adding duplicate entries */ - if (node->timestamp_us == timestamp_us) { - s_vpr_e(inst->sid, "%s: skip ts duplicate entry %lld\n", - __func__, node->timestamp_us); - goto unlock; - } + if (node->timestamp_us == timestamp_us) + duplicate = node; } - /* Maintain a sliding window of size 32 */ + /* Maintain a sliding window of size 64 */ entry = NULL; - if (count >= TIMESTAMPS_WINDOW_SIZE) { + if (count >= VIDEO_MAX_FRAME) { entry = list_first_entry(&inst->timestamps.list, struct msm_vidc_timestamps, list); - list_del_init(&entry->list); + if (!entry->is_valid) { + list_del_init(&entry->list); + } else { + s_vpr_e(inst->sid, "%s: first entry still valid %d\n", + __func__, count); + entry = NULL; + } } if (!entry) { entry = kzalloc(sizeof(*entry), GFP_KERNEL); @@ -7225,8 +7229,18 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) goto unlock; } } + + if (duplicate) { + entry->timestamp_us = duplicate->timestamp_us; + entry->framerate = duplicate->framerate; + entry->is_valid = true; + /* add entry next to duplicate */ + list_add(&entry->list, &duplicate->list); + goto unlock; + } entry->timestamp_us = timestamp_us; entry->framerate = DEFAULT_FPS << 16; + entry->is_valid = true; /* add new entry into the list in sorted order */ prev = NULL; @@ -7247,7 +7261,6 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) prev = node; } - /* inserted will be false if list is empty */ if (!inserted) list_add_tail(&entry->list, &inst->timestamps.list); @@ -7311,36 +7324,54 @@ u32 msm_comm_get_max_framerate(struct msm_vidc_inst *inst) return max_framerate; } -int msm_comm_fetch_framerate(struct msm_vidc_inst *inst, - u64 timestamp_us, u32 *framerate) +int msm_comm_fetch_ts_framerate(struct msm_vidc_inst *inst, + struct v4l2_buffer *b) { struct msm_vidc_timestamps *node; - bool found_fps = false; - u32 count = 0; int rc = 0; + bool invalidate_extra = false; + u32 input_tag = 0, input_tag2 = 0; - if (!inst || !framerate) { + if (!inst || !b) { d_vpr_e("%s: invalid parameters\n", __func__); return -EINVAL; } + input_tag = b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_1]; + input_tag2 = b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_2]; + + /* nothing to do for flushed buffers */ + if (!input_tag) + return 0; + + /* set default framerate */ + b->m.planes[0].reserved[MSM_VIDC_FRAMERATE] = DEFAULT_FPS << 16; + + /* to handle interlace, 2 input buffers and 1 output buffer*/ + if (input_tag2 && input_tag2 != input_tag) + invalidate_extra = true; + mutex_lock(&inst->timestamps.lock); list_for_each_entry(node, &inst->timestamps.list, list) { - count++; - if (timestamp_us == node->timestamp_us) { - *framerate = node->framerate; - found_fps = true; - break; + if (!node->is_valid) + continue; + + if (invalidate_extra) { + node->is_valid = false; + invalidate_extra = false; + continue; } + + /* do not update is_valid flag for subframe buffer */ + if (!(b->flags & HAL_BUFFERFLAG_ENDOFSUBFRAME)) + node->is_valid = false; + + b->timestamp.tv_sec = node->timestamp_us / 1000000ull; + b->timestamp.tv_usec = node->timestamp_us % 1000000ull; + b->m.planes[0].reserved[MSM_VIDC_FRAMERATE] = node->framerate; + break; } mutex_unlock(&inst->timestamps.lock); - - if (!found_fps) { - if (!inst->flush_timestamps) - s_vpr_e(inst->sid, "%s:ts %lld not found,listsize %d\n", - __func__, timestamp_us, count); - rc = -EINVAL; - } return rc; } diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 234d0c58be95..22c9666caa16 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -332,9 +332,9 @@ void msm_comm_clear_window_data(struct msm_vidc_inst *inst); void msm_comm_release_window_data(struct msm_vidc_inst *inst); int msm_comm_set_cvp_skip_ratio(struct msm_vidc_inst *inst, uint32_t capture_rate, uint32_t cvp_rate); +int msm_comm_fetch_ts_framerate(struct msm_vidc_inst *inst, + struct v4l2_buffer *b); int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us); -int msm_comm_fetch_framerate(struct msm_vidc_inst *inst, u64 timestamp_us, - u32 *framerate); void msm_comm_release_timestamps(struct msm_vidc_inst *inst); u32 msm_comm_get_max_framerate(struct msm_vidc_inst *inst); u32 msm_comm_calc_framerate(struct msm_vidc_inst *inst, u64 timestamp_us, diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 1ecea42a6521..caba423c583f 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -236,6 +236,7 @@ struct msm_vidc_timestamps { struct list_head list; u64 timestamp_us; u32 framerate; + bool is_valid; }; enum efuse_purpose { From 4f163fad006d0446ed04e024c51e287b2863a4c6 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Wed, 1 Apr 2020 14:40:50 -0700 Subject: [PATCH 248/452] msm: vidc: Update fbd packet size check FBD packets may contain UBWC CR data information, for certain targets. Packet size checks should take this into account. Change-Id: I3ed5705fd6d5b78921aadb2f91c75a071a1f16b2 Signed-off-by: Chinmay Sawarkar --- msm/vidc/hfi_response_handler.c | 19 ++++++++++++++----- msm/vidc/vidc_hfi.h | 8 +++++++- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index 92fcd791a1b2..91d9fec5874e 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -785,6 +785,8 @@ static int hfi_process_session_ftb_done( { struct vidc_hal_msg_pkt_hdr *msg_hdr = _pkt; struct msm_vidc_cb_data_done data_done = {0}; + u32 struct_size = 0; + bool is_decoder = false, is_encoder = false; if (!msg_hdr) { @@ -792,10 +794,17 @@ static int hfi_process_session_ftb_done( return -EINVAL; } - is_encoder = msg_hdr->size == sizeof(struct - hfi_msg_session_fill_buffer_done_compressed_packet) + 4; - is_decoder = msg_hdr->size == sizeof(struct - hfi_msg_session_fbd_uncompressed_plane0_packet) + 4; + struct_size = sizeof(struct + hfi_msg_session_fill_buffer_done_compressed_packet) + 4; + is_encoder = (msg_hdr->size == struct_size) || + (msg_hdr->size == (struct_size + + sizeof(struct hfi_ubwc_cr_stat) - 4)); + + struct_size = sizeof(struct + hfi_msg_session_fbd_uncompressed_plane0_packet) + 4; + is_decoder = (msg_hdr->size == struct_size) || + (msg_hdr->size == (struct_size + + sizeof(struct hfi_ubwc_cr_stat) - 4)); if (!(is_encoder ^ is_decoder)) { d_vpr_e("Ambiguous packet (%#x) received (size %d)\n", diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index 697fbbcd2575..d0798f53c0b0 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef __H_VIDC_HFI_H__ #define __H_VIDC_HFI_H__ @@ -548,6 +548,12 @@ struct hfi_msg_session_flush_done_packet { u32 flush_type; }; +struct hfi_ubwc_cr_stat { + u32 is_valid; + u32 worst_compression_ratio; + u32 worst_complexity_number; +}; + struct hfi_ubwc_cr_stats_info_type { u32 cr_stats_info0; u32 cr_stats_info1; From dc4de606315560a2469a5213ef83ddd8795f236c Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Thu, 9 Apr 2020 11:36:41 -0700 Subject: [PATCH 249/452] msm: vidc: Return ENOMEM for VP9 decode overload case Return ENOMEM instead of ENOTSUPP when VP9 decode overload occurs so that userspace can handle this error case correctly. ENOTSUPP is not available in userspace. Change-Id: I5260812bb00fde7eed02a29943a67af038e3c001 Signed-off-by: Mihir Ganu --- msm/vidc/msm_vdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 5e2840d3999a..5b218d603690 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -666,7 +666,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) if (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_VP9) { if (msm_vidc_check_for_vp9d_overload(inst->core)) { s_vpr_e(inst->sid, "VP9 Decode overload\n"); - rc = -ENOTSUPP; + rc = -ENOMEM; goto err_invalid_fmt; } } From 9d29e83709bde1b53e37293ad91877272fe97c79 Mon Sep 17 00:00:00 2001 From: Murali Nalajala Date: Wed, 25 Mar 2020 18:47:23 -0700 Subject: [PATCH 250/452] msm: video: config: Do not compile video sources for VM image Do not compile video sources for VM image for lahaina. Guard the source path against CONFIG_QTI_VM to decide to compile it are not. Change-Id: If9549c2a58ed3e7cf66c2cbc51c5fc01b82dd79b Signed-off-by: Murali Nalajala --- Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index ef196427110e..707ce2c2d67a 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,9 @@ # SPDX-License-Identifier: GPL-2.0-only # auto-detect subdirs +ifneq ($(CONFIG_ARCH_QTI_VM), y) ifeq ($(CONFIG_ARCH_LAHAINA), y) include $(srctree)/techpack/video/config/konavid.conf -endif - -ifeq ($(CONFIG_ARCH_LAHAINA), y) LINUXINCLUDE += -include $(srctree)/techpack/video/config/konavidconf.h endif @@ -17,6 +15,7 @@ endif ifeq ($(CONFIG_ARCH_LITO), y) LINUXINCLUDE += -include $(srctree)/techpack/video/config/litovidconf.h endif +endif LINUXINCLUDE += -I$(srctree)/techpack/video/include \ -I$(srctree)/techpack/video/include/uapi \ From a707b90ff2174bbe9736f09bfd3442cc3eb97198 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Mon, 27 Apr 2020 15:20:46 -0700 Subject: [PATCH 251/452] msm: vidc: Remove PM QoS functionality Remove deprecated PM QoS functionality from vidc driver. Change-Id: I922fdb2f2037a8fc820ebf4f2aa6d35a16c6b589 Signed-off-by: Mihir Ganu --- msm/vidc/hfi_common.c | 16 ---------------- msm/vidc/hfi_common.h | 2 -- msm/vidc/msm_vidc_res_parse.c | 3 --- msm/vidc/msm_vidc_resources.h | 1 - 4 files changed, 22 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 0a0d15796195..997d92685e42 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -1738,10 +1738,6 @@ static int venus_hfi_core_init(void *device) __set_ubwc_config(device); - if (dev->res->pm_qos_latency_us) { - pm_qos_add_request(&dev->qos, PM_QOS_CPU_DMA_LATENCY, - dev->res->pm_qos_latency_us); - } d_vpr_h("Core inited successfully\n"); mutex_unlock(&dev->lock); return rc; @@ -1767,9 +1763,6 @@ static int venus_hfi_core_release(void *dev) mutex_lock(&device->lock); d_vpr_h("Core releasing\n"); - if (device->res->pm_qos_latency_us && - pm_qos_request_active(&device->qos)) - pm_qos_remove_request(&device->qos); __resume(device, DEFAULT_SID); __set_state(device, VENUS_STATE_DEINIT); @@ -3809,10 +3802,6 @@ static inline int __suspend(struct venus_hfi_device *device) d_vpr_h("Entering suspend\n"); - if (device->res->pm_qos_latency_us && - pm_qos_request_active(&device->qos)) - pm_qos_remove_request(&device->qos); - rc = __tzbsp_set_video_state(TZBSP_VIDEO_STATE_SUSPEND, DEFAULT_SID); if (rc) { d_vpr_e("Failed to suspend video core %d\n", rc); @@ -3875,11 +3864,6 @@ static inline int __resume(struct venus_hfi_device *device, u32 sid) goto err_reset_core; } - if (device->res->pm_qos_latency_us) { - pm_qos_add_request(&device->qos, PM_QOS_CPU_DMA_LATENCY, - device->res->pm_qos_latency_us); - } - __sys_set_debug(device, (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT, sid); diff --git a/msm/vidc/hfi_common.h b/msm/vidc/hfi_common.h index 6043db6e7473..216e3c25a5ad 100644 --- a/msm/vidc/hfi_common.h +++ b/msm/vidc/hfi_common.h @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -279,7 +278,6 @@ struct venus_hfi_device { enum hfi_packetization_type packetization_type; struct msm_vidc_cb_info *response_pkt; u8 *raw_packet; - struct pm_qos_request qos; unsigned int skip_pc_count; struct venus_hfi_vpu_ops *vpu_ops; }; diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 809597fa4324..756277fb6e63 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -769,9 +769,6 @@ int read_platform_resources_from_drv_data( res->debug_timeout = find_key_value(platform_data, "qcom,debug-timeout"); - res->pm_qos_latency_us = find_key_value(platform_data, - "qcom,pm-qos-latency-us"); - res->max_secure_inst_count = find_key_value(platform_data, "qcom,max-secure-instances"); diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 9d296e33d63d..3cc9e483fd05 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -165,7 +165,6 @@ struct msm_vidc_platform_resources { const char *hfi_version; bool never_unload_fw; bool debug_timeout; - uint32_t pm_qos_latency_us; uint32_t max_inst_count; uint32_t max_secure_inst_count; uint32_t prefetch_pix_buf_count; From 7fe6ac162486712dd9bfc4aa308a16bd9b68aad8 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 24 Mar 2020 10:44:05 -0700 Subject: [PATCH 252/452] msm: vidc: delayed start of dec vpp processing in work mode 2 Introduced new property to configure start up delay for vpp processing. This feature is enabled for AVC/HEVC 8k resolution case. Due to the delay in vpp processing, ubwc stats structure is moved from ebd to fbd. Ubwc stats changed from per buffer stat to worst case stat from current dpb list. Introduced debugfs control "vpp_delay" to control delay of vpp processing, range 0 to 31. Updated min buffer count requirement due to vpp delay as well. Change-Id: Ib2a07e4b5d7a9cbf3661258790276843ad714d37 Signed-off-by: Chinmay Sawarkar --- msm/vidc/hfi_response_handler.c | 27 ++++++- msm/vidc/msm_vidc.c | 5 ++ msm/vidc/msm_vidc_buffer_calculations.c | 46 +++++++---- msm/vidc/msm_vidc_buffer_calculations.h | 2 +- msm/vidc/msm_vidc_clocks.c | 103 ++++++++++++++++++++---- msm/vidc/msm_vidc_clocks.h | 3 +- msm/vidc/msm_vidc_common.c | 70 +++++++++++----- msm/vidc/msm_vidc_debug.c | 6 +- msm/vidc/msm_vidc_debug.h | 3 +- msm/vidc/msm_vidc_internal.h | 6 ++ msm/vidc/msm_vidc_platform.c | 24 ++++++ msm/vidc/msm_vidc_res_parse.c | 4 + msm/vidc/msm_vidc_resources.h | 2 + msm/vidc/vidc_hfi.h | 4 +- msm/vidc/vidc_hfi_api.h | 7 ++ 15 files changed, 254 insertions(+), 58 deletions(-) diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index 91d9fec5874e..fb778e6cded4 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -798,13 +798,13 @@ static int hfi_process_session_ftb_done( hfi_msg_session_fill_buffer_done_compressed_packet) + 4; is_encoder = (msg_hdr->size == struct_size) || (msg_hdr->size == (struct_size + - sizeof(struct hfi_ubwc_cr_stat) - 4)); + sizeof(struct hfi_ubwc_cr_stats) - 4)); struct_size = sizeof(struct hfi_msg_session_fbd_uncompressed_plane0_packet) + 4; is_decoder = (msg_hdr->size == struct_size) || (msg_hdr->size == (struct_size + - sizeof(struct hfi_ubwc_cr_stat) - 4)); + sizeof(struct hfi_ubwc_cr_stats) - 4)); if (!(is_encoder ^ is_decoder)) { d_vpr_e("Ambiguous packet (%#x) received (size %d)\n", @@ -846,6 +846,17 @@ static int hfi_process_session_ftb_done( data_done.output_done.extra_data_buffer = pkt->extra_data_buffer; data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT; + /* FBD packet is extended only when stats=1. */ + if (pkt->stats == 1) { + struct hfi_ubwc_cr_stats *ubwc_stat = + (struct hfi_ubwc_cr_stats *)pkt->rgData; + data_done.output_done.ubwc_cr_stat.is_valid = + ubwc_stat->is_valid; + data_done.output_done.ubwc_cr_stat.worst_cr = + ubwc_stat->worst_compression_ratio; + data_done.output_done.ubwc_cr_stat.worst_cf = + ubwc_stat->worst_complexity_number; + } } else /* if (is_decoder) */ { struct hfi_msg_session_fbd_uncompressed_plane0_packet *pkt = (struct hfi_msg_session_fbd_uncompressed_plane0_packet *) @@ -883,6 +894,18 @@ static int hfi_process_session_ftb_done( data_done.output_done.extra_data_buffer = pkt->extra_data_buffer; + /* FBD packet is extended only when view_id=1. */ + if (pkt->view_id == 1) { + struct hfi_ubwc_cr_stats *ubwc_stat = + (struct hfi_ubwc_cr_stats *)pkt->rgData; + data_done.output_done.ubwc_cr_stat.is_valid = + ubwc_stat->is_valid; + data_done.output_done.ubwc_cr_stat.worst_cr = + ubwc_stat->worst_compression_ratio; + data_done.output_done.ubwc_cr_stat.worst_cf = + ubwc_stat->worst_complexity_number; + } + if (!pkt->stream_id) data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT; else if (pkt->stream_id == 1) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index aa1e2404755c..48237519f11a 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -855,6 +855,9 @@ static inline int start_streaming(struct msm_vidc_inst *inst) goto fail_start; } + /* Decide bse vpp delay after work mode */ + msm_vidc_set_bse_vpp_delay(inst); + /* Assign Core and LP mode for current session */ rc = call_core_op(inst->core, decide_core_and_power_mode, inst); if (rc) { @@ -1489,6 +1492,8 @@ void *msm_vidc_open(int core_id, int session_type) inst->max_filled_len = 0; inst->entropy_mode = HFI_H264_ENTROPY_CABAC; inst->full_range = COLOR_RANGE_UNSPECIFIED; + inst->bse_vpp_delay = DEFAULT_BSE_VPP_DELAY; + inst->first_reconfig = 0; for (i = SESSION_MSG_INDEX(SESSION_MSG_START); i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) { diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 0e251c0b8721..33f6ba234ad2 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -266,13 +266,13 @@ static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst); static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst); static inline u32 calculate_h264d_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, bool is_interlaced); + u32 width, u32 height, bool is_interlaced, u32 delay); static inline u32 calculate_h265d_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, bool is_interlaced); + u32 width, u32 height, bool is_interlaced, u32 delay); static inline u32 calculate_vpxd_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, bool is_interlaced); + u32 width, u32 height, bool is_interlaced, u32 delay); static inline u32 calculate_mpeg2d_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, bool is_interlaced); + u32 width, u32 height, bool is_interlaced, u32 delay); static inline u32 calculate_enc_scratch_size(struct msm_vidc_inst *inst, u32 width, u32 height, u32 work_mode, u32 lcu_size, u32 num_vpp_pipes); @@ -373,7 +373,7 @@ int msm_vidc_get_decoder_internal_buffer_sizes(struct msm_vidc_inst *inst) struct msm_vidc_dec_buff_size_calculators *dec_calculators; u32 width, height, i, out_min_count, num_vpp_pipes; struct v4l2_format *f; - u32 vpp_delay = 2 + 1; + u32 vpp_delay = inst->bse_vpp_delay; if (!inst || !inst->core || !inst->core->platform_data) { d_vpr_e("%s: Instance is null!", __func__); @@ -419,7 +419,8 @@ int msm_vidc_get_decoder_internal_buffer_sizes(struct msm_vidc_inst *inst) MSM_VIDC_PIC_STRUCT_MAYBE_INTERLACED); curr_req->buffer_size = dec_calculators->calculate_scratch_size( - inst, width, height, is_interlaced); + inst, width, height, is_interlaced, + vpp_delay); valid_buffer_type = true; } else if (curr_req->buffer_type == HAL_BUFFER_INTERNAL_SCRATCH_1) { @@ -428,7 +429,7 @@ int msm_vidc_get_decoder_internal_buffer_sizes(struct msm_vidc_inst *inst) fmt = &inst->fmts[OUTPUT_PORT]; out_min_count = fmt->count_min; out_min_count = - max(vpp_delay, out_min_count); + max(vpp_delay + 1, out_min_count); curr_req->buffer_size = dec_calculators->calculate_scratch1_size( inst, width, height, out_min_count, @@ -690,6 +691,17 @@ int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst) } else { output_min_count = MIN_ENC_OUTPUT_BUFFERS; } + + if (inst->core->resources.has_vpp_delay && + is_decode_session(inst) && + (codec == V4L2_PIX_FMT_H264 + || codec == V4L2_PIX_FMT_HEVC)) { + output_min_count = + max(output_min_count, (u32)MAX_BSE_VPP_DELAY); + output_min_count = + max(output_min_count, (u32)(msm_vidc_vpp_delay & 0x1F)); + } + extra_buff_count = msm_vidc_get_extra_buff_count(inst, HAL_BUFFER_OUTPUT); fmt->count_min = output_min_count; @@ -1115,12 +1127,11 @@ static inline u32 hfi_iris2_h264d_non_comv_size(u32 width, u32 height, return size; } -static inline u32 size_h264d_hw_bin_buffer(u32 width, u32 height) +static inline u32 size_h264d_hw_bin_buffer(u32 width, u32 height, u32 delay) { u32 size_yuv, size_bin_hdr, size_bin_res; u32 size = 0; u32 product; - u32 delay = 2; product = width * height; size_yuv = (product <= BIN_BUFFER_THRESHOLD) ? @@ -1138,14 +1149,15 @@ static inline u32 size_h264d_hw_bin_buffer(u32 width, u32 height) } static inline u32 calculate_h264d_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, bool is_interlaced) + u32 width, u32 height, bool is_interlaced, u32 delay) { u32 aligned_width = ALIGN(width, BUFFER_ALIGNMENT_SIZE(16)); u32 aligned_height = ALIGN(height, BUFFER_ALIGNMENT_SIZE(16)); u32 size = 0; if (!is_interlaced) - size = size_h264d_hw_bin_buffer(aligned_width, aligned_height); + size = size_h264d_hw_bin_buffer(aligned_width, aligned_height, + delay); else size = 0; @@ -1234,12 +1246,11 @@ static inline u32 hfi_iris2_h265d_non_comv_size(u32 width, u32 height, return size; } -static inline u32 size_h265d_hw_bin_buffer(u32 width, u32 height) +static inline u32 size_h265d_hw_bin_buffer(u32 width, u32 height, u32 delay) { u32 size = 0; u32 size_yuv, size_bin_hdr, size_bin_res; u32 product; - u32 delay = 2; product = width * height; size_yuv = (product <= BIN_BUFFER_THRESHOLD) ? @@ -1257,14 +1268,15 @@ static inline u32 size_h265d_hw_bin_buffer(u32 width, u32 height) } static inline u32 calculate_h265d_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, bool is_interlaced) + u32 width, u32 height, bool is_interlaced, u32 delay) { u32 aligned_width = ALIGN(width, BUFFER_ALIGNMENT_SIZE(16)); u32 aligned_height = ALIGN(height, BUFFER_ALIGNMENT_SIZE(16)); u32 size = 0; if (!is_interlaced) - size = size_h265d_hw_bin_buffer(aligned_width, aligned_height); + size = size_h265d_hw_bin_buffer(aligned_width, aligned_height, + delay); else size = 0; @@ -1272,7 +1284,7 @@ static inline u32 calculate_h265d_scratch_size(struct msm_vidc_inst *inst, } static inline u32 calculate_vpxd_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, bool is_interlaced) + u32 width, u32 height, bool is_interlaced, u32 delay) { u32 aligned_width = ALIGN(width, BUFFER_ALIGNMENT_SIZE(16)); u32 aligned_height = ALIGN(height, BUFFER_ALIGNMENT_SIZE(16)); @@ -1303,7 +1315,7 @@ static inline u32 calculate_vpxd_scratch_size(struct msm_vidc_inst *inst, } static inline u32 calculate_mpeg2d_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, bool is_interlaced) + u32 width, u32 height, bool is_interlaced, u32 delay) { return 0; } diff --git a/msm/vidc/msm_vidc_buffer_calculations.h b/msm/vidc/msm_vidc_buffer_calculations.h index a94bc485e32b..07c05659eba2 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.h +++ b/msm/vidc/msm_vidc_buffer_calculations.h @@ -12,7 +12,7 @@ struct msm_vidc_dec_buff_size_calculators { u32 (*calculate_scratch_size)(struct msm_vidc_inst *inst, u32 width, - u32 height, bool is_interlaced); + u32 height, bool is_interlaced, u32 delay); u32 (*calculate_scratch1_size)(struct msm_vidc_inst *inst, u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled, u32 num_vpp_pipes); diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index da9ff137d412..7d9ae82b9252 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -9,6 +9,7 @@ #include "msm_vidc_clocks.h" #include "msm_vidc_buffer_calculations.h" #include "msm_vidc_bus.h" +#include "vidc_hfi.h" #define MSM_VIDC_MIN_UBWC_COMPLEXITY_FACTOR (1 << 16) #define MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR (4 << 16) @@ -162,6 +163,9 @@ void update_recon_stats(struct msm_vidc_inst *inst, u32 CR = 0, CF = 0; u32 frame_size; + if (inst->core->resources.ubwc_stats_in_fbd == 1) + return; + /* do not consider recon stats in case of superframe */ ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); if (ctrl->val) @@ -199,25 +203,37 @@ static int fill_dynamic_stats(struct msm_vidc_inst *inst, u32 min_input_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO; u32 min_cr = MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO; - mutex_lock(&inst->refbufs.lock); - list_for_each_entry_safe(binfo, nextb, &inst->refbufs.list, list) { - if (binfo->CR) { - min_cr = min(min_cr, binfo->CR); - max_cr = max(max_cr, binfo->CR); + if (inst->core->resources.ubwc_stats_in_fbd == 1) { + mutex_lock(&inst->ubwc_stats_lock); + if (inst->ubwc_stats.is_valid == 1) { + min_cr = inst->ubwc_stats.worst_cr; + max_cf = inst->ubwc_stats.worst_cf; + min_input_cr = inst->ubwc_stats.worst_cr; } - if (binfo->CF) { - min_cf = min(min_cf, binfo->CF); - max_cf = max(max_cf, binfo->CF); + mutex_unlock(&inst->ubwc_stats_lock); + } else { + mutex_lock(&inst->refbufs.lock); + list_for_each_entry_safe(binfo, nextb, + &inst->refbufs.list, list) { + if (binfo->CR) { + min_cr = min(min_cr, binfo->CR); + max_cr = max(max_cr, binfo->CR); + } + if (binfo->CF) { + min_cf = min(min_cf, binfo->CF); + max_cf = max(max_cf, binfo->CF); + } } - } - mutex_unlock(&inst->refbufs.lock); + mutex_unlock(&inst->refbufs.lock); - mutex_lock(&inst->input_crs.lock); - list_for_each_entry_safe(temp, next, &inst->input_crs.list, list) { - min_input_cr = min(min_input_cr, temp->input_cr); - max_input_cr = max(max_input_cr, temp->input_cr); + mutex_lock(&inst->input_crs.lock); + list_for_each_entry_safe(temp, next, + &inst->input_crs.list, list) { + min_input_cr = min(min_input_cr, temp->input_cr); + max_input_cr = max(max_input_cr, temp->input_cr); + } + mutex_unlock(&inst->input_crs.lock); } - mutex_unlock(&inst->input_crs.lock); /* Sanitize CF values from HW . */ max_cf = min_t(u32, max_cf, MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR); @@ -1032,6 +1048,7 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) i = 0; inst->clk_data.buffer_counter = 0; + inst->ubwc_stats.is_valid = 0; rc = msm_comm_scale_clocks_and_bus(inst, 1); @@ -1160,6 +1177,62 @@ static int msm_vidc_decide_work_mode_ar50_lt(struct msm_vidc_inst *inst) return rc; } +int msm_vidc_set_bse_vpp_delay(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + u32 delay = 0; + u32 mbpf = 0, codec = 0; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params %pK\n", __func__, inst); + return -EINVAL; + } + + if (!inst->core->resources.has_vpp_delay || + inst->session_type != MSM_VIDC_DECODER || + inst->clk_data.work_mode != HFI_WORKMODE_2 || + inst->first_reconfig) { + s_vpr_hp(inst->sid, "%s: Skip bse-vpp\n", __func__); + return 0; + } + + hdev = inst->core->device; + + /* Decide VPP delay only on first reconfig */ + if (in_port_reconfig(inst)) + inst->first_reconfig = 1; + + codec = get_v4l2_codec(inst); + if (codec != V4L2_PIX_FMT_HEVC && codec != V4L2_PIX_FMT_H264) { + s_vpr_hp(inst->sid, "%s: Skip bse-vpp, codec %u\n", + __func__, codec); + goto exit; + } + + mbpf = msm_vidc_get_mbs_per_frame(inst); + if (mbpf >= NUM_MBS_PER_FRAME(7680, 3840)) + delay = MAX_BSE_VPP_DELAY; + else + delay = DEFAULT_BSE_VPP_DELAY; + + /* DebugFS override [1-31] */ + if (msm_vidc_vpp_delay & 0x1F) + delay = msm_vidc_vpp_delay & 0x1F; + + s_vpr_hp(inst->sid, "%s: bse-vpp delay %u\n", __func__, delay); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VDEC_VSP_VPP_DELAY, &delay, + sizeof(u32)); + if (rc) + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); + else + inst->bse_vpp_delay = delay; + +exit: + return rc; +} + int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) { int rc = 0; diff --git a/msm/vidc/msm_vidc_clocks.h b/msm/vidc/msm_vidc_clocks.h index 5d649ab9f301..c75d9117b8b6 100644 --- a/msm/vidc/msm_vidc_clocks.h +++ b/msm/vidc/msm_vidc_clocks.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #ifndef _MSM_VIDC_CLOCKS_H_ @@ -39,4 +39,5 @@ bool res_is_greater_than(u32 width, u32 height, u32 ref_width, u32 ref_height); bool res_is_less_than(u32 width, u32 height, u32 ref_width, u32 ref_height); +int msm_vidc_set_bse_vpp_delay(struct msm_vidc_inst *inst); #endif diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 469d416df5eb..b11cdf63a045 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1582,6 +1582,43 @@ static void msm_vidc_queue_rbr_event(struct msm_vidc_inst *inst, v4l2_event_queue_fh(&inst->event_handler, &buf_event); } +static void handle_event_change_insufficient(struct msm_vidc_inst *inst, + struct msm_vidc_format *fmt, + struct msm_vidc_cb_event *event_notify, + u32 codec) +{ + int extra_buff_count = 0; + + s_vpr_h(inst->sid, + "seq: V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT\n"); + + /* decide batching as configuration changed */ + inst->batch.enable = is_batching_allowed(inst); + s_vpr_hp(inst->sid, "seq : batching %s\n", + inst->batch.enable ? "enabled" : "disabled"); + msm_dcvs_try_enable(inst); + extra_buff_count = msm_vidc_get_extra_buff_count(inst, + HAL_BUFFER_OUTPUT); + fmt->count_min = event_notify->fw_min_cnt; + + if (inst->core->resources.has_vpp_delay && + is_decode_session(inst) && + (codec == V4L2_PIX_FMT_H264 + || codec == V4L2_PIX_FMT_HEVC)) { + fmt->count_min = + max(fmt->count_min, (u32)MAX_BSE_VPP_DELAY); + fmt->count_min = + max(fmt->count_min, + (u32)(msm_vidc_vpp_delay & 0x1F)); + } + + fmt->count_min_host = fmt->count_min + extra_buff_count; + s_vpr_h(inst->sid, + "seq: hal buffer[%d] count: min %d min_host %d\n", + HAL_BUFFER_OUTPUT, fmt->count_min, + fmt->count_min_host); +} + static void handle_event_change(enum hal_command_response cmd, void *data) { struct msm_vidc_inst *inst = NULL; @@ -1593,7 +1630,6 @@ static void handle_event_change(enum hal_command_response cmd, void *data) u32 *ptr = NULL; struct msm_vidc_format *fmt; struct v4l2_format *f; - int extra_buff_count = 0; u32 codec; if (!event_notify) { @@ -1754,24 +1790,9 @@ static void handle_event_change(enum hal_command_response cmd, void *data) fmt->v4l2_fmt.fmt.pix_mp.width = event_notify->width; mutex_unlock(&inst->lock); - if (event == V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT) { - s_vpr_h(inst->sid, - "seq: V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT\n"); - - /* decide batching as configuration changed */ - inst->batch.enable = is_batching_allowed(inst); - s_vpr_hp(inst->sid, "seq : batching %s\n", - inst->batch.enable ? "enabled" : "disabled"); - msm_dcvs_try_enable(inst); - extra_buff_count = msm_vidc_get_extra_buff_count(inst, - HAL_BUFFER_OUTPUT); - fmt->count_min = event_notify->fw_min_cnt; - fmt->count_min_host = fmt->count_min + extra_buff_count; - s_vpr_h(inst->sid, - "seq: hal buffer[%d] count: min %d min_host %d\n", - HAL_BUFFER_OUTPUT, fmt->count_min, - fmt->count_min_host); - } + if (event == V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT) + handle_event_change_insufficient(inst, fmt, + event_notify, codec); rc = msm_vidc_check_session_supported(inst); if (!rc) { @@ -2638,6 +2659,17 @@ static void handle_fbd(enum hal_command_response cmd, void *data) break; } + if (inst->core->resources.ubwc_stats_in_fbd == 1) { + mutex_lock(&inst->ubwc_stats_lock); + inst->ubwc_stats.is_valid = + fill_buf_done->ubwc_cr_stat.is_valid; + inst->ubwc_stats.worst_cr = + fill_buf_done->ubwc_cr_stat.worst_cr; + inst->ubwc_stats.worst_cf = + fill_buf_done->ubwc_cr_stat.worst_cf; + mutex_unlock(&inst->ubwc_stats_lock); + } + /* * dma cache operations need to be performed before dma_unmap * which is done inside msm_comm_put_vidc_buffer() diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index ccb0dc4ab6a8..a149ea791cf9 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -23,6 +23,7 @@ int msm_vidc_clock_voting = !1; bool msm_vidc_syscache_disable = !true; bool msm_vidc_cvp_usage = true; int msm_vidc_err_recovery_disable = !1; +int msm_vidc_vpp_delay; #define MAX_DBG_BUF_SIZE 4096 @@ -211,6 +212,8 @@ struct dentry *msm_vidc_debugfs_init_drv(void) bool ok = false; struct dentry *dir = NULL; + msm_vidc_vpp_delay = 0; + dir = debugfs_create_dir("msm_vidc", NULL); if (IS_ERR_OR_NULL(dir)) { dir = NULL; @@ -241,7 +244,8 @@ struct dentry *msm_vidc_debugfs_init_drv(void) __debugfs_create(bool, "lossless_encoding", &msm_vidc_lossless_encode) && __debugfs_create(u32, "disable_err_recovery", - &msm_vidc_err_recovery_disable); + &msm_vidc_err_recovery_disable) && + __debugfs_create(u32, "vpp_delay", &msm_vidc_vpp_delay); #undef __debugfs_create diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index e8524f9789d8..a972521f63e1 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef __MSM_VIDC_DEBUG__ @@ -132,6 +132,7 @@ extern bool msm_vidc_syscache_disable; extern bool msm_vidc_lossless_encode; extern bool msm_vidc_cvp_usage; extern int msm_vidc_err_recovery_disable; +extern int msm_vidc_vpp_delay; struct log_cookie { u32 used; diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 04a67f99af8e..e7355be5c2c1 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -39,6 +39,8 @@ #define MAX_NUM_OUTPUT_BUFFERS VIDEO_MAX_FRAME // same as VB2_MAX_FRAME #define MAX_SUPPORTED_INSTANCES 16 +#define MAX_BSE_VPP_DELAY 6 +#define DEFAULT_BSE_VPP_DELAY 2 /* Maintains the number of FTB's between each FBD over a window */ #define DCVS_FTB_WINDOW 16 @@ -561,6 +563,10 @@ struct msm_vidc_inst { bool is_perf_eligible_session; u32 max_filled_len; int full_range; + struct mutex ubwc_stats_lock; + struct msm_vidc_ubwc_stats ubwc_stats; + u32 bse_vpp_delay; + u32 first_reconfig; }; extern struct msm_vidc_drv *vidc_driver; diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index fea44112ab6f..9992be58cb9f 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -458,6 +458,14 @@ static struct msm_vidc_common_data lahaina_common_data[] = { */ .value = 13434880, }, + { + .key = "qcom,ubwc_stats_in_fbd", + .value = 1, + }, + { + .key = "qcom,vpp_delay_supported", + .value = 1, + }, }; static struct msm_vidc_common_data bengal_common_data_v0[] = { @@ -509,6 +517,14 @@ static struct msm_vidc_common_data bengal_common_data_v0[] = { .key = "qcom,fw-vpp-cycles", .value = 225975, }, + { + .key = "qcom,ubwc_stats_in_fbd", + .value = 0, + }, + { + .key = "qcom,vpp_delay_supported", + .value = 0, + }, }; static struct msm_vidc_common_data bengal_common_data_v1[] = { @@ -560,6 +576,14 @@ static struct msm_vidc_common_data bengal_common_data_v1[] = { .key = "qcom,fw-vpp-cycles", .value = 225975, }, + { + .key = "qcom,ubwc_stats_in_fbd", + .value = 0, + }, + { + .key = "qcom,vpp_delay_supported", + .value = 0, + }, }; /* Default UBWC config for LPDDR5 */ diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 809597fa4324..d972c8801d07 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -810,6 +810,10 @@ int read_platform_resources_from_drv_data( "qcom,fw-vpp-cycles"); res->avsync_window_size = find_key_value(platform_data, "qcom,avsync-window-size"); + res->ubwc_stats_in_fbd = find_key_value(platform_data, + "qcom,ubwc_stats_in_fbd"); + res->has_vpp_delay = find_key_value(platform_data, + "qcom,vpp_delay_supported"); res->csc_coeff_data = &platform_data->csc_data; diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 9d296e33d63d..bc212f192e4d 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -195,6 +195,8 @@ struct msm_vidc_platform_resources { struct msm_vidc_ubwc_config_data *ubwc_config; uint32_t clk_freq_threshold; struct cx_ipeak_client *cx_ipeak_context; + uint32_t ubwc_stats_in_fbd; + uint32_t has_vpp_delay; }; static inline bool is_iommu_present(struct msm_vidc_platform_resources *res) diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index d0798f53c0b0..784868e9e20c 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -191,6 +191,8 @@ struct hfi_extradata_header { (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x0022) #define HFI_PROPERTY_PARAM_VDEC_HDR10_HIST_EXTRADATA \ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x0023) +#define HFI_PROPERTY_PARAM_VDEC_VSP_VPP_DELAY \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x0024) #define HFI_PROPERTY_CONFIG_VDEC_OX_START \ (HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x4000) @@ -548,7 +550,7 @@ struct hfi_msg_session_flush_done_packet { u32 flush_type; }; -struct hfi_ubwc_cr_stat { +struct hfi_ubwc_cr_stats { u32 is_valid; u32 worst_compression_ratio; u32 worst_complexity_number; diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 8818ff3ada94..9d29c2d7440c 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -472,6 +472,12 @@ enum hal_command_response { HAL_RESPONSE_UNUSED = 0x10000000, }; +struct msm_vidc_ubwc_stats { + u32 is_valid; + u32 worst_cr; + u32 worst_cf; +}; + struct ubwc_cr_stats_info_type { u32 cr_stats_info0; u32 cr_stats_info1; @@ -534,6 +540,7 @@ struct vidc_hal_fbd { u32 offset3; u32 packet_buffer3; enum hal_buffer buffer_type; + struct msm_vidc_ubwc_stats ubwc_cr_stat; }; struct msm_vidc_capability { From 9903d41e304c83068314748fdb8b5d0963b0817f Mon Sep 17 00:00:00 2001 From: Prakruthi Deepak Heragu Date: Mon, 13 Apr 2020 16:15:01 -0700 Subject: [PATCH 253/452] msm: vidc: Fix NULL pointer error when DEBUG_FS is disabled Add extra check to avoid NULL pointer derefernce when DEBUG_FS is disabled. Change-Id: Id89e5422c5afce0428dd77280788d50af0a22fec Signed-off-by: Prakruthi Deepak Heragu --- msm/vidc/msm_vidc_debug.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index ccb0dc4ab6a8..3c3d725484fb 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -270,7 +270,8 @@ struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core, snprintf(debugfs_name, MAX_DEBUGFS_NAME, "core%d", core->id); dir = debugfs_create_dir(debugfs_name, parent); - if (!dir) { + if (IS_ERR_OR_NULL(dir)) { + dir = NULL; d_vpr_e("Failed to create debugfs for msm_vidc\n"); goto failed_create_dir; } @@ -491,6 +492,7 @@ struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst, dir = debugfs_create_dir(debugfs_name, parent); if (IS_ERR_OR_NULL(dir)) { + dir = NULL; s_vpr_e(inst->sid, "Failed to create debugfs for msm_vidc\n"); goto failed_create_dir; } From 39bfdaa63665080556f8aaa015adc0ed8e25488b Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Thu, 23 Apr 2020 13:35:48 -0700 Subject: [PATCH 254/452] msm: vidc: Enable msm_vidc_events tracing Enable tracing by adding trace function definitions and remove stubbed trace functions. Change-Id: I49902273b78265dabb43ef4a8ef1b8f2fe0529cc Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_debug.c | 84 -------- msm/vidc/msm_vidc_debug.h | 35 +--- msm/vidc/msm_vidc_events.h | 419 +++++++++++++++++++++++++++++++++++++ 3 files changed, 421 insertions(+), 117 deletions(-) create mode 100644 msm/vidc/msm_vidc_events.h diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index 3c3d725484fb..abd39917a558 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -724,90 +724,6 @@ inline bool is_print_allowed(u32 sid, u32 level) } /* Mock all the missing parts for successful compilation starts here */ -void trace_msm_smem_buffer_iommu_op_start(char *s, int i, int j, unsigned long k, - dma_addr_t iova, unsigned long l) -{ -} -void trace_msm_smem_buffer_iommu_op_end(char *s, int i, int j, unsigned long k, - dma_addr_t iova, unsigned long l) -{ -} -void trace_msm_smem_buffer_dma_op_start(char *s, u32 buffer_type, unsigned long heap_mask, - size_t size, u32 align, u32 flags, - int map_kernel) -{ -} -void trace_msm_smem_buffer_dma_op_end(char *s, u32 buffer_type, unsigned long heap_mask, - size_t size, u32 align, u32 flags, - int map_kernel) -{ -} -void trace_msm_v4l2_vidc_buffer_counter(char *s, int etb, int ebd, int ftb, int fbd) -{ -} -void trace_msm_v4l2_vidc_open_start(char *s) -{ - (void) s; -} -void trace_msm_v4l2_vidc_open_end(char *s) -{ - (void) s; -} -void trace_msm_v4l2_vidc_close_start(char *s) -{ - (void) s; -} -void trace_msm_v4l2_vidc_close_end(char *s) -{ - (void) s; -} -void trace_msm_vidc_common_state_change(void* inst, enum instance_state ins_state, int state) -{ - (void) inst; - (void) ins_state; - (void) state; -} - -void trace_msm_vidc_perf_clock_scale(const char *name, u32 freq) -{ - (void) name; - (void) freq; -} - -void trace_venus_hfi_var_done(u32 cp_start, u32 cp_size, - u32 cp_nonpixel_start, u32 cp_nonpixel_size) - -{ - (void) cp_start; - (void) cp_size; - (void) cp_nonpixel_start; - (void) cp_nonpixel_size; -} - -void trace_msm_v4l2_vidc_buffer_event_start(char *event_type, u32 device_addr, - int64_t timestamp, u32 alloc_len, - u32 filled_len, u32 offset) -{ - (void)event_type; - (void) device_addr; - (void) timestamp; - (void) alloc_len; - (void) filled_len; - (void) offset; -} - -void trace_msm_v4l2_vidc_buffer_event_end(char *event_type, u32 device_addr, - int64_t timestamp, u32 alloc_len, - u32 filled_len, u32 offset) -{ - (void) event_type; - (void) device_addr; - (void) timestamp; - (void) alloc_len; - (void) filled_len; - (void) offset; -} - void do_gettimeofday(struct timeval *__ddl_tv) { } diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index e8524f9789d8..9ab840fbc7b9 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -1,12 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef __MSM_VIDC_DEBUG__ #define __MSM_VIDC_DEBUG__ #include #include +#include "msm_vidc_events.h" /* Mock all the missing parts for successful compilation starts here */ #include @@ -15,38 +16,6 @@ #include #include "msm_vidc_internal.h" -#define MAX_TRACER_LOG_LENGTH 128 - -#define trace_msm_vidc_printf(trace_logbuf, log_length) (void) log_length -#define trace_msm_v4l2_vidc_fw_load_start(s) -#define trace_msm_v4l2_vidc_fw_load_end(s) - -void trace_msm_v4l2_vidc_open_start(char *s); -void trace_msm_v4l2_vidc_open_end(char *s); -void trace_msm_v4l2_vidc_close_start(char *s); -void trace_msm_v4l2_vidc_close_end(char *s); -void trace_msm_vidc_common_state_change(void*, enum instance_state ins_state, int state); -void trace_msm_smem_buffer_iommu_op_start(char *s, int i, int j, unsigned long k, - dma_addr_t iova, unsigned long l); -void trace_msm_smem_buffer_iommu_op_end(char *s, int i, int j, unsigned long k, - dma_addr_t iova, unsigned long l); -void trace_msm_smem_buffer_dma_op_start(char *s, u32 buffer_type, unsigned long heap_mask, - size_t size, u32 align, u32 flags, - int map_kernel); -void trace_msm_smem_buffer_dma_op_end(char *s, u32 buffer_type, unsigned long heap_mask, - size_t size, u32 align, u32 flags, - int map_kernel); -void trace_msm_v4l2_vidc_buffer_counter(char *s, int etb, int ebd, int ftb, int fbd); -void trace_msm_vidc_perf_clock_scale(const char *name, u32 freq); -void trace_venus_hfi_var_done(u32 cp_start, u32 cp_size, - u32 cp_nonpixel_start, u32 cp_nonpixel_size); -void trace_msm_v4l2_vidc_buffer_event_start(char *event_type, u32 device_addr, - int64_t timestamp, u32 alloc_len, - u32 filled_len, u32 offset); -void trace_msm_v4l2_vidc_buffer_event_end(char *event_type, u32 device_addr, - int64_t timestamp, u32 alloc_len, - u32 filled_len, u32 offset); - // void disable_irq_nosync(unsigned int irq); // void enable_irq(unsigned int irq); diff --git a/msm/vidc/msm_vidc_events.h b/msm/vidc/msm_vidc_events.h new file mode 100644 index 000000000000..d3db860d093e --- /dev/null +++ b/msm/vidc/msm_vidc_events.h @@ -0,0 +1,419 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM msm_vidc_events +#define TRACE_INCLUDE_FILE msm_vidc_events + +#if !defined(_TRACE_MSM_VIDC_H_) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_MSM_VIDC_H +#include +#include + +DECLARE_EVENT_CLASS(msm_v4l2_vidc, + + TP_PROTO(char *dummy), + + TP_ARGS(dummy), + + TP_STRUCT__entry( + __field(char *, dummy) + ), + + TP_fast_assign( + __entry->dummy = dummy; + ), + + TP_printk("%s", __entry->dummy) +); + +DEFINE_EVENT(msm_v4l2_vidc, msm_v4l2_vidc_open_start, + + TP_PROTO(char *dummy), + + TP_ARGS(dummy) +); + +DEFINE_EVENT(msm_v4l2_vidc, msm_v4l2_vidc_open_end, + + TP_PROTO(char *dummy), + + TP_ARGS(dummy) +); + +DEFINE_EVENT(msm_v4l2_vidc, msm_v4l2_vidc_close_start, + + TP_PROTO(char *dummy), + + TP_ARGS(dummy) +); + +DEFINE_EVENT(msm_v4l2_vidc, msm_v4l2_vidc_close_end, + + TP_PROTO(char *dummy), + + TP_ARGS(dummy) +); + +DEFINE_EVENT(msm_v4l2_vidc, msm_v4l2_vidc_fw_load_start, + + TP_PROTO(char *dummy), + + TP_ARGS(dummy) +); + +DEFINE_EVENT(msm_v4l2_vidc, msm_v4l2_vidc_fw_load_end, + + TP_PROTO(char *dummy), + + TP_ARGS(dummy) +); + +DECLARE_EVENT_CLASS(msm_vidc_common, + + TP_PROTO(void *instp, int old_state, int new_state), + + TP_ARGS(instp, old_state, new_state), + + TP_STRUCT__entry( + __field(void *, instp) + __field(int, old_state) + __field(int, new_state) + ), + + TP_fast_assign( + __entry->instp = instp; + __entry->old_state = old_state; + __entry->new_state = new_state; + ), + + TP_printk("Moved inst: %p from 0x%x to 0x%x", + __entry->instp, + __entry->old_state, + __entry->new_state) +); + +DEFINE_EVENT(msm_vidc_common, msm_vidc_common_state_change, + + TP_PROTO(void *instp, int old_state, int new_state), + + TP_ARGS(instp, old_state, new_state) +); + +DECLARE_EVENT_CLASS(venus_hfi_var, + + TP_PROTO(u32 cp_start, u32 cp_size, + u32 cp_nonpixel_start, u32 cp_nonpixel_size), + + TP_ARGS(cp_start, cp_size, cp_nonpixel_start, cp_nonpixel_size), + + TP_STRUCT__entry( + __field(u32, cp_start) + __field(u32, cp_size) + __field(u32, cp_nonpixel_start) + __field(u32, cp_nonpixel_size) + ), + + TP_fast_assign( + __entry->cp_start = cp_start; + __entry->cp_size = cp_size; + __entry->cp_nonpixel_start = cp_nonpixel_start; + __entry->cp_nonpixel_size = cp_nonpixel_size; + ), + + TP_printk( + "TZBSP_MEM_PROTECT_VIDEO_VAR done, cp_start : 0x%x, cp_size : 0x%x, cp_nonpixel_start : 0x%x, cp_nonpixel_size : 0x%x", + __entry->cp_start, + __entry->cp_size, + __entry->cp_nonpixel_start, + __entry->cp_nonpixel_size) +); + +DEFINE_EVENT(venus_hfi_var, venus_hfi_var_done, + + TP_PROTO(u32 cp_start, u32 cp_size, + u32 cp_nonpixel_start, u32 cp_nonpixel_size), + + TP_ARGS(cp_start, cp_size, cp_nonpixel_start, cp_nonpixel_size) +); + +DECLARE_EVENT_CLASS(msm_v4l2_vidc_count_events, + + TP_PROTO(char *event_type, + u32 etb, u32 ebd, u32 ftb, u32 fbd), + + TP_ARGS(event_type, etb, ebd, ftb, fbd), + + TP_STRUCT__entry( + __field(char *, event_type) + __field(u32, etb) + __field(u32, ebd) + __field(u32, ftb) + __field(u32, fbd) + ), + + TP_fast_assign( + __entry->event_type = event_type; + __entry->etb = etb; + __entry->ebd = ebd; + __entry->ftb = ftb; + __entry->fbd = fbd; + ), + + TP_printk( + "%s, ETB %u EBD %u FTB %u FBD %u", + __entry->event_type, + __entry->etb, + __entry->ebd, + __entry->ftb, + __entry->fbd) +); + +DEFINE_EVENT(msm_v4l2_vidc_count_events, msm_v4l2_vidc_buffer_counter, + + TP_PROTO(char *event_type, + u32 etb, u32 ebd, u32 ftb, u32 fbd), + + TP_ARGS(event_type, + etb, ebd, ftb, fbd) +); + +DECLARE_EVENT_CLASS(msm_v4l2_vidc_buffer_events, + + TP_PROTO(char *event_type, u32 device_addr, int64_t timestamp, + u32 alloc_len, u32 filled_len, u32 offset), + + TP_ARGS(event_type, device_addr, timestamp, alloc_len, + filled_len, offset), + + TP_STRUCT__entry( + __field(char *, event_type) + __field(u32, device_addr) + __field(int64_t, timestamp) + __field(u32, alloc_len) + __field(u32, filled_len) + __field(u32, offset) + ), + + TP_fast_assign( + __entry->event_type = event_type; + __entry->device_addr = device_addr; + __entry->timestamp = timestamp; + __entry->alloc_len = alloc_len; + __entry->filled_len = filled_len; + __entry->offset = offset; + ), + + TP_printk( + "%s, device_addr : 0x%x, timestamp : %lld, alloc_len : 0x%x, filled_len : 0x%x, offset : 0x%x", + __entry->event_type, + __entry->device_addr, + __entry->timestamp, + __entry->alloc_len, + __entry->filled_len, + __entry->offset) +); + +DEFINE_EVENT(msm_v4l2_vidc_buffer_events, msm_v4l2_vidc_buffer_event_start, + + TP_PROTO(char *event_type, u32 device_addr, int64_t timestamp, + u32 alloc_len, u32 filled_len, u32 offset), + + TP_ARGS(event_type, device_addr, timestamp, alloc_len, + filled_len, offset) +); + +DEFINE_EVENT(msm_v4l2_vidc_buffer_events, msm_v4l2_vidc_buffer_event_end, + + TP_PROTO(char *event_type, u32 device_addr, int64_t timestamp, + u32 alloc_len, u32 filled_len, u32 offset), + + TP_ARGS(event_type, device_addr, timestamp, alloc_len, + filled_len, offset) +); + +DECLARE_EVENT_CLASS(msm_smem_buffer_dma_ops, + + TP_PROTO(char *buffer_op, u32 buffer_type, u32 heap_mask, + size_t size, u32 align, u32 flags, int map_kernel), + + TP_ARGS(buffer_op, buffer_type, heap_mask, size, align, + flags, map_kernel), + + TP_STRUCT__entry( + __field(char *, buffer_op) + __field(u32, buffer_type) + __field(u32, heap_mask) + __field(u32, size) + __field(u32, align) + __field(u32, flags) + __field(int, map_kernel) + ), + + TP_fast_assign( + __entry->buffer_op = buffer_op; + __entry->buffer_type = buffer_type; + __entry->heap_mask = heap_mask; + __entry->size = size; + __entry->align = align; + __entry->flags = flags; + __entry->map_kernel = map_kernel; + ), + + TP_printk( + "%s, buffer_type : 0x%x, heap_mask : 0x%x, size : 0x%x, align : 0x%x, flags : 0x%x, map_kernel : %d", + __entry->buffer_op, + __entry->buffer_type, + __entry->heap_mask, + __entry->size, + __entry->align, + __entry->flags, + __entry->map_kernel) +); + +DEFINE_EVENT(msm_smem_buffer_dma_ops, msm_smem_buffer_dma_op_start, + + TP_PROTO(char *buffer_op, u32 buffer_type, u32 heap_mask, + size_t size, u32 align, u32 flags, int map_kernel), + + TP_ARGS(buffer_op, buffer_type, heap_mask, size, align, + flags, map_kernel) +); + +DEFINE_EVENT(msm_smem_buffer_dma_ops, msm_smem_buffer_dma_op_end, + + TP_PROTO(char *buffer_op, u32 buffer_type, u32 heap_mask, + size_t size, u32 align, u32 flags, int map_kernel), + + TP_ARGS(buffer_op, buffer_type, heap_mask, size, align, + flags, map_kernel) +); + +DECLARE_EVENT_CLASS(msm_smem_buffer_iommu_ops, + + TP_PROTO(char *buffer_op, int domain_num, int partition_num, + unsigned long align, unsigned long iova, + unsigned long buffer_size), + + TP_ARGS(buffer_op, domain_num, partition_num, align, iova, buffer_size), + + TP_STRUCT__entry( + __field(char *, buffer_op) + __field(int, domain_num) + __field(int, partition_num) + __field(unsigned long, align) + __field(unsigned long, iova) + __field(unsigned long, buffer_size) + ), + + TP_fast_assign( + __entry->buffer_op = buffer_op; + __entry->domain_num = domain_num; + __entry->partition_num = partition_num; + __entry->align = align; + __entry->iova = iova; + __entry->buffer_size = buffer_size; + ), + + TP_printk( + "%s, domain : %d, partition : %d, align : %lx, iova : 0x%lx, buffer_size=%lx", + __entry->buffer_op, + __entry->domain_num, + __entry->partition_num, + __entry->align, + __entry->iova, + __entry->buffer_size) +); + +DEFINE_EVENT(msm_smem_buffer_iommu_ops, msm_smem_buffer_iommu_op_start, + + TP_PROTO(char *buffer_op, int domain_num, int partition_num, + unsigned long align, unsigned long iova, + unsigned long buffer_size), + + TP_ARGS(buffer_op, domain_num, partition_num, align, iova, buffer_size) +); + +DEFINE_EVENT(msm_smem_buffer_iommu_ops, msm_smem_buffer_iommu_op_end, + + TP_PROTO(char *buffer_op, int domain_num, int partition_num, + unsigned long align, unsigned long iova, + unsigned long buffer_size), + + TP_ARGS(buffer_op, domain_num, partition_num, align, iova, buffer_size) +); + +DECLARE_EVENT_CLASS(msm_vidc_perf, + + TP_PROTO(const char *name, unsigned long value), + + TP_ARGS(name, value), + + TP_STRUCT__entry( + __field(const char *, name) + __field(unsigned long, value) + ), + + TP_fast_assign( + __entry->name = name; + __entry->value = value; + ), + + TP_printk("%s %lu", __entry->name, __entry->value) +); + +DEFINE_EVENT(msm_vidc_perf, msm_vidc_perf_clock_scale, + + TP_PROTO(const char *clock_name, unsigned long frequency), + + TP_ARGS(clock_name, frequency) +); + +DEFINE_EVENT(msm_vidc_perf, msm_vidc_perf_bus_vote, + + TP_PROTO(const char *governor_mode, unsigned long ab), + + TP_ARGS(governor_mode, ab) +); + +#define MAX_TRACER_LOG_LENGTH 128 + +DECLARE_EVENT_CLASS(msm_v4l2_vidc_log, + + TP_PROTO(char *dummy, int length), + + TP_ARGS(dummy, length), + + TP_STRUCT__entry( + __array(char, dummy, MAX_TRACER_LOG_LENGTH) + __field(int, length) + ), + + TP_fast_assign( + __entry->length = length < MAX_TRACER_LOG_LENGTH ? + length : MAX_TRACER_LOG_LENGTH; + __entry->dummy[0] = '\0'; + if (__entry->length > 0) { + memcpy(__entry->dummy, dummy, __entry->length); + if (__entry->dummy[__entry->length - 1] == '\n') + __entry->dummy[__entry->length - 1] = '\0'; + } + ), + + TP_printk("%s", __entry->dummy) +); + +DEFINE_EVENT(msm_v4l2_vidc_log, msm_vidc_printf, + + TP_PROTO(char *dummy, int length), + + TP_ARGS(dummy, length) +); +#endif + +/* This part must be outside protection */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH ../../techpack/video/msm/vidc + +#include From e12a799745d49db8190d801ea46f7bfb14768f9b Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Mon, 20 Apr 2020 20:00:43 -0700 Subject: [PATCH 255/452] msm: vidc: Add frame rate control entry Add entry for decoder frame rate control. Change-Id: I1ccc750dbed69d302d88ca7c0f209a2e10a0578e Signed-off-by: Mihir Ganu --- msm/vidc/msm_vdec.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 5b218d603690..041ed912bd8f 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -403,6 +403,16 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .step = 1, .qmenu = NULL, }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE, + .name = "Frame Rate", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = (MINIMUM_FPS << 16), + .maximum = (MAXIMUM_FPS << 16), + .default_value = (DEFAULT_FPS << 16), + .step = 1, + .qmenu = NULL, + }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY, .name = "Session Priority", @@ -904,6 +914,7 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER: case V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_8BIT: case V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_10BIT: + case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE: break; case V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE: inst->flags &= ~VIDC_THUMBNAIL; From c599ea068f1a43f011f50755792b4472630fad0a Mon Sep 17 00:00:00 2001 From: Rakshitha Shakamuri Date: Tue, 5 May 2020 17:31:22 -0700 Subject: [PATCH 256/452] msm: vidc: Cleanup VP8 on lahaina Remove all VP8 profiling on lahaina for both encoder and decoder. Change-Id: I575ffdced1dbe3db0b55243acb88de4fc8971f86 Signed-off-by: Rakshitha Shakamuri --- msm/vidc/hfi_packetization.c | 5 +- msm/vidc/msm_vdec.c | 33 ------------ msm/vidc/msm_venc.c | 98 ------------------------------------ msm/vidc/msm_vidc_clocks.c | 9 ++-- msm/vidc/msm_vidc_common.c | 45 ----------------- msm/vidc/msm_vidc_platform.c | 29 +++-------- msm/vidc/vidc_hfi_api.h | 1 - msm/vidc/vidc_hfi_helper.h | 12 +---- 8 files changed, 12 insertions(+), 220 deletions(-) diff --git a/msm/vidc/hfi_packetization.c b/msm/vidc/hfi_packetization.c index 23a6a83ebce3..eb09f3fb29b9 100644 --- a/msm/vidc/hfi_packetization.c +++ b/msm/vidc/hfi_packetization.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include "hfi_packetization.h" #include "msm_vidc_debug.h" @@ -42,9 +42,6 @@ u32 vidc_get_hfi_codec(enum hal_video_codec hal_codec, u32 sid) case HAL_VIDEO_CODEC_MPEG2: hfi_codec = HFI_VIDEO_CODEC_MPEG2; break; - case HAL_VIDEO_CODEC_VP8: - hfi_codec = HFI_VIDEO_CODEC_VP8; - break; case HAL_VIDEO_CODEC_HEVC: hfi_codec = HFI_VIDEO_CODEC_HEVC; break; diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 5b218d603690..5b0dbad48a5e 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -65,15 +65,6 @@ static const char *const mpeg_video_h264_level[] = { NULL, }; -static const char *const vp8_profile_level[] = { - "Unused", - "0.0", - "1.0", - "2.0", - "3.0", - NULL -}; - static const char *const vp9_level[] = { "Unused", "1.0", @@ -274,22 +265,6 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .menu_skip_mask = ~(1 << V4L2_MPEG_VIDEO_VP8_PROFILE_0), .qmenu = NULL, }, - { - .id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL, - .name = "VP8 Profile Level", - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED, - .maximum = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3, - .default_value = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3, - .menu_skip_mask = ~( - (1 << V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED) | - (1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0) | - (1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1) | - (1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_2) | - (1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3) - ), - .qmenu = vp8_profile_level, - }, { .id = V4L2_CID_MPEG_VIDEO_VP9_PROFILE, .name = "VP9 Profile", @@ -484,11 +459,6 @@ struct msm_vidc_format_desc vdec_input_formats[] = { .description = "HEVC compressed format", .fourcc = V4L2_PIX_FMT_HEVC, }, - { - .name = "VP8", - .description = "VP8 compressed format", - .fourcc = V4L2_PIX_FMT_VP8, - }, { .name = "VP9", .description = "VP9 compressed format", @@ -882,7 +852,6 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_MPEG_VIDEO_H264_PROFILE: case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: - case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE: inst->profile = msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val, @@ -890,7 +859,6 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDEO_H264_LEVEL: case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: - case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL: case V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL: case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL: inst->level = msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val, @@ -1378,7 +1346,6 @@ int msm_vdec_set_extradata(struct msm_vidc_inst *inst) case V4L2_PIX_FMT_HEVC: display_info = HFI_PROPERTY_PARAM_VUI_DISPLAY_INFO_EXTRADATA; break; - case V4L2_PIX_FMT_VP8: case V4L2_PIX_FMT_VP9: display_info = HFI_PROPERTY_PARAM_VDEC_VPX_COLORSPACE_EXTRADATA; diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 4abee1515a5d..0e7f0f8f4767 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -101,15 +101,6 @@ static const char *const mpeg_video_h264_level[] = { NULL, }; -static const char *const vp8_profile_level[] = { - "Unused", - "0.0", - "1.0", - "2.0", - "3.0", - NULL -}; - static const char *const mpeg_video_stream_format[] = { "NAL Format Start Codes", "NAL Format One NAL Per Buffer", @@ -354,32 +345,6 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { ), .qmenu = mpeg_video_h264_level, }, - { - .id = V4L2_CID_MPEG_VIDEO_VP8_PROFILE, - .name = "VP8 Profile", - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_VP8_PROFILE_0, - .maximum = V4L2_MPEG_VIDEO_VP8_PROFILE_0, - .default_value = V4L2_MPEG_VIDEO_VP8_PROFILE_0, - .menu_skip_mask = ~(1 << V4L2_MPEG_VIDEO_VP8_PROFILE_0), - .qmenu = NULL, - }, - { - .id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL, - .name = "VP8 Profile Level", - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED, - .maximum = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3, - .default_value = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3, - .menu_skip_mask = ~( - (1 << V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED) | - (1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0) | - (1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1) | - (1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_2) | - (1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3) - ), - .qmenu = vp8_profile_level, - }, { .id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, .name = "HEVC Profile", @@ -760,16 +725,6 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .step = 1, .qmenu = NULL, }, - { - .id = V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE, - .name = "VP8 Error Resilience mode", - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, - .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, - .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, - .step = 1, - .qmenu = NULL, - }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID, .name = "Set Base Layer Priority ID for Hier-P", @@ -1064,11 +1019,6 @@ static struct msm_vidc_format_desc venc_output_formats[] = { .description = "H264 compressed format", .fourcc = V4L2_PIX_FMT_H264, }, - { - .name = "VP8", - .description = "VP8 compressed format", - .fourcc = V4L2_PIX_FMT_VP8, - }, { .name = "HEVC", .description = "HEVC compressed format", @@ -1467,8 +1417,6 @@ int msm_venc_set_default_profile(struct msm_vidc_inst *inst) if (get_v4l2_codec(inst) == V4L2_PIX_FMT_HEVC) inst->profile = HFI_HEVC_PROFILE_MAIN; - else if (get_v4l2_codec(inst) == V4L2_PIX_FMT_VP8) - inst->profile = HFI_VP8_PROFILE_MAIN; else if (get_v4l2_codec(inst) == V4L2_PIX_FMT_H264) inst->profile = HFI_H264_PROFILE_HIGH; else @@ -1808,12 +1756,10 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDEO_H264_PROFILE: case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: - case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: inst->profile = msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val, sid); break; case V4L2_CID_MPEG_VIDEO_H264_LEVEL: case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: - case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL: inst->level = msm_comm_v4l2_to_hfi(ctrl->id, ctrl->val, sid); break; case V4L2_CID_MPEG_VIDEO_HEVC_TIER: @@ -2543,10 +2489,6 @@ int msm_venc_set_vbv_delay(struct msm_vidc_inst *inst) inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR) return 0; - /* vbv delay is not required for VP8 encoder */ - if (codec == V4L2_PIX_FMT_VP8) - return 0; - /* Default behavior */ is_legacy_cbr = false; buf_size = CBR_PLUS_BUF_SIZE; @@ -2823,10 +2765,6 @@ int msm_venc_set_frame_qp(struct msm_vidc_inst *inst) b_qp->val = i_qp->val; } - /* B frame QP is not supported for VP8. */ - if (get_v4l2_codec(inst) == V4L2_PIX_FMT_VP8) - qp.enable &= ~QP_ENABLE_B; - qp.qp_packed = i_qp->val | p_qp->val << 8 | b_qp->val << 16; s_vpr_h(inst->sid, "%s: layers %#x frames %#x qp_packed %#x\n", @@ -3552,35 +3490,6 @@ int msm_venc_set_hp_layer(struct msm_vidc_inst *inst) return rc; } -int msm_venc_set_vpx_error_resilience(struct msm_vidc_inst *inst) -{ - int rc = 0; - struct hfi_device *hdev; - struct v4l2_ctrl *ctrl; - struct hfi_enable enable; - - if (!inst || !inst->core) { - d_vpr_e("%s: invalid params %pK\n", __func__, inst); - return -EINVAL; - } - hdev = inst->core->device; - - if (get_v4l2_codec(inst) != V4L2_PIX_FMT_VP8) - return 0; - - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE); - enable.enable = !!ctrl->val; - - s_vpr_h(inst->sid, "%s: %d\n", __func__, enable.enable); - rc = call_hfi_op(hdev, session_set_property, inst->session, - HFI_PROPERTY_PARAM_VENC_VPX_ERROR_RESILIENCE_MODE, &enable, - sizeof(enable)); - if (rc) - s_vpr_e(inst->sid, "%s: set property failed\n", __func__); - - return rc; -} - int msm_venc_set_video_signal_info(struct msm_vidc_inst *inst) { int rc = 0; @@ -4098,10 +4007,6 @@ int msm_venc_set_dyn_qp(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) qp.enable = QP_ENABLE_I | QP_ENABLE_P | QP_ENABLE_B; qp.layer_id = MSM_VIDC_ALL_LAYER_ID; - /* B frame QP is not supported for VP8. */ - if (get_v4l2_codec(inst) == V4L2_PIX_FMT_VP8) - qp.enable &= ~QP_ENABLE_B; - s_vpr_h(inst->sid, "%s: %#x\n", __func__, ctrl->val); rc = call_hfi_op(hdev, session_set_property, inst->session, @@ -4532,9 +4437,6 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) if (rc) goto exit; rc = msm_venc_set_hdr_info(inst); - if (rc) - goto exit; - rc = msm_venc_set_vpx_error_resilience(inst); if (rc) goto exit; rc = msm_venc_set_nal_stream_format(inst); diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index da9ff137d412..bbdfb0736770 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -678,7 +678,7 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, codec = get_v4l2_codec(inst); base_cycles = inst->clk_data.entry->vsp_cycles; - if (codec == V4L2_PIX_FMT_VP8 || codec == V4L2_PIX_FMT_VP9) { + if (codec == V4L2_PIX_FMT_VP9) { vsp_cycles = div_u64(vsp_cycles * 170, 100); } else if (inst->entropy_mode == HFI_H264_ENTROPY_CABAC) { vsp_cycles = div_u64(vsp_cycles * 135, 100); @@ -709,7 +709,7 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, base_cycles = inst->clk_data.entry->vsp_cycles; vsp_cycles = fps * filled_len * 8; - if (codec == V4L2_PIX_FMT_VP8 || codec == V4L2_PIX_FMT_VP9) { + if (codec == V4L2_PIX_FMT_VP9) { vsp_cycles = div_u64(vsp_cycles * 170, 100); } else if (inst->entropy_mode == HFI_H264_ENTROPY_CABAC) { vsp_cycles = div_u64(vsp_cycles * 135, 100); @@ -1074,7 +1074,7 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) width = f->fmt.pix_mp.width; if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES || - codec == V4L2_PIX_FMT_VP8 || is_legacy_cbr) { + is_legacy_cbr) { pdata.video_work_route = 1; } } else { @@ -1196,8 +1196,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) width = inp_f->fmt.pix_mp.width; res_ok = !res_is_greater_than(width, height, 4096, 2160); if (res_ok && - (out_f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_VP8 || - inst->clk_data.low_latency_mode)) { + (inst->clk_data.low_latency_mode)) { pdata.video_work_mode = HFI_WORKMODE_1; /* For WORK_MODE_1, set Low Latency mode by default */ latency.enable = true; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 469d416df5eb..4f3eef5f903c 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -155,21 +155,6 @@ int msm_comm_hfi_to_v4l2(int id, int value, u32 sid) default: goto unknown_value; } - case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL: - switch (value) { - case HFI_VP8_LEVEL_VERSION_0: - return V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0; - case HFI_VP8_LEVEL_VERSION_1: - return V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1; - case HFI_VP8_LEVEL_VERSION_2: - return V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_2; - case HFI_VP8_LEVEL_VERSION_3: - return V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3; - case HFI_LEVEL_UNKNOWN: - return V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED; - default: - goto unknown_value; - } case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: switch (value) { case HFI_VP9_PROFILE_P0: @@ -400,28 +385,6 @@ int msm_comm_v4l2_to_hfi(int id, int value, u32 sid) default: return HFI_H264_ENTROPY_CABAC; } - case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: - switch (value) { - case V4L2_MPEG_VIDEO_VP8_PROFILE_0: - return HFI_VP8_PROFILE_MAIN; - default: - return HFI_VP8_PROFILE_MAIN; - } - case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL: - switch (value) { - case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0: - return HFI_VP8_LEVEL_VERSION_0; - case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1: - return HFI_VP8_LEVEL_VERSION_1; - case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_2: - return HFI_VP8_LEVEL_VERSION_2; - case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3: - return HFI_VP8_LEVEL_VERSION_3; - case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED: - return HFI_LEVEL_UNKNOWN; - default: - return HFI_LEVEL_UNKNOWN; - } case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: switch (value) { case V4L2_MPEG_VIDEO_VP9_PROFILE_0: @@ -503,7 +466,6 @@ int msm_comm_get_v4l2_profile(int fourcc, int profile, u32 sid) return msm_comm_hfi_to_v4l2( V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, profile, sid); - case V4L2_PIX_FMT_VP8: case V4L2_PIX_FMT_VP9: case V4L2_PIX_FMT_MPEG2: return 0; @@ -525,10 +487,6 @@ int msm_comm_get_v4l2_level(int fourcc, int level, u32 sid) return msm_comm_hfi_to_v4l2( V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, level, sid); - case V4L2_PIX_FMT_VP8: - return msm_comm_hfi_to_v4l2( - V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL, - level, sid); case V4L2_PIX_FMT_VP9: case V4L2_PIX_FMT_MPEG2: return 0; @@ -868,9 +826,6 @@ enum hal_video_codec get_hal_codec(int fourcc, u32 sid) case V4L2_PIX_FMT_MPEG2: codec = HAL_VIDEO_CODEC_MPEG2; break; - case V4L2_PIX_FMT_VP8: - codec = HAL_VIDEO_CODEC_VP8; - break; case V4L2_PIX_FMT_VP9: codec = HAL_VIDEO_CODEC_VP9; break; diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index fea44112ab6f..056d7e84a316 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -57,11 +57,9 @@ static struct msm_vidc_codec_data default_codec_data[] = { static struct msm_vidc_codec_data lahaina_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 25, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 25, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_ENCODER, 60, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 25, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 25, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 25, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 60, 200, 200), CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 60, 200, 200), }; @@ -77,13 +75,11 @@ static struct msm_vidc_codec_data bengal_codec_data[] = { #define DEC HAL_VIDEO_DOMAIN_DECODER #define H264 HAL_VIDEO_CODEC_H264 #define HEVC HAL_VIDEO_CODEC_HEVC -#define VP8 HAL_VIDEO_CODEC_VP8 #define VP9 HAL_VIDEO_CODEC_VP9 #define MPEG2 HAL_VIDEO_CODEC_MPEG2 #define DOMAINS_ALL (HAL_VIDEO_DOMAIN_ENCODER | HAL_VIDEO_DOMAIN_DECODER) #define CODECS_ALL (HAL_VIDEO_CODEC_H264 | HAL_VIDEO_CODEC_HEVC | \ - HAL_VIDEO_CODEC_VP8 | HAL_VIDEO_CODEC_VP9 | \ - HAL_VIDEO_CODEC_MPEG2) + HAL_VIDEO_CODEC_VP9 | HAL_VIDEO_CODEC_MPEG2) static struct msm_vidc_codec bengal_codecs[] = { /* {domain, codec} */ @@ -93,8 +89,8 @@ static struct msm_vidc_codec bengal_codecs[] = { static struct msm_vidc_codec default_codecs[] = { /* {domain, codec} */ - {DEC, H264}, {DEC, HEVC}, {DEC, VP8}, {DEC, VP9}, {DEC, MPEG2}, - {ENC, H264}, {ENC, HEVC}, {ENC, VP8}, + {DEC, H264}, {DEC, HEVC}, {DEC, VP9}, {DEC, MPEG2}, + {ENC, H264}, {ENC, HEVC}, }; static struct msm_vidc_codec_capability bengal_capabilities_v0[] = { @@ -242,27 +238,14 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, - {CAP_I_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 20}, - {CAP_P_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 40}, - {CAP_B_FRAME_QP, ENC, VP8|VP9, 0, 127, 1, 40}, + {CAP_I_FRAME_QP, ENC, VP9, 0, 127, 1, 20}, + {CAP_P_FRAME_QP, ENC, VP9, 0, 127, 1, 40}, + {CAP_B_FRAME_QP, ENC, VP9, 0, 127, 1, 40}, /* 10 slices */ {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, {CAP_SLICE_MB, ENC, H264|HEVC, 1, 10, 1, 10}, {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, - /* VP8 specific */ - {CAP_FRAME_WIDTH, ENC|DEC, VP8, 128, 4096, 1, 1920}, - {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 128, 4096, 1, 1080}, - /* (4096 * 2304) / 256 */ - {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 64, 36864, 1, 8160}, - /* ((4096 * 2304) / 256) * 120 */ - {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 64, 4423680, 1, 244800}, - {CAP_BFRAME, ENC, VP8, 0, 0, 1, 0}, - {CAP_FRAMERATE, ENC, VP8, 1, 60, 1, 30}, - {CAP_FRAMERATE, DEC, VP8, 1, 120, 1, 30}, - {CAP_BITRATE, ENC, VP8, 1, 74000000, 1, 20000000}, - {CAP_BITRATE, DEC, VP8, 1, 100000000, 1, 20000000}, - /* Mpeg2 decoder specific */ {CAP_FRAME_WIDTH, DEC, MPEG2, 128, 1920, 1, 1920}, {CAP_FRAME_HEIGHT, DEC, MPEG2, 128, 1920, 1, 1080}, diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 8818ff3ada94..00e883d5adc0 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -123,7 +123,6 @@ enum hal_video_codec { HAL_VIDEO_CODEC_SPARK = 0x00000200, HAL_VIDEO_CODEC_VP6 = 0x00000400, HAL_VIDEO_CODEC_VP7 = 0x00000800, - HAL_VIDEO_CODEC_VP8 = 0x00001000, HAL_VIDEO_CODEC_HEVC = 0x00002000, HAL_VIDEO_CODEC_VP9 = 0x00004000, HAL_VIDEO_CODEC_HEVC_HYBRID = 0x80000000, diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index 5231513650d0..cffdf04192d8 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef __H_VIDC_HFI_HELPER_H__ @@ -71,7 +71,6 @@ #define HFI_VIDEO_CODEC_H264 0x00000002 #define HFI_VIDEO_CODEC_MPEG1 0x00000008 #define HFI_VIDEO_CODEC_MPEG2 0x00000010 -#define HFI_VIDEO_CODEC_VP8 0x00001000 #define HFI_VIDEO_CODEC_HEVC 0x00002000 #define HFI_VIDEO_CODEC_VP9 0x00004000 @@ -115,13 +114,6 @@ #define HFI_MPEG2_LEVEL_ML 0x00000002 #define HFI_MPEG2_LEVEL_HL 0x00000004 -#define HFI_VP8_PROFILE_MAIN 0x00000001 - -#define HFI_VP8_LEVEL_VERSION_0 0x00000001 -#define HFI_VP8_LEVEL_VERSION_1 0x00000002 -#define HFI_VP8_LEVEL_VERSION_2 0x00000004 -#define HFI_VP8_LEVEL_VERSION_3 0x00000008 - #define HFI_VP9_PROFILE_P0 0x00000001 #define HFI_VP9_PROFILE_P2_10B 0x00000004 @@ -326,8 +318,6 @@ struct hfi_buffer_info { (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x026) #define HFI_PROPERTY_PARAM_VENC_DISABLE_RC_TIMESTAMP \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x027) -#define HFI_PROPERTY_PARAM_VENC_VPX_ERROR_RESILIENCE_MODE \ - (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x029) #define HFI_PROPERTY_PARAM_VENC_HIER_B_MAX_NUM_ENH_LAYER \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x02C) #define HFI_PROPERTY_PARAM_VENC_HIER_P_HYBRID_MODE \ From db9f5f903c37fc1b174a54057605b783543e446a Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Wed, 29 Jan 2020 12:04:37 -0800 Subject: [PATCH 257/452] msm: vidc: Introduce ETB flag for Enc Superframe handling Driver will internally produce subframe flag for all ETB of a Superframe to firmware (except last ETB). Firmware will propagate subframe flag to FBD. Driver client will receive multiple FBDs with subframe flag for single Superframe ETB (except last FBD). This subframe flag indicates that more FBD expected for same input. Change-Id: I627123ee2500dd7846363d8b819c3fa56234a494 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_vidc_common.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index b11cdf63a045..74b28c5e195a 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -4367,6 +4367,7 @@ static int msm_comm_qbuf_superframe_to_hfi(struct msm_vidc_inst *inst, frames[0].flags &= ~HAL_BUFFERFLAG_EXTRADATA; frames[0].flags &= ~HAL_BUFFERFLAG_EOS; frames[0].flags &= ~HAL_BUFFERFLAG_CVPMETADATA_SKIP; + frames[0].flags &= ~HAL_BUFFERFLAG_ENDOFSUBFRAME; if (frames[0].flags) s_vpr_e(inst->sid, "%s: invalid flags %#x\n", __func__, frames[0].flags); @@ -4388,10 +4389,20 @@ static int msm_comm_qbuf_superframe_to_hfi(struct msm_vidc_inst *inst, /* first frame */ if (frames[0].extradata_addr) frames[0].flags |= HAL_BUFFERFLAG_EXTRADATA; + + /* Add work incomplete flag for all etb's except the + * last one. For last frame, flag is cleared at the + * last frame iteration. + */ + frames[0].flags |= HAL_BUFFERFLAG_ENDOFSUBFRAME; } else if (i == superframe_count - 1) { /* last frame */ if (mbuf->vvb.flags & V4L2_BUF_FLAG_EOS) frames[i].flags |= HAL_BUFFERFLAG_EOS; + /* Clear Subframe flag just for the last frame to + * indicate the end of SuperFrame. + */ + frames[i].flags &= ~HAL_BUFFERFLAG_ENDOFSUBFRAME; } num_etbs++; } From b4510a377ba8e466174ad36a939b2a81d8f704b5 Mon Sep 17 00:00:00 2001 From: Karthikeyan Periasamy Date: Fri, 24 Jan 2020 17:37:22 -0800 Subject: [PATCH 258/452] msm: vidc: add RGBA UBWC colorformat support Video hardware supports RGBA888 compressed colorformat. So, adding RGBA support in driver. CRs-Fixed: 2610032 Change-Id: I5f69961c2df365058406fb8a1e5cb62e283385d0 Signed-off-by: Karthikeyan Periasamy --- msm/vidc/msm_venc.c | 5 +++++ msm/vidc/msm_vidc_bus.h | 1 + msm/vidc/msm_vidc_common.c | 8 ++++++++ 3 files changed, 14 insertions(+) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 4abee1515a5d..48ea0a4f390a 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1056,6 +1056,11 @@ static struct msm_vidc_format_desc venc_input_formats[] = { .description = "Y/CbCr 4:2:0 512 aligned", .fourcc = V4L2_PIX_FMT_NV12_512, }, + { + .name = "32bit RGBA UBWC 8:8:8:8", + .description = "32-bit RGBA UBWC 8:8:8:8", + .fourcc = V4L2_PIX_FMT_RGBA8888_UBWC, + }, }; static struct msm_vidc_format_desc venc_output_formats[] = { diff --git a/msm/vidc/msm_vidc_bus.h b/msm/vidc/msm_vidc_bus.h index 2e91ddddddcd..fb7ab82e5c5c 100644 --- a/msm/vidc/msm_vidc_bus.h +++ b/msm/vidc/msm_vidc_bus.h @@ -245,6 +245,7 @@ static inline int __bpp(enum hal_uncompressed_format f, u32 sid) case HAL_COLOR_FORMAT_NV12: case HAL_COLOR_FORMAT_NV21: case HAL_COLOR_FORMAT_NV12_UBWC: + case HAL_COLOR_FORMAT_RGBA8888_UBWC: return 8; case HAL_COLOR_FORMAT_NV12_TP10_UBWC: case HAL_COLOR_FORMAT_P010: diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index b11cdf63a045..ce33735e9b54 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -909,6 +909,9 @@ enum hal_uncompressed_format msm_comm_get_hal_uncompressed(int fourcc) case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS: format = HAL_COLOR_FORMAT_P010; break; + case V4L2_PIX_FMT_RGBA8888_UBWC: + format = HAL_COLOR_FORMAT_RGBA8888_UBWC; + break; default: format = HAL_UNUSED_COLOR; break; @@ -940,6 +943,9 @@ u32 msm_comm_get_hfi_uncompressed(int fourcc, u32 sid) case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS: format = HFI_COLOR_FORMAT_P010; break; + case V4L2_PIX_FMT_RGBA8888_UBWC: + format = HFI_COLOR_FORMAT_RGBA8888_UBWC; + break; default: format = HFI_COLOR_FORMAT_NV12_UBWC; s_vpr_e(sid, "Invalid format, defaulting to UBWC"); @@ -3517,6 +3523,8 @@ u32 msm_comm_convert_color_fmt(u32 v4l2_fmt, u32 sid) return COLOR_FMT_NV12_UBWC; case V4L2_PIX_FMT_NV12_TP10_UBWC: return COLOR_FMT_NV12_BPP10_UBWC; + case V4L2_PIX_FMT_RGBA8888_UBWC: + return COLOR_FMT_RGBA8888_UBWC; default: s_vpr_e(sid, "Invalid v4l2 color fmt FMT : %x, Set default(NV12)", From 71e99d72e21632e7a8626127c8049f6ae14658df Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Fri, 17 Apr 2020 18:02:43 -0700 Subject: [PATCH 259/452] msm: vidc: Add support to Adaptive Blur Updated BRS control to accept 0,1,2,3 values instead of boolean. 0 -> disable 1 -> 8-bit 2 -> 10-bit 3 -> both Also, Internal blur is treated as adaptive in firmware with new restrictions. Adding internal blur conditions accordingly. Change-Id: I0aa525bc333acaeeddb5b68cf947030c25466154 Signed-off-by: Akshata Sahukar --- include/uapi/vidc/media/msm_vidc_utils.h | 6 + msm/vidc/msm_venc.c | 181 ++++++++++++++++------- msm/vidc/msm_vidc.h | 6 + msm/vidc/msm_vidc_internal.h | 1 + 4 files changed, 140 insertions(+), 54 deletions(-) diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index 8269a44a999f..70e4edc34ec4 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -218,6 +218,12 @@ enum v4l2_mpeg_vidc_video_vp9_level { (V4L2_CID_MPEG_MSM_VIDC_BASE + 119) #define V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 131) +enum v4l2_mpeg_vidc_video_bitrate_savings_type { + V4L2_MPEG_VIDC_VIDEO_BRS_DISABLE = 0, + V4L2_MPEG_VIDC_VIDEO_BRS_ENABLE_8BIT = 1, + V4L2_MPEG_VIDC_VIDEO_BRS_ENABLE_10BIT = 2, + V4L2_MPEG_VIDC_VIDEO_BRS_ENABLE_ALL = 3, +}; #define V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 120) enum v4l2_mpeg_vidc_video_hevc_max_hier_coding_layer { diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 4abee1515a5d..a8443f4de157 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -965,10 +965,10 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { { .id = V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS, .name = "Enable/Disable bitrate savings", - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, - .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, - .default_value = V4L2_MPEG_MSM_VIDC_ENABLE, + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = V4L2_MPEG_VIDC_VIDEO_BRS_DISABLE, + .maximum = V4L2_MPEG_VIDC_VIDEO_BRS_ENABLE_ALL, + .default_value = V4L2_MPEG_VIDC_VIDEO_BRS_ENABLE_ALL, .step = 1, }, { @@ -1241,6 +1241,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) inst->buff_req.buffer[13].buffer_type = HAL_BUFFER_INTERNAL_RECON; msm_vidc_init_buffer_size_calculators(inst); inst->static_rotation_flip_enabled = false; + inst->external_blur = false; return rc; } @@ -1914,11 +1915,33 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } break; case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_DIMENSIONS: - if (inst->state == MSM_VIDC_START_DONE) { - rc = msm_venc_set_blur_resolution(inst); - if (rc) - s_vpr_e(sid, "%s: set blur resolution failed\n", + if (inst->state < MSM_VIDC_START_DONE) { + if ((ctrl->val != MSM_VIDC_BLUR_INTERNAL) && + (ctrl->val != MSM_VIDC_BLUR_DISABLE)) { + inst->external_blur = true; + } + } else if (inst->state == MSM_VIDC_START_DONE) { + if (!inst->external_blur) { + s_vpr_e(sid, "external blur not enabled"); + break; + } + if (ctrl->val == MSM_VIDC_BLUR_EXTERNAL_DYNAMIC) { + s_vpr_h(sid, + "external blur setting already enabled\n", __func__); + break; + } else if (ctrl->val == MSM_VIDC_BLUR_INTERNAL) { + s_vpr_e(sid, + "cannot change to internal blur config dynamically\n", + __func__); + break; + } else { + rc = msm_venc_set_blur_resolution(inst); + if (rc) + s_vpr_e(sid, + "%s: set blur resolution failed\n", + __func__); + } } break; case V4L2_CID_HFLIP: @@ -3234,8 +3257,10 @@ int msm_venc_set_bitrate_savings_mode(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; - struct v4l2_ctrl *ctrl = NULL; + struct v4l2_ctrl *cac = NULL; + struct v4l2_ctrl *profile = NULL; struct hfi_enable enable; + u32 codec; if (!inst || !inst->core) { d_vpr_e("%s: invalid params %pK\n", __func__, inst); @@ -3243,14 +3268,24 @@ int msm_venc_set_bitrate_savings_mode(struct msm_vidc_inst *inst) } hdev = inst->core->device; - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS); - enable.enable = !!ctrl->val; - if (!ctrl->val && inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { + enable.enable = 0; + if (inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { s_vpr_h(inst->sid, - "Can't disable bitrate savings for non-VBR_CFR\n"); - enable.enable = 1; + "Disable bitrate savings for non-VBR_CFR\n"); + goto setprop; } + codec = get_v4l2_codec(inst); + profile = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_PROFILE); + cac = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS); + + if (codec == V4L2_PIX_FMT_HEVC && + profile->val == V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10) + enable.enable = !!(cac->val & V4L2_MPEG_VIDC_VIDEO_BRS_ENABLE_10BIT); + else + enable.enable = !!(cac->val & V4L2_MPEG_VIDC_VIDEO_BRS_ENABLE_8BIT); + +setprop: s_vpr_h(inst->sid, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_BITRATE_SAVINGS, &enable, @@ -4154,9 +4189,10 @@ int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; - struct v4l2_ctrl *ctrl; + struct v4l2_ctrl *ctrl = NULL; struct hfi_frame_size frame_sz; struct v4l2_format *f; + bool disable_blur = false; if (!inst || !inst->core) { d_vpr_e("%s: invalid params %pK\n", __func__, inst); @@ -4170,33 +4206,48 @@ int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst) frame_sz.height = ctrl->val & 0xFFFF; frame_sz.width = (ctrl->val & 0x7FFF0000) >> 16; + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + /* * 0x0 is default value, internal blur enabled, external blur disabled * 0x1 means dynamic external blur, blur resolution will be set * after start, internal blur disabled * 0x2 means disable both internal and external blur */ - if (ctrl->val == 0x2) { - if (inst->state == MSM_VIDC_START_DONE) { - s_vpr_e(inst->sid, - "Dynamic disable all blur not supported\n"); - return -EINVAL; + if (ctrl->val == MSM_VIDC_BLUR_DISABLE) { + s_vpr_h(inst->sid, + "Disable internal/external blur\n"); + disable_blur = true; + } else if (ctrl->val == MSM_VIDC_BLUR_INTERNAL) { + if (check_blur_restrictions(inst)) { + s_vpr_h(inst->sid, + "Internal blur restrictions not met. Disabling blur..\n"); + disable_blur = true; } - f = &inst->fmts[INPUT_PORT].v4l2_fmt; + } else { + if (check_blur_restrictions(inst)) { + s_vpr_e(inst->sid, + "External blur is unsupported with rotation/flip/scalar\n"); + disable_blur = true; + } else if (frame_sz.width > f->fmt.pix_mp.width || + frame_sz.height > f->fmt.pix_mp.height) { + s_vpr_e(inst->sid, + "external blur wxh[%ux%u] exceeds input wxh[%ux%u]\n", + frame_sz.width, frame_sz.height, + f->fmt.pix_mp.width, f->fmt.pix_mp.height); + disable_blur = true; + } + if (inst->state < MSM_VIDC_START_DONE && disable_blur) + inst->external_blur = false; + } + + if (disable_blur) { /* * Use original input width/height (before VPSS) to inform FW * to disable all blur. */ frame_sz.width = f->fmt.pix_mp.width; frame_sz.height = f->fmt.pix_mp.height; - s_vpr_h(inst->sid, "Disable both auto and external blur\n"); - } else if (ctrl->val != 0){ - if (check_blur_restrictions(inst)) { - /* reject external blur */ - s_vpr_e(inst->sid, - "External blur is unsupported with rotation/flip/scalar\n"); - return -EINVAL; - } } s_vpr_h(inst->sid, "%s: type %u, height %u, width %u\n", __func__, @@ -4425,43 +4476,61 @@ int handle_all_intra_restrictions(struct msm_vidc_inst *inst) int check_blur_restrictions(struct msm_vidc_inst *inst) { - struct v4l2_ctrl *rotation = NULL; - struct v4l2_ctrl *hflip = NULL; - struct v4l2_ctrl *vflip = NULL; + struct v4l2_ctrl *cac = NULL; + struct v4l2_ctrl *profile = NULL; + struct v4l2_ctrl *blur = NULL; struct v4l2_format *f; - u32 output_height, output_width, input_height, input_width; bool scalar_enable = false; - bool rotation_enable = false; - bool flip_enable = false; + bool sup_resolution = false; + bool sup_codec = false; + bool is_10_bit = false; + u32 input_height, input_width; + u32 codec; /* Only need to check static VPSS conditions */ if (inst->state == MSM_VIDC_START_DONE) return 0; - f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; - output_height = f->fmt.pix_mp.height; - output_width = f->fmt.pix_mp.width; + scalar_enable = vidc_scalar_enabled(inst); + blur = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_BLUR_DIMENSIONS); + /* Minimum restrictions to enable any type of blur */ + if (scalar_enable || inst->static_rotation_flip_enabled) { + return -ENOTSUPP; + } + if (blur->val != MSM_VIDC_BLUR_INTERNAL) { + /* below restrictions applicable for internal blur only */ + return 0; + } + f = &inst->fmts[INPUT_PORT].v4l2_fmt; input_height = f->fmt.pix_mp.height; input_width = f->fmt.pix_mp.width; - if (output_height != input_height || output_width != input_width) - scalar_enable = true; + /* Adaptive blur restrictions */ + cac = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS); + codec = get_v4l2_codec(inst); + profile = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_PROFILE); - rotation = get_ctrl(inst, V4L2_CID_ROTATE); - if (rotation->val != 0) - rotation_enable = true; + if (codec == V4L2_PIX_FMT_HEVC && + profile->val == V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10) { + is_10_bit = true; + } + if (res_is_greater_than(input_width, input_height, 352, 240) && + res_is_less_than_or_equal_to(input_width, input_height, + 3840, 2160)) { + sup_resolution = true; + } - hflip = get_ctrl(inst, V4L2_CID_HFLIP); - vflip = get_ctrl(inst, V4L2_CID_VFLIP); - if ((hflip->val == V4L2_MPEG_MSM_VIDC_ENABLE) || - (vflip->val == V4L2_MPEG_MSM_VIDC_ENABLE)) - flip_enable = true; + if (codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264) + sup_codec = true; - if (scalar_enable || rotation_enable || flip_enable) + if (inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR || + !cac->val || is_10_bit || !sup_codec || inst->all_intra || + !sup_resolution) { return -ENOTSUPP; - else - return 0; + } + + return 0; } int msm_venc_set_properties(struct msm_vidc_inst *inst) @@ -4584,6 +4653,13 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) if (rc) goto exit; rc = msm_venc_set_video_csc(inst); + if (rc) + goto exit; + /* + * Downscalar and Static rotation/flip has higher priority + * than blur. + */ + rc = msm_venc_set_rotation(inst); if (rc) goto exit; rc = msm_venc_set_blur_resolution(inst); @@ -4596,9 +4672,6 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) if (rc) goto exit; rc = msm_venc_set_buffer_counts(inst); - if (rc) - goto exit; - rc = msm_venc_set_rotation(inst); if (rc) goto exit; rc = msm_venc_set_lossless(inst); diff --git a/msm/vidc/msm_vidc.h b/msm/vidc/msm_vidc.h index 92bd06426747..fcfe8b275ace 100644 --- a/msm/vidc/msm_vidc.h +++ b/msm/vidc/msm_vidc.h @@ -47,6 +47,12 @@ enum hal_buffer { HAL_BUFFER_INTERNAL_RECON = 0x1000, }; +enum msm_vidc_blur_type { + MSM_VIDC_BLUR_INTERNAL = 0x0, + MSM_VIDC_BLUR_EXTERNAL_DYNAMIC = 0x1, + MSM_VIDC_BLUR_DISABLE = 0x2, +}; + struct dma_mapping_info { struct device *dev; struct iommu_domain *domain; diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index e7355be5c2c1..efc5ea7a6148 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -550,6 +550,7 @@ struct msm_vidc_inst { u32 layer_bitrate; u32 client_set_ctrls; bool static_rotation_flip_enabled; + bool external_blur; struct internal_buf *dpb_extra_binfo; struct msm_vidc_codec_data *codec_data; struct hal_hdr10_pq_sei hdr10_sei_params; From 7aac68f40eb0469c7e2051d612a4a2e129424104 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Wed, 15 Apr 2020 21:14:30 +0530 Subject: [PATCH 260/452] msm: vidc: Enable work mode 2 for image sessions Enable work mode 2 for image sessions where rc type is Constant Quality(CQ). Change-Id: I55b6abe8a0e28b3afc55c83456c02be19cf1e7cb Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_clocks.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 7d9ae82b9252..b8f1c61e1461 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1146,9 +1146,17 @@ static int msm_vidc_decide_work_mode_ar50_lt(struct msm_vidc_inst *inst) pdata.video_work_mode = HFI_WORKMODE_1; break; } - } else if (inst->session_type == MSM_VIDC_ENCODER) + } else if (inst->session_type == MSM_VIDC_ENCODER) { pdata.video_work_mode = HFI_WORKMODE_1; - else { + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR || + inst->rc_type == + V4L2_MPEG_VIDEO_BITRATE_MODE_MBR || + inst->rc_type == + V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR || + inst->rc_type == + V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) + pdata.video_work_mode = HFI_WORKMODE_2; + } else { return -EINVAL; } From 23e16e4dcdc4d073502255de81ff487c3568ea78 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Tue, 5 May 2020 13:40:31 +0530 Subject: [PATCH 261/452] msm: vidc: update extradata size for input buffer packet As per the interface agreement, rg_data would communicate the size of extradata. Update the same while creating the packet. Change-Id: Id61bce9486a11db5263c336b3284e81953a9a070 Signed-off-by: Vikash Garodia Signed-off-by: Akshata Sahukar --- msm/vidc/hfi_packetization.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/msm/vidc/hfi_packetization.c b/msm/vidc/hfi_packetization.c index 23a6a83ebce3..922b9fd8da6d 100644 --- a/msm/vidc/hfi_packetization.c +++ b/msm/vidc/hfi_packetization.c @@ -477,6 +477,8 @@ int create_pkt_cmd_session_etb_decoder( pkt->filled_len = input_frame->filled_len; pkt->input_tag = input_frame->input_tag; pkt->packet_buffer = (u32)input_frame->device_addr; + pkt->extra_data_buffer = 0; + pkt->rgData[0] = 0; trace_msm_v4l2_vidc_buffer_event_start("ETB", input_frame->device_addr, input_frame->timestamp, @@ -511,6 +513,7 @@ int create_pkt_cmd_session_etb_encoder( pkt->input_tag = input_frame->input_tag; pkt->packet_buffer = (u32)input_frame->device_addr; pkt->extra_data_buffer = (u32)input_frame->extradata_addr; + pkt->rgData[0] = input_frame->extradata_size; trace_msm_v4l2_vidc_buffer_event_start("ETB", input_frame->device_addr, input_frame->timestamp, From 8e325f53028ebc5092d2872c02669989ecb0ebaf Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 8 May 2020 02:58:56 +0530 Subject: [PATCH 262/452] msm: vidc: Add control to configure latency hint The control would hint the video driver to prepare for latency mode during the video session. CRs-Fixed: 2681306 Change-Id: Ied0307ff66b755005dcd4fe05189d7e864be208e Signed-off-by: Vikash Garodia --- include/uapi/vidc/media/msm_vidc_utils.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index 8269a44a999f..38a33b4b2676 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -252,6 +252,9 @@ enum v4l2_mpeg_vidc_video_roi_type { V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_2BIT = 1, V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_2BYTE = 2, }; +#define V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_HINT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 133) + #define V4L2_CID_MPEG_VIDC_VIDEO_UNKNOWN \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 0xFFF) /* vendor controls end */ From 6a73486000862cdc7eb64cdbf7e7be2d0ab79f25 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 17 Apr 2020 23:02:20 +0530 Subject: [PATCH 263/452] msm: vidc: Add log to indicate image session During multiple error scenario, video driver prints the properties of ongoing video instances. Add a log to indicate if the session is of type image. Change-Id: Ie23522bd31c9f5188c204c4a1eeae59a627d1976 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_common.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 65a1c191ae17..7cf0fe93d45c 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -3174,7 +3174,7 @@ static void msm_vidc_print_running_insts(struct msm_vidc_core *core) inp_f = &temp->fmts[INPUT_PORT].v4l2_fmt; if (temp->state >= MSM_VIDC_OPEN_DONE && temp->state < MSM_VIDC_STOP_DONE) { - char properties[4] = ""; + char properties[5] = ""; if (is_thumbnail_session(temp)) strlcat(properties, "N", sizeof(properties)); @@ -3185,6 +3185,9 @@ static void msm_vidc_print_running_insts(struct msm_vidc_core *core) if (is_realtime_session(temp)) strlcat(properties, "R", sizeof(properties)); + if (is_grid_session(temp)) + strlcat(properties, "I", sizeof(properties)); + if (temp->clk_data.operating_rate) op_rate = temp->clk_data.operating_rate >> 16; else From 7d5566a34a130a1dcd45a41514c4ebe5b9f9f86c Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 3 Feb 2020 12:13:55 +0530 Subject: [PATCH 264/452] msm: vidc: Add IRIS2 1pipe support Add vpu_ver as IRIS2_1 for lagoon and its corresponding checks such as no CVP, ROI type, buffer size calculators based on vpu version. Change-Id: Ie26c015413c551ca430bb70822a4a65d61d56e11 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_venc.c | 7 ++++--- msm/vidc/msm_vidc.c | 3 ++- msm/vidc/msm_vidc_buffer_calculations.c | 4 +++- msm/vidc/msm_vidc_clocks.c | 7 +++++++ msm/vidc/msm_vidc_internal.h | 1 + 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 0e7f0f8f4767..b3288630e723 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1109,11 +1109,13 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) int rc = 0; struct msm_vidc_format_desc *fmt_desc = NULL; struct v4l2_format *f = NULL; + uint32_t vpu; if (!inst) { d_vpr_e("Invalid input = %pK\n", inst); return -EINVAL; } + vpu = inst->core->platform_data->vpu_ver; f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; f->type = OUTPUT_MPLANE; f->fmt.pix_mp.height = DEFAULT_HEIGHT; @@ -1139,9 +1141,8 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) f->fmt.pix_mp.height = DEFAULT_HEIGHT; f->fmt.pix_mp.width = DEFAULT_WIDTH; f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12_UBWC; - if(inst->core->platform_data->vpu_ver == VPU_VERSION_IRIS1) - f->fmt.pix_mp.num_planes = 1; - else + f->fmt.pix_mp.num_planes = 1; + if (vpu == VPU_VERSION_IRIS2) f->fmt.pix_mp.num_planes = 2; f->fmt.pix_mp.plane_fmt[0].sizeimage = msm_vidc_calculate_enc_input_frame_size(inst); diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 48237519f11a..cc534d2bd6ae 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1394,7 +1394,8 @@ static int try_get_ctrl_for_instance(struct msm_vidc_inst *inst, return -EINVAL; vpu_ver = inst->core->platform_data->vpu_ver; ctrl->val = (vpu_ver == VPU_VERSION_IRIS1 || - vpu_ver == VPU_VERSION_IRIS2) ? + vpu_ver == VPU_VERSION_IRIS2 || + vpu_ver == VPU_VERSION_IRIS2_1) ? V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_2BYTE : V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_2BIT; break; diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 33f6ba234ad2..776d4e05c48d 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -598,15 +598,17 @@ int msm_vidc_calculate_internal_buffer_sizes(struct msm_vidc_inst *inst) void msm_vidc_init_buffer_size_calculators(struct msm_vidc_inst *inst) { struct msm_vidc_core *core; + uint32_t vpu; if (!inst) return; inst->buffer_size_calculators = NULL; core = inst->core; + vpu = core->platform_data->vpu_ver; /* Change this to IRIS2 when ready */ - if (core->platform_data->vpu_ver == VPU_VERSION_IRIS2) + if (vpu == VPU_VERSION_IRIS2 || vpu == VPU_VERSION_IRIS2_1) inst->buffer_size_calculators = msm_vidc_calculate_internal_buffer_sizes; } diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 7ba24e8157ad..5fc2d3b38cf4 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1064,6 +1064,7 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) struct hfi_video_work_route pdata; bool is_legacy_cbr; u32 codec; + uint32_t vpu; if (!inst || !inst->core || !inst->core->device) { d_vpr_e("%s: Invalid args: Inst = %pK\n", @@ -1071,10 +1072,15 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) return -EINVAL; } + vpu = inst->core->platform_data->vpu_ver; hdev = inst->core->device; is_legacy_cbr = inst->clk_data.is_legacy_cbr; pdata.video_work_route = 4; + if (vpu == VPU_VERSION_IRIS2_1) { + pdata.video_work_route = 1; + goto decision_done; + } codec = get_v4l2_codec(inst); if (inst->session_type == MSM_VIDC_DECODER) { if (codec == V4L2_PIX_FMT_MPEG2 || @@ -1098,6 +1104,7 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) return -EINVAL; } +decision_done: s_vpr_h(inst->sid, "Configurng work route = %u", pdata.video_work_route); diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index e7355be5c2c1..4e7e62f277a5 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -263,6 +263,7 @@ enum vpu_version { VPU_VERSION_AR50 = 1, VPU_VERSION_IRIS1, VPU_VERSION_IRIS2, + VPU_VERSION_IRIS2_1, VPU_VERSION_AR50_LITE, }; From bc16bc24aa4ddfe507a48004129fa294f0445369 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Fri, 31 Jan 2020 14:56:40 +0530 Subject: [PATCH 265/452] msm: vidc: Change default width & height Change default width & height for 1080p to QVGA. Having 1080p as default, creates issue in concurrent sessions for low end targets where max capability is 1080p. CRs-Fixed: 2602438 Change-Id: I0ca9d8633af1882abd5dbfd113c7dd55cd399f0a Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index e7355be5c2c1..88701e6aecfd 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -26,8 +26,8 @@ #define MAX_DEBUGFS_NAME 50 #define DEFAULT_TIMEOUT 3 -#define DEFAULT_HEIGHT 1088 -#define DEFAULT_WIDTH 1920 +#define DEFAULT_HEIGHT 240 +#define DEFAULT_WIDTH 320 #define MIN_SUPPORTED_WIDTH 32 #define MIN_SUPPORTED_HEIGHT 32 #define DEFAULT_FPS 30 From 196a38b6478e0992111cdf06459e490461c30931 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 27 Apr 2020 12:07:31 +0530 Subject: [PATCH 266/452] msm: vidc: Update HFI enc_scratch1_size for lahaina Update colrcbuf_size calculations with frame width/height in MB's instead of frame width/heigt in LCU's. Change-Id: Ia84609e90c3bd6fb626cf759090e9ddcd1f86435 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_buffer_calculations.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 33f6ba234ad2..e1329e11df5d 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1523,7 +1523,7 @@ static inline u32 calculate_enc_scratch1_size(struct msm_vidc_inst *inst, u32 leftline_buf_ctrl_size_FE, line_buf_recon_pix_size; u32 leftline_buf_recon_pix_size, lambda_lut_size, override_buffer_size; u32 col_mv_buf_size, vpp_reg_buffer_size, ir_buffer_size; - u32 vpss_line_buf, leftline_buf_meta_recony, h265e_colrcbuf_size; + u32 vpss_line_buf, leftline_buf_meta_recony, col_rc_buf_size; u32 h265e_framerc_bufsize, h265e_lcubitcnt_bufsize; u32 h265e_lcubitmap_bufsize, se_stats_bufsize; u32 bse_reg_buffer_size, bse_slice_cmd_buffer_size, slice_info_bufsize; @@ -1533,6 +1533,8 @@ static inline u32 calculate_enc_scratch1_size(struct msm_vidc_inst *inst, u32 output_mv_bufsize = 0, temp_scratch_mv_bufsize = 0; u32 size, bit_depth, num_LCUMB; u32 vpss_lineBufferSize_1 = 0; + u32 width_mb_num = ((width + 15) >> 4); + u32 height_mb_num = ((height + 15) >> 4); width_lcu_num = ((width)+(lcu_size)-1) / (lcu_size); height_lcu_num = ((height)+(lcu_size)-1) / (lcu_size); @@ -1598,12 +1600,9 @@ static inline u32 calculate_enc_scratch1_size(struct msm_vidc_inst *inst, BUFFER_ALIGNMENT_SIZE(32))); col_mv_buf_size = ALIGN(col_mv_buf_size, VENUS_DMA_ALIGNMENT) * (num_ref + 1); - h265e_colrcbuf_size = (((width_lcu_num + 7) >> 3) * - 16 * 2 * height_lcu_num); - if (num_vpp_pipes > 1) - h265e_colrcbuf_size = ALIGN(h265e_colrcbuf_size, - VENUS_DMA_ALIGNMENT) * num_vpp_pipes; - h265e_colrcbuf_size = ALIGN(h265e_colrcbuf_size, + col_rc_buf_size = (((width_mb_num + 7) >> 3) * + 16 * 2 * height_mb_num); + col_rc_buf_size = ALIGN(col_rc_buf_size, VENUS_DMA_ALIGNMENT) * HFI_MAX_COL_FRAME; h265e_framerc_bufsize = (is_h265) ? (256 + 16 * (14 + (((height_coded >> 5) + 7) >> 3))) : @@ -1651,7 +1650,7 @@ static inline u32 calculate_enc_scratch1_size(struct msm_vidc_inst *inst, vpss_line_buf + col_mv_buf_size + topline_buf_ctrl_size_FE + leftline_buf_ctrl_size_FE + line_buf_recon_pix_size + leftline_buf_recon_pix_size + leftline_buf_meta_recony + - linebuf_meta_recon_uv + h265e_colrcbuf_size + + linebuf_meta_recon_uv + col_rc_buf_size + h265e_framerc_bufsize + h265e_lcubitcnt_bufsize + h265e_lcubitmap_bufsize + line_buf_sde_size + topline_bufsize_fe_1stg_sao + override_buffer_size + From c291a1bcb5c16e85117ce51e43c37018ceee4941 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Wed, 29 Apr 2020 14:30:32 +0800 Subject: [PATCH 267/452] msm: venc: add bitrate boost mode Add to enable bitrate boost mode when rate control mode is VBR and CAC is enabled. The default boost margin is 25. This value can be config from 0 - 100 by the client. Change-Id: I4c3d0ae557052d3e615aee4c74b52ce0596fcfcc Signed-off-by: Shi Zhongbo --- include/uapi/vidc/media/msm_vidc_utils.h | 18 +++++---- msm/vidc/msm_venc.c | 49 ++++++++++++++++++++++++ msm/vidc/msm_venc.h | 1 + msm/vidc/vidc_hfi_helper.h | 6 +++ 4 files changed, 66 insertions(+), 8 deletions(-) diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index bafaeb1c2088..a6f882e860aa 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -216,14 +216,6 @@ enum v4l2_mpeg_vidc_video_vp9_level { (V4L2_CID_MPEG_MSM_VIDC_BASE + 118) #define V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 119) -#define V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS \ - (V4L2_CID_MPEG_MSM_VIDC_BASE + 131) -enum v4l2_mpeg_vidc_video_bitrate_savings_type { - V4L2_MPEG_VIDC_VIDEO_BRS_DISABLE = 0, - V4L2_MPEG_VIDC_VIDEO_BRS_ENABLE_8BIT = 1, - V4L2_MPEG_VIDC_VIDEO_BRS_ENABLE_10BIT = 2, - V4L2_MPEG_VIDC_VIDEO_BRS_ENABLE_ALL = 3, -}; #define V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 120) enum v4l2_mpeg_vidc_video_hevc_max_hier_coding_layer { @@ -258,6 +250,16 @@ enum v4l2_mpeg_vidc_video_roi_type { V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_2BIT = 1, V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_2BYTE = 2, }; +#define V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 131) +enum v4l2_mpeg_vidc_video_bitrate_savings_type { + V4L2_MPEG_VIDC_VIDEO_BRS_DISABLE = 0, + V4L2_MPEG_VIDC_VIDEO_BRS_ENABLE_8BIT = 1, + V4L2_MPEG_VIDC_VIDEO_BRS_ENABLE_10BIT = 2, + V4L2_MPEG_VIDC_VIDEO_BRS_ENABLE_ALL = 3, +}; +#define V4L2_CID_MPEG_VIDC_VENC_BITRATE_BOOST \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 132) #define V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_HINT \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 133) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index bd0bc3dd6c27..3df5b13d3e8a 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -926,6 +926,15 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = V4L2_MPEG_VIDC_VIDEO_BRS_ENABLE_ALL, .step = 1, }, + { + .id = V4L2_CID_MPEG_VIDC_VENC_BITRATE_BOOST, + .name = "Bitrate boost margin", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 100, + .default_value = 25, + .step = 1, + }, { .id = V4L2_CID_MPEG_VIDEO_VBV_DELAY, .name = "Set Vbv Delay", @@ -1968,6 +1977,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VENC_RC_TIMESTAMP_DISABLE: case V4L2_CID_MPEG_VIDEO_VBV_DELAY: case V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS: + case V4L2_CID_MPEG_VIDC_VENC_BITRATE_BOOST: case V4L2_CID_MPEG_VIDC_SUPERFRAME: s_vpr_h(sid, "Control set: ID : 0x%x Val : %d\n", ctrl->id, ctrl->val); @@ -3230,10 +3240,49 @@ int msm_venc_set_bitrate_savings_mode(struct msm_vidc_inst *inst) sizeof(enable)); if (rc) s_vpr_e(inst->sid, "%s: set property failed\n", __func__); + else + rc = msm_venc_set_bitrate_boost_margin(inst, enable.enable); return rc; } +int msm_venc_set_bitrate_boost_margin(struct msm_vidc_inst *inst, u32 enable) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *ctrl = NULL; + struct hfi_bitrate_boost_margin boost_margin; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params %pK\n", __func__, inst); + return -EINVAL; + } + hdev = inst->core->device; + + if (!enable) { + boost_margin.margin = 0; + goto setprop; + } + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_BITRATE_BOOST); + /* Mapped value to 0, 25 or 50*/ + if (ctrl->val >= 50) + boost_margin.margin = 50; + else + boost_margin.margin = (u32)(ctrl->val/25) * 25; + +setprop: + /* s_vpr_h(inst->sid, "%s: %d\n", __func__, boost_margin.margin); + * rc = call_hfi_op(hdev, session_set_property, inst->session, + * HFI_PROPERTY_PARAM_VENC_BITRATE_BOOST, &boost_margin, + * sizeof(boost_margin)); + *if (rc) + * s_vpr_e(inst->sid, "%s: set property failed\n", __func__); + */ + return rc; +} + + int msm_venc_set_loop_filter_mode(struct msm_vidc_inst *inst) { int rc = 0; diff --git a/msm/vidc/msm_venc.h b/msm/vidc/msm_venc.h index a9ff51824eba..43b56bc21788 100644 --- a/msm/vidc/msm_venc.h +++ b/msm/vidc/msm_venc.h @@ -46,4 +46,5 @@ int handle_all_intra_restrictions(struct msm_vidc_inst *inst); int check_blur_restrictions(struct msm_vidc_inst *inst); int msm_venc_set_frame_quality(struct msm_vidc_inst *inst); int msm_venc_set_image_grid(struct msm_vidc_inst *inst); +int msm_venc_set_bitrate_boost_margin(struct msm_vidc_inst *inst, u32 enable); #endif diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index cffdf04192d8..e6b733b9aaeb 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -336,6 +336,8 @@ struct hfi_buffer_info { (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x038) #define HFI_PROPERTY_PARAM_VENC_LOSSLESS_ENCODING \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x039) +#define HFI_PROPERTY_PARAM_VENC_BITRATE_BOOST \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x041) #define HFI_PROPERTY_CONFIG_VENC_COMMON_START \ (HFI_DOMAIN_BASE_VENC + HFI_ARCH_COMMON_OFFSET + 0x6000) @@ -1063,4 +1065,8 @@ struct hfi_vbv_hrd_buf_size { u32 vbv_hrd_buf_size; }; +struct hfi_bitrate_boost_margin { + u32 margin; +}; + #endif From 71bfe61fdab457b21c4d1e5c2fd5aa2fbb76002b Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Sun, 17 May 2020 14:37:12 -0700 Subject: [PATCH 268/452] msm: vidc: Initialize ubwc_stats_lock Initialize ubwc_stats_lock before use and destroy it before video instance is destroyed. Change-Id: I4ecc02109d9d1c3f8b7cfe28c49b5467866b4d3e Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 48237519f11a..cba813cddd3d 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1459,6 +1459,7 @@ void *msm_vidc_open(int core_id, int session_type) mutex_init(&inst->bufq[INPUT_PORT].lock); mutex_init(&inst->lock); mutex_init(&inst->flush_lock); + mutex_init(&inst->ubwc_stats_lock); INIT_MSM_VIDC_LIST(&inst->scratchbufs); INIT_MSM_VIDC_LIST(&inst->input_crs); @@ -1562,6 +1563,7 @@ void *msm_vidc_open(int core_id, int session_type) vb2_queue_release(&inst->bufq[OUTPUT_PORT].vb2_bufq); fail_bufq_capture: msm_comm_ctrl_deinit(inst); + mutex_destroy(&inst->ubwc_stats_lock); mutex_destroy(&inst->sync_lock); mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); mutex_destroy(&inst->bufq[INPUT_PORT].lock); @@ -1707,6 +1709,7 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) DEINIT_MSM_VIDC_LIST(&inst->window_data); DEINIT_MSM_VIDC_LIST(&inst->timestamps); + mutex_destroy(&inst->ubwc_stats_lock); mutex_destroy(&inst->sync_lock); mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); mutex_destroy(&inst->bufq[INPUT_PORT].lock); From 6d5c90a321c442bcdd809e108b96b7746e372b33 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 15 Apr 2020 20:13:54 +0530 Subject: [PATCH 269/452] msm: vidc: Remove support for noc error info registers on IRIS2 1pipe a. NOC error info registers are different for IRIS2_1 pipe HW to IRIS2 HW. FW can retrieve the same info without NOC error info registers. Hence removing the support to print NOC error info registers for lagoon. b. Since IRIS2 has noc error recovery enabled and same FW is used for IRIS2 and IRIS2_1 pipe, only printing NOC error info registers is disabled with out disabling noc error recovery. Change-Id: I936629e4f53faa5e25b2a64fb92378a26499ed57 Signed-off-by: Priyanka Gujjula --- msm/vidc/hfi_iris2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/msm/vidc/hfi_iris2.c b/msm/vidc/hfi_iris2.c index e64d842d8661..22a1e2db3ade 100644 --- a/msm/vidc/hfi_iris2.c +++ b/msm/vidc/hfi_iris2.c @@ -328,6 +328,8 @@ void __noc_error_info_iris2(struct venus_hfi_device *device) u32 val = 0; u32 sid = DEFAULT_SID; + if (device->res->vpu_ver == VPU_VERSION_IRIS2_1) + return; val = __read_register(device, VCODEC_NOC_ERL_MAIN_SWID_LOW, sid); d_vpr_e("VCODEC_NOC_ERL_MAIN_SWID_LOW: %#x\n", val); val = __read_register(device, VCODEC_NOC_ERL_MAIN_SWID_HIGH, sid); From 201523fbce41230f220122f2543cadafa7a07e6f Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Fri, 14 Feb 2020 13:38:31 +0530 Subject: [PATCH 270/452] msm: vidc: Skip AON register programming for IRIS2 1pipe AON register programming is used to set NOC to low power mode during IRIS2 power off sequence. However AON register memory map is not applicable and hence skipping AON register programming for lagoon. Change-Id: Ib63248d118ed9fecfa5fa87925e8f69625dc1ba8 Signed-off-by: Priyanka Gujjula --- msm/vidc/hfi_iris2.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/msm/vidc/hfi_iris2.c b/msm/vidc/hfi_iris2.c index e64d842d8661..e1e613d3e6cc 100644 --- a/msm/vidc/hfi_iris2.c +++ b/msm/vidc/hfi_iris2.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #include "msm_vidc_debug.h" @@ -189,6 +189,8 @@ void __power_off_iris2(struct venus_hfi_device *device) __write_register(device, CPU_CS_X2RPMh_IRIS2, 0x3, sid); /* HPG 6.1.2 Step 2, noc to low power */ + if (device->res->vpu_ver == VPU_VERSION_IRIS2_1) + goto skip_aon_mvp_noc; __write_register(device, AON_WRAPPER_MVP_NOC_LPI_CONTROL, 0x1, sid); while (!reg_status && count < max_count) { lpi_status = @@ -205,6 +207,7 @@ void __power_off_iris2(struct venus_hfi_device *device) } /* HPG 6.1.2 Step 3, debug bridge to low power */ +skip_aon_mvp_noc: __write_register(device, WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2, 0x7, sid); reg_status = 0; From 690e327f3079297f3667b9728ad473f117f1380d Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Tue, 4 Feb 2020 13:12:12 +0530 Subject: [PATCH 271/452] msm: vidc: remove usage of core 1 Remove usage of core 1 since there is no support of IRIS1. Change-Id: I5588b452455b592b8156ea4f46cb8e3171e14947 Signed-off-by: Dikshita Agarwal --- msm/vidc/hfi_common.c | 97 ++++++++++++++++------------------------ msm/vidc/hfi_io_common.h | 29 ++++++------ 2 files changed, 52 insertions(+), 74 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 997d92685e42..b2a964296e14 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -4045,74 +4045,53 @@ static int venus_hfi_get_core_capabilities(void *dev) return rc; } -static void __noc_error_info(struct venus_hfi_device *device, u32 core_num) +static void __noc_error_info_common(struct venus_hfi_device *device) { - u32 vcodec_core_video_noc_base_offs, val; + u32 val = 0; u32 sid = DEFAULT_SID; if (!device) { d_vpr_e("%s: null device\n", __func__); return; } - if (!core_num) { - vcodec_core_video_noc_base_offs = - VCODEC_CORE0_VIDEO_NOC_BASE_OFFS; - } else if (core_num == 1) { - vcodec_core_video_noc_base_offs = - VCODEC_CORE1_VIDEO_NOC_BASE_OFFS; - } else { - d_vpr_e("%s: invalid core_num %u\n", __func__, core_num); - return; - } - - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_SWID_LOW_OFFS, sid); - d_vpr_e("CORE%d_NOC_ERR_SWID_LOW: %#x\n", core_num, val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_SWID_HIGH_OFFS, sid); - d_vpr_e("CORE%d_NOC_ERR_SWID_HIGH: %#x\n", core_num, val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_MAINCTL_LOW_OFFS, sid); - d_vpr_e("CORE%d_NOC_ERR_MAINCTL_LOW: %#x\n", core_num, val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_LOW_OFFS, sid); - d_vpr_e("CORE%d_NOC_ERR_ERRLOG0_LOW: %#x\n", core_num, val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_HIGH_OFFS, sid); - d_vpr_e("CORE%d_NOC_ERR_ERRLOG0_HIGH: %#x\n", core_num, val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_LOW_OFFS, sid); - d_vpr_e("CORE%d_NOC_ERR_ERRLOG1_LOW: %#x\n", core_num, val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_HIGH_OFFS, sid); - d_vpr_e("CORE%d_NOC_ERR_ERRLOG1_HIGH: %#x\n", core_num, val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_LOW_OFFS, sid); - d_vpr_e("CORE%d_NOC_ERR_ERRLOG2_LOW: %#x\n", core_num, val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_HIGH_OFFS, sid); - d_vpr_e("CORE%d_NOC_ERR_ERRLOG2_HIGH: %#x\n", core_num, val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_LOW_OFFS, sid); - d_vpr_e("CORE%d_NOC_ERR_ERRLOG3_LOW: %#x\n", core_num, val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_HIGH_OFFS, sid); - d_vpr_e("CORE%d_NOC_ERR_ERRLOG3_HIGH: %#x\n", core_num, val); -} - -static void __noc_error_info_common(struct venus_hfi_device *device) -{ - const u32 core0 = 0, core1 = 1; if (__read_register(device, VCODEC_CORE0_VIDEO_NOC_BASE_OFFS + - VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS, - DEFAULT_SID)) - __noc_error_info(device, core0); - - if (__read_register(device, VCODEC_CORE1_VIDEO_NOC_BASE_OFFS + - VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS, - DEFAULT_SID)) - __noc_error_info(device, core1); + VCODEC_CORE0_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS, + DEFAULT_SID)) { + val = __read_register(device, VCODEC_CORE0_VIDEO_NOC_BASE_OFFS + + VCODEC_CORE0_VIDEO_NOC_ERR_SWID_LOW_OFFS, sid); + d_vpr_e("VCODEC_NOC_ERR_SWID_LOW: %#x\n", val); + val = __read_register(device, VCODEC_CORE0_VIDEO_NOC_BASE_OFFS + + VCODEC_CORE0_VIDEO_NOC_ERR_SWID_HIGH_OFFS, sid); + d_vpr_e("VCODEC_NOC_ERR_SWID_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_CORE0_VIDEO_NOC_BASE_OFFS + + VCODEC_CORE0_VIDEO_NOC_ERR_MAINCTL_LOW_OFFS, sid); + d_vpr_e("VCODEC_NOC_ERR_MAINCTL_LOW: %#x\n", val); + val = __read_register(device, VCODEC_CORE0_VIDEO_NOC_BASE_OFFS + + VCODEC_CORE0_VIDEO_NOC_ERR_ERRLOG0_LOW_OFFS, sid); + d_vpr_e("VCODEC_NOC_ERR_ERRLOG0_LOW: %#x\n", val); + val = __read_register(device, VCODEC_CORE0_VIDEO_NOC_BASE_OFFS + + VCODEC_CORE0_VIDEO_NOC_ERR_ERRLOG0_HIGH_OFFS, sid); + d_vpr_e("VCODEC_NOC_ERR_ERRLOG0_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_CORE0_VIDEO_NOC_BASE_OFFS + + VCODEC_CORE0_VIDEO_NOC_ERR_ERRLOG1_LOW_OFFS, sid); + d_vpr_e("VCODEC_NOC_ERR_ERRLOG1_LOW: %#x\n", val); + val = __read_register(device, VCODEC_CORE0_VIDEO_NOC_BASE_OFFS + + VCODEC_CORE0_VIDEO_NOC_ERR_ERRLOG1_HIGH_OFFS, sid); + d_vpr_e("VCODEC_NOC_ERR_ERRLOG1_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_CORE0_VIDEO_NOC_BASE_OFFS + + VCODEC_CORE0_VIDEO_NOC_ERR_ERRLOG2_LOW_OFFS, sid); + d_vpr_e("VCODEC_NOC_ERR_ERRLOG2_LOW: %#x\n", val); + val = __read_register(device, VCODEC_CORE0_VIDEO_NOC_BASE_OFFS + + VCODEC_CORE0_VIDEO_NOC_ERR_ERRLOG2_HIGH_OFFS, sid); + d_vpr_e("VCODEC_NOC_ERR_ERRLOG2_HIGH: %#x\n", val); + val = __read_register(device, VCODEC_CORE0_VIDEO_NOC_BASE_OFFS + + VCODEC_CORE0_VIDEO_NOC_ERR_ERRLOG3_LOW_OFFS, sid); + d_vpr_e("VCODEC_NOC_ERR_ERRLOG3_LOW: %#x\n", val); + val = __read_register(device, VCODEC_CORE0_VIDEO_NOC_BASE_OFFS + + VCODEC_CORE0_VIDEO_NOC_ERR_ERRLOG3_HIGH_OFFS, sid); + d_vpr_e("VCODEC_NOC_ERR_ERRLOG3_HIGH: %#x\n", val); + } } static int venus_hfi_noc_error_info(void *dev) diff --git a/msm/vidc/hfi_io_common.h b/msm/vidc/hfi_io_common.h index 2d42fdaa381e..d68555a9d10a 100644 --- a/msm/vidc/hfi_io_common.h +++ b/msm/vidc/hfi_io_common.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #ifndef __HFI_IO_COMMON_H__ @@ -122,18 +122,17 @@ * -------------------------------------------------------------------------- */ #define VCODEC_CORE0_VIDEO_NOC_BASE_OFFS 0x00004000 -#define VCODEC_CORE1_VIDEO_NOC_BASE_OFFS 0x0000C000 -#define VCODEC_COREX_VIDEO_NOC_ERR_SWID_LOW_OFFS 0x0500 -#define VCODEC_COREX_VIDEO_NOC_ERR_SWID_HIGH_OFFS 0x0504 -#define VCODEC_COREX_VIDEO_NOC_ERR_MAINCTL_LOW_OFFS 0x0508 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS 0x0510 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRCLR_LOW_OFFS 0x0518 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_LOW_OFFS 0x0520 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_HIGH_OFFS 0x0524 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_LOW_OFFS 0x0528 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_HIGH_OFFS 0x052C -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_LOW_OFFS 0x0530 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_HIGH_OFFS 0x0534 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_LOW_OFFS 0x0538 -#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_HIGH_OFFS 0x053C +#define VCODEC_CORE0_VIDEO_NOC_ERR_SWID_LOW_OFFS 0x0500 +#define VCODEC_CORE0_VIDEO_NOC_ERR_SWID_HIGH_OFFS 0x0504 +#define VCODEC_CORE0_VIDEO_NOC_ERR_MAINCTL_LOW_OFFS 0x0508 +#define VCODEC_CORE0_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS 0x0510 +#define VCODEC_CORE0_VIDEO_NOC_ERR_ERRCLR_LOW_OFFS 0x0518 +#define VCODEC_CORE0_VIDEO_NOC_ERR_ERRLOG0_LOW_OFFS 0x0520 +#define VCODEC_CORE0_VIDEO_NOC_ERR_ERRLOG0_HIGH_OFFS 0x0524 +#define VCODEC_CORE0_VIDEO_NOC_ERR_ERRLOG1_LOW_OFFS 0x0528 +#define VCODEC_CORE0_VIDEO_NOC_ERR_ERRLOG1_HIGH_OFFS 0x052C +#define VCODEC_CORE0_VIDEO_NOC_ERR_ERRLOG2_LOW_OFFS 0x0530 +#define VCODEC_CORE0_VIDEO_NOC_ERR_ERRLOG2_HIGH_OFFS 0x0534 +#define VCODEC_CORE0_VIDEO_NOC_ERR_ERRLOG3_LOW_OFFS 0x0538 +#define VCODEC_CORE0_VIDEO_NOC_ERR_ERRLOG3_HIGH_OFFS 0x053C #endif From 07430ccb145e588bba5ce33978e1dc0dcefce611 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 4 Mar 2020 19:39:40 +0530 Subject: [PATCH 272/452] msm: vidc: add support for enc_chroma_qp_offset [1] add support for HFI_PROPERTY_PARAM_HEVC_PPS_CB_CR_OFFSET [2] send (cb_qp_offset << 16 | cr_qp_offset) to firmware [3] default:0 and overridden: -12 [4] firmware will subtract 12 from driver sent value. 0 maps to 12 to fw and bitstream has 0 -12 maps to 0 to fw and bitstream has -12 Change-Id: I286c7088640349691930c95e9b176e4e748c669a Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_venc.c | 79 ++++++++++++++++++++++++++++++++++++++ msm/vidc/vidc_hfi_helper.h | 7 ++++ 2 files changed, 86 insertions(+) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index d67f7d9f683c..30f8c710d9a5 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -31,6 +31,9 @@ #define MAX_QP_PACKED 0x7F7F7F #define DEFAULT_QP 0xA #define DEFAULT_QP_PACKED 0xA0A0A +#define MIN_CHROMA_QP_OFFSET -12 +#define MAX_CHROMA_QP_OFFSET 0 +#define DEFAULT_CHROMA_QP_OFFSET 0 #define MAX_INTRA_REFRESH_MBS ((7680 * 4320) >> 8) #define MAX_LTR_FRAME_COUNT 10 #define MAX_NUM_B_FRAMES 1 @@ -917,6 +920,15 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { ), .qmenu = mpeg_video_stream_format, }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET, + .name = "Chroma QP Index Offset", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MIN_CHROMA_QP_OFFSET, + .maximum = MAX_CHROMA_QP_OFFSET, + .default_value = DEFAULT_CHROMA_QP_OFFSET, + .step = 1, + }, { .id = V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS, .name = "Enable/Disable bitrate savings", @@ -1982,6 +1994,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: case V4L2_CID_MPEG_VIDC_VENC_RC_TIMESTAMP_DISABLE: case V4L2_CID_MPEG_VIDEO_VBV_DELAY: + case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET: case V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS: case V4L2_CID_MPEG_VIDC_VENC_BITRATE_BOOST: case V4L2_CID_MPEG_VIDC_SUPERFRAME: @@ -3207,6 +3220,69 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst) return rc; } +int msm_venc_set_chroma_qp_offset(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *chr; + struct v4l2_ctrl *ctrl_cs; + struct hfi_chroma_qp_offset chroma_qp; + struct v4l2_format *f; + u32 codec, width, height, mbpf; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params %pK\n", __func__, inst); + return -EINVAL; + } + hdev = inst->core->device; + + chr = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET); + if (chr->val != MIN_CHROMA_QP_OFFSET) + return 0; + + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + width = f->fmt.pix_mp.width; + height = f->fmt.pix_mp.height; + mbpf = NUM_MBS_PER_FRAME(width, height); + ctrl_cs = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE); + codec = get_v4l2_codec(inst); + + /** + * Set chroma qp offset to HEVC & VBR_CFR rc + * 10 bit: only BT2020 + * 8 bit: only mbpf >= num_mbs(7680, 3840) + */ + if (codec != V4L2_PIX_FMT_HEVC || + inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) + return 0; + + if ((inst->bit_depth == MSM_VIDC_BIT_DEPTH_10 && + ctrl_cs->val != MSM_VIDC_BT2020) || + (inst->bit_depth == MSM_VIDC_BIT_DEPTH_8 && + mbpf < NUM_MBS_PER_FRAME(7680, 3840))) + return 0; + + /** + * client sets one chroma offset only in range [-12, 0] + * firmware expects chroma cb offset and cr offset in + * range [0, 12], firmware subtracts 12 from driver set values. + */ + chroma_qp.chroma_offset = (chr->val + 12) << 16 | (chr->val + 12); + s_vpr_h(inst->sid, "%s: %x\n", __func__, chroma_qp.chroma_offset); + + /* TODO: Remove this check after firmware support added for 8-bit */ + if (inst->bit_depth == MSM_VIDC_BIT_DEPTH_8) + return 0; + + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_HEVC_PPS_CB_CR_OFFSET, &chroma_qp, + sizeof(chroma_qp)); + if (rc) + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); + + return rc; +} + int msm_venc_set_bitrate_savings_mode(struct msm_vidc_inst *inst) { int rc = 0; @@ -4617,6 +4693,9 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) * than blur. */ rc = msm_venc_set_rotation(inst); + if (rc) + goto exit; + rc = msm_venc_set_chroma_qp_offset(inst); if (rc) goto exit; rc = msm_venc_set_blur_resolution(inst); diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index e6b733b9aaeb..accdcdff8a16 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -336,6 +336,8 @@ struct hfi_buffer_info { (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x038) #define HFI_PROPERTY_PARAM_VENC_LOSSLESS_ENCODING \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x039) +#define HFI_PROPERTY_PARAM_HEVC_PPS_CB_CR_OFFSET \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x040) #define HFI_PROPERTY_PARAM_VENC_BITRATE_BOOST \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x041) @@ -506,6 +508,11 @@ struct hfi_operating_rate { u32 operating_rate; }; +struct hfi_chroma_qp_offset { + u32 chroma_offset; + u32 reserved; +}; + #define HFI_INTRA_REFRESH_NONE (HFI_COMMON_BASE + 0x1) #define HFI_INTRA_REFRESH_CYCLIC (HFI_COMMON_BASE + 0x2) #define HFI_INTRA_REFRESH_RANDOM (HFI_COMMON_BASE + 0x5) From ec7ac2c5f2fd5c338159eb891bc349d7fd81ad3b Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Thu, 9 Apr 2020 23:07:42 +0530 Subject: [PATCH 273/452] msm:vidc: Modify input buffer size calculation calculate buffer size as per the max resolution for the targets that does not support 4k and also ensure the size is equal to YUV size by overriding the div factor to 1. Change-Id: Ia63676d30d1ee1e697518780a03a48010380555d Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_buffer_calculations.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 54769c46afeb..b17c8a1ebb0f 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -845,6 +845,18 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) div_factor = 2; } + if (is_secure_session(inst)) + div_factor = div_factor << 1; + + /* + * For targets that doesn't support 4k, consider max mb's for that + * target and allocate max input buffer size for the same + */ + if (base_res_mbs > inst->capability.cap[CAP_MBS_PER_FRAME].max) { + base_res_mbs = inst->capability.cap[CAP_MBS_PER_FRAME].max; + div_factor = 1; + } + frame_size = base_res_mbs * MB_SIZE_IN_PIXEL * 3 / 2 / div_factor; /* multiply by 10/8 (1.25) to get size for 10 bit case */ @@ -852,9 +864,6 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_HEVC)) frame_size = frame_size + (frame_size >> 2); - if (is_secure_session(inst)) - frame_size /= 2; - if (inst->buffer_size_limit && (inst->buffer_size_limit < frame_size)) { frame_size = inst->buffer_size_limit; From 9f4d365098de7e3cd117ed0f6f154076888d999d Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 18 Dec 2019 17:00:22 +0530 Subject: [PATCH 274/452] msm: vidc: keep memory_size_limit check for new session do not allow to open new session, if total video consumed memory is beyond allowed memory_size_max_limit for video. Change-Id: I6bfade01f99bae24691254744adf7ce38de51fdd Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc.c | 16 +- msm/vidc/msm_vidc_common.c | 320 ++++++++++++++++++++++++++++++---- msm/vidc/msm_vidc_common.h | 14 ++ msm/vidc/msm_vidc_res_parse.c | 12 ++ msm/vidc/msm_vidc_resources.h | 7 + 5 files changed, 336 insertions(+), 33 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index c57faf865f41..3ddbf614ea43 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -825,8 +825,15 @@ static inline int start_streaming(struct msm_vidc_inst *inst) b.buffer_type = HFI_BUFFER_OUTPUT; if (inst->session_type == MSM_VIDC_DECODER && - is_secondary_output_mode(inst)) + is_secondary_output_mode(inst)) { b.buffer_type = HFI_BUFFER_OUTPUT2; + rc = msm_comm_update_dpb_bufreqs(inst); + if (rc) { + s_vpr_e(inst->sid, + "%s: set dpb bufreq failed\n", __func__); + goto fail_start; + } + } /* Check if current session is under HW capability */ rc = msm_vidc_check_session_supported(inst); @@ -868,6 +875,13 @@ static inline int start_streaming(struct msm_vidc_inst *inst) rc = msm_comm_try_get_bufreqs(inst); + rc = msm_comm_check_memory_supported(inst); + if (rc) { + s_vpr_e(inst->sid, + "Memory not sufficient to proceed current session\n"); + goto fail_start; + } + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; b.buffer_size = f->fmt.pix_mp.plane_fmt[0].sizeimage; rc = call_hfi_op(hdev, session_set_property, diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index ccb26795b592..f34957431023 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -3163,6 +3163,185 @@ static int msm_comm_session_init(int flipped_state, return rc; } +int msm_comm_update_dpb_bufreqs(struct msm_vidc_inst *inst) +{ + struct hal_buffer_requirements *req = NULL; + struct msm_vidc_format *fmt; + struct v4l2_format *f; + u32 i, hfi_fmt, rc = 0; + + if (!inst) { + d_vpr_e("%s: invalid parameters\n", __func__); + return -EINVAL; + } + + if (msm_comm_get_stream_output_mode(inst) != + HAL_VIDEO_DECODER_SECONDARY) + return 0; + + for (i = 0; i < HAL_BUFFER_MAX; i++) { + if (inst->buff_req.buffer[i].buffer_type == HAL_BUFFER_OUTPUT) { + req = &inst->buff_req.buffer[i]; + break; + } + } + + if (!req) { + s_vpr_e(inst->sid, "%s: req not found\n", __func__); + return -EINVAL; + } + + fmt = &inst->fmts[OUTPUT_PORT]; + /* For DPB buffers, Always use min count */ + req->buffer_count_actual = fmt->count_min; + + hfi_fmt = msm_comm_convert_color_fmt(inst->clk_data.dpb_fourcc, + inst->sid); + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + req->buffer_size = VENUS_BUFFER_SIZE(hfi_fmt, f->fmt.pix_mp.width, + f->fmt.pix_mp.height); + + return rc; +} + +static int msm_comm_get_dpb_bufreqs(struct msm_vidc_inst *inst, + struct hal_buffer_requirements *req) +{ + struct hal_buffer_requirements *dpb = NULL; + u32 i; + + if (!inst || !req) { + d_vpr_e("%s: invalid parameters\n", __func__); + return -EINVAL; + } + + if (msm_comm_get_stream_output_mode(inst) != + HAL_VIDEO_DECODER_SECONDARY) + return 0; + + for (i = 0; i < HAL_BUFFER_MAX; i++) { + if (inst->buff_req.buffer[i].buffer_type == HAL_BUFFER_OUTPUT) { + dpb = &inst->buff_req.buffer[i]; + break; + } + } + + if (!dpb) { + s_vpr_e(inst->sid, "%s: req not found\n", __func__); + return -EINVAL; + } + + memcpy(req, dpb, sizeof(struct hal_buffer_requirements)); + + return 0; +} + +static void msm_comm_print_mem_usage(struct msm_vidc_core *core) +{ + struct msm_vidc_inst *inst; + struct msm_vidc_format *inp_f, *out_f; + u32 dpb_cnt, dpb_size, i = 0, rc = 0; + struct v4l2_pix_format_mplane *iplane, *oplane; + u32 sz_i, sz_i_e, sz_o, sz_o_e, sz_s, sz_s1, sz_s2, sz_p, sz_p1, sz_r; + u32 cnt_i, cnt_o, cnt_s, cnt_s1, cnt_s2, cnt_p, cnt_p1, cnt_r; + u64 total; + + d_vpr_e("Running instances - mem breakup:\n"); + d_vpr_e( + "%4s|%4s|%24s|%24s|%24s|%24s|%24s|%10s|%10s|%10s|%10s|%10s|%10s|%10s\n", + "w", "h", "in", "extra_in", "out", "extra_out", + "out2", "scratch", "scratch_1", "scratch_2", + "persist", "persist_1", "recon", "total_kb"); + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) { + dpb_cnt = dpb_size = total = 0; + sz_s = sz_s1 = sz_s2 = sz_p = sz_p1 = sz_r = 0; + cnt_s = cnt_s1 = cnt_s2 = cnt_p = cnt_p1 = cnt_r = 0; + + inp_f = &inst->fmts[INPUT_PORT]; + out_f = &inst->fmts[OUTPUT_PORT]; + iplane = &inp_f->v4l2_fmt.fmt.pix_mp; + oplane = &out_f->v4l2_fmt.fmt.pix_mp; + + if (msm_comm_get_stream_output_mode(inst) == + HAL_VIDEO_DECODER_SECONDARY) { + struct hal_buffer_requirements dpb = {0}; + + rc = msm_comm_get_dpb_bufreqs(inst, &dpb); + if (rc) { + s_vpr_e(inst->sid, + "%s: get dpb bufreq failed\n", + __func__); + goto error; + } + dpb_cnt = dpb.buffer_count_actual; + dpb_size = dpb.buffer_size; + } + for (i = 0; i < HAL_BUFFER_MAX; i++) { + struct hal_buffer_requirements *req; + + req = &inst->buff_req.buffer[i]; + switch (req->buffer_type) { + case HAL_BUFFER_INTERNAL_SCRATCH: + sz_s = req->buffer_size; + cnt_s = req->buffer_count_actual; + break; + case HAL_BUFFER_INTERNAL_SCRATCH_1: + sz_s1 = req->buffer_size; + cnt_s1 = req->buffer_count_actual; + break; + case HAL_BUFFER_INTERNAL_SCRATCH_2: + sz_s2 = req->buffer_size; + cnt_s2 = req->buffer_count_actual; + break; + case HAL_BUFFER_INTERNAL_PERSIST: + sz_p = req->buffer_size; + cnt_p = req->buffer_count_actual; + break; + case HAL_BUFFER_INTERNAL_PERSIST_1: + sz_p1 = req->buffer_size; + cnt_p1 = req->buffer_count_actual; + break; + case HAL_BUFFER_INTERNAL_RECON: + sz_r = req->buffer_size; + cnt_r = req->buffer_count_actual; + break; + default: + break; + } + } + sz_i = iplane->plane_fmt[0].sizeimage; + sz_i_e = iplane->plane_fmt[1].sizeimage; + cnt_i = inp_f->count_min_host; + + sz_o = oplane->plane_fmt[0].sizeimage; + sz_o_e = oplane->plane_fmt[1].sizeimage; + cnt_o = out_f->count_min_host; + + total = sz_i * cnt_i + sz_i_e * cnt_i + sz_o * cnt_o + + sz_o_e * cnt_o + dpb_cnt * dpb_size + sz_s * cnt_s + + sz_s1 * cnt_s1 + sz_s2 * cnt_s2 + sz_p * cnt_p + + sz_p1 * cnt_p1 + sz_r * cnt_r; + total = total >> 10; + + s_vpr_e(inst->sid, + "%4d|%4d|%11u(%8ux%2u)|%11u(%8ux%2u)|%11u(%8ux%2u)|%11u(%8ux%2u)|%11u(%8ux%2u)|%10u|%10u|%10u|%10u|%10u|%10u|%10llu\n", + max(iplane->width, oplane->width), + max(iplane->height, oplane->height), + sz_i * cnt_i, sz_i, cnt_i, + sz_i_e * cnt_i, sz_i_e, cnt_i, + sz_o * cnt_o, sz_o, cnt_o, + sz_o_e * cnt_o, sz_o_e, cnt_o, + dpb_size * dpb_cnt, dpb_size, dpb_cnt, + sz_s * cnt_s, sz_s1 * cnt_s1, + sz_s2 * cnt_s2, sz_p * cnt_p, sz_p1 * cnt_p1, + sz_r * cnt_r, total); + } +error: + mutex_unlock(&core->lock); + +} + static void msm_vidc_print_running_insts(struct msm_vidc_core *core) { struct msm_vidc_inst *temp; @@ -3542,27 +3721,26 @@ static int set_dpb_only_buffers(struct msm_vidc_inst *inst, { int rc = 0; struct internal_buf *binfo = NULL; - u32 smem_flags = SMEM_UNCACHED, buffer_size, num_buffers, hfi_fmt; - struct msm_vidc_format *fmt; + u32 smem_flags = SMEM_UNCACHED, buffer_size = 0, num_buffers = 0; unsigned int i; struct hfi_device *hdev; struct hfi_buffer_size_minimum b; struct v4l2_format *f; + struct hal_buffer_requirements dpb = {0}; hdev = inst->core->device; - fmt = &inst->fmts[OUTPUT_PORT]; + rc = msm_comm_get_dpb_bufreqs(inst, &dpb); + if (rc) { + s_vpr_e(inst->sid, "Couldn't retrieve dpb count & size\n"); + return -EINVAL; + } + num_buffers = dpb.buffer_count_actual; + buffer_size = dpb.buffer_size; + s_vpr_h(inst->sid, "dpb: cnt = %d, size = %d\n", + num_buffers, buffer_size); - /* For DPB buffers, Always use min count */ - num_buffers = fmt->count_min; - hfi_fmt = msm_comm_convert_color_fmt(inst->clk_data.dpb_fourcc, - inst->sid); f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; - buffer_size = VENUS_BUFFER_SIZE(hfi_fmt, f->fmt.pix_mp.width, - f->fmt.pix_mp.height); - s_vpr_h(inst->sid, "output: num = %d, size = %d\n", - num_buffers, - buffer_size); b.buffer_type = get_hfi_buffer(buffer_type, inst->sid); if (!b.buffer_type) @@ -4645,14 +4823,6 @@ int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst) { int rc = -EINVAL, i = 0; union hal_get_property hprop; - enum hal_buffer int_buf[] = { - HAL_BUFFER_INTERNAL_SCRATCH, - HAL_BUFFER_INTERNAL_SCRATCH_1, - HAL_BUFFER_INTERNAL_SCRATCH_2, - HAL_BUFFER_INTERNAL_PERSIST, - HAL_BUFFER_INTERNAL_PERSIST_1, - HAL_BUFFER_INTERNAL_RECON, - }; memset(&hprop, 0x0, sizeof(hprop)); /* @@ -4681,8 +4851,13 @@ int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst) } /* reset internal buffers */ - for (i = 0; i < ARRAY_SIZE(int_buf); i++) - msm_comm_reset_bufreqs(inst, int_buf[i]); + for (i = 0; i < HAL_BUFFER_MAX; i++) { + struct hal_buffer_requirements *req; + + req = &inst->buff_req.buffer[i]; + if (is_internal_buffer(req->buffer_type)) + msm_comm_reset_bufreqs(inst, req->buffer_type); + } for (i = 0; i < HAL_BUFFER_MAX; i++) { struct hal_buffer_requirements req; @@ -4698,16 +4873,7 @@ int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst) if (!curr_req) return -EINVAL; - if (req.buffer_type == HAL_BUFFER_INTERNAL_SCRATCH || - req.buffer_type == - HAL_BUFFER_INTERNAL_SCRATCH_1 || - req.buffer_type == - HAL_BUFFER_INTERNAL_SCRATCH_2 || - req.buffer_type == - HAL_BUFFER_INTERNAL_PERSIST || - req.buffer_type == - HAL_BUFFER_INTERNAL_PERSIST_1 || - req.buffer_type == HAL_BUFFER_INTERNAL_RECON) { + if (is_internal_buffer(req.buffer_type)) { memcpy(curr_req, &req, sizeof(struct hal_buffer_requirements)); } @@ -5523,6 +5689,96 @@ static int msm_vidc_check_mbpf_supported(struct msm_vidc_inst *inst) return 0; } +static u32 msm_comm_get_memory_limit(struct msm_vidc_core *core) +{ + struct memory_limit_table *memory_limits_tbl; + u32 memory_limits_tbl_size = 0; + u32 memory_limit = 0, memory_size = 0; + u32 memory_limit_mbytes = 0; + int i = 0; + + memory_limits_tbl = core->resources.mem_limit_tbl; + memory_limits_tbl_size = core->resources.memory_limit_table_size; + memory_limit_mbytes = ((u64)totalram_pages * PAGE_SIZE) >> 20; + for (i = memory_limits_tbl_size - 1; i >= 0; i--) { + memory_size = memory_limits_tbl[i].ddr_size; + memory_limit = memory_limits_tbl[i].mem_limit; + if (memory_size >= memory_limit_mbytes) + break; + } + + return memory_limit; +} + +int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst) +{ + struct msm_vidc_core *core; + struct msm_vidc_inst *inst; + struct msm_vidc_format *fmt; + struct v4l2_format *f; + struct hal_buffer_requirements *req; + u32 i, dpb_cnt = 0, dpb_size = 0, rc = 0; + u64 mem_size = 0; + u32 memory_limit_mbytes; + + core = vidc_inst->core; + + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) { + /* input port buffers memory size */ + fmt = &inst->fmts[INPUT_PORT]; + f = &fmt->v4l2_fmt; + for (i = 0; i < f->fmt.pix_mp.num_planes; i++) + mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage * + fmt->count_min_host; + + /* output port buffers memory size */ + fmt = &inst->fmts[OUTPUT_PORT]; + f = &fmt->v4l2_fmt; + for (i = 0; i < f->fmt.pix_mp.num_planes; i++) + mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage * + fmt->count_min_host; + + /* dpb buffers memory size */ + if (msm_comm_get_stream_output_mode(inst) == + HAL_VIDEO_DECODER_SECONDARY) { + struct hal_buffer_requirements dpb = {0}; + + rc = msm_comm_get_dpb_bufreqs(inst, &dpb); + if (rc) { + s_vpr_e(inst->sid, + "Couldn't retrieve dpb count & size\n"); + mutex_unlock(&core->lock); + return rc; + } + dpb_cnt = dpb.buffer_count_actual; + dpb_size = dpb.buffer_size; + mem_size += dpb_cnt * dpb_size; + } + + /* internal buffers memory size */ + for (i = 0; i < HAL_BUFFER_MAX; i++) { + req = &inst->buff_req.buffer[i]; + if (is_internal_buffer(req->buffer_type)) + mem_size += req->buffer_size * + req->buffer_count_actual; + } + } + mutex_unlock(&core->lock); + + memory_limit_mbytes = msm_comm_get_memory_limit(core); + + if ((mem_size >> 20) > memory_limit_mbytes) { + s_vpr_e(vidc_inst->sid, + "%s: video mem overshoot - reached %llu MB, max_limit %llu MB\n", + __func__, mem_size >> 20, memory_limit_mbytes); + msm_comm_print_mem_usage(core); + return -EBUSY; + } + + return 0; +} + static int msm_vidc_check_mbps_supported(struct msm_vidc_inst *inst) { int num_mbs_per_sec = 0, max_load_adj = 0; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 35b6887252ae..2e95871b9dd9 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -162,6 +162,18 @@ static inline bool is_output_buffer(struct msm_vidc_buffer *mbuf) return mbuf->vvb.vb2_buf.type == OUTPUT_MPLANE; } +static inline bool is_internal_buffer(enum hal_buffer type) +{ + u32 buf_type = + HAL_BUFFER_INTERNAL_SCRATCH | + HAL_BUFFER_INTERNAL_SCRATCH_1 | + HAL_BUFFER_INTERNAL_SCRATCH_2 | + HAL_BUFFER_INTERNAL_PERSIST | + HAL_BUFFER_INTERNAL_PERSIST_1 | + HAL_BUFFER_INTERNAL_RECON; + return !!(buf_type & type); +} + static inline int msm_comm_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl) { @@ -342,4 +354,6 @@ u32 msm_comm_calc_framerate(struct msm_vidc_inst *inst, u64 timestamp_us, int msm_comm_memory_prefetch(struct msm_vidc_inst *inst); int msm_comm_memory_drain(struct msm_vidc_inst *inst); int msm_comm_check_prefetch_sufficient(struct msm_vidc_inst *inst); +int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst); +int msm_comm_update_dpb_bufreqs(struct msm_vidc_inst *inst); #endif diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 993c6283513a..a8d6edf0ce57 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -15,6 +15,15 @@ enum clock_properties { CLOCK_PROP_HAS_MEM_RETENTION = 1 << 1, }; +static struct memory_limit_table memory_limit_tbl_mbytes[] = { + /* target_memory_size - max_video_cap */ + {12288, 4096}, /* 12 GB - 4 Gb*/ + {8192, 3584}, /* 8 GB - 3.5 Gb*/ + {6144, 2560}, /* 6 GB - 2.5 Gb*/ + {4096, 1536}, /* 4 GB - 1.5 Gb*/ + {2048, 768}, /* 2 GB - 0.75 Gb*/ +}; + static inline struct device *msm_iommu_get_ctx(const char *ctx_name) { return NULL; @@ -741,6 +750,9 @@ int read_platform_resources_from_drv_data( res->codec_data = platform_data->codec_data; res->sku_version = platform_data->sku_version; + res->mem_limit_tbl = memory_limit_tbl_mbytes; + res->memory_limit_table_size = + ARRAY_SIZE(memory_limit_tbl_mbytes); res->max_load = find_key_value(platform_data, "qcom,max-hw-load"); diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 8474decd2d9a..5cea98cad011 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -103,6 +103,11 @@ struct allowed_clock_rates_table { u32 clock_rate; }; +struct memory_limit_table { + u32 ddr_size; /* mega bytes */ + u32 mem_limit; /* mega bytes */ +}; + struct clock_profile_entry { u32 codec_mask; u32 vpp_cycles; @@ -140,6 +145,8 @@ struct msm_vidc_platform_resources { struct allowed_clock_rates_table *allowed_clks_tbl; u32 allowed_clks_tbl_size; struct clock_freq_table clock_freq_tbl; + struct memory_limit_table *mem_limit_tbl; + u32 memory_limit_table_size; bool sys_cache_present; bool sys_cache_res_set; struct subcache_set subcache_set; From 809cf3a2e5c0d36bfb81549f44cf0c3d6b60e61b Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Thu, 5 Mar 2020 20:29:04 +0530 Subject: [PATCH 275/452] msm: vidc: restrict non_secure iova usage check total non_secure memory usage, reject the new non-secure session, if total non-secure memory usage exceeds the non-secure region size. Change-Id: I2b0aaae061e5b022237a4c49c66e92461fb40fca Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_common.c | 2 ++ msm/vidc/msm_smem.c | 2 ++ msm/vidc/msm_v4l2_vidc.c | 2 ++ msm/vidc/msm_vidc_common.c | 56 ++++++++++++++++++++++++++++++----- msm/vidc/msm_vidc_common.h | 1 + msm/vidc/msm_vidc_res_parse.c | 14 ++++----- msm/vidc/msm_vidc_resources.h | 1 + 7 files changed, 63 insertions(+), 15 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index b2a964296e14..88dd892ded14 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -3397,6 +3397,7 @@ static int __protect_cp_mem(struct venus_hfi_device *device) memprot.cp_nonpixel_start = 0x0; memprot.cp_nonpixel_size = 0x0; + mutex_lock(&device->res->cb_lock); list_for_each_entry(cb, &device->res->context_banks, list) { if (!strcmp(cb->name, "venus_ns")) { memprot.cp_size = cb->addr_range.start; @@ -3414,6 +3415,7 @@ static int __protect_cp_mem(struct venus_hfi_device *device) memprot.cp_nonpixel_size); } } + mutex_unlock(&device->res->cb_lock); rc = qcom_scm_mem_protect_video(memprot.cp_start, memprot.cp_size, memprot.cp_nonpixel_start, memprot.cp_nonpixel_size); diff --git a/msm/vidc/msm_smem.c b/msm/vidc/msm_smem.c index 4d326ab0bea5..4688aa9717a3 100644 --- a/msm/vidc/msm_smem.c +++ b/msm/vidc/msm_smem.c @@ -583,6 +583,7 @@ struct context_bank_info *msm_smem_get_context_bank(u32 session_type, buffer_type = HAL_BUFFER_INTERNAL_PERSIST_1; } + mutex_lock(&res->cb_lock); list_for_each_entry(cb, &res->context_banks, list) { if (cb->is_secure == is_secure && cb->buffer_type & buffer_type) { @@ -590,6 +591,7 @@ struct context_bank_info *msm_smem_get_context_bank(u32 session_type, break; } } + mutex_unlock(&res->cb_lock); if (!match) s_vpr_e(sid, "%s: cb not found for buffer_type %x, is_secure %d\n", diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index 1bf40ea95347..fb4aca41fcbd 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -289,6 +289,7 @@ static int msm_vidc_initialize_core(struct platform_device *pdev, INIT_LIST_HEAD(&core->instances); mutex_init(&core->lock); + mutex_init(&core->resources.cb_lock); core->state = VIDC_CORE_UNINIT; for (i = SYS_MSG_INDEX(SYS_MSG_START); @@ -644,6 +645,7 @@ static int msm_vidc_remove(struct platform_device *pdev) msm_vidc_free_platform_resources(&core->resources); sysfs_remove_group(&pdev->dev.kobj, &msm_vidc_core_attr_group); dev_set_drvdata(&pdev->dev, NULL); + mutex_destroy(&core->resources.cb_lock); mutex_destroy(&core->lock); kfree(core); return rc; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index f34957431023..0edf1ad8913f 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5717,26 +5717,29 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst) struct msm_vidc_format *fmt; struct v4l2_format *f; struct hal_buffer_requirements *req; + struct context_bank_info *cb = NULL; u32 i, dpb_cnt = 0, dpb_size = 0, rc = 0; - u64 mem_size = 0; + u32 inst_mem_size, non_sec_cb_size = 0; + u64 total_mem_size = 0, non_sec_mem_size = 0; u32 memory_limit_mbytes; core = vidc_inst->core; mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { + inst_mem_size = 0; /* input port buffers memory size */ fmt = &inst->fmts[INPUT_PORT]; f = &fmt->v4l2_fmt; for (i = 0; i < f->fmt.pix_mp.num_planes; i++) - mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage * + inst_mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage * fmt->count_min_host; /* output port buffers memory size */ fmt = &inst->fmts[OUTPUT_PORT]; f = &fmt->v4l2_fmt; for (i = 0; i < f->fmt.pix_mp.num_planes; i++) - mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage * + inst_mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage * fmt->count_min_host; /* dpb buffers memory size */ @@ -5753,29 +5756,49 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst) } dpb_cnt = dpb.buffer_count_actual; dpb_size = dpb.buffer_size; - mem_size += dpb_cnt * dpb_size; + inst_mem_size += dpb_cnt * dpb_size; } /* internal buffers memory size */ for (i = 0; i < HAL_BUFFER_MAX; i++) { req = &inst->buff_req.buffer[i]; if (is_internal_buffer(req->buffer_type)) - mem_size += req->buffer_size * + inst_mem_size += req->buffer_size * req->buffer_count_actual; } + + if (!is_secure_session(inst)) + non_sec_mem_size += inst_mem_size; + total_mem_size += inst_mem_size; } mutex_unlock(&core->lock); memory_limit_mbytes = msm_comm_get_memory_limit(core); - if ((mem_size >> 20) > memory_limit_mbytes) { + if ((total_mem_size >> 20) > memory_limit_mbytes) { s_vpr_e(vidc_inst->sid, "%s: video mem overshoot - reached %llu MB, max_limit %llu MB\n", - __func__, mem_size >> 20, memory_limit_mbytes); - msm_comm_print_mem_usage(core); + __func__, total_mem_size >> 20, memory_limit_mbytes); + msm_comm_print_insts_info(core); return -EBUSY; } + if (!is_secure_session(vidc_inst)) { + mutex_lock(&core->resources.cb_lock); + list_for_each_entry(cb, &core->resources.context_banks, list) + if (!cb->is_secure) + non_sec_cb_size = cb->addr_range.size; + mutex_unlock(&core->resources.cb_lock); + + if (non_sec_mem_size > non_sec_cb_size) { + s_vpr_e(vidc_inst->sid, + "%s: insufficient device addr space, required %llu, available %llu\n", + __func__, non_sec_mem_size, non_sec_cb_size); + msm_comm_print_insts_info(core); + return -EINVAL; + } + } + return 0; } @@ -6284,6 +6307,23 @@ void msm_comm_print_inst_info(struct msm_vidc_inst *inst) mutex_unlock(&inst->outputbufs.lock); } +void msm_comm_print_insts_info(struct msm_vidc_core *core) +{ + struct msm_vidc_inst *inst = NULL; + + if (!core) { + d_vpr_e("%s: invalid params\n", __func__); + return; + } + + msm_comm_print_mem_usage(core); + + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) + msm_comm_print_inst_info(inst); + mutex_unlock(&core->lock); +} + int msm_comm_session_continue(void *instance) { struct msm_vidc_inst *inst = instance; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 2e95871b9dd9..124edf58c036 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -273,6 +273,7 @@ int msm_comm_ctrl_deinit(struct msm_vidc_inst *inst); void msm_comm_cleanup_internal_buffers(struct msm_vidc_inst *inst); bool msm_comm_turbo_session(struct msm_vidc_inst *inst); void msm_comm_print_inst_info(struct msm_vidc_inst *inst); +void msm_comm_print_insts_info(struct msm_vidc_core *core); int msm_comm_v4l2_to_hfi(int id, int value, u32 sid); int msm_comm_hfi_to_v4l2(int id, int value, u32 sid); int msm_comm_get_v4l2_profile(int fourcc, int profile, u32 sid); diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index a8d6edf0ce57..82343b0ae837 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -850,7 +850,6 @@ int read_platform_resources_from_dt( if (rc) return rc; - INIT_LIST_HEAD(&res->context_banks); res->firmware_base = (phys_addr_t)firmware_base; @@ -989,7 +988,6 @@ int msm_vidc_smmu_fault_handler(struct iommu_domain *domain, struct device *dev, unsigned long iova, int flags, void *token) { struct msm_vidc_core *core = token; - struct msm_vidc_inst *inst; if (!domain || !core) { d_vpr_e("%s: invalid params %pK %pK\n", @@ -1008,12 +1006,8 @@ int msm_vidc_smmu_fault_handler(struct iommu_domain *domain, d_vpr_e("%s: faulting address: %lx\n", __func__, iova); - mutex_lock(&core->lock); - list_for_each_entry(inst, &core->instances, list) { - msm_comm_print_inst_info(inst); - } core->smmu_fault_handled = true; - mutex_unlock(&core->lock); + msm_comm_print_insts_info(core); /* * Return -EINVAL to elicit the default behaviour of smmu driver. * If we return -EINVAL, then smmu driver assumes page fault handler @@ -1043,7 +1037,10 @@ static int msm_vidc_populate_context_bank(struct device *dev, } INIT_LIST_HEAD(&cb->list); + + mutex_lock(&core->resources.cb_lock); list_add_tail(&cb->list, &core->resources.context_banks); + mutex_unlock(&core->resources.cb_lock); rc = of_property_read_string(np, "label", &cb->name); if (rc) { @@ -1123,7 +1120,10 @@ static int msm_vidc_populate_legacy_context_bank( return -ENOMEM; } INIT_LIST_HEAD(&cb->list); + + mutex_lock(&res->cb_lock); list_add_tail(&cb->list, &res->context_banks); + mutex_unlock(&res->cb_lock); ctx_node = of_parse_phandle(domains_child_node, "qcom,vidc-domain-phandle", 0); diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 5cea98cad011..a192430bbabe 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -167,6 +167,7 @@ struct msm_vidc_platform_resources { bool sw_power_collapsible; bool slave_side_cp; struct list_head context_banks; + struct mutex cb_lock; bool thermal_mitigable; const char *fw_name; const char *hfi_version; From 343e1966ff029444aed563f0515422aa010c68eb Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Sat, 14 Mar 2020 15:46:28 +0530 Subject: [PATCH 276/452] msm: vidc: update dpb buffer requirements buffer counts(min_cnt, min_host, actual_cnt) is updated in hal_buffer_requirements only for internal buffers. Currently for dpb, we are updating only actual_cnt, due to that msm_vidc_verify_buffer_counts check is failing. So updated all 3 variables (min_cnt, min_host, actual) for dpb. Change-Id: Ib6e476fae57407a2b5fb55b1b73986dfca410ae6 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 0edf1ad8913f..90a4d7931aed 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -3193,6 +3193,7 @@ int msm_comm_update_dpb_bufreqs(struct msm_vidc_inst *inst) fmt = &inst->fmts[OUTPUT_PORT]; /* For DPB buffers, Always use min count */ + req->buffer_count_min = req->buffer_count_min_host = req->buffer_count_actual = fmt->count_min; hfi_fmt = msm_comm_convert_color_fmt(inst->clk_data.dpb_fourcc, From 5b0dfe97c89b2a3e549f6cd6dc7c43bbd9cbbc71 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Thu, 9 Apr 2020 13:18:08 +0800 Subject: [PATCH 277/452] msm: vidc: fix dpb buffer count validation Shouldn't use count_min to validate dpb buffer count, as it has already been modified when received seq change event. Use dpb buffer_count_actual instead. Change-Id: Iad4117e4d0045859312d726caae1c8801ba1b897 Signed-off-by: Qiwei Liu Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_common.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 90a4d7931aed..3b4587f375d6 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1911,9 +1911,19 @@ void msm_comm_validate_output_buffers(struct msm_vidc_inst *inst) { struct internal_buf *binfo; u32 buffers_owned_by_driver = 0; - struct msm_vidc_format *fmt; + struct hal_buffer_requirements *dpb = NULL; + u32 i; - fmt = &inst->fmts[OUTPUT_PORT]; + for (i = 0; i < HAL_BUFFER_MAX; i++) { + if (inst->buff_req.buffer[i].buffer_type == HAL_BUFFER_OUTPUT) { + dpb = &inst->buff_req.buffer[i]; + break; + } + } + if (!dpb) { + s_vpr_e(inst->sid, "Couldn't retrieve dpb buf req\n"); + return; + } mutex_lock(&inst->outputbufs.lock); if (list_empty(&inst->outputbufs.list)) { @@ -1932,11 +1942,10 @@ void msm_comm_validate_output_buffers(struct msm_vidc_inst *inst) } mutex_unlock(&inst->outputbufs.lock); - /* Only minimum number of DPBs are allocated */ - if (buffers_owned_by_driver != fmt->count_min) { - s_vpr_e(inst->sid, "OUTPUT Buffer count mismatch %d of %d\n", + if (buffers_owned_by_driver != dpb->buffer_count_actual) { + s_vpr_e(inst->sid, "DPB buffer count mismatch %d of %d\n", buffers_owned_by_driver, - fmt->count_min); + dpb->buffer_count_actual); msm_vidc_handle_hw_error(inst->core); } } From 8eaf9d9bc8d9eb1d60f80da484e00f7ff91d5da1 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Sun, 5 Apr 2020 16:33:43 +0530 Subject: [PATCH 278/452] msm: vidc: add active session check for clk and bus vote calculation After couple of buffer transaction, sometimes session will be idle, So do not consider inactive sessions for clk scaling and bus vote calculation. Change-Id: Ib4cc7606da6c828ce1d9108528a2cbbad4e5f6e4 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc.c | 3 +++ msm/vidc/msm_vidc_clocks.c | 38 ++++++++++++++++++++++++++++++++++++ msm/vidc/msm_vidc_internal.h | 2 ++ 3 files changed, 43 insertions(+) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 3ddbf614ea43..275d86a677a1 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -387,6 +387,8 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, return -EINVAL; } + inst->last_qbuf_time_ns = ktime_get_ns(); + for (i = 0; i < b->length; i++) { b->m.planes[i].m.fd = b->m.planes[i].reserved[MSM_VIDC_BUFFER_FD]; @@ -1510,6 +1512,7 @@ void *msm_vidc_open(int core_id, int session_type) inst->full_range = COLOR_RANGE_UNSPECIFIED; inst->bse_vpp_delay = DEFAULT_BSE_VPP_DELAY; inst->first_reconfig = 0; + inst->active = true; for (i = SESSION_MSG_INDEX(SESSION_MSG_START); i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) { diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 8fbe805618fd..2aedffc911c8 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -17,6 +17,8 @@ #define MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO (1 << 16) #define MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO (5 << 16) +#define MSM_VIDC_SESSION_INACTIVE_THRESHOLD_MS 1000 + static int msm_vidc_decide_work_mode_ar50_lt(struct msm_vidc_inst *inst); static unsigned long msm_vidc_calc_freq_ar50_lt(struct msm_vidc_inst *inst, u32 filled_len); @@ -155,6 +157,19 @@ int msm_vidc_get_fps(struct msm_vidc_inst *inst) return fps; } +static inline bool is_active_session(u64 prev, u64 curr) +{ + u64 ts_delta; + + if (!prev || !curr) + return true; + + ts_delta = (prev < curr) ? curr - prev : prev - curr; + + return ((ts_delta / NSEC_PER_MSEC) <= + MSM_VIDC_SESSION_INACTIVE_THRESHOLD_MS); +} + void update_recon_stats(struct msm_vidc_inst *inst, struct recon_stats_type *recon_stats) { @@ -263,12 +278,14 @@ int msm_comm_set_buses(struct msm_vidc_core *core, u32 sid) struct msm_vidc_inst *inst = NULL; struct hfi_device *hdev; unsigned long total_bw_ddr = 0, total_bw_llcc = 0; + u64 curr_time_ns; if (!core || !core->device) { s_vpr_e(sid, "%s: Invalid args: %pK\n", __func__, core); return -EINVAL; } hdev = core->device; + curr_time_ns = ktime_get_ns(); mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { @@ -292,6 +309,12 @@ int msm_comm_set_buses(struct msm_vidc_core *core, u32 sid) continue; } + /* skip inactive session bus bandwidth */ + if (!is_active_session(inst->last_qbuf_time_ns, curr_time_ns)) { + inst->active = false; + continue; + } + if (inst->bus_data.power_mode == VIDC_POWER_TURBO) { total_bw_ddr = total_bw_llcc = INT_MAX; break; @@ -766,8 +789,10 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid) int rc = 0, i = 0; struct allowed_clock_rates_table *allowed_clks_tbl = NULL; bool increment, decrement; + u64 curr_time_ns; hdev = core->device; + curr_time_ns = ktime_get_ns(); allowed_clks_tbl = core->resources.allowed_clks_tbl; if (!allowed_clks_tbl) { s_vpr_e(sid, "%s: Invalid parameters\n", __func__); @@ -796,6 +821,12 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid) continue; } + /* skip inactive session clock rate */ + if (!is_active_session(inst->last_qbuf_time_ns, curr_time_ns)) { + inst->active = false; + continue; + } + if (inst->clk_data.core_id == VIDC_CORE_ID_1) freq_core_1 += inst->clk_data.min_freq; else if (inst->clk_data.core_id == VIDC_CORE_ID_2) @@ -919,6 +950,12 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc) core = inst->core; hdev = core->device; + if (!inst->active) { + /* do not skip bw voting for inactive -> active session */ + do_bw_calc = true; + inst->active = true; + } + if (msm_comm_scale_clocks(inst)) { s_vpr_e(inst->sid, "Failed to scale clocks. May impact performance\n"); @@ -930,6 +967,7 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc) "Failed to scale DDR bus. May impact perf\n"); } } + return 0; } diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 9b8c1cdb9d58..f14e8d3abe90 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -569,6 +569,8 @@ struct msm_vidc_inst { struct msm_vidc_ubwc_stats ubwc_stats; u32 bse_vpp_delay; u32 first_reconfig; + u64 last_qbuf_time_ns; + bool active; }; extern struct msm_vidc_drv *vidc_driver; From 70c6739172cdf3a4637dd429c40cec3b47e2014c Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Fri, 22 May 2020 20:46:01 +0800 Subject: [PATCH 279/452] msm: vidc: fix input port enum_fmt Assign enum_fmt_out to support input port enum_fmt. Fix encoder enum_fmt compressd flag. Change-Id: I822ee81586fe50bfe1fbfd8a808307051e639a79 Signed-off-by: Qiwei Liu --- msm/vidc/msm_v4l2_vidc.c | 1 + msm/vidc/msm_venc.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index 1bf40ea95347..140530e64f9b 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -208,6 +208,7 @@ static int msm_v4l2_querymenu(struct file *file, void *fh, const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = { .vidioc_querycap = msm_v4l2_querycap, .vidioc_enum_fmt_vid_cap = msm_v4l2_enum_fmt, + .vidioc_enum_fmt_vid_out = msm_v4l2_enum_fmt, .vidioc_s_fmt_vid_cap_mplane = msm_v4l2_s_fmt, .vidioc_s_fmt_vid_out_mplane = msm_v4l2_s_fmt, .vidioc_g_fmt_vid_cap_mplane = msm_v4l2_g_fmt, diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 30f8c710d9a5..b03af186d7bf 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1234,10 +1234,10 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) if (f->type == OUTPUT_MPLANE) { fmt_desc = msm_comm_get_pixel_fmt_index(venc_output_formats, ARRAY_SIZE(venc_output_formats), f->index, inst->sid); + f->flags = V4L2_FMT_FLAG_COMPRESSED; } else if (f->type == INPUT_MPLANE) { fmt_desc = msm_comm_get_pixel_fmt_index(venc_input_formats, ARRAY_SIZE(venc_input_formats), f->index, inst->sid); - f->flags = V4L2_FMT_FLAG_COMPRESSED; } memset(f->reserved, 0, sizeof(f->reserved)); From c13ea9ecdb335bf4943b21be9098ab3ee61ca5f8 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Mon, 6 Apr 2020 15:17:19 +0530 Subject: [PATCH 280/452] msm: vidc: Adjust the load for concurrent sessions Adjust the load by max image spec for concurrent video and image sessions. Change-Id: I433b3a4fb4436589b930a842a02033ac665a826c Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc.h | 5 +++ msm/vidc/msm_vidc_common.c | 82 ++++++++++++++++++++++++++--------- msm/vidc/msm_vidc_common.h | 9 +++- msm/vidc/msm_vidc_platform.c | 12 +++++ msm/vidc/msm_vidc_res_parse.c | 3 ++ msm/vidc/msm_vidc_resources.h | 1 + 6 files changed, 90 insertions(+), 22 deletions(-) diff --git a/msm/vidc/msm_vidc.h b/msm/vidc/msm_vidc.h index fcfe8b275ace..cea3b470f408 100644 --- a/msm/vidc/msm_vidc.h +++ b/msm/vidc/msm_vidc.h @@ -107,6 +107,11 @@ enum session_type { MSM_VIDC_MAX_DEVICES = MSM_VIDC_UNKNOWN, }; +enum load_type { + MSM_VIDC_VIDEO = 0, + MSM_VIDC_IMAGE, +}; + union msm_v4l2_cmd { struct v4l2_decoder_cmd dec; struct v4l2_encoder_cmd enc; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index ccb26795b592..03c8f1dacb3d 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -766,7 +766,8 @@ int msm_comm_get_inst_load_per_core(struct msm_vidc_inst *inst, } int msm_comm_get_device_load(struct msm_vidc_core *core, - enum session_type type, enum load_calc_quirks quirks) + enum session_type sess_type, enum load_type load_type, + enum load_calc_quirks quirks) { struct msm_vidc_inst *inst = NULL; int num_mbs_per_sec = 0; @@ -778,7 +779,12 @@ int msm_comm_get_device_load(struct msm_vidc_core *core, mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { - if (inst->session_type != type) + if (inst->session_type != sess_type) + continue; + + if (load_type == MSM_VIDC_VIDEO && !is_video_session(inst)) + continue; + else if (load_type == MSM_VIDC_IMAGE && !is_grid_session(inst)) continue; num_mbs_per_sec += msm_comm_get_inst_load(inst, quirks); @@ -3217,8 +3223,9 @@ static int msm_vidc_load_resources(int flipped_state, { int rc = 0; struct hfi_device *hdev; - int num_mbs_per_sec = 0, max_load_adj = 0; struct msm_vidc_core *core; + int max_video_load = 0, max_image_load = 0; + int video_load = 0, image_load = 0; enum load_calc_quirks quirks = LOAD_ADMISSION_CONTROL; if (!inst || !inst->core || !inst->core->device) { @@ -3237,18 +3244,33 @@ static int msm_vidc_load_resources(int flipped_state, } core = inst->core; - num_mbs_per_sec = - msm_comm_get_device_load(core, MSM_VIDC_DECODER, quirks) + - msm_comm_get_device_load(core, MSM_VIDC_ENCODER, quirks); + image_load = msm_comm_get_device_load(core, + MSM_VIDC_ENCODER, MSM_VIDC_IMAGE, + quirks); + video_load = msm_comm_get_device_load(core, + MSM_VIDC_DECODER, MSM_VIDC_VIDEO, + quirks); + video_load += msm_comm_get_device_load(core, + MSM_VIDC_ENCODER, MSM_VIDC_VIDEO, + quirks); - max_load_adj = core->resources.max_load + - inst->capability.cap[CAP_MBS_PER_FRAME].max; + max_video_load = inst->core->resources.max_load + + inst->capability.cap[CAP_MBS_PER_FRAME].max; + max_image_load = inst->core->resources.max_image_load; - if (num_mbs_per_sec > max_load_adj) { - s_vpr_e(inst->sid, "HW is overloaded, needed: %d max: %d\n", - num_mbs_per_sec, max_load_adj); - msm_vidc_print_running_insts(core); - msm_comm_kill_session(inst); + if (video_load > max_video_load) { + s_vpr_e(inst->sid, + "H/W is overloaded. needed: %d max: %d\n", + video_load, max_video_load); + msm_vidc_print_running_insts(inst->core); + return -EBUSY; + } + + if (video_load + image_load > max_video_load + max_image_load) { + s_vpr_e(inst->sid, + "H/W is overloaded. needed: [video + image][%d + %d], max: [video + image][%d + %d]\n", + video_load, image_load, max_video_load, max_image_load); + msm_vidc_print_running_insts(inst->core); return -EBUSY; } @@ -5525,19 +5547,37 @@ static int msm_vidc_check_mbpf_supported(struct msm_vidc_inst *inst) static int msm_vidc_check_mbps_supported(struct msm_vidc_inst *inst) { - int num_mbs_per_sec = 0, max_load_adj = 0; + int max_video_load = 0, max_image_load = 0; + int video_load = 0, image_load = 0; enum load_calc_quirks quirks = LOAD_ADMISSION_CONTROL; if (inst->state == MSM_VIDC_OPEN_DONE) { - max_load_adj = inst->core->resources.max_load; - num_mbs_per_sec = msm_comm_get_device_load(inst->core, - MSM_VIDC_DECODER, quirks); - num_mbs_per_sec += msm_comm_get_device_load(inst->core, - MSM_VIDC_ENCODER, quirks); - if (num_mbs_per_sec > max_load_adj) { + image_load = msm_comm_get_device_load(inst->core, + MSM_VIDC_ENCODER, MSM_VIDC_IMAGE, + quirks); + video_load = msm_comm_get_device_load(inst->core, + MSM_VIDC_DECODER, MSM_VIDC_VIDEO, + quirks); + video_load += msm_comm_get_device_load(inst->core, + MSM_VIDC_ENCODER, MSM_VIDC_VIDEO, + quirks); + + max_video_load = inst->core->resources.max_load; + max_image_load = inst->core->resources.max_image_load; + + if (video_load > max_video_load) { s_vpr_e(inst->sid, "H/W is overloaded. needed: %d max: %d\n", - num_mbs_per_sec, max_load_adj); + video_load, max_video_load); + msm_vidc_print_running_insts(inst->core); + return -EBUSY; + } + + if (video_load + image_load > max_video_load + max_image_load) { + s_vpr_e(inst->sid, + "H/W is overloaded. needed: [video + image][%d + %d], max: [video + image][%d + %d]\n", + video_load, image_load, + max_video_load, max_image_load); msm_vidc_print_running_insts(inst->core); return -EBUSY; } diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 35b6887252ae..6b8ea0309c4c 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -115,6 +115,11 @@ static inline bool is_grid_session(struct msm_vidc_inst *inst) } return 0; } + +static inline bool is_video_session(struct msm_vidc_inst *inst) +{ + return !is_grid_session(inst); +} static inline bool is_realtime_session(struct msm_vidc_inst *inst) { struct v4l2_ctrl *ctrl; @@ -248,7 +253,9 @@ int msm_comm_get_inst_load(struct msm_vidc_inst *inst, int msm_comm_get_inst_load_per_core(struct msm_vidc_inst *inst, enum load_calc_quirks quirks); int msm_comm_get_device_load(struct msm_vidc_core *core, - enum session_type type, enum load_calc_quirks quirks); + enum session_type sess_type, + enum load_type load_type, + enum load_calc_quirks quirks); int msm_comm_set_color_format(struct msm_vidc_inst *inst, enum hal_buffer buffer_type, int fourcc); int msm_comm_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl); diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 43e7aad5b168..f86c1d0f8013 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -358,6 +358,10 @@ static struct msm_vidc_common_data lahaina_common_data[] = { * 8192x4320@48fps */ }, + { + .key = "qcom,max-image-load", + .value = 1048576, /* ((16384x16384)/256)@1fps */ + }, { .key = "qcom,max-mbpf", .value = 173056, /* (8192x4320)/256 + (4096x2176)/256*/ @@ -472,6 +476,10 @@ static struct msm_vidc_common_data bengal_common_data_v0[] = { .key = "qcom,max-hw-load", .value = 489600, }, + { + .key = "qcom,max-image-load", + .value = 262144, /* ((8192x8192)/256)@1fps */ + }, { .key = "qcom,max-hq-mbs-per-frame", .value = 8160, @@ -531,6 +539,10 @@ static struct msm_vidc_common_data bengal_common_data_v1[] = { .key = "qcom,max-hw-load", .value = 244800, }, + { + .key = "qcom,max-image-load", + .value = 262144, /* ((8192x8192)/256)@1fps */ + }, { .key = "qcom,max-hq-mbs-per-frame", .value = 8160, diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 993c6283513a..dc6daede88eb 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -745,6 +745,9 @@ int read_platform_resources_from_drv_data( res->max_load = find_key_value(platform_data, "qcom,max-hw-load"); + res->max_image_load = find_key_value(platform_data, + "qcom,max-image-load"); + res->max_mbpf = find_key_value(platform_data, "qcom,max-mbpf"); diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 8474decd2d9a..81735051dc5e 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -147,6 +147,7 @@ struct msm_vidc_platform_resources { struct addr_set qdss_addr_set; struct buffer_usage_set buffer_usage_set; uint32_t max_load; + uint32_t max_image_load; uint32_t max_mbpf; uint32_t max_hq_mbs_per_frame; uint32_t max_hq_mbs_per_sec; From d05afd5d286fec95cc54176337b28608ffcd1ad2 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Sun, 17 May 2020 14:37:12 -0700 Subject: [PATCH 281/452] msm: vidc: Initialize ubwc_stats_lock Initialize ubwc_stats_lock before use and destroy it before video instance is destroyed. Change-Id: I4ecc02109d9d1c3f8b7cfe28c49b5467866b4d3e Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 48237519f11a..cba813cddd3d 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1459,6 +1459,7 @@ void *msm_vidc_open(int core_id, int session_type) mutex_init(&inst->bufq[INPUT_PORT].lock); mutex_init(&inst->lock); mutex_init(&inst->flush_lock); + mutex_init(&inst->ubwc_stats_lock); INIT_MSM_VIDC_LIST(&inst->scratchbufs); INIT_MSM_VIDC_LIST(&inst->input_crs); @@ -1562,6 +1563,7 @@ void *msm_vidc_open(int core_id, int session_type) vb2_queue_release(&inst->bufq[OUTPUT_PORT].vb2_bufq); fail_bufq_capture: msm_comm_ctrl_deinit(inst); + mutex_destroy(&inst->ubwc_stats_lock); mutex_destroy(&inst->sync_lock); mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); mutex_destroy(&inst->bufq[INPUT_PORT].lock); @@ -1707,6 +1709,7 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) DEINIT_MSM_VIDC_LIST(&inst->window_data); DEINIT_MSM_VIDC_LIST(&inst->timestamps); + mutex_destroy(&inst->ubwc_stats_lock); mutex_destroy(&inst->sync_lock); mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); mutex_destroy(&inst->bufq[INPUT_PORT].lock); From 0429942772b5104ec7c49a403a1e680204082218 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Mon, 17 Feb 2020 12:26:33 +0800 Subject: [PATCH 282/452] msm: venc: update min input buffer count for HEIC After grid flag enabled for HEIC, update min input buffer count to 2. Change-Id: Ia279b571af8c15e029a1cc77e3cbd3f6e51448f7 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_venc.c | 7 ++++++- msm/vidc/msm_vidc_buffer_calculations.c | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index b03af186d7bf..945ff83be6e7 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3006,9 +3006,14 @@ int msm_venc_set_image_properties(struct msm_vidc_inst *inst) return -EINVAL; } - if (inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) + if (!is_image_session(inst) && !is_grid_session(inst)) return 0; + if (inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) { + d_vpr_e("%s: invalid rate control mode\n", __func__); + return -EINVAL; + } + rc = msm_venc_set_frame_quality(inst); if (rc) { s_vpr_e(inst->sid, diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index b17c8a1ebb0f..5036551bb416 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -637,6 +637,12 @@ int msm_vidc_calculate_input_buffer_count(struct msm_vidc_inst *inst) return 0; } + if (is_grid_session(inst)) { + fmt->count_min = fmt->count_min_host = fmt->count_actual = + SINGLE_INPUT_BUFFER + 1; + return 0; + } + extra_buff_count = msm_vidc_get_extra_buff_count(inst, HAL_BUFFER_INPUT); fmt->count_min = MIN_INPUT_BUFFERS; From 5ffcf2bdc2123131c0bf3709a6e0619f2feff328 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Tue, 10 Sep 2019 14:55:01 +0800 Subject: [PATCH 283/452] msm_vidc: venc: update HEIF output buffer count 1. Update buffer count after setting bitrate mode 2. Update HEIF output buffer count to 12 Change-Id: Ibbe80bc219b51db7d9c10cb001932d8e55a6f086 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_vidc_buffer_calculations.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index b17c8a1ebb0f..94ab5874c0a5 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -24,6 +24,9 @@ /* minimum number of output buffers */ #define MIN_ENC_OUTPUT_BUFFERS 4 +/* extra output buffers for encoder HEIF usecase */ +#define HEIF_ENC_TOTAL_OUTPUT_BUFFERS 12 + #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_WIDTH 32 #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_HEIGHT 8 #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_UV_TILE_WIDTH 16 @@ -803,6 +806,13 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) if (!is_realtime_session(inst) || is_thumbnail_session(inst)) return extra_output_count; + /* For HEIF, we are increasing buffer count */ + if (is_image_session(inst)) { + extra_output_count = (HEIF_ENC_TOTAL_OUTPUT_BUFFERS - + MIN_ENC_OUTPUT_BUFFERS); + return extra_output_count; + } + if (is_decode_session(inst)) { /* add 4 extra buffers for dcvs */ if (core->resources.dcvs) From 03507c27f62147d852d7955e6c5b0c4fab07d41e Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Thu, 21 May 2020 23:50:15 +0800 Subject: [PATCH 284/452] msm: vidc: restore native recorder interface Restore native recorder interface to keep driver interface aligned with kona. Change-Id: I8588bd6d85b024556c78d269c7e8d5c0b1518209 Signed-off-by: Qiwei Liu --- include/uapi/vidc/media/msm_vidc_utils.h | 2 ++ msm/vidc/msm_venc.c | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index a6f882e860aa..63894f8fb219 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -229,6 +229,8 @@ enum v4l2_mpeg_vidc_video_hevc_max_hier_coding_layer { }; #define V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 121) +#define V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 122) #define V4L2_CID_MPEG_VIDC_VENC_RC_TIMESTAMP_DISABLE \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 123) #define V4L2_CID_MPEG_VIDC_SUPERFRAME \ diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 945ff83be6e7..f0f91abcd21d 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -929,6 +929,15 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = DEFAULT_CHROMA_QP_OFFSET, .step = 1, }, + { + .id = V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER, + .name = "Enable/Disable Native Recorder", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, { .id = V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS, .name = "Enable/Disable bitrate savings", @@ -1992,6 +2001,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY: case V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM: case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: + case V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER: case V4L2_CID_MPEG_VIDC_VENC_RC_TIMESTAMP_DISABLE: case V4L2_CID_MPEG_VIDEO_VBV_DELAY: case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET: From bdd837dd06a818c89e8513e5d16bb38e866ac155 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Tue, 26 May 2020 18:12:22 -0700 Subject: [PATCH 285/452] msm: vidc: modify driver output min buffer count Modify output driver min count to 4 for HEVC/H264. Change-Id: I8efa986b693804392a6178b369ef43c7edf9e0d4 Signed-off-by: Darshana Patil --- msm/vidc/msm_vidc_buffer_calculations.c | 7 +++++-- msm/vidc/msm_vidc_common.c | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 33f6ba234ad2..02a10e8769c7 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -653,6 +653,7 @@ int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst) struct msm_vidc_format *fmt; int extra_buff_count = 0; u32 codec, output_min_count; + u32 mbpf = 0; if (!inst) { d_vpr_e("%s: invalid params\n", __func__); @@ -686,16 +687,18 @@ int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst) output_min_count = 9; break; default: - output_min_count = 8; //H264, HEVC + output_min_count = 4; //H264, HEVC } } else { output_min_count = MIN_ENC_OUTPUT_BUFFERS; } + mbpf = msm_vidc_get_mbs_per_frame(inst); if (inst->core->resources.has_vpp_delay && is_decode_session(inst) && (codec == V4L2_PIX_FMT_H264 - || codec == V4L2_PIX_FMT_HEVC)) { + || codec == V4L2_PIX_FMT_HEVC) && + mbpf >= NUM_MBS_PER_FRAME(7680, 3840)) { output_min_count = max(output_min_count, (u32)MAX_BSE_VPP_DELAY); output_min_count = diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 65a1c191ae17..fc75ac091668 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1543,6 +1543,7 @@ static void handle_event_change_insufficient(struct msm_vidc_inst *inst, u32 codec) { int extra_buff_count = 0; + u32 mbpf = 0; s_vpr_h(inst->sid, "seq: V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT\n"); @@ -1556,10 +1557,12 @@ static void handle_event_change_insufficient(struct msm_vidc_inst *inst, HAL_BUFFER_OUTPUT); fmt->count_min = event_notify->fw_min_cnt; + mbpf = msm_vidc_get_mbs_per_frame(inst); if (inst->core->resources.has_vpp_delay && is_decode_session(inst) && (codec == V4L2_PIX_FMT_H264 - || codec == V4L2_PIX_FMT_HEVC)) { + || codec == V4L2_PIX_FMT_HEVC) && + mbpf >= NUM_MBS_PER_FRAME(7680, 3840)) { fmt->count_min = max(fmt->count_min, (u32)MAX_BSE_VPP_DELAY); fmt->count_min = From 8fc8209df6ce2a911283685cf92a9ddc787ed259 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Wed, 27 May 2020 14:27:58 +0800 Subject: [PATCH 286/452] msm: venc: uncomment bitrate boost HFI calling Uncomment HFI calling part for bitrate boost setting. Change-Id: I289b1866089fff883d624bb505b37cca4061a626 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_venc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index b03af186d7bf..58d40ad50958 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3354,13 +3354,13 @@ int msm_venc_set_bitrate_boost_margin(struct msm_vidc_inst *inst, u32 enable) boost_margin.margin = (u32)(ctrl->val/25) * 25; setprop: - /* s_vpr_h(inst->sid, "%s: %d\n", __func__, boost_margin.margin); - * rc = call_hfi_op(hdev, session_set_property, inst->session, - * HFI_PROPERTY_PARAM_VENC_BITRATE_BOOST, &boost_margin, - * sizeof(boost_margin)); - *if (rc) - * s_vpr_e(inst->sid, "%s: set property failed\n", __func__); - */ + s_vpr_h(inst->sid, "%s: %d\n", __func__, boost_margin.margin); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_BITRATE_BOOST, &boost_margin, + sizeof(boost_margin)); + if (rc) + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); + return rc; } From 6ec572de63613416f5562390c88725dd6752f6e7 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Wed, 20 May 2020 14:48:22 -0700 Subject: [PATCH 287/452] msm: vidc: Ignore vpp delay in thumbnail usecase VPP delay is not applicable to Thumbnail usecase. Hence buffer counts should not include VPP delay, in thumbnail usecase. Change-Id: Iba7d3efec48c08c160eb602d946643d620d2a36f Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc.c | 2 +- msm/vidc/msm_vidc_buffer_calculations.c | 8 +---- msm/vidc/msm_vidc_clocks.c | 48 ++++++++++++++----------- msm/vidc/msm_vidc_clocks.h | 1 + msm/vidc/msm_vidc_common.c | 8 +---- msm/vidc/msm_vidc_internal.h | 2 +- 6 files changed, 32 insertions(+), 37 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 275d86a677a1..30fa43deeb02 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1511,7 +1511,7 @@ void *msm_vidc_open(int core_id, int session_type) inst->entropy_mode = HFI_H264_ENTROPY_CABAC; inst->full_range = COLOR_RANGE_UNSPECIFIED; inst->bse_vpp_delay = DEFAULT_BSE_VPP_DELAY; - inst->first_reconfig = 0; + inst->first_reconfig_done = 0; inst->active = true; for (i = SESSION_MSG_INDEX(SESSION_MSG_START); diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 79e0c1f290c1..e99e2fc7aee2 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -664,7 +664,6 @@ int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst) struct msm_vidc_format *fmt; int extra_buff_count = 0; u32 codec, output_min_count; - u32 mbpf = 0; if (!inst) { d_vpr_e("%s: invalid params\n", __func__); @@ -704,12 +703,7 @@ int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst) output_min_count = MIN_ENC_OUTPUT_BUFFERS; } - mbpf = msm_vidc_get_mbs_per_frame(inst); - if (inst->core->resources.has_vpp_delay && - is_decode_session(inst) && - (codec == V4L2_PIX_FMT_H264 - || codec == V4L2_PIX_FMT_HEVC) && - mbpf >= NUM_MBS_PER_FRAME(7680, 3840)) { + if (is_vpp_delay_allowed(inst)) { output_min_count = max(output_min_count, (u32)MAX_BSE_VPP_DELAY); output_min_count = diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 2aedffc911c8..5f267bc951ae 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -128,6 +128,19 @@ bool res_is_less_than_or_equal_to(u32 width, u32 height, return false; } +bool is_vpp_delay_allowed(struct msm_vidc_inst *inst) +{ + u32 codec = get_v4l2_codec(inst); + u32 mbpf = msm_vidc_get_mbs_per_frame(inst); + + return (inst->core->resources.has_vpp_delay && + is_decode_session(inst) && + !is_thumbnail_session(inst) && + (mbpf >= NUM_MBS_PER_FRAME(7680, 3840)) && + (codec == V4L2_PIX_FMT_H264 + || codec == V4L2_PIX_FMT_HEVC)); +} + int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst) { int height, width; @@ -1234,40 +1247,34 @@ int msm_vidc_set_bse_vpp_delay(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; - u32 delay = 0; - u32 mbpf = 0, codec = 0; + u32 delay = DEFAULT_BSE_VPP_DELAY; if (!inst || !inst->core) { d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } + /* Set VPP delay only upto first reconfig */ + if (inst->first_reconfig_done) { + s_vpr_hp(inst->sid, "%s: Skip bse-vpp\n", __func__); + return 0; + } + + if (in_port_reconfig(inst)) + inst->first_reconfig_done = 1; + if (!inst->core->resources.has_vpp_delay || - inst->session_type != MSM_VIDC_DECODER || - inst->clk_data.work_mode != HFI_WORKMODE_2 || - inst->first_reconfig) { + !is_decode_session(inst) || + is_thumbnail_session(inst) || + inst->clk_data.work_mode != HFI_WORKMODE_2) { s_vpr_hp(inst->sid, "%s: Skip bse-vpp\n", __func__); return 0; } hdev = inst->core->device; - /* Decide VPP delay only on first reconfig */ - if (in_port_reconfig(inst)) - inst->first_reconfig = 1; - - codec = get_v4l2_codec(inst); - if (codec != V4L2_PIX_FMT_HEVC && codec != V4L2_PIX_FMT_H264) { - s_vpr_hp(inst->sid, "%s: Skip bse-vpp, codec %u\n", - __func__, codec); - goto exit; - } - - mbpf = msm_vidc_get_mbs_per_frame(inst); - if (mbpf >= NUM_MBS_PER_FRAME(7680, 3840)) + if (is_vpp_delay_allowed(inst)) delay = MAX_BSE_VPP_DELAY; - else - delay = DEFAULT_BSE_VPP_DELAY; /* DebugFS override [1-31] */ if (msm_vidc_vpp_delay & 0x1F) @@ -1282,7 +1289,6 @@ int msm_vidc_set_bse_vpp_delay(struct msm_vidc_inst *inst) else inst->bse_vpp_delay = delay; -exit: return rc; } diff --git a/msm/vidc/msm_vidc_clocks.h b/msm/vidc/msm_vidc_clocks.h index c75d9117b8b6..f32b370849d6 100644 --- a/msm/vidc/msm_vidc_clocks.h +++ b/msm/vidc/msm_vidc_clocks.h @@ -40,4 +40,5 @@ bool res_is_greater_than(u32 width, u32 height, bool res_is_less_than(u32 width, u32 height, u32 ref_width, u32 ref_height); int msm_vidc_set_bse_vpp_delay(struct msm_vidc_inst *inst); +bool is_vpp_delay_allowed(struct msm_vidc_inst *inst); #endif diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 3b63f68e1fa2..fa25d14376a3 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1555,7 +1555,6 @@ static void handle_event_change_insufficient(struct msm_vidc_inst *inst, u32 codec) { int extra_buff_count = 0; - u32 mbpf = 0; s_vpr_h(inst->sid, "seq: V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT\n"); @@ -1569,12 +1568,7 @@ static void handle_event_change_insufficient(struct msm_vidc_inst *inst, HAL_BUFFER_OUTPUT); fmt->count_min = event_notify->fw_min_cnt; - mbpf = msm_vidc_get_mbs_per_frame(inst); - if (inst->core->resources.has_vpp_delay && - is_decode_session(inst) && - (codec == V4L2_PIX_FMT_H264 - || codec == V4L2_PIX_FMT_HEVC) && - mbpf >= NUM_MBS_PER_FRAME(7680, 3840)) { + if (is_vpp_delay_allowed(inst)) { fmt->count_min = max(fmt->count_min, (u32)MAX_BSE_VPP_DELAY); fmt->count_min = diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 187ec7a1c2aa..1ea315bb785d 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -568,7 +568,7 @@ struct msm_vidc_inst { struct mutex ubwc_stats_lock; struct msm_vidc_ubwc_stats ubwc_stats; u32 bse_vpp_delay; - u32 first_reconfig; + u32 first_reconfig_done; u64 last_qbuf_time_ns; bool active; }; From e55786492dbceb0e4fc31b32c31b6dfbac280ee3 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Mon, 27 Apr 2020 12:38:36 +0530 Subject: [PATCH 288/452] msm: vdec: configure latency mode for decode session Static - Enable latency hint which indicates that the decode session may go into low latency mode during the session. With this configuration, video driver disables DCVS and decode batching. Dynamic - Enable or disable low latency control during the session. Based on it, video driver would decide the work mode and set the same. Change-Id: If6e85b7adb1bbe4b4bec9e4a8671db64f240cfe8 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vdec.c | 40 ++++++++++++++++++++++++++++++++++++++ msm/vidc/msm_vidc_clocks.c | 1 + msm/vidc/msm_vidc_common.c | 10 ++++++++++ msm/vidc/msm_vidc_common.h | 11 +++++++++++ msm/vidc/vidc_hfi.h | 2 ++ 5 files changed, 64 insertions(+) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index c141fb09ad87..c53353abd940 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -416,6 +416,15 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, .step = 1, }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_HINT, + .name = "Low Latency Hint", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, { .id = V4L2_CID_MPEG_VIDC_SUPERFRAME, .name = "Superframe", @@ -937,6 +946,8 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) inst->clk_data.low_latency_mode = !!ctrl->val; inst->batch.enable = is_batching_allowed(inst); break; + case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_HINT: + break; default: s_vpr_e(inst->sid, "Unknown control %#x\n", ctrl->id); break; @@ -1313,6 +1324,32 @@ int msm_vdec_set_priority(struct msm_vidc_inst *inst) return rc; } +int msm_vdec_set_seqchng_at_syncframe(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct hfi_enable hfi_property; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params %pK\n", __func__, inst); + return -EINVAL; + } + hdev = inst->core->device; + hfi_property.enable = is_low_latency_hint(inst); + + if (!hfi_property.enable) + return 0; + + s_vpr_h(inst->sid, "%s: %#x\n", __func__, hfi_property.enable); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VDEC_SEQCHNG_AT_SYNCFRM, &hfi_property, + sizeof(hfi_property)); + if (rc) + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); + + return rc; +} + int msm_vdec_set_conceal_color(struct msm_vidc_inst *inst) { int rc = 0; @@ -1447,6 +1484,9 @@ int msm_vdec_set_properties(struct msm_vidc_inst *inst) rc = msm_vdec_set_conceal_color(inst); if (rc) goto exit; + rc = msm_vdec_set_seqchng_at_syncframe(inst); + if (rc) + goto exit; } rc = msm_vdec_set_color_format(inst); diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 5f267bc951ae..791fe244b340 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -995,6 +995,7 @@ int msm_dcvs_try_enable(struct msm_vidc_inst *inst) !(msm_vidc_clock_voting || !inst->core->resources.dcvs || inst->flags & VIDC_THUMBNAIL || + is_low_latency_hint(inst) || inst->clk_data.low_latency_mode || inst->batch.enable || is_turbo_session(inst) || diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index fa25d14376a3..af087866f1db 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1656,6 +1656,15 @@ static void handle_event_change(enum hal_command_response cmd, void *data) } else { inst->entropy_mode = event_notify->entropy_mode; + /* configure work mode considering low latency*/ + if (is_low_latency_hint(inst)) { + rc = call_core_op(inst->core, decide_work_mode, + inst); + if (rc) + s_vpr_e(inst->sid, + "%s: Failed to decide work mode\n", + __func__); + } s_vpr_h(inst->sid, "seq: No parameter change continue session\n"); rc = call_hfi_op(hdev, session_continue, @@ -2805,6 +2814,7 @@ bool is_batching_allowed(struct msm_vidc_inst *inst) */ return (inst->batch.enable && inst->core->resources.decode_batching && + !is_low_latency_hint(inst) && is_single_session(inst, ignore_flags) && is_decode_session(inst) && !is_thumbnail_session(inst) && diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index fa48aa7ae830..806a8edb3dbd 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -127,6 +127,17 @@ static inline bool is_realtime_session(struct msm_vidc_inst *inst) return !!ctrl->val; } +static inline bool is_low_latency_hint(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *ctrl; + + if (inst->session_type != MSM_VIDC_DECODER) + return false; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_HINT); + return !!ctrl->val; +} + static inline bool is_secure_session(struct msm_vidc_inst *inst) { return !!(inst->flags & VIDC_SECURE); diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index 784868e9e20c..ed078af401b5 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -193,6 +193,8 @@ struct hfi_extradata_header { (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x0023) #define HFI_PROPERTY_PARAM_VDEC_VSP_VPP_DELAY \ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x0024) +#define HFI_PROPERTY_PARAM_VDEC_SEQCHNG_AT_SYNCFRM \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x0025) #define HFI_PROPERTY_CONFIG_VDEC_OX_START \ (HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x4000) From 930011097f7ee0107dd4e55d478bc77ae948e400 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Thu, 21 May 2020 23:34:50 +0800 Subject: [PATCH 289/452] msm: vidc: support encoder auto dynamic fps Encoder calculate fps based on timestamp, if fps changes and stable for 2 frames, set to firmware to facilitate rate control. Use closest rounding instead of floor rounding when calculate fps. Change-Id: Id2420729a309378107ff6f7830515fae31512ddd Signed-off-by: Qiwei Liu --- msm/vidc/msm_venc.c | 68 +++++++++++++++++++++++++++++++++++ msm/vidc/msm_venc.h | 1 + msm/vidc/msm_vidc.c | 13 +++++-- msm/vidc/msm_vidc_common.c | 10 +++--- msm/vidc/msm_vidc_platform.c | 4 +++ msm/vidc/msm_vidc_res_parse.c | 2 ++ msm/vidc/msm_vidc_resources.h | 1 + 7 files changed, 93 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 5eeb51464593..c7f16dfe3c72 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -47,6 +47,7 @@ #define MIN_NUM_ENC_OUTPUT_BUFFERS 4 #define MIN_NUM_ENC_CAPTURE_BUFFERS 5 +#define VENC_MAX_TIMESTAMP_LIST_SIZE 2 static const char *const mpeg_video_rate_control[] = { "VBR", @@ -1653,6 +1654,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (rc) s_vpr_e(sid, "%s: set frame rate failed\n", __func__); + msm_comm_release_timestamps(inst); } break; case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: @@ -2112,6 +2114,72 @@ int msm_venc_set_frame_rate(struct msm_vidc_inst *inst) return rc; } +int msm_venc_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) +{ + struct msm_vidc_timestamps *entry, *node, *prev = NULL; + int count = 0; + int rc = 0; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid parameters\n", __func__); + return -EINVAL; + } + + if (!inst->core->resources.enc_auto_dynamic_fps || + is_image_session(inst)) + return rc; + + mutex_lock(&inst->timestamps.lock); + list_for_each_entry(node, &inst->timestamps.list, list) { + count++; + if (timestamp_us <= node->timestamp_us) { + s_vpr_e(inst->sid, "%s: invalid ts %llu, exist %llu\n", + __func__, timestamp_us, node->timestamp_us); + goto unlock; + } + } + + /* Maintain a sliding window */ + entry = NULL; + if (count >= VENC_MAX_TIMESTAMP_LIST_SIZE) { + entry = list_first_entry(&inst->timestamps.list, + struct msm_vidc_timestamps, list); + list_del_init(&entry->list); + } + if (!entry) { + entry = kzalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) { + s_vpr_e(inst->sid, "%s: ts malloc failure\n", + __func__); + rc = -ENOMEM; + goto unlock; + } + } + + entry->timestamp_us = timestamp_us; + entry->framerate = inst->clk_data.frame_rate; + prev = list_last_entry(&inst->timestamps.list, + struct msm_vidc_timestamps, list); + list_add_tail(&entry->list, &inst->timestamps.list); + + if (!count) + goto unlock; + + entry->framerate = msm_comm_calc_framerate(inst, + timestamp_us, prev->timestamp_us); + + /* if framerate changed and stable for 2 frames, set to firmware */ + if (entry->framerate == prev->framerate && + entry->framerate != inst->clk_data.frame_rate) { + inst->clk_data.frame_rate = entry->framerate; + msm_venc_set_frame_rate(inst); + } + +unlock: + mutex_unlock(&inst->timestamps.lock); + return rc; +} + int msm_venc_set_color_format(struct msm_vidc_inst *inst) { int rc = 0; diff --git a/msm/vidc/msm_venc.h b/msm/vidc/msm_venc.h index 43b56bc21788..bb5a651f3da9 100644 --- a/msm/vidc/msm_venc.h +++ b/msm/vidc/msm_venc.h @@ -24,6 +24,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, int msm_venc_set_properties(struct msm_vidc_inst *inst); int msm_venc_set_extradata(struct msm_vidc_inst *inst); int msm_venc_set_frame_rate(struct msm_vidc_inst *inst); +int msm_venc_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us); int msm_venc_set_bitrate(struct msm_vidc_inst *inst); int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst); int msm_venc_set_operating_rate(struct msm_vidc_inst *inst); diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 30fa43deeb02..bf40eeef23a8 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -420,18 +420,27 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, if (is_grid_session(inst) && b->type == INPUT_MPLANE) b->flags |= V4L2_BUF_FLAG_PERF_MODE; + timestamp_us = (u64)((b->timestamp.tv_sec * 1000000ULL) + + b->timestamp.tv_usec); if (is_decode_session(inst) && b->type == INPUT_MPLANE) { if (inst->flush_timestamps) msm_comm_release_timestamps(inst); inst->flush_timestamps = false; - timestamp_us = (u64)((b->timestamp.tv_sec * 1000000ULL) + - b->timestamp.tv_usec); rc = msm_comm_store_timestamp(inst, timestamp_us); if (rc) return rc; inst->clk_data.frame_rate = msm_comm_get_max_framerate(inst); } + if (is_encode_session(inst) && b->type == INPUT_MPLANE) { + if (inst->flush_timestamps) + msm_comm_release_timestamps(inst); + inst->flush_timestamps = false; + + rc = msm_venc_store_timestamp(inst, timestamp_us); + if (rc) + return rc; + } q = msm_comm_get_vb2q(inst, b->type); if (!q) { diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index fa25d14376a3..b49b654f4cd1 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5596,7 +5596,7 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) * flush is issued, before adding the next buffer's timestamp * to the list. */ - if (is_decode_session(inst) && inst->in_flush) { + if (!is_image_session(inst) && inst->in_flush) { inst->flush_timestamps = true; s_vpr_h(inst->sid, "Setting flush variable to clear timestamp list: %d\n", @@ -7610,7 +7610,7 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) goto unlock; } entry->timestamp_us = timestamp_us; - entry->framerate = DEFAULT_FPS << 16; + entry->framerate = inst->clk_data.frame_rate; entry->is_valid = true; /* add new entry into the list in sorted order */ @@ -7661,14 +7661,16 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) u32 msm_comm_calc_framerate(struct msm_vidc_inst *inst, u64 timestamp_us, u64 prev_ts) { - u32 framerate = DEFAULT_FPS << 16; + u32 framerate = inst->clk_data.frame_rate; + u32 interval; if (timestamp_us <= prev_ts) { s_vpr_e(inst->sid, "%s: invalid ts %lld, prev ts %lld\n", __func__, timestamp_us, prev_ts); return framerate; } - framerate = (1000000 / (timestamp_us - prev_ts)) << 16; + interval = (u32)(timestamp_us - prev_ts); + framerate = ((1000000 + interval / 2) / interval) << 16; return framerate; } diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index f86c1d0f8013..ddf55e190a6b 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -453,6 +453,10 @@ static struct msm_vidc_common_data lahaina_common_data[] = { .key = "qcom,vpp_delay_supported", .value = 1, }, + { + .key = "qcom,enc_auto_dynamic_fps", + .value = 1, + }, }; static struct msm_vidc_common_data bengal_common_data_v0[] = { diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index c565ee6ec708..ff6df21c3d36 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -826,6 +826,8 @@ int read_platform_resources_from_drv_data( "qcom,ubwc_stats_in_fbd"); res->has_vpp_delay = find_key_value(platform_data, "qcom,vpp_delay_supported"); + res->enc_auto_dynamic_fps = find_key_value(platform_data, + "qcom,enc_auto_dynamic_fps"); res->csc_coeff_data = &platform_data->csc_data; diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index c8f20b258ac2..d7c8ee88b887 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -205,6 +205,7 @@ struct msm_vidc_platform_resources { struct cx_ipeak_client *cx_ipeak_context; uint32_t ubwc_stats_in_fbd; uint32_t has_vpp_delay; + bool enc_auto_dynamic_fps; }; static inline bool is_iommu_present(struct msm_vidc_platform_resources *res) From 5de4c1dce46ec51c942869e66a790ee8064ddb94 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Thu, 4 Jun 2020 11:56:11 +0530 Subject: [PATCH 290/452] msm: vidc: configure work mode for 720p For 720p or lower, video hardware can run only in a specific work mode. Fix the condition, so that the work mode is configured as desired by firmware CRs-Fixed: 2699234 Change-Id: I8f9ad5030e7a83075a9d2d1bfe2fc39774f4aa56 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_clocks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 5f267bc951ae..7998c00e002c 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1317,7 +1317,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) if (inst->session_type == MSM_VIDC_DECODER) { height = out_f->fmt.pix_mp.height; width = out_f->fmt.pix_mp.width; - res_ok = res_is_less_than(width, height, 1280, 720); + res_ok = res_is_less_than_or_equal_to(width, height, 1280, 720); if (inp_f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_MPEG2 || inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE || inst->clk_data.low_latency_mode || res_ok) { From 77ffbca8ebcbe5d2b6ba3b07d45bfd2d02040731 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Thu, 14 May 2020 03:18:44 +0530 Subject: [PATCH 291/452] msm: vidc: Add platform capabilities for holi Add platform capabilities for holi target. CRs-Fixed: 2684474 Change-Id: I15560796a4297632d58556f2027494d26e0855c5 Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_platform.c | 148 +++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index ddf55e190a6b..3d63a1423a72 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -71,6 +71,14 @@ static struct msm_vidc_codec_data bengal_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 0, 440, 440), }; +static struct msm_vidc_codec_data holi_codec_data[] = { + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 0, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 0, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 0, 440, 440), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 0, 440, 440), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 0, 440, 440), +}; + #define ENC HAL_VIDEO_DOMAIN_ENCODER #define DEC HAL_VIDEO_DOMAIN_DECODER #define H264 HAL_VIDEO_CODEC_H264 @@ -87,6 +95,12 @@ static struct msm_vidc_codec bengal_codecs[] = { {ENC, H264}, {ENC, HEVC}, }; +static struct msm_vidc_codec holi_codecs[] = { + /* {domain, codec} */ + {DEC, H264}, {DEC, HEVC}, {DEC, VP9}, + {ENC, H264}, {ENC, HEVC}, +}; + static struct msm_vidc_codec default_codecs[] = { /* {domain, codec} */ {DEC, H264}, {DEC, HEVC}, {DEC, VP9}, {DEC, MPEG2}, @@ -213,6 +227,69 @@ static struct msm_vidc_codec_capability bengal_capabilities_v1[] = { V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1}, }; +static struct msm_vidc_codec_capability holi_capabilities[] = { + /* {cap_type, domains, codecs, min, max, step_size, default_value} */ + {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1080}, + /* ((1920 * 1088) / 256) */ + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 8160, 1, 8160}, + /* 1080@30 decode + 1080@30 encode */ + {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 64, 489600, 1, 244800}, + {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 120, 1, 30}, + {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 60000000, 1, 20000000}, + {CAP_CABAC_BITRATE, ENC, H264, 1, 60000000, 1, 20000000}, + {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, + {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 4, 1, 0}, + /* ((1920 * 1088) / 256) * 30 fps */ + {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, + 0, 244800, 1, 244800}, + {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, + {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + + /* 10 slices */ + {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_SLICE_MB, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, + + /* Secure usecase specific */ + {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1080}, + /* (1920 * 1088) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 8160, 1, 8160}, + {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 35000000, 1, 20000000}, + + /* All intra encoding usecase specific */ + {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 30, 1, 30}, + + /* Image specific */ + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 1, 8192}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192}, + + /* Level for AVC and HEVC encoder specific. + * Default for levels is UNKNOWN value. But if we use unknown + * value here to set as default, max value needs to be set to + * unknown as well, which creates a problem of allowing client + * to set higher level than supported + */ + {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_1}, + {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1}, + + /* Level for AVC and HEVC decoder specific */ + {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_1}, + {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1}, +}; + static struct msm_vidc_codec_capability lahaina_capabilities[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 8192, 1, 1920}, @@ -585,6 +662,53 @@ static struct msm_vidc_common_data bengal_common_data_v1[] = { }, }; +static struct msm_vidc_common_data holi_common_data[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 3, + }, + { + .key = "qcom,max-hw-load", + .value = 489600, /* ((1088x1920)/256)@60fps */ + }, + { + .key = "qcom,max-mbpf", + .value = 65280,/* ((3840x2176)/256) x 2 */ + }, + { + .key = "qcom,power-collapse-delay", + .value = 1500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, + { + .key = "qcom,fw-cycles", + .value = 733003, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 225975, + }, +}; + /* Default UBWC config for LPDDR5 */ static struct msm_vidc_ubwc_config_data lahaina_ubwc_data[] = { UBWC_CONFIG(1, 1, 1, 0, 0, 0, 8, 32, 16, 0, 0), @@ -646,6 +770,26 @@ static struct msm_vidc_platform_data bengal_data = { .codec_caps_count = ARRAY_SIZE(bengal_capabilities_v0), }; +static struct msm_vidc_platform_data holi_data = { + .codec_data = holi_codec_data, + .codec_data_length = ARRAY_SIZE(holi_codec_data), + .common_data = holi_common_data, + .common_data_length = ARRAY_SIZE(holi_common_data), + .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, + .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, + .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, + .efuse_data = NULL, + .efuse_data_length = 0, + .sku_version = 0, + .vpu_ver = VPU_VERSION_AR50_LITE, + .num_vpp_pipes = 0x1, + .ubwc_config = 0x0, + .codecs = holi_codecs, + .codecs_count = ARRAY_SIZE(holi_codecs), + .codec_caps = holi_capabilities, + .codec_caps_count = ARRAY_SIZE(holi_capabilities), +}; + static const struct of_device_id msm_vidc_dt_device[] = { { .compatible = "qcom,lahaina-vidc", @@ -655,6 +799,10 @@ static const struct of_device_id msm_vidc_dt_device[] = { .compatible = "qcom,bengal-vidc", .data = &bengal_data, }, + { + .compatible = "qcom,holi-vidc", + .data = &holi_data, + }, {}, }; From 9ea86bc34d54353bff0cb51e64113f1cb486cff8 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Thu, 14 May 2020 22:51:15 +0530 Subject: [PATCH 292/452] msm: vidc: Add config files for holi Add video config files for holi to enable the video driver for holi target CRs-Fixed: 2684474 Change-Id: I7aaf47f2616300665bfe155aface8aa5ed9e4d6e --- Makefile | 9 +++++++++ config/holivid.conf | 5 +++++ config/holividconf.h | 6 ++++++ 3 files changed, 20 insertions(+) create mode 100644 config/holivid.conf create mode 100644 config/holividconf.h diff --git a/Makefile b/Makefile index 707ce2c2d67a..3fdadb733a2e 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,15 @@ include $(srctree)/techpack/video/config/konavid.conf LINUXINCLUDE += -include $(srctree)/techpack/video/config/konavidconf.h endif +# auto-detect subdirs +ifeq ($(CONFIG_ARCH_HOLI), y) +include $(srctree)/techpack/video/config/holivid.conf +endif + +ifeq ($(CONFIG_ARCH_HOLI), y) +LINUXINCLUDE += -include $(srctree)/techpack/video/config/holividconf.h +endif + # auto-detect subdirs ifeq ($(CONFIG_ARCH_LITO), y) include $(srctree)/techpack/video/config/litovid.conf diff --git a/config/holivid.conf b/config/holivid.conf new file mode 100644 index 000000000000..65eae99c590b --- /dev/null +++ b/config/holivid.conf @@ -0,0 +1,5 @@ +ifeq ($(CONFIG_QGKI),y) +export CONFIG_MSM_VIDC_V4L2=y +else +export CONFIG_MSM_VIDC_V4L2=m +endif diff --git a/config/holividconf.h b/config/holividconf.h new file mode 100644 index 000000000000..594a99490792 --- /dev/null +++ b/config/holividconf.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#define CONFIG_MSM_VIDC_V4L2 1 From 0db29bbac37f4e4754e77bc99d7a921639ca0732 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Mon, 1 Jun 2020 00:50:26 +0530 Subject: [PATCH 293/452] msm: vidc: Configure video context bank for best fit With best fit configuration, the probability of getting a mapping for video buffer increases even when the system is fragmented. Change-Id: I8689447ce1341fd1189b543eb9fb6a2e03edcc94 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_res_parse.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index ff6df21c3d36..ca4cd5b442c4 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include "msm_vidc_debug.h" @@ -968,6 +969,12 @@ static int msm_vidc_setup_context_bank(struct msm_vidc_platform_resources *res, cb->domain = iommu_get_domain_for_dev(cb->dev); + /* + * When memory is fragmented, below configuration increases the + * possibility to get a mapping for buffer in the configured CB. + */ + iommu_dma_enable_best_fit_algo(cb->dev); + /* * configure device segment size and segment boundary to ensure * iommu mapping returns one mapping (which is required for partial From b62727af64a3d8c5a5edb6654f8203178a7aea29 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Tue, 9 Jun 2020 10:54:08 +0530 Subject: [PATCH 294/452] msm: vidc: Bail_out missing platform_data cases during probe During msm_vidc_probe, core->platform_data will be NULL, if there is no match with compatible string in the of_dt table. In msm_decide_dt_node sku-index check will be by passed due to default value(0) i.e leading to NULL ptr dereference exception in msm_vidc_init_core_clk_ops. So added check to avoid subsequent calls, if core->platform_data is NULL. Change-Id: I335a2836b2e34e79dcb8743816205d23f798617d Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_v4l2_vidc.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index 53eee0685228..48d435af9fbc 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -261,17 +261,28 @@ static int read_platform_resources(struct msm_vidc_core *core, __func__, core, pdev); return -EINVAL; } + if (!pdev->dev.of_node) { + d_vpr_e("%s: pdev node is NULL\n", __func__); + return -EINVAL; + } + core->hfi_type = VIDC_HFI_VENUS; core->resources.pdev = pdev; - if (pdev->dev.of_node) { - /* Target supports DT, parse from it */ - rc = read_platform_resources_from_drv_data(core); - rc = read_platform_resources_from_dt(&core->resources); - } else { - d_vpr_e("pdev node is NULL\n"); - rc = -EINVAL; + /* Target supports DT, parse from it */ + rc = read_platform_resources_from_drv_data(core); + if (rc) { + d_vpr_e("%s: read platform resources from driver failed\n", + __func__); + return rc; } - return rc; + + rc = read_platform_resources_from_dt(&core->resources); + if (rc) { + d_vpr_e("%s: read platform resources from dt failed\n", + __func__); + return rc; + } + return 0; } static int msm_vidc_initialize_core(struct platform_device *pdev, From 5640d137186f55356b133a2ec03f4f163807695c Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Wed, 3 Jun 2020 00:21:59 +0530 Subject: [PATCH 295/452] msm: vidc: Update min resolution capability Update min resolution support from 128x128 to 96x96 for decoder Change-Id: Ib6b09af6c00323b67a1f50887d80e59148e6cfd8 Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_platform.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index ddf55e190a6b..11132f13d93c 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -215,12 +215,16 @@ static struct msm_vidc_codec_capability bengal_capabilities_v1[] = { static struct msm_vidc_codec_capability lahaina_capabilities[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ - {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 8192, 1, 1920}, - {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 8192, 1, 1080}, + {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 8192, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 8192, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 8192, 1, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 8192, 1, 1080}, /* (8192 * 4320) / 256 */ - {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 138240, 1, 138240}, + {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 138240, 1, 138240}, + {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 138240, 1, 138240}, /* ((1920 * 1088) / 256) * 960 fps */ - {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 64, 7833600, 1, 7833600}, + {CAP_MBS_PER_SECOND, DEC, CODECS_ALL, 36, 7833600, 1, 7833600}, + {CAP_MBS_PER_SECOND, ENC, CODECS_ALL, 64, 7833600, 1, 7833600}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 960, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 220000000, 1, 20000000}, {CAP_BITRATE, ENC, HEVC, 1, 160000000, 1, 20000000}, @@ -247,24 +251,27 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, /* Mpeg2 decoder specific */ - {CAP_FRAME_WIDTH, DEC, MPEG2, 128, 1920, 1, 1920}, - {CAP_FRAME_HEIGHT, DEC, MPEG2, 128, 1920, 1, 1080}, + {CAP_FRAME_WIDTH, DEC, MPEG2, 96, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, MPEG2, 96, 1920, 1, 1080}, /* (1920 * 1088) / 256 */ - {CAP_MBS_PER_FRAME, DEC, MPEG2, 64, 8160, 1, 8160}, + {CAP_MBS_PER_FRAME, DEC, MPEG2, 36, 8160, 1, 8160}, /* ((1920 * 1088) / 256) * 30*/ - {CAP_MBS_PER_SECOND, DEC, MPEG2, 64, 244800, 1, 244800}, + {CAP_MBS_PER_SECOND, DEC, MPEG2, 36, 244800, 1, 244800}, {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, /* Secure usecase specific */ - {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1920}, - {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 1, 1080}, /* (4096 * 2304) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 36864, 1, 36864}, + {CAP_SECURE_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 36864, 1, 36864}, + {CAP_SECURE_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 36864, 1, 36864}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, /* Batch Mode Decode */ - {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 64, 34816, 1, 34816}, + {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 36, 34816, 1, 34816}, /* (4096 * 2176) / 256 */ {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 120, 1, 120}, From e98028956eb67708f01f224fec87246da7043b2c Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 3 Jun 2020 15:36:44 +0530 Subject: [PATCH 296/452] msm: vidc: Ignore thumbnail session load Thumbnail sessions are considered to be non realtime sessions. Hence ignore the thumbnail sessions load on device while calculating the load and mark thumbnail sessions as perf session. Change-Id: Ifa89c2f670fa631b6805a5d796a04e07e294ca4c Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc.c | 7 ++++--- msm/vidc/msm_vidc_common.c | 15 ++++++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index bf40eeef23a8..180b6a39eb97 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -414,10 +414,11 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, } /* - * set perf mode for image session buffers so that - * they will be processed quickly + * set perf mode for image and thumbnail session buffers + * so that they will be processed quickly */ - if (is_grid_session(inst) && b->type == INPUT_MPLANE) + if ((is_grid_session(inst) || is_thumbnail_session(inst)) + && b->type == INPUT_MPLANE) b->flags |= V4L2_BUF_FLAG_PERF_MODE; timestamp_us = (u64)((b->timestamp.tv_sec * 1000000ULL) + diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 071e616eec90..d22a7c85d0ea 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -735,15 +735,20 @@ int msm_comm_get_inst_load(struct msm_vidc_inst *inst, * | Power Request Load = | * | res * max(op, fps)| * ----------------|----------------------------| - * NON-REALTIME/ | Admission Control Load = 0 | - * THUMBNAIL | Power Request Load = | + * NON-REALTIME | Admission Control Load = 0 | + * | Power Request Load = | * | res * max(op, fps)| * ----------------|----------------------------| + * THUMBNAIL | Always Load = 0 | + * | Perf mode added for | + * | thumbnail session buffers | + * | for faster decoding. | + * ----------------|----------------------------| */ - if ((is_thumbnail_session(inst) || - !is_realtime_session(inst)) && - quirks == LOAD_ADMISSION_CONTROL) { + if (is_thumbnail_session(inst) || + (!is_realtime_session(inst) && + quirks == LOAD_ADMISSION_CONTROL)) { load = 0; } else { load = msm_comm_get_mbs_per_sec(inst, quirks); From dfe241edf23daf3c1ccbb79b02798965123fad98 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Fri, 12 Jun 2020 13:30:10 -0700 Subject: [PATCH 297/452] msm: vidc: Increase reset delay to 400us Increase the delay between reset assert and deassert to a minimum of 400us, as required for Lahaina power sequence. Change-Id: I8fb77b0746a7cc68ad3925b2e22b402cd0ff8070 Signed-off-by: Mihir Ganu --- msm/vidc/hfi_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 88dd892ded14..915a7c6bf4e5 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -3107,7 +3107,7 @@ int __reset_ahb2axi_bridge_common(struct venus_hfi_device *device, u32 sid) } /* wait for deassert */ - usleep_range(150, 250); + usleep_range(400, 500); rc = __handle_reset_clk(device->res, i, DEASSERT, sid); if (rc) { From d9dcb1e6a3508f8eb5801ec85995c6a1d9043b1f Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 15 Jun 2020 11:24:56 +0530 Subject: [PATCH 298/452] msm: vidc: add shima platform configs Add configurations specific to shima platform as per H/W and spec. Eg: Codec data, performance configs, fuse etc. Change-Id: I4918af58dcafba3aaafa5eeaaaec256f8cbdca37 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_platform.c | 707 +++++++++++++++++++++++++++++++++++ 1 file changed, 707 insertions(+) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 91838505d0b7..00683754e34b 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -71,6 +71,15 @@ static struct msm_vidc_codec_data bengal_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 0, 440, 440), }; +static struct msm_vidc_codec_data shima_codec_data[] = { + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 0, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 0, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 0, 200, 200), +}; + static struct msm_vidc_codec_data holi_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 0, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 0, 675, 320), @@ -95,6 +104,12 @@ static struct msm_vidc_codec bengal_codecs[] = { {ENC, H264}, {ENC, HEVC}, }; +static struct msm_vidc_codec shima_codecs[] = { + /* {domain, codec} */ + {DEC, H264}, {DEC, HEVC}, {DEC, VP9}, {DEC, MPEG2}, + {ENC, H264}, {ENC, HEVC}, +}; + static struct msm_vidc_codec holi_codecs[] = { /* {domain, codec} */ {DEC, H264}, {DEC, HEVC}, {DEC, VP9}, @@ -390,6 +405,281 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { V4L2_MPEG_VIDEO_HEVC_LEVEL_5}, }; +static struct msm_vidc_codec_capability shima_capabilities_v0[] = { + /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ + {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 8192, 1, 1920}, + {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 8192, 1, 1080}, + /* (8192 * 4320) / 256 */ + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 138240, 1, 138240}, + {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 480, 1, 30}, + + /* Encode spec - 4K@60 */ + /* ((3840 * 2176) / 256) * 60 fps */ + {CAP_MBS_PER_SECOND, ENC, CODECS_ALL, 64, 1958400, 1, 489600}, + + /* Decode spec - 8K@30, 4k@120*/ + /* ((8192 * 4320) / 256) * 30 fps */ + {CAP_MBS_PER_SECOND, DEC, CODECS_ALL, 64, 4147200, 1, 979200}, + + {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 160000000, 1, 20000000}, + {CAP_CABAC_BITRATE, ENC, H264, 1, 160000000, 1, 20000000}, + {CAP_SCALE_X, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, + {CAP_SCALE_Y, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, + {CAP_SCALE_X, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, + {CAP_SCALE_Y, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, + {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, + {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, + {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 4, 1, 0}, + /* ((1920 * 1088) / 256) * 60 fps */ + {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, + 0, 489600, 1, 489600}, + {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, + {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + /* 10 slices */ + {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_SLICE_MB, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, + + /* Mpeg2 decoder specific */ + {CAP_FRAME_WIDTH, DEC, MPEG2, 128, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, MPEG2, 128, 1920, 1, 1080}, + /* (1920 * 1088) / 256 */ + {CAP_MBS_PER_FRAME, DEC, MPEG2, 64, 8160, 1, 8160}, + /* ((1920 * 1088) / 256) * 30*/ + {CAP_MBS_PER_SECOND, DEC, MPEG2, 64, 244800, 1, 244800}, + {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, + {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, + + /* Secure usecase specific */ + {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1080}, + /* (3840 * 2176) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 34816, 1, 8160}, + {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, + + /* Batch Mode Decode */ + {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 64, 8160, 1, 8160}, + /* (1920 * 1088) / 256 */ + {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 60, 1, 60}, + + /* Lossless encoding usecase specific */ + {CAP_LOSSLESS_FRAME_WIDTH, ENC, H264|HEVC, 128, 4096, 1, 1920}, + {CAP_LOSSLESS_FRAME_HEIGHT, ENC, H264|HEVC, 128, 4096, 1, 1080}, + /* (4096 * 2176) / 256 */ + {CAP_LOSSLESS_MBS_PER_FRAME, ENC, H264|HEVC, 64, 34816, 1, 8160}, + + /* All intra encoding usecase specific */ + {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 120, 1, 30}, + + /* Image specific */ + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 16384, 1, 16384}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 16384, 1, 16384}, + + /* + * Level for AVC and HEVC encoder specific. + * Default for levels is UNKNOWN value. But if we use unknown + * value here to set as default, max value needs to be set to + * unknown as well, which creates a problem of allowing client + * to set higher level than supported. + */ + {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, + {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, + + /* Level for AVC and HEVC decoder specific */ + {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, + {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, +}; + +static struct msm_vidc_codec_capability shima_capabilities_v1[] = { + /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ + {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1080}, + /* ((4096 * 2176) / 256) */ + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 34816, 1, 8160}, + /* ((3840 * 2176) / 256) * 60 fps */ + {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 64, 1958400, 1, 489600}, + {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 480, 1, 30}, + + {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 100000000, 1, 20000000}, + {CAP_CABAC_BITRATE, ENC, H264, 1, 100000000, 1, 20000000}, + {CAP_SCALE_X, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, + {CAP_SCALE_Y, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, + {CAP_SCALE_X, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, + {CAP_SCALE_Y, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, + {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, + {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, + {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 4, 1, 0}, + /* ((1920 * 1088) / 256) * 30 fps */ + {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, + 0, 244800, 1, 244800}, + {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, + {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + /* 10 slices */ + {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_SLICE_MB, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, + + /* Mpeg2 decoder specific */ + {CAP_FRAME_WIDTH, DEC, MPEG2, 128, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, MPEG2, 128, 1920, 1, 1080}, + /* (1920 * 1088) / 256 */ + {CAP_MBS_PER_FRAME, DEC, MPEG2, 64, 8160, 1, 8160}, + /* ((1920 * 1088) / 256) * 30 */ + {CAP_MBS_PER_SECOND, DEC, MPEG2, 64, 244800, 1, 244800}, + {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, + {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, + + /* Secure usecase specific */ + {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1080}, + /* (4096 * 2176) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 34816, 1, 8160}, + {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, + + /* Batch Mode Decode */ + {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 64, 8160, 1, 8160}, + /* (1920 * 1088) / 256 */ + {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, + + /* Lossless encoding usecase specific */ + {CAP_LOSSLESS_FRAME_WIDTH, ENC, H264|HEVC, 128, 3840, 1, 1920}, + {CAP_LOSSLESS_FRAME_HEIGHT, ENC, H264|HEVC, 128, 3840, 1, 1080}, + /* (3840 * 2176) / 256 */ + {CAP_LOSSLESS_MBS_PER_FRAME, ENC, H264|HEVC, 64, 32640, 1, 8160}, + + /* All intra encoding usecase specific */ + {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 120, 1, 30}, + + /* Image specific */ + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 16384, 1, 16384}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 16384, 1, 16384}, + + /* + * Level for AVC and HEVC encoder specific. + * Default for levels is UNKNOWN value. But if we use unknown + * value here to set as default, max value needs to be set to + * unknown as well, which creates a problem of allowing client + * to set higher level than supported. + */ + {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, + {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, + + /* Level for AVC and HEVC decoder specific */ + {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, + {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, +}; + +static struct msm_vidc_codec_capability shima_capabilities_v2[] = { + /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ + {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1080}, + /* (4096 * 2176) / 256 */ + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 34816, 1, 8160}, + /* ((3840 * 2176) / 256) * 30 fps */ + {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 64, 979200, 1, 244800}, + {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 240, 1, 30}, + {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 100000000, 1, 20000000}, + {CAP_CABAC_BITRATE, ENC, H264, 1, 100000000, 1, 20000000}, + {CAP_SCALE_X, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, + {CAP_SCALE_Y, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, + {CAP_SCALE_X, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, + {CAP_SCALE_Y, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, + {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, + {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, + {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 2, 1, 0}, + /* ((1920 * 1088) / 256) * 60 fps */ + {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, + 0, 244800, 1, 244800}, + {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, + {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + /* 10 slices */ + {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_SLICE_MB, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, + + /* Mpeg2 decoder specific */ + {CAP_FRAME_WIDTH, DEC, MPEG2, 128, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, MPEG2, 128, 1920, 1, 1080}, + /* (1920 * 1088) / 256 */ + {CAP_MBS_PER_FRAME, DEC, MPEG2, 64, 8160, 1, 8160}, + /* ((1920 * 1088) / 256) * 30*/ + {CAP_MBS_PER_SECOND, DEC, MPEG2, 64, 244800, 1, 244800}, + {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, + {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, + + /* Secure usecase specific */ + {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1080}, + /* (4096 * 2176) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 34816, 1, 8160}, + {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, + + /* Batch Mode Decode */ + {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 64, 8160, 1, 8160}, + /* (1920 * 1088) / 256 */ + {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, + + /* Lossless encoding usecase specific */ + {CAP_LOSSLESS_FRAME_WIDTH, ENC, H264|HEVC, 128, 4096, 1, 1920}, + {CAP_LOSSLESS_FRAME_HEIGHT, ENC, H264|HEVC, 128, 4096, 1, 1080}, + /* (4096 * 2176) / 256 */ + {CAP_LOSSLESS_MBS_PER_FRAME, ENC, H264|HEVC, 64, 34816, 1, 8160}, + + /* All intra encoding usecase specific */ + {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 120, 1, 30}, + + /* Image specific */ + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 16384, 1, 16384}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 16384, 1, 16384}, + + /* + * Level for AVC and HEVC encoder specific. + * Default for levels is UNKNOWN value. But if we use unknown + * value here to set as default, max value needs to be set to + * unknown as well, which creates a problem of allowing client + * to set higher level than supported. + */ + {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, + {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, + + /* Level for AVC and HEVC decoder specific */ + {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, + {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, +}; + /* * Custom conversion coefficients for resolution: 176x144 negative * coeffs are converted to s4.9 format @@ -669,6 +959,334 @@ static struct msm_vidc_common_data bengal_common_data_v1[] = { }, }; +static struct msm_vidc_common_data shima_common_data_v0[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 3, + }, + { + .key = "qcom,max-hw-load", + .value = 4147200, + /** + * (3840x2176)/256)@120fps decode, + * (8192x4320)/256)@30fps decode + */ + }, + { + .key = "qcom,max-mbpf", + .value = 138240, /* ((8192x4320)/256) */ + }, + { + .key = "qcom,max-hq-mbs-per-frame", + .value = 8160, /* ((1920x1088)/256) */ + }, + { + .key = "qcom,max-hq-mbs-per-sec", + .value = 489600, /* ((1920x1088)/256)@60fps */ + }, + { + .key = "qcom,power-collapse-delay", + .value = 1500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,debug-timeout", + .value = 0, + }, + { + .key = "qcom,decode-batching", + .value = 1, + }, + { + .key = "qcom,batch-timeout", + .value = 200, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, + { + .key = "qcom,fw-cycles", + .value = 326389, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 44156, + }, + { + .key = "qcom,avsync-window-size", + .value = 40, + }, + { + .key = "qcom,prefetch_non_pix_buf_count", + .value = 1, + }, + { + .key = "qcom,prefetch_non_pix_buf_size", + /* + * Internal buffer size is calculated for secure decode session + * of resolution 4k (4096x2160) + * Internal buf size = calculate_scratch_size() + + * calculate_scratch1_size() + calculate_persist1_size() + * Take maximum between VP9 10bit, HEVC 10bit, AVC, MPEG2 secure + * decoder sessions + */ + .value = 209715200, + }, + { + .key = "qcom,prefetch_pix_buf_count", + .value = 18, + }, + { + .key = "qcom,prefetch_pix_buf_size", + /* + * Calculated by VENUS_BUFFER_SIZE for 4096x2160 UBWC + */ + .value = 13434880, + }, + { + .key = "qcom,ubwc_stats_in_fbd", + .value = 0, + }, + { + .key = "qcom,vpp_delay_supported", + .value = 0, + }, +}; + +static struct msm_vidc_common_data shima_common_data_v1[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 3, + }, + { + .key = "qcom,max-hw-load", + .value = 1958400, + /** + * (3840x2176)/256)@60fps decode + */ + }, + { + .key = "qcom,max-mbpf", + .value = 130560, /* ((3840x2176)/256) x 4 */ + }, + { + .key = "qcom,max-hq-mbs-per-frame", + .value = 8160, /* ((1920x1088)/256) */ + }, + { + .key = "qcom,max-hq-mbs-per-sec", + .value = 489600, /* ((1920x1088)/256)@60fps */ + }, + { + .key = "qcom,power-collapse-delay", + .value = 1500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,debug-timeout", + .value = 0, + }, + { + .key = "qcom,decode-batching", + .value = 1, + }, + { + .key = "qcom,batch-timeout", + .value = 200, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, + { + .key = "qcom,fw-cycles", + .value = 326389, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 44156, + }, + { + .key = "qcom,avsync-window-size", + .value = 40, + }, + { + .key = "qcom,prefetch_non_pix_buf_count", + .value = 1, + }, + { + .key = "qcom,prefetch_non_pix_buf_size", + /* + * Internal buffer size is calculated for secure decode session + * of resolution 4k (4096x2160) + * Internal buf size = calculate_scratch_size() + + * calculate_scratch1_size() + calculate_persist1_size() + * Take maximum between VP9 10bit, HEVC 10bit, AVC, MPEG2 secure + * decoder sessions + */ + .value = 209715200, + }, + { + .key = "qcom,prefetch_pix_buf_count", + .value = 18, + }, + { + .key = "qcom,prefetch_pix_buf_size", + /* + * Calculated by VENUS_BUFFER_SIZE for 4096x2160 UBWC + */ + .value = 13434880, + }, + { + .key = "qcom,ubwc_stats_in_fbd", + .value = 0, + }, + { + .key = "qcom,vpp_delay_supported", + .value = 0, + }, +}; + +static struct msm_vidc_common_data shima_common_data_v2[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 3, + }, + { + .key = "qcom,max-hw-load", + .value = 979200, + /** + * (3840x2176)/256)@30fps decode + */ + }, + { + .key = "qcom,max-mbpf", + .value = 130560, /* ((3840x2176)/256) x 4 */ + }, + { + .key = "qcom,max-hq-mbs-per-frame", + .value = 8160, /* ((1920x1088)/256) */ + }, + { + .key = "qcom,max-hq-mbs-per-sec", + .value = 489600, /* ((1920x1088)/256)@60fps */ + }, + { + .key = "qcom,power-collapse-delay", + .value = 1500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,debug-timeout", + .value = 0, + }, + { + .key = "qcom,decode-batching", + .value = 1, + }, + { + .key = "qcom,batch-timeout", + .value = 200, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, + { + .key = "qcom,fw-cycles", + .value = 326389, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 44156, + }, + { + .key = "qcom,avsync-window-size", + .value = 40, + }, + { + .key = "qcom,prefetch_non_pix_buf_count", + .value = 1, + }, + { + .key = "qcom,prefetch_non_pix_buf_size", + /* + * Internal buffer size is calculated for secure decode session + * of resolution 4k (4096x2160) + * Internal buf size = calculate_scratch_size() + + * calculate_scratch1_size() + calculate_persist1_size() + * Take maximum between VP9 10bit, HEVC 10bit, AVC, MPEG2 secure + * decoder sessions + */ + .value = 209715200, + }, + { + .key = "qcom,prefetch_pix_buf_count", + .value = 18, + }, + { + .key = "qcom,prefetch_pix_buf_size", + /* + * Calculated by VENUS_BUFFER_SIZE for 4096x2160 UBWC + */ + .value = 13434880, + }, + { + .key = "qcom,ubwc_stats_in_fbd", + .value = 0, + }, + { + .key = "qcom,vpp_delay_supported", + .value = 0, + }, +}; + static struct msm_vidc_common_data holi_common_data[] = { { .key = "qcom,never-unload-fw", @@ -777,6 +1395,26 @@ static struct msm_vidc_platform_data bengal_data = { .codec_caps_count = ARRAY_SIZE(bengal_capabilities_v0), }; +static struct msm_vidc_platform_data shima_data = { + .codec_data = shima_codec_data, + .codec_data_length = ARRAY_SIZE(shima_codec_data), + .common_data = shima_common_data_v0, + .common_data_length = ARRAY_SIZE(shima_common_data_v0), + .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, + .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, + .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, + .efuse_data = NULL, + .efuse_data_length = 0, + .sku_version = 0, + .vpu_ver = VPU_VERSION_IRIS2, + .num_vpp_pipes = 0x2, + .ubwc_config = 0x0, + .codecs = shima_codecs, + .codecs_count = ARRAY_SIZE(shima_codecs), + .codec_caps = shima_capabilities_v0, + .codec_caps_count = ARRAY_SIZE(shima_capabilities_v0), +}; + static struct msm_vidc_platform_data holi_data = { .codec_data = holi_codec_data, .codec_data_length = ARRAY_SIZE(holi_codec_data), @@ -802,6 +1440,10 @@ static const struct of_device_id msm_vidc_dt_device[] = { .compatible = "qcom,lahaina-vidc", .data = &lahaina_data, }, + { + .compatible = "qcom,shima-vidc", + .data = &shima_data, + }, { .compatible = "qcom,bengal-vidc", .data = &bengal_data, @@ -815,6 +1457,48 @@ static const struct of_device_id msm_vidc_dt_device[] = { MODULE_DEVICE_TABLE(of, msm_vidc_dt_device); +static int msm_vidc_read_efuse( + struct msm_vidc_platform_data *data, struct device *dev) +{ + void __iomem *base; + uint32_t i; + u32 efuse = 0; + struct msm_vidc_efuse_data *efuse_data = data->efuse_data; + uint32_t efuse_data_count = data->efuse_data_length; + + if (!efuse_data) + return 0; + + for (i = 0; i < efuse_data_count; i++) { + switch ((efuse_data[i]).purpose) { + case SKU_VERSION: + base = devm_ioremap(dev, (efuse_data[i]).start_address, + (efuse_data[i]).size); + if (!base) { + d_vpr_e("failed efuse: start %#x, size %d\n", + (efuse_data[i]).start_address, + (efuse_data[i]).size); + return -EINVAL; + } else { + efuse = readl_relaxed(base); + data->sku_version = + (efuse & (efuse_data[i]).mask) >> + (efuse_data[i]).shift; + devm_iounmap(dev, base); + } + break; + default: + break; + } + if (data->sku_version) { + d_vpr_h("efuse 0x%x, platform version 0x%x\n", + efuse, data->sku_version); + break; + } + } + return 0; +} + static int msm_vidc_read_rank( struct msm_vidc_platform_data *data, struct device *dev) { @@ -850,6 +1534,13 @@ void *vidc_get_drv_data(struct device *dev) if (!driver_data) goto exit; + /* Check for sku version */ + if (of_find_property(dev->of_node, "sku-index", NULL)) { + rc = msm_vidc_read_efuse(driver_data, dev); + if (rc) + goto exit; + } + if (!strcmp(match->compatible, "qcom,lahaina-vidc")) { ddr_type = of_fdt_get_ddrtype(); if (ddr_type == -ENOENT) { @@ -878,6 +1569,22 @@ void *vidc_get_drv_data(struct device *dev) driver_data->codec_caps_count = ARRAY_SIZE(bengal_capabilities_v1); } + } else if (!strcmp(match->compatible, "qcom,shima-vidc")) { + if (driver_data->sku_version == SKU_VERSION_1) { + driver_data->common_data = shima_common_data_v1; + driver_data->common_data_length = + ARRAY_SIZE(shima_common_data_v1); + driver_data->codec_caps = shima_capabilities_v1; + driver_data->codec_caps_count = + ARRAY_SIZE(shima_capabilities_v1); + } else if (driver_data->sku_version == SKU_VERSION_2) { + driver_data->common_data = shima_common_data_v2; + driver_data->common_data_length = + ARRAY_SIZE(shima_common_data_v2); + driver_data->codec_caps = shima_capabilities_v2; + driver_data->codec_caps_count = + ARRAY_SIZE(shima_capabilities_v2); + } } exit: return driver_data; From aa1e0df29bcb1bd5c220237a486cf813b1668fca Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 10 Apr 2020 20:47:07 +0530 Subject: [PATCH 299/452] msm: vidc: add fuse support for shima shima supports 3 target variants. [1] fuse IRIS_MULTIPIPE_DISABLE - max 4K@30 [2] fuse IRIS_4K60_FMAX_LIMIT_EFUSE - max 4K@60 [3] no fuse blown - max 4K@120 decode Change-Id: I2a42fd80f067202b4b9ac62a0c6d548fcb2705c8 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_platform.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 00683754e34b..6e65c86735ca 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1334,6 +1334,13 @@ static struct msm_vidc_common_data holi_common_data[] = { }, }; +static struct msm_vidc_efuse_data shima_efuse_data[] = { + /* IRIS_4K60_FMAX_LIMIT_EFUSE - max 4K@60 */ + EFUSE_ENTRY(0x007801E0, 4, 0x00200000, 0x15, SKU_VERSION), + /* IRIS_MULTIPIPE_DISABLE - max 4K@30 */ + EFUSE_ENTRY(0x007801E0, 4, 0x00001000, 0x0B, SKU_VERSION), +}; + /* Default UBWC config for LPDDR5 */ static struct msm_vidc_ubwc_config_data lahaina_ubwc_data[] = { UBWC_CONFIG(1, 1, 1, 0, 0, 0, 8, 32, 16, 0, 0), @@ -1403,8 +1410,8 @@ static struct msm_vidc_platform_data shima_data = { .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, - .efuse_data = NULL, - .efuse_data_length = 0, + .efuse_data = shima_efuse_data, + .efuse_data_length = ARRAY_SIZE(shima_efuse_data), .sku_version = 0, .vpu_ver = VPU_VERSION_IRIS2, .num_vpp_pipes = 0x2, From 588b71a376323f7048dec874930c46d5bdeaea67 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Thu, 2 Apr 2020 16:39:48 +0530 Subject: [PATCH 300/452] msm: vidc: update workroute settings for shima use num_vpp_pipes from platform_data to configure workroute. Change-Id: I5fea0d381402f9877fdb5d0df179bc0857016c56 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_clocks.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 791fe244b340..82fb3e8e16c8 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1118,7 +1118,8 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) u32 codec; uint32_t vpu; - if (!inst || !inst->core || !inst->core->device) { + if (!inst || !inst->core || !inst->core->device || + !inst->core->platform_data) { d_vpr_e("%s: Invalid args: Inst = %pK\n", __func__, inst); return -EINVAL; @@ -1127,7 +1128,7 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) vpu = inst->core->platform_data->vpu_ver; hdev = inst->core->device; is_legacy_cbr = inst->clk_data.is_legacy_cbr; - pdata.video_work_route = 4; + pdata.video_work_route = inst->core->platform_data->num_vpp_pipes; if (vpu == VPU_VERSION_IRIS2_1) { pdata.video_work_route = 1; From 96620e5dff2037fae00e763e560608fe6088e32d Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 22 May 2020 22:28:27 +0530 Subject: [PATCH 301/452] msm: vidc: update hbb bit based on ddr type for shima Update highest_bank_bit for shima based on ddr type. LPDDR5 - 15, LPDDR4 - 14. Change-Id: I04d404da18fe9acea4564e4cefe89e3293f5ae13 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_platform.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 6e65c86735ca..b5dba03ad97d 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1346,6 +1346,11 @@ static struct msm_vidc_ubwc_config_data lahaina_ubwc_data[] = { UBWC_CONFIG(1, 1, 1, 0, 0, 0, 8, 32, 16, 0, 0), }; +/* Default UBWC config for LPDDR5 */ +static struct msm_vidc_ubwc_config_data shima_ubwc_data[] = { + UBWC_CONFIG(1, 1, 1, 0, 0, 0, 8, 32, 15, 0, 0), +}; + static struct msm_vidc_platform_data default_data = { .codec_data = default_codec_data, .codec_data_length = ARRAY_SIZE(default_codec_data), @@ -1415,7 +1420,7 @@ static struct msm_vidc_platform_data shima_data = { .sku_version = 0, .vpu_ver = VPU_VERSION_IRIS2, .num_vpp_pipes = 0x2, - .ubwc_config = 0x0, + .ubwc_config = shima_ubwc_data, .codecs = shima_codecs, .codecs_count = ARRAY_SIZE(shima_codecs), .codec_caps = shima_capabilities_v0, @@ -1592,6 +1597,19 @@ void *vidc_get_drv_data(struct device *dev) driver_data->codec_caps_count = ARRAY_SIZE(shima_capabilities_v2); } + ddr_type = of_fdt_get_ddrtype(); + if (ddr_type == -ENOENT) { + d_vpr_e("Failed to get ddr type, use LPDDR5\n"); + } + + if (driver_data->ubwc_config && + (ddr_type == DDR_TYPE_LPDDR4 || + ddr_type == DDR_TYPE_LPDDR4X)) + driver_data->ubwc_config->highest_bank_bit = 0xe; + + d_vpr_h("DDR Type 0x%x hbb 0x%x\n", + ddr_type, driver_data->ubwc_config ? + driver_data->ubwc_config->highest_bank_bit : -1); } exit: return driver_data; From 06532ebf6516a51f6271b59a90dcb4344d512f88 Mon Sep 17 00:00:00 2001 From: Divya Sharma Date: Tue, 16 Jun 2020 18:13:36 -0700 Subject: [PATCH 302/452] Revert "msm: vidc: Initialize ubwc_stats_lock" This reverts commit d05afd5d286fec95cc54176337b28608ffcd1ad2. --- msm/vidc/msm_vidc.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index cba813cddd3d..48237519f11a 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1459,7 +1459,6 @@ void *msm_vidc_open(int core_id, int session_type) mutex_init(&inst->bufq[INPUT_PORT].lock); mutex_init(&inst->lock); mutex_init(&inst->flush_lock); - mutex_init(&inst->ubwc_stats_lock); INIT_MSM_VIDC_LIST(&inst->scratchbufs); INIT_MSM_VIDC_LIST(&inst->input_crs); @@ -1563,7 +1562,6 @@ void *msm_vidc_open(int core_id, int session_type) vb2_queue_release(&inst->bufq[OUTPUT_PORT].vb2_bufq); fail_bufq_capture: msm_comm_ctrl_deinit(inst); - mutex_destroy(&inst->ubwc_stats_lock); mutex_destroy(&inst->sync_lock); mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); mutex_destroy(&inst->bufq[INPUT_PORT].lock); @@ -1709,7 +1707,6 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) DEINIT_MSM_VIDC_LIST(&inst->window_data); DEINIT_MSM_VIDC_LIST(&inst->timestamps); - mutex_destroy(&inst->ubwc_stats_lock); mutex_destroy(&inst->sync_lock); mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); mutex_destroy(&inst->bufq[INPUT_PORT].lock); From d0d60bbc2a5ef3d45e6dead47ed6adce77fd88ef Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Wed, 17 Jun 2020 14:50:04 +0800 Subject: [PATCH 303/452] msm: vidc: increase h265 decoder max slice count For 8K video, bse-vpp delay is 6, and one frame may have maximum 600 slices according to h265 spec, so need to increase max slice count to 3600 to allocate large working buffer size for worst case. Change-Id: Iab035b4cbe8c0121bf1e63d4f3e18c9436a16f5d Signed-off-by: Qiwei Liu --- msm/vidc/msm_vidc_buffer_calculations.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index e99e2fc7aee2..694778094289 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -142,7 +142,7 @@ #define LCU_MAX_SIZE_PELS 64 #define LCU_MIN_SIZE_PELS 16 -#define H265D_MAX_SLICE 1200 +#define H265D_MAX_SLICE 3600 #define SIZE_H265D_HW_PIC_T SIZE_H264D_HW_PIC_T #define SIZE_H265D_BSE_CMD_PER_BUF (16 * sizeof(u32)) #define SIZE_H265D_VPP_CMD_PER_BUF 256 From 8dc245dc59f97474a861ccbb144e02ac6af10432 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Tue, 16 Jun 2020 12:45:20 -0700 Subject: [PATCH 304/452] msm: vidc: Delay force firmware unload by 1sec Video instances might still be alive at the time firmware unload handler is called. As a result, firmware unload request is not propagated to firmware. Add place holder to increase default delay for this request to 1sec to wait until all instances are closed and successfully unload firmware. Change-Id: Id1e7455d40c1808690148046f9a839f1b79574ae --- msm/vidc/msm_vidc_platform.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index b5dba03ad97d..76ddec62c6b4 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -705,6 +705,10 @@ static struct msm_vidc_common_data default_common_data[] = { .key = "qcom,never-unload-fw", .value = 1, }, + { + .key = "qcom,fw-unload-delay", + .value = 1000, + }, }; static struct msm_vidc_common_data lahaina_common_data[] = { @@ -712,6 +716,10 @@ static struct msm_vidc_common_data lahaina_common_data[] = { .key = "qcom,never-unload-fw", .value = 1, }, + { + .key = "qcom,fw-unload-delay", + .value = 1000, + }, { .key = "qcom,sw-power-collapse", .value = 1, @@ -838,6 +846,10 @@ static struct msm_vidc_common_data bengal_common_data_v0[] = { .key = "qcom,never-unload-fw", .value = 1, }, + { + .key = "qcom,fw-unload-delay", + .value = 1000, + }, { .key = "qcom,sw-power-collapse", .value = 1, @@ -901,6 +913,10 @@ static struct msm_vidc_common_data bengal_common_data_v1[] = { .key = "qcom,never-unload-fw", .value = 1, }, + { + .key = "qcom,fw-unload-delay", + .value = 1000, + }, { .key = "qcom,sw-power-collapse", .value = 1, @@ -964,6 +980,10 @@ static struct msm_vidc_common_data shima_common_data_v0[] = { .key = "qcom,never-unload-fw", .value = 1, }, + { + .key = "qcom,fw-unload-delay", + .value = 1000, + }, { .key = "qcom,sw-power-collapse", .value = 1, @@ -1074,6 +1094,10 @@ static struct msm_vidc_common_data shima_common_data_v1[] = { .key = "qcom,never-unload-fw", .value = 1, }, + { + .key = "qcom,fw-unload-delay", + .value = 1000, + }, { .key = "qcom,sw-power-collapse", .value = 1, @@ -1183,6 +1207,10 @@ static struct msm_vidc_common_data shima_common_data_v2[] = { .key = "qcom,never-unload-fw", .value = 1, }, + { + .key = "qcom,fw-unload-delay", + .value = 1000, + }, { .key = "qcom,sw-power-collapse", .value = 1, @@ -1292,6 +1320,10 @@ static struct msm_vidc_common_data holi_common_data[] = { .key = "qcom,never-unload-fw", .value = 1, }, + { + .key = "qcom,fw-unload-delay", + .value = 1000, + }, { .key = "qcom,sw-power-collapse", .value = 1, From 53de1be85254a97eebb70a2c00d6cf38494ff77c Mon Sep 17 00:00:00 2001 From: Rakshitha Shakamuri Date: Thu, 4 Jun 2020 21:05:22 -0700 Subject: [PATCH 305/452] msm: vidc: Fix KW error Fixing KW error with ID: 72859, 72860, 72861, 72862, 111827. Change-Id: Ia37cb77b27689c2064e0c4d5138d4f9d95c84455 Signed-off-by: Rakshitha Shakamuri --- msm/vidc/msm_vidc_buffer_calculations.c | 4 +++- msm/vidc/msm_vidc_debug.h | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index e99e2fc7aee2..4f3561b64006 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -376,13 +376,15 @@ int msm_vidc_get_decoder_internal_buffer_sizes(struct msm_vidc_inst *inst) struct msm_vidc_dec_buff_size_calculators *dec_calculators; u32 width, height, i, out_min_count, num_vpp_pipes; struct v4l2_format *f; - u32 vpp_delay = inst->bse_vpp_delay; + u32 vpp_delay; if (!inst || !inst->core || !inst->core->platform_data) { d_vpr_e("%s: Instance is null!", __func__); return -EINVAL; } + vpp_delay = inst->bse_vpp_delay; + num_vpp_pipes = inst->core->platform_data->num_vpp_pipes; f = &inst->fmts[INPUT_PORT].v4l2_fmt; switch (f->fmt.pix_mp.pixelformat) { diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index c7ec5ae0e558..7b523eddb55f 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -228,7 +228,7 @@ static inline char *get_debug_level_str(int level) static inline void tic(struct msm_vidc_inst *i, enum profiling_points p, char *b) { - struct timeval __ddl_tv; + struct timeval __ddl_tv = { 0 }; if (!i->debug.pdata[p].name[0]) memcpy(i->debug.pdata[p].name, b, 64); @@ -243,7 +243,7 @@ static inline void tic(struct msm_vidc_inst *i, enum profiling_points p, static inline void toc(struct msm_vidc_inst *i, enum profiling_points p) { - struct timeval __ddl_tv; + struct timeval __ddl_tv = { 0 }; if ((msm_vidc_debug & VIDC_PERF) && !i->debug.pdata[p].sampling) { From d2690f588936ca59a0b8123b082d0726136c43bc Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Wed, 17 Jun 2020 14:50:04 +0800 Subject: [PATCH 306/452] msm: vidc: increase h265 decoder max slice count For 8K video, bse-vpp delay is 6, and one frame may have maximum 600 slices according to h265 spec, so need to increase max slice count to 3600 to allocate large working buffer size for worst case. Change-Id: Iab035b4cbe8c0121bf1e63d4f3e18c9436a16f5d Signed-off-by: Qiwei Liu --- msm/vidc/msm_vidc_buffer_calculations.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index e99e2fc7aee2..694778094289 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -142,7 +142,7 @@ #define LCU_MAX_SIZE_PELS 64 #define LCU_MIN_SIZE_PELS 16 -#define H265D_MAX_SLICE 1200 +#define H265D_MAX_SLICE 3600 #define SIZE_H265D_HW_PIC_T SIZE_H264D_HW_PIC_T #define SIZE_H265D_BSE_CMD_PER_BUF (16 * sizeof(u32)) #define SIZE_H265D_VPP_CMD_PER_BUF 256 From bc901f21ba80b342fcae2819d0ff4803dc35d536 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 22 Jun 2020 19:00:30 +0530 Subject: [PATCH 307/452] msm: vidc: Align per pipe usage with DMA alignment Currently, total buffer size across pipes is aligned with 256. It should be per pipe usage aligned with 256. Change-Id: I389f2a0539bb04b9d038fe44122da70690c43466 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_buffer_calculations.c | 58 +++++++++++++++---------- msm/vidc/msm_vidc_buffer_calculations.h | 2 +- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 1885f0cfff5c..d9ef661314db 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -269,13 +269,17 @@ static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst); static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst); static inline u32 calculate_h264d_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, bool is_interlaced, u32 delay); + u32 width, u32 height, bool is_interlaced, u32 delay, + u32 num_vpp_pipes); static inline u32 calculate_h265d_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, bool is_interlaced, u32 delay); + u32 width, u32 height, bool is_interlaced, u32 delay, + u32 num_vpp_pipes); static inline u32 calculate_vpxd_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, bool is_interlaced, u32 delay); + u32 width, u32 height, bool is_interlaced, u32 delay, + u32 num_vpp_pipes); static inline u32 calculate_mpeg2d_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, bool is_interlaced, u32 delay); + u32 width, u32 height, bool is_interlaced, u32 delay, + u32 num_vpp_pipes); static inline u32 calculate_enc_scratch_size(struct msm_vidc_inst *inst, u32 width, u32 height, u32 work_mode, u32 lcu_size, u32 num_vpp_pipes); @@ -425,7 +429,7 @@ int msm_vidc_get_decoder_internal_buffer_sizes(struct msm_vidc_inst *inst) curr_req->buffer_size = dec_calculators->calculate_scratch_size( inst, width, height, is_interlaced, - vpp_delay); + vpp_delay, num_vpp_pipes); valid_buffer_type = true; } else if (curr_req->buffer_type == HAL_BUFFER_INTERNAL_SCRATCH_1) { @@ -1153,7 +1157,8 @@ static inline u32 hfi_iris2_h264d_non_comv_size(u32 width, u32 height, return size; } -static inline u32 size_h264d_hw_bin_buffer(u32 width, u32 height, u32 delay) +static inline u32 size_h264d_hw_bin_buffer(u32 width, u32 height, u32 delay, + u32 num_vpp_pipes) { u32 size_yuv, size_bin_hdr, size_bin_res; u32 size = 0; @@ -1168,14 +1173,16 @@ static inline u32 size_h264d_hw_bin_buffer(u32 width, u32 height, u32 delay) size_bin_res = size_yuv * H264_CABAC_RES_RATIO_HD_TOT; size_bin_hdr = size_bin_hdr * (((((u32)(delay)) & 31) / 10) + 2) / 2; size_bin_res = size_bin_res * (((((u32)(delay)) & 31) / 10) + 2) / 2; - size_bin_hdr = ALIGN(size_bin_hdr, VENUS_DMA_ALIGNMENT); - size_bin_res = ALIGN(size_bin_res, VENUS_DMA_ALIGNMENT); + size_bin_hdr = ALIGN(size_bin_hdr / num_vpp_pipes, + VENUS_DMA_ALIGNMENT) * num_vpp_pipes; + size_bin_res = ALIGN(size_bin_res / num_vpp_pipes, + VENUS_DMA_ALIGNMENT) * num_vpp_pipes; size = size_bin_hdr + size_bin_res; return size; } static inline u32 calculate_h264d_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, bool is_interlaced, u32 delay) + u32 width, u32 height, bool is_interlaced, u32 delay, u32 num_vpp_pipes) { u32 aligned_width = ALIGN(width, BUFFER_ALIGNMENT_SIZE(16)); u32 aligned_height = ALIGN(height, BUFFER_ALIGNMENT_SIZE(16)); @@ -1183,7 +1190,7 @@ static inline u32 calculate_h264d_scratch_size(struct msm_vidc_inst *inst, if (!is_interlaced) size = size_h264d_hw_bin_buffer(aligned_width, aligned_height, - delay); + delay, num_vpp_pipes); else size = 0; @@ -1272,7 +1279,8 @@ static inline u32 hfi_iris2_h265d_non_comv_size(u32 width, u32 height, return size; } -static inline u32 size_h265d_hw_bin_buffer(u32 width, u32 height, u32 delay) +static inline u32 size_h265d_hw_bin_buffer(u32 width, u32 height, u32 delay, + u32 num_vpp_pipes) { u32 size = 0; u32 size_yuv, size_bin_hdr, size_bin_res; @@ -1286,15 +1294,17 @@ static inline u32 size_h265d_hw_bin_buffer(u32 width, u32 height, u32 delay) size_bin_res = size_yuv * H265_CABAC_RES_RATIO_HD_TOT; size_bin_hdr = size_bin_hdr * (((((u32)(delay)) & 31) / 10) + 2) / 2; size_bin_res = size_bin_res * (((((u32)(delay)) & 31) / 10) + 2) / 2; - size_bin_hdr = ALIGN(size_bin_hdr, VENUS_DMA_ALIGNMENT); - size_bin_res = ALIGN(size_bin_res, VENUS_DMA_ALIGNMENT); + size_bin_hdr = ALIGN(size_bin_hdr / num_vpp_pipes, + VENUS_DMA_ALIGNMENT) * num_vpp_pipes; + size_bin_res = ALIGN(size_bin_res / num_vpp_pipes, + VENUS_DMA_ALIGNMENT) * num_vpp_pipes; size = size_bin_hdr + size_bin_res; return size; } static inline u32 calculate_h265d_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, bool is_interlaced, u32 delay) + u32 width, u32 height, bool is_interlaced, u32 delay, u32 num_vpp_pipes) { u32 aligned_width = ALIGN(width, BUFFER_ALIGNMENT_SIZE(16)); u32 aligned_height = ALIGN(height, BUFFER_ALIGNMENT_SIZE(16)); @@ -1302,7 +1312,7 @@ static inline u32 calculate_h265d_scratch_size(struct msm_vidc_inst *inst, if (!is_interlaced) size = size_h265d_hw_bin_buffer(aligned_width, aligned_height, - delay); + delay, num_vpp_pipes); else size = 0; @@ -1310,7 +1320,7 @@ static inline u32 calculate_h265d_scratch_size(struct msm_vidc_inst *inst, } static inline u32 calculate_vpxd_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, bool is_interlaced, u32 delay) + u32 width, u32 height, bool is_interlaced, u32 delay, u32 num_vpp_pipes) { u32 aligned_width = ALIGN(width, BUFFER_ALIGNMENT_SIZE(16)); u32 aligned_height = ALIGN(height, BUFFER_ALIGNMENT_SIZE(16)); @@ -1319,20 +1329,22 @@ static inline u32 calculate_vpxd_scratch_size(struct msm_vidc_inst *inst, if (!is_interlaced) { /* binbuffer1_size + binbufer2_size */ - u32 binbuffer1_size = 0, binbufer2_size = 0; + u32 binbuffer1_size = 0, binbuffer2_size = 0; - binbuffer1_size = max_t(u32, size_yuv, + binbuffer1_size = ALIGN(max_t(u32, size_yuv, ((BIN_BUFFER_THRESHOLD * 3) >> 1)) * VPX_DECODER_FRAME_CONCURENCY_LVL * VPX_DECODER_FRAME_BIN_HDR_BUDGET_RATIO_NUM / - VPX_DECODER_FRAME_BIN_HDR_BUDGET_RATIO_DEN; - binbufer2_size = max_t(u32, size_yuv, + VPX_DECODER_FRAME_BIN_HDR_BUDGET_RATIO_DEN, + VENUS_DMA_ALIGNMENT); + binbuffer2_size = ALIGN(max_t(u32, size_yuv, ((BIN_BUFFER_THRESHOLD * 3) >> 1)) * VPX_DECODER_FRAME_CONCURENCY_LVL * VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO_NUM / - VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO_DEN; - size = ALIGN(binbuffer1_size + binbufer2_size, + VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO_DEN, VENUS_DMA_ALIGNMENT); + size = binbuffer1_size + binbuffer2_size; + size = size * num_vpp_pipes; } else { size = 0; } @@ -1341,7 +1353,7 @@ static inline u32 calculate_vpxd_scratch_size(struct msm_vidc_inst *inst, } static inline u32 calculate_mpeg2d_scratch_size(struct msm_vidc_inst *inst, - u32 width, u32 height, bool is_interlaced, u32 delay) + u32 width, u32 height, bool is_interlaced, u32 delay, u32 num_vpp_pipes) { return 0; } diff --git a/msm/vidc/msm_vidc_buffer_calculations.h b/msm/vidc/msm_vidc_buffer_calculations.h index 07c05659eba2..dce14310991e 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.h +++ b/msm/vidc/msm_vidc_buffer_calculations.h @@ -12,7 +12,7 @@ struct msm_vidc_dec_buff_size_calculators { u32 (*calculate_scratch_size)(struct msm_vidc_inst *inst, u32 width, - u32 height, bool is_interlaced, u32 delay); + u32 height, bool is_interlaced, u32 delay, u32 num_vpp_pipes); u32 (*calculate_scratch1_size)(struct msm_vidc_inst *inst, u32 width, u32 height, u32 min_buf_count, bool split_mode_enabled, u32 num_vpp_pipes); From 7b3b1524c45444e32bf8713969fc90e8edb9bd2f Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 24 Jun 2020 20:31:31 +0530 Subject: [PATCH 308/452] msm: vidc: fix deadlock between queue and flush buffer handling qbuf ioctl acquired bufq[port].lock in one thread and flush call acquired registeredbufs.lock in another thread. So thread-1 is waiting for registeredbufs.lock & thread-2 is waiting for bufq[port].lock i.e leading to deadlock. So added change to avoid above mentioned deadlock. Change-Id: Ie21984fdb562ca7a09f801f036f3a78429ceab94 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc.c | 33 +++++++++++++------------- msm/vidc/msm_vidc_common.c | 45 +++++++++++++++++++++++------------- msm/vidc/msm_vidc_internal.h | 2 +- msm/vidc/vidc_hfi_api.h | 7 +++--- 4 files changed, 49 insertions(+), 38 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 180b6a39eb97..3f789a4afe46 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -380,13 +380,21 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, return -EINVAL; } + q = msm_comm_get_vb2q(inst, b->type); + if (!q) { + s_vpr_e(inst->sid, + "Failed to find buffer queue. type %d\n", b->type); + return -EINVAL; + } + + mutex_lock(&q->lock); if ((inst->out_flush && b->type == OUTPUT_MPLANE) || inst->in_flush) { s_vpr_e(inst->sid, "%s: in flush, discarding qbuf, type %u, index %u\n", __func__, b->type, b->index); - return -EINVAL; + rc = -EINVAL; + goto unlock; } - inst->last_qbuf_time_ns = ktime_get_ns(); for (i = 0; i < b->length; i++) { @@ -409,7 +417,8 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, 0, inst->sid); if (rc) { s_vpr_e(inst->sid, "Failed to store input tag"); - return -EINVAL; + rc = -EINVAL; + goto unlock; } } @@ -430,7 +439,7 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, rc = msm_comm_store_timestamp(inst, timestamp_us); if (rc) - return rc; + goto unlock; inst->clk_data.frame_rate = msm_comm_get_max_framerate(inst); } if (is_encode_session(inst) && b->type == INPUT_MPLANE) { @@ -440,21 +449,14 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, rc = msm_venc_store_timestamp(inst, timestamp_us); if (rc) - return rc; + goto unlock; } - q = msm_comm_get_vb2q(inst, b->type); - if (!q) { - s_vpr_e(inst->sid, - "Failed to find buffer queue. type %d\n", b->type); - return -EINVAL; - } - - mutex_lock(&q->lock); rc = vb2_qbuf(&q->vb2_bufq, mdev, b); - mutex_unlock(&q->lock); if (rc) s_vpr_e(inst->sid, "Failed to qbuf, %d\n", rc); +unlock: + mutex_unlock(&q->lock); return rc; } @@ -1485,7 +1487,6 @@ void *msm_vidc_open(int core_id, int session_type) mutex_init(&inst->bufq[OUTPUT_PORT].lock); mutex_init(&inst->bufq[INPUT_PORT].lock); mutex_init(&inst->lock); - mutex_init(&inst->flush_lock); mutex_init(&inst->ubwc_stats_lock); INIT_MSM_VIDC_LIST(&inst->scratchbufs); @@ -1596,7 +1597,6 @@ void *msm_vidc_open(int core_id, int session_type) mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); mutex_destroy(&inst->bufq[INPUT_PORT].lock); mutex_destroy(&inst->lock); - mutex_destroy(&inst->flush_lock); DEINIT_MSM_VIDC_LIST(&inst->scratchbufs); DEINIT_MSM_VIDC_LIST(&inst->persistbufs); @@ -1742,7 +1742,6 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); mutex_destroy(&inst->bufq[INPUT_PORT].lock); mutex_destroy(&inst->lock); - mutex_destroy(&inst->flush_lock); msm_vidc_debugfs_deinit_inst(inst); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index d22a7c85d0ea..4fd181f268ab 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2028,7 +2028,10 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) return; } - mutex_lock(&inst->flush_lock); + if (response->data.flush_type & HAL_FLUSH_INPUT) + mutex_lock(&inst->bufq[INPUT_PORT].lock); + if (response->data.flush_type & HAL_FLUSH_OUTPUT) + mutex_lock(&inst->bufq[OUTPUT_PORT].lock); if (msm_comm_get_stream_output_mode(inst) == HAL_VIDEO_DECODER_SECONDARY) { @@ -2078,7 +2081,10 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) v4l2_event_queue_fh(&inst->event_handler, &flush_event); exit: - mutex_unlock(&inst->flush_lock); + if (response->data.flush_type & HAL_FLUSH_OUTPUT) + mutex_unlock(&inst->bufq[OUTPUT_PORT].lock); + if (response->data.flush_type & HAL_FLUSH_INPUT) + mutex_unlock(&inst->bufq[INPUT_PORT].lock); s_vpr_l(inst->sid, "handled: SESSION_FLUSH_DONE\n"); put_inst(inst); } @@ -2290,7 +2296,7 @@ struct vb2_buffer *msm_comm_get_vb_using_vidc_buffer( return NULL; } - mutex_lock(&inst->bufq[port].lock); + WARN_ON(!mutex_is_locked(&inst->bufq[port].lock)); found = false; q = &inst->bufq[port].vb2_bufq; if (!q->streaming) { @@ -2306,7 +2312,6 @@ struct vb2_buffer *msm_comm_get_vb_using_vidc_buffer( } } unlock: - mutex_unlock(&inst->bufq[port].lock); if (!found) { print_vidc_buffer(VIDC_ERR, "vb2 not found for", inst, mbuf); return NULL; @@ -2321,6 +2326,7 @@ int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst, struct vb2_buffer *vb2; struct vb2_v4l2_buffer *vbuf; u32 i, port; + int rc = 0; if (!inst || !mbuf) { d_vpr_e("%s: invalid params %pK %pK\n", @@ -2335,16 +2341,19 @@ int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst, else return -EINVAL; - vb2 = msm_comm_get_vb_using_vidc_buffer(inst, mbuf); - if (!vb2) - return -EINVAL; - /* * access vb2 buffer under q->lock and if streaming only to * ensure the buffer was not free'd by vb2 framework while * we are accessing it here. */ mutex_lock(&inst->bufq[port].lock); + vb2 = msm_comm_get_vb_using_vidc_buffer(inst, mbuf); + if (!vb2) { + s_vpr_e(inst->sid, "%s: port %d buffer not found\n", + __func__, port); + rc = -EINVAL; + goto unlock; + } if (inst->bufq[port].vb2_bufq.streaming) { vbuf = to_vb2_v4l2_buffer(vb2); vbuf->flags = mbuf->vvb.flags; @@ -2360,9 +2369,10 @@ int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst, s_vpr_e(inst->sid, "%s: port %d is not streaming\n", __func__, port); } +unlock: mutex_unlock(&inst->bufq[port].lock); - return 0; + return rc; } static bool is_eos_buffer(struct msm_vidc_inst *inst, u32 device_addr) @@ -5516,7 +5526,6 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) ip_flush = !!(flags & V4L2_CMD_FLUSH_OUTPUT); op_flush = !!(flags & V4L2_CMD_FLUSH_CAPTURE); - if (ip_flush && !op_flush) { s_vpr_e(inst->sid, "Input only flush not supported, making it flush all\n"); @@ -5539,7 +5548,10 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) goto exit; } - mutex_lock(&inst->flush_lock); + if (ip_flush) + mutex_lock(&inst->bufq[INPUT_PORT].lock); + if (op_flush) + mutex_lock(&inst->bufq[OUTPUT_PORT].lock); /* enable in flush */ inst->in_flush = ip_flush; inst->out_flush = op_flush; @@ -5595,7 +5607,10 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) rc = call_hfi_op(hdev, session_flush, inst->session, HAL_FLUSH_OUTPUT); } - mutex_unlock(&inst->flush_lock); + if (op_flush) + mutex_unlock(&inst->bufq[OUTPUT_PORT].lock); + if (ip_flush) + mutex_unlock(&inst->bufq[INPUT_PORT].lock); if (rc) { s_vpr_e(inst->sid, "Sending flush to firmware failed, flush out all buffers\n"); @@ -6661,7 +6676,6 @@ int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst, else return -EINVAL; - mutex_lock(&inst->bufq[port].lock); if (inst->bufq[port].vb2_bufq.streaming) { vb->planes[0].bytesused = 0; vb2_buffer_done(vb, VB2_BUF_STATE_DONE); @@ -6669,7 +6683,6 @@ int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst, s_vpr_e(inst->sid, "%s: port %d is not streaming\n", __func__, port); } - mutex_unlock(&inst->bufq[port].lock); return 0; } @@ -7015,7 +7028,7 @@ void handle_release_buffer_reference(struct msm_vidc_inst *inst, unsigned int i = 0; u32 planes[VIDEO_MAX_PLANES] = {0}; - mutex_lock(&inst->flush_lock); + mutex_lock(&inst->bufq[OUTPUT_PORT].lock); mutex_lock(&inst->registeredbufs.lock); found = false; /* check if mbuf was not removed by any chance */ @@ -7104,7 +7117,7 @@ void handle_release_buffer_reference(struct msm_vidc_inst *inst, print_vidc_buffer(VIDC_ERR, "rbr qbuf failed", inst, mbuf); } - mutex_unlock(&inst->flush_lock); + mutex_unlock(&inst->bufq[OUTPUT_PORT].lock); } int msm_comm_unmap_vidc_buffer(struct msm_vidc_inst *inst, diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 1ea315bb785d..a10853e87366 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -494,7 +494,7 @@ struct msm_vidc_inst_smem_ops { struct msm_vidc_inst { struct list_head list; - struct mutex sync_lock, lock, flush_lock; + struct mutex sync_lock, lock; struct msm_vidc_core *core; enum session_type session_type; void *session; diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 7ce6be36c68d..84b277520ac8 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -384,10 +384,9 @@ struct hal_fw_info { }; enum hal_flush { - HAL_FLUSH_INPUT, - HAL_FLUSH_OUTPUT, - HAL_FLUSH_ALL, - HAL_UNUSED_FLUSH = 0x10000000, + HAL_FLUSH_INPUT = BIT(0), + HAL_FLUSH_OUTPUT = BIT(1), + HAL_FLUSH_ALL = HAL_FLUSH_INPUT | HAL_FLUSH_OUTPUT, }; enum hal_event_type { From 8fa3a6f8a4a9f6e1cc75593f5972e19da8945269 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Fri, 3 Jul 2020 10:03:17 +0530 Subject: [PATCH 309/452] msm: vidc: Update min resolution capability Update min resolution support from 128x128 to 96x96 for decoder. CRs-Fixed: 2724675 Change-Id: I230d3c5fbdc1d476a634160de30b20e207a5f315 Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_platform.c | 106 ++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 40 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 76ddec62c6b4..6c0e5bf18ccd 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -244,12 +244,16 @@ static struct msm_vidc_codec_capability bengal_capabilities_v1[] = { static struct msm_vidc_codec_capability holi_capabilities[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value} */ - {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1920}, - {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1080}, + {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 1920, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 1920, 1, 1080}, /* ((1920 * 1088) / 256) */ - {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 8160, 1, 8160}, + {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 8160, 1, 8160}, + {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 8160, 1, 8160}, /* 1080@30 decode + 1080@30 encode */ - {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 64, 489600, 1, 244800}, + {CAP_MBS_PER_SECOND, DEC, CODECS_ALL, 36, 489600, 1, 244800}, + {CAP_MBS_PER_SECOND, ENC, CODECS_ALL, 64, 489600, 1, 244800}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 120, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 60000000, 1, 20000000}, {CAP_CABAC_BITRATE, ENC, H264, 1, 60000000, 1, 20000000}, @@ -268,8 +272,10 @@ static struct msm_vidc_codec_capability holi_capabilities[] = { {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, /* Secure usecase specific */ - {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1920}, - {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 1920, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 1920, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 1920, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 1920, 1, 1080}, /* (1920 * 1088) / 256 */ {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 8160, 1, 8160}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 35000000, 1, 20000000}, @@ -407,10 +413,13 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { static struct msm_vidc_codec_capability shima_capabilities_v0[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ - {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 8192, 1, 1920}, - {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 8192, 1, 1080}, + {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 8192, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 8192, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 8192, 1, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 8192, 1, 1080}, /* (8192 * 4320) / 256 */ - {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 138240, 1, 138240}, + {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 138240, 1, 138240}, + {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 138240, 1, 138240}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 480, 1, 30}, /* Encode spec - 4K@60 */ @@ -419,7 +428,7 @@ static struct msm_vidc_codec_capability shima_capabilities_v0[] = { /* Decode spec - 8K@30, 4k@120*/ /* ((8192 * 4320) / 256) * 30 fps */ - {CAP_MBS_PER_SECOND, DEC, CODECS_ALL, 64, 4147200, 1, 979200}, + {CAP_MBS_PER_SECOND, DEC, CODECS_ALL, 36, 4147200, 1, 979200}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 160000000, 1, 20000000}, {CAP_CABAC_BITRATE, ENC, H264, 1, 160000000, 1, 20000000}, @@ -442,24 +451,27 @@ static struct msm_vidc_codec_capability shima_capabilities_v0[] = { {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, /* Mpeg2 decoder specific */ - {CAP_FRAME_WIDTH, DEC, MPEG2, 128, 1920, 1, 1920}, - {CAP_FRAME_HEIGHT, DEC, MPEG2, 128, 1920, 1, 1080}, + {CAP_FRAME_WIDTH, DEC, MPEG2, 96, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, MPEG2, 96, 1920, 1, 1080}, /* (1920 * 1088) / 256 */ - {CAP_MBS_PER_FRAME, DEC, MPEG2, 64, 8160, 1, 8160}, + {CAP_MBS_PER_FRAME, DEC, MPEG2, 36, 8160, 1, 8160}, /* ((1920 * 1088) / 256) * 30*/ - {CAP_MBS_PER_SECOND, DEC, MPEG2, 64, 244800, 1, 244800}, + {CAP_MBS_PER_SECOND, DEC, MPEG2, 36, 244800, 1, 244800}, {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, /* Secure usecase specific */ - {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1920}, - {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 1, 1080}, /* (3840 * 2176) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 34816, 1, 8160}, + {CAP_SECURE_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 34816, 1, 8160}, + {CAP_SECURE_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 8160}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, /* Batch Mode Decode */ - {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 64, 8160, 1, 8160}, + {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 36, 8160, 1, 8160}, /* (1920 * 1088) / 256 */ {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 60, 1, 60}, @@ -503,12 +515,16 @@ static struct msm_vidc_codec_capability shima_capabilities_v0[] = { static struct msm_vidc_codec_capability shima_capabilities_v1[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ - {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1920}, - {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1080}, + {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 1, 1080}, /* ((4096 * 2176) / 256) */ - {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 34816, 1, 8160}, + {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 34816, 1, 8160}, + {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 8160}, /* ((3840 * 2176) / 256) * 60 fps */ - {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 64, 1958400, 1, 489600}, + {CAP_MBS_PER_SECOND, DEC, CODECS_ALL, 36, 1958400, 1, 489600}, + {CAP_MBS_PER_SECOND, ENC, CODECS_ALL, 64, 1958400, 1, 489600}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 480, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 100000000, 1, 20000000}, @@ -532,24 +548,27 @@ static struct msm_vidc_codec_capability shima_capabilities_v1[] = { {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, /* Mpeg2 decoder specific */ - {CAP_FRAME_WIDTH, DEC, MPEG2, 128, 1920, 1, 1920}, - {CAP_FRAME_HEIGHT, DEC, MPEG2, 128, 1920, 1, 1080}, + {CAP_FRAME_WIDTH, DEC, MPEG2, 96, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, MPEG2, 96, 1920, 1, 1080}, /* (1920 * 1088) / 256 */ - {CAP_MBS_PER_FRAME, DEC, MPEG2, 64, 8160, 1, 8160}, + {CAP_MBS_PER_FRAME, DEC, MPEG2, 36, 8160, 1, 8160}, /* ((1920 * 1088) / 256) * 30 */ - {CAP_MBS_PER_SECOND, DEC, MPEG2, 64, 244800, 1, 244800}, + {CAP_MBS_PER_SECOND, DEC, MPEG2, 36, 244800, 1, 244800}, {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, /* Secure usecase specific */ + {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1080}, /* (4096 * 2176) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 34816, 1, 8160}, + {CAP_SECURE_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 34816, 1, 8160}, + {CAP_SECURE_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 8160}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, /* Batch Mode Decode */ - {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 64, 8160, 1, 8160}, + {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 36, 8160, 1, 8160}, /* (1920 * 1088) / 256 */ {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, @@ -593,12 +612,16 @@ static struct msm_vidc_codec_capability shima_capabilities_v1[] = { static struct msm_vidc_codec_capability shima_capabilities_v2[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ - {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1920}, - {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1080}, + {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 1, 1080}, /* (4096 * 2176) / 256 */ - {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 34816, 1, 8160}, + {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 34816, 1, 8160}, + {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 8160}, /* ((3840 * 2176) / 256) * 30 fps */ - {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 64, 979200, 1, 244800}, + {CAP_MBS_PER_SECOND, DEC, CODECS_ALL, 36, 979200, 1, 244800}, + {CAP_MBS_PER_SECOND, ENC, CODECS_ALL, 64, 979200, 1, 244800}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 240, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 100000000, 1, 20000000}, {CAP_CABAC_BITRATE, ENC, H264, 1, 100000000, 1, 20000000}, @@ -621,24 +644,27 @@ static struct msm_vidc_codec_capability shima_capabilities_v2[] = { {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, /* Mpeg2 decoder specific */ - {CAP_FRAME_WIDTH, DEC, MPEG2, 128, 1920, 1, 1920}, - {CAP_FRAME_HEIGHT, DEC, MPEG2, 128, 1920, 1, 1080}, + {CAP_FRAME_WIDTH, DEC, MPEG2, 96, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, MPEG2, 96, 1920, 1, 1080}, /* (1920 * 1088) / 256 */ - {CAP_MBS_PER_FRAME, DEC, MPEG2, 64, 8160, 1, 8160}, + {CAP_MBS_PER_FRAME, DEC, MPEG2, 36, 8160, 1, 8160}, /* ((1920 * 1088) / 256) * 30*/ - {CAP_MBS_PER_SECOND, DEC, MPEG2, 64, 244800, 1, 244800}, + {CAP_MBS_PER_SECOND, DEC, MPEG2, 36, 244800, 1, 244800}, {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, /* Secure usecase specific */ - {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1920}, - {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 1, 1080}, /* (4096 * 2176) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 34816, 1, 8160}, + {CAP_SECURE_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 34816, 1, 8160}, + {CAP_SECURE_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 8160}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, /* Batch Mode Decode */ - {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 64, 8160, 1, 8160}, + {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 36, 8160, 1, 8160}, /* (1920 * 1088) / 256 */ {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, From 9f8094a79d78e5be90b83b501b1d674fad8aaebe Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 29 Jun 2020 20:40:36 +0530 Subject: [PATCH 310/452] msm: vidc: use clock-rates from static table instead from dtsi Currently video has multiple nodes in dtsi to support/limit sw capabilities via sku-index. Mostly restriction comes in terms of allowed-clock-rate. So created static entries in platform.c to configure clocks based on plaform fuse value. So that single vidc dtsi node is sufficient and there will not be a probe defer/failure during bootup. For ex. Shima supports 3 sku's. AB - max 364.8 MHz - sku_version(1) - picked from dtsi(default sku) AA - max 201.6 MHz - sku_version(2) - clock_data_v2 AC - max 444 MHz - sku_version(0) - clock_data_v0(no fuse) Single vidc node - "aa00000.qcom,vidc" Change-Id: I870f1e3a24c0cbfdd92c537d3e40c4cf5400326d Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_internal.h | 2 ++ msm/vidc/msm_vidc_platform.c | 21 +++++++++++++++++++++ msm/vidc/msm_vidc_res_parse.c | 34 +++++++--------------------------- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index a10853e87366..cd2f35c46852 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -289,6 +289,8 @@ struct msm_vidc_platform_data { unsigned int common_data_length; struct msm_vidc_codec_data *codec_data; unsigned int codec_data_length; + struct allowed_clock_rates_table *clock_data; + unsigned int clock_data_length; struct msm_vidc_codec *codecs; uint32_t codecs_count; struct msm_vidc_codec_capability *codec_caps; diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 6c0e5bf18ccd..6a8b8668bdf4 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -726,6 +726,14 @@ static u32 vpe_csc_custom_limit_coeff[HAL_MAX_LIMIT_COEFFS] = { 16, 235, 16, 240, 16, 240 }; +struct allowed_clock_rates_table shima_clock_data_v0[] = { + {240000000}, {338000000}, {366000000}, {444000000} +}; + +struct allowed_clock_rates_table shima_clock_data_v2[] = { + {201600000} +}; + static struct msm_vidc_common_data default_common_data[] = { { .key = "qcom,never-unload-fw", @@ -1428,6 +1436,8 @@ static struct msm_vidc_platform_data default_data = { static struct msm_vidc_platform_data lahaina_data = { .codec_data = lahaina_codec_data, .codec_data_length = ARRAY_SIZE(lahaina_codec_data), + .clock_data = NULL, + .clock_data_length = 0, .common_data = lahaina_common_data, .common_data_length = ARRAY_SIZE(lahaina_common_data), .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, @@ -1448,6 +1458,8 @@ static struct msm_vidc_platform_data lahaina_data = { static struct msm_vidc_platform_data bengal_data = { .codec_data = bengal_codec_data, .codec_data_length = ARRAY_SIZE(bengal_codec_data), + .clock_data = NULL, + .clock_data_length = 0, .common_data = bengal_common_data_v0, .common_data_length = ARRAY_SIZE(bengal_common_data_v0), .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, @@ -1468,6 +1480,8 @@ static struct msm_vidc_platform_data bengal_data = { static struct msm_vidc_platform_data shima_data = { .codec_data = shima_codec_data, .codec_data_length = ARRAY_SIZE(shima_codec_data), + .clock_data = shima_clock_data_v0, + .clock_data_length = ARRAY_SIZE(shima_clock_data_v0), .common_data = shima_common_data_v0, .common_data_length = ARRAY_SIZE(shima_common_data_v0), .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, @@ -1488,6 +1502,8 @@ static struct msm_vidc_platform_data shima_data = { static struct msm_vidc_platform_data holi_data = { .codec_data = holi_codec_data, .codec_data_length = ARRAY_SIZE(holi_codec_data), + .clock_data = NULL, + .clock_data_length = 0, .common_data = holi_common_data, .common_data_length = ARRAY_SIZE(holi_common_data), .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, @@ -1641,6 +1657,8 @@ void *vidc_get_drv_data(struct device *dev) } } else if (!strcmp(match->compatible, "qcom,shima-vidc")) { if (driver_data->sku_version == SKU_VERSION_1) { + driver_data->clock_data = NULL; + driver_data->clock_data_length = 0; driver_data->common_data = shima_common_data_v1; driver_data->common_data_length = ARRAY_SIZE(shima_common_data_v1); @@ -1648,6 +1666,9 @@ void *vidc_get_drv_data(struct device *dev) driver_data->codec_caps_count = ARRAY_SIZE(shima_capabilities_v1); } else if (driver_data->sku_version == SKU_VERSION_2) { + driver_data->clock_data = shima_clock_data_v2; + driver_data->clock_data_length = + ARRAY_SIZE(shima_clock_data_v2); driver_data->common_data = shima_common_data_v2; driver_data->common_data_length = ARRAY_SIZE(shima_common_data_v2); diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index ca4cd5b442c4..0e14602d8f3d 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -347,6 +347,11 @@ static int msm_vidc_load_allowed_clocks_table( int rc = 0; struct platform_device *pdev = res->pdev; + if (res->allowed_clks_tbl) { + d_vpr_h("allowed-clock-rates populated from platform_data\n"); + return 0; + } + if (!of_find_property(pdev->dev.of_node, "qcom,allowed-clock-rates", NULL)) { d_vpr_h("allowed-clock-rates not found\n"); @@ -692,29 +697,6 @@ static int msm_vidc_load_reset_table( return 0; } -static int msm_decide_dt_node( - struct msm_vidc_platform_resources *res) -{ - struct platform_device *pdev = res->pdev; - int rc = 0; - u32 sku_index = 0; - - rc = of_property_read_u32(pdev->dev.of_node, "sku-index", - &sku_index); - if (rc) { - d_vpr_h("'sku_index' not found in node\n"); - return 0; - } - - if (sku_index != res->sku_version) { - d_vpr_h("Failed to parse dt: sku_index %d sku_version %d\n", - sku_index, res->sku_version); - return -EINVAL; - } - - return 0; -} - static int find_key_value(struct msm_vidc_platform_data *platform_data, const char *key) { @@ -749,6 +731,8 @@ int read_platform_resources_from_drv_data( res->codec_caps_count = platform_data->codec_caps_count; res->codec_data_count = platform_data->codec_data_length; res->codec_data = platform_data->codec_data; + res->allowed_clks_tbl = platform_data->clock_data; + res->allowed_clks_tbl_size = platform_data->clock_data_length; res->sku_version = platform_data->sku_version; res->mem_limit_tbl = memory_limit_tbl_mbytes; @@ -852,10 +836,6 @@ int read_platform_resources_from_dt( return -ENOENT; } - rc = msm_decide_dt_node(res); - if (rc) - return rc; - INIT_LIST_HEAD(&res->context_banks); res->firmware_base = (phys_addr_t)firmware_base; From f9f03040091111f2f2c1fd702b63656ddf04f0ca Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Fri, 26 Jun 2020 17:35:57 -0700 Subject: [PATCH 311/452] msm: vidc: use v4l2 standard h264 profile and levels Startdard v4l2 uapi header introduced h264 profile and levels and hence remove internal profile and levels to resolve compilation issues. Change-Id: I9e077066f9983b9a9e1b089457c060fd83d86860 Signed-off-by: Maheshwar Ajja --- include/uapi/vidc/media/msm_vidc_utils.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index 63894f8fb219..2e4f351c4927 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -72,18 +72,6 @@ enum v4l2_mpeg_vidc_video_bitrate_mode { V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR, V4L2_MPEG_VIDEO_BITRATE_MODE_CQ, }; - -enum v4l2_mpeg_vidc_video_h264_profile { - V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH = - V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH + 1, -}; - -enum v4l2_mpeg_vidc_video_h264_level { - V4L2_MPEG_VIDEO_H264_LEVEL_5_2 = V4L2_MPEG_VIDEO_H264_LEVEL_5_1 + 1, - V4L2_MPEG_VIDEO_H264_LEVEL_6_0, - V4L2_MPEG_VIDEO_H264_LEVEL_6_1, - V4L2_MPEG_VIDEO_H264_LEVEL_6_2, -}; /* missing v4l2 entries end */ /* vendor controls start */ From f171a0918b85290873ccf6feb2e27b8b93e76243 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Thu, 16 Jul 2020 00:12:24 +0530 Subject: [PATCH 312/452] msm: vidc: Update perf mode spec for shima As per the recommended configuration, the max spec for running an encode session in high quality is 1080p@30. Updating the same. Change-Id: I649790bbf8a3c2264bfe6c36769717df2d2f2a55 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_platform.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 6a8b8668bdf4..f5ea2f69e633 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1048,7 +1048,7 @@ static struct msm_vidc_common_data shima_common_data_v0[] = { }, { .key = "qcom,max-hq-mbs-per-sec", - .value = 489600, /* ((1920x1088)/256)@60fps */ + .value = 244800, /* ((1920x1088)/256)@30fps */ }, { .key = "qcom,power-collapse-delay", @@ -1161,7 +1161,7 @@ static struct msm_vidc_common_data shima_common_data_v1[] = { }, { .key = "qcom,max-hq-mbs-per-sec", - .value = 489600, /* ((1920x1088)/256)@60fps */ + .value = 244800, /* ((1920x1088)/256)@30fps */ }, { .key = "qcom,power-collapse-delay", @@ -1274,7 +1274,7 @@ static struct msm_vidc_common_data shima_common_data_v2[] = { }, { .key = "qcom,max-hq-mbs-per-sec", - .value = 489600, /* ((1920x1088)/256)@60fps */ + .value = 244800, /* ((1920x1088)/256)@30fps */ }, { .key = "qcom,power-collapse-delay", From 911dc56174d5df8d005df92ee136510ddfa6c67f Mon Sep 17 00:00:00 2001 From: Amit Shekhar Date: Thu, 28 May 2020 10:14:58 -0700 Subject: [PATCH 313/452] msm: vidc: Add support for Hier-B Add support for Hier-B. Change-Id: I2bd6f1b6525224795500d8a260de3d78a78d2163 CRs-Fixed: 2637948 Signed-off-by: Amit Shekhar --- msm/vidc/msm_venc.c | 171 +++++++++++++++++++----- msm/vidc/msm_venc.h | 1 + msm/vidc/msm_vidc_buffer_calculations.c | 41 ++++-- msm/vidc/msm_vidc_common.h | 19 +++ msm/vidc/vidc_hfi_helper.h | 4 + 5 files changed, 193 insertions(+), 43 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index c7f16dfe3c72..b703dbf04c1a 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -601,10 +601,11 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE, .name = "Set Hier coding type", .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P, + .minimum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B, .maximum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P, .default_value = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P, .menu_skip_mask = ~( + (1 << V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B) | (1 << V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P) ), .qmenu = NULL, @@ -2451,8 +2452,14 @@ int msm_venc_set_intra_period(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; - struct v4l2_ctrl *ctrl; + struct v4l2_ctrl *gop_size = NULL; + struct v4l2_ctrl *bframes = NULL; + struct v4l2_ctrl *max_layer = NULL; + struct v4l2_ctrl *frame_t = NULL; struct hfi_intra_period intra_period; + struct hfi_adaptive_p_b_intra_period adaptive_p_b_intra_period; + u32 codec; + bool adaptive_bframes = false; if (!inst || !inst->core) { d_vpr_e("%s: invalid params %pK\n", __func__, inst); @@ -2460,38 +2467,78 @@ int msm_venc_set_intra_period(struct msm_vidc_inst *inst) } hdev = inst->core->device; - msm_venc_adjust_gop_size(inst); + frame_t = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE); + gop_size = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_GOP_SIZE); + max_layer = get_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); + codec = get_v4l2_codec(inst); - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_GOP_SIZE); - intra_period.pframes = ctrl->val; + if (!max_layer->val && codec == V4L2_PIX_FMT_H264) { + intra_period.pframes = gop_size->val; + /* + * At this point we've already made decision on bframe. + * Control value gives updated bframe value. + */ + bframes = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); + intra_period.bframes = bframes->val; + if (intra_period.bframes) + adaptive_bframes = true; + } - /* - * At this point we have already made decision on bframe - * Control value gives updated bframe value. - */ - ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); - intra_period.bframes = ctrl->val; + if (max_layer->val > 1) { + if (frame_t->val == + V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B) { + if (codec == V4L2_PIX_FMT_HEVC) { + adaptive_p_b_intra_period.nframes = + gop_size->val; + adaptive_bframes = true; + } else { + d_vpr_e("%s: Hier-B supported for HEVC only\n", + __func__); + return -EINVAL; + } + } else if (frame_t->val == + V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P) { + msm_venc_adjust_gop_size(inst); + intra_period.pframes = gop_size->val; + intra_period.bframes = 0; + adaptive_bframes = false; + } + } if (inst->state == MSM_VIDC_START_DONE && - !intra_period.pframes && !intra_period.bframes) { + !intra_period.pframes && !intra_period.bframes) { s_vpr_h(inst->sid, "%s: Switch from IPPP to All Intra is not allowed\n", __func__); return rc; } - s_vpr_h(inst->sid, "%s: %d %d\n", __func__, intra_period.pframes, - intra_period.bframes); - rc = call_hfi_op(hdev, session_set_property, inst->session, - HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD, &intra_period, - sizeof(intra_period)); + if (frame_t->val == + V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B && + codec == V4L2_PIX_FMT_HEVC) { + s_vpr_h(inst->sid, "%s: nframes: %d\n", + __func__, adaptive_p_b_intra_period.nframes); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD, + &adaptive_p_b_intra_period, + sizeof(adaptive_p_b_intra_period)); + + } else { + s_vpr_h(inst->sid, "%s: pframes: %d bframes: %d\n", + __func__, intra_period.pframes, + intra_period.bframes); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD, + &intra_period, sizeof(intra_period)); + } + if (rc) { s_vpr_e(inst->sid, "%s: set property failed\n", __func__); return rc; } - if (intra_period.bframes) { - /* Enable adaptive bframes as nbframes!= 0 */ + if (adaptive_bframes) { rc = msm_venc_set_adaptive_bframes(inst); if (rc) { s_vpr_e(inst->sid, "%s: set property failed\n", @@ -2499,6 +2546,7 @@ int msm_venc_set_intra_period(struct msm_vidc_inst *inst) return rc; } } + return rc; } @@ -2764,14 +2812,14 @@ int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst) if (!max_layer->val || !layer->val) { s_vpr_h(inst->sid, - "%s: Hierp layer not set. Ignore layer bitrate\n", + "%s: Hier-P layer not set. Ignore layer bitrate\n", __func__); goto error; } if (max_layer->val < layer->val) { s_vpr_h(inst->sid, - "%s: Hierp layer greater than max isn't allowed\n", + "%s: Hier-P layer greater than max isn't allowed\n", __func__); goto error; } @@ -3611,7 +3659,7 @@ int msm_venc_set_base_layer_priority_id(struct msm_vidc_inst *inst) max_layer = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); if (max_layer->val <= 0) { - s_vpr_h(inst->sid, "%s: Layer id can only be set with Hierp\n", + s_vpr_h(inst->sid, "%s: Layer id can only be set with Hier-P\n", __func__); return 0; } @@ -3629,11 +3677,54 @@ int msm_venc_set_base_layer_priority_id(struct msm_vidc_inst *inst) return rc; } +int msm_venc_set_hb_max_layer(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct hfi_device *hdev; + struct v4l2_ctrl *frame_t = NULL; + struct v4l2_ctrl *max_layer = NULL; + u32 hb_layer = 0; + u32 codec; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params %pK\n", __func__, inst); + return -EINVAL; + } + hdev = inst->core->device; + + codec = get_v4l2_codec(inst); + if (codec != V4L2_PIX_FMT_HEVC) + return 0; + + max_layer = get_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); + frame_t = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE); + if (max_layer->val < 2 || + frame_t->val != V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B) { + s_vpr_h(inst->sid, + "%s: Hier-B not requested for this session\n", + __func__); + return 0; + } + hb_layer = max_layer->val - 1; + + s_vpr_h(inst->sid, "%s: Hier-B max layer: %d\n", + __func__, hb_layer); + rc = call_hfi_op(hdev, session_set_property, inst->session, + HFI_PROPERTY_PARAM_VENC_HIER_B_MAX_NUM_ENH_LAYER, + &hb_layer, sizeof(hb_layer)); + if (rc) + s_vpr_e(inst->sid, "%s: set property failed\n", __func__); + + return rc; +} + int msm_venc_set_hp_max_layer(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; - struct v4l2_ctrl *ctrl; + struct v4l2_ctrl *frame_t = NULL; + struct v4l2_ctrl *max_layer = NULL; u32 hp_layer = 0; u32 codec; @@ -3647,12 +3738,20 @@ int msm_venc_set_hp_max_layer(struct msm_vidc_inst *inst) if (codec != V4L2_PIX_FMT_H264 && codec != V4L2_PIX_FMT_HEVC) return 0; - ctrl = get_ctrl(inst, + max_layer = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); + frame_t = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE); + if (max_layer->val < 2 || + frame_t->val != V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P) { + s_vpr_h(inst->sid, + "%s: Hier-P not requested for this session\n", + __func__); + return 0; + } rc = msm_venc_enable_hybrid_hp(inst); if (rc) { - s_vpr_e(inst->sid, "%s: get hybrid hp decision failed\n", + s_vpr_e(inst->sid, "%s: get hybrid hier-P decision failed\n", __func__); return rc; } @@ -3661,17 +3760,17 @@ int msm_venc_set_hp_max_layer(struct msm_vidc_inst *inst) * We send enhancement layer count to FW, * hence, input 0/1 indicates absence of layer encoding. */ - if (ctrl->val) - hp_layer = ctrl->val - 1; + if (max_layer->val) + hp_layer = max_layer->val - 1; if (inst->hybrid_hp) { - s_vpr_h(inst->sid, "%s: Hybrid hierp layer: %d\n", + s_vpr_h(inst->sid, "%s: Hybrid hier-P layer: %d\n", __func__, hp_layer); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_HIER_P_HYBRID_MODE, &hp_layer, sizeof(hp_layer)); } else { - s_vpr_h(inst->sid, "%s: Hierp max layer: %d\n", + s_vpr_h(inst->sid, "%s: Hier-P max layer: %d\n", __func__, hp_layer); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER, @@ -3686,6 +3785,7 @@ int msm_venc_set_hp_layer(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; + struct v4l2_ctrl *frame_t = NULL; struct v4l2_ctrl *ctrl = NULL; struct v4l2_ctrl *max_layer = NULL; u32 hp_layer = 0; @@ -3697,6 +3797,14 @@ int msm_venc_set_hp_layer(struct msm_vidc_inst *inst) } hdev = inst->core->device; + frame_t = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE); + if (frame_t->val != V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P) { + s_vpr_h(inst->sid, + "%s: Hier-P layer can be set for P type frame only\n", + __func__); + return 0; + } + codec = get_v4l2_codec(inst); if (codec != V4L2_PIX_FMT_H264 && codec != V4L2_PIX_FMT_HEVC) return 0; @@ -3728,7 +3836,7 @@ int msm_venc_set_hp_layer(struct msm_vidc_inst *inst) if (ctrl->val) hp_layer = ctrl->val - 1; - s_vpr_h(inst->sid, "%s: Hierp enhancement layer: %d\n", + s_vpr_h(inst->sid, "%s: Hier-P enhancement layer: %d\n", __func__, hp_layer); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER, @@ -4735,6 +4843,9 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) if (rc) goto exit; rc = msm_venc_set_ltr_mode(inst); + if (rc) + goto exit; + rc = msm_venc_set_hb_max_layer(inst); if (rc) goto exit; rc = msm_venc_set_hp_max_layer(inst); diff --git a/msm/vidc/msm_venc.h b/msm/vidc/msm_venc.h index bb5a651f3da9..4f5689fe50d1 100644 --- a/msm/vidc/msm_venc.h +++ b/msm/vidc/msm_venc.h @@ -35,6 +35,7 @@ int msm_venc_set_ltr_markframe(struct msm_vidc_inst *inst); int msm_venc_set_dyn_qp(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl); int msm_venc_set_request_keyframe(struct msm_vidc_inst *inst); int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst); +int msm_venc_set_hb_max_layer(struct msm_vidc_inst *inst); int msm_venc_set_hp_max_layer(struct msm_vidc_inst *inst); int msm_venc_set_hp_layer(struct msm_vidc_inst *inst); int msm_venc_set_base_layer_priority_id(struct msm_vidc_inst *inst); diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index d9ef661314db..63ed34ed17f8 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -465,10 +465,11 @@ int msm_vidc_get_decoder_internal_buffer_sizes(struct msm_vidc_inst *inst) int msm_vidc_get_num_ref_frames(struct msm_vidc_inst *inst) { int num_ref = 1; - int num_bframes = -1, ltr_count = -1, num_hp_layers; - struct v4l2_ctrl *bframe_ctrl; - struct v4l2_ctrl *ltr_ctrl; - struct v4l2_ctrl *layer_ctrl; + int num_bframes = -1, ltr_count = -1; + struct v4l2_ctrl *bframe_ctrl = NULL; + struct v4l2_ctrl *ltr_ctrl = NULL; + struct v4l2_ctrl *frame_t = NULL; + struct v4l2_ctrl *max_layer = NULL; u32 codec; bframe_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); @@ -482,21 +483,27 @@ int msm_vidc_get_num_ref_frames(struct msm_vidc_inst *inst) if (ltr_count > 0) num_ref = num_ref + ltr_count; - layer_ctrl = get_ctrl(inst, + frame_t = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE); + max_layer = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); - num_hp_layers = layer_ctrl->val; - codec = get_v4l2_codec(inst); - if (num_hp_layers > 0) { + if (frame_t->val == V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P && + max_layer->val > 0) { + codec = get_v4l2_codec(inst); /* LTR and B - frame not supported with hybrid HP */ if (inst->hybrid_hp) - num_ref = (num_hp_layers - 1); + num_ref = (max_layer->val - 1); else if (codec == V4L2_PIX_FMT_HEVC) - num_ref = ((num_hp_layers + 1) / 2) + ltr_count; - else if ((codec == V4L2_PIX_FMT_H264) && (num_hp_layers <= 4)) - num_ref = ((1 << (num_hp_layers - 1)) - 1) + ltr_count; + num_ref = ((max_layer->val + 1) / 2) + ltr_count; + else if ((codec == V4L2_PIX_FMT_H264) && (max_layer->val <= 4)) + num_ref = ((1 << (max_layer->val - 1)) - 1) + ltr_count; else - num_ref = ((num_hp_layers + 1) / 2) + ltr_count; + num_ref = ((max_layer->val + 1) / 2) + ltr_count; } + + if (is_hier_b_session(inst)) { + num_ref = (1 << (max_layer->val - 1)) / 2 + 1; + } + return num_ref; } @@ -626,6 +633,7 @@ int msm_vidc_calculate_input_buffer_count(struct msm_vidc_inst *inst) { struct msm_vidc_format *fmt; int extra_buff_count = 0; + struct v4l2_ctrl *max_layer = NULL; if (!inst) { d_vpr_e("%s: invalid params\n", __func__); @@ -655,6 +663,13 @@ int msm_vidc_calculate_input_buffer_count(struct msm_vidc_inst *inst) extra_buff_count = msm_vidc_get_extra_buff_count(inst, HAL_BUFFER_INPUT); fmt->count_min = MIN_INPUT_BUFFERS; + + if (is_hier_b_session(inst)) { + max_layer = get_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); + fmt->count_min = (1 << (max_layer->val - 1)) + 2; + } + fmt->count_min_host = fmt->count_actual = fmt->count_min + extra_buff_count; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 806a8edb3dbd..98287b8570e7 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -190,6 +190,25 @@ static inline bool is_internal_buffer(enum hal_buffer type) return !!(buf_type & type); } +static inline bool is_hier_b_session(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *max_layer = NULL; + struct v4l2_ctrl *frame_t = NULL; + + if (inst->session_type == MSM_VIDC_ENCODER) { + max_layer = get_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); + frame_t = get_ctrl(inst, + V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE); + if (get_v4l2_codec(inst) == V4L2_PIX_FMT_HEVC && + max_layer->val > 1 && + frame_t->val == + V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B) + return true; + } + return false; +} + static inline int msm_comm_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl) { diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index accdcdff8a16..65e1f0e486e3 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -541,6 +541,10 @@ struct hfi_intra_period { u32 bframes; }; +struct hfi_adaptive_p_b_intra_period { + u32 nframes; +}; + struct hfi_multi_stream { u32 buffer_type; u32 enable; From 209b06e403016bd327396bff6b37c45922b66409 Mon Sep 17 00:00:00 2001 From: Amit Shekhar Date: Wed, 15 Jul 2020 22:56:39 -0700 Subject: [PATCH 314/452] msm: vidc: Fix static analysis issues Fix uninitialized access issue with a few variables. Change-Id: Ib79186e0b837ce1d020546c8a3436745c5d50532 CRs-Fixed: 2729628 Signed-off-by: Amit Shekhar --- msm/vidc/msm_venc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index b703dbf04c1a..7e4d638319b6 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2456,8 +2456,13 @@ int msm_venc_set_intra_period(struct msm_vidc_inst *inst) struct v4l2_ctrl *bframes = NULL; struct v4l2_ctrl *max_layer = NULL; struct v4l2_ctrl *frame_t = NULL; - struct hfi_intra_period intra_period; - struct hfi_adaptive_p_b_intra_period adaptive_p_b_intra_period; + struct hfi_intra_period intra_period = { + .pframes = 0, + .bframes = 0 + }; + struct hfi_adaptive_p_b_intra_period adaptive_p_b_intra_period = { + .nframes = 0 + }; u32 codec; bool adaptive_bframes = false; From b226cd01b3fbf517806ca91b25a1376048d3803b Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Thu, 16 Jul 2020 18:30:43 +0800 Subject: [PATCH 315/452] msm: vidc: fix sub_frame flag when fetch ts Need to check against v4l2 flag instead of hfi flag. Change-Id: Ib15974b1cc2ee23861b47425ebe21d25ff6dc694 Signed-off-by: Qiwei Liu --- msm/vidc/msm_vidc_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 4fd181f268ab..c5a5f45aa3f0 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7764,7 +7764,7 @@ int msm_comm_fetch_ts_framerate(struct msm_vidc_inst *inst, } /* do not update is_valid flag for subframe buffer */ - if (!(b->flags & HAL_BUFFERFLAG_ENDOFSUBFRAME)) + if (!(b->flags & V4L2_BUF_FLAG_END_OF_SUBFRAME)) node->is_valid = false; b->timestamp.tv_sec = node->timestamp_us / 1000000ull; From 6b73bf247d3a38b9e254a168c6853d50f5cd26a4 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Fri, 17 Jul 2020 11:20:00 -0700 Subject: [PATCH 316/452] msm: vidc: Check validity of a timestamp before inserting it to list In steady state, the first entry in the linked list of timestamps is always invalid. When adding a new timestamp entry, adding the timestamp which is a duplicate of first entry leads to duplicate linked list nodes. To avoid this, check for validity of an entry before inserting duplicates to the linked list. Change-Id: I47dd8fb06b9e4eb307605df6b0e2b352a2e263fe Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 4fd181f268ab..b48c41400867 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7602,7 +7602,7 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) duplicate = NULL; list_for_each_entry(node, &inst->timestamps.list, list) { count++; - if (node->timestamp_us == timestamp_us) + if (node->is_valid && node->timestamp_us == timestamp_us) duplicate = node; } From 1fd9cfcf2e671073f688dbe25409dc4fee1c1081 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Mon, 20 Jul 2020 10:32:32 -0700 Subject: [PATCH 317/452] msm: vidc: Fix to add correct superframe buffer timestamps Avoid adapting driver framerate to camera qbuf rate in superframe enabled case to avoid setting incorrect hfr buffer timestamps. Change-Id: I354e7517b9aeef7f1b01f33089b81bf7122e12e2 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_venc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 7e4d638319b6..6030230d3df6 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2120,6 +2120,7 @@ int msm_venc_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) struct msm_vidc_timestamps *entry, *node, *prev = NULL; int count = 0; int rc = 0; + struct v4l2_ctrl *superframe_ctrl = NULL; if (!inst || !inst->core) { d_vpr_e("%s: invalid parameters\n", __func__); @@ -2172,7 +2173,13 @@ int msm_venc_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) /* if framerate changed and stable for 2 frames, set to firmware */ if (entry->framerate == prev->framerate && entry->framerate != inst->clk_data.frame_rate) { - inst->clk_data.frame_rate = entry->framerate; + superframe_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); + if (superframe_ctrl->val > 1) + inst->clk_data.frame_rate = entry->framerate * superframe_ctrl->val; + else + inst->clk_data.frame_rate = entry->framerate; + s_vpr_l(inst->sid, "%s: updated fps to %u\n", + __func__, (inst->clk_data.frame_rate >> 16)); msm_venc_set_frame_rate(inst); } From 59ca4e236545aa5dbb4c7d3e57cca1effff68be7 Mon Sep 17 00:00:00 2001 From: Amit Shekhar Date: Mon, 20 Jul 2020 17:12:55 -0700 Subject: [PATCH 318/452] msm: vidc: Fix p-frame count Fix p-frame count during intra-period setting for HEVC session without layer encoding. Change-Id: I796cac16fbb0538012f9fc97262e1877285e1803 CRs-Fixed: 2735233 Signed-off-by: Amit Shekhar --- msm/vidc/msm_venc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 6030230d3df6..48c438b9baae 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2485,8 +2485,9 @@ int msm_venc_set_intra_period(struct msm_vidc_inst *inst) V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); codec = get_v4l2_codec(inst); + intra_period.pframes = gop_size->val; + if (!max_layer->val && codec == V4L2_PIX_FMT_H264) { - intra_period.pframes = gop_size->val; /* * At this point we've already made decision on bframe. * Control value gives updated bframe value. From fbc3b10e060aa7072dc1f48af86bafdce0cfaf8b Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Sat, 27 Jun 2020 13:20:56 -0700 Subject: [PATCH 319/452] msm: vidc: Update power sequence to match Lahaina HPG steps Update power sequence by removing all resets during power down. Change-Id: I88610e9c71a91a32332626bf6da88f0f64ed1c65 Signed-off-by: Mihir Ganu (cherry picked from commit 5cffae52eacaaf6b0698de06c11397339d904f35) --- msm/vidc/hfi_iris2.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/msm/vidc/hfi_iris2.c b/msm/vidc/hfi_iris2.c index 4627f8b46871..5ac62b788ea4 100644 --- a/msm/vidc/hfi_iris2.c +++ b/msm/vidc/hfi_iris2.c @@ -243,10 +243,6 @@ void __power_off_iris2(struct venus_hfi_device *device) /* HPG 6.1.2 Step 6 */ __disable_unprepare_clks(device); - /* HPG 6.1.2 Step 7 & 8 */ - if (call_venus_op(device, reset_ahb2axi_bridge, device, sid)) - d_vpr_e("%s: Failed to reset ahb2axi\n", __func__); - /* HPG 6.1.2 Step 5 */ if (__disable_regulators(device)) d_vpr_e("%s: Failed to disable regulators\n", __func__); From 35ae83039878921d6f60ea91a1a2c11a9134e0a5 Mon Sep 17 00:00:00 2001 From: Divya Sharma Date: Tue, 21 Jul 2020 13:19:44 -0700 Subject: [PATCH 320/452] Revert "msm: vidc: increase h265 decoder max slice count" This reverts commit d2690f588936ca59a0b8123b082d0726136c43bc. Change-Id: Id48074d6ec5efefa7317f191f1d2853eef1a01a9 --- msm/vidc/msm_vidc_buffer_calculations.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 694778094289..e99e2fc7aee2 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -142,7 +142,7 @@ #define LCU_MAX_SIZE_PELS 64 #define LCU_MIN_SIZE_PELS 16 -#define H265D_MAX_SLICE 3600 +#define H265D_MAX_SLICE 1200 #define SIZE_H265D_HW_PIC_T SIZE_H264D_HW_PIC_T #define SIZE_H265D_BSE_CMD_PER_BUF (16 * sizeof(u32)) #define SIZE_H265D_VPP_CMD_PER_BUF 256 From 6d1b1c1a3d0ede5ef018b12932eab8eb258efe63 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Sat, 27 Jun 2020 13:20:56 -0700 Subject: [PATCH 321/452] msm: vidc: Update power sequence to match Lahaina HPG steps Update power sequence by removing all resets during power down. Change-Id: I88610e9c71a91a32332626bf6da88f0f64ed1c65 Signed-off-by: Mihir Ganu (cherry picked from commit 5cffae52eacaaf6b0698de06c11397339d904f35) --- msm/vidc/hfi_iris2.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/msm/vidc/hfi_iris2.c b/msm/vidc/hfi_iris2.c index 4627f8b46871..5ac62b788ea4 100644 --- a/msm/vidc/hfi_iris2.c +++ b/msm/vidc/hfi_iris2.c @@ -243,10 +243,6 @@ void __power_off_iris2(struct venus_hfi_device *device) /* HPG 6.1.2 Step 6 */ __disable_unprepare_clks(device); - /* HPG 6.1.2 Step 7 & 8 */ - if (call_venus_op(device, reset_ahb2axi_bridge, device, sid)) - d_vpr_e("%s: Failed to reset ahb2axi\n", __func__); - /* HPG 6.1.2 Step 5 */ if (__disable_regulators(device)) d_vpr_e("%s: Failed to disable regulators\n", __func__); From 1b93961cacc8a3b226f9d473e830721ebe229055 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Mon, 20 Jul 2020 10:32:32 -0700 Subject: [PATCH 322/452] msm: vidc: Fix to add correct superframe buffer timestamps Avoid adapting driver framerate to camera qbuf rate in superframe enabled case to avoid setting incorrect hfr buffer timestamps. Change-Id: I354e7517b9aeef7f1b01f33089b81bf7122e12e2 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_venc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 7e4d638319b6..6030230d3df6 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2120,6 +2120,7 @@ int msm_venc_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) struct msm_vidc_timestamps *entry, *node, *prev = NULL; int count = 0; int rc = 0; + struct v4l2_ctrl *superframe_ctrl = NULL; if (!inst || !inst->core) { d_vpr_e("%s: invalid parameters\n", __func__); @@ -2172,7 +2173,13 @@ int msm_venc_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) /* if framerate changed and stable for 2 frames, set to firmware */ if (entry->framerate == prev->framerate && entry->framerate != inst->clk_data.frame_rate) { - inst->clk_data.frame_rate = entry->framerate; + superframe_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); + if (superframe_ctrl->val > 1) + inst->clk_data.frame_rate = entry->framerate * superframe_ctrl->val; + else + inst->clk_data.frame_rate = entry->framerate; + s_vpr_l(inst->sid, "%s: updated fps to %u\n", + __func__, (inst->clk_data.frame_rate >> 16)); msm_venc_set_frame_rate(inst); } From 879bf52d7fb0d703cb8c4558c03b0c7a2c226c1f Mon Sep 17 00:00:00 2001 From: Amit Shekhar Date: Mon, 20 Jul 2020 17:12:55 -0700 Subject: [PATCH 323/452] msm: vidc: Fix p-frame count Fix p-frame count during intra-period setting for HEVC session without layer encoding. Change-Id: I796cac16fbb0538012f9fc97262e1877285e1803 CRs-Fixed: 2735233 Signed-off-by: Amit Shekhar --- msm/vidc/msm_venc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 6030230d3df6..48c438b9baae 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2485,8 +2485,9 @@ int msm_venc_set_intra_period(struct msm_vidc_inst *inst) V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); codec = get_v4l2_codec(inst); + intra_period.pframes = gop_size->val; + if (!max_layer->val && codec == V4L2_PIX_FMT_H264) { - intra_period.pframes = gop_size->val; /* * At this point we've already made decision on bframe. * Control value gives updated bframe value. From 4f287b68adf643c37a56a725c97d7a3bcedcc991 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Fri, 24 Jul 2020 12:48:34 +0530 Subject: [PATCH 324/452] msm: vidc: disable DCVS for camera encode batching Disable DCVS for encode usecases if the control V4L2_CID_MPEG_VIDC_SUPERFRAME is enabled. Change-Id: I72a4bebbd79c42988867572d69f6833629054cba --- msm/vidc/msm_vidc_clocks.c | 3 ++- msm/vidc/msm_vidc_common.h | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index c2db722ec8fd..59dfd21a88dc 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -999,7 +999,8 @@ int msm_dcvs_try_enable(struct msm_vidc_inst *inst) inst->clk_data.low_latency_mode || inst->batch.enable || is_turbo_session(inst) || - inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ); + inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ || + is_encode_batching(inst)); s_vpr_hp(inst->sid, "DCVS %s: %pK\n", inst->clk_data.dcvs_mode ? "enabled" : "disabled", inst); diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 98287b8570e7..f9fe8cbb098c 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -153,6 +153,17 @@ static inline bool is_encode_session(struct msm_vidc_inst *inst) return inst->session_type == MSM_VIDC_ENCODER; } +static inline bool is_encode_batching(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *ctrl; + + if (inst->session_type != MSM_VIDC_ENCODER) + return false; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); + return !!ctrl->val; +} + static inline bool is_primary_output_mode(struct msm_vidc_inst *inst) { return inst->stream_output_mode == HAL_VIDEO_DECODER_PRIMARY; From f8eaa17bf0c87024eb166394206d4fa583074acb Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Fri, 24 Jul 2020 16:14:08 -0700 Subject: [PATCH 325/452] msm: vidc: Enable 8-bit chroma QP offset support Enable support for 8-bit chroma QP offset. Change-Id: I296f7a5669439c21d9727b1b731cfce14cbcd529 Signed-off-by: Mihir Ganu --- msm/vidc/msm_venc.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 48c438b9baae..ef75cc28987e 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3414,10 +3414,6 @@ int msm_venc_set_chroma_qp_offset(struct msm_vidc_inst *inst) chroma_qp.chroma_offset = (chr->val + 12) << 16 | (chr->val + 12); s_vpr_h(inst->sid, "%s: %x\n", __func__, chroma_qp.chroma_offset); - /* TODO: Remove this check after firmware support added for 8-bit */ - if (inst->bit_depth == MSM_VIDC_BIT_DEPTH_8) - return 0; - rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_HEVC_PPS_CB_CR_OFFSET, &chroma_qp, sizeof(chroma_qp)); From e2a2a4a190efe4acf8402e5d85a252ba528e1683 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Sun, 12 Jul 2020 21:29:21 +0530 Subject: [PATCH 326/452] msm: vidc: Copy hfi buf req to hal buf req copy hfi buf req to hal buf req element by element. Due to change in structure sizes, memcpy may lead to memory corruption. CRs-Fixed: 2741030 Change-Id: Ie4a3aeba7cac78af99355eb766a5ead755cf654b Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/hfi_response_handler.c | 73 +++++++++++++++++---------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index fb778e6cded4..9e65e0462498 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -496,11 +496,21 @@ static int hfi_process_sys_rel_resource_done(u32 device_id, return 0; } +static void copy_hfi_to_hal_buf_req(struct hal_buffer_requirements *dst, + struct hfi_buffer_requirements *src) { + dst->buffer_size = src->buffer_size; + dst->buffer_count_min = (u16)src->buffer_count_min; + dst->buffer_count_min_host = (u16)src->buffer_count_min_host; + dst->buffer_count_actual = (u16)src->buffer_count_actual; + dst->buffer_alignment = (u16)src->buffer_alignment; +} + static void hfi_process_sess_get_prop_buf_req( struct hfi_msg_session_property_info_packet *prop, struct buffer_requirements *buffreq, u32 sid) { struct hfi_buffer_requirements *hfi_buf_req; + struct hal_buffer_requirements *hal_buf_req; u32 req_bytes; if (!prop) { @@ -529,79 +539,70 @@ static void hfi_process_sess_get_prop_buf_req( hfi_buf_req->buffer_type); switch (hfi_buf_req->buffer_type) { case HFI_BUFFER_INPUT: - memcpy(&buffreq->buffer[0], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[0].buffer_type = HAL_BUFFER_INPUT; + hal_buf_req = &buffreq->buffer[0]; + hal_buf_req->buffer_type = HAL_BUFFER_INPUT; break; case HFI_BUFFER_OUTPUT: - memcpy(&buffreq->buffer[1], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[1].buffer_type = HAL_BUFFER_OUTPUT; + hal_buf_req = &buffreq->buffer[1]; + hal_buf_req->buffer_type = HAL_BUFFER_OUTPUT; break; case HFI_BUFFER_OUTPUT2: - memcpy(&buffreq->buffer[2], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[2].buffer_type = HAL_BUFFER_OUTPUT2; + hal_buf_req = &buffreq->buffer[2]; + hal_buf_req->buffer_type = HAL_BUFFER_OUTPUT2; break; case HFI_BUFFER_EXTRADATA_INPUT: - memcpy(&buffreq->buffer[3], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[3].buffer_type = + hal_buf_req = &buffreq->buffer[3]; + hal_buf_req->buffer_type = HAL_BUFFER_EXTRADATA_INPUT; break; case HFI_BUFFER_EXTRADATA_OUTPUT: - memcpy(&buffreq->buffer[4], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[4].buffer_type = + hal_buf_req = &buffreq->buffer[4]; + hal_buf_req->buffer_type = HAL_BUFFER_EXTRADATA_OUTPUT; break; case HFI_BUFFER_EXTRADATA_OUTPUT2: - memcpy(&buffreq->buffer[5], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[5].buffer_type = + hal_buf_req = &buffreq->buffer[5]; + hal_buf_req->buffer_type = HAL_BUFFER_EXTRADATA_OUTPUT2; break; case HFI_BUFFER_COMMON_INTERNAL_SCRATCH: - memcpy(&buffreq->buffer[6], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[6].buffer_type = + hal_buf_req = &buffreq->buffer[6]; + hal_buf_req->buffer_type = HAL_BUFFER_INTERNAL_SCRATCH; break; case HFI_BUFFER_COMMON_INTERNAL_SCRATCH_1: - memcpy(&buffreq->buffer[7], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[7].buffer_type = + hal_buf_req = &buffreq->buffer[7]; + hal_buf_req->buffer_type = HAL_BUFFER_INTERNAL_SCRATCH_1; break; case HFI_BUFFER_COMMON_INTERNAL_SCRATCH_2: - memcpy(&buffreq->buffer[8], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[8].buffer_type = + hal_buf_req = &buffreq->buffer[8]; + hal_buf_req->buffer_type = HAL_BUFFER_INTERNAL_SCRATCH_2; break; case HFI_BUFFER_INTERNAL_PERSIST: - memcpy(&buffreq->buffer[9], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[9].buffer_type = + hal_buf_req = &buffreq->buffer[9]; + hal_buf_req->buffer_type = HAL_BUFFER_INTERNAL_PERSIST; break; case HFI_BUFFER_INTERNAL_PERSIST_1: - memcpy(&buffreq->buffer[10], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[10].buffer_type = + hal_buf_req = &buffreq->buffer[10]; + hal_buf_req->buffer_type = HAL_BUFFER_INTERNAL_PERSIST_1; break; case HFI_BUFFER_COMMON_INTERNAL_RECON: - memcpy(&buffreq->buffer[11], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[11].buffer_type = + hal_buf_req = &buffreq->buffer[11]; + hal_buf_req->buffer_type = HAL_BUFFER_INTERNAL_RECON; break; default: + hal_buf_req = NULL; s_vpr_e(sid, "%s: bad_buffer_type: %d\n", __func__, hfi_buf_req->buffer_type); break; } + if (hal_buf_req) + copy_hfi_to_hal_buf_req(hal_buf_req, hfi_buf_req); req_bytes -= sizeof(struct hfi_buffer_requirements); hfi_buf_req++; } From 7ae805aa633f455ffee9af69fcc4ddf2a1483403 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Wed, 15 Jul 2020 22:55:12 +0530 Subject: [PATCH 327/452] msm: vidc: check for cvp support check for cvp support before any cvp related operation. CRs-Fixed: 2741030 Change-Id: I7a457608321f0aa5b93b6f62d7ceb76c0b00fb93 Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_venc.c | 6 ++++++ msm/vidc/msm_vidc.c | 5 +++++ msm/vidc/msm_vidc_common.h | 5 +++++ msm/vidc/msm_vidc_platform.c | 4 ++++ msm/vidc/msm_vidc_res_parse.c | 2 ++ msm/vidc/msm_vidc_resources.h | 1 + 6 files changed, 23 insertions(+) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index ef75cc28987e..cf7b502ce8f5 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -4607,6 +4607,12 @@ int msm_venc_set_cvp_skipratio(struct msm_vidc_inst *inst) d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } + + if (!is_cvp_supported(inst)) { + s_vpr_h(inst->sid, "%s cvp is not supported", __func__); + return rc; + } + if (!msm_vidc_cvp_usage) return 0; diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 3f789a4afe46..d0d6b128983a 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -794,6 +794,11 @@ static bool msm_vidc_set_cvp_metadata(struct msm_vidc_inst *inst) { return false; } + if (!is_cvp_supported(inst)) { + s_vpr_h(inst->sid, "%s cvp is not supported", __func__); + return true; + } + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) value = 0x1; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 98287b8570e7..7be37c5cb70f 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -59,6 +59,11 @@ static inline bool is_low_power_session(struct msm_vidc_inst *inst) return !!(inst->flags & VIDC_LOW_POWER); } +static inline bool is_cvp_supported(struct msm_vidc_inst *inst) +{ + return inst->core && !inst->core->resources.no_cvp; +} + static inline struct v4l2_ctrl *get_ctrl(struct msm_vidc_inst *inst, u32 id) { diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index f5ea2f69e633..473c3e934208 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1398,6 +1398,10 @@ static struct msm_vidc_common_data holi_common_data[] = { .key = "qcom,fw-vpp-cycles", .value = 225975, }, + { + .key = "qcom,no-cvp", + .value = 1, + }, }; static struct msm_vidc_efuse_data shima_efuse_data[] = { diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 0e14602d8f3d..1e17830ff333 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -813,6 +813,8 @@ int read_platform_resources_from_drv_data( "qcom,vpp_delay_supported"); res->enc_auto_dynamic_fps = find_key_value(platform_data, "qcom,enc_auto_dynamic_fps"); + res->no_cvp = find_key_value(platform_data, + "qcom,no-cvp"); res->csc_coeff_data = &platform_data->csc_data; diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index d7c8ee88b887..5add5ec54373 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -206,6 +206,7 @@ struct msm_vidc_platform_resources { uint32_t ubwc_stats_in_fbd; uint32_t has_vpp_delay; bool enc_auto_dynamic_fps; + bool no_cvp; }; static inline bool is_iommu_present(struct msm_vidc_platform_resources *res) From e05aff730dbc581bb4e9b8096fd72e94be750e23 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Wed, 29 Jul 2020 11:35:59 +0800 Subject: [PATCH 328/452] msm: vidc: fix less_or_equal resolution check For less_or_equal check, need to meet all the conditions when return true, not only one condition. Change-Id: Icf103721596cdcb6a4a90e1def67f3151140db85 Signed-off-by: Qiwei Liu --- msm/vidc/msm_vidc_clocks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 59dfd21a88dc..4e2a8958a008 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -120,8 +120,8 @@ bool res_is_less_than_or_equal_to(u32 width, u32 height, u32 num_mbs = NUM_MBS_PER_FRAME(height, width); u32 max_side = max(ref_width, ref_height); - if (num_mbs <= NUM_MBS_PER_FRAME(ref_height, ref_width) || - width <= max_side || + if (num_mbs <= NUM_MBS_PER_FRAME(ref_height, ref_width) && + width <= max_side && height <= max_side) return true; else From a03df1c59360676143d4f06f1957d712a47af93e Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Sun, 2 Aug 2020 20:14:27 -0700 Subject: [PATCH 329/452] msm: vidc: Update timer API Replace the obsolete do_gettimeofday API with ktime API. Change-Id: Id105d2c531f8b9aa3315800ab3312bc6a619b792 Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_debug.c | 4 ---- msm/vidc/msm_vidc_debug.h | 6 ++---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index 4b0f6090de40..b692f8c9f05b 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -728,10 +728,6 @@ inline bool is_print_allowed(u32 sid, u32 level) } /* Mock all the missing parts for successful compilation starts here */ -void do_gettimeofday(struct timeval *__ddl_tv) -{ -} - #ifndef CONFIG_VIDEOBUF2_CORE void vb2_queue_release(struct vb2_queue *q) { diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index 7b523eddb55f..389b0d9e9eb8 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -19,8 +19,6 @@ // void disable_irq_nosync(unsigned int irq); // void enable_irq(unsigned int irq); -void do_gettimeofday(struct timeval *__ddl_tv); - #ifndef CONFIG_VIDEOBUF2_CORE int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req); int vb2_qbuf(struct vb2_queue *q, struct media_device *mdev, @@ -234,7 +232,7 @@ static inline void tic(struct msm_vidc_inst *i, enum profiling_points p, memcpy(i->debug.pdata[p].name, b, 64); if ((msm_vidc_debug & VIDC_PERF) && i->debug.pdata[p].sampling) { - do_gettimeofday(&__ddl_tv); + __ddl_tv = ktime_to_timeval(ktime_get_real()); i->debug.pdata[p].start = (__ddl_tv.tv_sec * 1000) + (__ddl_tv.tv_usec / 1000); i->debug.pdata[p].sampling = false; @@ -247,7 +245,7 @@ static inline void toc(struct msm_vidc_inst *i, enum profiling_points p) if ((msm_vidc_debug & VIDC_PERF) && !i->debug.pdata[p].sampling) { - do_gettimeofday(&__ddl_tv); + __ddl_tv = ktime_to_timeval(ktime_get_real()); i->debug.pdata[p].stop = (__ddl_tv.tv_sec * 1000) + (__ddl_tv.tv_usec / 1000); i->debug.pdata[p].cumulative += i->debug.pdata[p].stop - From 21cba5ad49a1cf7f2892f5bc1bcae2b9dcb8a543 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Mon, 3 Aug 2020 16:21:45 +0800 Subject: [PATCH 330/452] msm: vidc: fix time stamp store and fetch Fix to skip time stamp store and fetch for buffers with codec config flag. Change-Id: I867db519c45751ef2dadef5a323c7a4ad2741385 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_vidc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index d0d6b128983a..c2125e6a8330 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -437,7 +437,9 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, msm_comm_release_timestamps(inst); inst->flush_timestamps = false; - rc = msm_comm_store_timestamp(inst, timestamp_us); + if (!(b->flags & V4L2_BUF_FLAG_CODECCONFIG)) + rc = msm_comm_store_timestamp(inst, timestamp_us); + if (rc) goto unlock; inst->clk_data.frame_rate = msm_comm_get_max_framerate(inst); @@ -508,7 +510,9 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) return -EINVAL; } } - if (is_decode_session(inst) && b->type == OUTPUT_MPLANE) + if (is_decode_session(inst) && + b->type == OUTPUT_MPLANE && + !(b->flags & V4L2_BUF_FLAG_CODECCONFIG)) msm_comm_fetch_ts_framerate(inst, b); return rc; From 912bb52fc15ba63817822188267deea898d1d939 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Fri, 31 Jul 2020 13:58:28 -0700 Subject: [PATCH 331/452] msm: vidc: Update DCVS thresholds for sufficient seq change 1. Sufficient event should use fw min count for DCVS. 2. Input buffer count calculation is independent of Realtime/Non-Realtime. 3. Batching should be disabled if it is non-realtime session. 4. Removed misleading logs and changed buffer count logs to convey the correct meaning. Change-Id: Ieba6fc022549f5e767a833410ead5aa7fb52e14b Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc.c | 8 +-- msm/vidc/msm_vidc_buffer_calculations.c | 3 +- msm/vidc/msm_vidc_buffer_calculations.h | 4 +- msm/vidc/msm_vidc_clocks.c | 78 ++++++++++++++++--------- msm/vidc/msm_vidc_clocks.h | 1 + msm/vidc/msm_vidc_common.c | 38 ++++++++---- 6 files changed, 86 insertions(+), 46 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 3f789a4afe46..f93db252a0a2 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1403,13 +1403,13 @@ static int try_get_ctrl_for_instance(struct msm_vidc_inst *inst, break; case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: ctrl->val = inst->fmts[OUTPUT_PORT].count_min_host; - s_vpr_h(inst->sid, "g_min: hal_buffer %d min buffers %d\n", - HAL_BUFFER_OUTPUT, ctrl->val); + s_vpr_h(inst->sid, "g_min: OUTPUT_PORT count_min_host %d\n", + ctrl->val); break; case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: ctrl->val = inst->fmts[INPUT_PORT].count_min_host; - s_vpr_h(inst->sid, "g_min: hal_buffer %d min buffers %d\n", - HAL_BUFFER_INPUT, ctrl->val); + s_vpr_h(inst->sid, "g_min: INPUT_PORT count_min_host %d\n", + ctrl->val); break; case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA: ctrl->val = inst->prop.extradata_ctrls; diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 63ed34ed17f8..f9feb2fd649b 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -790,11 +790,10 @@ static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst) core = inst->core; /* - * For a non-realtime session, extra buffers are not required. * For thumbnail session, extra buffers are not required as * neither dcvs nor batching will be enabled. */ - if (!is_realtime_session(inst) || is_thumbnail_session(inst)) + if (is_thumbnail_session(inst)) return extra_input_count; if (is_decode_session(inst)) { diff --git a/msm/vidc/msm_vidc_buffer_calculations.h b/msm/vidc/msm_vidc_buffer_calculations.h index dce14310991e..e890db526660 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.h +++ b/msm/vidc/msm_vidc_buffer_calculations.h @@ -6,9 +6,9 @@ #ifndef __H_MSM_VIDC_BUFFER_MEM_DEFS_H__ #define __H_MSM_VIDC_BUFFER_MEM_DEFS_H__ -/* extra o/p buffers in case of dcvs */ +/* extra buffers in case of dcvs */ #define DCVS_DEC_EXTRA_OUTPUT_BUFFERS 4 -#define DCVS_ENC_EXTRA_INPUT_BUFFERS DCVS_DEC_EXTRA_OUTPUT_BUFFERS +#define DCVS_ENC_EXTRA_INPUT_BUFFERS 4 struct msm_vidc_dec_buff_size_calculators { u32 (*calculate_scratch_size)(struct msm_vidc_inst *inst, u32 width, diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 59dfd21a88dc..d8681cf26474 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1008,6 +1008,53 @@ int msm_dcvs_try_enable(struct msm_vidc_inst *inst) return 0; } +void msm_dcvs_reset(struct msm_vidc_inst *inst) +{ + struct msm_vidc_format *fmt; + struct clock_data *dcvs; + + if (!inst) { + d_vpr_e("%s: Invalid params\n", __func__); + return; + } + + dcvs = &inst->clk_data; + if (inst->session_type == MSM_VIDC_ENCODER) { + fmt = &inst->fmts[INPUT_PORT]; + } else if (inst->session_type == MSM_VIDC_DECODER) { + fmt = &inst->fmts[OUTPUT_PORT]; + } else { + s_vpr_e(inst->sid, "%s: invalid session type %#x\n", + __func__, inst->session_type); + return; + } + + dcvs->min_threshold = fmt->count_min; + if (inst->session_type == MSM_VIDC_ENCODER) + dcvs->max_threshold = + min((fmt->count_min + DCVS_ENC_EXTRA_INPUT_BUFFERS), + fmt->count_actual); + else + dcvs->max_threshold = + min((fmt->count_min + DCVS_DEC_EXTRA_OUTPUT_BUFFERS), + fmt->count_actual); + + dcvs->dcvs_window = + dcvs->max_threshold < dcvs->min_threshold ? 0 : + dcvs->max_threshold - dcvs->min_threshold; + dcvs->nom_threshold = dcvs->min_threshold + + (dcvs->dcvs_window ? + (dcvs->dcvs_window / 2) : 0); + + dcvs->dcvs_flags = 0; + + s_vpr_p(inst->sid, "DCVS: Th[%d %d %d] Flag %#x\n", + dcvs->min_threshold, + dcvs->nom_threshold, dcvs->max_threshold, + dcvs->dcvs_flags); + +} + int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst) { int rc = 0, j = 0; @@ -1048,8 +1095,6 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) struct allowed_clock_rates_table *allowed_clks_tbl = NULL; u64 total_freq = 0, rate = 0, load; int cycles; - struct clock_data *dcvs; - struct msm_vidc_format *fmt; if (!inst || !inst->core || !inst->clk_data.entry) { d_vpr_e("%s: Invalid args: Inst = %pK\n", @@ -1059,35 +1104,14 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) s_vpr_h(inst->sid, "Init DCVS Load\n"); core = inst->core; - dcvs = &inst->clk_data; load = msm_comm_get_inst_load_per_core(inst, LOAD_POWER); cycles = inst->clk_data.entry->vpp_cycles; allowed_clks_tbl = core->resources.allowed_clks_tbl; - if (inst->session_type == MSM_VIDC_ENCODER) { - cycles = inst->flags & VIDC_LOW_POWER ? - inst->clk_data.entry->low_power_cycles : - cycles; + if (inst->session_type == MSM_VIDC_ENCODER && + inst->flags & VIDC_LOW_POWER) + cycles = inst->clk_data.entry->low_power_cycles; - fmt = &inst->fmts[INPUT_PORT]; - } else if (inst->session_type == MSM_VIDC_DECODER) { - fmt = &inst->fmts[OUTPUT_PORT]; - } else { - s_vpr_e(inst->sid, "%s: invalid session type %#x\n", - __func__, inst->session_type); - return; - } - - dcvs->min_threshold = fmt->count_min; - dcvs->max_threshold = - min((fmt->count_min + DCVS_DEC_EXTRA_OUTPUT_BUFFERS), - fmt->count_actual); - - dcvs->dcvs_window = - dcvs->max_threshold < dcvs->min_threshold ? 0 : - dcvs->max_threshold - dcvs->min_threshold; - dcvs->nom_threshold = dcvs->min_threshold + - (dcvs->dcvs_window ? - (dcvs->dcvs_window / 2) : 0); + msm_dcvs_reset(inst); total_freq = cycles * load; diff --git a/msm/vidc/msm_vidc_clocks.h b/msm/vidc/msm_vidc_clocks.h index f32b370849d6..30a2d40a039f 100644 --- a/msm/vidc/msm_vidc_clocks.h +++ b/msm/vidc/msm_vidc_clocks.h @@ -8,6 +8,7 @@ #include "msm_vidc_internal.h" void msm_clock_data_reset(struct msm_vidc_inst *inst); +void msm_dcvs_reset(struct msm_vidc_inst *inst); int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid); int msm_comm_vote_bus(struct msm_vidc_inst *inst); int msm_dcvs_try_enable(struct msm_vidc_inst *inst); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 6fcc7be8bba8..90a6605ac539 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1598,7 +1598,6 @@ static void handle_event_change(enum hal_command_response cmd, void *data) struct hfi_device *hdev; u32 *ptr = NULL; struct msm_vidc_format *fmt; - struct v4l2_format *f; u32 codec; if (!event_notify) { @@ -1650,11 +1649,12 @@ static void handle_event_change(enum hal_command_response cmd, void *data) inst->pic_struct == MSM_VIDC_PIC_STRUCT_MAYBE_INTERLACED)) event_fields_changed = true; - f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + fmt = &inst->fmts[OUTPUT_PORT]; event_fields_changed |= - (f->fmt.pix_mp.height != event_notify->height); + (fmt->v4l2_fmt.fmt.pix_mp.height != + event_notify->height); event_fields_changed |= - (f->fmt.pix_mp.width != event_notify->width); + (fmt->v4l2_fmt.fmt.pix_mp.width != event_notify->width); if (event_fields_changed) { event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT; @@ -1670,6 +1670,10 @@ static void handle_event_change(enum hal_command_response cmd, void *data) "%s: Failed to decide work mode\n", __func__); } + + fmt->count_min = event_notify->fw_min_cnt; + msm_dcvs_reset(inst); + s_vpr_h(inst->sid, "seq: No parameter change continue session\n"); rc = call_hfi_op(hdev, session_continue, @@ -2809,6 +2813,7 @@ bool is_batching_allowed(struct msm_vidc_inst *inst) { u32 op_pixelformat, fps, maxmbs, maxfps; u32 ignore_flags = VIDC_THUMBNAIL; + u32 enable = 0; if (!inst || !inst->core) return false; @@ -2827,17 +2832,23 @@ bool is_batching_allowed(struct msm_vidc_inst *inst) * as sufficient extra buffers (required for batch mode * on both ports) may not have been updated to client. */ - return (inst->batch.enable && + enable = (inst->batch.enable && inst->core->resources.decode_batching && !is_low_latency_hint(inst) && is_single_session(inst, ignore_flags) && is_decode_session(inst) && !is_thumbnail_session(inst) && + is_realtime_session(inst) && !inst->clk_data.low_latency_mode && (op_pixelformat == V4L2_PIX_FMT_NV12_UBWC || op_pixelformat == V4L2_PIX_FMT_NV12_TP10_UBWC) && fps <= maxfps && msm_vidc_get_mbs_per_frame(inst) <= maxmbs); + + s_vpr_hp(inst->sid, "%s: batching %s\n", + __func__, enable ? "enabled" : "disabled"); + + return enable; } static int msm_comm_session_abort(struct msm_vidc_inst *inst) @@ -4941,7 +4952,10 @@ int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst) for (i = 0; i < HAL_BUFFER_MAX; i++) { struct hal_buffer_requirements req = inst->buff_req.buffer[i]; - if (req.buffer_type != HAL_BUFFER_NONE) { + if (req.buffer_type != HAL_BUFFER_NONE && + req.buffer_type != HAL_BUFFER_INPUT && + req.buffer_type != HAL_BUFFER_OUTPUT && + req.buffer_type != HAL_BUFFER_OUTPUT2) { s_vpr_h(inst->sid, "%15s %8d %8d %8d %8d %8d\n", get_buffer_name(req.buffer_type), req.buffer_count_actual, @@ -5319,7 +5333,7 @@ int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst) } int msm_comm_set_buffer_count(struct msm_vidc_inst *inst, - int host_count, int act_count, enum hal_buffer type) + int min_count, int act_count, enum hal_buffer type) { int rc = 0; struct v4l2_ctrl *ctrl; @@ -5334,20 +5348,22 @@ int msm_comm_set_buffer_count(struct msm_vidc_inst *inst, buf_count.buffer_type = get_hfi_buffer(type, inst->sid); buf_count.buffer_count_actual = act_count; - buf_count.buffer_count_min_host = host_count; + buf_count.buffer_count_min_host = min_count; /* set total superframe buffers count */ ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); if (ctrl->val) buf_count.buffer_count_actual = act_count * ctrl->val; - s_vpr_h(inst->sid, "%s: hal_buffer %d min_host %d actual %d\n", - __func__, type, host_count, act_count); + s_vpr_h(inst->sid, + "%s: hal_buffer %d min %d actual %d superframe %d\n", + __func__, type, min_count, + buf_count.buffer_count_actual, ctrl->val); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL, &buf_count, sizeof(buf_count)); if (rc) s_vpr_e(inst->sid, "Failed to set actual buffer count %d for buffer type %d\n", - act_count, type); + buf_count.buffer_count_actual, type); return rc; } From cd778f698821e409194d3112004a2b2fe4bed133 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Thu, 30 Jul 2020 09:46:52 +0530 Subject: [PATCH 332/452] msm: vidc: always read fuse value irrespective of sku-index [1] Only one vidc node is maintained, so "sku-index" entry is removed in dtsi. [2] In video driver, always read fuse value if efuse_data entry is populated Change-Id: I86b8c38f1e71491678b54a11783292e1281f90d3 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_platform.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 473c3e934208..a08af134f47d 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1625,11 +1625,9 @@ void *vidc_get_drv_data(struct device *dev) goto exit; /* Check for sku version */ - if (of_find_property(dev->of_node, "sku-index", NULL)) { - rc = msm_vidc_read_efuse(driver_data, dev); - if (rc) - goto exit; - } + rc = msm_vidc_read_efuse(driver_data, dev); + if (rc) + goto exit; if (!strcmp(match->compatible, "qcom,lahaina-vidc")) { ddr_type = of_fdt_get_ddrtype(); From d36983b6f630a991451867588026787957ce5c7d Mon Sep 17 00:00:00 2001 From: Rakshitha Shakamuri Date: Fri, 7 Aug 2020 14:43:07 -0700 Subject: [PATCH 333/452] Revert "msm: vidc: Update timer API" This reverts commit a03df1c59360676143d4f06f1957d712a47af93e. Change-Id: I65a664bfcb25a534fc71be238dae8560cea3fd6c Signed-off-by: Rakshitha Shakamuri --- msm/vidc/msm_vidc_debug.c | 4 ++++ msm/vidc/msm_vidc_debug.h | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index b692f8c9f05b..4b0f6090de40 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -728,6 +728,10 @@ inline bool is_print_allowed(u32 sid, u32 level) } /* Mock all the missing parts for successful compilation starts here */ +void do_gettimeofday(struct timeval *__ddl_tv) +{ +} + #ifndef CONFIG_VIDEOBUF2_CORE void vb2_queue_release(struct vb2_queue *q) { diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index 389b0d9e9eb8..7b523eddb55f 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -19,6 +19,8 @@ // void disable_irq_nosync(unsigned int irq); // void enable_irq(unsigned int irq); +void do_gettimeofday(struct timeval *__ddl_tv); + #ifndef CONFIG_VIDEOBUF2_CORE int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req); int vb2_qbuf(struct vb2_queue *q, struct media_device *mdev, @@ -232,7 +234,7 @@ static inline void tic(struct msm_vidc_inst *i, enum profiling_points p, memcpy(i->debug.pdata[p].name, b, 64); if ((msm_vidc_debug & VIDC_PERF) && i->debug.pdata[p].sampling) { - __ddl_tv = ktime_to_timeval(ktime_get_real()); + do_gettimeofday(&__ddl_tv); i->debug.pdata[p].start = (__ddl_tv.tv_sec * 1000) + (__ddl_tv.tv_usec / 1000); i->debug.pdata[p].sampling = false; @@ -245,7 +247,7 @@ static inline void toc(struct msm_vidc_inst *i, enum profiling_points p) if ((msm_vidc_debug & VIDC_PERF) && !i->debug.pdata[p].sampling) { - __ddl_tv = ktime_to_timeval(ktime_get_real()); + do_gettimeofday(&__ddl_tv); i->debug.pdata[p].stop = (__ddl_tv.tv_sec * 1000) + (__ddl_tv.tv_usec / 1000); i->debug.pdata[p].cumulative += i->debug.pdata[p].stop - From 5e7df6ab913136de82b3009cf498ab979c1b6afe Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 10 Aug 2020 13:24:30 +0530 Subject: [PATCH 334/452] msm: vidc: Deprecate Mpeg2 secure decode support Remove secure deocde support for Mpeg2 codec. Change-Id: Ieec132b0c86aa6be3e382c091acdf734d1e1c31e Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vdec.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index c53353abd940..42707e64d3f1 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -1195,10 +1195,9 @@ int msm_vdec_set_secure_mode(struct msm_vidc_inst *inst) if (ctrl->val) { if (!(codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264 || - codec == V4L2_PIX_FMT_VP9 || - codec == V4L2_PIX_FMT_MPEG2)) { + codec == V4L2_PIX_FMT_VP9)) { s_vpr_e(inst->sid, - "%s: Secure allowed for HEVC/H264/VP9/MPEG2\n", + "%s: Secure allowed for HEVC/H264/VP9\n", __func__); return -EINVAL; } From 460c45b72ae224d3f136cb0dc1d96584610d793e Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Wed, 5 Aug 2020 14:13:37 +0800 Subject: [PATCH 335/452] msm: vidc: fix time stamp store after EOS for decoders 1. Add a new EOS flag to denote EOS pending status; 2. Set all existed time stamps with EOS flag as true after inserting EOS time stamp; 3. Ignore time stamp sorting to buffers with EOS pending flag as true; Change-Id: I72b041150973e2a28d1039c5f906fdb222a86081 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_vidc.c | 3 ++- msm/vidc/msm_vidc_common.c | 19 +++++++++++++++---- msm/vidc/msm_vidc_common.h | 3 ++- msm/vidc/msm_vidc_internal.h | 1 + 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 9d7d8d27257a..8243a1a88737 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -438,7 +438,8 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, inst->flush_timestamps = false; if (!(b->flags & V4L2_BUF_FLAG_CODECCONFIG)) - rc = msm_comm_store_timestamp(inst, timestamp_us); + rc = msm_comm_store_timestamp(inst, timestamp_us, + b->flags & V4L2_BUF_FLAG_EOS); if (rc) goto unlock; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 90a6605ac539..f92584b6a485 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7600,7 +7600,8 @@ void msm_comm_release_timestamps(struct msm_vidc_inst *inst) mutex_unlock(&inst->timestamps.lock); } -int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) +int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us, + bool is_eos) { struct msm_vidc_timestamps *entry, *node, *prev = NULL; struct msm_vidc_timestamps *duplicate; @@ -7618,7 +7619,8 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) duplicate = NULL; list_for_each_entry(node, &inst->timestamps.list, list) { count++; - if (node->is_valid && node->timestamp_us == timestamp_us) + if (node->is_valid && node->timestamp_us == timestamp_us && + !node->is_eos) duplicate = node; } @@ -7649,6 +7651,7 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) entry->timestamp_us = duplicate->timestamp_us; entry->framerate = duplicate->framerate; entry->is_valid = true; + entry->is_eos = is_eos; /* add entry next to duplicate */ list_add(&entry->list, &duplicate->list); goto unlock; @@ -7661,7 +7664,8 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) prev = NULL; inserted = false; list_for_each_entry(node, &inst->timestamps.list, list) { - if (entry->timestamp_us < node->timestamp_us) { + if (entry->timestamp_us < node->timestamp_us && + !node->is_eos) { /* * if prev available add entry next to prev else * entry is first so add it at head. @@ -7688,7 +7692,8 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) node->timestamp_us, prev->timestamp_us); break; } - if (node->timestamp_us == entry->timestamp_us) { + if (node->timestamp_us == entry->timestamp_us && + !node->is_eos) { if (prev) node->framerate = msm_comm_calc_framerate(inst, node->timestamp_us, prev->timestamp_us); @@ -7697,6 +7702,12 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) prev = node; } + /* mark all entries as eos if is_eos is queued */ + if (is_eos) + list_for_each_entry(node, &inst->timestamps.list, list) { + node->is_eos = true; + } + unlock: mutex_unlock(&inst->timestamps.lock); return rc; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 57f30be43c1a..7880f6d7a5d7 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -400,7 +400,8 @@ int msm_comm_set_cvp_skip_ratio(struct msm_vidc_inst *inst, uint32_t capture_rate, uint32_t cvp_rate); int msm_comm_fetch_ts_framerate(struct msm_vidc_inst *inst, struct v4l2_buffer *b); -int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us); +int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us, + bool is_eos); void msm_comm_release_timestamps(struct msm_vidc_inst *inst); u32 msm_comm_get_max_framerate(struct msm_vidc_inst *inst); u32 msm_comm_calc_framerate(struct msm_vidc_inst *inst, u64 timestamp_us, diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index cd2f35c46852..f57f36e455c9 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -239,6 +239,7 @@ struct msm_vidc_timestamps { u64 timestamp_us; u32 framerate; bool is_valid; + bool is_eos; }; enum efuse_purpose { From 4be4e326bfc34a12173199d248f29a510e21cd84 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Thu, 6 Aug 2020 14:31:37 -0700 Subject: [PATCH 336/452] msm: vidc: Fix incorrect VP9 scratch buffer calculation Fix the incorrect VP9 decoder scratch buffer calculation and match it with firmware definition of scratch buffer size. Change-Id: Ie901082760d675153d1eb898cbe665cc6ad59bd1 Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_buffer_calculations.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index f9feb2fd649b..03079a37ee35 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1349,13 +1349,15 @@ static inline u32 calculate_vpxd_scratch_size(struct msm_vidc_inst *inst, ((BIN_BUFFER_THRESHOLD * 3) >> 1)) * VPX_DECODER_FRAME_CONCURENCY_LVL * VPX_DECODER_FRAME_BIN_HDR_BUDGET_RATIO_NUM / - VPX_DECODER_FRAME_BIN_HDR_BUDGET_RATIO_DEN, + VPX_DECODER_FRAME_BIN_HDR_BUDGET_RATIO_DEN / + num_vpp_pipes, VENUS_DMA_ALIGNMENT); binbuffer2_size = ALIGN(max_t(u32, size_yuv, ((BIN_BUFFER_THRESHOLD * 3) >> 1)) * VPX_DECODER_FRAME_CONCURENCY_LVL * VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO_NUM / - VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO_DEN, + VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO_DEN / + num_vpp_pipes, VENUS_DMA_ALIGNMENT); size = binbuffer1_size + binbuffer2_size; size = size * num_vpp_pipes; From b1a132ad57c384f0d2fe4a22cf0d7de0817b1bc7 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Mon, 10 Aug 2020 13:52:36 +0800 Subject: [PATCH 337/452] msm: vidc: revise timestamp data type to s64 Revise internal timestamp data type from u64 to s64 in case of negative timestamps. Change-Id: Ib026d504a08ce5ac67d1d962b671c37637761321 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_vidc.c | 4 ++-- msm/vidc/msm_vidc_common.c | 6 +++--- msm/vidc/msm_vidc_common.h | 2 +- msm/vidc/msm_vidc_internal.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 8243a1a88737..7f78071d585d 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -366,7 +366,7 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, int rc = 0; unsigned int i = 0; struct buf_queue *q = NULL; - u64 timestamp_us = 0; + s64 timestamp_us = 0; u32 cr = 0; if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) { @@ -430,7 +430,7 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, && b->type == INPUT_MPLANE) b->flags |= V4L2_BUF_FLAG_PERF_MODE; - timestamp_us = (u64)((b->timestamp.tv_sec * 1000000ULL) + + timestamp_us = (s64)((b->timestamp.tv_sec * 1000000) + b->timestamp.tv_usec); if (is_decode_session(inst) && b->type == INPUT_MPLANE) { if (inst->flush_timestamps) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index f92584b6a485..652334c646c4 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7600,7 +7600,7 @@ void msm_comm_release_timestamps(struct msm_vidc_inst *inst) mutex_unlock(&inst->timestamps.lock); } -int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us, +int msm_comm_store_timestamp(struct msm_vidc_inst *inst, s64 timestamp_us, bool is_eos) { struct msm_vidc_timestamps *entry, *node, *prev = NULL; @@ -7794,8 +7794,8 @@ int msm_comm_fetch_ts_framerate(struct msm_vidc_inst *inst, if (!(b->flags & V4L2_BUF_FLAG_END_OF_SUBFRAME)) node->is_valid = false; - b->timestamp.tv_sec = node->timestamp_us / 1000000ull; - b->timestamp.tv_usec = node->timestamp_us % 1000000ull; + b->timestamp.tv_sec = node->timestamp_us / 1000000; + b->timestamp.tv_usec = node->timestamp_us % 1000000; b->m.planes[0].reserved[MSM_VIDC_FRAMERATE] = node->framerate; break; } diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 7880f6d7a5d7..e46c5bbd9f62 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -400,7 +400,7 @@ int msm_comm_set_cvp_skip_ratio(struct msm_vidc_inst *inst, uint32_t capture_rate, uint32_t cvp_rate); int msm_comm_fetch_ts_framerate(struct msm_vidc_inst *inst, struct v4l2_buffer *b); -int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us, +int msm_comm_store_timestamp(struct msm_vidc_inst *inst, s64 timestamp_us, bool is_eos); void msm_comm_release_timestamps(struct msm_vidc_inst *inst); u32 msm_comm_get_max_framerate(struct msm_vidc_inst *inst); diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index f57f36e455c9..e04ac940ace2 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -236,7 +236,7 @@ struct msm_vidc_codec { struct msm_vidc_timestamps { struct list_head list; - u64 timestamp_us; + s64 timestamp_us; u32 framerate; bool is_valid; bool is_eos; From be77d74ff10deb720932db7678e4f622bc93c7b6 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Tue, 11 Aug 2020 20:20:00 +0530 Subject: [PATCH 338/452] msm: vidc: update vsp_cycle entries for shima Updated VSP base cycle entries for Shima to inline with vperf. Change-Id: I26e7a521434765b97cc1a508b714652d14adf2aa Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_platform.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index a08af134f47d..877b7aeebde3 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -72,12 +72,12 @@ static struct msm_vidc_codec_data bengal_codec_data[] = { }; static struct msm_vidc_codec_data shima_codec_data[] = { - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 0, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 0, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 25, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 25, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 25, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 25, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 25, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 60, 200, 200), }; static struct msm_vidc_codec_data holi_codec_data[] = { From 36d91e66e0fe1e93f1035e16b05d1af894e170a2 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Tue, 11 Aug 2020 11:50:52 +0530 Subject: [PATCH 339/452] msm: vidc: set chroma_qp_offset only for client set cases Set chroma_qp_offset hfi to firmware only for client set cases. Supported value: 0 & -12 If hfi not set, firmware proceeds with its own default value. 10-bit: default: 0 8-bit : default: Adaptive chroma_qp Change-Id: I40262aae87b2a385c6cd7d60faa19b6adfe8b151 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_venc.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index cf7b502ce8f5..bf3184fe1040 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -32,8 +32,6 @@ #define DEFAULT_QP 0xA #define DEFAULT_QP_PACKED 0xA0A0A #define MIN_CHROMA_QP_OFFSET -12 -#define MAX_CHROMA_QP_OFFSET 0 -#define DEFAULT_CHROMA_QP_OFFSET 0 #define MAX_INTRA_REFRESH_MBS ((7680 * 4320) >> 8) #define MAX_LTR_FRAME_COUNT 10 #define MAX_NUM_B_FRAMES 1 @@ -927,8 +925,8 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .name = "Chroma QP Index Offset", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = MIN_CHROMA_QP_OFFSET, - .maximum = MAX_CHROMA_QP_OFFSET, - .default_value = DEFAULT_CHROMA_QP_OFFSET, + .maximum = INT_MAX, + .default_value = INT_MAX, .step = 1, }, { @@ -3381,7 +3379,7 @@ int msm_venc_set_chroma_qp_offset(struct msm_vidc_inst *inst) hdev = inst->core->device; chr = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET); - if (chr->val != MIN_CHROMA_QP_OFFSET) + if (chr->val == INT_MAX || (chr->val != 0 && chr->val != -12)) return 0; f = &inst->fmts[INPUT_PORT].v4l2_fmt; From 5a5d1b28593037876d9c973d8cd2809595a0aae1 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Tue, 11 Aug 2020 15:47:34 -0700 Subject: [PATCH 340/452] msm: vidc: Update VP9 decoder capabilities Revise VP9 decoder capabilities and limits to match the updated Lahaina PRD. Change-Id: I7a92c88b21e19ab44b43a0c829491f58aa1ce492 Signed-off-by: Mihir Ganu --- msm/vidc/msm_vdec.c | 2 +- msm/vidc/msm_vidc_platform.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 42707e64d3f1..685f56e6c17b 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -17,7 +17,7 @@ #define MIN_NUM_DEC_CAPTURE_BUFFERS 4 /* Y=16(0-9bits), Cb(10-19bits)=Cr(20-29bits)=128, black by default */ #define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8020010 -#define MAX_VP9D_INST_COUNT 6 +#define MAX_VP9D_INST_COUNT 3 static const char *const mpeg_video_h264_profile[] = { "Baseline", diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 877b7aeebde3..259c13747682 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -358,6 +358,16 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, + /* VP9 decoder-specific */ + {CAP_FRAME_WIDTH, DEC, VP9, 96, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, VP9, 96, 4096, 1, 1080}, + /* (4096 * 2304) / 256 */ + {CAP_MBS_PER_FRAME, DEC, VP9, 36, 36864, 1, 36864}, + /* ((4096 * 2304) / 256) * 60*/ + {CAP_MBS_PER_SECOND, DEC, VP9, 36, 2211840, 1, 2211840}, + {CAP_FRAMERATE, DEC, VP9, 1, 60, 1, 60}, + {CAP_BITRATE, DEC, VP9, 1, 100000000, 1, 20000000}, + /* Secure usecase specific */ {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, From b560c7a295076b2bde60e2b7cfdc28fa2c44771d Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Mon, 17 Aug 2020 17:49:35 +0530 Subject: [PATCH 341/452] msm: vidc: Restrict dynamic low latency for h264 and hevc In existing approach, dynamic low latency i.e low latency hint is restricted via specific low latency components in userspace. This change adds one more checkpoint to ensure that video firmware is configured for low latency only for desired codecs. Change-Id: Iad36c3b84ddc3b94033c4bf5f0afdd3a18600111 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vdec.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 685f56e6c17b..a05c28d11f89 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -1326,6 +1326,7 @@ int msm_vdec_set_priority(struct msm_vidc_inst *inst) int msm_vdec_set_seqchng_at_syncframe(struct msm_vidc_inst *inst) { int rc = 0; + u32 codec; struct hfi_device *hdev; struct hfi_enable hfi_property; @@ -1339,6 +1340,13 @@ int msm_vdec_set_seqchng_at_syncframe(struct msm_vidc_inst *inst) if (!hfi_property.enable) return 0; + codec = get_v4l2_codec(inst); + if (!(codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264)) { + s_vpr_e(inst->sid, + "%s: low latency hint supported for HEVC/H264\n", + __func__); + return -EINVAL; + } s_vpr_h(inst->sid, "%s: %#x\n", __func__, hfi_property.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_VDEC_SEQCHNG_AT_SYNCFRM, &hfi_property, From 0e570d90fa28e843d8b375202b054100256b4e71 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Wed, 10 Jun 2020 15:09:10 +0800 Subject: [PATCH 342/452] msm: vidc: improve heif decoder performance Add V4L2 interface to indicate heif decoder, and use below configurations to improve performance. 1. Set turbo session 2. Disable DCVS and batch 3. Increase input and output buffer count to 12 4. Modify input buffer size calculation 5. Avoid framerate calc and ts list maintenance 6. Skip setting bse-vpp delay Change-Id: I9a47a88154238db3ac4285462c6030114546d333 Signed-off-by: Qiwei Liu --- include/uapi/vidc/media/msm_vidc_utils.h | 2 ++ msm/vidc/msm_vdec.c | 18 ++++++++++++++++++ msm/vidc/msm_vidc.c | 6 ++++-- msm/vidc/msm_vidc_buffer_calculations.c | 17 ++++++++++++++++- msm/vidc/msm_vidc_clocks.c | 1 + msm/vidc/msm_vidc_common.c | 1 + msm/vidc/msm_vidc_common.h | 11 +++++++++++ 7 files changed, 53 insertions(+), 3 deletions(-) diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index 2e4f351c4927..a20d4816841a 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -252,6 +252,8 @@ enum v4l2_mpeg_vidc_video_bitrate_savings_type { (V4L2_CID_MPEG_MSM_VIDC_BASE + 132) #define V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_HINT \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 133) +#define V4L2_CID_MPEG_VIDC_VDEC_HEIF_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 134) #define V4L2_CID_MPEG_VIDC_VIDEO_UNKNOWN \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 0xFFF) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 685f56e6c17b..5a2b8a348978 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -434,6 +434,15 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .default_value = 0, .step = 1, }, + { + .id = V4L2_CID_MPEG_VIDC_VDEC_HEIF_MODE, + .name = "HEIF Decoder", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, }; #define NUM_CTRLS ARRAY_SIZE(msm_vdec_ctrls) @@ -948,6 +957,15 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_HINT: break; + case V4L2_CID_MPEG_VIDC_VDEC_HEIF_MODE: + if(get_v4l2_codec(inst) != V4L2_PIX_FMT_HEVC) + break; + inst->flags &= ~VIDC_TURBO; + if (ctrl->val) + inst->flags |= VIDC_TURBO; + if (inst->state < MSM_VIDC_LOAD_RESOURCES) + msm_vidc_calculate_buffer_counts(inst); + break; default: s_vpr_e(inst->sid, "Unknown control %#x\n", ctrl->id); break; diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 7f78071d585d..499abc4f5ad8 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -432,7 +432,8 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, timestamp_us = (s64)((b->timestamp.tv_sec * 1000000) + b->timestamp.tv_usec); - if (is_decode_session(inst) && b->type == INPUT_MPLANE) { + if (is_decode_session(inst) && b->type == INPUT_MPLANE && + !is_heif_decoder(inst)) { if (inst->flush_timestamps) msm_comm_release_timestamps(inst); inst->flush_timestamps = false; @@ -513,7 +514,8 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) } if (is_decode_session(inst) && b->type == OUTPUT_MPLANE && - !(b->flags & V4L2_BUF_FLAG_CODECCONFIG)) + !(b->flags & V4L2_BUF_FLAG_CODECCONFIG) && + !is_heif_decoder(inst)) msm_comm_fetch_ts_framerate(inst, b); return rc; diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 03079a37ee35..4b1a2bd287d9 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -27,6 +27,10 @@ /* extra output buffers for encoder HEIF usecase */ #define HEIF_ENC_TOTAL_OUTPUT_BUFFERS 12 +/* extra buffer count for heif decoder */ +#define HEIF_DEC_TOTAL_INPUT_BUFFERS 12 +#define HEIF_DEC_EXTRA_OUTPUT_BUFFERS 8 + #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_WIDTH 32 #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_HEIGHT 8 #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_UV_TILE_WIDTH 16 @@ -789,6 +793,9 @@ static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst) core = inst->core; + if (is_heif_decoder(inst)) + return (HEIF_DEC_TOTAL_INPUT_BUFFERS - MIN_INPUT_BUFFERS); + /* * For thumbnail session, extra buffers are not required as * neither dcvs nor batching will be enabled. @@ -821,6 +828,9 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) core = inst->core; + if (is_heif_decoder(inst)) + return HEIF_DEC_EXTRA_OUTPUT_BUFFERS; + /* * For a non-realtime session, extra buffers are not required. * For thumbnail session, extra buffers are not required as @@ -829,7 +839,7 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) if (!is_realtime_session(inst) || is_thumbnail_session(inst)) return extra_output_count; - /* For HEIF, we are increasing buffer count */ + /* For HEIF encoder, we are increasing buffer count */ if (is_image_session(inst)) { extra_output_count = (HEIF_ENC_TOTAL_OUTPUT_BUFFERS - MIN_ENC_OUTPUT_BUFFERS); @@ -889,6 +899,11 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) base_res_mbs = inst->capability.cap[CAP_MBS_PER_FRAME].max; div_factor = 1; } + /* For HEIF image, use the actual resolution to calc buffer size */ + if (is_heif_decoder(inst)) { + base_res_mbs = num_mbs; + div_factor = 1; + } frame_size = base_res_mbs * MB_SIZE_IN_PIXEL * 3 / 2 / div_factor; diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 0af709fe2d36..64b5f95408f9 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1293,6 +1293,7 @@ int msm_vidc_set_bse_vpp_delay(struct msm_vidc_inst *inst) if (!inst->core->resources.has_vpp_delay || !is_decode_session(inst) || is_thumbnail_session(inst) || + is_heif_decoder(inst) || inst->clk_data.work_mode != HFI_WORKMODE_2) { s_vpr_hp(inst->sid, "%s: Skip bse-vpp\n", __func__); return 0; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 652334c646c4..0cab94351d95 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2839,6 +2839,7 @@ bool is_batching_allowed(struct msm_vidc_inst *inst) is_decode_session(inst) && !is_thumbnail_session(inst) && is_realtime_session(inst) && + !is_heif_decoder(inst) && !inst->clk_data.low_latency_mode && (op_pixelformat == V4L2_PIX_FMT_NV12_UBWC || op_pixelformat == V4L2_PIX_FMT_NV12_TP10_UBWC) && diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index e46c5bbd9f62..24a04dd0a257 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -121,6 +121,17 @@ static inline bool is_grid_session(struct msm_vidc_inst *inst) return 0; } +static inline bool is_heif_decoder(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *ctrl = NULL; + if (inst->session_type == MSM_VIDC_DECODER && + get_v4l2_codec(inst) == V4L2_PIX_FMT_HEVC) { + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VDEC_HEIF_MODE); + return (ctrl->val > 0); + } + return 0; +} + static inline bool is_video_session(struct msm_vidc_inst *inst) { return !is_grid_session(inst); From c24265be5ce3e7150ba5cd0dec22a8c8aa90b2c0 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Tue, 18 Aug 2020 18:42:47 +0530 Subject: [PATCH 343/452] msm: vidc: Update VP9 decoder capabilities for shima Update VP9 decoder capabilities for shima to be inline with lahaina. Change-Id: Ieab73987d92bb093fd06391086935900b5e01768 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_platform.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 259c13747682..1d42b06aced4 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -448,7 +448,7 @@ static struct msm_vidc_codec_capability shima_capabilities_v0[] = { {CAP_SCALE_Y, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, - {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 4, 1, 0}, + {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 2, 1, 0}, /* ((1920 * 1088) / 256) * 60 fps */ {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, 0, 489600, 1, 489600}, @@ -470,6 +470,16 @@ static struct msm_vidc_codec_capability shima_capabilities_v0[] = { {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, + /* VP9 decoder-specific */ + {CAP_FRAME_WIDTH, DEC, VP9, 96, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, VP9, 96, 4096, 1, 1080}, + /* (4096 * 2304) / 256 */ + {CAP_MBS_PER_FRAME, DEC, VP9, 36, 36864, 1, 36864}, + /* ((4096 * 2304) / 256) * 60 */ + {CAP_MBS_PER_SECOND, DEC, VP9, 36, 2211840, 1, 2211840}, + {CAP_FRAMERATE, DEC, VP9, 1, 60, 1, 60}, + {CAP_BITRATE, DEC, VP9, 1, 100000000, 1, 20000000}, + /* Secure usecase specific */ {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, @@ -545,7 +555,7 @@ static struct msm_vidc_codec_capability shima_capabilities_v1[] = { {CAP_SCALE_Y, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, - {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 4, 1, 0}, + {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 2, 1, 0}, /* ((1920 * 1088) / 256) * 30 fps */ {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, 0, 244800, 1, 244800}, @@ -567,6 +577,16 @@ static struct msm_vidc_codec_capability shima_capabilities_v1[] = { {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, + /* VP9 decoder-specific */ + {CAP_FRAME_WIDTH, DEC, VP9, 96, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, VP9, 96, 4096, 1, 1080}, + /* (4096 * 2304) / 256 */ + {CAP_MBS_PER_FRAME, DEC, VP9, 36, 36864, 1, 36864}, + /* ((4096 * 2304) / 256) * 60 */ + {CAP_MBS_PER_SECOND, DEC, VP9, 36, 2211840, 1, 2211840}, + {CAP_FRAMERATE, DEC, VP9, 1, 60, 1, 60}, + {CAP_BITRATE, DEC, VP9, 1, 100000000, 1, 20000000}, + /* Secure usecase specific */ {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, @@ -663,6 +683,16 @@ static struct msm_vidc_codec_capability shima_capabilities_v2[] = { {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, + /* VP9 decoder-specific */ + {CAP_FRAME_WIDTH, DEC, VP9, 96, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, VP9, 96, 4096, 1, 1080}, + /* (4096 * 2304) / 256 */ + {CAP_MBS_PER_FRAME, DEC, VP9, 36, 36864, 1, 36864}, + /* ((4096 * 2304) / 256) * 30 */ + {CAP_MBS_PER_SECOND, DEC, VP9, 36, 1105920, 1, 1105920}, + {CAP_FRAMERATE, DEC, VP9, 1, 60, 1, 60}, + {CAP_BITRATE, DEC, VP9, 1, 100000000, 1, 20000000}, + /* Secure usecase specific */ {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, From 2686a86b947226d8a63b439e40569d9162af9a46 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Tue, 18 Aug 2020 12:10:57 +0530 Subject: [PATCH 344/452] msm: vidc: Include uapi header files from techpack Currently uapi header files are included from core kernel include path since core kernel makefile also includes them. Hence making changes to include path in techpack makefile such that uapi header files are included from techpack project. Change-Id: I604b8bbb3058473b3e301cbbce112c8c93a0e963 Signed-off-by: Priyanka Gujjula --- Makefile | 3 +-- msm/vidc/msm_vidc.h | 2 +- msm/vidc/msm_vidc_internal.h | 2 +- msm/vidc/vidc_hfi.h | 2 +- msm/vidc/vidc_hfi_helper.h | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 3fdadb733a2e..dfbd2d489355 100644 --- a/Makefile +++ b/Makefile @@ -27,8 +27,7 @@ endif endif LINUXINCLUDE += -I$(srctree)/techpack/video/include \ - -I$(srctree)/techpack/video/include/uapi \ - -I$(srctree)/techpack/video/include/uapi/vidc + -I$(srctree)/techpack/video/include/uapi USERINCLUDE += -I$(srctree)/techpack/video/include/uapi diff --git a/msm/vidc/msm_vidc.h b/msm/vidc/msm_vidc.h index cea3b470f408..136cea68a7e9 100644 --- a/msm/vidc/msm_vidc.h +++ b/msm/vidc/msm_vidc.h @@ -8,7 +8,7 @@ #include #include -#include +#include "vidc/media/msm_vidc_utils.h" #include #define HAL_BUFFER_MAX 0xe diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index e04ac940ace2..7df2afb76eb1 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -15,7 +15,7 @@ #include #include #include "msm_vidc.h" -#include +#include "vidc/media/msm_media_info.h" #include "vidc_hfi_api.h" #include "vidc_hfi_helper.h" diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index ed078af401b5..29c6c85b699c 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -5,7 +5,7 @@ #ifndef __H_VIDC_HFI_H__ #define __H_VIDC_HFI_H__ -#include +#include "vidc/media/msm_media_info.h" #include "vidc_hfi_helper.h" #include "vidc_hfi_api.h" diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index 65e1f0e486e3..dd64a6ae9866 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -6,7 +6,7 @@ #ifndef __H_VIDC_HFI_HELPER_H__ #define __H_VIDC_HFI_HELPER_H__ -#include +#include "vidc/media/msm_vidc_utils.h" #define HFI_COMMON_BASE (0) #define HFI_OX_BASE (0x01000000) From 4b6d9b11693682332a4586cd6f58ecb399729e24 Mon Sep 17 00:00:00 2001 From: Divya Sharma Date: Wed, 19 Aug 2020 12:24:26 -0700 Subject: [PATCH 345/452] Revert "msm: vidc: Fix p-frame count" This reverts commit 879bf52d7fb0d703cb8c4558c03b0c7a2c226c1f. Change-Id: I7b301cd8a0644f48b17fd4e544f27ad105a47625 --- msm/vidc/msm_venc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 48c438b9baae..6030230d3df6 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2485,9 +2485,8 @@ int msm_venc_set_intra_period(struct msm_vidc_inst *inst) V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); codec = get_v4l2_codec(inst); - intra_period.pframes = gop_size->val; - if (!max_layer->val && codec == V4L2_PIX_FMT_H264) { + intra_period.pframes = gop_size->val; /* * At this point we've already made decision on bframe. * Control value gives updated bframe value. From d46accac05c6ae2503131c0668484432f9f37f07 Mon Sep 17 00:00:00 2001 From: Divya Sharma Date: Wed, 19 Aug 2020 12:24:48 -0700 Subject: [PATCH 346/452] Revert "msm: vidc: Fix to add correct superframe buffer timestamps" This reverts commit 1b93961cacc8a3b226f9d473e830721ebe229055. Change-Id: I46930fb27a7a3ce176408148d51909edfc0a7732 --- msm/vidc/msm_venc.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 6030230d3df6..7e4d638319b6 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2120,7 +2120,6 @@ int msm_venc_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) struct msm_vidc_timestamps *entry, *node, *prev = NULL; int count = 0; int rc = 0; - struct v4l2_ctrl *superframe_ctrl = NULL; if (!inst || !inst->core) { d_vpr_e("%s: invalid parameters\n", __func__); @@ -2173,13 +2172,7 @@ int msm_venc_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) /* if framerate changed and stable for 2 frames, set to firmware */ if (entry->framerate == prev->framerate && entry->framerate != inst->clk_data.frame_rate) { - superframe_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); - if (superframe_ctrl->val > 1) - inst->clk_data.frame_rate = entry->framerate * superframe_ctrl->val; - else - inst->clk_data.frame_rate = entry->framerate; - s_vpr_l(inst->sid, "%s: updated fps to %u\n", - __func__, (inst->clk_data.frame_rate >> 16)); + inst->clk_data.frame_rate = entry->framerate; msm_venc_set_frame_rate(inst); } From 42f8fb53cfd8ed396fc4bba4f5e9a8576419df87 Mon Sep 17 00:00:00 2001 From: Divya Sharma Date: Wed, 19 Aug 2020 12:25:02 -0700 Subject: [PATCH 347/452] Revert "msm: vidc: Update power sequence to match Lahaina HPG steps" This reverts commit 6d1b1c1a3d0ede5ef018b12932eab8eb258efe63. Change-Id: I1c7a19f9afc9a1bc61cfc43adf5dc8e6acccc4c5 --- msm/vidc/hfi_iris2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/msm/vidc/hfi_iris2.c b/msm/vidc/hfi_iris2.c index 5ac62b788ea4..4627f8b46871 100644 --- a/msm/vidc/hfi_iris2.c +++ b/msm/vidc/hfi_iris2.c @@ -243,6 +243,10 @@ void __power_off_iris2(struct venus_hfi_device *device) /* HPG 6.1.2 Step 6 */ __disable_unprepare_clks(device); + /* HPG 6.1.2 Step 7 & 8 */ + if (call_venus_op(device, reset_ahb2axi_bridge, device, sid)) + d_vpr_e("%s: Failed to reset ahb2axi\n", __func__); + /* HPG 6.1.2 Step 5 */ if (__disable_regulators(device)) d_vpr_e("%s: Failed to disable regulators\n", __func__); From b28387c5c427f17e3cd6c8d5504f72b4b925b2ef Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Fri, 14 Aug 2020 14:35:15 +0530 Subject: [PATCH 348/452] msm-vidc: update bw calculation for ar50LT Update bw calculation formulas for ar50LT. Change-Id: Ife2342304947f4108f908f7a5c56de24ad088b23 Signed-off-by: Dikshita Agarwal --- msm/vidc/msm_vidc_bus_ar50lite.c | 199 +++++++++++++++++-------------- 1 file changed, 109 insertions(+), 90 deletions(-) diff --git a/msm/vidc/msm_vidc_bus_ar50lite.c b/msm/vidc/msm_vidc_bus_ar50lite.c index d98592703d6c..496e379083fb 100644 --- a/msm/vidc/msm_vidc_bus_ar50lite.c +++ b/msm/vidc/msm_vidc_bus_ar50lite.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #include "msm_vidc_bus.h" @@ -9,33 +9,35 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) { /* Encoder Parameters */ - int width, height, fps, bitrate, lcu_size; + int width, height, fps, bitrate, lcu_size, lcu_per_frame, + collocated_bytes_per_lcu, search_range_v, search_range_h, + vertical_tile_size, num_tiles; - /* Derived Parameter */ - int search_range, lcu_per_frame; + unsigned int bins_to_bit_factor; fp_t y_bw; bool is_h264_category = true; fp_t orig_read_factor, recon_write_factor, - ref_y_read_factor, ref_c_read_factor, lb_factor, - rest_factor, total_read_factor, total_write_factor, - total_factor, overhead_factor; + ref_y_read_factor, ref_c_read_factor, overhead_factor; /* Output parameters */ fp_t orig_read, recon_write, - ref_y_read, ref_c_read, - lb_read, lb_write, - bse_read, bse_write, - total_read, total_write, - total; + ref_y_read, ref_c_read, + bse_lb_read, bse_lb_write, + collocated_read, collocated_write, + bitstream_read, bitstream_write, + total_read, total_write, + total; unsigned long ret = 0; - /* Encoder Fixed Parameters */ + /* Encoder Fixed Parameters setup */ + search_range_h = 96; + search_range_v = 48; + bins_to_bit_factor = 4; overhead_factor = FP(1, 3, 100); orig_read_factor = FP(1, 50, 100); /* L + C */ recon_write_factor = FP(1, 50, 100); /* L + C */ ref_c_read_factor = FP(0, 75, 100); /* 1.5/2 ( 1.5 Cache efficiency )*/ - lb_factor = FP(1, 25, 100); /* Worst case : HEVC 720p = 1.25 */ fps = d->fps; width = max(d->output_width, BASELINE_DIMENSIONS.width); @@ -55,40 +57,46 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) is_h264_category = false; } - search_range = 48; + collocated_bytes_per_lcu = lcu_size == 16 ? 16 : + lcu_size == 32 ? 64 : 256; + if (width >= 1296 && width <= 1536) + vertical_tile_size = 768; + else + vertical_tile_size = 640; + + num_tiles = DIV_ROUND_UP(width, vertical_tile_size); y_bw = fp_mult(fp_mult(FP_INT(width), FP_INT(height)), FP_INT(fps)); - y_bw = fp_div(y_bw, FP_INT(1000000)); + y_bw = fp_div(y_bw, FP_INT(bps(1))); - ref_y_read_factor = fp_div(FP_INT(search_range * 2), FP_INT(lcu_size)); + /* -1 for 1 less tile boundary penalty */ + ref_y_read_factor = (num_tiles - 1) * 2; + ref_y_read_factor = fp_div(fp_mult(FP_INT(ref_y_read_factor), + FP_INT(search_range_h)), FP_INT(width)); ref_y_read_factor = ref_y_read_factor + FP_INT(1); - rest_factor = FP_INT(bitrate) + fp_div(FP_INT(bitrate), FP_INT(8)); - rest_factor = fp_div(rest_factor, y_bw); - - total_read_factor = fp_div(rest_factor, FP_INT(2)) + - fp_div(lb_factor, FP_INT(2)); - total_read_factor = total_read_factor + orig_read_factor + - ref_y_read_factor + ref_c_read_factor; - - total_write_factor = fp_div(rest_factor, FP_INT(2)) + - fp_div(lb_factor, FP_INT(2)); - total_write_factor = total_write_factor + recon_write_factor; - - total_factor = total_read_factor + total_write_factor; - orig_read = fp_mult(y_bw, orig_read_factor); recon_write = fp_mult(y_bw, recon_write_factor); ref_y_read = fp_mult(y_bw, ref_y_read_factor); ref_c_read = fp_mult(y_bw, ref_c_read_factor); - lb_read = fp_div(fp_mult(y_bw, lb_factor), FP_INT(2)); - lb_write = lb_read; - bse_read = fp_mult(y_bw, fp_div(rest_factor, FP_INT(2))); - bse_write = bse_read; + + bse_lb_read = fp_div(FP_INT(16 * fps * lcu_per_frame), + FP_INT(bps(1))); + bse_lb_write = bse_lb_read; + + collocated_read = fp_div(FP_INT(lcu_per_frame * + collocated_bytes_per_lcu * fps), FP_INT(bps(1))); + collocated_write = collocated_read; + + bitstream_read = fp_mult(fp_div(FP_INT(bitrate), FP_INT(8)), + FP_INT(bins_to_bit_factor)); + bitstream_write = fp_div(FP_INT(bitrate), FP_INT(8)); + bitstream_write = bitstream_write + bitstream_read; total_read = orig_read + ref_y_read + ref_c_read + - lb_read + bse_read; - total_write = recon_write + lb_write + bse_write; + bse_lb_read + collocated_read + bitstream_read; + total_write = recon_write + bse_lb_write + + collocated_write + bitstream_write; total = total_read + total_write; total = fp_mult(total, overhead_factor); @@ -101,20 +109,21 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) {"fps", "%d", fps}, {"bitrate (Mbit/sec)", "%lu", bitrate}, {"lcu size", "%d", lcu_size}, + {"collocated byter per lcu", "%d", collocated_bytes_per_lcu}, + {"horizontal search range", "%d", search_range_h}, + {"vertical search range", "%d", search_range_v}, + {"bins to bit factor", "%d", bins_to_bit_factor}, {"DERIVED PARAMETERS", "", DUMP_HEADER_MAGIC}, {"lcu/frame", "%d", lcu_per_frame}, + {"vertical tile size", "%d", vertical_tile_size}, + {"number of tiles", "%d", num_tiles}, {"Y BW", DUMP_FP_FMT, y_bw}, - {"search range", "%d", search_range}, + {"original read factor", DUMP_FP_FMT, orig_read_factor}, {"recon write factor", DUMP_FP_FMT, recon_write_factor}, {"ref read Y factor", DUMP_FP_FMT, ref_y_read_factor}, {"ref read C factor", DUMP_FP_FMT, ref_c_read_factor}, - {"lb factor", DUMP_FP_FMT, lb_factor}, - {"rest factor", DUMP_FP_FMT, rest_factor}, - {"total_read_factor", DUMP_FP_FMT, total_read_factor}, - {"total_write_factor", DUMP_FP_FMT, total_write_factor}, - {"total_factor", DUMP_FP_FMT, total_factor}, {"overhead_factor", DUMP_FP_FMT, overhead_factor}, {"INTERMEDIATE B/W DDR", "", DUMP_HEADER_MAGIC}, @@ -122,10 +131,12 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) {"recon write", DUMP_FP_FMT, recon_write}, {"ref read Y", DUMP_FP_FMT, ref_y_read}, {"ref read C", DUMP_FP_FMT, ref_c_read}, - {"lb read", DUMP_FP_FMT, lb_read}, - {"lb write", DUMP_FP_FMT, lb_write}, - {"bse read", DUMP_FP_FMT, bse_read}, - {"bse write", DUMP_FP_FMT, bse_write}, + {"BSE lb read", DUMP_FP_FMT, bse_lb_read}, + {"BSE lb write", DUMP_FP_FMT, bse_lb_write}, + {"collocated read", DUMP_FP_FMT, collocated_read}, + {"collocated write", DUMP_FP_FMT, collocated_write}, + {"bitstream read", DUMP_FP_FMT, bitstream_read}, + {"bitstream write", DUMP_FP_FMT, bitstream_write}, {"total read", DUMP_FP_FMT, total_read}, {"total write", DUMP_FP_FMT, total_write}, {"total", DUMP_FP_FMT, total}, @@ -142,24 +153,24 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) { /* Decoder parameters */ - int width, height, fps, bitrate, lcu_size; + int width, height, fps, bitrate, lcu_size, + lcu_per_frame, collocated_bytes_per_lcu, + motion_complexity; - /* Derived parameters */ - int lcu_per_frame, motion_complexity; + unsigned int bins_to_bits_factor, vsp_read_factor; fp_t y_bw; bool is_h264_category = true; - fp_t recon_write_factor, ref_read_factor, lb_factor, - rest_factor, opb_factor, - total_read_factor, total_write_factor, - total_factor, overhead_factor; + fp_t recon_write_factor, ref_read_factor, + opb_factor, overhead_factor; /* Output parameters */ fp_t opb_write, recon_write, - ref_read, - lb_read, lb_write, - bse_read, bse_write, - total_read, total_write, - total; + ref_read, + bse_lb_read, bse_lb_write, + collocated_read, collocated_write, + bitstream_read, bitstream_write, + total_read, total_write, + total; unsigned long ret = 0; @@ -167,8 +178,9 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) overhead_factor = FP(1, 3, 100); recon_write_factor = FP(1, 50, 100); /* L + C */ opb_factor = FP(1, 50, 100); /* L + C */ - lb_factor = FP(1, 13, 100); /* Worst case : H264 1080p = 1.125 */ motion_complexity = 5; /* worst case complexity */ + bins_to_bits_factor = 4; + vsp_read_factor = 6; fps = d->fps; width = max(d->output_width, BASELINE_DIMENSIONS.width); @@ -188,35 +200,42 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) is_h264_category = false; } + collocated_bytes_per_lcu = lcu_size == 16 ? 16 : + lcu_size == 32 ? 64 : 256; + y_bw = fp_mult(fp_mult(FP_INT(width), FP_INT(height)), FP_INT(fps)); - y_bw = fp_div(y_bw, FP_INT(1000000)); + y_bw = fp_div(y_bw, FP_INT(bps(1))); ref_read_factor = FP(1, 50, 100); /* L + C */ ref_read_factor = fp_mult(ref_read_factor, FP_INT(motion_complexity)); - rest_factor = FP_INT(bitrate) + fp_div(FP_INT(bitrate), FP_INT(8)); - rest_factor = fp_div(rest_factor, y_bw); - - total_read_factor = fp_div(rest_factor, FP_INT(2)) + - fp_div(lb_factor, FP_INT(2)); - total_read_factor = total_read_factor + ref_read_factor; - - total_write_factor = fp_div(rest_factor, FP_INT(2)); - total_write_factor = total_write_factor + - recon_write_factor + opb_factor; - - total_factor = total_read_factor + total_write_factor; - recon_write = fp_mult(y_bw, recon_write_factor); ref_read = fp_mult(y_bw, ref_read_factor); - lb_read = fp_div(fp_mult(y_bw, lb_factor), FP_INT(2)); - lb_write = lb_read; - bse_read = fp_div(fp_mult(y_bw, rest_factor), FP_INT(2)); - bse_write = bse_read; + + if (d->codec == HAL_VIDEO_CODEC_HEVC) + bse_lb_read = FP_INT(lcu_size == 32 ? 64 : + lcu_size == 16 ? 32 : 128); + else + bse_lb_read = FP_INT(128); + bse_lb_read = fp_div(fp_mult(FP_INT(lcu_per_frame * fps), bse_lb_read), + FP_INT(bps(1))); + bse_lb_write = bse_lb_read; + + collocated_read = fp_div(FP_INT(lcu_per_frame * + collocated_bytes_per_lcu * fps), FP_INT(bps(1))); + collocated_write = collocated_read; + + bitstream_read = fp_mult(fp_div(FP_INT(bitrate), FP_INT(8)), + FP_INT(vsp_read_factor)); + bitstream_write = fp_mult(fp_div(FP_INT(bitrate), FP_INT(8)), + FP_INT(bins_to_bits_factor)); + opb_write = fp_mult(y_bw, opb_factor); - total_read = ref_read + lb_read + bse_read; - total_write = recon_write + lb_write + bse_write + opb_write; + total_read = ref_read + bse_lb_read + collocated_read + + bitstream_read; + total_write = recon_write + bse_lb_write + bitstream_write + + opb_write; total = total_read + total_write; total = fp_mult(total, overhead_factor); @@ -229,28 +248,28 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) {"fps", "%d", fps}, {"bitrate (Mbit/sec)", "%lu", bitrate}, {"lcu size", "%d", lcu_size}, + {"collocated byter per lcu", "%d", collocated_bytes_per_lcu}, + {"vsp read factor", "%d", vsp_read_factor}, + {"bins to bits factor", "%d", bins_to_bits_factor}, + {"motion complexity", "%d", motion_complexity}, {"DERIVED PARAMETERS", "", DUMP_HEADER_MAGIC}, {"lcu/frame", "%d", lcu_per_frame}, {"Y BW", DUMP_FP_FMT, y_bw}, - {"motion complexity", "%d", motion_complexity}, {"recon write factor", DUMP_FP_FMT, recon_write_factor}, {"ref_read_factor", DUMP_FP_FMT, ref_read_factor}, - {"lb factor", DUMP_FP_FMT, lb_factor}, - {"rest factor", DUMP_FP_FMT, rest_factor}, {"opb factor", DUMP_FP_FMT, opb_factor}, - {"total_read_factor", DUMP_FP_FMT, total_read_factor}, - {"total_write_factor", DUMP_FP_FMT, total_write_factor}, - {"total_factor", DUMP_FP_FMT, total_factor}, {"overhead_factor", DUMP_FP_FMT, overhead_factor}, {"INTERMEDIATE B/W DDR", "", DUMP_HEADER_MAGIC}, {"recon write", DUMP_FP_FMT, recon_write}, {"ref read", DUMP_FP_FMT, ref_read}, - {"lb read", DUMP_FP_FMT, lb_read}, - {"lb write", DUMP_FP_FMT, lb_write}, - {"bse read", DUMP_FP_FMT, bse_read}, - {"bse write", DUMP_FP_FMT, bse_write}, + {"BSE lb read", DUMP_FP_FMT, bse_lb_read}, + {"BSE lb write", DUMP_FP_FMT, bse_lb_write}, + {"collocated read", DUMP_FP_FMT, collocated_read}, + {"collocated write", DUMP_FP_FMT, collocated_write}, + {"bitstream read", DUMP_FP_FMT, bitstream_read}, + {"bitstream write", DUMP_FP_FMT, bitstream_write}, {"opb write", DUMP_FP_FMT, opb_write}, {"total read", DUMP_FP_FMT, total_read}, {"total write", DUMP_FP_FMT, total_write}, From 0bca035ef74fcce443ef372aa0d8061b44f77942 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Mon, 17 Aug 2020 13:24:28 -0700 Subject: [PATCH 349/452] msm: vidc: Update cycle count requirement of B frames. Decoder base cycle requirement of B frames has increased to 80. Also, updated cycle count requirement for Encoder HIER B usecase. Change-Id: Iec1bee89be6bb6c18235c2903080025c312bef2d Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_vidc.c | 1 + msm/vidc/msm_vidc_clocks.c | 12 +++++++++--- msm/vidc/msm_vidc_common.c | 1 + msm/vidc/msm_vidc_internal.h | 1 + 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 7f78071d585d..fc479e961e64 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1534,6 +1534,7 @@ void *msm_vidc_open(int core_id, int session_type) inst->bse_vpp_delay = DEFAULT_BSE_VPP_DELAY; inst->first_reconfig_done = 0; inst->active = true; + inst->has_bframe = 0; for (i = SESSION_MSG_INDEX(SESSION_MSG_START); i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) { diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 0af709fe2d36..7fab1d9ab821 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -701,9 +701,14 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, vpp_cycles = mbs_per_second * vpp_cycles_per_mb / inst->clk_data.work_route; - /* 1.25 factor for IbP GOP structure */ - if (msm_comm_g_ctrl_for_id(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES)) + /* Factor 1.25 for IbP and 1.375 for I1B2b1P GOP structure */ + if (is_hier_b_session(inst)) { + vpp_cycles += (vpp_cycles / 4) + (vpp_cycles / 8); + } else if (msm_comm_g_ctrl_for_id(inst, + V4L2_CID_MPEG_VIDEO_B_FRAMES)) { vpp_cycles += vpp_cycles / 4; + } + /* 21 / 20 is minimum overhead factor */ vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles); /* 1.01 is multi-pipe overhead */ @@ -758,7 +763,8 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, /* VSP */ codec = get_v4l2_codec(inst); - base_cycles = inst->clk_data.entry->vsp_cycles; + base_cycles = inst->has_bframe ? + 80 : inst->clk_data.entry->vsp_cycles; vsp_cycles = fps * filled_len * 8; if (codec == V4L2_PIX_FMT_VP9) { diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 652334c646c4..7b4602af6d92 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2650,6 +2650,7 @@ static void handle_fbd(enum hal_command_response cmd, void *data) break; case HFI_PICTURE_TYPE_B: mbuf->vvb.flags |= V4L2_BUF_FLAG_BFRAME; + inst->has_bframe = 1; break; case HFI_FRAME_NOTCODED: case HFI_UNUSED_PICT: diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index e04ac940ace2..f2ba25f90463 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -574,6 +574,7 @@ struct msm_vidc_inst { u32 first_reconfig_done; u64 last_qbuf_time_ns; bool active; + bool has_bframe; }; extern struct msm_vidc_drv *vidc_driver; From 372b7136f5aaf04b29aa491085573116ee8101ac Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 26 Aug 2020 20:48:01 +0530 Subject: [PATCH 350/452] msm: vidc: Add support for 128x32 alignment of NV12 Introduce new internal driver color format V4L2_PIX_FMT_NV12_128 and uapi color format COLOR_FMT_NV12_128 to map with NV12 128x32 alignment. Also, clean up intermediate HAL color formats. Change-Id: Ia28d0f422f2777bda865c2fc6c7499cce9dabb54 Signed-off-by: Priyanka Gujjula --- include/uapi/vidc/media/msm_media_info.h | 42 +++++++++++++++++++++++- include/uapi/vidc/media/msm_vidc_utils.h | 2 ++ msm/vidc/msm_venc.c | 13 ++++++++ msm/vidc/msm_vidc_bus.h | 28 ++++++++-------- msm/vidc/msm_vidc_bus_iris2.c | 4 +-- msm/vidc/msm_vidc_clocks.c | 12 +++---- msm/vidc/msm_vidc_common.c | 39 ++-------------------- msm/vidc/msm_vidc_common.h | 1 - msm/vidc/msm_vidc_internal.h | 2 +- msm/vidc/vidc_hfi_api.h | 23 ------------- 10 files changed, 82 insertions(+), 84 deletions(-) diff --git a/include/uapi/vidc/media/msm_media_info.h b/include/uapi/vidc/media/msm_media_info.h index 309a17bde02d..f9487c93ebeb 100644 --- a/include/uapi/vidc/media/msm_media_info.h +++ b/include/uapi/vidc/media/msm_media_info.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #ifndef __MSM_MEDIA_INFO_H__ @@ -57,6 +57,41 @@ enum color_fmts { * + UV_Stride * UV_Scanlines, 4096) */ COLOR_FMT_NV12, + /* Venus NV12: + * YUV 4:2:0 image with a plane of 8 bit Y samples followed + * by an interleaved U/V plane containing 8 bit 2x2 subsampled + * colour difference samples. + * + * <-------- Y/UV_Stride --------> + * <------- Width -------> + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . ^ ^ + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . Height | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | Y_Scanlines + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * U V U V U V U V U V U V . . . . ^ + * U V U V U V U V U V U V . . . . | + * U V U V U V U V U V U V . . . . | + * U V U V U V U V U V U V . . . . UV_Scanlines + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . . . --> Buffer size alignment + * + * Y_Stride : Width aligned to 128 + * UV_Stride : Width aligned to 128 + * Y_Scanlines: Height aligned to 32 + * UV_Scanlines: Height/2 aligned to 16 + * Total size = align(Y_Stride * Y_Scanlines + * + UV_Stride * UV_Scanlines, 4096) + */ + COLOR_FMT_NV12_128, /* Venus NV21: * YUV 4:2:0 image with a plane of 8 bit Y samples followed * by an interleaved V/U plane containing 8 bit 2x2 subsampled @@ -790,6 +825,7 @@ static inline unsigned int VENUS_Y_STRIDE(unsigned int color_fmt, alignment = 512; stride = MSM_MEDIA_ALIGN(width, alignment); break; + case COLOR_FMT_NV12_128: case COLOR_FMT_NV12_UBWC: alignment = 128; stride = MSM_MEDIA_ALIGN(width, alignment); @@ -833,6 +869,7 @@ static inline unsigned int VENUS_UV_STRIDE(unsigned int color_fmt, alignment = 512; stride = MSM_MEDIA_ALIGN(width, alignment); break; + case COLOR_FMT_NV12_128: case COLOR_FMT_NV12_UBWC: alignment = 128; stride = MSM_MEDIA_ALIGN(width, alignment); @@ -875,6 +912,7 @@ static inline unsigned int VENUS_Y_SCANLINES(unsigned int color_fmt, case COLOR_FMT_NV12_512: alignment = 512; break; + case COLOR_FMT_NV12_128: case COLOR_FMT_NV12_UBWC: case COLOR_FMT_P010: alignment = 32; @@ -912,6 +950,7 @@ static inline unsigned int VENUS_UV_SCANLINES(unsigned int color_fmt, case COLOR_FMT_NV12_512: alignment = 256; break; + case COLOR_FMT_NV12_128: case COLOR_FMT_NV12_BPP10_UBWC: case COLOR_FMT_P010_UBWC: case COLOR_FMT_P010: @@ -1212,6 +1251,7 @@ static inline unsigned int VENUS_BUFFER_SIZE(unsigned int color_fmt, case COLOR_FMT_NV12: case COLOR_FMT_P010: case COLOR_FMT_NV12_512: + case COLOR_FMT_NV12_128: y_plane = y_stride * y_sclines; uv_plane = uv_stride * uv_sclines; size = y_plane + uv_plane; diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index a20d4816841a..0bca1dad6153 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -14,6 +14,8 @@ #define V4L2_PIX_FMT_NV12_UBWC v4l2_fourcc('Q', '1', '2', '8') /* NV12_512 8-bit Y/CbCr 4:2:0 */ #define V4L2_PIX_FMT_NV12_512 v4l2_fourcc('Q', '5', '1', '2') +/* NV12_128 8-bit Y/CbCr 4:2:0 */ +#define V4L2_PIX_FMT_NV12_128 v4l2_fourcc('N', '1', '2', '8') /* NV12 10-bit Y/CbCr 4:2:0 */ #define V4L2_PIX_FMT_NV12_P010_UBWC v4l2_fourcc('Q', '1', '2', 'B') /* UBWC 10-bit Y/CbCr 4:2:0 */ diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index bf3184fe1040..7808b90810d9 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1036,6 +1036,11 @@ static struct msm_vidc_format_desc venc_input_formats[] = { .description = "Y/CbCr 4:2:0 10bit", .fourcc = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS, }, + { + .name = "YCbCr Semiplanar 4:2:0 128 aligned", + .description = "Y/CbCr 4:2:0 128 aligned", + .fourcc = V4L2_PIX_FMT_NV12_128, + }, { .name = "YCbCr Semiplanar 4:2:0 512 aligned", .description = "Y/CbCr 4:2:0 512 aligned", @@ -1070,6 +1075,14 @@ struct msm_vidc_format_constraint enc_pix_format_constraints[] = { .uv_max_stride = 8192, .uv_buffer_alignment = 256, }, + { + .fourcc = V4L2_PIX_FMT_NV12_128, + .num_planes = 2, + .y_max_stride = 8192, + .y_buffer_alignment = 128, + .uv_max_stride = 8192, + .uv_buffer_alignment = 32, + }, { .fourcc = V4L2_PIX_FMT_NV12_512, .num_planes = 2, diff --git a/msm/vidc/msm_vidc_bus.h b/msm/vidc/msm_vidc_bus.h index fb7ab82e5c5c..43dc76ea9ed6 100644 --- a/msm/vidc/msm_vidc_bus.h +++ b/msm/vidc/msm_vidc_bus.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #ifndef __H_MSM_VIDC_BUS_DEFS_H__ @@ -228,30 +228,30 @@ struct lut const *__lut(int width, int height, int fps); fp_t __compression_ratio(struct lut const *entry, int bpp); void __dump(struct dump dump[], int len, u32 sid); -static inline bool __ubwc(enum hal_uncompressed_format f) +static inline bool __ubwc(u32 format) { - switch (f) { - case HAL_COLOR_FORMAT_NV12_UBWC: - case HAL_COLOR_FORMAT_NV12_TP10_UBWC: + switch (format) { + case HFI_COLOR_FORMAT_NV12_UBWC: + case HFI_COLOR_FORMAT_YUV420_TP10_UBWC: return true; default: return false; } } -static inline int __bpp(enum hal_uncompressed_format f, u32 sid) +static inline int __bpp(u32 format, u32 sid) { - switch (f) { - case HAL_COLOR_FORMAT_NV12: - case HAL_COLOR_FORMAT_NV21: - case HAL_COLOR_FORMAT_NV12_UBWC: - case HAL_COLOR_FORMAT_RGBA8888_UBWC: + switch (format) { + case HFI_COLOR_FORMAT_NV12: + case HFI_COLOR_FORMAT_NV21: + case HFI_COLOR_FORMAT_NV12_UBWC: + case HFI_COLOR_FORMAT_RGBA8888_UBWC: return 8; - case HAL_COLOR_FORMAT_NV12_TP10_UBWC: - case HAL_COLOR_FORMAT_P010: + case HFI_COLOR_FORMAT_YUV420_TP10_UBWC: + case HFI_COLOR_FORMAT_P010: return 10; default: - s_vpr_e(sid, "Unsupported colorformat (%x)", f); + s_vpr_e(sid, "Unsupported colorformat (%x)", format); return INT_MAX; } } diff --git a/msm/vidc/msm_vidc_bus_iris2.c b/msm/vidc/msm_vidc_bus_iris2.c index a197bda82b1f..6252fd3ddf27 100644 --- a/msm/vidc/msm_vidc_bus_iris2.c +++ b/msm/vidc/msm_vidc_bus_iris2.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #include "msm_vidc_bus.h" @@ -337,7 +337,7 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) b_frames_enabled = d->b_frames_enabled; original_color_format = d->num_formats >= 1 ? - d->color_formats[0] : HAL_UNUSED_COLOR; + d->color_formats[0] : HFI_COLOR_FORMAT_NV12_UBWC; original_compression_enabled = __ubwc(original_color_format); diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 64b5f95408f9..bba5b936cc78 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -438,16 +438,16 @@ int msm_comm_vote_bus(struct msm_vidc_inst *inst) if (msm_comm_get_stream_output_mode(inst) == HAL_VIDEO_DECODER_PRIMARY) { vote_data->color_formats[0] = - msm_comm_get_hal_uncompressed( - inst->clk_data.opb_fourcc); + msm_comm_get_hfi_uncompressed( + inst->clk_data.opb_fourcc, inst->sid); vote_data->num_formats = 1; } else { vote_data->color_formats[0] = - msm_comm_get_hal_uncompressed( - inst->clk_data.dpb_fourcc); + msm_comm_get_hfi_uncompressed( + inst->clk_data.dpb_fourcc, inst->sid); vote_data->color_formats[1] = - msm_comm_get_hal_uncompressed( - inst->clk_data.opb_fourcc); + msm_comm_get_hfi_uncompressed( + inst->clk_data.opb_fourcc, inst->sid); vote_data->num_formats = 2; } vote_data->work_mode = inst->clk_data.work_mode; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 0cab94351d95..c3ef773a44e5 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -852,48 +852,13 @@ enum hal_video_codec get_hal_codec(int fourcc, u32 sid) return codec; } -enum hal_uncompressed_format msm_comm_get_hal_uncompressed(int fourcc) -{ - enum hal_uncompressed_format format = HAL_UNUSED_COLOR; - - switch (fourcc) { - case V4L2_PIX_FMT_NV12: - format = HAL_COLOR_FORMAT_NV12; - break; - case V4L2_PIX_FMT_NV12_512: - format = HAL_COLOR_FORMAT_NV12_512; - break; - case V4L2_PIX_FMT_NV21: - format = HAL_COLOR_FORMAT_NV21; - break; - case V4L2_PIX_FMT_NV12_UBWC: - format = HAL_COLOR_FORMAT_NV12_UBWC; - break; - case V4L2_PIX_FMT_NV12_TP10_UBWC: - format = HAL_COLOR_FORMAT_NV12_TP10_UBWC; - break; - case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS: - format = HAL_COLOR_FORMAT_P010; - break; - case V4L2_PIX_FMT_RGBA8888_UBWC: - format = HAL_COLOR_FORMAT_RGBA8888_UBWC; - break; - default: - format = HAL_UNUSED_COLOR; - break; - } - - return format; -} - u32 msm_comm_get_hfi_uncompressed(int fourcc, u32 sid) { u32 format; switch (fourcc) { case V4L2_PIX_FMT_NV12: - format = HFI_COLOR_FORMAT_NV12; - break; + case V4L2_PIX_FMT_NV12_128: case V4L2_PIX_FMT_NV12_512: format = HFI_COLOR_FORMAT_NV12; break; @@ -3718,6 +3683,8 @@ u32 msm_comm_convert_color_fmt(u32 v4l2_fmt, u32 sid) return COLOR_FMT_NV12; case V4L2_PIX_FMT_NV21: return COLOR_FMT_NV21; + case V4L2_PIX_FMT_NV12_128: + return COLOR_FMT_NV12_128; case V4L2_PIX_FMT_NV12_512: return COLOR_FMT_NV12_512; case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS: diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 24a04dd0a257..42467096c2f3 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -344,7 +344,6 @@ int msm_comm_get_v4l2_profile(int fourcc, int profile, u32 sid); int msm_comm_get_v4l2_level(int fourcc, int level, u32 sid); int msm_comm_session_continue(void *instance); int msm_vidc_send_pending_eos_buffers(struct msm_vidc_inst *inst); -enum hal_uncompressed_format msm_comm_get_hal_uncompressed(int fourcc); u32 msm_comm_get_hfi_uncompressed(int fourcc, u32 sid); u32 msm_comm_convert_color_fmt(u32 v4l2_fmt, u32 sid); struct vb2_buffer *msm_comm_get_vb_using_vidc_buffer( diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 7df2afb76eb1..d4169575060b 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -411,7 +411,7 @@ struct vidc_bus_vote_data { u32 sid; enum hal_domain domain; enum hal_video_codec codec; - enum hal_uncompressed_format color_formats[2]; + u32 color_formats[2]; int num_formats; /* 1 = DPB-OPB unified; 2 = split */ int input_height, input_width, bitrate; int output_height, output_width; diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 84b277520ac8..1193b227ca9f 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -129,29 +129,6 @@ enum hal_video_codec { HAL_UNUSED_CODEC = 0x10000000, }; -enum hal_uncompressed_format { - HAL_COLOR_FORMAT_MONOCHROME = 0x00000001, - HAL_COLOR_FORMAT_NV12 = 0x00000002, - HAL_COLOR_FORMAT_NV21 = 0x00000004, - HAL_COLOR_FORMAT_NV12_4x4TILE = 0x00000008, - HAL_COLOR_FORMAT_NV21_4x4TILE = 0x00000010, - HAL_COLOR_FORMAT_YUYV = 0x00000020, - HAL_COLOR_FORMAT_YVYU = 0x00000040, - HAL_COLOR_FORMAT_UYVY = 0x00000080, - HAL_COLOR_FORMAT_VYUY = 0x00000100, - HAL_COLOR_FORMAT_RGB565 = 0x00000200, - HAL_COLOR_FORMAT_BGR565 = 0x00000400, - HAL_COLOR_FORMAT_RGB888 = 0x00000800, - HAL_COLOR_FORMAT_BGR888 = 0x00001000, - HAL_COLOR_FORMAT_NV12_UBWC = 0x00002000, - HAL_COLOR_FORMAT_NV12_TP10_UBWC = 0x00004000, - HAL_COLOR_FORMAT_RGBA8888 = 0x00008000, - HAL_COLOR_FORMAT_RGBA8888_UBWC = 0x00010000, - HAL_COLOR_FORMAT_P010 = 0x00020000, - HAL_COLOR_FORMAT_NV12_512 = 0x00040000, - HAL_UNUSED_COLOR = 0x10000000, -}; - enum hal_ssr_trigger_type { SSR_ERR_FATAL = 1, SSR_SW_DIV_BY_ZERO, From fcad90b130aadb56918b1229abc47d55c20367b4 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Thu, 3 Sep 2020 18:27:07 +0530 Subject: [PATCH 351/452] msm: vidc: reverse sort allowed_clock_tbl for shima Clock_table entries are kept as ascending order. So always highest clk corner is picked from clock_table during clock calculation. So enable reverse sort for clk table entries to pick the right corner. Change-Id: I5adc61368aa15ae69c11a0539dcb05437bf686b4 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_res_parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 1e17830ff333..b730636ef31e 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -349,7 +349,7 @@ static int msm_vidc_load_allowed_clocks_table( if (res->allowed_clks_tbl) { d_vpr_h("allowed-clock-rates populated from platform_data\n"); - return 0; + goto exit; } if (!of_find_property(pdev->dev.of_node, @@ -367,7 +367,7 @@ static int msm_vidc_load_allowed_clocks_table( d_vpr_e("%s: failed to read allowed clocks table\n", __func__); return rc; } - +exit: sort(res->allowed_clks_tbl, res->allowed_clks_tbl_size, sizeof(*res->allowed_clks_tbl), cmp, NULL); From 08b43c99a26604794897f2ad2b1a4205d87ca92c Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Thu, 3 Sep 2020 20:38:37 +0530 Subject: [PATCH 352/452] msm: vidc: shima: Update max profile level caps Update level values for ENC and DEC based on shima caps. Change-Id: I967b4ef65a59b711815e09e03547b895cc572e39 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_platform.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 1d42b06aced4..5165cc5fec50 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -425,11 +425,12 @@ static struct msm_vidc_codec_capability shima_capabilities_v0[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 8192, 1, 1920}, {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 8192, 1, 1080}, - {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 8192, 1, 1920}, - {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 8192, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 1, 1080}, /* (8192 * 4320) / 256 */ {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 138240, 1, 138240}, - {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 138240, 1, 138240}, + /* (4096 * 2176) / 256 */ + {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 138240}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 480, 1, 30}, /* Encode spec - 4K@60 */ @@ -518,18 +519,18 @@ static struct msm_vidc_codec_capability shima_capabilities_v0[] = { * to set higher level than supported. */ {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, /* Level for AVC and HEVC decoder specific */ {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_6_0, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_6, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, }; @@ -625,18 +626,18 @@ static struct msm_vidc_codec_capability shima_capabilities_v1[] = { * to set higher level than supported. */ {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, /* Level for AVC and HEVC decoder specific */ {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, }; @@ -731,18 +732,18 @@ static struct msm_vidc_codec_capability shima_capabilities_v2[] = { * to set higher level than supported. */ {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, /* Level for AVC and HEVC decoder specific */ {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, }; From 541b40c07293bc83ad276c88954856b3dfd319ce Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Tue, 1 Sep 2020 21:42:08 +0530 Subject: [PATCH 353/452] msm: vidc: Optimize enc scratch and scratch_2 buffer sizes Optimize scratch and scratch_2 internal buffer size calculators for encoder. Change-Id: Idfaf7df13a427788cbb983a17fc2137be154bce8 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_buffer_calculations.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 4b1a2bd287d9..834726183fca 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1410,7 +1410,9 @@ static inline u32 calculate_enc_scratch_size(struct msm_vidc_inst *inst, bitstream_size = aligned_width * aligned_height * 3; bitbin_size = ALIGN(bitstream_size, VENUS_DMA_ALIGNMENT); } - if (num_vpp_pipes > 2) + if (aligned_width * aligned_height >= 3840 * 2160) + size_singlePipe = bitbin_size / 4; + else if (num_vpp_pipes > 2) size_singlePipe = bitbin_size / 2; else size_singlePipe = bitbin_size; @@ -1814,7 +1816,7 @@ static inline u32 calculate_enc_scratch2_size(struct msm_vidc_inst *inst, metadata_stride, meta_buf_height); size = (aligned_height + chroma_height) * aligned_width + meta_size_y + meta_size_c; - size = (size * (num_ref+3)) + 4096; + size = (size * (num_ref + 2)) + 4096; } else { ref_buf_height = (height + (HFI_VENUS_HEIGHT_ALIGNMENT - 1)) & (~(HFI_VENUS_HEIGHT_ALIGNMENT - 1)); @@ -1847,7 +1849,7 @@ static inline u32 calculate_enc_scratch2_size(struct msm_vidc_inst *inst, meta_size_c = hfi_ubwc_metadata_plane_buffer_size( metadata_stride, meta_buf_height); size = ref_buf_size + meta_size_y + meta_size_c; - size = (size * (num_ref+3)) + 4096; + size = (size * (num_ref + 2)) + 4096; } return size; } From ec74a635f52e5b2554d55d7cd01cc85ff2865b61 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Fri, 4 Sep 2020 11:20:35 +0800 Subject: [PATCH 354/452] msm: venc: add bitrate boost QP range interface Add bitrate boost QP range interface to support additional configs for boost QP range. Boost QP range should only be effective when bitrate boost is enabled. And, common vendor extension QP range overwrites boost QP range. Change-Id: I9b6601cd7e9bbf4326f67b9e0f40788e915040b0 Signed-off-by: Shi Zhongbo --- include/uapi/vidc/media/msm_vidc_utils.h | 2 ++ msm/vidc/msm_venc.c | 40 ++++++++++++++++++++++-- msm/vidc/msm_vidc.c | 3 ++ msm/vidc/msm_vidc_internal.h | 3 ++ 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index 0bca1dad6153..5359ec8e7538 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -256,6 +256,8 @@ enum v4l2_mpeg_vidc_video_bitrate_savings_type { (V4L2_CID_MPEG_MSM_VIDC_BASE + 133) #define V4L2_CID_MPEG_VIDC_VDEC_HEIF_MODE \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 134) +#define V4L2_CID_MPEG_VIDC_VENC_QPRANGE_BOOST \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 135) #define V4L2_CID_MPEG_VIDC_VIDEO_UNKNOWN \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 0xFFF) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 7808b90810d9..00296c346b95 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -42,6 +42,7 @@ #define LEGACY_CBR_BUF_SIZE 500 #define CBR_PLUS_BUF_SIZE 1000 #define MAX_GOP 0xFFFFFFF +#define MAX_QPRANGE_BOOST 0x3333 #define MIN_NUM_ENC_OUTPUT_BUFFERS 4 #define MIN_NUM_ENC_CAPTURE_BUFFERS 5 @@ -956,6 +957,15 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = 25, .step = 1, }, + { + .id = V4L2_CID_MPEG_VIDC_VENC_QPRANGE_BOOST, + .name = "Bitrate boost QP range", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = MAX_QPRANGE_BOOST, + .default_value = 0, + .step = 1, + }, { .id = V4L2_CID_MPEG_VIDEO_VBV_DELAY, .name = "Set Vbv Delay", @@ -2021,6 +2031,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET: case V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS: case V4L2_CID_MPEG_VIDC_VENC_BITRATE_BOOST: + case V4L2_CID_MPEG_VIDC_VENC_QPRANGE_BOOST: case V4L2_CID_MPEG_VIDC_SUPERFRAME: s_vpr_h(sid, "Control set: ID : 0x%x Val : %d\n", ctrl->id, ctrl->val); @@ -2993,7 +3004,8 @@ int msm_venc_set_qp_range(struct msm_vidc_inst *inst) hdev = inst->core->device; if (!(inst->client_set_ctrls & CLIENT_SET_MIN_QP) && - !(inst->client_set_ctrls & CLIENT_SET_MAX_QP)) { + !(inst->client_set_ctrls & CLIENT_SET_MAX_QP) && + !inst->boost_qp_enabled) { s_vpr_h(inst->sid, "%s: Client didn't set QP range\n", __func__); return 0; @@ -3003,10 +3015,18 @@ int msm_venc_set_qp_range(struct msm_vidc_inst *inst) qp_range.max_qp.layer_id = MSM_VIDC_ALL_LAYER_ID; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP); - qp_range.min_qp.qp_packed = ctrl->val; + if (inst->boost_qp_enabled && + !(inst->client_set_ctrls & CLIENT_SET_MIN_QP)) + qp_range.min_qp.qp_packed = inst->boost_min_qp; + else + qp_range.min_qp.qp_packed = ctrl->val; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP); - qp_range.max_qp.qp_packed = ctrl->val; + if (inst->boost_qp_enabled && + !(inst->client_set_ctrls & CLIENT_SET_MAX_QP)) + qp_range.max_qp.qp_packed = inst->boost_max_qp; + else + qp_range.max_qp.qp_packed = ctrl->val; s_vpr_h(inst->sid, "%s: layers %#x qp_min %#x qp_max %#x\n", __func__, qp_range.min_qp.layer_id, @@ -3485,6 +3505,7 @@ int msm_venc_set_bitrate_boost_margin(struct msm_vidc_inst *inst, u32 enable) struct hfi_device *hdev; struct v4l2_ctrl *ctrl = NULL; struct hfi_bitrate_boost_margin boost_margin; + int minqp, maxqp; if (!inst || !inst->core) { d_vpr_e("%s: invalid params %pK\n", __func__, inst); @@ -3498,6 +3519,7 @@ int msm_venc_set_bitrate_boost_margin(struct msm_vidc_inst *inst, u32 enable) } ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_BITRATE_BOOST); + /* Mapped value to 0, 25 or 50*/ if (ctrl->val >= 50) boost_margin.margin = 50; @@ -3512,6 +3534,18 @@ int msm_venc_set_bitrate_boost_margin(struct msm_vidc_inst *inst, u32 enable) if (rc) s_vpr_e(inst->sid, "%s: set property failed\n", __func__); + /* Boost QP range is only enabled when bitrate boost is enabled + * and boost QP range is set by client + */ + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_QPRANGE_BOOST); + if (enable && ctrl->val) { + minqp = ctrl->val & 0xFF; + maxqp = (ctrl->val >> 8) & 0xFF; + inst->boost_qp_enabled = true; + inst->boost_min_qp = minqp | (minqp << 8) | (minqp << 16); + inst->boost_max_qp = maxqp | (maxqp << 8) | (maxqp << 16); + } + return rc; } diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 051bfb2d2810..cf10f063a732 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1537,6 +1537,9 @@ void *msm_vidc_open(int core_id, int session_type) inst->first_reconfig_done = 0; inst->active = true; inst->has_bframe = 0; + inst->boost_qp_enabled = false; + inst->boost_min_qp = 0; + inst->boost_max_qp = 0; for (i = SESSION_MSG_INDEX(SESSION_MSG_START); i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) { diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 27844dbe19a8..ee6571e434b7 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -575,6 +575,9 @@ struct msm_vidc_inst { u64 last_qbuf_time_ns; bool active; bool has_bframe; + bool boost_qp_enabled; + u32 boost_min_qp; + u32 boost_max_qp; }; extern struct msm_vidc_drv *vidc_driver; From 4b5d7127383a4bb8870b181e51d487da3685b03b Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Thu, 3 Sep 2020 18:27:07 +0530 Subject: [PATCH 355/452] msm: vidc: reverse sort allowed_clock_tbl for shima Clock_table entries are kept as ascending order. So always highest clk corner is picked from clock_table during clock calculation. So enable reverse sort for clk table entries to pick the right corner. Change-Id: I5adc61368aa15ae69c11a0539dcb05437bf686b4 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_res_parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 1e17830ff333..b730636ef31e 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -349,7 +349,7 @@ static int msm_vidc_load_allowed_clocks_table( if (res->allowed_clks_tbl) { d_vpr_h("allowed-clock-rates populated from platform_data\n"); - return 0; + goto exit; } if (!of_find_property(pdev->dev.of_node, @@ -367,7 +367,7 @@ static int msm_vidc_load_allowed_clocks_table( d_vpr_e("%s: failed to read allowed clocks table\n", __func__); return rc; } - +exit: sort(res->allowed_clks_tbl, res->allowed_clks_tbl_size, sizeof(*res->allowed_clks_tbl), cmp, NULL); From d7a360d9ed587c09f550ad89a809494f7381dace Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Thu, 3 Sep 2020 20:38:37 +0530 Subject: [PATCH 356/452] msm: vidc: shima: Update max profile level caps Update level values for ENC and DEC based on shima caps. Change-Id: I967b4ef65a59b711815e09e03547b895cc572e39 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_platform.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 1d42b06aced4..5165cc5fec50 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -425,11 +425,12 @@ static struct msm_vidc_codec_capability shima_capabilities_v0[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 8192, 1, 1920}, {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 8192, 1, 1080}, - {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 8192, 1, 1920}, - {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 8192, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 1, 1080}, /* (8192 * 4320) / 256 */ {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 138240, 1, 138240}, - {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 138240, 1, 138240}, + /* (4096 * 2176) / 256 */ + {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 138240}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 480, 1, 30}, /* Encode spec - 4K@60 */ @@ -518,18 +519,18 @@ static struct msm_vidc_codec_capability shima_capabilities_v0[] = { * to set higher level than supported. */ {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, /* Level for AVC and HEVC decoder specific */ {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_6_0, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_6, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, }; @@ -625,18 +626,18 @@ static struct msm_vidc_codec_capability shima_capabilities_v1[] = { * to set higher level than supported. */ {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, /* Level for AVC and HEVC decoder specific */ {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, }; @@ -731,18 +732,18 @@ static struct msm_vidc_codec_capability shima_capabilities_v2[] = { * to set higher level than supported. */ {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, /* Level for AVC and HEVC decoder specific */ {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, }; From 10cba22262d78ac14356996e3c9baa5478244682 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 9 Sep 2020 17:19:19 +0530 Subject: [PATCH 357/452] msm: vdec: Do not consider 10bit size for specific video hardware Certain video hardware does not have support for hdr. Avoid adding size for the same for such video hardware. CRs-Fixed: 2772982 Change-Id: Iceb64dab0d346fb483976dac16fed4888a2f0277 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_buffer_calculations.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 4b1a2bd287d9..021b1ff4615b 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -908,8 +908,9 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) frame_size = base_res_mbs * MB_SIZE_IN_PIXEL * 3 / 2 / div_factor; /* multiply by 10/8 (1.25) to get size for 10 bit case */ - if ((f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_VP9) || - (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_HEVC)) + if ((f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_VP9 || + f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_HEVC) && + inst->core->platform_data->vpu_ver != VPU_VERSION_AR50_LITE) frame_size = frame_size + (frame_size >> 2); if (inst->buffer_size_limit && From 253c43239c010a3db1991e4eb7e0028ecf3b9096 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Thu, 10 Sep 2020 18:21:17 +0530 Subject: [PATCH 358/452] msm: vidc: update iris2 clock calculation As per vperf sheet, VSP FW Overhead factor(1.05) needs to be applied to both entropy mode CABAC & CAVLC. Change-Id: I93dc00137e0633ac2a79862c58970ba43b515ad6 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_clocks.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 92cf50997829..221fcadda6b5 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -742,9 +742,9 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, } else { base_cycles = 0; vsp_cycles = div_u64(vsp_cycles, 2); - /* VSP FW Overhead 1.05 */ - vsp_cycles = div_u64(vsp_cycles * 21, 20); } + /* VSP FW Overhead 1.05 */ + vsp_cycles = div_u64(vsp_cycles * 21, 20); if (inst->clk_data.work_mode == HFI_WORKMODE_1) vsp_cycles = vsp_cycles * 3; @@ -774,9 +774,9 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, } else { base_cycles = 0; vsp_cycles = div_u64(vsp_cycles, 2); - /* VSP FW Overhead 1.05 */ - vsp_cycles = div_u64(vsp_cycles * 21, 20); } + /* VSP FW Overhead 1.05 */ + vsp_cycles = div_u64(vsp_cycles * 21, 20); if (inst->clk_data.work_mode == HFI_WORKMODE_1) vsp_cycles = vsp_cycles * 3; From ad4f5e867085072f581d4be30510ede4df1ce44a Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Tue, 4 Aug 2020 21:03:21 +0530 Subject: [PATCH 359/452] msm: vidc: Cleanup HFI_CMD_SESSION_SYNC support HFI_CMD_SESSION_SYNC is used for synchronization of encode batching between driver and FW. Currently, encode batching is only between camera and driver. To FW, it is always regular encode session without batching. Hence cleaning up the encode batching HFI's. Change-Id: I5d493c98a350e36cd8bb85bf9b82d3f8d41451cf Signed-off-by: Priyanka Gujjula --- msm/vidc/hfi_common.c | 10 ---------- msm/vidc/hfi_packetization.c | 16 ---------------- msm/vidc/hfi_packetization.h | 2 -- msm/vidc/hfi_response_handler.c | 15 --------------- msm/vidc/vidc_hfi_helper.h | 8 -------- 5 files changed, 51 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 915a7c6bf4e5..addf03b45c8f 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -2292,7 +2292,6 @@ static int venus_hfi_session_process_batch(void *sess, int rc = 0, c = 0; struct hal_session *session = sess; struct venus_hfi_device *device = &venus_hfi_dev; - struct hfi_cmd_session_sync_process_packet pkt; mutex_lock(&device->lock); @@ -2319,15 +2318,6 @@ static int venus_hfi_session_process_batch(void *sess, } } - rc = call_hfi_pkt_op(device, session_sync_process, &pkt, session->sid); - if (rc) { - s_vpr_e(session->sid, "Failed to create sync packet\n"); - goto err_etbs_and_ftbs; - } - - if (__iface_cmdq_write(device, &pkt, session->sid)) - rc = -ENOTEMPTY; - err_etbs_and_ftbs: mutex_unlock(&device->lock); return rc; diff --git a/msm/vidc/hfi_packetization.c b/msm/vidc/hfi_packetization.c index 5e0f80530a72..30623ff31d5e 100644 --- a/msm/vidc/hfi_packetization.c +++ b/msm/vidc/hfi_packetization.c @@ -671,21 +671,6 @@ int create_pkt_cmd_sys_image_version( return 0; } -int create_pkt_cmd_session_sync_process( - struct hfi_cmd_session_sync_process_packet *pkt, u32 sid) -{ - if (!pkt) - return -EINVAL; - - *pkt = (struct hfi_cmd_session_sync_process_packet) {0}; - pkt->size = sizeof(*pkt); - pkt->packet_type = HFI_CMD_SESSION_SYNC; - pkt->sid = sid; - pkt->sync_id = 0; - - return 0; -} - static struct hfi_packetization_ops hfi_default = { .sys_init = create_pkt_cmd_sys_init, .sys_pc_prep = create_pkt_cmd_sys_pc_prep, @@ -707,7 +692,6 @@ static struct hfi_packetization_ops hfi_default = { .session_get_buf_req = create_pkt_cmd_session_get_buf_req, .session_flush = create_pkt_cmd_session_flush, .session_set_property = create_pkt_cmd_session_set_property, - .session_sync_process = create_pkt_cmd_session_sync_process, }; struct hfi_packetization_ops *hfi_get_pkt_ops_handle( diff --git a/msm/vidc/hfi_packetization.h b/msm/vidc/hfi_packetization.h index 5240bb16f259..f77c4be243db 100644 --- a/msm/vidc/hfi_packetization.h +++ b/msm/vidc/hfi_packetization.h @@ -64,8 +64,6 @@ struct hfi_packetization_ops { int (*session_set_property)( struct hfi_cmd_session_set_property_packet *pkt, u32 sid, u32 ptype, void *pdata, u32 size); - int (*session_sync_process)( - struct hfi_cmd_session_sync_process_packet *pkt, u32 sid); }; struct hfi_packetization_ops *hfi_get_pkt_ops_handle( diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index 9e65e0462498..b129dec72f31 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -1153,18 +1153,6 @@ static int hfi_process_sys_property_info(u32 device_id, } -static int hfi_process_ignore(u32 device_id, - void *_pkt, - struct msm_vidc_cb_info *info) -{ - *info = (struct msm_vidc_cb_info) { - .response_type = HAL_RESPONSE_UNUSED, - }; - d_vpr_h("RECEIVED: SESSION_SYNC_DONE\n"); - - return 0; -} - int hfi_process_msg_packet(u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr, struct msm_vidc_cb_info *info) { @@ -1225,9 +1213,6 @@ int hfi_process_msg_packet(u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr, case HFI_MSG_SYS_SESSION_ABORT_DONE: pkt_func = (pkt_func_def)hfi_process_session_abort_done; break; - case HFI_MSG_SESSION_SYNC_DONE: - pkt_func = (pkt_func_def)hfi_process_ignore; - break; default: d_vpr_l("Unable to parse message: %#x\n", msg_hdr->packet); break; diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index dd64a6ae9866..7800ac795a6e 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -963,14 +963,6 @@ struct hfi_buffer_mapping_type { u32 size; }; -struct hfi_cmd_session_sync_process_packet { - u32 size; - u32 packet_type; - u32 sid; - u32 sync_id; - u32 rg_data[1]; -}; - struct hfi_msg_event_notify_packet { u32 size; u32 packet_type; From fecdc2cd769ff3f922aca24de144d70066a90abf Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Thu, 10 Sep 2020 16:51:19 -0700 Subject: [PATCH 360/452] msm: vidc: Increase decoder persist_1 buffer size Increase H264/H265 decoder persist_1 buffer size to acommodate t35 userdata. Change-Id: Ifb38d32ee0f3e737b3f8e518976511cf727d295f Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_buffer_calculations.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 4b1a2bd287d9..87dde605568e 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -142,6 +142,7 @@ #define NUM_SLIST_BUF_H264 (256 + 32) #define SIZE_SLIST_BUF_H264 512 +#define SIZE_SEI_USERDATA 4096 #define LCU_MAX_SIZE_PELS 64 #define LCU_MIN_SIZE_PELS 16 @@ -1861,7 +1862,8 @@ static inline u32 calculate_h264d_persist1_size(void) { u32 size = 0; - size = ALIGN((SIZE_SLIST_BUF_H264 * NUM_SLIST_BUF_H264), + size = ALIGN((SIZE_SLIST_BUF_H264 * NUM_SLIST_BUF_H264 + + NUM_HW_PIC_BUF * SIZE_SEI_USERDATA), VENUS_DMA_ALIGNMENT); return size; } @@ -1871,7 +1873,8 @@ static inline u32 calculate_h265d_persist1_size(void) u32 size = 0; size = ALIGN((SIZE_SLIST_BUF_H265 * NUM_SLIST_BUF_H265 + H265_NUM_TILE - * sizeof(u32)), VENUS_DMA_ALIGNMENT); + * sizeof(u32) + NUM_HW_PIC_BUF * SIZE_SEI_USERDATA), + VENUS_DMA_ALIGNMENT); return size; } From 2f691c151e122cfa5206ae0fb7f5b3385bc16dd9 Mon Sep 17 00:00:00 2001 From: Akshay Chandrashekhar Kalghatgi Date: Fri, 11 Sep 2020 16:49:00 -0700 Subject: [PATCH 361/452] msm: vidc: Disable timestamp store-fetch logic Sometimes during sequence change, timestamps may be repeated. This corner case breaks the TS store-fetch logic. Disabling this logic for secure decoder sessions. Change-Id: Ib5c00cc509364ce29b0f69f9b7441edd11b1eef2 Signed-off-by: Akshay Chandrashekhar Kalghatgi --- msm/vidc/msm_vidc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index cf10f063a732..9f2fd2e570c2 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -433,7 +433,7 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, timestamp_us = (s64)((b->timestamp.tv_sec * 1000000) + b->timestamp.tv_usec); if (is_decode_session(inst) && b->type == INPUT_MPLANE && - !is_heif_decoder(inst)) { + !is_heif_decoder(inst) && !is_secure_session(inst)) { if (inst->flush_timestamps) msm_comm_release_timestamps(inst); inst->flush_timestamps = false; @@ -515,7 +515,8 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) if (is_decode_session(inst) && b->type == OUTPUT_MPLANE && !(b->flags & V4L2_BUF_FLAG_CODECCONFIG) && - !is_heif_decoder(inst)) + !is_heif_decoder(inst) && + !is_secure_session(inst)) msm_comm_fetch_ts_framerate(inst, b); return rc; From b2a44dd7fc1ed8508d1597b5acda2f41d643a5b8 Mon Sep 17 00:00:00 2001 From: Salendarsingh Gaud Date: Sun, 13 Sep 2020 21:26:52 +0530 Subject: [PATCH 362/452] Revert "msm: vidc: shima: Update max profile level caps" This reverts commit d7a360d9ed587c09f550ad89a809494f7381dace. Change-Id: I25a34f84c215db420f0aa14f6e3f830653845eac --- msm/vidc/msm_vidc_platform.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 5165cc5fec50..1d42b06aced4 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -425,12 +425,11 @@ static struct msm_vidc_codec_capability shima_capabilities_v0[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 8192, 1, 1920}, {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 8192, 1, 1080}, - {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 1, 1920}, - {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 8192, 1, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 8192, 1, 1080}, /* (8192 * 4320) / 256 */ {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 138240, 1, 138240}, - /* (4096 * 2176) / 256 */ - {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 138240}, + {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 138240, 1, 138240}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 480, 1, 30}, /* Encode spec - 4K@60 */ @@ -519,18 +518,18 @@ static struct msm_vidc_codec_capability shima_capabilities_v0[] = { * to set higher level than supported. */ {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, /* Level for AVC and HEVC decoder specific */ {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_6_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_6, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, }; @@ -626,18 +625,18 @@ static struct msm_vidc_codec_capability shima_capabilities_v1[] = { * to set higher level than supported. */ {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, /* Level for AVC and HEVC decoder specific */ {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, }; @@ -732,18 +731,18 @@ static struct msm_vidc_codec_capability shima_capabilities_v2[] = { * to set higher level than supported. */ {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, /* Level for AVC and HEVC decoder specific */ {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1, 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, }; From 28954c0c09f01773bc5cf610753e8f0a552905ac Mon Sep 17 00:00:00 2001 From: Salendarsingh Gaud Date: Sun, 13 Sep 2020 21:27:16 +0530 Subject: [PATCH 363/452] Revert "msm: vidc: reverse sort allowed_clock_tbl for shima" This reverts commit 4b5d7127383a4bb8870b181e51d487da3685b03b. Change-Id: I67c95ad1be5ec8280db20485a60ccf140cbda95f --- msm/vidc/msm_vidc_res_parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index b730636ef31e..1e17830ff333 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -349,7 +349,7 @@ static int msm_vidc_load_allowed_clocks_table( if (res->allowed_clks_tbl) { d_vpr_h("allowed-clock-rates populated from platform_data\n"); - goto exit; + return 0; } if (!of_find_property(pdev->dev.of_node, @@ -367,7 +367,7 @@ static int msm_vidc_load_allowed_clocks_table( d_vpr_e("%s: failed to read allowed clocks table\n", __func__); return rc; } -exit: + sort(res->allowed_clks_tbl, res->allowed_clks_tbl_size, sizeof(*res->allowed_clks_tbl), cmp, NULL); From 3e7994b2a02019dce8a17e4c77dd9e6c13041948 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Mon, 14 Sep 2020 16:38:32 +0800 Subject: [PATCH 364/452] msm: venc: enable VUI timing for native recorder Enable VUI timing info when using native recorder by default. Change-Id: I1edb9d8b9bcd84e06bcd0f52429bda96af5d0de3 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_venc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 00296c346b95..faea1871f65f 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -4161,7 +4161,7 @@ int msm_venc_set_vui_timing_info(struct msm_vidc_inst *inst) struct hfi_device *hdev; struct v4l2_ctrl *ctrl; struct hfi_vui_timing_info timing_info; - bool cfr; + bool cfr, native_recorder; u32 codec; if (!inst || !inst->core) { @@ -4174,8 +4174,13 @@ int msm_venc_set_vui_timing_info(struct msm_vidc_inst *inst) if (codec != V4L2_PIX_FMT_H264 && codec != V4L2_PIX_FMT_HEVC) return 0; + native_recorder = false; + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER); + if (ctrl->val == V4L2_MPEG_MSM_VIDC_ENABLE) + native_recorder = true; + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_VUI_TIMING_INFO); - if (ctrl->val == V4L2_MPEG_MSM_VIDC_DISABLE) + if (ctrl->val == V4L2_MPEG_MSM_VIDC_DISABLE && native_recorder == false) return 0; switch (inst->rc_type) { From 5bef15ac091db687d8182a3a14749b4a8464a7b7 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 16 Sep 2020 18:50:21 +0530 Subject: [PATCH 365/452] msm: vidc: Add query support for HEIC caps Add support to VIDIOC_ENUM_FRAMESIZES for querying HEIC frame size. Change-Id: I9ceba027c798e0c0fb7781702ccb2873fc8276ac Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index cf10f063a732..8313e8316e29 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -598,14 +598,31 @@ int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize) capability = &inst->capability; fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; - fsize->stepwise.min_width = capability->cap[CAP_FRAME_WIDTH].min; - fsize->stepwise.max_width = capability->cap[CAP_FRAME_WIDTH].max; - fsize->stepwise.step_width = - capability->cap[CAP_FRAME_WIDTH].step_size; - fsize->stepwise.min_height = capability->cap[CAP_FRAME_HEIGHT].min; - fsize->stepwise.max_height = capability->cap[CAP_FRAME_HEIGHT].max; - fsize->stepwise.step_height = - capability->cap[CAP_FRAME_HEIGHT].step_size; + if(is_grid_session(inst)) { + fsize->stepwise.min_width = + capability->cap[CAP_HEIC_IMAGE_FRAME_WIDTH].min; + fsize->stepwise.max_width = + capability->cap[CAP_HEIC_IMAGE_FRAME_WIDTH].max; + fsize->stepwise.step_width = + capability->cap[CAP_HEIC_IMAGE_FRAME_WIDTH].step_size; + fsize->stepwise.min_height = + capability->cap[CAP_HEIC_IMAGE_FRAME_HEIGHT].min; + fsize->stepwise.max_height = + capability->cap[CAP_HEIC_IMAGE_FRAME_HEIGHT].max; + fsize->stepwise.step_height = + capability->cap[CAP_HEIC_IMAGE_FRAME_HEIGHT].step_size; + + } + else { + fsize->stepwise.min_width = capability->cap[CAP_FRAME_WIDTH].min; + fsize->stepwise.max_width = capability->cap[CAP_FRAME_WIDTH].max; + fsize->stepwise.step_width = + capability->cap[CAP_FRAME_WIDTH].step_size; + fsize->stepwise.min_height = capability->cap[CAP_FRAME_HEIGHT].min; + fsize->stepwise.max_height = capability->cap[CAP_FRAME_HEIGHT].max; + fsize->stepwise.step_height = + capability->cap[CAP_FRAME_HEIGHT].step_size; + } return 0; } EXPORT_SYMBOL(msm_vidc_enum_framesizes); From 31f9744ab8fda02903b9196e5433162c1511ed87 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Mon, 14 Sep 2020 20:14:37 +0530 Subject: [PATCH 366/452] msm: vidc: update calculation for BSE LB write for decoder For h264 BSE LB write should be half of BSE LB read for decoder. Update the calculation for the same. Change-Id: I5ebceff4fa0795eaaf67b569e754d174be4a8146 Signed-off-by: Dikshita Agarwal --- msm/vidc/msm_vidc_bus_iris2.c | 12 +++++++++++- msm/vidc/msm_vidc_clocks.c | 3 +++ msm/vidc/msm_vidc_internal.h | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_bus_iris2.c b/msm/vidc/msm_vidc_bus_iris2.c index 6252fd3ddf27..db922351b54d 100644 --- a/msm/vidc/msm_vidc_bus_iris2.c +++ b/msm/vidc/msm_vidc_bus_iris2.c @@ -32,6 +32,7 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) /* Derived parameters */ int lcu_per_frame, collocated_bytes_per_lcu, tnbr_per_lcu; unsigned long bitrate; + unsigned int num_vpp_pipes; fp_t bins_to_bit_factor, vsp_read_factor, vsp_write_factor, dpb_factor, dpb_write_factor, y_bw_no_ubwc_8bpp; @@ -83,6 +84,8 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) opb_write_compression_factor = opb_compression_enabled ? dpb_write_compression_factor : FP_ONE; + num_vpp_pipes = d->num_vpp_pipes; + if (d->codec == HAL_VIDEO_CODEC_HEVC || d->codec == HAL_VIDEO_CODEC_VP9) { /* H264, VP8, MPEG2 use the same settings */ @@ -163,7 +166,14 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) ddr.line_buffer_read = fp_div(FP_INT(tnbr_per_lcu * lcu_per_frame * fps), FP_INT(bps(1))); - ddr.line_buffer_write = ddr.line_buffer_read; + /* This change is applicable for all IRIS2 targets, + * but currently being done for IRIS2 with 2 pipes + * only due to timeline constraints. + */ + if((num_vpp_pipes == 2) && (is_h264_category)) + ddr.line_buffer_write = fp_div(ddr.line_buffer_read,FP_INT(2)); + else + ddr.line_buffer_write = ddr.line_buffer_read; if (llc_top_line_buf_enabled) { llc.line_buffer_read = ddr.line_buffer_read; llc.line_buffer_write = ddr.line_buffer_write; diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 92cf50997829..405dd253b1c7 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -456,6 +456,9 @@ int msm_comm_vote_bus(struct msm_vidc_inst *inst) if (core->resources.sys_cache_res_set) vote_data->use_sys_cache = true; + vote_data->num_vpp_pipes = + inst->core->platform_data->num_vpp_pipes; + call_core_op(core, calc_bw, vote_data); } diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 27844dbe19a8..123ac97212c5 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -427,6 +427,7 @@ struct vidc_bus_vote_data { bool b_frames_enabled; unsigned long calc_bw_ddr; unsigned long calc_bw_llcc; + u32 num_vpp_pipes; }; struct profile_data { From b03e989d89e3aec75e59f539c1954de22fbf85b4 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Thu, 17 Sep 2020 11:38:00 +0530 Subject: [PATCH 367/452] msm: vidc: cleanup unsupported profile and levels for VP9 VP9 decoder spec is reduced. So cleaning up unsupported profiles & levels for VP9. Supported Profile - 0 & 2 Max supported level - 5.1 Change-Id: I5b131f5bbd3c50aea2949f62ab6b16d51728ba7d Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vdec.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 9da5158a5ae8..cadd95ced921 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -77,8 +77,6 @@ static const char *const vp9_level[] = { "4.1", "5.0", "5.1", - "6.0", - "6.1", NULL }; @@ -274,7 +272,6 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .default_value = V4L2_MPEG_VIDEO_VP9_PROFILE_0, .menu_skip_mask = ~( (1 << V4L2_MPEG_VIDEO_VP9_PROFILE_0) | - (1 << V4L2_MPEG_VIDEO_VP9_PROFILE_1) | (1 << V4L2_MPEG_VIDEO_VP9_PROFILE_2) ), .qmenu = NULL, @@ -284,8 +281,8 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .name = "VP9 Level", .type = V4L2_CTRL_TYPE_MENU, .minimum = V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_UNUSED, - .maximum = V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_61, - .default_value = V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_61, + .maximum = V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_51, + .default_value = V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_51, .menu_skip_mask = ~( (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_UNUSED) | (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_1) | @@ -297,9 +294,7 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_4) | (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_41) | (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_5) | - (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_51) | - (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6) | - (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_61) + (1 << V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_51) ), .qmenu = vp9_level, }, From 2efb0193b30dcbbe4f0cb9cf0c606bbe5ce60dfe Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Thu, 17 Sep 2020 14:35:54 -0700 Subject: [PATCH 368/452] msm: vidc: Force nominal for high bitrate decode usecases Force the clocks to NOM if bitrate nears or exceeds maximum supported for VP9 usecases. Signed-off-by: Chinmay Sawarkar Change-Id: I917b0f6c624837403fd9f1499a68812acb00b568 --- msm/vidc/msm_vidc_clocks.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 9a4716ef16eb..13a3bf130977 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -679,6 +679,7 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, u32 operating_rate, vsp_factor_num = 1, vsp_factor_den = 1; u32 base_cycles = 0; u32 codec = 0; + u64 bitrate = 0; core = inst->core; dcvs = &inst->clk_data; @@ -768,7 +769,8 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, codec = get_v4l2_codec(inst); base_cycles = inst->has_bframe ? 80 : inst->clk_data.entry->vsp_cycles; - vsp_cycles = fps * filled_len * 8; + bitrate = fps * filled_len * 8; + vsp_cycles = bitrate; if (codec == V4L2_PIX_FMT_VP9) { vsp_cycles = div_u64(vsp_cycles * 170, 100); @@ -786,6 +788,11 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, vsp_cycles += mbs_per_second * base_cycles; + if (codec == V4L2_PIX_FMT_VP9 && + inst->clk_data.work_mode == HFI_WORKMODE_2 && + inst->clk_data.work_route == 4 && + bitrate > 90000000) + vsp_cycles = msm_vidc_max_freq(inst->core, inst->sid); } else { s_vpr_e(inst->sid, "%s: Unknown session type\n", __func__); return msm_vidc_max_freq(inst->core, inst->sid); From 8f4637a4ac8337abe0d2dcca630d725f418d9201 Mon Sep 17 00:00:00 2001 From: Akshay Chandrashekhar Kalghatgi Date: Fri, 11 Sep 2020 16:49:00 -0700 Subject: [PATCH 369/452] msm: vidc: Disable timestamp store-fetch logic Sometimes during sequence change, timestamps may be repeated. This corner case breaks the TS store-fetch logic. Disabling this logic for secure decoder sessions. Change-Id: Ib5c00cc509364ce29b0f69f9b7441edd11b1eef2 Signed-off-by: Akshay Chandrashekhar Kalghatgi --- msm/vidc/msm_vidc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index cf10f063a732..9f2fd2e570c2 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -433,7 +433,7 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, timestamp_us = (s64)((b->timestamp.tv_sec * 1000000) + b->timestamp.tv_usec); if (is_decode_session(inst) && b->type == INPUT_MPLANE && - !is_heif_decoder(inst)) { + !is_heif_decoder(inst) && !is_secure_session(inst)) { if (inst->flush_timestamps) msm_comm_release_timestamps(inst); inst->flush_timestamps = false; @@ -515,7 +515,8 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) if (is_decode_session(inst) && b->type == OUTPUT_MPLANE && !(b->flags & V4L2_BUF_FLAG_CODECCONFIG) && - !is_heif_decoder(inst)) + !is_heif_decoder(inst) && + !is_secure_session(inst)) msm_comm_fetch_ts_framerate(inst, b); return rc; From 70a2ee6e3cca4356f59ba29344fc0b9550f64b31 Mon Sep 17 00:00:00 2001 From: Chandrakant I Viraktamath Date: Fri, 18 Sep 2020 17:13:13 +0530 Subject: [PATCH 370/452] msm: vidc: Add control to handle timestamp reorder Add control to enable/disable timestamp reordering in driver. Change-Id: I50c3f60bb8af053881073b40c6df0c74f3f0aafb Signed-off-by: Chandrakant I Viraktamath --- include/uapi/vidc/media/msm_vidc_utils.h | 2 ++ msm/vidc/msm_vdec.c | 11 +++++++++++ msm/vidc/msm_vidc.c | 5 ++--- msm/vidc/msm_vidc_common.h | 18 ++++++++++++++++++ 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index 5359ec8e7538..4108ed84b036 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -258,6 +258,8 @@ enum v4l2_mpeg_vidc_video_bitrate_savings_type { (V4L2_CID_MPEG_MSM_VIDC_BASE + 134) #define V4L2_CID_MPEG_VIDC_VENC_QPRANGE_BOOST \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 135) +#define V4L2_CID_MPEG_VIDC_VIDEO_DISABLE_TIMESTAMP_REORDER \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 136) #define V4L2_CID_MPEG_VIDC_VIDEO_UNKNOWN \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 0xFFF) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index cadd95ced921..bb69dede610c 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -420,6 +420,15 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, .step = 1, }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_DISABLE_TIMESTAMP_REORDER, + .name = "Disable TimeStamp Reorder", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, { .id = V4L2_CID_MPEG_VIDC_SUPERFRAME, .name = "Superframe", @@ -952,6 +961,8 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_HINT: break; + case V4L2_CID_MPEG_VIDC_VIDEO_DISABLE_TIMESTAMP_REORDER: + break; case V4L2_CID_MPEG_VIDC_VDEC_HEIF_MODE: if(get_v4l2_codec(inst) != V4L2_PIX_FMT_HEVC) break; diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index ec3e6551233d..e9fe48f72943 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -433,7 +433,7 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, timestamp_us = (s64)((b->timestamp.tv_sec * 1000000) + b->timestamp.tv_usec); if (is_decode_session(inst) && b->type == INPUT_MPLANE && - !is_heif_decoder(inst) && !is_secure_session(inst)) { + is_ts_reorder_allowed(inst)) { if (inst->flush_timestamps) msm_comm_release_timestamps(inst); inst->flush_timestamps = false; @@ -515,8 +515,7 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) if (is_decode_session(inst) && b->type == OUTPUT_MPLANE && !(b->flags & V4L2_BUF_FLAG_CODECCONFIG) && - !is_heif_decoder(inst) && - !is_secure_session(inst)) + is_ts_reorder_allowed(inst)) msm_comm_fetch_ts_framerate(inst, b); return rc; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 42467096c2f3..779f0c8cbf96 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -159,6 +159,24 @@ static inline bool is_secure_session(struct msm_vidc_inst *inst) return !!(inst->flags & VIDC_SECURE); } +static inline bool is_ts_reorder_allowed(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *ctrl; + + if (is_secure_session(inst)) + return false; + + if (inst->session_type != MSM_VIDC_DECODER) + return true; + + if (!is_heif_decoder(inst)) + return true; + + ctrl = get_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_DISABLE_TIMESTAMP_REORDER); + return !ctrl->val; +} + static inline bool is_decode_session(struct msm_vidc_inst *inst) { return inst->session_type == MSM_VIDC_DECODER; From 7377b0c45405efff818d96c2f508d4b80f3d94d3 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Wed, 19 Aug 2020 14:46:20 +0800 Subject: [PATCH 371/452] msm: venc: reject unsupported sessions with VPSS enabled Reject any sessions with non-multiple 8 of resolution and rotation/flip is enabled. Change-Id: Ifac0cc8884461fe8d2502e92481643d9443aa527 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_venc.c | 69 +++++++++++++++++++++++++++++++++++ msm/vidc/msm_venc.h | 1 + msm/vidc/msm_vidc_internal.h | 7 ++++ msm/vidc/msm_vidc_platform.c | 18 +++++++++ msm/vidc/msm_vidc_res_parse.c | 2 + msm/vidc/msm_vidc_resources.h | 2 + 6 files changed, 99 insertions(+) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index faea1871f65f..5277fb34ca6a 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -4039,6 +4039,9 @@ int msm_venc_check_dynamic_flip_constraints(struct msm_vidc_inst *inst) /* Reject dynamic flip with scalar enabled */ s_vpr_e(inst->sid, "Unsupported dynamic flip with scalar\n"); rc = -EINVAL; + } else if (handle_vpss_restrictions(inst)) { + s_vpr_e(inst->sid, "Unsupported resolution for dynamic flip\n"); + rc = -EINVAL; } return rc; @@ -4825,6 +4828,69 @@ int check_blur_restrictions(struct msm_vidc_inst *inst) return 0; } +int handle_vpss_restrictions(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *rotation = NULL; + struct v4l2_ctrl *hflip = NULL; + struct v4l2_ctrl *vflip = NULL; + struct v4l2_format *f; + struct msm_vidc_vpss_capability *vpss_caps; + u32 vpss_caps_count; + bool rotation_flip_enable = false; + u32 i,input_height, input_width; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params %pK\n", __func__, inst); + return -EINVAL; + } + + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + input_height = f->fmt.pix_mp.height; + input_width = f->fmt.pix_mp.width; + + vpss_caps = inst->core->resources.vpss_caps; + vpss_caps_count = inst->core->resources.vpss_caps_count; + + /* check customer specified VPSS resolutions */ + if (vpss_caps) { + for (i = 0; i < vpss_caps_count; i++) { + if (input_width == vpss_caps[i].width && + input_height == vpss_caps[i].height) { + s_vpr_h(inst->sid, + "supported resolution found for VPSS, width = %d, height = %d\n", + input_width, input_height); + return 0; + } + } + } + + /* check rotation and flip contraint for VPSS + * any rotation or flip sessions with non-multiple of 8 + * resolution is rejected. + */ + rotation = get_ctrl(inst, V4L2_CID_ROTATE); + hflip = get_ctrl(inst, V4L2_CID_HFLIP); + vflip = get_ctrl(inst, V4L2_CID_VFLIP); + if (rotation->val != 0 || + hflip->val != V4L2_MPEG_MSM_VIDC_DISABLE || + vflip->val != V4L2_MPEG_MSM_VIDC_DISABLE) + rotation_flip_enable = true; + + if (rotation_flip_enable) { + if ((input_width & 7) != 0) { + s_vpr_e(inst->sid, "Unsupported width = %d for VPSS\n", + input_width); + return -ENOTSUPP; + } + if ((input_height & 7) != 0) { + s_vpr_e(inst->sid, "Unsupported height = %d for VPSS\n", + input_height); + return -ENOTSUPP; + } + } + return 0; +} + int msm_venc_set_properties(struct msm_vidc_inst *inst) { int rc = 0; @@ -4836,6 +4902,9 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) if (rc) goto exit; rc = handle_all_intra_restrictions(inst); + if (rc) + goto exit; + rc = handle_vpss_restrictions(inst); if (rc) goto exit; rc = msm_venc_set_frame_size(inst); diff --git a/msm/vidc/msm_venc.h b/msm/vidc/msm_venc.h index 4f5689fe50d1..e172bf748336 100644 --- a/msm/vidc/msm_venc.h +++ b/msm/vidc/msm_venc.h @@ -49,4 +49,5 @@ int check_blur_restrictions(struct msm_vidc_inst *inst); int msm_venc_set_frame_quality(struct msm_vidc_inst *inst); int msm_venc_set_image_grid(struct msm_vidc_inst *inst); int msm_venc_set_bitrate_boost_margin(struct msm_vidc_inst *inst, u32 enable); +int handle_vpss_restrictions(struct msm_vidc_inst *inst); #endif diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 26e3239351b3..b54f981e6017 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -229,6 +229,11 @@ struct msm_vidc_codec_capability { u32 default_value; }; +struct msm_vidc_vpss_capability { + u32 width; + u32 height; +}; + struct msm_vidc_codec { enum hal_domain domain; enum hal_video_codec codec; @@ -296,6 +301,8 @@ struct msm_vidc_platform_data { uint32_t codecs_count; struct msm_vidc_codec_capability *codec_caps; uint32_t codec_caps_count; + struct msm_vidc_vpss_capability *vpss_caps; + uint32_t vpss_caps_count; struct msm_vidc_csc_coeff csc_data; struct msm_vidc_efuse_data *efuse_data; unsigned int efuse_data_length; diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 5165cc5fec50..710944785d82 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -747,6 +747,16 @@ static struct msm_vidc_codec_capability shima_capabilities_v2[] = { V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, }; +/* Generally Iris2 VPSS only support 8 multiple encoding if + * rotation/flip is enabled, however customer can require specific + * resolution supports and expand capabilities here. + */ +static struct msm_vidc_vpss_capability vpss_capabilities[] = { + /* {supported width, supported height,} */ + {3840, 1644}, + {1644, 3840}, +}; + /* * Custom conversion coefficients for resolution: 176x144 negative * coeffs are converted to s4.9 format @@ -1498,6 +1508,8 @@ static struct msm_vidc_platform_data lahaina_data = { .codecs_count = ARRAY_SIZE(default_codecs), .codec_caps = lahaina_capabilities, .codec_caps_count = ARRAY_SIZE(lahaina_capabilities), + .vpss_caps = vpss_capabilities, + .vpss_caps_count = ARRAY_SIZE(vpss_capabilities), }; static struct msm_vidc_platform_data bengal_data = { @@ -1520,6 +1532,8 @@ static struct msm_vidc_platform_data bengal_data = { .codecs_count = ARRAY_SIZE(bengal_codecs), .codec_caps = bengal_capabilities_v0, .codec_caps_count = ARRAY_SIZE(bengal_capabilities_v0), + .vpss_caps = NULL, + .vpss_caps_count = 0, }; static struct msm_vidc_platform_data shima_data = { @@ -1542,6 +1556,8 @@ static struct msm_vidc_platform_data shima_data = { .codecs_count = ARRAY_SIZE(shima_codecs), .codec_caps = shima_capabilities_v0, .codec_caps_count = ARRAY_SIZE(shima_capabilities_v0), + .vpss_caps = vpss_capabilities, + .vpss_caps_count = ARRAY_SIZE(vpss_capabilities), }; static struct msm_vidc_platform_data holi_data = { @@ -1564,6 +1580,8 @@ static struct msm_vidc_platform_data holi_data = { .codecs_count = ARRAY_SIZE(holi_codecs), .codec_caps = holi_capabilities, .codec_caps_count = ARRAY_SIZE(holi_capabilities), + .vpss_caps = NULL, + .vpss_caps_count = 0, }; static const struct of_device_id msm_vidc_dt_device[] = { diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index b730636ef31e..1aa93ac5bb75 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -733,6 +733,8 @@ int read_platform_resources_from_drv_data( res->codec_data = platform_data->codec_data; res->allowed_clks_tbl = platform_data->clock_data; res->allowed_clks_tbl_size = platform_data->clock_data_length; + res->vpss_caps = platform_data->vpss_caps; + res->vpss_caps_count = platform_data->vpss_caps_count; res->sku_version = platform_data->sku_version; res->mem_limit_tbl = memory_limit_tbl_mbytes; diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 5add5ec54373..7a2916cd62ac 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -194,6 +194,8 @@ struct msm_vidc_platform_resources { uint32_t codecs_count; struct msm_vidc_codec_capability *codec_caps; uint32_t codec_caps_count; + struct msm_vidc_vpss_capability *vpss_caps; + uint32_t vpss_caps_count; struct msm_vidc_csc_coeff *csc_coeff_data; struct msm_vidc_mem_cdsp mem_cdsp; uint32_t vpu_ver; From 173068c67f80f6661e37f1850e47d729d9b0e98f Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 23 Sep 2020 21:36:28 +0530 Subject: [PATCH 372/452] msm: vidc: Add max-image-load caps to holi and shima Add max-image-load caps as 8k for holi and 16k for shima for all variants. Change-Id: I5d1483c0e2dc06af61eca4944bc269e36baa6d73 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_platform.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 5165cc5fec50..2387793d3ace 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1079,6 +1079,10 @@ static struct msm_vidc_common_data shima_common_data_v0[] = { * (8192x4320)/256)@30fps decode */ }, + { + .key = "qcom,max-image-load", + .value = 1048576, /* ((16384x16384)/256)@1fps */ + }, { .key = "qcom,max-mbpf", .value = 138240, /* ((8192x4320)/256) */ @@ -1192,6 +1196,10 @@ static struct msm_vidc_common_data shima_common_data_v1[] = { * (3840x2176)/256)@60fps decode */ }, + { + .key = "qcom,max-image-load", + .value = 1048576, /* ((16384x16384)/256)@1fps */ + }, { .key = "qcom,max-mbpf", .value = 130560, /* ((3840x2176)/256) x 4 */ @@ -1305,6 +1313,10 @@ static struct msm_vidc_common_data shima_common_data_v2[] = { * (3840x2176)/256)@30fps decode */ }, + { + .key = "qcom,max-image-load", + .value = 1048576, /* ((16384x16384)/256)@1fps */ + }, { .key = "qcom,max-mbpf", .value = 130560, /* ((3840x2176)/256) x 4 */ @@ -1415,6 +1427,10 @@ static struct msm_vidc_common_data holi_common_data[] = { .key = "qcom,max-hw-load", .value = 489600, /* ((1088x1920)/256)@60fps */ }, + { + .key = "qcom,max-image-load", + .value = 262144, /* ((8192x8192)/256)@1fps */ + }, { .key = "qcom,max-mbpf", .value = 65280,/* ((3840x2176)/256) x 2 */ From 3486a7e10a0a12585677c7ff8d2e69044625ada2 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Fri, 18 Sep 2020 22:25:35 +0800 Subject: [PATCH 373/452] msm: vidc: always use HQ for HEIC and lossless encoder Always use HQ mode for HEIC and lossless encoder. Refine FW version retrieve to support version string start with lower case v. Change-Id: I092956b34250da55a4cfc2c7b88815c05a64375f Signed-off-by: Qiwei Liu --- msm/vidc/hfi_common.c | 7 ++++--- msm/vidc/msm_vidc_clocks.c | 5 ++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index addf03b45c8f..bbb48a5120de 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -3993,16 +3993,17 @@ static int venus_hfi_get_fw_info(void *dev, struct hal_fw_info *fw_info) smem_table_ptr + smem_image_index_venus, VENUS_VERSION_LENGTH); - while (version[i++] != 'V' && i < VENUS_VERSION_LENGTH) + while (version[i] != 'V' && version[i] != 'v' && + ++i < VENUS_VERSION_LENGTH) ; - if (i == VENUS_VERSION_LENGTH - 1) { + if (i >= VENUS_VERSION_LENGTH - 1) { d_vpr_e("Venus version string is not proper\n"); fw_info->version[0] = '\0'; goto fail_version_string; } - for (i--; i < VENUS_VERSION_LENGTH && j < VENUS_VERSION_LENGTH - 1; i++) + for (; i < VENUS_VERSION_LENGTH && j < VENUS_VERSION_LENGTH - 1; i++) fw_info->version[j++] = version[i]; fw_info->version[j] = '\0'; diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 9a4716ef16eb..b9a1359a9387 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1462,7 +1462,10 @@ int msm_vidc_decide_core_and_power_mode_iris2(struct msm_vidc_inst *inst) max_hq_mbpf = inst->core->resources.max_hq_mbs_per_frame; max_hq_mbps = inst->core->resources.max_hq_mbs_per_sec; - if (mbpf <= max_hq_mbpf && mbps <= max_hq_mbps) + /* Power saving always disabled for CQ and LOSSLESS RC modes. */ + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ || + inst->rc_type == RATE_CONTROL_LOSSLESS || + (mbpf <= max_hq_mbpf && mbps <= max_hq_mbps)) enable = false; rc = msm_vidc_power_save_mode_enable(inst, enable); From 5d0c3973bcd7f1127c20be5bf131741f09741d4e Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 28 Sep 2020 11:25:31 +0530 Subject: [PATCH 374/452] msm: vidc: reduce shima max spec Update max-hw-load to be inline with shima pro-sku spec. Change-Id: I98aaa4d870156812a240fecdf31feaa242aca4a8 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_platform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 5165cc5fec50..e211ab2f2243 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1073,10 +1073,10 @@ static struct msm_vidc_common_data shima_common_data_v0[] = { }, { .key = "qcom,max-hw-load", - .value = 4147200, + .value = 3916800, /** * (3840x2176)/256)@120fps decode, - * (8192x4320)/256)@30fps decode + * (7680x4320)/256)@30fps decode */ }, { From 7c4bb220ce18c1f18b91739c11f0a858afa1d983 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Tue, 29 Sep 2020 17:54:38 +0530 Subject: [PATCH 375/452] msm: vidc: Add fn pointer for ar50lt bw calc Add ar50lt bw calc function pointer in core ops. Change-Id: I83cb81dde373a14b5b07594ca5af286bc01eefd1 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_clocks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 13a3bf130977..87aa76a65cc0 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -31,7 +31,7 @@ struct msm_vidc_core_ops core_ops_ar50_lt = { .decide_work_mode = msm_vidc_decide_work_mode_ar50_lt, .decide_core_and_power_mode = msm_vidc_decide_core_and_power_mode_ar50lt, - .calc_bw = NULL, + .calc_bw = calc_bw_ar50lt, }; struct msm_vidc_core_ops core_ops_iris2 = { From f033016e9e842c5b548b36d5785cc5e94a12c8e2 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Thu, 1 Oct 2020 16:32:22 +0530 Subject: [PATCH 376/452] msm-vidc: fix final BW voting to ICC Currently, Required BW is calculated in bytes per second but when setting it to ICC, kbps_to_icc macro is applied to calculated BW which again divides the value by 8 and resulting into less final vote to icc. Change-Id: I7a645478d05909308edea2170d7c5cb911cbf6f0 Signed-off-by: Dikshita Agarwal --- msm/vidc/hfi_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 915a7c6bf4e5..1ffdc65a27ad 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -888,7 +888,7 @@ static int __vote_bandwidth(struct bus_info *bus, int rc = 0; s_vpr_p(sid, "Voting bus %s to ab %llu kbps\n", bus->name, bw_kbps); - rc = icc_set_bw(bus->path, kbps_to_icc(bw_kbps), 0); + rc = icc_set_bw(bus->path, bw_kbps, 0); if (rc) s_vpr_e(sid, "Failed voting bus %s to ab %llu, rc=%d\n", bus->name, bw_kbps, rc); From cb1896477067d3b9f9451a0f64d6c5f20535d915 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Fri, 19 Jun 2020 12:37:47 +0530 Subject: [PATCH 377/452] msm: vidc: Add support for hw stability test Add support for noc error and vcodec hung HFI to test hardware stability via ssr_type and to input the sub client id and test address accordingly. ssr_type: 0-3 bits sub_client_id: 4-7 bits reserved: 8-31 bits test_addr: 32-63 bits Change-Id: I05970d3dc3e54da50688319eabccd5d11f8f55e2 Signed-off-by: Priyanka Gujjula lock); - rc = call_hfi_pkt_op(dev, ssr_cmd, type, &pkt); + rc = call_hfi_pkt_op(dev, ssr_cmd, &pkt, ssr_type, + sub_client_id, test_addr); if (rc) { d_vpr_e("core_ping: failed to create packet\n"); goto err_create_pkt; diff --git a/msm/vidc/hfi_packetization.c b/msm/vidc/hfi_packetization.c index 30623ff31d5e..8518dc27018e 100644 --- a/msm/vidc/hfi_packetization.c +++ b/msm/vidc/hfi_packetization.c @@ -626,7 +626,7 @@ int create_pkt_cmd_session_set_property( static int get_hfi_ssr_type(enum hal_ssr_trigger_type type) { - int rc = HFI_TEST_SSR_HW_WDOG_IRQ; + int rc = HFI_TEST_SSR_SW_ERR_FATAL; switch (type) { case SSR_ERR_FATAL: @@ -638,22 +638,37 @@ static int get_hfi_ssr_type(enum hal_ssr_trigger_type type) case SSR_HW_WDOG_IRQ: rc = HFI_TEST_SSR_HW_WDOG_IRQ; break; + case SSR_NOC_ERROR: + rc = HFI_TEST_SSR_NOC_ERROR; + break; + case SSR_VCODEC_HUNG: + rc = HFI_TEST_SSR_VCODEC_HUNG; + break; default: d_vpr_e("SSR trigger type not recognized, using WDOG.\n"); } return rc; } -int create_pkt_ssr_cmd(enum hal_ssr_trigger_type type, - struct hfi_cmd_sys_test_ssr_packet *pkt) +int create_pkt_ssr_cmd(struct hfi_cmd_sys_test_ssr_packet *pkt, + enum hal_ssr_trigger_type ssr_type, u32 sub_client_id, + u32 test_addr) { + struct hfi_ssr_payload payload; if (!pkt) { d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } - pkt->size = sizeof(struct hfi_cmd_sys_test_ssr_packet); + pkt->size = sizeof(struct hfi_cmd_sys_test_ssr_packet) - sizeof(u32); pkt->packet_type = HFI_CMD_SYS_TEST_SSR; - pkt->trigger_type = get_hfi_ssr_type(type); + pkt->trigger_type = get_hfi_ssr_type(ssr_type); + if (pkt->trigger_type == HFI_TEST_SSR_NOC_ERROR || + pkt->trigger_type == HFI_TEST_SSR_VCODEC_HUNG) { + pkt->size += sizeof(struct hfi_ssr_payload); + payload.sub_client_id = sub_client_id; + payload.test_addr = test_addr; + memcpy(&pkt->rg_data[0], &payload, sizeof(struct hfi_ssr_payload)); + } return 0; } diff --git a/msm/vidc/hfi_packetization.h b/msm/vidc/hfi_packetization.h index f77c4be243db..accce3144aa4 100644 --- a/msm/vidc/hfi_packetization.h +++ b/msm/vidc/hfi_packetization.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef __HFI_PACKETIZATION_H__ #define __HFI_PACKETIZATION_H__ @@ -36,8 +36,9 @@ struct hfi_packetization_ops { int (*sys_image_version)(struct hfi_cmd_sys_get_property_packet *pkt); int (*sys_ubwc_config)(struct hfi_cmd_sys_set_property_packet *pkt, struct msm_vidc_ubwc_config_data *ubwc_config); - int (*ssr_cmd)(enum hal_ssr_trigger_type type, - struct hfi_cmd_sys_test_ssr_packet *pkt); + int (*ssr_cmd)(struct hfi_cmd_sys_test_ssr_packet *pkt, + enum hal_ssr_trigger_type ssr_type, u32 sub_client_id, + u32 test_addr); int (*session_init)( struct hfi_cmd_sys_session_init_packet *pkt, u32 sid, u32 session_domain, u32 session_codec); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index f85fe2017c4d..4c71d3512441 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -25,6 +25,12 @@ static void msm_vidc_print_running_insts(struct msm_vidc_core *core); #define V4L2_VP9_LEVEL_61 V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_61 #define TIMESTAMPS_WINDOW_SIZE 32 +#define SSR_TYPE 0x0000000F +#define SSR_TYPE_SHIFT 0 +#define SSR_SUB_CLIENT_ID 0x000000F0 +#define SSR_SUB_CLIENT_ID_SHIFT 4 +#define SSR_ADDR_ID 0xFFFFFFFF00000000 +#define SSR_ADDR_SHIFT 32 int msm_comm_g_ctrl_for_id(struct msm_vidc_inst *inst, int id) { @@ -5644,13 +5650,25 @@ int msm_vidc_noc_error_info(struct msm_vidc_core *core) } int msm_vidc_trigger_ssr(struct msm_vidc_core *core, - enum hal_ssr_trigger_type type) + u64 trigger_ssr_val) { + struct msm_vidc_ssr *ssr; if (!core) { d_vpr_e("%s: Invalid parameters\n", __func__); return -EINVAL; } - core->ssr_type = type; + ssr = &core->ssr; + /* + * ssr_type: 0-3 bits + * sub_client_id: 4-7 bits + * reserved: 8-31 bits + * test_addr: 32-63 bits */ + ssr->ssr_type = (trigger_ssr_val & + (unsigned long)SSR_TYPE) >> SSR_TYPE_SHIFT; + ssr->sub_client_id = (trigger_ssr_val & + (unsigned long)SSR_SUB_CLIENT_ID) >> SSR_SUB_CLIENT_ID_SHIFT; + ssr->test_addr = (trigger_ssr_val & + (unsigned long)SSR_ADDR_ID) >> SSR_ADDR_SHIFT; schedule_work(&core->ssr_work); return 0; } @@ -5660,6 +5678,7 @@ void msm_vidc_ssr_handler(struct work_struct *work) int rc; struct msm_vidc_core *core; struct hfi_device *hdev; + struct msm_vidc_ssr *ssr; core = container_of(work, struct msm_vidc_core, ssr_work); if (!core || !core->device) { @@ -5667,10 +5686,11 @@ void msm_vidc_ssr_handler(struct work_struct *work) return; } hdev = core->device; + ssr = &core->ssr; mutex_lock(&core->lock); if (core->state == VIDC_CORE_INIT_DONE) { - d_vpr_e("%s: ssr type %d\n", __func__, core->ssr_type); + d_vpr_e("%s: ssr type %d\n", __func__, ssr->ssr_type); /* * In current implementation user-initiated SSR triggers * a fatal error from hardware. However, there is no way @@ -5679,7 +5699,8 @@ void msm_vidc_ssr_handler(struct work_struct *work) */ core->trigger_ssr = true; rc = call_hfi_op(hdev, core_trigger_ssr, - hdev->hfi_device_data, core->ssr_type); + hdev->hfi_device_data, ssr->ssr_type, + ssr->sub_client_id, ssr->test_addr); if (rc) { d_vpr_e("%s: trigger_ssr failed\n", __func__); core->trigger_ssr = false; diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index 4b0f6090de40..cd69a2ae161a 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -4,7 +4,7 @@ */ #define CREATE_TRACE_POINTS -#define MAX_SSR_STRING_LEN 10 +#define MAX_SSR_STRING_LEN 64 #define MAX_DEBUG_LEVEL_STRING_LEN 15 #include "msm_vidc_debug.h" #include "vidc_hfi_api.h" diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index b54f981e6017..2c1d1c4c7d41 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -467,6 +467,12 @@ struct msm_vidc_core_ops { int (*calc_bw)(struct vidc_bus_vote_data *vidc_data); }; +struct msm_vidc_ssr { + enum hal_ssr_trigger_type ssr_type; + u32 sub_client_id; + u32 test_addr; +}; + struct msm_vidc_core { struct list_head list; struct mutex lock; @@ -485,7 +491,7 @@ struct msm_vidc_core { struct delayed_work fw_unload_work; struct work_struct ssr_work; struct workqueue_struct *vidc_core_workq; - enum hal_ssr_trigger_type ssr_type; + struct msm_vidc_ssr ssr; bool smmu_fault_handled; bool trigger_ssr; unsigned long min_freq; @@ -605,7 +611,7 @@ struct msm_vidc_ctrl { void handle_cmd_response(enum hal_command_response cmd, void *data); int msm_vidc_trigger_ssr(struct msm_vidc_core *core, - enum hal_ssr_trigger_type type); + u64 trigger_ssr_val); int msm_vidc_noc_error_info(struct msm_vidc_core *core); int msm_vidc_check_session_supported(struct msm_vidc_inst *inst); int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst); diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index 29c6c85b699c..9d2ab5d0dfe7 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -282,6 +282,11 @@ struct hfi_hybrid_hierp { u32 layers; }; +struct hfi_ssr_payload { + u32 sub_client_id; + u32 test_addr; +}; + #define HFI_PRIORITY_LOW 10 #define HFI_PRIOIRTY_MEDIUM 20 #define HFI_PRIORITY_HIGH 30 diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 1193b227ca9f..ee86ad85f7be 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -133,6 +133,8 @@ enum hal_ssr_trigger_type { SSR_ERR_FATAL = 1, SSR_SW_DIV_BY_ZERO, SSR_HW_WDOG_IRQ, + SSR_NOC_ERROR, + SSR_VCODEC_HUNG, }; struct hal_profile_level { @@ -634,7 +636,9 @@ struct hfi_device { /*Add function pointers for all the hfi functions below*/ int (*core_init)(void *device); int (*core_release)(void *device); - int (*core_trigger_ssr)(void *device, enum hal_ssr_trigger_type); + int (*core_trigger_ssr)(void *device, + enum hal_ssr_trigger_type ssr_type, u32 sub_client_id, + u32 test_addr); int (*session_init)(void *device, void *inst_id, enum hal_domain session_type, enum hal_video_codec codec_type, void **new_session, u32 sid); diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index 7800ac795a6e..177069932797 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -833,6 +833,8 @@ struct hfi_aspect_ratio { #define HFI_TEST_SSR_SW_ERR_FATAL 0x1 #define HFI_TEST_SSR_SW_DIV_BY_ZERO 0x2 #define HFI_TEST_SSR_HW_WDOG_IRQ 0x3 +#define HFI_TEST_SSR_NOC_ERROR 0x4 +#define HFI_TEST_SSR_VCODEC_HUNG 0x5 struct vidc_hal_cmd_pkt_hdr { u32 size; @@ -1057,6 +1059,7 @@ struct hfi_cmd_sys_test_ssr_packet { u32 size; u32 packet_type; u32 trigger_type; + u32 rg_data[1]; }; struct hfi_hdr10_pq_sei { From 2e034d11ee5300f3686d7ceede5b967b01c9817d Mon Sep 17 00:00:00 2001 From: Ashwini Muduganti Date: Tue, 6 Oct 2020 13:32:42 -0700 Subject: [PATCH 378/452] Revert "msm: vidc: Disable timestamp store-fetch logic" This reverts commit 8f4637a4ac8337abe0d2dcca630d725f418d9201. Signed-off-by: Ashwini Muduganti --- msm/vidc/msm_vidc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 9f2fd2e570c2..cf10f063a732 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -433,7 +433,7 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, timestamp_us = (s64)((b->timestamp.tv_sec * 1000000) + b->timestamp.tv_usec); if (is_decode_session(inst) && b->type == INPUT_MPLANE && - !is_heif_decoder(inst) && !is_secure_session(inst)) { + !is_heif_decoder(inst)) { if (inst->flush_timestamps) msm_comm_release_timestamps(inst); inst->flush_timestamps = false; @@ -515,8 +515,7 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) if (is_decode_session(inst) && b->type == OUTPUT_MPLANE && !(b->flags & V4L2_BUF_FLAG_CODECCONFIG) && - !is_heif_decoder(inst) && - !is_secure_session(inst)) + !is_heif_decoder(inst)) msm_comm_fetch_ts_framerate(inst, b); return rc; From 63b9cfe02d375ac6b27fd657acd1947a55560fbe Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 9 Oct 2020 11:31:59 +0530 Subject: [PATCH 379/452] msm: vidc: enable mark_target and mark_data Currently firmware populates tag_data and produces FBD for all ETB's only if mark_target and mark_data is enabled. So sending dummy value as a WA. Change-Id: I93a80d59e4f0f52eac94391ff86afc341468677f Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_packetization.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/msm/vidc/hfi_packetization.c b/msm/vidc/hfi_packetization.c index 8518dc27018e..345638f86902 100644 --- a/msm/vidc/hfi_packetization.c +++ b/msm/vidc/hfi_packetization.c @@ -469,6 +469,8 @@ int create_pkt_cmd_session_etb_decoder( pkt->time_stamp_hi = upper_32_bits(input_frame->timestamp); pkt->time_stamp_lo = lower_32_bits(input_frame->timestamp); pkt->flags = input_frame->flags; + pkt->mark_target = 0xff; + pkt->mark_data = 0xff; pkt->offset = input_frame->offset; pkt->alloc_len = input_frame->alloc_len; pkt->filled_len = input_frame->filled_len; @@ -504,6 +506,8 @@ int create_pkt_cmd_session_etb_encoder( pkt->time_stamp_hi = upper_32_bits(input_frame->timestamp); pkt->time_stamp_lo = lower_32_bits(input_frame->timestamp); pkt->flags = input_frame->flags; + pkt->mark_target = 0xff; + pkt->mark_data = 0xff; pkt->offset = input_frame->offset; pkt->alloc_len = input_frame->alloc_len; pkt->filled_len = input_frame->filled_len; From 48957371a423e5c729423bd20f92574ce58686e5 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Mon, 5 Oct 2020 23:24:09 +0530 Subject: [PATCH 380/452] msm: venc: fix the VUI timing info The timing info should represent the number of time units in one seconds, as per the timescale and time units per tick. Update the same while setting the HFI to video firmware. Change-Id: Ifb6bc34ad295e472715fb72813a236c851d4480f Signed-off-by: Vikash Garodia --- msm/vidc/msm_venc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 5277fb34ca6a..9c603016add0 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -4199,7 +4199,7 @@ int msm_venc_set_vui_timing_info(struct msm_vidc_inst *inst) timing_info.enable = 1; timing_info.fixed_frame_rate = cfr; - timing_info.time_scale = NSEC_PER_SEC; + timing_info.time_scale = (inst->clk_data.frame_rate >> 16) * USEC_PER_SEC; s_vpr_h(inst->sid, "%s: %d %d\n", __func__, timing_info.enable, timing_info.fixed_frame_rate); From 17ef44847b321a1bf858023fa7979ddc22cc1bac Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Thu, 1 Oct 2020 16:32:22 +0530 Subject: [PATCH 381/452] msm-vidc: fix final BW voting to ICC Currently, Required BW is calculated in bytes per second but when setting it to ICC, kbps_to_icc macro is applied to calculated BW which again divides the value by 8 and resulting into less final vote to icc. Change-Id: I7a645478d05909308edea2170d7c5cb911cbf6f0 Signed-off-by: Dikshita Agarwal --- msm/vidc/hfi_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index bbb48a5120de..ba8106a16d1b 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -888,7 +888,7 @@ static int __vote_bandwidth(struct bus_info *bus, int rc = 0; s_vpr_p(sid, "Voting bus %s to ab %llu kbps\n", bus->name, bw_kbps); - rc = icc_set_bw(bus->path, kbps_to_icc(bw_kbps), 0); + rc = icc_set_bw(bus->path, bw_kbps, 0); if (rc) s_vpr_e(sid, "Failed voting bus %s to ab %llu, rc=%d\n", bus->name, bw_kbps, rc); From cbfcd83f512c4d1fd0cfc3e10a5fed5bf5249602 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 14 Oct 2020 19:38:41 +0530 Subject: [PATCH 382/452] msm: vidc: Update enc scratch2 buffer size calc Consider downscaling buffer size with unrotated wxh when rotation or flip is enabled along with downscaling. Also correct wxh to all buffer calc if rotation is enabled. Change-Id: I5b89a5206057c4bbfed793b439aa2fb2c5d2601e Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_venc.c | 20 ---------- msm/vidc/msm_vidc_buffer_calculations.c | 53 ++++++++++++++++++++----- msm/vidc/msm_vidc_buffer_calculations.h | 3 +- msm/vidc/msm_vidc_common.c | 19 +++++++++ msm/vidc/msm_vidc_common.h | 1 + 5 files changed, 64 insertions(+), 32 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 9c603016add0..5bcbfe2cfbf2 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1139,26 +1139,6 @@ u32 v4l2_to_hfi_flip(struct msm_vidc_inst *inst) return flip; } -inline bool vidc_scalar_enabled(struct msm_vidc_inst *inst) -{ - struct v4l2_format *f; - u32 output_height, output_width, input_height, input_width; - bool scalar_enable = false; - - f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; - output_height = f->fmt.pix_mp.height; - output_width = f->fmt.pix_mp.width; - f = &inst->fmts[INPUT_PORT].v4l2_fmt; - input_height = f->fmt.pix_mp.height; - input_width = f->fmt.pix_mp.width; - - if (output_height != input_height || output_width != input_width) - scalar_enable = true; - - return scalar_enable; -} - - static int msm_venc_set_csc(struct msm_vidc_inst *inst, u32 color_primaries, u32 custom_matrix); diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 45e75a527235..4797b0bcad43 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -319,7 +319,8 @@ static inline u32 calculate_vp8e_scratch1_size(struct msm_vidc_inst *inst, u32 width, u32 height, u32 num_ref, bool ten_bit, u32 num_vpp_pipes); static inline u32 calculate_enc_scratch2_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 num_ref, bool ten_bit); + u32 width, u32 height, u32 num_ref, bool ten_bit, bool downscale, + u32 rotation_val, u32 flip); static inline u32 calculate_enc_persist_size(void); @@ -516,9 +517,10 @@ int msm_vidc_get_encoder_internal_buffer_sizes(struct msm_vidc_inst *inst) { struct msm_vidc_enc_buff_size_calculators *enc_calculators; u32 width, height, i, num_ref, num_vpp_pipes; - bool is_tenbit = false; + u32 rotation_val = 0, flip = 0; + bool is_tenbit = false, is_downscale = false; int num_bframes; - struct v4l2_ctrl *bframe; + struct v4l2_ctrl *bframe, *rotation, *hflip, *vflip; struct v4l2_format *f; if (!inst || !inst->core || !inst->core->platform_data) { @@ -545,18 +547,30 @@ int msm_vidc_get_encoder_internal_buffer_sizes(struct msm_vidc_inst *inst) return -EINVAL; } - f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; - width = f->fmt.pix_mp.width; - height = f->fmt.pix_mp.height; bframe = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); num_bframes = bframe->val; if (num_bframes < 0) { s_vpr_e(inst->sid, "%s: get num bframe failed\n", __func__); return -EINVAL; } + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + rotation = get_ctrl(inst, V4L2_CID_ROTATE); + rotation_val = rotation->val; + if (rotation_val == 90 || rotation_val == 270) { + /* Internal buffer size calculators are based on rotated w x h */ + width = f->fmt.pix_mp.height; + height = f->fmt.pix_mp.width; + } else { + width = f->fmt.pix_mp.width; + height = f->fmt.pix_mp.height; + } + hflip = get_ctrl(inst, V4L2_CID_HFLIP); + vflip = get_ctrl(inst, V4L2_CID_VFLIP); + flip = hflip->val | vflip->val; num_ref = msm_vidc_get_num_ref_frames(inst); is_tenbit = (inst->bit_depth == MSM_VIDC_BIT_DEPTH_10); + is_downscale = vidc_scalar_enabled(inst); for (i = 0; i < HAL_BUFFER_MAX; i++) { struct hal_buffer_requirements *curr_req; @@ -582,7 +596,7 @@ int msm_vidc_get_encoder_internal_buffer_sizes(struct msm_vidc_inst *inst) curr_req->buffer_size = enc_calculators->calculate_scratch2_size( inst, width, height, num_ref, - is_tenbit); + is_tenbit, is_downscale, rotation_val, flip); valid_buffer_type = true; } else if (curr_req->buffer_type == HAL_BUFFER_INTERNAL_PERSIST) { @@ -1792,8 +1806,8 @@ static inline u32 hfi_ubwc_uv_metadata_plane_bufheight(u32 height, tile_height_pels), metadata_height_multi); } -static inline u32 calculate_enc_scratch2_size(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 num_ref, bool ten_bit) +static inline u32 hfi_iris2_enc_dpb_buffer_size(u32 width, u32 height, + bool ten_bit) { u32 aligned_width, aligned_height, chroma_height, ref_buf_height; u32 luma_size, chroma_size; @@ -1818,7 +1832,6 @@ static inline u32 calculate_enc_scratch2_size(struct msm_vidc_inst *inst, metadata_stride, meta_buf_height); size = (aligned_height + chroma_height) * aligned_width + meta_size_y + meta_size_c; - size = (size * (num_ref + 2)) + 4096; } else { ref_buf_height = (height + (HFI_VENUS_HEIGHT_ALIGNMENT - 1)) & (~(HFI_VENUS_HEIGHT_ALIGNMENT - 1)); @@ -1851,7 +1864,25 @@ static inline u32 calculate_enc_scratch2_size(struct msm_vidc_inst *inst, meta_size_c = hfi_ubwc_metadata_plane_buffer_size( metadata_stride, meta_buf_height); size = ref_buf_size + meta_size_y + meta_size_c; - size = (size * (num_ref + 2)) + 4096; + } + return size; +} + +static inline u32 calculate_enc_scratch2_size(struct msm_vidc_inst *inst, + u32 width, u32 height, u32 num_ref, bool ten_bit, bool downscale, + u32 rotation_val, u32 flip) +{ + u32 size; + + size = hfi_iris2_enc_dpb_buffer_size(width, height, ten_bit); + size = size * (num_ref + 1) + 4096; + if (downscale && (rotation_val || flip)) { + /* VPSS output is always 128 x 32 (8-bit) or 192 x 16 (10-bit) aligned */ + if (rotation_val == 90 || rotation_val == 270) + size += hfi_iris2_enc_dpb_buffer_size(height, width, ten_bit); + else + size += hfi_iris2_enc_dpb_buffer_size(width, height, ten_bit); + size += 4096; } return size; } diff --git a/msm/vidc/msm_vidc_buffer_calculations.h b/msm/vidc/msm_vidc_buffer_calculations.h index e890db526660..e172201ec261 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.h +++ b/msm/vidc/msm_vidc_buffer_calculations.h @@ -26,7 +26,8 @@ struct msm_vidc_enc_buff_size_calculators { u32 width, u32 height, u32 num_ref, bool ten_bit, u32 num_vpp_pipes); u32 (*calculate_scratch2_size)(struct msm_vidc_inst *inst, - u32 width, u32 height, u32 num_ref, bool ten_bit); + u32 width, u32 height, u32 num_ref, bool ten_bit, bool downscale, + u32 rotation_val, u32 flip); u32 (*calculate_persist_size)(void); }; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 4c71d3512441..863af1e82c6d 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -662,6 +662,25 @@ enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst) return HAL_VIDEO_DECODER_PRIMARY; } +bool vidc_scalar_enabled(struct msm_vidc_inst *inst) +{ + struct v4l2_format *f; + u32 output_height, output_width, input_height, input_width; + bool scalar_enable = false; + + f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + output_height = f->fmt.pix_mp.height; + output_width = f->fmt.pix_mp.width; + f = &inst->fmts[INPUT_PORT].v4l2_fmt; + input_height = f->fmt.pix_mp.height; + input_width = f->fmt.pix_mp.width; + + if (output_height != input_height || output_width != input_width) + scalar_enable = true; + + return scalar_enable; +} + bool is_single_session(struct msm_vidc_inst *inst, u32 ignore_flags) { bool single = true; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 779f0c8cbf96..ae8467cd8da3 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -266,6 +266,7 @@ static inline int msm_comm_s_ctrl(struct msm_vidc_inst *inst, return v4l2_s_ctrl(NULL, &inst->ctrl_handler, ctrl); } +bool vidc_scalar_enabled(struct msm_vidc_inst *inst); bool is_single_session(struct msm_vidc_inst *inst, u32 ignore_flags); bool is_batching_allowed(struct msm_vidc_inst *inst); enum hal_buffer get_hal_buffer_type(unsigned int type, From 6090ef6b025e45b13370038ab6dacf5729a3f36e Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Mon, 21 Sep 2020 14:07:57 +0800 Subject: [PATCH 383/452] msm: venc: distinguish client frame rate handling from auto detection of frame rate By default, encoder needs to enable VUI timing info. Frame rate change triggers new header and timing info. Hence, we need to distinguish client trigger fps change vs auto detection of fps change. Introduced new HFI for setting auto detection of fps. In auto fps case, VUI timing is not re-generated. Change-Id: I6b579d1e6ef0c49a849b7b7e0383f593a949bab3 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_venc.c | 19 +++++++++++++------ msm/vidc/msm_venc.h | 2 +- msm/vidc/vidc_hfi_helper.h | 2 ++ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 9c603016add0..2a2aadb37868 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1672,7 +1672,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) if (inst->state < MSM_VIDC_LOAD_RESOURCES) msm_vidc_calculate_buffer_counts(inst); if (inst->state == MSM_VIDC_START_DONE) { - rc = msm_venc_set_frame_rate(inst); + rc = msm_venc_set_frame_rate(inst, true); if (rc) s_vpr_e(sid, "%s: set frame rate failed\n", __func__); @@ -2095,7 +2095,7 @@ int msm_venc_set_frame_size(struct msm_vidc_inst *inst) return rc; } -int msm_venc_set_frame_rate(struct msm_vidc_inst *inst) +int msm_venc_set_frame_rate(struct msm_vidc_inst *inst, bool external_requested) { int rc = 0; struct hfi_device *hdev; @@ -2128,9 +2128,16 @@ int msm_venc_set_frame_rate(struct msm_vidc_inst *inst) s_vpr_h(inst->sid, "%s: %#x\n", __func__, frame_rate.frame_rate); - rc = call_hfi_op(hdev, session_set_property, - inst->session, HFI_PROPERTY_CONFIG_FRAME_RATE, + if (external_requested) { + rc = call_hfi_op(hdev, session_set_property, + inst->session, HFI_PROPERTY_CONFIG_FRAME_RATE, + &frame_rate, sizeof(frame_rate)); + } else { + s_vpr_l(inst->sid, "Auto frame rate set"); + rc = call_hfi_op(hdev, session_set_property, + inst->session, HFI_PROPERTY_CONFIG_VENC_AUTO_FRAME_RATE, &frame_rate, sizeof(frame_rate)); + } if (rc) s_vpr_e(inst->sid, "%s: set property failed\n", __func__); @@ -2202,7 +2209,7 @@ int msm_venc_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) inst->clk_data.frame_rate = entry->framerate; s_vpr_l(inst->sid, "%s: updated fps to %u\n", __func__, (inst->clk_data.frame_rate >> 16)); - msm_venc_set_frame_rate(inst); + msm_venc_set_frame_rate(inst, false); } unlock: @@ -4910,7 +4917,7 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) rc = msm_venc_set_frame_size(inst); if (rc) goto exit; - rc = msm_venc_set_frame_rate(inst); + rc = msm_venc_set_frame_rate(inst, true); if (rc) goto exit; rc = msm_venc_set_secure_mode(inst); diff --git a/msm/vidc/msm_venc.h b/msm/vidc/msm_venc.h index e172bf748336..ac3f38a829ff 100644 --- a/msm/vidc/msm_venc.h +++ b/msm/vidc/msm_venc.h @@ -23,7 +23,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl); int msm_venc_set_properties(struct msm_vidc_inst *inst); int msm_venc_set_extradata(struct msm_vidc_inst *inst); -int msm_venc_set_frame_rate(struct msm_vidc_inst *inst); +int msm_venc_set_frame_rate(struct msm_vidc_inst *inst, bool external_requested); int msm_venc_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us); int msm_venc_set_bitrate(struct msm_vidc_inst *inst); int msm_venc_set_layer_bitrate(struct msm_vidc_inst *inst); diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index 177069932797..bf1d55a4f1ea 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -379,6 +379,8 @@ struct hfi_buffer_info { (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x015) #define HFI_PROPERTY_CONFIG_CVP_SKIP_RATIO \ (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x016) +#define HFI_PROPERTY_CONFIG_VENC_AUTO_FRAME_RATE \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x017) #define HFI_PROPERTY_PARAM_VPE_COMMON_START \ (HFI_DOMAIN_BASE_VPE + HFI_ARCH_COMMON_OFFSET + 0x7000) From e2f86b092aa9837714a9efc3004eed226890f1d6 Mon Sep 17 00:00:00 2001 From: Chandrakant I Viraktamath Date: Fri, 16 Oct 2020 17:36:18 +0530 Subject: [PATCH 384/452] msm: vidc: fix ts reorder for heif Fix logic for ts reorder in heif decoder since default value of disable timestamp reorder control is 0. Change-Id: I56cb8c40d99c3a3de867da659005faebd201be80 Signed-off-by: Chandrakant I Viraktamath --- msm/vidc/msm_vidc_common.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 779f0c8cbf96..5340ff8e1bcf 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -169,8 +169,8 @@ static inline bool is_ts_reorder_allowed(struct msm_vidc_inst *inst) if (inst->session_type != MSM_VIDC_DECODER) return true; - if (!is_heif_decoder(inst)) - return true; + if (is_heif_decoder(inst)) + return false; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_DISABLE_TIMESTAMP_REORDER); From cbbf49a6e1f9b01d65cc3abcfd775cf57ec011f8 Mon Sep 17 00:00:00 2001 From: Brijesh Patel Date: Sat, 10 Oct 2020 02:38:19 +0530 Subject: [PATCH 385/452] msm: vidc: Avoid dma_buf memory leak under memory pressure dma_buf_put does not happen in case of failure while mapping dma_buf. This leads to ion_dma_buf leak as refcount is 1 even after session close. In memory pressure scenario while running concurrency usecase such scenario can occur. Change-Id: I2084538162b54d87acd6fa57bb5cc5bd2096c08d Signed-off-by: Brijesh Patel --- msm/vidc/msm_smem.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_smem.c b/msm/vidc/msm_smem.c index 4688aa9717a3..4d3454ebc46b 100644 --- a/msm/vidc/msm_smem.c +++ b/msm/vidc/msm_smem.c @@ -216,7 +216,7 @@ int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) rc = dma_buf_get_flags(dbuf, &ion_flags); if (rc) { s_vpr_e(inst->sid, "Failed to get dma buf flags: %d\n", rc); - goto exit; + goto fail_map_dma_buf; } if (ion_flags & ION_FLAG_CACHED) smem->flags |= SMEM_CACHED; @@ -230,7 +230,7 @@ int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) smem->flags & SMEM_SECURE ? "secure" : "non-secure", inst->flags & VIDC_SECURE ? "secure" : "non-secure"); rc = -EINVAL; - goto exit; + goto fail_map_dma_buf; } buffer_size = smem->size; @@ -240,18 +240,25 @@ int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) inst->sid); if (rc) { s_vpr_e(inst->sid, "Failed to get device address: %d\n", rc); - goto exit; + goto fail_map_dma_buf; } temp = (u32)iova; if ((dma_addr_t)temp != iova) { s_vpr_e(inst->sid, "iova(%pa) truncated to %#x", &iova, temp); rc = -EINVAL; - goto exit; + goto fail_iova_truncation; } smem->device_addr = (u32)iova + smem->offset; smem->refcount++; + return 0; + +fail_iova_truncation: + msm_dma_put_device_address(smem->flags, &smem->mapping_info, + smem->buffer_type, inst->sid); +fail_map_dma_buf: + msm_smem_put_dma_buf(dbuf, inst->sid); exit: return rc; } From 8a3082af38f7ce1479637f2e18c72b3a3874f665 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 19 Oct 2020 15:18:35 +0530 Subject: [PATCH 386/452] msm: vidc: raise interrupt for encode batching usecase HFR recording usecases, batch mode is enabled by default. Currently no interrupt is raised to firmware for ETB write on command queue. So firmware was not reading the queue, though there are lot of pending messages in the command queue, So complete encoder pipeline is getting stalled after encoding couple of frames. To avoid above problem, raising interrupt to firmware every time(Only for last ETB in the batch). Change-Id: If584a8175bfa54402087d1888dd032d08e1f3c15 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_common.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index ac95cff157a9..d08e240cfce3 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -2294,6 +2294,7 @@ static int venus_hfi_session_process_batch(void *sess, int rc = 0, c = 0; struct hal_session *session = sess; struct venus_hfi_device *device = &venus_hfi_dev; + bool is_last_frame = false; mutex_lock(&device->lock); @@ -2303,7 +2304,8 @@ static int venus_hfi_session_process_batch(void *sess, } for (c = 0; c < num_ftbs; ++c) { - rc = __session_ftb(session, &ftbs[c], true); + is_last_frame = (c + 1 == num_ftbs); + rc = __session_ftb(session, &ftbs[c], !is_last_frame); if (rc) { s_vpr_e(session->sid, "Failed to queue batched ftb: %d\n", rc); @@ -2312,7 +2314,8 @@ static int venus_hfi_session_process_batch(void *sess, } for (c = 0; c < num_etbs; ++c) { - rc = __session_etb(session, &etbs[c], true); + is_last_frame = (c + 1 == num_etbs); + rc = __session_etb(session, &etbs[c], !is_last_frame); if (rc) { s_vpr_e(session->sid, "Failed to queue batched etb: %d\n", rc); From cb416629211fb4688438d1ef9d393a1da1668fd0 Mon Sep 17 00:00:00 2001 From: Malathi Gottam Date: Thu, 15 Oct 2020 16:33:27 +0530 Subject: [PATCH 387/452] msm: vidc: allocate max input buffer size for specific video hardware For certain video hardware which doesn't support higher resolutions like 4k or above, allocate maximum input buffer size Change-Id: I30a908573cf4d0dce8bcbaeb813913130f051884 Signed-off-by: Malathi Gottam --- msm/vidc/msm_vidc_buffer_calculations.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 4797b0bcad43..3dea060b692b 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -910,7 +910,7 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) * For targets that doesn't support 4k, consider max mb's for that * target and allocate max input buffer size for the same */ - if (base_res_mbs > inst->capability.cap[CAP_MBS_PER_FRAME].max) { + if (inst->core->platform_data->vpu_ver == VPU_VERSION_AR50_LITE) { base_res_mbs = inst->capability.cap[CAP_MBS_PER_FRAME].max; div_factor = 1; } From 2c0ee3a2b6881a4ca30ab8d79b4f4e5e40a7c681 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 19 Oct 2020 20:27:05 +0530 Subject: [PATCH 388/452] msm: vidc: tune input buffer size based on buffer_size_limit Codec2 HAL sets V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT for all session and it is very low value. So decoder input buffer size is always limited by buffer_size_limit. Memory budget estimation is going for toss in msm_comm_check_memory_supported. So video driver started allowing all sessions during concurrency run without any restriction. Added change to use correct buffer size during memory estimation. Change-Id: Ic7c5e51a91615fdba8965b3a359c2d3a37c9a14b Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vdec.c | 6 +++--- msm/vidc/msm_vidc_buffer_calculations.c | 7 +++---- msm/vidc/msm_vidc_buffer_calculations.h | 3 ++- msm/vidc/msm_vidc_common.c | 16 +++++++++++++--- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index bb69dede610c..7d4b1de3b252 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -685,7 +685,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) } mplane->plane_fmt[0].sizeimage = - msm_vidc_calculate_dec_input_frame_size(inst); + msm_vidc_calculate_dec_input_frame_size(inst, inst->buffer_size_limit); /* Driver can recalculate buffer count only for * only for bitstream port. Decoder YUV port reconfig @@ -733,7 +733,7 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) } else if (f->type == INPUT_MPLANE) { fmt = &inst->fmts[INPUT_PORT].v4l2_fmt; fmt->fmt.pix_mp.plane_fmt[0].sizeimage = - msm_vidc_calculate_dec_input_frame_size(inst); + msm_vidc_calculate_dec_input_frame_size(inst, inst->buffer_size_limit); memcpy(f, fmt, sizeof(struct v4l2_format)); } else { s_vpr_e(inst->sid, "%s: Unsupported buf type: %d\n", @@ -817,7 +817,7 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; f->fmt.pix_mp.num_planes = 1; f->fmt.pix_mp.plane_fmt[0].sizeimage = - msm_vidc_calculate_dec_input_frame_size(inst); + msm_vidc_calculate_dec_input_frame_size(inst, inst->buffer_size_limit); fmt_desc = msm_comm_get_pixel_fmt_fourcc(vdec_input_formats, ARRAY_SIZE(vdec_input_formats), f->fmt.pix_mp.pixelformat, inst->sid); diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 4797b0bcad43..d529685d8d1c 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -876,7 +876,7 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) return extra_output_count; } -u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) +u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst, u32 buffer_size_limit) { u32 frame_size, num_mbs; u32 div_factor = 1; @@ -928,9 +928,8 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) inst->core->platform_data->vpu_ver != VPU_VERSION_AR50_LITE) frame_size = frame_size + (frame_size >> 2); - if (inst->buffer_size_limit && - (inst->buffer_size_limit < frame_size)) { - frame_size = inst->buffer_size_limit; + if (buffer_size_limit && (buffer_size_limit < frame_size)) { + frame_size = buffer_size_limit; s_vpr_h(inst->sid, "input buffer size limited to %d\n", frame_size); } else { diff --git a/msm/vidc/msm_vidc_buffer_calculations.h b/msm/vidc/msm_vidc_buffer_calculations.h index e172201ec261..043199854830 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.h +++ b/msm/vidc/msm_vidc_buffer_calculations.h @@ -37,7 +37,8 @@ int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst); int msm_vidc_calculate_buffer_counts(struct msm_vidc_inst *inst); int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, enum hal_buffer buffer_type); -u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst); +u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst, + u32 buffer_size_limit); u32 msm_vidc_calculate_dec_output_frame_size(struct msm_vidc_inst *inst); u32 msm_vidc_calculate_dec_output_extra_size(struct msm_vidc_inst *inst); u32 msm_vidc_calculate_enc_input_frame_size(struct msm_vidc_inst *inst); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 863af1e82c6d..45f303aa2cf4 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -3351,7 +3351,10 @@ static void msm_comm_print_mem_usage(struct msm_vidc_core *core) break; } } - sz_i = iplane->plane_fmt[0].sizeimage; + if (is_decode_session(inst)) + sz_i = msm_vidc_calculate_dec_input_frame_size(inst, 0); + else + sz_i = iplane->plane_fmt[0].sizeimage; sz_i_e = iplane->plane_fmt[1].sizeimage; cnt_i = inp_f->count_min_host; @@ -5802,7 +5805,7 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst) struct v4l2_format *f; struct hal_buffer_requirements *req; struct context_bank_info *cb = NULL; - u32 i, dpb_cnt = 0, dpb_size = 0, rc = 0; + u32 i, dpb_cnt = 0, dpb_size = 0, input_size = 1, rc = 0; u32 inst_mem_size, non_sec_cb_size = 0; u64 total_mem_size = 0, non_sec_mem_size = 0; u32 memory_limit_mbytes; @@ -5812,10 +5815,17 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst) mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { inst_mem_size = 0; + input_size = 1; /* input port buffers memory size */ fmt = &inst->fmts[INPUT_PORT]; f = &fmt->v4l2_fmt; - for (i = 0; i < f->fmt.pix_mp.num_planes; i++) + if (is_decode_session(inst)) + input_size = msm_vidc_calculate_dec_input_frame_size(inst, 0); + else + input_size = f->fmt.pix_mp.plane_fmt[0].sizeimage; + inst_mem_size += input_size * fmt->count_min_host; + + for (i = 1; i < f->fmt.pix_mp.num_planes; i++) inst_mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage * fmt->count_min_host; From fbaf79c21fd8412f9774a61cdf0dd41a85d9ed1e Mon Sep 17 00:00:00 2001 From: Ashwini Muduganti Date: Tue, 20 Oct 2020 21:57:02 -0700 Subject: [PATCH 389/452] Revert "msm-vidc: fix final BW voting to ICC" This reverts commit 17ef44847b321a1bf858023fa7979ddc22cc1bac. --- msm/vidc/hfi_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index ba8106a16d1b..bbb48a5120de 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -888,7 +888,7 @@ static int __vote_bandwidth(struct bus_info *bus, int rc = 0; s_vpr_p(sid, "Voting bus %s to ab %llu kbps\n", bus->name, bw_kbps); - rc = icc_set_bw(bus->path, bw_kbps, 0); + rc = icc_set_bw(bus->path, kbps_to_icc(bw_kbps), 0); if (rc) s_vpr_e(sid, "Failed voting bus %s to ab %llu, rc=%d\n", bus->name, bw_kbps, rc); From bbb37a48685a03af92d608d1108f3ff7d0d871de Mon Sep 17 00:00:00 2001 From: Brijesh Patel Date: Sat, 10 Oct 2020 02:38:19 +0530 Subject: [PATCH 390/452] msm: vidc: Avoid dma_buf memory leak under memory pressure dma_buf_put does not happen in case of failure while mapping dma_buf. This leads to ion_dma_buf leak as refcount is 1 even after session close. In memory pressure scenario while running concurrency usecase such scenario can occur. Change-Id: I2084538162b54d87acd6fa57bb5cc5bd2096c08d Signed-off-by: Brijesh Patel --- msm/vidc/msm_smem.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_smem.c b/msm/vidc/msm_smem.c index 4688aa9717a3..4d3454ebc46b 100644 --- a/msm/vidc/msm_smem.c +++ b/msm/vidc/msm_smem.c @@ -216,7 +216,7 @@ int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) rc = dma_buf_get_flags(dbuf, &ion_flags); if (rc) { s_vpr_e(inst->sid, "Failed to get dma buf flags: %d\n", rc); - goto exit; + goto fail_map_dma_buf; } if (ion_flags & ION_FLAG_CACHED) smem->flags |= SMEM_CACHED; @@ -230,7 +230,7 @@ int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) smem->flags & SMEM_SECURE ? "secure" : "non-secure", inst->flags & VIDC_SECURE ? "secure" : "non-secure"); rc = -EINVAL; - goto exit; + goto fail_map_dma_buf; } buffer_size = smem->size; @@ -240,18 +240,25 @@ int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem) inst->sid); if (rc) { s_vpr_e(inst->sid, "Failed to get device address: %d\n", rc); - goto exit; + goto fail_map_dma_buf; } temp = (u32)iova; if ((dma_addr_t)temp != iova) { s_vpr_e(inst->sid, "iova(%pa) truncated to %#x", &iova, temp); rc = -EINVAL; - goto exit; + goto fail_iova_truncation; } smem->device_addr = (u32)iova + smem->offset; smem->refcount++; + return 0; + +fail_iova_truncation: + msm_dma_put_device_address(smem->flags, &smem->mapping_info, + smem->buffer_type, inst->sid); +fail_map_dma_buf: + msm_smem_put_dma_buf(dbuf, inst->sid); exit: return rc; } From ad3fef369895a69cd1d3dfc39420fb5a94d80757 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 19 Oct 2020 15:18:35 +0530 Subject: [PATCH 391/452] msm: vidc: raise interrupt for encode batching usecase HFR recording usecases, batch mode is enabled by default. Currently no interrupt is raised to firmware for ETB write on command queue. So firmware was not reading the queue, though there are lot of pending messages in the command queue, So complete encoder pipeline is getting stalled after encoding couple of frames. To avoid above problem, raising interrupt to firmware every time(Only for last ETB in the batch). Change-Id: If584a8175bfa54402087d1888dd032d08e1f3c15 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_common.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index ac95cff157a9..d08e240cfce3 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -2294,6 +2294,7 @@ static int venus_hfi_session_process_batch(void *sess, int rc = 0, c = 0; struct hal_session *session = sess; struct venus_hfi_device *device = &venus_hfi_dev; + bool is_last_frame = false; mutex_lock(&device->lock); @@ -2303,7 +2304,8 @@ static int venus_hfi_session_process_batch(void *sess, } for (c = 0; c < num_ftbs; ++c) { - rc = __session_ftb(session, &ftbs[c], true); + is_last_frame = (c + 1 == num_ftbs); + rc = __session_ftb(session, &ftbs[c], !is_last_frame); if (rc) { s_vpr_e(session->sid, "Failed to queue batched ftb: %d\n", rc); @@ -2312,7 +2314,8 @@ static int venus_hfi_session_process_batch(void *sess, } for (c = 0; c < num_etbs; ++c) { - rc = __session_etb(session, &etbs[c], true); + is_last_frame = (c + 1 == num_etbs); + rc = __session_etb(session, &etbs[c], !is_last_frame); if (rc) { s_vpr_e(session->sid, "Failed to queue batched etb: %d\n", rc); From 5a0dcb5bae8c03b5a38b82d603c4cc895b19b189 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 19 Oct 2020 20:27:05 +0530 Subject: [PATCH 392/452] msm: vidc: tune input buffer size based on buffer_size_limit Codec2 HAL sets V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT for all session and it is very low value. So decoder input buffer size is always limited by buffer_size_limit. Memory budget estimation is going for toss in msm_comm_check_memory_supported. So video driver started allowing all sessions during concurrency run without any restriction. Added change to use correct buffer size during memory estimation. Change-Id: Ic7c5e51a91615fdba8965b3a359c2d3a37c9a14b Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vdec.c | 6 +++--- msm/vidc/msm_vidc_buffer_calculations.c | 7 +++---- msm/vidc/msm_vidc_buffer_calculations.h | 3 ++- msm/vidc/msm_vidc_common.c | 16 +++++++++++++--- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index bb69dede610c..7d4b1de3b252 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -685,7 +685,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) } mplane->plane_fmt[0].sizeimage = - msm_vidc_calculate_dec_input_frame_size(inst); + msm_vidc_calculate_dec_input_frame_size(inst, inst->buffer_size_limit); /* Driver can recalculate buffer count only for * only for bitstream port. Decoder YUV port reconfig @@ -733,7 +733,7 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) } else if (f->type == INPUT_MPLANE) { fmt = &inst->fmts[INPUT_PORT].v4l2_fmt; fmt->fmt.pix_mp.plane_fmt[0].sizeimage = - msm_vidc_calculate_dec_input_frame_size(inst); + msm_vidc_calculate_dec_input_frame_size(inst, inst->buffer_size_limit); memcpy(f, fmt, sizeof(struct v4l2_format)); } else { s_vpr_e(inst->sid, "%s: Unsupported buf type: %d\n", @@ -817,7 +817,7 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; f->fmt.pix_mp.num_planes = 1; f->fmt.pix_mp.plane_fmt[0].sizeimage = - msm_vidc_calculate_dec_input_frame_size(inst); + msm_vidc_calculate_dec_input_frame_size(inst, inst->buffer_size_limit); fmt_desc = msm_comm_get_pixel_fmt_fourcc(vdec_input_formats, ARRAY_SIZE(vdec_input_formats), f->fmt.pix_mp.pixelformat, inst->sid); diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 45e75a527235..ae233546846f 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -862,7 +862,7 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) return extra_output_count; } -u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) +u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst, u32 buffer_size_limit) { u32 frame_size, num_mbs; u32 div_factor = 1; @@ -914,9 +914,8 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) inst->core->platform_data->vpu_ver != VPU_VERSION_AR50_LITE) frame_size = frame_size + (frame_size >> 2); - if (inst->buffer_size_limit && - (inst->buffer_size_limit < frame_size)) { - frame_size = inst->buffer_size_limit; + if (buffer_size_limit && (buffer_size_limit < frame_size)) { + frame_size = buffer_size_limit; s_vpr_h(inst->sid, "input buffer size limited to %d\n", frame_size); } else { diff --git a/msm/vidc/msm_vidc_buffer_calculations.h b/msm/vidc/msm_vidc_buffer_calculations.h index e890db526660..a4d27a696dad 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.h +++ b/msm/vidc/msm_vidc_buffer_calculations.h @@ -36,7 +36,8 @@ int msm_vidc_calculate_output_buffer_count(struct msm_vidc_inst *inst); int msm_vidc_calculate_buffer_counts(struct msm_vidc_inst *inst); int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst, enum hal_buffer buffer_type); -u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst); +u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst, + u32 buffer_size_limit); u32 msm_vidc_calculate_dec_output_frame_size(struct msm_vidc_inst *inst); u32 msm_vidc_calculate_dec_output_extra_size(struct msm_vidc_inst *inst); u32 msm_vidc_calculate_enc_input_frame_size(struct msm_vidc_inst *inst); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 4c71d3512441..b01fe32fcbdc 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -3332,7 +3332,10 @@ static void msm_comm_print_mem_usage(struct msm_vidc_core *core) break; } } - sz_i = iplane->plane_fmt[0].sizeimage; + if (is_decode_session(inst)) + sz_i = msm_vidc_calculate_dec_input_frame_size(inst, 0); + else + sz_i = iplane->plane_fmt[0].sizeimage; sz_i_e = iplane->plane_fmt[1].sizeimage; cnt_i = inp_f->count_min_host; @@ -5783,7 +5786,7 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst) struct v4l2_format *f; struct hal_buffer_requirements *req; struct context_bank_info *cb = NULL; - u32 i, dpb_cnt = 0, dpb_size = 0, rc = 0; + u32 i, dpb_cnt = 0, dpb_size = 0, input_size = 1, rc = 0; u32 inst_mem_size, non_sec_cb_size = 0; u64 total_mem_size = 0, non_sec_mem_size = 0; u32 memory_limit_mbytes; @@ -5793,10 +5796,17 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst) mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { inst_mem_size = 0; + input_size = 1; /* input port buffers memory size */ fmt = &inst->fmts[INPUT_PORT]; f = &fmt->v4l2_fmt; - for (i = 0; i < f->fmt.pix_mp.num_planes; i++) + if (is_decode_session(inst)) + input_size = msm_vidc_calculate_dec_input_frame_size(inst, 0); + else + input_size = f->fmt.pix_mp.plane_fmt[0].sizeimage; + inst_mem_size += input_size * fmt->count_min_host; + + for (i = 1; i < f->fmt.pix_mp.num_planes; i++) inst_mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage * fmt->count_min_host; From 50adf52c82afb95fd96b93dc16b5743a1b6e8d86 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Mon, 26 Oct 2020 09:27:12 -0700 Subject: [PATCH 393/452] msm: vidc: Increase vpp cycles for 960fps use case Increase vpp cycles to bump frequency to 366MHz for encoder 960fps use case. Change-Id: If0f9d0f084dfcefa9f8614ec6774588dec6b7007 Signed-off-by: Mihir Ganu --- msm/vidc/msm_vidc_clocks.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 1442128a27d4..4185500e5bdd 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -726,6 +726,13 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, if (fps == 480) vpp_cycles += div_u64(vpp_cycles * 2, 100); + /* + * Add 5 percent extra for 720p@960fps use case + * to bump it to next level (366MHz). + */ + if (fps == 960) + vpp_cycles += div_u64(vpp_cycles * 5, 100); + /* VSP */ /* bitrate is based on fps, scale it using operating rate */ operating_rate = inst->clk_data.operating_rate >> 16; From 4b02c344e1fadf38322287c1d359ffdeafc22d31 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Tue, 27 Oct 2020 18:25:27 +0530 Subject: [PATCH 394/452] msm: vidc: resolve use-after-free problem msm_vidc_open() failure is freeing the inst structure which might have been under use by other threads and hence use kref_put instead of kfree instance in msm_vidc_open() to resolve use-after-free problem. Change-Id: I611aa6347da6c884345890153c7f7e4525a4307c Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index e9fe48f72943..be9034418f9f 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1476,6 +1476,14 @@ static struct msm_vidc_inst_smem_ops msm_vidc_smem_ops = { .smem_drain = msm_smem_memory_drain, }; +static void close_helper(struct kref *kref) +{ + struct msm_vidc_inst *inst = container_of(kref, + struct msm_vidc_inst, kref); + + msm_vidc_destroy(inst); +} + void *msm_vidc_open(int core_id, int session_type) { struct msm_vidc_inst *inst = NULL; @@ -1598,7 +1606,9 @@ void *msm_vidc_open(int core_id, int session_type) if (rc) { s_vpr_e(inst->sid, "Failed to move video instance to init state\n"); - goto fail_init; + kref_put(&inst->kref, close_helper); + inst = NULL; + goto err_invalid_core; } if (msm_comm_check_for_inst_overload(core)) { @@ -1786,14 +1796,6 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) return 0; } -static void close_helper(struct kref *kref) -{ - struct msm_vidc_inst *inst = container_of(kref, - struct msm_vidc_inst, kref); - - msm_vidc_destroy(inst); -} - int msm_vidc_close(void *instance) { struct msm_vidc_inst *inst = instance; From 34f376ccdca87bdd21fd0dce1815059f1f9ee667 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Tue, 4 Aug 2020 17:17:48 +0530 Subject: [PATCH 395/452] msm: vidc: Handle race condition for accessing session head Currently session_end() accesses &dev->sess_head without device->lock. So there are high chances of use-after-free in &dev->sess_head. Change-Id: I34593e6507da9bad13c6d92faf40c4d790825d39 Signed-off-by: Priyanka Gujjula Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_common.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index d08e240cfce3..3e4e5d40c760 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -1984,18 +1984,20 @@ static int venus_hfi_session_end(void *sess) struct venus_hfi_device *device = &venus_hfi_dev; int rc = 0; - if (!__is_session_valid(device, session, __func__)) - return -EINVAL; - mutex_lock(&device->lock); + if (!__is_session_valid(device, session, __func__)) { + rc = -EINVAL; + goto exit; + } + if (msm_vidc_fw_coverage) { if (__sys_set_coverage(device, msm_vidc_fw_coverage, session->sid)) s_vpr_e(session->sid, "Fw_coverage msg ON failed\n"); } rc = __send_session_cmd(session, HFI_CMD_SYS_SESSION_END); +exit: mutex_unlock(&device->lock); - return rc; } From 459ecf6ee662cb60ea252f815db11011c094dbce Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 28 Oct 2020 21:33:13 +0530 Subject: [PATCH 396/452] msm: vidc: tune dynamic framerate logic Some vp9 clips contains alt-ref frames(decode only) at periodic intervals and that particular frames buffer ts delta is very low(as low as 1 ms). So dynamic framerate calculation in driver is going for a toss. To mitigate above problem, taking avg framerate instead of max value. Change-Id: I0f320c6a24199efe28d357d53c7cc9ddf6fc3062 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_common.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 45f303aa2cf4..8add4f9684a2 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7751,24 +7751,24 @@ u32 msm_comm_calc_framerate(struct msm_vidc_inst *inst, u32 msm_comm_get_max_framerate(struct msm_vidc_inst *inst) { struct msm_vidc_timestamps *node; - u32 max_framerate = 1 << 16; - int count = 0; + u64 avg_framerate = 0; + u32 count = 0; if (!inst) { d_vpr_e("%s: invalid parameters\n", __func__); - return max_framerate; + return (1 << 16); } mutex_lock(&inst->timestamps.lock); list_for_each_entry(node, &inst->timestamps.list, list) { count++; - max_framerate = max_framerate < node->framerate ? - node->framerate : max_framerate; + avg_framerate += node->framerate; } - s_vpr_l(inst->sid, "%s: fps %u, list size %d\n", - __func__, max_framerate, count); + avg_framerate = count ? (avg_framerate / count) : (1 << 16); + + s_vpr_l(inst->sid, "%s: fps %u, list size %d\n", __func__, avg_framerate, count); mutex_unlock(&inst->timestamps.lock); - return max_framerate; + return (u32)avg_framerate; } int msm_comm_fetch_ts_framerate(struct msm_vidc_inst *inst, From af73385543f01925b21a1f2f5ce0e5648a4d2ed1 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Tue, 3 Nov 2020 13:27:13 +0800 Subject: [PATCH 397/452] msm: vidc: fix BW overvote due to wrong worst_cf in fbd For worst complexity factor received in fbd, also need to divide it by frame_size, otherwise will cause bus BW overvote. Change-Id: Ibb20103c4ab8e3830eea8cf8a04b32f421b60362 Signed-off-by: Qiwei Liu --- msm/vidc/msm_vidc_common.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 8add4f9684a2..fba98b0e548d 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2652,6 +2652,9 @@ static void handle_fbd(enum hal_command_response cmd, void *data) } if (inst->core->resources.ubwc_stats_in_fbd == 1) { + u32 frame_size = + (msm_vidc_get_mbs_per_frame(inst) / (32 * 8) * 3) / 2; + mutex_lock(&inst->ubwc_stats_lock); inst->ubwc_stats.is_valid = fill_buf_done->ubwc_cr_stat.is_valid; @@ -2659,6 +2662,8 @@ static void handle_fbd(enum hal_command_response cmd, void *data) fill_buf_done->ubwc_cr_stat.worst_cr; inst->ubwc_stats.worst_cf = fill_buf_done->ubwc_cr_stat.worst_cf; + if (frame_size) + inst->ubwc_stats.worst_cf /= frame_size; mutex_unlock(&inst->ubwc_stats_lock); } From d427f1ffdebba6a8fbb70b8624d7d9b96bbea64d Mon Sep 17 00:00:00 2001 From: Uma Mehta Date: Thu, 1 Oct 2020 17:25:42 +0530 Subject: [PATCH 398/452] msm: vidc: change default step size change default step size for encoders on different targets to 2. Change-Id: I0db827920f6c452154296b79e8641e1aba0b03ab Signed-off-by: Uma Mehta --- msm/vidc/msm_vidc_platform.c | 136 ++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 64 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index fa2e214f4ef7..7c5f1a2b1ce5 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -124,8 +124,10 @@ static struct msm_vidc_codec default_codecs[] = { static struct msm_vidc_codec_capability bengal_capabilities_v0[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value} */ - {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1920}, - {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1080}, + {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 128, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 128, 1920, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 1920, 2, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 1920, 2, 1080}, /* ((1920 * 1088) / 256) */ {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 8160, 1, 8160}, /* 1080@30 decode + 1080@30 encode */ @@ -148,17 +150,19 @@ static struct msm_vidc_codec_capability bengal_capabilities_v0[] = { {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, /* Secure usecase specific */ - {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1920}, - {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 128, 1920, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 128, 1920, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 1920, 2, 1920}, + {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 1920, 2, 1080}, /* (1920 * 1088) / 256 */ {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 8160, 1, 8160}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 35000000, 1, 20000000}, /* Image specific */ - {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 1, 8192}, - {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192}, + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 2, 8192}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 2, 8192}, /* Level for AVC and HEVC encoder specific. * Default for levels is UNKNOWN value. But if we use unknown @@ -184,8 +188,10 @@ static struct msm_vidc_codec_capability bengal_capabilities_v0[] = { static struct msm_vidc_codec_capability bengal_capabilities_v1[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value} */ - {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1920}, - {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1080}, + {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 128, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 128, 1920, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 1920, 2, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 1920, 2, 1080}, /* ((1920 * 1088) / 256) */ {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 8160, 1, 8160}, /* 1920*1088 @30fps */ @@ -208,17 +214,19 @@ static struct msm_vidc_codec_capability bengal_capabilities_v1[] = { {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, /* Secure usecase specific */ - {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1920}, - {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 128, 1920, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 128, 1920, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 1920, 2, 1920}, + {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 1920, 2, 1080}, /* (1920 * 1088) / 256 */ {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 8160, 1, 8160}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 35000000, 1, 20000000}, /* Image specific */ - {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 1, 8192}, - {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192}, + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 2, 8192}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 2, 8192}, /* Level for AVC and HEVC encoder specific. * Default for levels is UNKNOWN value. But if we use unknown @@ -246,8 +254,8 @@ static struct msm_vidc_codec_capability holi_capabilities[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value} */ {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 1920, 1, 1920}, {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 1920, 1, 1080}, - {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 1920, 1, 1920}, - {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 1920, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 1920, 2, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 1920, 2, 1080}, /* ((1920 * 1088) / 256) */ {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 8160, 1, 8160}, {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 8160, 1, 8160}, @@ -274,8 +282,8 @@ static struct msm_vidc_codec_capability holi_capabilities[] = { /* Secure usecase specific */ {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 1920, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 1920, 1, 1080}, - {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 1920, 1, 1920}, - {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 1920, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 1920, 2, 1920}, + {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 1920, 2, 1080}, /* (1920 * 1088) / 256 */ {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 8160, 1, 8160}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 35000000, 1, 20000000}, @@ -284,10 +292,10 @@ static struct msm_vidc_codec_capability holi_capabilities[] = { {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 30, 1, 30}, /* Image specific */ - {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 1, 8192}, - {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192}, + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 2, 8192}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 2, 8192}, /* Level for AVC and HEVC encoder specific. * Default for levels is UNKNOWN value. But if we use unknown @@ -315,8 +323,8 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 8192, 1, 1920}, {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 8192, 1, 1080}, - {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 8192, 1, 1920}, - {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 8192, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 8192, 2, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 8192, 2, 1080}, /* (8192 * 4320) / 256 */ {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 138240, 1, 138240}, {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 138240, 1, 138240}, @@ -371,8 +379,8 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { /* Secure usecase specific */ {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, - {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 1, 1920}, - {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 2, 1920}, + {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 2, 1080}, /* (4096 * 2304) / 256 */ {CAP_SECURE_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 36864, 1, 36864}, {CAP_SECURE_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 36864, 1, 36864}, @@ -384,8 +392,8 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 120, 1, 120}, /* Lossless encoding usecase specific */ - {CAP_LOSSLESS_FRAME_WIDTH, ENC, H264|HEVC, 128, 4096, 1, 1920}, - {CAP_LOSSLESS_FRAME_HEIGHT, ENC, H264|HEVC, 128, 4096, 1, 1080}, + {CAP_LOSSLESS_FRAME_WIDTH, ENC, H264|HEVC, 128, 4096, 2, 1920}, + {CAP_LOSSLESS_FRAME_HEIGHT, ENC, H264|HEVC, 128, 4096, 2, 1080}, /* (4096 * 2304) / 256 */ {CAP_LOSSLESS_MBS_PER_FRAME, ENC, H264|HEVC, 64, 36864, 1, 36864}, @@ -393,10 +401,10 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 240, 1, 30}, /* Image specific */ - {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 16384, 1, 16384}, - {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 16384, 1, 16384}, + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 16384, 2, 16384}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 16384, 2, 16384}, /* * Level for AVC and HEVC encoder specific. @@ -425,8 +433,8 @@ static struct msm_vidc_codec_capability shima_capabilities_v0[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 8192, 1, 1920}, {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 8192, 1, 1080}, - {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 1, 1920}, - {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 2, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 2, 1080}, /* (8192 * 4320) / 256 */ {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 138240, 1, 138240}, /* (4096 * 2176) / 256 */ @@ -484,8 +492,8 @@ static struct msm_vidc_codec_capability shima_capabilities_v0[] = { /* Secure usecase specific */ {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, - {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 1, 1920}, - {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 2, 1920}, + {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 2, 1080}, /* (3840 * 2176) / 256 */ {CAP_SECURE_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 34816, 1, 8160}, {CAP_SECURE_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 8160}, @@ -497,8 +505,8 @@ static struct msm_vidc_codec_capability shima_capabilities_v0[] = { {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 60, 1, 60}, /* Lossless encoding usecase specific */ - {CAP_LOSSLESS_FRAME_WIDTH, ENC, H264|HEVC, 128, 4096, 1, 1920}, - {CAP_LOSSLESS_FRAME_HEIGHT, ENC, H264|HEVC, 128, 4096, 1, 1080}, + {CAP_LOSSLESS_FRAME_WIDTH, ENC, H264|HEVC, 128, 4096, 2, 1920}, + {CAP_LOSSLESS_FRAME_HEIGHT, ENC, H264|HEVC, 128, 4096, 2, 1080}, /* (4096 * 2176) / 256 */ {CAP_LOSSLESS_MBS_PER_FRAME, ENC, H264|HEVC, 64, 34816, 1, 8160}, @@ -506,10 +514,10 @@ static struct msm_vidc_codec_capability shima_capabilities_v0[] = { {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 120, 1, 30}, /* Image specific */ - {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 16384, 1, 16384}, - {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 16384, 1, 16384}, + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 16384, 2, 16384}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 16384, 2, 16384}, /* * Level for AVC and HEVC encoder specific. @@ -538,8 +546,8 @@ static struct msm_vidc_codec_capability shima_capabilities_v1[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, - {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 1, 1920}, - {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 2, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 2, 1080}, /* ((4096 * 2176) / 256) */ {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 34816, 1, 8160}, {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 8160}, @@ -591,8 +599,8 @@ static struct msm_vidc_codec_capability shima_capabilities_v1[] = { /* Secure usecase specific */ {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, - {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1920}, - {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 4096, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 2, 1920}, + {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 2, 1080}, /* (4096 * 2176) / 256 */ {CAP_SECURE_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 34816, 1, 8160}, {CAP_SECURE_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 8160}, @@ -604,8 +612,8 @@ static struct msm_vidc_codec_capability shima_capabilities_v1[] = { {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, /* Lossless encoding usecase specific */ - {CAP_LOSSLESS_FRAME_WIDTH, ENC, H264|HEVC, 128, 3840, 1, 1920}, - {CAP_LOSSLESS_FRAME_HEIGHT, ENC, H264|HEVC, 128, 3840, 1, 1080}, + {CAP_LOSSLESS_FRAME_WIDTH, ENC, H264|HEVC, 128, 3840, 2, 1920}, + {CAP_LOSSLESS_FRAME_HEIGHT, ENC, H264|HEVC, 128, 3840, 2, 1080}, /* (3840 * 2176) / 256 */ {CAP_LOSSLESS_MBS_PER_FRAME, ENC, H264|HEVC, 64, 32640, 1, 8160}, @@ -613,10 +621,10 @@ static struct msm_vidc_codec_capability shima_capabilities_v1[] = { {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 120, 1, 30}, /* Image specific */ - {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 16384, 1, 16384}, - {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 16384, 1, 16384}, + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 16384, 2, 16384}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 16384, 2, 16384}, /* * Level for AVC and HEVC encoder specific. @@ -645,8 +653,8 @@ static struct msm_vidc_codec_capability shima_capabilities_v2[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, - {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 1, 1920}, - {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 2, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 2, 1080}, /* (4096 * 2176) / 256 */ {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 34816, 1, 8160}, {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 8160}, @@ -697,8 +705,8 @@ static struct msm_vidc_codec_capability shima_capabilities_v2[] = { /* Secure usecase specific */ {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, - {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 1, 1920}, - {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 2, 1920}, + {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 2, 1080}, /* (4096 * 2176) / 256 */ {CAP_SECURE_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 34816, 1, 8160}, {CAP_SECURE_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 8160}, @@ -710,8 +718,8 @@ static struct msm_vidc_codec_capability shima_capabilities_v2[] = { {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, /* Lossless encoding usecase specific */ - {CAP_LOSSLESS_FRAME_WIDTH, ENC, H264|HEVC, 128, 4096, 1, 1920}, - {CAP_LOSSLESS_FRAME_HEIGHT, ENC, H264|HEVC, 128, 4096, 1, 1080}, + {CAP_LOSSLESS_FRAME_WIDTH, ENC, H264|HEVC, 128, 4096, 2, 1920}, + {CAP_LOSSLESS_FRAME_HEIGHT, ENC, H264|HEVC, 128, 4096, 2, 1080}, /* (4096 * 2176) / 256 */ {CAP_LOSSLESS_MBS_PER_FRAME, ENC, H264|HEVC, 64, 34816, 1, 8160}, @@ -719,10 +727,10 @@ static struct msm_vidc_codec_capability shima_capabilities_v2[] = { {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 120, 1, 30}, /* Image specific */ - {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512}, - {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 16384, 1, 16384}, - {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 16384, 1, 16384}, + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 16384, 2, 16384}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 16384, 2, 16384}, /* * Level for AVC and HEVC encoder specific. From 92828b48eec7afb1f8deef37ebd85d0afd6c155b Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Tue, 3 Nov 2020 23:27:52 +0800 Subject: [PATCH 399/452] msm: vidc: fix ctrl limits update for MENU type When update limits for MENU type controls, should keep original menu_skip_mask, shouldn't replace it with step_size. Change-Id: I9706f139fd299f7ca931d812e1a95017606a2267 Signed-off-by: Qiwei Liu --- msm/vidc/msm_vidc_common.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index fba98b0e548d..cfeeb7dfe0de 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1345,6 +1345,10 @@ static int msm_vidc_comm_update_ctrl(struct msm_vidc_inst *inst, return -EINVAL; } + /* For menu type, keep original menu_skip_mask(step) */ + if (ctrl->type == V4L2_CTRL_TYPE_MENU) + cap->step_size = (u32)ctrl->step; + rc = v4l2_ctrl_modify_range(ctrl, cap->min, cap->max, cap->step_size, cap->default_value); if (rc) { From cc97f61b4b346af0363dcee45882f8a76326a304 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Thu, 22 Oct 2020 02:09:48 +0530 Subject: [PATCH 400/452] msm: venc: add support for boost for holi For holi, boost is set as 15%. With the change, a level of 15% can be set to video firmware. Also ensure that the boost is set only when client has set the boost control. CRs-Fixed: 2810440 Change-Id: Ib4e4c5511c57daa78b405f8a92c2ee924b1cc1bd Signed-off-by: Vikash Garodia --- msm/vidc/msm_venc.c | 19 ++++++++++++++++--- msm/vidc/msm_vidc_internal.h | 1 + 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index a1c1b1021839..55e05e41e5a6 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1970,6 +1970,9 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE: inst->full_range = ctrl->val; break; + case V4L2_CID_MPEG_VIDC_VENC_BITRATE_BOOST: + inst->boost_enabled = true; + break; case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: inst->entropy_mode = msm_comm_v4l2_to_hfi( V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, @@ -2010,7 +2013,6 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDEO_VBV_DELAY: case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET: case V4L2_CID_MPEG_VIDC_VENC_BITRATE_SAVINGS: - case V4L2_CID_MPEG_VIDC_VENC_BITRATE_BOOST: case V4L2_CID_MPEG_VIDC_VENC_QPRANGE_BOOST: case V4L2_CID_MPEG_VIDC_SUPERFRAME: s_vpr_h(sid, "Control set: ID : 0x%x Val : %d\n", @@ -3493,12 +3495,14 @@ int msm_venc_set_bitrate_boost_margin(struct msm_vidc_inst *inst, u32 enable) struct v4l2_ctrl *ctrl = NULL; struct hfi_bitrate_boost_margin boost_margin; int minqp, maxqp; + uint32_t vpu; if (!inst || !inst->core) { d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } hdev = inst->core->device; + vpu = inst->core->platform_data->vpu_ver; if (!enable) { boost_margin.margin = 0; @@ -3507,11 +3511,20 @@ int msm_venc_set_bitrate_boost_margin(struct msm_vidc_inst *inst, u32 enable) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_BITRATE_BOOST); - /* Mapped value to 0, 25 or 50*/ + /* + * For certain SOC, default value should be 0 unless client enabled + */ + if (!inst->boost_enabled && vpu == VPU_VERSION_AR50_LITE) { + ctrl->val = 0; + update_ctrl(ctrl, 0, inst->sid); + } + /* Mapped value to 0, 15, 25 or 50*/ if (ctrl->val >= 50) boost_margin.margin = 50; - else + else if (ctrl->val >= 25) boost_margin.margin = (u32)(ctrl->val/25) * 25; + else + boost_margin.margin = (u32)(ctrl->val/15) * 15; setprop: s_vpr_h(inst->sid, "%s: %d\n", __func__, boost_margin.margin); diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 2c1d1c4c7d41..b85e43d1b270 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -589,6 +589,7 @@ struct msm_vidc_inst { u64 last_qbuf_time_ns; bool active; bool has_bframe; + bool boost_enabled; bool boost_qp_enabled; u32 boost_min_qp; u32 boost_max_qp; From 9e9322b41d26810df966f45fd7fa7f216f045677 Mon Sep 17 00:00:00 2001 From: Uma Mehta Date: Wed, 21 Oct 2020 23:49:21 +0530 Subject: [PATCH 401/452] msm: vidc: Enable Average QP extradata Enabling Average QP extradata Change-Id: I94edb55f57ee0c88554a98688665bf2eb805045e Signed-off-by: Uma Mehta --- include/uapi/vidc/media/msm_vidc_utils.h | 1 + msm/vidc/msm_venc.c | 10 ++++++++-- msm/vidc/msm_vidc_buffer_calculations.c | 3 +++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index 4108ed84b036..e45ffa06f231 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -116,6 +116,7 @@ enum v4l2_mpeg_vidc_extradata { EXTRADATA_ENC_INPUT_ROI = 4, EXTRADATA_ENC_INPUT_HDR10PLUS = 8, EXTRADATA_ENC_INPUT_CVP = 16, + EXTRADATA_ENC_FRAME_QP = 32, }; #define V4L2_CID_MPEG_VIDC_VIDEO_VUI_TIMING_INFO \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 19) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 55e05e41e5a6..10477853cfde 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -522,7 +522,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .minimum = EXTRADATA_NONE, .maximum = EXTRADATA_ADVANCED | EXTRADATA_ENC_INPUT_ROI | EXTRADATA_ENC_INPUT_HDR10PLUS | - EXTRADATA_ENC_INPUT_CVP, + EXTRADATA_ENC_INPUT_CVP | EXTRADATA_ENC_FRAME_QP, .default_value = EXTRADATA_NONE, .menu_skip_mask = 0, .qmenu = NULL, @@ -1782,7 +1782,8 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) msm_vidc_calculate_enc_input_extra_size(inst); } - if (inst->prop.extradata_ctrls & EXTRADATA_ADVANCED) { + if ((inst->prop.extradata_ctrls & EXTRADATA_ADVANCED) || + (inst->prop.extradata_ctrls & EXTRADATA_ENC_FRAME_QP)) { f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; f->fmt.pix_mp.num_planes = 2; f->fmt.pix_mp.plane_fmt[1].sizeimage = @@ -4604,6 +4605,11 @@ int msm_venc_set_extradata(struct msm_vidc_inst *inst) msm_comm_set_extradata(inst, HFI_PROPERTY_PARAM_VENC_LTR_INFO, 0x1); + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_FRAME_QP) + // Enable AvgQP Extradata + msm_comm_set_extradata(inst, + HFI_PROPERTY_PARAM_VENC_FRAME_QP_EXTRADATA, 0x1); + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_ROI) // Enable ROIQP Extradata msm_comm_set_extradata(inst, diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 0d63bca7395d..f09cb898b6f2 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1076,6 +1076,9 @@ u32 msm_vidc_calculate_enc_output_extra_size(struct msm_vidc_inst *inst) if (inst->prop.extradata_ctrls & EXTRADATA_ADVANCED) size += sizeof(struct msm_vidc_metadata_ltr_payload); + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_FRAME_QP) + size += sizeof(struct msm_vidc_frame_qp_payload); + /* Add size for extradata none */ if (size) size += sizeof(struct msm_vidc_extradata_header); From 5bf834b78e77dcf2d9cc0e832b20ad6aa142fb96 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Tue, 20 Oct 2020 14:36:32 +0530 Subject: [PATCH 402/452] msm: vidc: Update num_ref calc and limit max_layer Limit max number of temporal layers to 4 if hybrid_hp is not enabled as per POR. Also, inline num_ref calculations with FW. Change-Id: Iad1deaf757a8aa3715b2dce861b1454faeed7a39 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_venc.c | 6 ++++++ msm/vidc/msm_vidc_buffer_calculations.c | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 55e05e41e5a6..b13866942db4 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3809,6 +3809,12 @@ int msm_venc_set_hp_max_layer(struct msm_vidc_inst *inst) __func__); return rc; } + if (!inst->hybrid_hp && max_layer->val > 4) { + update_ctrl(max_layer, 0, inst->sid); + s_vpr_h(inst->sid, + "%s: Hier-P requested beyond max capability\n", __func__); + return 0; + } /* * We send enhancement layer count to FW, diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 0d63bca7395d..d19ed2b32cf1 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -497,13 +497,13 @@ int msm_vidc_get_num_ref_frames(struct msm_vidc_inst *inst) codec = get_v4l2_codec(inst); /* LTR and B - frame not supported with hybrid HP */ if (inst->hybrid_hp) - num_ref = (max_layer->val - 1); + num_ref = max_layer->val >> 1; else if (codec == V4L2_PIX_FMT_HEVC) num_ref = ((max_layer->val + 1) / 2) + ltr_count; - else if ((codec == V4L2_PIX_FMT_H264) && (max_layer->val <= 4)) - num_ref = ((1 << (max_layer->val - 1)) - 1) + ltr_count; + else if ((codec == V4L2_PIX_FMT_H264) && (max_layer->val < 4)) + num_ref = (max_layer->val - 1) + ltr_count; else - num_ref = ((max_layer->val + 1) / 2) + ltr_count; + num_ref = max_layer->val + ltr_count; } if (is_hier_b_session(inst)) { From fe6842e2747845aca6b74191c8f7717f156d6127 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 6 Nov 2020 11:15:36 +0530 Subject: [PATCH 403/452] msm: vidc: fix format string mismatch Some debug prints doesn't contain proper args. So added proper args. Change-Id: I36fe3e967b3bf600b3a948cb88f556a4d93c02d1 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_venc.c | 8 ++++---- msm/vidc/msm_vidc_clocks.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 55e05e41e5a6..fe2da7816dac 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1555,7 +1555,7 @@ static int msm_venc_update_bitrate(struct msm_vidc_inst *inst) u32 cabac_max_bitrate = 0; if (!inst) { - d_vpr_e("%s: invalid params %pK\n", __func__); + d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } @@ -1908,17 +1908,17 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } } else if (inst->state == MSM_VIDC_START_DONE) { if (!inst->external_blur) { - s_vpr_e(sid, "external blur not enabled"); + s_vpr_e(sid, "%s: external blur not enabled", __func__); break; } if (ctrl->val == MSM_VIDC_BLUR_EXTERNAL_DYNAMIC) { s_vpr_h(sid, - "external blur setting already enabled\n", + "%s: external blur setting already enabled\n", __func__); break; } else if (ctrl->val == MSM_VIDC_BLUR_INTERNAL) { s_vpr_e(sid, - "cannot change to internal blur config dynamically\n", + "%s: cannot change to internal blur config dynamically\n", __func__); break; } else { diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 4185500e5bdd..aa8825caa007 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1444,7 +1444,7 @@ static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, sizeof(hfi_perf_mode)); if (rc) { s_vpr_e(inst->sid, "%s: Failed to set power save mode\n", - __func__, inst); + __func__); return rc; } inst->flags = enable ? From 90477015a6d4c2cf5068e63c3afc37b5269d1edb Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 2 Nov 2020 16:02:39 +0530 Subject: [PATCH 404/452] msm: vidc: optimize HEIC output buffer calc for encoder For HEIC encode, output buffer dimension is 512 x 512. Updating total output buffer size as twice the frame size of 512 x 512 for image sessions. Change-Id: I69311b485072ef7f43afd23da690e77eecee180d Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_buffer_calculations.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 0d63bca7395d..8cd29bb19eeb 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -982,6 +982,7 @@ u32 msm_vidc_calculate_enc_output_frame_size(struct msm_vidc_inst *inst) f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; /* * Encoder output size calculation: 32 Align width/height + * For CQ or heic session : YUVsize * 2 * For resolution < 720p : YUVsize * 4 * For resolution > 720p & <= 4K : YUVsize / 2 * For resolution > 4k : YUVsize / 4 @@ -996,6 +997,10 @@ u32 msm_vidc_calculate_enc_output_frame_size(struct msm_vidc_inst *inst) mbs_per_frame = NUM_MBS_PER_FRAME(width, height); frame_size = (width * height * 3); + if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ || + is_grid_session(inst) || is_image_session(inst)) + goto calc_done; + if (mbs_per_frame < NUM_MBS_720P) frame_size = frame_size << 1; else if (mbs_per_frame <= NUM_MBS_4k) @@ -1003,17 +1008,19 @@ u32 msm_vidc_calculate_enc_output_frame_size(struct msm_vidc_inst *inst) else frame_size = frame_size >> 3; - if ((inst->rc_type == RATE_CONTROL_OFF) || - (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ)) + if (inst->rc_type == RATE_CONTROL_OFF) frame_size = frame_size << 1; if (inst->rc_type == RATE_CONTROL_LOSSLESS) frame_size = (width * height * 9) >> 2; /* multiply by 10/8 (1.25) to get size for 10 bit case */ - if (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_HEVC) + if (inst->core->platform_data->vpu_ver != VPU_VERSION_AR50_LITE && + f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_HEVC) { frame_size = frame_size + (frame_size >> 2); + } +calc_done: return ALIGN(frame_size, SZ_4K); } From f607704b4476b70290c8d2992be4a61d39edfb77 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 6 Nov 2020 12:30:03 +0530 Subject: [PATCH 405/452] msm: vidc: fix msm_vidc_err_recovery_disable for non_noc_err disable error_recovery for non-NOC error if VIDC_DISABLE_NON_NOC_ERR_RECOV is set. but error_recovery is getting disabled even for type NOC error when VIDC_DISABLE_NON_NOC_ERR_RECOV is set. [1] Only NOC error adb shell "echo 1 > /d/msm_vidc/disable_err_recovery" [2] Only non-NOC error adb shell "echo 2 > /d/msm_vidc/disable_err_recovery" [3] Both NOC & non-NOC error adb shell "echo 3 > /d/msm_vidc/disable_err_recovery" Change-Id: Ia09ca23708d41a77f1d77cf6ed57506a16b32c73 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_common.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index cfeeb7dfe0de..dbbff4d938be 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2168,6 +2168,7 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) struct hfi_device *hdev = NULL; struct msm_vidc_inst *inst = NULL; int rc = 0; + bool panic = false; subsystem_crashed("venus"); if (!response) { @@ -2203,12 +2204,11 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) } /* handle the hw error before core released to get full debug info */ - msm_vidc_handle_hw_error(core); - if ((response->status == VIDC_ERR_NOC_ERROR && - (msm_vidc_err_recovery_disable & - VIDC_DISABLE_NOC_ERR_RECOV)) || - (msm_vidc_err_recovery_disable & - VIDC_DISABLE_NON_NOC_ERR_RECOV)) { + if (response->status == VIDC_ERR_NOC_ERROR) + panic = !!(msm_vidc_err_recovery_disable & VIDC_DISABLE_NOC_ERR_RECOV); + else + panic = !!(msm_vidc_err_recovery_disable & VIDC_DISABLE_NON_NOC_ERR_RECOV); + if (panic) { d_vpr_e("Got unrecoverable video fw error"); MSM_VIDC_ERROR(true); } From 66e18fb51eb97b20530f54bc9118525d21426ad5 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Sat, 24 Oct 2020 02:58:31 +0530 Subject: [PATCH 406/452] msm: vidc: print inode and refcount for all dma_buffers Print dma_buffer inode and file refcount details for all dma buffers including dpb and driver internal buffers. Change-Id: I3c22ccc1aaba555a3748d4607617737bd24adb12 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_smem.c | 23 +++++++++++------- msm/vidc/msm_vidc_common.c | 49 ++++++++++++++++++++++++++------------ 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/msm/vidc/msm_smem.c b/msm/vidc/msm_smem.c index 4d3454ebc46b..5dfa1e70a089 100644 --- a/msm/vidc/msm_smem.c +++ b/msm/vidc/msm_smem.c @@ -440,8 +440,9 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, } s_vpr_h(sid, - "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, buffer_type = %#x, flags = %#lx\n", - __func__, mem->dma_buf, mem->device_addr, mem->size, + "%s: dma_buf = %pK, inode = %lu, ref = %ld, device_addr = %x, size = %d, kvaddr = %pK, buffer_type = %#x, flags = %#lx\n", + __func__, mem->dma_buf, (dbuf ? file_inode(dbuf->file)->i_ino : -1), + (dbuf ? file_count(dbuf->file) : -1), mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type, mem->flags); return rc; @@ -456,10 +457,14 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, static int free_dma_mem(struct msm_smem *mem, u32 sid) { + struct dma_buf *dbuf = NULL; + + dbuf = (struct dma_buf *)mem->dma_buf; s_vpr_h(sid, - "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, buffer_type = %#x\n", - __func__, mem->dma_buf, mem->device_addr, mem->size, - mem->kvaddr, mem->buffer_type); + "%s: dma_buf = %pK, inode = %lu, ref = %ld, device_addr = %x, size = %d, kvaddr = %pK, buffer_type = %#x\n", + __func__, dbuf, (dbuf ? file_inode(dbuf->file)->i_ino : -1), + (dbuf ? file_count(dbuf->file) : -1), mem->device_addr, + mem->size, mem->kvaddr, mem->buffer_type); if (mem->device_addr) { msm_dma_put_device_address(mem->flags, @@ -468,16 +473,16 @@ static int free_dma_mem(struct msm_smem *mem, u32 sid) } if (mem->kvaddr) { - dma_buf_vunmap(mem->dma_buf, mem->kvaddr); + dma_buf_vunmap(dbuf, mem->kvaddr); mem->kvaddr = NULL; - dma_buf_end_cpu_access(mem->dma_buf, DMA_BIDIRECTIONAL); + dma_buf_end_cpu_access(dbuf, DMA_BIDIRECTIONAL); } - if (mem->dma_buf) { + if (dbuf) { trace_msm_smem_buffer_dma_op_start("FREE", (u32)mem->buffer_type, -1, mem->size, -1, mem->flags, -1); - dma_buf_put(mem->dma_buf); + dma_buf_put(dbuf); mem->dma_buf = NULL; trace_msm_smem_buffer_dma_op_end("FREE", (u32)mem->buffer_type, -1, mem->size, -1, mem->flags, -1); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index cfeeb7dfe0de..8104f60fd5de 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -6372,6 +6372,7 @@ int msm_comm_set_color_format(struct msm_vidc_inst *inst, void msm_comm_print_inst_info(struct msm_vidc_inst *inst) { struct msm_vidc_buffer *mbuf; + struct dma_buf *dbuf; struct internal_buf *buf; bool is_decode = false; enum vidc_ports port; @@ -6405,26 +6406,35 @@ void msm_comm_print_inst_info(struct msm_vidc_inst *inst) mutex_lock(&inst->scratchbufs.lock); s_vpr_e(inst->sid, "scratch buffer list:\n"); - list_for_each_entry(buf, &inst->scratchbufs.list, list) - s_vpr_e(inst->sid, "type: %d addr: %x size: %u\n", - buf->buffer_type, buf->smem.device_addr, - buf->smem.size); + list_for_each_entry(buf, &inst->scratchbufs.list, list) { + dbuf = (struct dma_buf *)buf->smem.dma_buf; + s_vpr_e(inst->sid, "type: %d addr: %x size: %u inode: %lu ref: %ld\n", + buf->buffer_type, buf->smem.device_addr, buf->smem.size, + (dbuf ? file_inode(dbuf->file)->i_ino : -1), + (dbuf ? file_count(dbuf->file) : -1)); + } mutex_unlock(&inst->scratchbufs.lock); mutex_lock(&inst->persistbufs.lock); s_vpr_e(inst->sid, "persist buffer list:\n"); - list_for_each_entry(buf, &inst->persistbufs.list, list) - s_vpr_e(inst->sid, "type: %d addr: %x size: %u\n", - buf->buffer_type, buf->smem.device_addr, - buf->smem.size); + list_for_each_entry(buf, &inst->persistbufs.list, list) { + dbuf = (struct dma_buf *)buf->smem.dma_buf; + s_vpr_e(inst->sid, "type: %d addr: %x size: %u inode: %lu ref: %ld\n", + buf->buffer_type, buf->smem.device_addr, buf->smem.size, + (dbuf ? file_inode(dbuf->file)->i_ino : -1), + (dbuf ? file_count(dbuf->file) : -1)); + } mutex_unlock(&inst->persistbufs.lock); mutex_lock(&inst->outputbufs.lock); s_vpr_e(inst->sid, "dpb buffer list:\n"); - list_for_each_entry(buf, &inst->outputbufs.list, list) - s_vpr_e(inst->sid, "type: %d addr: %x size: %u\n", - buf->buffer_type, buf->smem.device_addr, - buf->smem.size); + list_for_each_entry(buf, &inst->outputbufs.list, list) { + dbuf = (struct dma_buf *)buf->smem.dma_buf; + s_vpr_e(inst->sid, "type: %d addr: %x size: %u inode: %lu ref: %ld\n", + buf->buffer_type, buf->smem.device_addr, buf->smem.size, + (dbuf ? file_inode(dbuf->file)->i_ino : -1), + (dbuf ? file_count(dbuf->file) : -1)); + } mutex_unlock(&inst->outputbufs.lock); } @@ -6499,34 +6509,43 @@ void print_vidc_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) { struct vb2_buffer *vb2 = NULL; + struct dma_buf *dbuf[2]; if (!(tag & msm_vidc_debug) || !inst || !mbuf) return; vb2 = &mbuf->vvb.vb2_buf; + dbuf[0] = (struct dma_buf *)mbuf->smem[0].dma_buf; + dbuf[1] = (struct dma_buf *)mbuf->smem[1].dma_buf; if (vb2->num_planes == 1) dprintk(tag, inst->sid, - "%s: %s: idx %2d fd %d off %d daddr %x size %d filled %d flags 0x%x ts %lld refcnt %d mflags 0x%x\n", + "%s: %s: idx %2d fd %d off %d daddr %x inode %lu ref %ld size %d filled %d flags 0x%x ts %lld refcnt %d mflags 0x%x\n", str, vb2->type == INPUT_MPLANE ? "OUTPUT" : "CAPTURE", vb2->index, vb2->planes[0].m.fd, vb2->planes[0].data_offset, mbuf->smem[0].device_addr, + (dbuf[0] ? file_inode(dbuf[0]->file)->i_ino : -1), + (dbuf[0] ? file_count(dbuf[0]->file) : -1), vb2->planes[0].length, vb2->planes[0].bytesused, mbuf->vvb.flags, mbuf->vvb.vb2_buf.timestamp, mbuf->smem[0].refcount, mbuf->flags); else dprintk(tag, inst->sid, - "%s: %s: idx %2d fd %d off %d daddr %x size %d filled %d flags 0x%x ts %lld refcnt %d mflags 0x%x, extradata: fd %d off %d daddr %x size %d filled %d refcnt %d\n", + "%s: %s: idx %2d fd %d off %d daddr %x inode %lu ref %ld size %d filled %d flags 0x%x ts %lld refcnt %d mflags 0x%x, extradata: fd %d off %d daddr %x inode %lu ref %ld size %d filled %d refcnt %d\n", str, vb2->type == INPUT_MPLANE ? "OUTPUT" : "CAPTURE", vb2->index, vb2->planes[0].m.fd, vb2->planes[0].data_offset, mbuf->smem[0].device_addr, + (dbuf[0] ? file_inode(dbuf[0]->file)->i_ino : -1), + (dbuf[0] ? file_count(dbuf[0]->file) : -1), vb2->planes[0].length, vb2->planes[0].bytesused, mbuf->vvb.flags, mbuf->vvb.vb2_buf.timestamp, mbuf->smem[0].refcount, mbuf->flags, vb2->planes[1].m.fd, vb2->planes[1].data_offset, - mbuf->smem[1].device_addr, vb2->planes[1].length, + mbuf->smem[1].device_addr, + (dbuf[1] ? file_inode(dbuf[1]->file)->i_ino : -1), + (dbuf[1] ? file_count(dbuf[1]->file) : -1), vb2->planes[1].length, vb2->planes[1].bytesused, mbuf->smem[1].refcount); } From b689990576e846dc2dfa9af2980af5ddf476a760 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 1 Apr 2020 13:13:42 +0530 Subject: [PATCH 407/452] msm: vidc: do not update inst state for map failure Currently for map failure inst->state updated to MSM_VIDC_CORE_INVALID. So during flush driver issues session_abort to firmware. So firmware asserts and sends sys_error back. So added change to avoid updating inst->state. Change-Id: I30f90726d21cb13bf5a27dd3d259a8d026260746 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index be9034418f9f..e5e3f4db8c26 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1267,7 +1267,9 @@ static void msm_vidc_buf_queue(struct vb2_buffer *vb2) if (rc) { print_vb2_buffer("failed vb2-qbuf", inst, vb2); - msm_comm_generate_session_error(inst); + vb2_buffer_done(vb2, VB2_BUF_STATE_DONE); + msm_vidc_queue_v4l2_event(inst, + V4L2_EVENT_MSM_VIDC_SYS_ERROR); } } From a69feaa56883cc2946bff2354d4cc1483e6acf89 Mon Sep 17 00:00:00 2001 From: Malathi Gottam Date: Mon, 28 Sep 2020 22:19:18 +0530 Subject: [PATCH 408/452] msm: vidc: Modify allocated buffer size for lower resolution For targets that doesn't support 4k, current buffer size of 3MB is modified for FWVGA and below resolution to 6 MB. Change-Id: Id9152bf4b88a1b86d790bc061cd7265896c62a98 Signed-off-by: Malathi Gottam --- msm/vidc/msm_vidc_buffer_calculations.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 8b90e60b2c63..d5cb06e20b67 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -913,6 +913,8 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst, u32 buff if (inst->core->platform_data->vpu_ver == VPU_VERSION_AR50_LITE) { base_res_mbs = inst->capability.cap[CAP_MBS_PER_FRAME].max; div_factor = 1; + if (num_mbs < NUM_MBS_720P) + base_res_mbs = base_res_mbs * 2; } /* For HEIF image, use the actual resolution to calc buffer size */ if (is_heif_decoder(inst)) { From eb19e74fe05b7b7ab21fc29404447e4d9fc69d7c Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 9 Nov 2020 12:46:46 +0530 Subject: [PATCH 409/452] msm: vidc: handle qbuf failure in decode batching usecase if msm_comm_qbuf_to_hfi is failed at msm_vidc_batch_handler path, then vb2_buffer refcount is still held at v4l2 layer. So added error handling for qbuf failure at decode_batching sequence. Change-Id: Ic900ff95faec075620323c989430dea7ce34f26b Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_common.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index c7444042ed1b..3bab57959bb5 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -4765,6 +4765,7 @@ int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, { int rc = 0; struct msm_vidc_buffer *buf; + struct vb2_buffer *vb2; int do_bw_calc = 0; do_bw_calc = mbuf ? mbuf->vvb.vb2_buf.type == INPUT_MPLANE : 0; @@ -4789,6 +4790,11 @@ int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, if (rc) { s_vpr_e(inst->sid, "%s: Failed batch qbuf to hfi: %d\n", __func__, rc); + if (buf != mbuf) { + vb2 = &buf->vvb.vb2_buf; + vb2_buffer_done(vb2, VB2_BUF_STATE_DONE); + msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); + } break; } loop_end: From 1fc8b2829c24d295861479f0e979afb8fc644a02 Mon Sep 17 00:00:00 2001 From: Chandrakant I Viraktamath Date: Wed, 10 Jun 2020 10:26:51 +0530 Subject: [PATCH 410/452] msm: vidc: Fix mbpf calculation for active session Fix macro block per frame calculation by not considering sessions which have state greater than or equal to MSM_VIDC_STOP_DONE. Change-Id: Ie25e52e946386fcf226b0f9c073c1b022cf1ac0c Signed-off-by: Chandrakant I Viraktamath --- msm/vidc/msm_vidc_common.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 3bab57959bb5..d1e8cdf99715 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5768,8 +5768,9 @@ static int msm_vidc_check_mbpf_supported(struct msm_vidc_inst *inst) mutex_lock(&core->lock); list_for_each_entry(temp, &core->instances, list) { - /* ignore invalid session */ - if (temp->state == MSM_VIDC_CORE_INVALID) + /* ignore invalid and completed session */ + if (temp->state == MSM_VIDC_CORE_INVALID || + temp->state >= MSM_VIDC_STOP_DONE) continue; /* ignore thumbnail session */ if (is_thumbnail_session(temp)) From 7e5c67e9b03195002a77f24cb43446b6f98eb4f3 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 13 Nov 2020 11:58:26 +0530 Subject: [PATCH 411/452] Revert "msm: vidc: handle qbuf failure in decode batching usecase" This reverts commit eb19e74fe05b7b7ab21fc29404447e4d9fc69d7c. --- msm/vidc/msm_vidc_common.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 3bab57959bb5..c7444042ed1b 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -4765,7 +4765,6 @@ int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, { int rc = 0; struct msm_vidc_buffer *buf; - struct vb2_buffer *vb2; int do_bw_calc = 0; do_bw_calc = mbuf ? mbuf->vvb.vb2_buf.type == INPUT_MPLANE : 0; @@ -4790,11 +4789,6 @@ int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, if (rc) { s_vpr_e(inst->sid, "%s: Failed batch qbuf to hfi: %d\n", __func__, rc); - if (buf != mbuf) { - vb2 = &buf->vvb.vb2_buf; - vb2_buffer_done(vb2, VB2_BUF_STATE_DONE); - msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); - } break; } loop_end: From 1e662d20c0dbdfbfdae6eb106d28cb22fbc94594 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 13 Nov 2020 12:07:17 +0530 Subject: [PATCH 412/452] msm: vidc: handle qbuf failure in batch_handler if msm_comm_qbuf_to_hfi is failed at msm_vidc_batch_handler path, then vb2_buffer refcount is still held at v4l2 layer. So added error handling for qbuf failure at batch timeout sequence. Change-Id: I61b14210ae382944e456df5c11790dc115ab2a15 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_common.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index c7444042ed1b..13b3f30b3605 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -4482,6 +4482,7 @@ static int msm_comm_qbuf_to_hfi(struct msm_vidc_inst *inst, rc = -EINVAL; } if (rc) { + mbuf->flags |= MSM_VIDC_FLAG_DEFERRED; s_vpr_e(inst->sid, "%s: Failed to qbuf: %d\n", __func__, rc); goto err_bad_input; } @@ -4517,8 +4518,10 @@ void msm_vidc_batch_handler(struct work_struct *work) __func__); rc = msm_comm_qbufs_batch(inst, NULL); - if (rc) + if (rc) { s_vpr_e(inst->sid, "%s: batch qbufs failed\n", __func__); + msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); + } exit: put_inst(inst); From ab6467c5f417ff1661453088f419e05fa5805fc1 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 13 Nov 2020 11:58:26 +0530 Subject: [PATCH 413/452] Revert "msm: vidc: handle qbuf failure in decode batching usecase" This reverts commit eb19e74fe05b7b7ab21fc29404447e4d9fc69d7c. --- msm/vidc/msm_vidc_common.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 3bab57959bb5..c7444042ed1b 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -4765,7 +4765,6 @@ int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, { int rc = 0; struct msm_vidc_buffer *buf; - struct vb2_buffer *vb2; int do_bw_calc = 0; do_bw_calc = mbuf ? mbuf->vvb.vb2_buf.type == INPUT_MPLANE : 0; @@ -4790,11 +4789,6 @@ int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, if (rc) { s_vpr_e(inst->sid, "%s: Failed batch qbuf to hfi: %d\n", __func__, rc); - if (buf != mbuf) { - vb2 = &buf->vvb.vb2_buf; - vb2_buffer_done(vb2, VB2_BUF_STATE_DONE); - msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); - } break; } loop_end: From 0716102518a816a2da096a0023e3005f30141610 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 13 Nov 2020 12:07:17 +0530 Subject: [PATCH 414/452] msm: vidc: handle qbuf failure in batch_handler if msm_comm_qbuf_to_hfi is failed at msm_vidc_batch_handler path, then vb2_buffer refcount is still held at v4l2 layer. So added error handling for qbuf failure at batch timeout sequence. Change-Id: I61b14210ae382944e456df5c11790dc115ab2a15 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_common.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index c7444042ed1b..13b3f30b3605 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -4482,6 +4482,7 @@ static int msm_comm_qbuf_to_hfi(struct msm_vidc_inst *inst, rc = -EINVAL; } if (rc) { + mbuf->flags |= MSM_VIDC_FLAG_DEFERRED; s_vpr_e(inst->sid, "%s: Failed to qbuf: %d\n", __func__, rc); goto err_bad_input; } @@ -4517,8 +4518,10 @@ void msm_vidc_batch_handler(struct work_struct *work) __func__); rc = msm_comm_qbufs_batch(inst, NULL); - if (rc) + if (rc) { s_vpr_e(inst->sid, "%s: batch qbufs failed\n", __func__); + msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); + } exit: put_inst(inst); From 9e7171650a541c79be3e4758e0c2baeda53bd65c Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 25 Nov 2020 17:08:46 +0530 Subject: [PATCH 415/452] msm: vidc: print only memory usage To avoid overlogging issue, print only memory usage during session rejection. Change-Id: Ie155d5611a998b8e32c8cc5700f4e0a7fbd558ae Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 13b3f30b3605..7945be8a9c3e 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5885,7 +5885,7 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst) s_vpr_e(vidc_inst->sid, "%s: video mem overshoot - reached %llu MB, max_limit %llu MB\n", __func__, total_mem_size >> 20, memory_limit_mbytes); - msm_comm_print_insts_info(core); + msm_comm_print_mem_usage(core); return -EBUSY; } @@ -5900,7 +5900,7 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst) s_vpr_e(vidc_inst->sid, "%s: insufficient device addr space, required %llu, available %llu\n", __func__, non_sec_mem_size, non_sec_cb_size); - msm_comm_print_insts_info(core); + msm_comm_print_mem_usage(core); return -EINVAL; } } From 48fc0fe3e954b1f7376c3a1550c35e318878f1c2 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 3 Feb 2020 16:13:39 +0530 Subject: [PATCH 416/452] msm: vidc: update menu_skip_mask for menu type controls Need to pass menu_skip_mask instead of step_size to v4l2_ctrl_modify_range for menu type controls. Otherwise step_size will override skip mask. Mostly step size value is 1. So any menu_item with ctrl.val == 1, will not be allowed at runtime. Change-Id: If33f340a6e85335f80e3cf0a0b13266263e318ed Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_common.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 13b3f30b3605..51437beaf1d9 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1337,6 +1337,7 @@ static int msm_vidc_comm_update_ctrl(struct msm_vidc_inst *inst, { struct v4l2_ctrl *ctrl = NULL; int rc = 0; + bool is_menu = false; ctrl = v4l2_ctrl_find(&inst->ctrl_handler, id); if (!ctrl) { @@ -1345,33 +1346,32 @@ static int msm_vidc_comm_update_ctrl(struct msm_vidc_inst *inst, return -EINVAL; } - /* For menu type, keep original menu_skip_mask(step) */ if (ctrl->type == V4L2_CTRL_TYPE_MENU) - cap->step_size = (u32)ctrl->step; + is_menu = true; + /** + * For menu controls the step value is interpreted + * as a menu_skip_mask. + */ rc = v4l2_ctrl_modify_range(ctrl, cap->min, cap->max, - cap->step_size, cap->default_value); + is_menu ? ctrl->menu_skip_mask : cap->step_size, + cap->default_value); if (rc) { s_vpr_e(inst->sid, - "%s: failed: control name %s, min %d, max %d, step %d, default_value %d\n", + "%s: failed: control name %s, min %d, max %d, %s %x, default_value %d\n", __func__, ctrl->name, cap->min, cap->max, - cap->step_size, cap->default_value); - goto error; - } - /* - * v4l2_ctrl_modify_range() is not updating default_value, - * so use v4l2_ctrl_s_ctrl() to update it. - */ - rc = v4l2_ctrl_s_ctrl(ctrl, cap->default_value); - if (rc) { - s_vpr_e(inst->sid, "%s: failed s_ctrl: %s with value %d\n", - __func__, ctrl->name, cap->default_value); + is_menu ? "menu_skip_mask" : "step", + is_menu ? ctrl->menu_skip_mask : cap->step_size, + cap->default_value); goto error; } + s_vpr_h(inst->sid, - "Updated control: %s: min %lld, max %lld, step %lld, default value = %lld\n", + "Updated control: %s: min %lld, max %lld, %s %x, default value = %lld\n", ctrl->name, ctrl->minimum, ctrl->maximum, - ctrl->step, ctrl->default_value); + is_menu ? "menu_skip_mask" : "step", + is_menu ? ctrl->menu_skip_mask : ctrl->step, + ctrl->default_value); error: return rc; From 395da1fe6e4ac144618dfe456f6398f7cd40a07d Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 12 Feb 2020 11:41:42 +0800 Subject: [PATCH 417/452] msm: vidc: move inline functions into header file It's better to put inline function in header files If not, gcc would complain "function body not available". Change-Id: I81c363dc96bb4135593087e726d7a872b1bc3451 Signed-off-by: Jean Xiao --- msm/vidc/msm_vidc_debug.c | 43 +--------------------------- msm/vidc/msm_vidc_debug.h | 60 ++++++++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 52 deletions(-) diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index cd69a2ae161a..18a78bf6e69b 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -31,7 +31,7 @@ int msm_vidc_vpp_delay; atomic_read(&__binfo->ref_count) >= 2 ? "video driver" : "firmware";\ }) -static struct log_cookie ctxt[MAX_SUPPORTED_INSTANCES]; +struct log_cookie ctxt[MAX_SUPPORTED_INSTANCES]; struct core_inst_pair { struct msm_vidc_core *core; @@ -626,17 +626,6 @@ int get_sid(u32 *sid, u32 session_type) return (i == MAX_SUPPORTED_INSTANCES); } -void put_sid(u32 sid) -{ - if (!sid || sid > MAX_SUPPORTED_INSTANCES) { - d_vpr_e("%s: invalid sid %#x\n", - __func__, sid); - return; - } - if (ctxt[sid-1].used) - ctxt[sid-1].used = 0; -} - inline void update_log_ctxt(u32 sid, u32 session_type, u32 fourcc) { const char *codec; @@ -697,36 +686,6 @@ inline void update_log_ctxt(u32 sid, u32 session_type, u32 fourcc) ctxt[sid-1].name[5] = '\0'; } -inline char *get_codec_name(u32 sid) -{ - if (!sid || sid > MAX_SUPPORTED_INSTANCES) - return "....."; - - return ctxt[sid-1].name; -} - -/** - * 0xx -> allow prints for all sessions - * 1xx -> allow only encoder prints - * 2xx -> allow only decoder prints - */ -inline bool is_print_allowed(u32 sid, u32 level) -{ - if (!(msm_vidc_debug & level)) - return false; - - if (!((msm_vidc_debug >> 8) & 0xF)) - return true; - - if (!sid || sid > MAX_SUPPORTED_INSTANCES) - return true; - - if (ctxt[sid-1].session_type & msm_vidc_debug) - return true; - - return false; -} - /* Mock all the missing parts for successful compilation starts here */ void do_gettimeofday(struct timeval *__ddl_tv) { diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index 7b523eddb55f..8dfaee14cd98 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -92,6 +92,13 @@ enum vidc_err_recovery_disable { VIDC_DISABLE_NON_NOC_ERR_RECOV = 0x0002 }; +struct log_cookie { + u32 used; + u32 session_type; + u32 codec_type; + char name[20]; +}; + extern int msm_vidc_debug; extern int msm_vidc_fw_debug_mode; extern bool msm_vidc_fw_coverage; @@ -102,13 +109,7 @@ extern bool msm_vidc_lossless_encode; extern bool msm_vidc_cvp_usage; extern int msm_vidc_err_recovery_disable; extern int msm_vidc_vpp_delay; - -struct log_cookie { - u32 used; - u32 session_type; - u32 codec_type; - char name[20]; -}; +extern struct log_cookie ctxt[MAX_SUPPORTED_INSTANCES]; #define dprintk(__level, sid, __fmt, ...) \ do { \ @@ -200,9 +201,6 @@ void msm_vidc_debugfs_update(struct msm_vidc_inst *inst, int msm_vidc_check_ratelimit(void); int get_sid(u32 *sid, u32 session_type); void update_log_ctxt(u32 sid, u32 session_type, u32 fourcc); -inline char *get_codec_name(u32 sid); -inline void put_sid(u32 sid); -inline bool is_print_allowed(u32 sid, u32 level); static inline char *get_debug_level_str(int level) { @@ -225,6 +223,48 @@ static inline char *get_debug_level_str(int level) } } +/** + * 0xx -> allow prints for all sessions + * 1xx -> allow only encoder prints + * 2xx -> allow only decoder prints + * 4xx -> allow only cvp prints + */ +static inline bool is_print_allowed(u32 sid, u32 level) +{ + if (!(msm_vidc_debug & level)) + return false; + + if (!((msm_vidc_debug >> 8) & 0xF)) + return true; + + if (!sid || sid > MAX_SUPPORTED_INSTANCES) + return true; + + if (ctxt[sid-1].session_type & msm_vidc_debug) + return true; + + return false; +} + +static inline char *get_codec_name(u32 sid) +{ + if (!sid || sid > MAX_SUPPORTED_INSTANCES) + return "....."; + + return ctxt[sid-1].name; +} + +static inline void put_sid(u32 sid) +{ + if (!sid || sid > MAX_SUPPORTED_INSTANCES) { + d_vpr_e("%s: invalid sid %#x\n", + __func__, sid); + return; + } + if (ctxt[sid-1].used) + ctxt[sid-1].used = 0; +} + static inline void tic(struct msm_vidc_inst *i, enum profiling_points p, char *b) { From 3cd260e651a0878563c1582e6152d0511f1fd29e Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 2 Dec 2020 20:07:32 +0530 Subject: [PATCH 418/452] msm: vidc: return appropriate error code for overload errors Return -ENOMEM instead of -EBUSY for hardware overload errors. Change-Id: I3b1c54e2035969c929bb2fdaea9e981e9c43ab32 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_common.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index eccec057b747..cf2c71b06be4 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1777,7 +1777,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data) } else if (rc == -ENOTSUPP) { msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED); - } else if (rc == -EBUSY) { + } else if (rc == -ENOMEM) { msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_HW_OVERLOAD); } @@ -5782,7 +5782,7 @@ static int msm_vidc_check_mbpf_supported(struct msm_vidc_inst *inst) if (mbpf > core->resources.max_mbpf) { msm_vidc_print_running_insts(inst->core); - return -EBUSY; + return -ENOMEM; } return 0; @@ -5933,7 +5933,7 @@ static int msm_vidc_check_mbps_supported(struct msm_vidc_inst *inst) "H/W is overloaded. needed: %d max: %d\n", video_load, max_video_load); msm_vidc_print_running_insts(inst->core); - return -EBUSY; + return -ENOMEM; } if (video_load + image_load > max_video_load + max_image_load) { @@ -5942,7 +5942,7 @@ static int msm_vidc_check_mbps_supported(struct msm_vidc_inst *inst) video_load, image_load, max_video_load, max_image_load); msm_vidc_print_running_insts(inst->core); - return -EBUSY; + return -ENOMEM; } } return 0; From ae4c88ee646856098027615985d38c758d15d3e0 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Thu, 3 Dec 2020 13:51:24 +0530 Subject: [PATCH 419/452] msm: vidc: update all intra to allow more than 30 fps Certain clients enables all intra tests for 720p @42 fps. To allow such configuration, which is within the allowed specification, extend the capability. Change-Id: I0a0247e95bb040635c92404c5a342c92c340154c Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 7c5f1a2b1ce5..be9fad4f1300 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -289,7 +289,7 @@ static struct msm_vidc_codec_capability holi_capabilities[] = { {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 35000000, 1, 20000000}, /* All intra encoding usecase specific */ - {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 30, 1, 30}, + {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 60, 1, 30}, /* Image specific */ {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 2, 512}, From a30dfea1551316cb9ee5cac1e385de2c33010fd6 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Thu, 3 Dec 2020 14:11:43 +0530 Subject: [PATCH 420/452] msm: vidc: avoid access to unwanted register While processing the response from video hardware, video driver is accessing a register which does not exist. It is even not needed for functionality purpose. Removing the access for the same. Change-Id: Ib4fec718d2f057860878bf8928b96fb46be47b13 Signed-off-by: Vikash Garodia --- msm/vidc/hfi_ar50_lt.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/msm/vidc/hfi_ar50_lt.c b/msm/vidc/hfi_ar50_lt.c index f883cdfc8d26..85b4909342e7 100644 --- a/msm/vidc/hfi_ar50_lt.c +++ b/msm/vidc/hfi_ar50_lt.c @@ -87,7 +87,6 @@ #define VIDC_WRAPPER_INTR_MASK_A2HCPU_BMSK_AR50_LT 0x4 #define VIDC_WRAPPER_INTR_MASK_A2HCPU_SHFT_AR50_LT 0x2 -#define VIDC_WRAPPER_INTR_CLEAR_AR50_LT (VIDC_WRAPPER_BASE_OFFS_AR50_LT + 0x14) #define VIDC_WRAPPER_INTR_CLEAR_A2HWD_BMSK_AR50_LT 0x10 #define VIDC_WRAPPER_INTR_CLEAR_A2HWD_SHFT_AR50_LT 0x4 #define VIDC_WRAPPER_INTR_CLEAR_A2H_BMSK_AR50_LT 0x4 @@ -246,7 +245,6 @@ void __core_clear_interrupt_ar50_lt(struct venus_hfi_device *device) } __write_register(device, VIDC_CPU_CS_A2HSOFTINTCLR_AR50_LT, 1, DEFAULT_SID); - __write_register(device, VIDC_WRAPPER_INTR_CLEAR_AR50_LT, intr_status, DEFAULT_SID); } int __boot_firmware_ar50_lt(struct venus_hfi_device *device, u32 sid) From da9ca974d5a76caf4d9761b0cc887cc555205837 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 25 Nov 2020 17:08:46 +0530 Subject: [PATCH 421/452] msm: vidc: print only memory usage To avoid overlogging issue, print only memory usage during session rejection. Change-Id: Ie155d5611a998b8e32c8cc5700f4e0a7fbd558ae Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 13b3f30b3605..7945be8a9c3e 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5885,7 +5885,7 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst) s_vpr_e(vidc_inst->sid, "%s: video mem overshoot - reached %llu MB, max_limit %llu MB\n", __func__, total_mem_size >> 20, memory_limit_mbytes); - msm_comm_print_insts_info(core); + msm_comm_print_mem_usage(core); return -EBUSY; } @@ -5900,7 +5900,7 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst) s_vpr_e(vidc_inst->sid, "%s: insufficient device addr space, required %llu, available %llu\n", __func__, non_sec_mem_size, non_sec_cb_size); - msm_comm_print_insts_info(core); + msm_comm_print_mem_usage(core); return -EINVAL; } } From 8929fa4bcc4283e54e4b05d71b387857c168a02a Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Tue, 8 Dec 2020 14:15:21 +0800 Subject: [PATCH 422/452] msm: vidc: limit max and min auto frame rate Limit auto frame rate to [1,platform frame rate capability] before sending to firmware. Change-Id: I96dc4b8d76b7752a76f6c15dcb6b20817857372f Signed-off-by: Shi Zhongbo --- msm/vidc/msm_vidc_common.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index cf2c71b06be4..088f46acec9f 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7768,6 +7768,8 @@ u32 msm_comm_calc_framerate(struct msm_vidc_inst *inst, { u32 framerate = inst->clk_data.frame_rate; u32 interval; + struct msm_vidc_capability *capability; + capability = &inst->capability; if (timestamp_us <= prev_ts) { s_vpr_e(inst->sid, "%s: invalid ts %lld, prev ts %lld\n", @@ -7775,8 +7777,12 @@ u32 msm_comm_calc_framerate(struct msm_vidc_inst *inst, return framerate; } interval = (u32)(timestamp_us - prev_ts); - framerate = ((1000000 + interval / 2) / interval) << 16; - return framerate; + framerate = (1000000 + interval / 2) / interval; + if (framerate > capability->cap[CAP_FRAMERATE].max) + framerate = capability->cap[CAP_FRAMERATE].max; + if (framerate < 1) + framerate = 1; + return framerate << 16; } u32 msm_comm_get_max_framerate(struct msm_vidc_inst *inst) From 9aa7ae0ed15c4c3b04f95cb7104cc621179d31c8 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Thu, 10 Dec 2020 20:40:12 +0530 Subject: [PATCH 423/452] msm: vidc: Update encoder o/p buffer size calc Update enc o/p buffer size calc inline with FW calculations. Change-Id: Ie5aae40cb51909446430b7b8d5ff9405bbcd7f8b Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_buffer_calculations.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index ed1d23c84e20..8c849bc7d162 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -264,6 +264,7 @@ #define HFI_VENUS_HEIGHT_ALIGNMENT 32 #define SYSTEM_LAL_TILE10 192 +#define NUM_MBS_360P (((480 + 15) >> 4) * ((360 + 15) >> 4)) #define NUM_MBS_720P (((1280 + 15) >> 4) * ((720 + 15) >> 4)) #define NUM_MBS_4k (((4096 + 15) >> 4) * ((2304 + 15) >> 4)) #define MB_SIZE_IN_PIXEL (16 * 16) @@ -985,8 +986,8 @@ u32 msm_vidc_calculate_enc_output_frame_size(struct msm_vidc_inst *inst) /* * Encoder output size calculation: 32 Align width/height * For CQ or heic session : YUVsize * 2 - * For resolution < 720p : YUVsize * 4 - * For resolution > 720p & <= 4K : YUVsize / 2 + * For resolution <= 480x360p : YUVsize * 2 + * For resolution > 360p & <= 4K : YUVsize / 2 * For resolution > 4k : YUVsize / 4 * Initially frame_size = YUVsize * 2; */ @@ -1003,8 +1004,8 @@ u32 msm_vidc_calculate_enc_output_frame_size(struct msm_vidc_inst *inst) is_grid_session(inst) || is_image_session(inst)) goto calc_done; - if (mbs_per_frame < NUM_MBS_720P) - frame_size = frame_size << 1; + if (mbs_per_frame <= NUM_MBS_360P) + goto calc_done; /* Default frame_size = YUVsize * 2 */ else if (mbs_per_frame <= NUM_MBS_4k) frame_size = frame_size >> 2; else From e8004219db5dfc8cfa0bf082ccf0352c29888f19 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Tue, 15 Dec 2020 13:18:59 +0530 Subject: [PATCH 424/452] msm: vidc: Fix criteria for hierp num_ref calc [1] num_ref for hierp has to be calculated only if max_layer value is > 1. Since max_layer value 0/1 indicates absence of layer encoding. [2] Fix hybrid_hp num_ref calculation inline with FW calc. Change-Id: I507d58c33529e5976974cc2d5a6e2d3fd8c55026 --- msm/vidc/msm_vidc_buffer_calculations.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index ed1d23c84e20..973eff400d71 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -493,11 +493,11 @@ int msm_vidc_get_num_ref_frames(struct msm_vidc_inst *inst) max_layer = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); if (frame_t->val == V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P && - max_layer->val > 0) { + max_layer->val > 1) { codec = get_v4l2_codec(inst); /* LTR and B - frame not supported with hybrid HP */ if (inst->hybrid_hp) - num_ref = max_layer->val >> 1; + num_ref = (max_layer->val + 1) >> 1; else if (codec == V4L2_PIX_FMT_HEVC) num_ref = ((max_layer->val + 1) / 2) + ltr_count; else if ((codec == V4L2_PIX_FMT_H264) && (max_layer->val < 4)) From cf15569f3dfef16f94a38e5f27a4795c12f02a8a Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Thu, 17 Dec 2020 13:03:39 +0800 Subject: [PATCH 425/452] msm: vdec: update clock data frame rate Update clock data frame rate to client's set value for mbps calculation so as to reject sessions out of mbps capability. Change-Id: I62559172b71fb4d2e911c16be7f07110e53f23a1 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_vdec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 7d4b1de3b252..2e9780442231 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -904,7 +904,9 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER: case V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_8BIT: case V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_10BIT: + break; case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE: + inst->clk_data.frame_rate = ctrl->val; break; case V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE: inst->flags &= ~VIDC_THUMBNAIL; From 66265b505b6ea8e3380c1601c3c5c380328c87d0 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 28 Oct 2020 19:39:42 +0530 Subject: [PATCH 426/452] msm: vidc: yupik: Add platform data Add driver platform data for yupik yupik_v0: 4k@60 Dec, 4k@30 Enc Concurrency: 4k@30 Dec + 1080p@30 Enc yupik_v1: 4k@30 Dec/Enc Concurrency: UHD@30 Dec + 1080p@30 Enc DDR5 UBWC3.0 HBB value: 15 DDR4 UBWC3.0 HBB value: 14 Change-Id: Ia33befb5eb9694fe7eded7b0bed662c0c406c6e9 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_platform.c | 590 +++++++++++++++++++++++++++++++++-- 1 file changed, 564 insertions(+), 26 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index be9fad4f1300..583a63a5e16c 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -88,6 +88,15 @@ static struct msm_vidc_codec_data holi_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 0, 440, 440), }; +static struct msm_vidc_codec_data yupik_codec_data[] = { + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 25, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 25, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 25, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 25, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 25, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 60, 200, 200), +}; + #define ENC HAL_VIDEO_DOMAIN_ENCODER #define DEC HAL_VIDEO_DOMAIN_DECODER #define H264 HAL_VIDEO_CODEC_H264 @@ -429,6 +438,229 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { V4L2_MPEG_VIDEO_HEVC_LEVEL_5}, }; +static struct msm_vidc_codec_capability yupik_capabilities_v0[] = { + /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ + /* Decode spec */ + {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 5760, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 5760, 1, 1080}, + /* (5760 * 2880) / 256 */ + {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 64800, 1, 8160}, + /* ((4096 * 2176) / 256) * 60 fps */ + {CAP_MBS_PER_SECOND, DEC, CODECS_ALL, 36, 2088960, 1, 244800}, + {CAP_FRAMERATE, DEC, CODECS_ALL, 1, 480, 1, 30}, + + /* Encode spec */ + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 2, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 2, 1080}, + /* (4096 * 2176) / 256 */ + {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 8160}, + /* ((4096 * 2176) / 256) * 30 fps */ + {CAP_MBS_PER_SECOND, ENC, CODECS_ALL, 64, 1044480, 1, 244800}, + {CAP_FRAMERATE, ENC, CODECS_ALL, 1, 240, 1, 30}, + + {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 100000000, 1, 20000000}, + {CAP_CABAC_BITRATE, ENC, H264, 1, 100000000, 1, 20000000}, + {CAP_SCALE_X, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, + {CAP_SCALE_Y, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, + {CAP_SCALE_X, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, + {CAP_SCALE_Y, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, + {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, + {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, + {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 2, 1, 0}, + /* ((1920 * 1088) / 256) * 30 fps */ + {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, + 0, 244800, 1, 244800}, + {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, + {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_I_FRAME_QP, DEC, VP9, 0, 127, 1, 20}, + {CAP_P_FRAME_QP, DEC, VP9, 0, 127, 1, 40}, + {CAP_B_FRAME_QP, DEC, VP9, 0, 127, 1, 40}, + /* 10 slices */ + {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_SLICE_MB, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, + + /* Mpeg2 decoder specific */ + {CAP_FRAME_WIDTH, DEC, MPEG2, 96, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, MPEG2, 96, 1920, 1, 1088}, + /* (1920 * 1088) / 256 */ + {CAP_MBS_PER_FRAME, DEC, MPEG2, 36, 8160, 1, 8160}, + /* ((1920 * 1088) / 256) * 30*/ + {CAP_MBS_PER_SECOND, DEC, MPEG2, 36, 244800, 1, 244800}, + {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, + {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, + + /* Vp9 specific */ + {CAP_FRAME_WIDTH, DEC, VP9, 96, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, VP9, 96, 4096, 1, 1080}, + /* (4096 * 2176) / 256 */ + {CAP_MBS_PER_FRAME, DEC, VP9, 36, 34816, 1, 8160}, + /* ((4096 * 2176) / 256) * 60*/ + {CAP_MBS_PER_SECOND, DEC, VP9, 36, 2088960, 1, 244800}, + {CAP_FRAMERATE, DEC, VP9, 1, 60, 1, 60}, + {CAP_BITRATE, DEC, VP9, 1, 100000000, 1, 20000000}, + + /* Secure usecase specific */ + {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 2, 1920}, + {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 2, 1080}, + /* (4096 * 2176) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 34816, 1, 8160}, + {CAP_SECURE_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 8160}, + {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, + + /* Batch Mode Decode */ + {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 36, 8160, 1, 8160}, + /* (1920 * 1088) / 256 */ + {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, + + /* Lossless encoding usecase specific */ + {CAP_LOSSLESS_FRAME_WIDTH, ENC, H264|HEVC, 128, 4096, 2, 1920}, + {CAP_LOSSLESS_FRAME_HEIGHT, ENC, H264|HEVC, 128, 4096, 2, 1080}, + /* (4096 * 2176) / 256 */ + {CAP_LOSSLESS_MBS_PER_FRAME, ENC, H264|HEVC, 64, 34816, 1, 8160}, + + /* All intra encoding usecase specific */ + {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 120, 1, 30}, + + /* Image specific */ + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 16834, 2, 16834}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 16834, 2, 16834}, + + /* Level for AVC and HEVC encoder specific. + * Default for levels is UNKNOWN value. But if we use unknown + * value here to set as default, max value needs to be set to + * unknown as well, which creates a problem of allowing client + * to set higher level than supported + */ + {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, + {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, + + /* Level for AVC and HEVC decoder specific */ + {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, + {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, +}; + +static struct msm_vidc_codec_capability yupik_capabilities_v1[] = { + /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ + {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 2, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 2, 1080}, + /* (4096 * 2176) / 256 */ + {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 34816, 1, 8160}, + {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 8160}, + /* ((4096 * 2176) / 256) * 30 fps */ + {CAP_MBS_PER_SECOND, DEC, CODECS_ALL, 36, 1044480, 1, 244800}, + {CAP_MBS_PER_SECOND, ENC, CODECS_ALL, 64, 1044480, 1, 244800}, + {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 240, 1, 30}, + {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 100000000, 1, 20000000}, + {CAP_CABAC_BITRATE, ENC, H264, 1, 100000000, 1, 20000000}, + {CAP_SCALE_X, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, + {CAP_SCALE_Y, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, + {CAP_SCALE_X, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, + {CAP_SCALE_Y, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, + {CAP_BFRAME, ENC, H264|HEVC, 0, 1, 1, 0}, + {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, + {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 2, 1, 0}, + /* ((1920 * 1088) / 256) * 30 fps */ + {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, + 0, 244800, 1, 244800}, + {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, + {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_I_FRAME_QP, DEC, VP9, 0, 127, 1, 20}, + {CAP_P_FRAME_QP, DEC, VP9, 0, 127, 1, 40}, + {CAP_B_FRAME_QP, DEC, VP9, 0, 127, 1, 40}, + /* 10 slices */ + {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_SLICE_MB, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, + + /* Mpeg2 decoder specific */ + {CAP_FRAME_WIDTH, DEC, MPEG2, 96, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, MPEG2, 96, 1920, 1, 1088}, + /* (1920 * 1088) / 256 */ + {CAP_MBS_PER_FRAME, DEC, MPEG2, 36, 8160, 1, 8160}, + /* ((1920 * 1088) / 256) * 30*/ + {CAP_MBS_PER_SECOND, DEC, MPEG2, 36, 244800, 1, 244800}, + {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, + {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, + + /* Vp9 specific */ + {CAP_FRAME_WIDTH, DEC, VP9, 96, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, VP9, 96, 4096, 1, 1080}, + /* (4096 * 2176) / 256 */ + {CAP_MBS_PER_FRAME, DEC, VP9, 36, 34816, 1, 8160}, + /* ((4096 * 2176) / 256) * 30*/ + {CAP_MBS_PER_SECOND, DEC, VP9, 36, 1044480, 1, 244800}, + {CAP_FRAMERATE, DEC, VP9, 1, 60, 1, 60}, + {CAP_BITRATE, DEC, VP9, 1, 100000000, 1, 20000000}, + + /* Secure usecase specific */ + {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 1, 1080}, + /* (4096 * 2176) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 34816, 1, 8160}, + {CAP_SECURE_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 34816, 1, 8160}, + {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, + + /* Batch Mode Decode */ + {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 36, 8160, 1, 8160}, + /* (1920 * 1088) / 256 */ + {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, + + /* Lossless encoding usecase specific */ + {CAP_LOSSLESS_FRAME_WIDTH, ENC, H264|HEVC, 128, 4096, 2, 1920}, + {CAP_LOSSLESS_FRAME_HEIGHT, ENC, H264|HEVC, 128, 4096, 2, 1080}, + /* (4096 * 2176)/ 256 */ + {CAP_LOSSLESS_MBS_PER_FRAME, ENC, H264|HEVC, 64, 34816, 1, 8160}, + + /* All intra encoding usecase specific */ + {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 120, 1, 30}, + + /* Image specific */ + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 16834, 2, 16834}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 16834, 2, 16834}, + + /* Level for AVC and HEVC encoder specific. + * Default for levels is UNKNOWN value. But if we use unknown + * value here to set as default, max value needs to be set to + * unknown as well, which creates a problem of allowing client + * to set higher level than supported + */ + {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, + {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, + + /* Level for AVC and HEVC decoder specific */ + {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, + {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, +}; + static struct msm_vidc_codec_capability shima_capabilities_v0[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 8192, 1, 1920}, @@ -785,6 +1017,10 @@ static u32 vpe_csc_custom_limit_coeff[HAL_MAX_LIMIT_COEFFS] = { 16, 235, 16, 240, 16, 240 }; +struct allowed_clock_rates_table yupik_clock_data_v1[] = { + {133330000}, {240000000}, {335000000}, {380000000} +}; + struct allowed_clock_rates_table shima_clock_data_v0[] = { {240000000}, {338000000}, {366000000}, {444000000} }; @@ -934,6 +1170,262 @@ static struct msm_vidc_common_data lahaina_common_data[] = { }, }; +static struct msm_vidc_common_data yupik_common_data_v0[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,fw-unload-delay", + .value = 1000, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 3, + }, + { + .key = "qcom,max-hw-load", + .value = 2088960, + /* ((4096x2176)/256)@60 + * 4k@30 decode + 1080p@30 encode + */ + }, + { + .key = "qcom,max-image-load", + .value = 1048576, /* ((16384x16384)/256)@1fps */ + }, + { + .key = "qcom,max-mbpf", + .value = 139264, /* ((4096x2176)/256) x 4 */ + }, + { + .key = "qcom,max-hq-mbs-per-frame", + .value = 8160, /* ((1920x1088)/256) */ + }, + { + .key = "qcom,max-hq-mbs-per-sec", + .value = 244800, /* ((1920x1088)/256)@30fps */ + }, + { + .key = "qcom,max-b-frame-mbs-per-frame", + .value = 8160, /* ((1920x1088)/256) */ + }, + { + .key = "qcom,max-b-frame-mbs-per-sec", + .value = 489600, /* ((1920x1088)/256) MBs@60fps */ + }, + { + .key = "qcom,power-collapse-delay", + .value = 1500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,debug-timeout", + .value = 0, + }, + { + .key = "qcom,decode-batching", + .value = 1, + }, + { + .key = "qcom,batch-timeout", + .value = 200, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, + { + .key = "qcom,fw-cycles", + .value = 436000, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 166667, + }, + { + .key = "qcom,avsync-window-size", + .value = 40, + }, + { + .key = "qcom,prefetch_non_pix_buf_count", + .value = 1, + }, + { + .key = "qcom,prefetch_non_pix_buf_size", + /* + * Internal buffer size is calculated for secure decode session + * of resolution 4k (4096x2160) + * Internal buf size = calculate_scratch_size() + + * calculate_scratch1_size() + calculate_persist1_size() + * Take maximum between VP9 10bit, HEVC 10bit, AVC, MPEG2 secure + * decoder sessions + */ + .value = 209715200, + }, + { + .key = "qcom,prefetch_pix_buf_count", + .value = 18, + }, + { + .key = "qcom,prefetch_pix_buf_size", + /* + * Calculated by VENUS_BUFFER_SIZE for 4096x2160 UBWC + */ + .value = 13434880, + }, + { + .key = "qcom,ubwc_stats_in_fbd", + .value = 0, + }, + { + .key = "qcom,vpp_delay_supported", + .value = 0, + }, + { + .key = "qcom,enc_auto_dynamic_fps", + .value = 0, + }, +}; + +static struct msm_vidc_common_data yupik_common_data_v1[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,fw-unload-delay", + .value = 1000, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 3, + }, + { + .key = "qcom,max-hw-load", + .value = 1224000, + /* UHD@30 decode + 1080p@30 encode */ + }, + { + .key = "qcom,max-image-load", + .value = 1048576, /* ((16384x16384)/256)@1fps */ + }, + { + .key = "qcom,max-mbpf", + .value = 139264, /* ((4096x2176)/256) x 4 */ + }, + { + .key = "qcom,max-hq-mbs-per-frame", + .value = 8160, /* ((1920x1088)/256) */ + }, + { + .key = "qcom,max-hq-mbs-per-sec", + .value = 244800, /* ((1920x1088)/256)@30fps */ + }, + { + .key = "qcom,max-b-frame-mbs-per-frame", + .value = 8160, /* ((1920x1088)/256) */ + }, + { + .key = "qcom,max-b-frame-mbs-per-sec", + .value = 489600, /* ((1920x1088)/256) MBs@60fps */ + }, + { + .key = "qcom,power-collapse-delay", + .value = 1500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,debug-timeout", + .value = 0, + }, + { + .key = "qcom,decode-batching", + .value = 1, + }, + { + .key = "qcom,batch-timeout", + .value = 200, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, + { + .key = "qcom,fw-cycles", + .value = 436000, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 166667, + }, + { + .key = "qcom,avsync-window-size", + .value = 40, + }, + { + .key = "qcom,prefetch_non_pix_buf_count", + .value = 1, + }, + { + .key = "qcom,prefetch_non_pix_buf_size", + /* + * Internal buffer size is calculated for secure decode session + * of resolution 4k (4096x2160) + * Internal buf size = calculate_scratch_size() + + * calculate_scratch1_size() + calculate_persist1_size() + * Take maximum between VP9 10bit, HEVC 10bit, AVC, MPEG2 secure + * decoder sessions + */ + .value = 209715200, + }, + { + .key = "qcom,prefetch_pix_buf_count", + .value = 18, + }, + { + .key = "qcom,prefetch_pix_buf_size", + /* + * Calculated by VENUS_BUFFER_SIZE for 4096x2160 UBWC + */ + .value = 13434880, + }, + { + .key = "qcom,ubwc_stats_in_fbd", + .value = 0, + }, + { + .key = "qcom,vpp_delay_supported", + .value = 0, + }, + { + .key = "qcom,enc_auto_dynamic_fps", + .value = 0, + }, +}; + static struct msm_vidc_common_data bengal_common_data_v0[] = { { .key = "qcom,never-unload-fw", @@ -1479,6 +1971,11 @@ static struct msm_vidc_common_data holi_common_data[] = { }, }; +static struct msm_vidc_efuse_data yupik_efuse_data[] = { + /* IRIS_4K60_FMAX_LIMIT_EFUSE - max 4K@60 */ + EFUSE_ENTRY(0x007801E8, 4, 0x00004000, 0x0E, SKU_VERSION), +}; + static struct msm_vidc_efuse_data shima_efuse_data[] = { /* IRIS_4K60_FMAX_LIMIT_EFUSE - max 4K@60 */ EFUSE_ENTRY(0x007801E0, 4, 0x00200000, 0x15, SKU_VERSION), @@ -1491,6 +1988,11 @@ static struct msm_vidc_ubwc_config_data lahaina_ubwc_data[] = { UBWC_CONFIG(1, 1, 1, 0, 0, 0, 8, 32, 16, 0, 0), }; +/* Default UBWC config for LPDDR5 */ +static struct msm_vidc_ubwc_config_data yupik_ubwc_data[] = { + UBWC_CONFIG(1, 1, 1, 0, 0, 0, 8, 32, 15, 0, 0), +}; + /* Default UBWC config for LPDDR5 */ static struct msm_vidc_ubwc_config_data shima_ubwc_data[] = { UBWC_CONFIG(1, 1, 1, 0, 0, 0, 8, 32, 15, 0, 0), @@ -1536,6 +2038,30 @@ static struct msm_vidc_platform_data lahaina_data = { .vpss_caps_count = ARRAY_SIZE(vpss_capabilities), }; +static struct msm_vidc_platform_data yupik_data = { + .codec_data = yupik_codec_data, + .codec_data_length = ARRAY_SIZE(yupik_codec_data), + .clock_data = NULL, + .clock_data_length = 0, + .common_data = yupik_common_data_v0, + .common_data_length = ARRAY_SIZE(yupik_common_data_v0), + .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, + .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, + .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, + .efuse_data = yupik_efuse_data, + .efuse_data_length = ARRAY_SIZE(yupik_efuse_data), + .sku_version = 0, + .vpu_ver = VPU_VERSION_IRIS2_1, + .num_vpp_pipes = 0x1, + .ubwc_config = yupik_ubwc_data, + .codecs = default_codecs, + .codecs_count = ARRAY_SIZE(default_codecs), + .codec_caps = yupik_capabilities_v0, + .codec_caps_count = ARRAY_SIZE(yupik_capabilities_v0), + .vpss_caps = vpss_capabilities, + .vpss_caps_count = ARRAY_SIZE(vpss_capabilities), +}; + static struct msm_vidc_platform_data bengal_data = { .codec_data = bengal_codec_data, .codec_data_length = ARRAY_SIZE(bengal_codec_data), @@ -1625,6 +2151,10 @@ static const struct of_device_id msm_vidc_dt_device[] = { .compatible = "qcom,holi-vidc", .data = &holi_data, }, + { + .compatible = "qcom,yupik-vidc", + .data = &yupik_data, + }, {}, }; @@ -1686,11 +2216,30 @@ static int msm_vidc_read_rank( return 0; } +static inline void msm_vidc_ddr_ubwc_config( + struct msm_vidc_platform_data *driver_data, u32 hbb_override_val) +{ + uint32_t ddr_type = DDR_TYPE_LPDDR5; + + ddr_type = of_fdt_get_ddrtype(); + if (ddr_type == -ENOENT) { + d_vpr_e("Failed to get ddr type, use LPDDR5\n"); + } + + if (driver_data->ubwc_config && + (ddr_type == DDR_TYPE_LPDDR4 || + ddr_type == DDR_TYPE_LPDDR4X)) + driver_data->ubwc_config->highest_bank_bit = hbb_override_val; + + d_vpr_h("DDR Type 0x%x hbb 0x%x\n", + ddr_type, driver_data->ubwc_config ? + driver_data->ubwc_config->highest_bank_bit : -1); +} + void *vidc_get_drv_data(struct device *dev) { struct msm_vidc_platform_data *driver_data = NULL; const struct of_device_id *match; - uint32_t ddr_type = DDR_TYPE_LPDDR5; int rc = 0; if (!IS_ENABLED(CONFIG_OF) || !dev->of_node) { @@ -1713,19 +2262,7 @@ void *vidc_get_drv_data(struct device *dev) goto exit; if (!strcmp(match->compatible, "qcom,lahaina-vidc")) { - ddr_type = of_fdt_get_ddrtype(); - if (ddr_type == -ENOENT) { - d_vpr_e("Failed to get ddr type, use LPDDR5\n"); - } - - if (driver_data->ubwc_config && - (ddr_type == DDR_TYPE_LPDDR4 || - ddr_type == DDR_TYPE_LPDDR4X)) - driver_data->ubwc_config->highest_bank_bit = 0xf; - - d_vpr_h("DDR Type 0x%x hbb 0x%x\n", - ddr_type, driver_data->ubwc_config ? - driver_data->ubwc_config->highest_bank_bit : -1); + msm_vidc_ddr_ubwc_config(driver_data, 0xf); } else if (!strcmp(match->compatible, "qcom,bengal-vidc")) { rc = msm_vidc_read_rank(driver_data, dev); if (rc) { @@ -1761,19 +2298,20 @@ void *vidc_get_drv_data(struct device *dev) driver_data->codec_caps_count = ARRAY_SIZE(shima_capabilities_v2); } - ddr_type = of_fdt_get_ddrtype(); - if (ddr_type == -ENOENT) { - d_vpr_e("Failed to get ddr type, use LPDDR5\n"); + msm_vidc_ddr_ubwc_config(driver_data, 0xe); + } else if (!strcmp(match->compatible, "qcom,yupik-vidc")) { + if (driver_data->sku_version == SKU_VERSION_1) { + driver_data->clock_data = yupik_clock_data_v1; + driver_data->clock_data_length = + ARRAY_SIZE(yupik_clock_data_v1);; + driver_data->common_data = yupik_common_data_v1; + driver_data->common_data_length = + ARRAY_SIZE(yupik_common_data_v1); + driver_data->codec_caps = yupik_capabilities_v1; + driver_data->codec_caps_count = + ARRAY_SIZE(yupik_capabilities_v1); } - - if (driver_data->ubwc_config && - (ddr_type == DDR_TYPE_LPDDR4 || - ddr_type == DDR_TYPE_LPDDR4X)) - driver_data->ubwc_config->highest_bank_bit = 0xe; - - d_vpr_h("DDR Type 0x%x hbb 0x%x\n", - ddr_type, driver_data->ubwc_config ? - driver_data->ubwc_config->highest_bank_bit : -1); + msm_vidc_ddr_ubwc_config(driver_data, 0xe); } exit: return driver_data; From 83b35fa14a82065dc9d67dd2ee58535563e783f5 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 6 Jan 2021 11:19:04 +0530 Subject: [PATCH 427/452] msm: vidc: Update offset for yupik FMAX fuse Update offset from 14 to 21 for yupik fmax fuse. IRIS_PLL_FMAX: Limits the enc/dec capability to 4k@30. Change-Id: I60dc110e85a5aa7d4427424b401b759e49d345ac Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_platform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 583a63a5e16c..75259c34c5c0 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1972,8 +1972,8 @@ static struct msm_vidc_common_data holi_common_data[] = { }; static struct msm_vidc_efuse_data yupik_efuse_data[] = { - /* IRIS_4K60_FMAX_LIMIT_EFUSE - max 4K@60 */ - EFUSE_ENTRY(0x007801E8, 4, 0x00004000, 0x0E, SKU_VERSION), + /* IRIS_PLL_FMAX - max 4K@30 */ + EFUSE_ENTRY(0x007801E8, 4, 0x00200000, 0x15, SKU_VERSION), }; static struct msm_vidc_efuse_data shima_efuse_data[] = { From 76cae5a345ced8afef26ffd435b44c44befcf279 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Thu, 7 Jan 2021 12:44:31 +0530 Subject: [PATCH 428/452] msm: vidc: Amend DCVS handling for encoder For DCVS, there are mainly 3 buffer count watermarks i.e low, normal, high. When the buffers held with firmware goes above high or below low, DCVS changes the clock to high or low respectively. At this state, to come back to normal clock, it needs the buffer in firmware to come back to normal count. For cases, when DCVS decides to decrease the clock, the clock remains lowered till the buffer count in firmware is back to normal. During this phase, the clock remains low and impacts performance. Since encode usecase always desire more clock, keeping low for them leads to measurable impact. The fix considers a case for encoder to bring back to normal clock when the buffer count is more than low watermark. CRs-Fixed: 2845570 Change-Id: I426a17f7b16db544ea09ec072c77e95198634c84 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_clocks.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index aa8825caa007..271178a1e1a0 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -525,7 +525,10 @@ static int msm_dcvs_scale_clocks(struct msm_vidc_inst *inst, } else if ((dcvs->dcvs_flags & MSM_VIDC_DCVS_DECR && bufs_with_fw >= dcvs->nom_threshold) || (dcvs->dcvs_flags & MSM_VIDC_DCVS_INCR && - bufs_with_fw <= dcvs->nom_threshold)) + bufs_with_fw <= dcvs->nom_threshold) || + (inst->session_type == MSM_VIDC_ENCODER && + dcvs->dcvs_flags & MSM_VIDC_DCVS_DECR && + bufs_with_fw >= dcvs->min_threshold)) dcvs->dcvs_flags = 0; s_vpr_p(inst->sid, "DCVS: bufs_with_fw %d Th[%d %d %d] Flag %#x\n", From 5bf127b94f38f9ec179e767f84716845365e719a Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Fri, 8 Jan 2021 13:40:50 +0530 Subject: [PATCH 429/452] msm: vidc: Increase 10-bit enc o/p buffer size for <=360p Increase 10-bit enc bistream buffer size for <=360p. For 8-bit YUV size : w x h x 1.5 For 10-bit YUV size : w x h x 1.5 x 2 Change-Id: I6fddcf960b8b06fe6edbe4b8262374303a045530 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_buffer_calculations.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 3052801b9589..2db5696313c7 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1005,7 +1005,7 @@ u32 msm_vidc_calculate_enc_output_frame_size(struct msm_vidc_inst *inst) goto calc_done; if (mbs_per_frame <= NUM_MBS_360P) - goto calc_done; /* Default frame_size = YUVsize * 2 */ + (void)frame_size; /* Default frame_size = YUVsize * 2 */ else if (mbs_per_frame <= NUM_MBS_4k) frame_size = frame_size >> 2; else From 8c49286d812aab237ead4097ff9ed3b864154db2 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Sat, 23 Jan 2021 16:09:35 +0530 Subject: [PATCH 430/452] msm: vidc: Update level for avc enc/dec Update level for enc on both the SKU's Update level for dec on 4k@30 dec SKU. Change-Id: I6c4c2d55179e154afcd54bb362f47aeab4189bba --- msm/vidc/msm_vidc_platform.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 75259c34c5c0..cd7330ba623f 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -538,7 +538,7 @@ static struct msm_vidc_codec_capability yupik_capabilities_v0[] = { * to set higher level than supported */ {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, @@ -646,7 +646,7 @@ static struct msm_vidc_codec_capability yupik_capabilities_v1[] = { * to set higher level than supported */ {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, @@ -654,7 +654,7 @@ static struct msm_vidc_codec_capability yupik_capabilities_v1[] = { /* Level for AVC and HEVC decoder specific */ {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_5_2, 1, V4L2_MPEG_VIDEO_H264_LEVEL_4_0}, {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, From 12a438218427759055b0bcf15d92d12621f21007 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Thu, 28 Jan 2021 15:25:47 +0530 Subject: [PATCH 431/452] msm: vidc: Increase dec batching spec for Yupik Update decode batching spec for yupik to 1080p@60. Change-Id: I87d73872655ebfc0afb38862ff5e7c3324dac83e --- msm/vidc/msm_vidc_platform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 75259c34c5c0..425e2236a367 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -514,7 +514,7 @@ static struct msm_vidc_codec_capability yupik_capabilities_v0[] = { /* Batch Mode Decode */ {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 36, 8160, 1, 8160}, /* (1920 * 1088) / 256 */ - {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, + {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 60, 1, 30}, /* Lossless encoding usecase specific */ {CAP_LOSSLESS_FRAME_WIDTH, ENC, H264|HEVC, 128, 4096, 2, 1920}, @@ -622,7 +622,7 @@ static struct msm_vidc_codec_capability yupik_capabilities_v1[] = { /* Batch Mode Decode */ {CAP_BATCH_MAX_MB_PER_FRAME, DEC, CODECS_ALL, 36, 8160, 1, 8160}, /* (1920 * 1088) / 256 */ - {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 30, 1, 30}, + {CAP_BATCH_MAX_FPS, DEC, CODECS_ALL, 1, 60, 1, 30}, /* Lossless encoding usecase specific */ {CAP_LOSSLESS_FRAME_WIDTH, ENC, H264|HEVC, 128, 4096, 2, 1920}, From fd0413602c2ed4570e2d23ec4da97a8f346d6097 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 27 Jan 2021 14:02:03 +0530 Subject: [PATCH 432/452] msm: vidc: add work_mode and latency debug info for holi Automation scripts expects work_mode and low_latency config related debug prints to evaluate testcase pass/fail. So added debug prints for holi. Change-Id: I8ab051e0efbb8c8e78a9085e2fc79e7fe43e9c99 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_clocks.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 271178a1e1a0..68841ff06206 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1282,6 +1282,7 @@ static int msm_vidc_decide_work_mode_ar50_lt(struct msm_vidc_inst *inst) /* For WORK_MODE_1, set Low Latency mode by default to HW. */ + latency.enable = false; if (inst->session_type == MSM_VIDC_ENCODER && inst->clk_data.work_mode == HFI_WORKMODE_1) { latency.enable = true; @@ -1291,6 +1292,10 @@ static int msm_vidc_decide_work_mode_ar50_lt(struct msm_vidc_inst *inst) (void *)&latency, sizeof(latency)); } + s_vpr_h(inst->sid, "Configuring work mode = %u low latency = %u", + pdata.video_work_mode, + latency.enable); + rc = msm_comm_scale_clocks_and_bus(inst, 1); return rc; From 5d09f02e14f8a897eb510c0ecbec97ce891b0ef5 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Tue, 16 Feb 2021 11:53:24 +0530 Subject: [PATCH 433/452] msm: vidc: Update BSE TLB write for H264 dec BSE TLB write is half of TLB read for H264 decoder Change-Id: Ifbe3ef1a6e6f827f4bcc7a15e1ff0a0df3f8ce12 --- msm/vidc/msm_vidc_bus_iris2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_bus_iris2.c b/msm/vidc/msm_vidc_bus_iris2.c index db922351b54d..79f3f40184c1 100644 --- a/msm/vidc/msm_vidc_bus_iris2.c +++ b/msm/vidc/msm_vidc_bus_iris2.c @@ -168,9 +168,9 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) FP_INT(bps(1))); /* This change is applicable for all IRIS2 targets, * but currently being done for IRIS2 with 2 pipes - * only due to timeline constraints. + * and 1 pipe only due to timeline constraints. */ - if((num_vpp_pipes == 2) && (is_h264_category)) + if((num_vpp_pipes != 4) && (is_h264_category)) ddr.line_buffer_write = fp_div(ddr.line_buffer_read,FP_INT(2)); else ddr.line_buffer_write = ddr.line_buffer_read; From fc3bb5ec5e5eb90e2008b5e1086266946fb74540 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Fri, 19 Feb 2021 12:03:53 +0530 Subject: [PATCH 434/452] msm: vidc: Update BW calc for yupik 1. Update BSE TLB read calculation for H264 decoder 2. Update vertical_tile_width value for encoder Change-Id: Id9adfbaeb1acce3e40113d48e48395e7882d2516 --- msm/vidc/msm_vidc_bus_iris2.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/msm/vidc/msm_vidc_bus_iris2.c b/msm/vidc/msm_vidc_bus_iris2.c index 79f3f40184c1..187820fc41a5 100644 --- a/msm/vidc/msm_vidc_bus_iris2.c +++ b/msm/vidc/msm_vidc_bus_iris2.c @@ -115,7 +115,15 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) dpb_factor = FP(1, 50, 100); dpb_write_factor = FP(1, 5, 100); - tnbr_per_lcu = lcu_size == 16 ? 128 : + /* Ref A: This change is applicable for all + * IRIS2 targets, but currently being done for + * 1 pipe only due to timeline constraints. + */ + if (num_vpp_pipes == 1) + tnbr_per_lcu = lcu_size == 16 ? 64 : + lcu_size == 32 ? 64 : 128; + else + tnbr_per_lcu = lcu_size == 16 ? 128 : lcu_size == 32 ? 64 : 128; /* .... For DDR & LLC ...... */ @@ -166,11 +174,11 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d) ddr.line_buffer_read = fp_div(FP_INT(tnbr_per_lcu * lcu_per_frame * fps), FP_INT(bps(1))); - /* This change is applicable for all IRIS2 targets, - * but currently being done for IRIS2 with 2 pipes - * and 1 pipe only due to timeline constraints. + /* This change is applicable when 'Ref A' code change + * is missing. But currently being done for IRIS2 + * with 2 pipes only due to timeline constraints. */ - if((num_vpp_pipes != 4) && (is_h264_category)) + if ((num_vpp_pipes == 2) && (is_h264_category)) ddr.line_buffer_write = fp_div(ddr.line_buffer_read,FP_INT(2)); else ddr.line_buffer_write = ddr.line_buffer_read; @@ -289,6 +297,7 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) total_ref_read_crcb, qsmmu_bw_overhead_factor; fp_t integer_part, frac_part; + unsigned int num_vpp_pipes; unsigned long ret = 0; /* Output parameters */ @@ -307,7 +316,6 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) /* Encoder Parameters setup */ rotation = d->rotation; cropping_or_scaling = false; - vertical_tile_width = 960; /* * recon_write_bw_factor varies according to resolution and bit-depth, * here use 1.08(1.075) for worst case. @@ -321,6 +329,7 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) /* Derived Parameters */ + num_vpp_pipes = d->num_vpp_pipes; fps = d->fps; width = max(d->output_width, BASELINE_DIMENSIONS.width); height = max(d->output_height, BASELINE_DIMENSIONS.height); @@ -346,9 +355,15 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d) } b_frames_enabled = d->b_frames_enabled; + if (num_vpp_pipes == 1 && b_frames_enabled) + vertical_tile_width = 480; + else if (num_vpp_pipes == 1 && !b_frames_enabled) + vertical_tile_width = 672; + else + vertical_tile_width = 960; + original_color_format = d->num_formats >= 1 ? d->color_formats[0] : HFI_COLOR_FORMAT_NV12_UBWC; - original_compression_enabled = __ubwc(original_color_format); work_mode_1 = d->work_mode == HFI_WORKMODE_1; From 36f3788ea4d8a0e5e6c9c9888e0f5b6b5cc6e398 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Tue, 23 Feb 2021 17:28:36 +0800 Subject: [PATCH 435/452] msm: vidc: enable hdr10 sei only when client set it For HLG HDR recording, client won't set HDR10 SEI, and driver shouldn't set this info to firmware either. Otherwise some applications may have wrong behavior when HDR10 SEI is present in HLG clips. Change-Id: I7a054ded39e3b9309d823e97da039f0de1bcde9d Signed-off-by: Qiwei Liu --- msm/vidc/msm_venc.c | 5 ++++- msm/vidc/msm_vidc_internal.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index b5499c609a50..bc15a1383ed4 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1231,6 +1231,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) msm_vidc_init_buffer_size_calculators(inst); inst->static_rotation_flip_enabled = false; inst->external_blur = false; + inst->hdr10_sei_enabled = false; return rc; } @@ -1722,6 +1723,7 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) u32 info_type = ((u32)ctrl->val >> 28) & 0xF; u32 val = (ctrl->val & 0xFFFFFFF); + inst->hdr10_sei_enabled = true; s_vpr_h(sid, "Ctrl:%d, HDR Info with value %u (%#X)", info_type, val, ctrl->val); switch (info_type) { @@ -4569,7 +4571,8 @@ int msm_venc_set_hdr_info(struct msm_vidc_inst *inst) } hdev = inst->core->device; - if (get_v4l2_codec(inst) != V4L2_PIX_FMT_HEVC) + if (get_v4l2_codec(inst) != V4L2_PIX_FMT_HEVC || + !inst->hdr10_sei_enabled) return 0; profile = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_PROFILE); diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index b85e43d1b270..153464382683 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -571,6 +571,7 @@ struct msm_vidc_inst { bool external_blur; struct internal_buf *dpb_extra_binfo; struct msm_vidc_codec_data *codec_data; + bool hdr10_sei_enabled; struct hal_hdr10_pq_sei hdr10_sei_params; struct batch_mode batch; struct delayed_work batch_work; From b28166cbf042092c22fa8f9470b68724ff8694ed Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Tue, 2 Mar 2021 16:51:20 +0530 Subject: [PATCH 436/452] msm: vidc: Release scratch buffers of size 0 during reconfig Release the existing scratch buffers instead of reuse, provided the new buffer requirements is of size zero. For ex, scratch buffer for interlace clips is zero. Change-Id: Ic540839f1b5f8063ae5a1e4eda6df90b60b49af5 --- msm/vidc/msm_vidc_common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 0e32af28ef4c..7f6af02398e2 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5150,6 +5150,7 @@ static enum hal_buffer scratch_buf_sufficient(struct msm_vidc_inst *inst, list_for_each_entry(buf, &inst->scratchbufs.list, list) { if (buf->buffer_type == buffer_type && + bufreq->buffer_size && buf->smem.size >= bufreq->buffer_size) count++; } From 26782be24885a6384b8e0b930b6b160933fcbb3f Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 22 Mar 2021 20:05:20 +0530 Subject: [PATCH 437/452] msm: vidc: Allocate required bin size for >=UHD enc Allocate equal bin size across all the pipes for encoder >=UHD Change-Id: Id6a4c2bda50da2bbd81e968be22b76bada51449a --- msm/vidc/msm_vidc_buffer_calculations.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 2db5696313c7..997c1ee62749 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1439,7 +1439,7 @@ static inline u32 calculate_enc_scratch_size(struct msm_vidc_inst *inst, bitbin_size = ALIGN(bitstream_size, VENUS_DMA_ALIGNMENT); } if (aligned_width * aligned_height >= 3840 * 2160) - size_singlePipe = bitbin_size / 4; + size_singlePipe = bitbin_size / num_vpp_pipes; else if (num_vpp_pipes > 2) size_singlePipe = bitbin_size / 2; else From 8f2e5d783215a6c74605ccc326d226a228569724 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 24 Mar 2021 11:31:46 +0530 Subject: [PATCH 438/452] msm: vidc: Add check for maximum height While accepting a video session, keep a check for frame height w.r.t maximum capability. CRs-Fixed: 2883699 Change-Id: I068dd9af868093dbdddf0301d8d40a95643314e0 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_common.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 7f6af02398e2..7ff136aff22e 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #include @@ -6162,10 +6162,12 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) width_min, height_min); rc = -ENOTSUPP; } - if (!rc && output_width > width_max) { + if (!rc && (output_width > width_max || + output_height > height_max)) { s_vpr_e(sid, - "Unsupported width = %u supported max width = %u\n", - output_width, width_max); + "Unsupported WxH (%u)x(%u), max supported is (%u)x(%u)\n", + output_width, output_height, + width_max, height_max); rc = -ENOTSUPP; } From 15964d66631b092057df878507d3a3e869097bc6 Mon Sep 17 00:00:00 2001 From: Laisheng Hu Date: Thu, 4 Feb 2021 16:26:36 +0800 Subject: [PATCH 439/452] msm: vidc: fix memory leak in open/close refbufs should be destroyed in vidc close. CRs-Fixed: 2846268 Change-Id: Ic36b7ac824a6c46524b0c4f0ca364e9c87f015ba Signed-off-by: Laisheng Hu --- msm/vidc/msm_vidc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index e5e3f4db8c26..d848eb08976b 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1648,6 +1648,7 @@ void *msm_vidc_open(int core_id, int session_type) DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq); DEINIT_MSM_VIDC_LIST(&inst->outputbufs); DEINIT_MSM_VIDC_LIST(&inst->registeredbufs); + DEINIT_MSM_VIDC_LIST(&inst->refbufs); DEINIT_MSM_VIDC_LIST(&inst->eosbufs); DEINIT_MSM_VIDC_LIST(&inst->input_crs); DEINIT_MSM_VIDC_LIST(&inst->etb_data); @@ -1775,6 +1776,7 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq); DEINIT_MSM_VIDC_LIST(&inst->outputbufs); DEINIT_MSM_VIDC_LIST(&inst->registeredbufs); + DEINIT_MSM_VIDC_LIST(&inst->refbufs); DEINIT_MSM_VIDC_LIST(&inst->eosbufs); DEINIT_MSM_VIDC_LIST(&inst->input_crs); DEINIT_MSM_VIDC_LIST(&inst->etb_data); From f537e62907920b4b0eba630e7197494b6e50c266 Mon Sep 17 00:00:00 2001 From: Anand Abhishek Date: Fri, 2 Apr 2021 11:58:38 +0530 Subject: [PATCH 440/452] msm: vidc: Resolve compilation erorr on 32bit device Division(/) and modulus(%) are failed to link on 32-bit kernel. To resolve the linker error, use API for division and modulus which are available for both 32bit and 64bit architecture. Change-Id: Ib45b993c5ec4eee45d5f50e0d7b6d4831c256d8c --- msm/vidc/msm_vidc_common.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 7ff136aff22e..13a4b9ecdfd5 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7805,7 +7805,7 @@ u32 msm_comm_get_max_framerate(struct msm_vidc_inst *inst) count++; avg_framerate += node->framerate; } - avg_framerate = count ? (avg_framerate / count) : (1 << 16); + avg_framerate = count ? (div_u64(avg_framerate, count)) : (1 << 16); s_vpr_l(inst->sid, "%s: fps %u, list size %d\n", __func__, avg_framerate, count); mutex_unlock(&inst->timestamps.lock); @@ -7819,6 +7819,8 @@ int msm_comm_fetch_ts_framerate(struct msm_vidc_inst *inst, int rc = 0; bool invalidate_extra = false; u32 input_tag = 0, input_tag2 = 0; + s32 factor = 1000000; + s32 remainder = 0; if (!inst || !b) { d_vpr_e("%s: invalid parameters\n", __func__); @@ -7854,8 +7856,8 @@ int msm_comm_fetch_ts_framerate(struct msm_vidc_inst *inst, if (!(b->flags & V4L2_BUF_FLAG_END_OF_SUBFRAME)) node->is_valid = false; - b->timestamp.tv_sec = node->timestamp_us / 1000000; - b->timestamp.tv_usec = node->timestamp_us % 1000000; + b->timestamp.tv_sec = div_s64_rem(node->timestamp_us, factor, &remainder); + b->timestamp.tv_usec = remainder; b->m.planes[0].reserved[MSM_VIDC_FRAMERATE] = node->framerate; break; } From f0556555c7d7758f8cdbfdec81fbb2eb818aca14 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 24 May 2021 15:02:49 +0530 Subject: [PATCH 441/452] msm: vidc: Allow adaptive B frame encode for hevc Both H264 and HEVC can support adaptive B frame encoding. Change-Id: I4b51a224d9ed9bb173f40ea5c4c919ff2800a85c --- msm/vidc/msm_venc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index bc15a1383ed4..2002a8bccaf3 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2501,7 +2501,8 @@ int msm_venc_set_intra_period(struct msm_vidc_inst *inst) intra_period.pframes = gop_size->val; - if (!max_layer->val && codec == V4L2_PIX_FMT_H264) { + /* max_layer 0/1 indicates absence of layer encoding */ + if (max_layer->val < 2) { /* * At this point we've already made decision on bframe. * Control value gives updated bframe value. From ca17de823f14307056f41f826dc69109bb4f2bab Mon Sep 17 00:00:00 2001 From: Santhosh Behara Date: Thu, 20 May 2021 19:50:19 +0530 Subject: [PATCH 442/452] msm: vidc: Add support for encoder complexity Add support for encoder complexity handling. Enable lowpower mode if the complexity is 0. Change-Id: Ife290b377c844e5b1d3be93b2509c787f8e05c59 Signed-off-by: Santhosh Behara --- include/uapi/vidc/media/msm_vidc_utils.h | 2 ++ msm/vidc/msm_venc.c | 15 +++++++++++++++ msm/vidc/msm_vidc_clocks.c | 4 ++++ 3 files changed, 21 insertions(+) diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index e45ffa06f231..73ff48f86ca4 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -261,6 +261,8 @@ enum v4l2_mpeg_vidc_video_bitrate_savings_type { (V4L2_CID_MPEG_MSM_VIDC_BASE + 135) #define V4L2_CID_MPEG_VIDC_VIDEO_DISABLE_TIMESTAMP_REORDER \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 136) +#define V4L2_CID_MPEG_VIDC_VENC_COMPLEXITY \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 137) #define V4L2_CID_MPEG_VIDC_VIDEO_UNKNOWN \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 0xFFF) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index bc15a1383ed4..68a9118d6c4f 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -596,6 +596,16 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .step = 1, .menu_skip_mask = 0, }, + { + .id = V4L2_CID_MPEG_VIDC_VENC_COMPLEXITY, + .name = "Encoder complexity", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 100, + .default_value = 100, + .step = 1, + .qmenu = NULL, + }, { .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE, .name = "Set Hier coding type", @@ -1976,6 +1986,11 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VENC_BITRATE_BOOST: inst->boost_enabled = true; break; + case V4L2_CID_MPEG_VIDC_VENC_COMPLEXITY: + if (is_realtime_session(inst)) { + s_vpr_h(sid, "Client is setting complexity for RT session\n"); + } + break; case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: inst->entropy_mode = msm_comm_v4l2_to_hfi( V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 68841ff06206..7ddf39a1ba70 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1434,6 +1434,7 @@ static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, void *pdata = NULL; struct hfi_device *hdev = NULL; u32 hfi_perf_mode; + struct v4l2_ctrl *ctrl; hdev = inst->core->device; if (inst->session_type != MSM_VIDC_ENCODER) { @@ -1443,6 +1444,9 @@ static inline int msm_vidc_power_save_mode_enable(struct msm_vidc_inst *inst, return 0; } + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_COMPLEXITY); + if (!is_realtime_session(inst) && !ctrl->val) + enable = true; prop_id = HFI_PROPERTY_CONFIG_VENC_PERF_MODE; hfi_perf_mode = enable ? HFI_VENC_PERFMODE_POWER_SAVE : HFI_VENC_PERFMODE_MAX_QUALITY; From b1b38cd3475823b37ba9026edf1aec0a33505d60 Mon Sep 17 00:00:00 2001 From: Sayantan Majumder Date: Tue, 15 Jun 2021 14:45:48 +0530 Subject: [PATCH 443/452] msm: vidc: enabling new DTSI compatibility for IOT specific target Added new compatibility string to enable video H/W acceleration for qcm6490 Change-Id: I51fcc010cc85e05f26ac5b1e8d3ba4ad5fa8b052 Signed-off-by: Sayantan Majumder --- msm/vidc/msm_vidc_platform.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index af7fb8f00f1f..74dd3730dd31 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -2155,6 +2155,10 @@ static const struct of_device_id msm_vidc_dt_device[] = { .compatible = "qcom,yupik-vidc", .data = &yupik_data, }, + { + .compatible = "qcom,qcm6490-vidc", + .data = &yupik_data, + }, {}, }; @@ -2312,6 +2316,19 @@ void *vidc_get_drv_data(struct device *dev) ARRAY_SIZE(yupik_capabilities_v1); } msm_vidc_ddr_ubwc_config(driver_data, 0xe); + } else if (!strcmp(match->compatible, "qcom,qcm6490-vidc")) { + if (driver_data->sku_version == SKU_VERSION_1) { + driver_data->clock_data = yupik_clock_data_v1; + driver_data->clock_data_length = + ARRAY_SIZE(yupik_clock_data_v1); + driver_data->common_data = yupik_common_data_v1; + driver_data->common_data_length = + ARRAY_SIZE(yupik_common_data_v1); + driver_data->codec_caps = yupik_capabilities_v1; + driver_data->codec_caps_count = + ARRAY_SIZE(yupik_capabilities_v1); + } + msm_vidc_ddr_ubwc_config(driver_data, 0xe); } exit: return driver_data; From 20846af2196687191c68b576d77265b176ab745b Mon Sep 17 00:00:00 2001 From: Sayantan Majumder Date: Thu, 17 Jun 2021 00:52:55 +0530 Subject: [PATCH 444/452] msm: vidc: enabling dynamic session context for different targets Adding support to enable dynamic maximum no of instances for video sessions based on the different platforms. Change-Id: I16b92cc8cc740809042947590dcd73dcf4801f96 Signed-off-by: Sayantan Majumder --- msm/vidc/msm_v4l2_vidc.c | 11 ++++++++++- msm/vidc/msm_vidc_common.c | 1 - msm/vidc/msm_vidc_debug.c | 24 +++++++++++------------- msm/vidc/msm_vidc_debug.h | 24 ++++++++---------------- msm/vidc/msm_vidc_internal.h | 13 ++++++++++++- msm/vidc/msm_vidc_platform.c | 9 ++++++++- msm/vidc/msm_vidc_res_parse.c | 3 ++- 7 files changed, 51 insertions(+), 34 deletions(-) diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index 48d435af9fbc..873b1a2053da 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #include @@ -492,6 +492,12 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) core->id = MSM_VIDC_CORE_VENUS; + vidc_driver->ctxt = kcalloc(core->platform_data->max_inst_count, + sizeof(*vidc_driver->ctxt), GFP_KERNEL); + if (!vidc_driver->ctxt) + goto err_vidc_context; + vidc_driver->num_ctxt = core->platform_data->max_inst_count; + rc = v4l2_device_register(&pdev->dev, &core->v4l2_dev); if (rc) { d_vpr_e("Failed to register v4l2 device\n"); @@ -588,6 +594,8 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) err_dec: v4l2_device_unregister(&core->v4l2_dev); err_v4l2_register: + kfree(vidc_driver->ctxt); +err_vidc_context: sysfs_remove_group(&pdev->dev.kobj, &msm_vidc_core_attr_group); err_core_init: dev_set_drvdata(&pdev->dev, NULL); @@ -660,6 +668,7 @@ static int msm_vidc_remove(struct platform_device *pdev) mutex_destroy(&core->resources.cb_lock); mutex_destroy(&core->lock); kfree(core); + kfree(vidc_driver->ctxt); return rc; } diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 13a4b9ecdfd5..b4de4e3b235e 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -3014,7 +3014,6 @@ static int msm_comm_init_core(struct msm_vidc_inst *inst) core->state = VIDC_CORE_INIT; core->smmu_fault_handled = false; core->trigger_ssr = false; - core->resources.max_inst_count = MAX_SUPPORTED_INSTANCES; core->resources.max_secure_inst_count = core->resources.max_secure_inst_count ? core->resources.max_secure_inst_count : diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index 18a78bf6e69b..263840a68581 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #define CREATE_TRACE_POINTS @@ -31,8 +31,6 @@ int msm_vidc_vpp_delay; atomic_read(&__binfo->ref_count) >= 2 ? "video driver" : "firmware";\ }) -struct log_cookie ctxt[MAX_SUPPORTED_INSTANCES]; - struct core_inst_pair { struct msm_vidc_core *core; struct msm_vidc_inst *inst; @@ -614,16 +612,16 @@ int get_sid(u32 *sid, u32 session_type) { int i; - for (i = 0; i < MAX_SUPPORTED_INSTANCES; i++) { - if (!ctxt[i].used) { - ctxt[i].used = 1; + for (i = 0; i < vidc_driver->num_ctxt; i++) { + if (!vidc_driver->ctxt[i].used) { + vidc_driver->ctxt[i].used = 1; *sid = i+1; update_log_ctxt(*sid, session_type, 0); break; } } - return (i == MAX_SUPPORTED_INSTANCES); + return (i == vidc_driver->num_ctxt); } inline void update_log_ctxt(u32 sid, u32 session_type, u32 fourcc) @@ -632,7 +630,7 @@ inline void update_log_ctxt(u32 sid, u32 session_type, u32 fourcc) char type; u32 s_type = 0; - if (!sid || sid > MAX_SUPPORTED_INSTANCES) { + if (!sid || sid > vidc_driver->num_ctxt) { d_vpr_e("%s: invalid sid %#x\n", __func__, sid); } @@ -679,11 +677,11 @@ inline void update_log_ctxt(u32 sid, u32 session_type, u32 fourcc) break; } - ctxt[sid-1].session_type = s_type; - ctxt[sid-1].codec_type = fourcc; - memcpy(&ctxt[sid-1].name, codec, 4); - ctxt[sid-1].name[4] = type; - ctxt[sid-1].name[5] = '\0'; + vidc_driver->ctxt[sid-1].session_type = s_type; + vidc_driver->ctxt[sid-1].codec_type = fourcc; + memcpy(&vidc_driver->ctxt[sid-1].name, codec, 4); + vidc_driver->ctxt[sid-1].name[4] = type; + vidc_driver->ctxt[sid-1].name[5] = '\0'; } /* Mock all the missing parts for successful compilation starts here */ diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index 8dfaee14cd98..4c10d93863a4 100644 --- a/msm/vidc/msm_vidc_debug.h +++ b/msm/vidc/msm_vidc_debug.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #ifndef __MSM_VIDC_DEBUG__ @@ -92,13 +92,6 @@ enum vidc_err_recovery_disable { VIDC_DISABLE_NON_NOC_ERR_RECOV = 0x0002 }; -struct log_cookie { - u32 used; - u32 session_type; - u32 codec_type; - char name[20]; -}; - extern int msm_vidc_debug; extern int msm_vidc_fw_debug_mode; extern bool msm_vidc_fw_coverage; @@ -109,7 +102,6 @@ extern bool msm_vidc_lossless_encode; extern bool msm_vidc_cvp_usage; extern int msm_vidc_err_recovery_disable; extern int msm_vidc_vpp_delay; -extern struct log_cookie ctxt[MAX_SUPPORTED_INSTANCES]; #define dprintk(__level, sid, __fmt, ...) \ do { \ @@ -237,10 +229,10 @@ static inline bool is_print_allowed(u32 sid, u32 level) if (!((msm_vidc_debug >> 8) & 0xF)) return true; - if (!sid || sid > MAX_SUPPORTED_INSTANCES) + if (!sid || sid > vidc_driver->num_ctxt) return true; - if (ctxt[sid-1].session_type & msm_vidc_debug) + if (vidc_driver->ctxt[sid-1].session_type & msm_vidc_debug) return true; return false; @@ -248,21 +240,21 @@ static inline bool is_print_allowed(u32 sid, u32 level) static inline char *get_codec_name(u32 sid) { - if (!sid || sid > MAX_SUPPORTED_INSTANCES) + if (!sid || sid > vidc_driver->num_ctxt) return "....."; - return ctxt[sid-1].name; + return vidc_driver->ctxt[sid-1].name; } static inline void put_sid(u32 sid) { - if (!sid || sid > MAX_SUPPORTED_INSTANCES) { + if (!sid || sid > vidc_driver->num_ctxt) { d_vpr_e("%s: invalid sid %#x\n", __func__, sid); return; } - if (ctxt[sid-1].used) - ctxt[sid-1].used = 0; + if (vidc_driver->ctxt[sid-1].used) + vidc_driver->ctxt[sid-1].used = 0; } static inline void tic(struct msm_vidc_inst *i, enum profiling_points p, diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 153464382683..62e8c0b6a110 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #ifndef _MSM_VIDC_INTERNAL_H_ @@ -39,6 +39,7 @@ #define MAX_NUM_OUTPUT_BUFFERS VIDEO_MAX_FRAME // same as VB2_MAX_FRAME #define MAX_SUPPORTED_INSTANCES 16 +#define MAX_SUPPORTED_INSTANCES_24 24 #define MAX_BSE_VPP_DELAY 6 #define DEFAULT_BSE_VPP_DELAY 2 @@ -310,6 +311,7 @@ struct msm_vidc_platform_data { uint32_t vpu_ver; uint32_t num_vpp_pipes; struct msm_vidc_ubwc_config_data *ubwc_config; + uint32_t max_inst_count; }; struct msm_vidc_format_desc { @@ -336,6 +338,13 @@ struct msm_vidc_format_constraint { u32 uv_buffer_alignment; }; +struct log_cookie { + u32 used; + u32 session_type; + u32 codec_type; + char name[20]; +}; + struct msm_vidc_drv { struct mutex lock; struct list_head cores; @@ -343,6 +352,8 @@ struct msm_vidc_drv { struct dentry *debugfs_root; int thermal_level; u32 sku_version; + struct log_cookie *ctxt; + u32 num_ctxt; }; struct msm_video_device { diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 74dd3730dd31..51c99758de69 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #include @@ -2012,6 +2012,7 @@ static struct msm_vidc_platform_data default_data = { .vpu_ver = VPU_VERSION_IRIS2, .num_vpp_pipes = 0x4, .ubwc_config = 0x0, + .max_inst_count = MAX_SUPPORTED_INSTANCES, }; static struct msm_vidc_platform_data lahaina_data = { @@ -2036,6 +2037,7 @@ static struct msm_vidc_platform_data lahaina_data = { .codec_caps_count = ARRAY_SIZE(lahaina_capabilities), .vpss_caps = vpss_capabilities, .vpss_caps_count = ARRAY_SIZE(vpss_capabilities), + .max_inst_count = MAX_SUPPORTED_INSTANCES, }; static struct msm_vidc_platform_data yupik_data = { @@ -2060,6 +2062,7 @@ static struct msm_vidc_platform_data yupik_data = { .codec_caps_count = ARRAY_SIZE(yupik_capabilities_v0), .vpss_caps = vpss_capabilities, .vpss_caps_count = ARRAY_SIZE(vpss_capabilities), + .max_inst_count = MAX_SUPPORTED_INSTANCES, }; static struct msm_vidc_platform_data bengal_data = { @@ -2084,6 +2087,7 @@ static struct msm_vidc_platform_data bengal_data = { .codec_caps_count = ARRAY_SIZE(bengal_capabilities_v0), .vpss_caps = NULL, .vpss_caps_count = 0, + .max_inst_count = MAX_SUPPORTED_INSTANCES, }; static struct msm_vidc_platform_data shima_data = { @@ -2108,6 +2112,7 @@ static struct msm_vidc_platform_data shima_data = { .codec_caps_count = ARRAY_SIZE(shima_capabilities_v0), .vpss_caps = vpss_capabilities, .vpss_caps_count = ARRAY_SIZE(vpss_capabilities), + .max_inst_count = MAX_SUPPORTED_INSTANCES, }; static struct msm_vidc_platform_data holi_data = { @@ -2132,6 +2137,7 @@ static struct msm_vidc_platform_data holi_data = { .codec_caps_count = ARRAY_SIZE(holi_capabilities), .vpss_caps = NULL, .vpss_caps_count = 0, + .max_inst_count = MAX_SUPPORTED_INSTANCES, }; static const struct of_device_id msm_vidc_dt_device[] = { @@ -2329,6 +2335,7 @@ void *vidc_get_drv_data(struct device *dev) ARRAY_SIZE(yupik_capabilities_v1); } msm_vidc_ddr_ubwc_config(driver_data, 0xe); + driver_data->max_inst_count = MAX_SUPPORTED_INSTANCES_24; } exit: return driver_data; diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 1aa93ac5bb75..412fd52e9679 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #include @@ -822,6 +822,7 @@ int read_platform_resources_from_drv_data( res->vpu_ver = platform_data->vpu_ver; res->ubwc_config = platform_data->ubwc_config; + res->max_inst_count = platform_data->max_inst_count; return rc; From 763a8236a81d9135dd6e82051f4bb4c7cbf5e81e Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Fri, 18 Jun 2021 09:01:58 +0530 Subject: [PATCH 445/452] msm: vidc: Fix low latency log print Fix low latency log print for decoder Change-Id: I9fbcb0650a1c89ef4863866225c0e98092f51409 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_clocks.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 7ddf39a1ba70..168abc2f8080 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1237,9 +1237,11 @@ static int msm_vidc_decide_work_mode_ar50_lt(struct msm_vidc_inst *inst) return -EINVAL; } + latency.enable = false; hdev = inst->core->device; if (inst->clk_data.low_latency_mode) { pdata.video_work_mode = HFI_WORKMODE_1; + latency.enable = true; goto decision_done; } @@ -1259,20 +1261,25 @@ static int msm_vidc_decide_work_mode_ar50_lt(struct msm_vidc_inst *inst) } } else if (inst->session_type == MSM_VIDC_ENCODER) { pdata.video_work_mode = HFI_WORKMODE_1; + /* For WORK_MODE_1, set Low Latency mode by default */ + latency.enable = true; if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR || inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_MBR || inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR || inst->rc_type == - V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) + V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) { pdata.video_work_mode = HFI_WORKMODE_2; + latency.enable = false; + } } else { return -EINVAL; } decision_done: - + s_vpr_h(inst->sid, "Configuring work mode = %u low latency = %u", + pdata.video_work_mode, latency.enable); inst->clk_data.work_mode = pdata.video_work_mode; rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_PARAM_WORK_MODE, @@ -1280,22 +1287,12 @@ static int msm_vidc_decide_work_mode_ar50_lt(struct msm_vidc_inst *inst) if (rc) s_vpr_e(inst->sid, "Failed to configure Work Mode\n"); - /* For WORK_MODE_1, set Low Latency mode by default to HW. */ - - latency.enable = false; - if (inst->session_type == MSM_VIDC_ENCODER && - inst->clk_data.work_mode == HFI_WORKMODE_1) { - latency.enable = true; + if (inst->session_type == MSM_VIDC_ENCODER && latency.enable) { rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE, (void *)&latency, sizeof(latency)); } - - s_vpr_h(inst->sid, "Configuring work mode = %u low latency = %u", - pdata.video_work_mode, - latency.enable); - rc = msm_comm_scale_clocks_and_bus(inst, 1); return rc; @@ -1401,8 +1398,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) } s_vpr_h(inst->sid, "Configuring work mode = %u low latency = %u", - pdata.video_work_mode, - latency.enable); + pdata.video_work_mode, latency.enable); if (inst->session_type == MSM_VIDC_ENCODER) { rc = call_hfi_op(hdev, session_set_property, From a2e13c93b9f649a0910b803f2666a259f33e4ae4 Mon Sep 17 00:00:00 2001 From: Yang Xiaoqin Date: Fri, 2 Jul 2021 11:22:08 +0800 Subject: [PATCH 446/452] msm: venc: set auto frame rate only for VBR CFR native recorder Don't set AUDO_FRAME_RATE for non camera-recorder usercase. Change-Id: I1e072538d2a7f431653c7bfd933b5d1c0b83f906 Signed-off-by: Yang Xiaoqin --- msm/vidc/msm_venc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index c47f37121628..849dc9b72c10 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2150,6 +2150,7 @@ int msm_venc_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) int count = 0; int rc = 0; struct v4l2_ctrl *superframe_ctrl = NULL; + struct v4l2_ctrl *ctrl = NULL; if (!inst || !inst->core) { d_vpr_e("%s: invalid parameters\n", __func__); @@ -2160,6 +2161,12 @@ int msm_venc_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) is_image_session(inst)) return rc; + /* set auto-framerate only for VBR CFR native recorder */ + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_NATIVE_RECORDER); + if ((ctrl && ctrl->val == V4L2_MPEG_MSM_VIDC_DISABLE) || + (inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)) + return rc; + mutex_lock(&inst->timestamps.lock); list_for_each_entry(node, &inst->timestamps.list, list) { count++; From a65ceebe831354bf673c21587047984157243f81 Mon Sep 17 00:00:00 2001 From: Fudong Zhang Date: Fri, 18 Jun 2021 15:12:48 +0800 Subject: [PATCH 447/452] msm: vidc: Add config files for scuba Add video config files for scuba to enable the video driver for scuba target Change-Id: I2ee99356ab66f81e2b1a15b4a76155938ffe0db5 --- Makefile | 9 +++++++++ config/scubavid.conf | 5 +++++ config/scubavidconf.h | 6 ++++++ 3 files changed, 20 insertions(+) create mode 100644 config/scubavid.conf create mode 100644 config/scubavidconf.h diff --git a/Makefile b/Makefile index dfbd2d489355..6216c2266d9b 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,15 @@ LINUXINCLUDE += -include $(srctree)/techpack/video/config/litovidconf.h endif endif +# auto-detect subdirs +ifeq ($(CONFIG_ARCH_SCUBA), y) +include $(srctree)/techpack/video/config/scubavid.conf +endif + +ifeq ($(CONFIG_ARCH_SCUBA), y) +LINUXINCLUDE += -include $(srctree)/techpack/video/config/scubavidconf.h +endif + LINUXINCLUDE += -I$(srctree)/techpack/video/include \ -I$(srctree)/techpack/video/include/uapi diff --git a/config/scubavid.conf b/config/scubavid.conf new file mode 100644 index 000000000000..65eae99c590b --- /dev/null +++ b/config/scubavid.conf @@ -0,0 +1,5 @@ +ifeq ($(CONFIG_QGKI),y) +export CONFIG_MSM_VIDC_V4L2=y +else +export CONFIG_MSM_VIDC_V4L2=m +endif diff --git a/config/scubavidconf.h b/config/scubavidconf.h new file mode 100644 index 000000000000..a31a91c7390e --- /dev/null +++ b/config/scubavidconf.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#define CONFIG_MSM_VIDC_V4L2 1 From ad091aa6ae69a22786ed398c60028bd779eb5a03 Mon Sep 17 00:00:00 2001 From: Fudong Zhang Date: Fri, 18 Jun 2021 15:19:25 +0800 Subject: [PATCH 448/452] msm: vidc: Add platform capabilities for scuba Add platform specific capabilities for scuba target. Change-Id: I1296b4934b1d3e2fb338fd0eff2617d45d406286 --- msm/vidc/msm_vidc_platform.c | 170 +++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 51c99758de69..740c5d0587ff 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -88,6 +88,14 @@ static struct msm_vidc_codec_data holi_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 0, 440, 440), }; +static struct msm_vidc_codec_data scuba_codec_data[] = { + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 0, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 0, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 0, 440, 440), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 0, 440, 440), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 0, 440, 440), +}; + static struct msm_vidc_codec_data yupik_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 25, 675, 320), CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 25, 675, 320), @@ -125,6 +133,12 @@ static struct msm_vidc_codec holi_codecs[] = { {ENC, H264}, {ENC, HEVC}, }; +static struct msm_vidc_codec scuba_codecs[] = { + /* {domain, codec} */ + {DEC, H264}, {DEC, HEVC}, {DEC, VP9}, + {ENC, H264}, {ENC, HEVC}, +}; + static struct msm_vidc_codec default_codecs[] = { /* {domain, codec} */ {DEC, H264}, {DEC, HEVC}, {DEC, VP9}, {DEC, MPEG2}, @@ -328,6 +342,75 @@ static struct msm_vidc_codec_capability holi_capabilities[] = { V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1}, }; +static struct msm_vidc_codec_capability scuba_capabilities[] = { + /* {cap_type, domains, codecs, min, max, step_size, default_value} */ + {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 1920, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 128, 1920, 2, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 1920, 2, 1080}, + /* ((1920 * 1088) / 256) */ + {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 36, 8160, 1, 8160}, + {CAP_MBS_PER_FRAME, ENC, CODECS_ALL, 64, 8160, 1, 8160}, + /* 1080@30 decode + 1080@30 encode */ + {CAP_MBS_PER_SECOND, DEC, CODECS_ALL, 36, 489600, 1, 244800}, + {CAP_MBS_PER_SECOND, ENC, CODECS_ALL, 64, 489600, 1, 244800}, + {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 120, 1, 30}, + {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 60000000, 1, 20000000}, + {CAP_CABAC_BITRATE, ENC, H264, 1, 60000000, 1, 20000000}, + {CAP_HIER_P_NUM_ENH_LAYERS, ENC, H264|HEVC, 0, 6, 1, 0}, + {CAP_LTR_COUNT, ENC, H264|HEVC, 0, 4, 1, 0}, + /* ((1920 * 1088) / 256) * 30 fps */ + {CAP_MBS_PER_SECOND_POWER_SAVE, ENC, CODECS_ALL, + 0, 244800, 1, 244800}, + {CAP_I_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 10}, + {CAP_P_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + {CAP_B_FRAME_QP, ENC, H264|HEVC, 0, 51, 1, 20}, + + /* 10 slices */ + {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_SLICE_MB, ENC, H264|HEVC, 1, 10, 1, 10}, + {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, + + /* Secure usecase specific */ + {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 1920, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 1920, 1, 1080}, + {CAP_SECURE_FRAME_WIDTH, ENC, CODECS_ALL, 128, 1920, 2, 1920}, + {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 128, 1920, 2, 1080}, + /* (1920 * 1088) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 8160, 1, 8160}, + {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 35000000, 1, 20000000}, + + /* All intra encoding usecase specific */ + {CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 60, 1, 30}, + + /* Image specific */ + {CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 2, 512}, + {CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 2, 8192}, + {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 2, 8192}, + + /* Level for AVC and HEVC encoder specific. + * Default for levels is UNKNOWN value. But if we use unknown + * value here to set as default, max value needs to be set to + * unknown as well, which creates a problem of allowing client + * to set higher level than supported + */ + {CAP_H264_LEVEL, ENC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_1}, + {CAP_HEVC_LEVEL, ENC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1}, + + /* Level for AVC and HEVC decoder specific */ + {CAP_H264_LEVEL, DEC, H264, V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 1, + V4L2_MPEG_VIDEO_H264_LEVEL_4_1}, + {CAP_HEVC_LEVEL, DEC, HEVC, V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1}, +}; + static struct msm_vidc_codec_capability lahaina_capabilities[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 8192, 1, 1920}, @@ -1971,6 +2054,65 @@ static struct msm_vidc_common_data holi_common_data[] = { }, }; +static struct msm_vidc_common_data scuba_common_data[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,fw-unload-delay", + .value = 1000, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 3, + }, + { + .key = "qcom,max-hw-load", + .value = 489600, /* ((1088x1920)/256)@60fps */ + }, + { + .key = "qcom,max-image-load", + .value = 262144, /* ((8192x8192)/256)@1fps */ + }, + { + .key = "qcom,max-mbpf", + .value = 65280,/* ((3840x2176)/256) x 2 */ + }, + { + .key = "qcom,power-collapse-delay", + .value = 1500, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,dcvs", + .value = 1, + }, + { + .key = "qcom,fw-cycles", + .value = 733003, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 225975, + }, + { + .key = "qcom,no-cvp", + .value = 1, + }, +}; + static struct msm_vidc_efuse_data yupik_efuse_data[] = { /* IRIS_PLL_FMAX - max 4K@30 */ EFUSE_ENTRY(0x007801E8, 4, 0x00200000, 0x15, SKU_VERSION), @@ -2140,6 +2282,30 @@ static struct msm_vidc_platform_data holi_data = { .max_inst_count = MAX_SUPPORTED_INSTANCES, }; +static struct msm_vidc_platform_data scuba_data = { + .codec_data = scuba_codec_data, + .codec_data_length = ARRAY_SIZE(scuba_codec_data), + .clock_data = NULL, + .clock_data_length = 0, + .common_data = scuba_common_data, + .common_data_length = ARRAY_SIZE(scuba_common_data), + .csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff, + .csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff, + .csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff, + .efuse_data = NULL, + .efuse_data_length = 0, + .sku_version = 0, + .vpu_ver = VPU_VERSION_AR50_LITE, + .num_vpp_pipes = 0x1, + .ubwc_config = 0x0, + .codecs = scuba_codecs, + .codecs_count = ARRAY_SIZE(scuba_codecs), + .codec_caps = scuba_capabilities, + .codec_caps_count = ARRAY_SIZE(scuba_capabilities), + .vpss_caps = NULL, + .vpss_caps_count = 0, +}; + static const struct of_device_id msm_vidc_dt_device[] = { { .compatible = "qcom,lahaina-vidc", @@ -2153,6 +2319,10 @@ static const struct of_device_id msm_vidc_dt_device[] = { .compatible = "qcom,bengal-vidc", .data = &bengal_data, }, + { + .compatible = "qcom,scuba-vidc", + .data = &scuba_data, + }, { .compatible = "qcom,holi-vidc", .data = &holi_data, From 046dec9f65ccb7a4a32cdef01b27d8cb079477cb Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Fri, 9 Jul 2021 14:37:54 +0530 Subject: [PATCH 449/452] msm: vidc: Add support for cx_ipeak Add supporting changes in video driver for cx_ipeak feature Change-Id: Iea30144b52dce525c6abc80f415c859fffdb0b2d --- msm/vidc/hfi_common.c | 28 +++++++++++++++++- msm/vidc/msm_vidc_res_parse.c | 53 +++++++++++++++++++++++++++++++++++ msm/vidc/msm_vidc_resources.h | 3 +- 3 files changed, 82 insertions(+), 2 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 3e4e5d40c760..4995f45a5376 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #include "hfi_common.h" @@ -1105,8 +1105,21 @@ static int __set_clk_rate(struct venus_hfi_device *device, struct clock_info *cl, u64 rate, u32 sid) { int rc = 0; + u64 threshold_freq = device->res->clk_freq_threshold; + struct cx_ipeak_client *ipeak = device->res->cx_ipeak_context; struct clk *clk = cl->clk; + if (ipeak && device->clk_freq < threshold_freq && rate >= threshold_freq) { + rc = cx_ipeak_update(ipeak, true); + if (rc) { + s_vpr_e(sid, "%s: cx_ipeak_update failed!\n", __func__); + return rc; + } + s_vpr_p(sid, + "cx_ipeak_update: up, clk freq = %lu rate = %lu threshold_freq = %lu\n", + device->clk_freq, rate, threshold_freq); + } + rc = clk_set_rate(clk, rate); if (rc) { s_vpr_e(sid, @@ -1115,6 +1128,19 @@ static int __set_clk_rate(struct venus_hfi_device *device, return rc; } + if (ipeak && device->clk_freq >= threshold_freq && rate < threshold_freq) { + rc = cx_ipeak_update(ipeak, false); + if (rc) { + s_vpr_e(sid, + "cx_ipeak_update failed! ipeak %pK\n", ipeak); + device->clk_freq = rate; + return rc; + } + s_vpr_p(sid, + "cx_ipeak_update: up, clk freq = %lu rate = %lu threshold_freq = %lu\n", + device->clk_freq, rate, threshold_freq); + } + device->clk_freq = rate; return rc; diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 412fd52e9679..b9dc0d4b6450 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -115,6 +115,13 @@ static inline void msm_vidc_free_clock_table( res->clock_set.count = 0; } +static inline void msm_vidc_free_cx_ipeak_context( + struct msm_vidc_platform_resources *res) +{ + cx_ipeak_unregister(res->cx_ipeak_context); + res->cx_ipeak_context = NULL; +} + void msm_vidc_free_platform_resources( struct msm_vidc_platform_resources *res) { @@ -125,6 +132,7 @@ void msm_vidc_free_platform_resources( msm_vidc_free_qdss_addr_table(res); msm_vidc_free_bus_table(res); msm_vidc_free_buffer_usage_table(res); + msm_vidc_free_cx_ipeak_context(res); } static int msm_vidc_load_fw_name(struct msm_vidc_platform_resources *res) @@ -828,6 +836,44 @@ int read_platform_resources_from_drv_data( } +static int msm_vidc_populate_cx_ipeak_context( + struct msm_vidc_platform_resources *res) +{ + struct platform_device *pdev = res->pdev; + int rc = 0; + + if (of_find_property(pdev->dev.of_node, + "qcom,cx-ipeak-data", NULL)) + res->cx_ipeak_context = cx_ipeak_register( + pdev->dev.of_node, "qcom,cx-ipeak-data"); + else + return rc; + + if (IS_ERR(res->cx_ipeak_context)) { + rc = PTR_ERR(res->cx_ipeak_context); + if (rc == -EPROBE_DEFER) + d_vpr_h("cx-ipeak register failed. Deferring probe!"); + else + d_vpr_e("cx-ipeak register failed. rc: %d", rc); + + res->cx_ipeak_context = NULL; + return rc; + } + + if (res->cx_ipeak_context) + d_vpr_h("cx-ipeak register successful"); + else + d_vpr_h("cx-ipeak register not implemented"); + + of_property_read_u32(pdev->dev.of_node, + "qcom,clock-freq-threshold", + &res->clk_freq_threshold); + d_vpr_h("cx ipeak threshold frequency = %u\n", + res->clk_freq_threshold); + + return rc; +} + int read_platform_resources_from_dt( struct msm_vidc_platform_resources *res) { @@ -913,9 +959,16 @@ int read_platform_resources_from_dt( goto err_setup_legacy_cb; } + rc = msm_vidc_populate_cx_ipeak_context(res); + if (rc) { + d_vpr_e("Failed to setup cx-ipeak %d\n", rc); + goto err_register_cx_ipeak; + } return rc; +err_register_cx_ipeak: + msm_vidc_free_cx_ipeak_context(res); err_setup_legacy_cb: err_load_reset_table: msm_vidc_free_allowed_clocks_table(res); diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 7a2916cd62ac..ac6dd6eca9ec 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved. */ #ifndef __MSM_VIDC_RESOURCES_H__ @@ -9,6 +9,7 @@ #include #include "msm_vidc.h" #include +#include #define MAX_BUFFER_TYPES 32 From 43cb7c32342c4ecec412b2db347228afb6312d4f Mon Sep 17 00:00:00 2001 From: Fudong Zhang Date: Wed, 30 Jun 2021 14:51:50 +0800 Subject: [PATCH 450/452] msm: vidc: support input crop feature for encoder Support input crop feature for encoder Change-Id: Ic7b5a273fc589b917b4b7672d67026cda7264941 --- include/uapi/vidc/media/msm_vidc_utils.h | 13 +++++++++++++ msm/vidc/msm_venc.c | 10 +++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index 73ff48f86ca4..41f9c88a7dce 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -117,6 +117,7 @@ enum v4l2_mpeg_vidc_extradata { EXTRADATA_ENC_INPUT_HDR10PLUS = 8, EXTRADATA_ENC_INPUT_CVP = 16, EXTRADATA_ENC_FRAME_QP = 32, + EXTRADATA_ENC_INPUT_CROP = 64, }; #define V4L2_CID_MPEG_VIDC_VIDEO_VUI_TIMING_INFO \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 19) @@ -328,6 +329,17 @@ struct msm_vidc_aspect_ratio_payload { __u32 aspect_height; }; +#define MSM_VIDC_EXTRADATA_INPUT_CROP 0x0700000E +struct msm_vidc_input_crop_payload { + __u32 size; + __u32 version; + __u32 port_index; + __u32 left; + __u32 top; + __u32 width; + __u32 height; +}; + struct msm_vidc_misr_info { __u32 misr_set; __u32 misr_dpb_luma[8]; @@ -356,6 +368,7 @@ struct msm_vidc_output_crop_payload { struct msm_vidc_extradata_index { __u32 type; union { + struct msm_vidc_input_crop_payload input_crop; struct msm_vidc_aspect_ratio_payload aspect_ratio; }; }; diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index c47f37121628..b315fdac63af 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -522,6 +522,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .minimum = EXTRADATA_NONE, .maximum = EXTRADATA_ADVANCED | EXTRADATA_ENC_INPUT_ROI | EXTRADATA_ENC_INPUT_HDR10PLUS | + EXTRADATA_ENC_INPUT_CROP | EXTRADATA_ENC_INPUT_CVP | EXTRADATA_ENC_FRAME_QP, .default_value = EXTRADATA_NONE, .menu_skip_mask = 0, @@ -1787,7 +1788,8 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) inst->prop.extradata_ctrls |= ctrl->val; if ((inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_ROI) || - (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_HDR10PLUS)) { + (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_HDR10PLUS) || + (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CROP)) { f = &inst->fmts[INPUT_PORT].v4l2_fmt; f->fmt.pix_mp.num_planes = 2; f->fmt.pix_mp.plane_fmt[1].sizeimage = @@ -4649,6 +4651,12 @@ int msm_venc_set_extradata(struct msm_vidc_inst *inst) } } + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CROP) { + // Enable Input Crop Extradata + msm_comm_set_index_extradata(inst, MSM_VIDC_EXTRADATA_INPUT_CROP, 0x1); + s_vpr_l(inst->sid, "%s: enable input crop encoding\n", __func__); + } + if(!msm_vidc_cvp_usage) inst->prop.extradata_ctrls &= ~EXTRADATA_ENC_INPUT_CVP; From 0e56923f41358a3d8603e4f83a321eef81f04b63 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 16 Jul 2021 21:44:33 +0530 Subject: [PATCH 451/452] msm: vidc: set ib bandwidth for holi For holi, there is a requirement to vote for ib bandwidth as twice the ab. Configuring the same. Change-Id: Idccc40669c8d84bbe9a1f536ea230c2f1cae6662 --- msm/vidc/hfi_common.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 4995f45a5376..16f9d17e3d2c 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -882,16 +882,15 @@ static void __set_registers(struct venus_hfi_device *device, u32 sid) } } -static int __vote_bandwidth(struct bus_info *bus, - unsigned long bw_kbps, u32 sid) +static int __vote_bandwidth(struct bus_info *bus, unsigned long ab_kbps, + unsigned long ib_kbps, u32 sid) { int rc = 0; - - s_vpr_p(sid, "Voting bus %s to ab %llu kbps\n", bus->name, bw_kbps); - rc = icc_set_bw(bus->path, bw_kbps, 0); + s_vpr_p(sid, "Voting bus %s to ab %llu ib %llu kbps\n", bus->name, ab_kbps, ib_kbps); + rc = icc_set_bw(bus->path, ab_kbps, ib_kbps); if (rc) - s_vpr_e(sid, "Failed voting bus %s to ab %llu, rc=%d\n", - bus->name, bw_kbps, rc); + s_vpr_e(sid, "Failed voting bus %s to ab %llu ib %llu, rc=%d\n", + bus->name, ab_kbps, ib_kbps, rc); return rc; } @@ -904,7 +903,7 @@ int __unvote_buses(struct venus_hfi_device *device, u32 sid) device->bus_vote = DEFAULT_BUS_VOTE; venus_hfi_for_each_bus(device, bus) { - rc = __vote_bandwidth(bus, 0, sid); + rc = __vote_bandwidth(bus, 0, 0, sid); if (rc) goto err_unknown_device; } @@ -918,7 +917,7 @@ static int __vote_buses(struct venus_hfi_device *device, { int rc = 0; struct bus_info *bus = NULL; - unsigned long bw_kbps = 0, bw_prev = 0; + unsigned long ab_kbps = 0, ib_kbps = 0, bw_prev = 0; enum vidc_bus_type type; venus_hfi_for_each_bus(device, bus) { @@ -926,33 +925,36 @@ static int __vote_buses(struct venus_hfi_device *device, type = get_type_frm_name(bus->name); if (type == DDR) { - bw_kbps = bw_ddr; + ab_kbps = bw_ddr; bw_prev = device->bus_vote.total_bw_ddr; } else if (type == LLCC) { - bw_kbps = bw_llcc; + ab_kbps = bw_llcc; bw_prev = device->bus_vote.total_bw_llcc; } else { - bw_kbps = bus->range[1]; + ab_kbps = bus->range[1]; bw_prev = device->bus_vote.total_bw_ddr ? - bw_kbps : 0; + ab_kbps : 0; } /* ensure freq is within limits */ - bw_kbps = clamp_t(typeof(bw_kbps), bw_kbps, + ab_kbps = clamp_t(typeof(ab_kbps), ab_kbps, bus->range[0], bus->range[1]); - if (TRIVIAL_BW_CHANGE(bw_kbps, bw_prev) && bw_prev) { + if (TRIVIAL_BW_CHANGE(ab_kbps, bw_prev) && bw_prev) { s_vpr_l(sid, "Skip voting bus %s to %llu bps", - bus->name, bw_kbps * 1000); + bus->name, ab_kbps * 1000); continue; } - rc = __vote_bandwidth(bus, bw_kbps, sid); + if (device->res->vpu_ver == VPU_VERSION_AR50_LITE) + ib_kbps = 2 * ab_kbps; + + rc = __vote_bandwidth(bus, ab_kbps, ib_kbps, sid); if (type == DDR) - device->bus_vote.total_bw_ddr = bw_kbps; + device->bus_vote.total_bw_ddr = ab_kbps; else if (type == LLCC) - device->bus_vote.total_bw_llcc = bw_kbps; + device->bus_vote.total_bw_llcc = ab_kbps; } else { s_vpr_e(sid, "No BUS to Vote\n"); } From 667025ee574e7405346522d10cbc750a2fdda2a0 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 20 Aug 2021 11:39:15 +0530 Subject: [PATCH 452/452] msm: vidc: Ping hardware during timeouts Added PING command. Send the command to video firmware when any awaited response is not received within the stipulated time. PING would help firmware to check if some commands or messages are not processed in queue. At the same time, the interrupts for handling PING command would clear up the queues processing, if any. Change-Id: Iee981dde3b3a1a21b74639703f86881fd5779027 Signed-off-by: Vikash Garodia Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_common.c | 30 +++++++++++++++++++++++++ msm/vidc/hfi_packetization.c | 15 +++++++++++++ msm/vidc/hfi_packetization.h | 1 + msm/vidc/hfi_response_handler.c | 26 ++++++++++++++++++++++ msm/vidc/msm_vidc_common.c | 39 ++++++++++++++++++++++++++++++++- msm/vidc/vidc_hfi.h | 15 +++++++++++++ msm/vidc/vidc_hfi_api.h | 3 ++- 7 files changed, 127 insertions(+), 2 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 16f9d17e3d2c..74aa73796f39 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -1807,6 +1807,34 @@ static int venus_hfi_core_release(void *dev) return rc; } +static int venus_hfi_core_ping(void *device, u32 sid) +{ + struct hfi_cmd_sys_ping_packet pkt; + int rc = 0; + struct venus_hfi_device *dev; + + if (!device) { + d_vpr_e("invalid device\n"); + return -ENODEV; + } + + dev = device; + mutex_lock(&dev->lock); + + rc = call_hfi_pkt_op(dev, sys_ping, &pkt, sid); + if (rc) { + d_vpr_e("core_ping: failed to create packet\n"); + goto err_create_pkt; + } + + if (__iface_cmdq_write(dev, &pkt, sid)) + rc = -ENOTEMPTY; + +err_create_pkt: + mutex_unlock(&dev->lock); + return rc; +} + static int venus_hfi_core_trigger_ssr(void *device, enum hal_ssr_trigger_type ssr_type, u32 sub_client_id, u32 test_addr) @@ -2790,6 +2818,7 @@ static int __response_handler(struct venus_hfi_device *device) case HAL_SESSION_RELEASE_BUFFER_DONE: case HAL_SESSION_RELEASE_RESOURCE_DONE: case HAL_SESSION_PROPERTY_INFO: + case HAL_SYS_PING_ACK: inst_id = &info->response.cmd.inst_id; break; case HAL_SESSION_ERROR: @@ -4284,6 +4313,7 @@ void venus_hfi_delete_device(void *device) static void venus_init_hfi_callbacks(struct hfi_device *hdev) { hdev->core_init = venus_hfi_core_init; + hdev->core_ping = venus_hfi_core_ping; hdev->core_release = venus_hfi_core_release; hdev->core_trigger_ssr = venus_hfi_core_trigger_ssr; hdev->session_init = venus_hfi_session_init; diff --git a/msm/vidc/hfi_packetization.c b/msm/vidc/hfi_packetization.c index 345638f86902..00f92a68c406 100644 --- a/msm/vidc/hfi_packetization.c +++ b/msm/vidc/hfi_packetization.c @@ -71,6 +71,20 @@ int create_pkt_cmd_sys_init(struct hfi_cmd_sys_init_packet *pkt, return rc; } +int create_pkt_cmd_sys_ping(struct hfi_cmd_sys_ping_packet *pkt, u32 sid) +{ + int rc = 0; + + if (!pkt) + return -EINVAL; + + pkt->size = sizeof(struct hfi_cmd_sys_ping_packet); + pkt->packet_type = HFI_CMD_SYS_PING; + pkt->sid = sid; + + return rc; +} + int create_pkt_cmd_sys_pc_prep(struct hfi_cmd_sys_pc_prep_packet *pkt) { int rc = 0; @@ -692,6 +706,7 @@ int create_pkt_cmd_sys_image_version( static struct hfi_packetization_ops hfi_default = { .sys_init = create_pkt_cmd_sys_init, + .sys_ping = create_pkt_cmd_sys_ping, .sys_pc_prep = create_pkt_cmd_sys_pc_prep, .sys_power_control = create_pkt_cmd_sys_power_control, .sys_set_resource = create_pkt_cmd_sys_set_resource, diff --git a/msm/vidc/hfi_packetization.h b/msm/vidc/hfi_packetization.h index accce3144aa4..412f83199660 100644 --- a/msm/vidc/hfi_packetization.h +++ b/msm/vidc/hfi_packetization.h @@ -19,6 +19,7 @@ enum hfi_packetization_type { struct hfi_packetization_ops { int (*sys_init)(struct hfi_cmd_sys_init_packet *pkt, u32 arch_type); + int (*sys_ping)(struct hfi_cmd_sys_ping_packet *pkt, u32 sid); int (*sys_pc_prep)(struct hfi_cmd_sys_pc_prep_packet *pkt); int (*sys_power_control)(struct hfi_cmd_sys_set_property_packet *pkt, u32 enable); diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index b129dec72f31..ca5c21f3a9d6 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -1079,6 +1079,29 @@ static int hfi_process_session_abort_done(u32 device_id, return 0; } +static int hfi_process_sys_ping_ack(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_sys_ping_ack_pkt *pkt = _pkt; + struct msm_vidc_cb_cmd_done cmd_done = {0}; + if (!pkt || pkt->size != + sizeof(struct hfi_msg_sys_ping_ack_pkt)) { + d_vpr_e("%s: bad packet/packet size: %d\n", + __func__, pkt ? pkt->size : 0); + return -E2BIG; + } + s_vpr_h(pkt->sid, "RECEIVED: SYS PING ACK\n"); + cmd_done.device_id = device_id; + cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; + cmd_done.size = 0; + + info->response_type = HAL_SYS_PING_ACK; + info->response.cmd = cmd_done; + + return 0; +} + static void hfi_process_sys_get_prop_image_version( struct hfi_msg_sys_property_info_packet *pkt) { @@ -1213,6 +1236,9 @@ int hfi_process_msg_packet(u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr, case HFI_MSG_SYS_SESSION_ABORT_DONE: pkt_func = (pkt_func_def)hfi_process_session_abort_done; break; + case HFI_MSG_SYS_PING_ACK: + pkt_func = (pkt_func_def)hfi_process_sys_ping_ack; + break; default: d_vpr_l("Unable to parse message: %#x\n", msg_hdr->packet); break; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index b4de4e3b235e..b8a97f53c778 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1269,8 +1269,20 @@ static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst, msecs_to_jiffies( inst->core->resources.msm_vidc_hw_rsp_timeout)); if (!rc) { - s_vpr_e(inst->sid, "Wait interrupted or timed out: %d\n", + s_vpr_e(inst->sid, "Wait interrupted or timed out(sending ping cmd): %d\n", SESSION_MSG_INDEX(cmd)); + rc = call_hfi_op(hdev, core_ping, hdev->hfi_device_data, inst->sid); + rc = wait_for_completion_timeout( + &inst->core->completions[SYS_MSG_INDEX(HAL_SYS_PING_ACK)], + msecs_to_jiffies( + inst->core->resources.msm_vidc_hw_rsp_timeout)); + if (rc) { + if (try_wait_for_completion(&inst->completions[SESSION_MSG_INDEX(cmd)])) { + s_vpr_e(inst->sid, "Received %d response. Continue session\n", + SESSION_MSG_INDEX(cmd)); + return 0; + } + } msm_comm_kill_session(inst); rc = -EIO; } else { @@ -1900,6 +1912,28 @@ static void handle_stop_done(enum hal_command_response cmd, void *data) put_inst(inst); } +static void handle_ping_done(enum hal_command_response cmd, void *data) +{ + struct msm_vidc_cb_cmd_done *response = data; + struct msm_vidc_inst *inst; + + if (!response) { + d_vpr_e("Failed to get valid response for stop\n"); + return; + } + + inst = get_inst(get_vidc_core(response->device_id), + response->inst_id); + if (!inst) { + d_vpr_e("Got a response for an inactive session\n"); + return; + } + + s_vpr_l(inst->sid, "handled: SYS_PING_DONE\n"); + complete(&inst->core->completions[SYS_MSG_INDEX(HAL_SYS_PING_ACK)]); + put_inst(inst); +} + static void handle_release_res_done(enum hal_command_response cmd, void *data) { struct msm_vidc_cb_cmd_done *response = data; @@ -2728,6 +2762,9 @@ void handle_cmd_response(enum hal_command_response cmd, void *data) case HAL_SESSION_ABORT_DONE: handle_session_close(cmd, data); break; + case HAL_SYS_PING_ACK: + handle_ping_done(cmd, data); + break; case HAL_SESSION_EVENT_CHANGE: handle_event_change(cmd, data); break; diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index 9d2ab5d0dfe7..3ae3d0ffb2ab 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -313,6 +313,8 @@ struct hfi_uncompressed_plane_actual_constraints_info { #define HFI_CMD_SYS_OX_START \ (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_CMD_START_OFFSET + 0x0000) #define HFI_CMD_SYS_SESSION_ABORT (HFI_CMD_SYS_OX_START + 0x001) +#define HFI_CMD_SYS_PING (HFI_CMD_SYS_OX_START + 0x002) + #define HFI_CMD_SESSION_OX_START \ (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_CMD_START_OFFSET + 0x1000) @@ -336,6 +338,7 @@ struct hfi_uncompressed_plane_actual_constraints_info { #define HFI_MSG_SYS_OX_START \ (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_MSG_START_OFFSET + 0x0000) +#define HFI_MSG_SYS_PING_ACK (HFI_MSG_SYS_OX_START + 0x2) #define HFI_MSG_SYS_SESSION_ABORT_DONE (HFI_MSG_SYS_OX_START + 0x4) #define HFI_MSG_SESSION_OX_START \ @@ -368,6 +371,12 @@ struct hfi_cmd_sys_session_abort_packet { u32 sid; }; +struct hfi_cmd_sys_ping_packet { + u32 size; + u32 packet_type; + u32 sid; +}; + struct hfi_cmd_session_load_resources_packet { u32 size; u32 packet_type; @@ -507,6 +516,12 @@ struct hfi_msg_sys_session_abort_done_packet { u32 error_type; }; +struct hfi_msg_sys_ping_ack_pkt { + u32 size; + u32 packet_type; + u32 sid; +}; + struct hfi_msg_sys_property_info_packet { u32 size; u32 packet_type; diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index ee86ad85f7be..230c217d3db6 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -423,7 +423,7 @@ enum hal_command_response { HAL_SYS_SET_RESOURCE_DONE, HAL_SYS_RELEASE_RESOURCE_DONE, HAL_SYS_PC_PREP_DONE, - HAL_SYS_IDLE, + HAL_SYS_PING_ACK, HAL_SYS_DEBUG, HAL_SYS_WATCHDOG_TIMEOUT, HAL_SYS_ERROR, @@ -635,6 +635,7 @@ struct hfi_device { /*Add function pointers for all the hfi functions below*/ int (*core_init)(void *device); + int (*core_ping)(void *device, u32 sid); int (*core_release)(void *device); int (*core_trigger_ssr)(void *device, enum hal_ssr_trigger_type ssr_type, u32 sub_client_id,