From 7eb9a06ef53e727dc5775121fddebbbada60b907 Mon Sep 17 00:00:00 2001 From: Git User Date: Wed, 3 Apr 2019 04:01:20 -0700 Subject: [PATCH 001/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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 168e116ffa4d58abcdb3d8de9f27a2b37bab7668 Mon Sep 17 00:00:00 2001 From: Amit Shekhar Date: Tue, 27 Aug 2019 16:49:55 -0700 Subject: [PATCH 152/350] msm: vidc: Add support for 16K HEIF encode Add support for 16K HEIF encode by extending HEIF capability and linear color format stride. Change-Id: I3711efb41a1a621345fd68e1929cc416f7b23ef7 Signed-off-by: Amit Shekhar --- msm/vidc/msm_venc.c | 8 ++++---- msm/vidc/msm_vidc_platform.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 59b7b3b2e078..2e0af3514e7f 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1023,17 +1023,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, }, { diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 7d7715a8da4c..3d6a4872e44a 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -365,8 +365,8 @@ 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}, }; /* From f9a35e6304ac28d820547d08399d316116900063 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Tue, 27 Aug 2019 20:59:02 +0800 Subject: [PATCH 153/350] 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 154/350] 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 155/350] 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 95c553361675598bec15a4457305556f3163d495 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Mon, 19 Aug 2019 16:33:24 +0530 Subject: [PATCH 156/350] msm-vidc: add cap for all intra frame encode for lito Add max fps cap for which all intra frame encode is supported. Change-Id: Ia5914c50e507ba11985d08022ed22eb7126ba027 --- msm/vidc/msm_vidc_platform.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 56df8a2cda01..f2458e7f636d 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -221,6 +221,9 @@ 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}, @@ -292,6 +295,9 @@ 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}, From c705bf58efaefd7e9dddf4b4e7973f86c58d75e6 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 26 Aug 2019 20:28:19 +0530 Subject: [PATCH 157/350] 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 158/350] 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 159/350] 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 160/350] 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 161/350] 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 162/350] 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 163/350] 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 043315fa21fe2e95fa9747b3241d4a46eb110c00 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 21 Aug 2019 16:20:37 +0530 Subject: [PATCH 164/350] msm: vidc: add support for dpb_buffer_count payload [1] Send dpb buffer count payload to userspace during seq_change_event. [2] Use min_buffer_req field in dpb_buffer_count pkt to calibrate driver internal buffer calculation. Change-Id: If8cdee618282ea0c8d5affdaa4cddfe502e438f7 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_response_handler.c | 32 ++++++++++++++++++++++++++++++-- msm/vidc/msm_vidc_common.c | 3 ++- msm/vidc/vidc_hfi.h | 2 ++ msm/vidc/vidc_hfi_api.h | 6 +++++- msm/vidc/vidc_hfi_helper.h | 8 ++++++++ 5 files changed, 47 insertions(+), 4 deletions(-) diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index 81d833dc3920..0a3b62f4317b 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -110,6 +110,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, struct hfi_bit_depth *pixel_depth; struct hfi_pic_struct *pic_struct; struct hfi_buffer_requirements *buf_req; + struct hfi_dpb_counts *dpb_counts; struct hfi_index_extradata_input_crop_payload *crop_info; u32 rem_size,entropy_mode = 0; u8 *data_ptr; @@ -266,10 +267,10 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, buf_req = (struct hfi_buffer_requirements *) data_ptr; - event_notify.capture_buf_count = + event_notify.fw_min_cnt = buf_req->buffer_count_min; s_vpr_hp(sid, "Capture Count : 0x%x\n", - event_notify.capture_buf_count); + event_notify.fw_min_cnt); data_ptr += sizeof(struct hfi_buffer_requirements); rem_size -= @@ -300,6 +301,33 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, 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_vidc_common.c b/msm/vidc/msm_vidc_common.c index 60f8d6e79d84..d33fe916de02 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1764,6 +1764,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data) event_notify->profile, inst->sid); ptr[10] = msm_comm_get_v4l2_level(codec, event_notify->level, inst->sid); + ptr[11] = event_notify->fw_min_cnt; s_vpr_h(inst->sid, "seq: height = %u width = %u profile = %u level = %u\n", @@ -1803,7 +1804,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", 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..6df230b90c25 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -622,7 +622,11 @@ struct msm_vidc_cb_event { u32 profile; u32 level; u32 entropy_mode; - u32 capture_buf_count; + u32 max_dpb_count; + u32 max_ref_frames; + u32 max_dec_buffering; + u32 max_reorder_frames; + u32 fw_min_cnt; struct hal_index_extradata_input_crop_payload crop_data; }; 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 46f2efd476b5c2e22e97aeedc7061ebe0a9a9d86 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Fri, 30 Aug 2019 19:12:37 +0530 Subject: [PATCH 165/350] msm-vidc: return unknown ctrl for internal cvp client CVP clients does not set any v4l2 controls on video node. - Remove the present controls for CVP and keep the unknown control alone. - In get_ctrl calls, directly pass the base control inst->ctrls[0] for internal CVP session. Change-Id: I9a1c9f4638039cd93368b6a1e8335d64985e0e3b --- msm/vidc/msm_cvp_internal.c | 8 ++++---- msm/vidc/msm_vidc_common.h | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_cvp_internal.c b/msm/vidc/msm_cvp_internal.c index b5c7350b70c9..cd4abc0d2095 100644 --- a/msm/vidc/msm_cvp_internal.c +++ b/msm/vidc/msm_cvp_internal.c @@ -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_vidc_common.h b/msm/vidc/msm_vidc_common.h index e854cd3abf3d..59fad32145e8 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]; From 16ffe6b0ea40a5b49a074f444436e0bb31275aa1 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Thu, 5 Sep 2019 09:50:01 +0800 Subject: [PATCH 166/350] msm: vidc: add dynamic support of frame quality Add to set frame quality in run time. Change-Id: Ibd694b6c111d1b8a1813e22b6ddaaed77af125ff Signed-off-by: Shi Zhongbo --- msm/vidc/msm_venc.c | 62 ++++++++++++++++++++++++++++++++++++++++++--- msm/vidc/msm_venc.h | 2 ++ 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 26452da8c3e8..8682fbbd195a 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1837,8 +1837,16 @@ 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_CAPTURE_FRAME_RATE: 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: @@ -2925,13 +2933,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 +2960,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 +2995,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; } 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 From 1f61e2cbc32a910ce7be2b144e4bdf794a1730ca Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 9 Sep 2019 17:35:28 +0530 Subject: [PATCH 167/350] msm: vidc: Update mb/frame resolution to 4096x2304 Update maximum mb/frame resolution to 4096x2304, inplace of 4096x2160. Change-Id: I430161bc169e66dc517b9539cb32b00f912cecd2 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_platform.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 65ea4cd885bb..ceb9cc5d95b1 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -162,7 +162,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 +191,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 +212,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 */ @@ -235,8 +235,8 @@ 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}, @@ -286,8 +286,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 */ From 622514e000206baa96c5e5ca20adc125aa382463 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Wed, 11 Sep 2019 17:57:28 -0700 Subject: [PATCH 168/350] msm: vidc: fix extradata none parsing issue Fix an issue in extradata parsing to locate extradata_none header when multiple extradata types are enabled by client to avoid video usecase failure. Change-Id: Ica24b61f24e5d7b5662fd46f2440b63f961f1516 Signed-off-by: Maheshwar Ajja --- msm/vidc/msm_cvp_external.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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__); From a16c6173811f77c3e3563c48149c1647edd6f2f2 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Tue, 10 Sep 2019 14:55:01 +0800 Subject: [PATCH 169/350] 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_venc.c | 3 ++- msm/vidc/msm_vidc_buffer_calculations.c | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 26452da8c3e8..254c3495e870 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -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: @@ -1615,7 +1617,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) { diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 72d252395274..49d1e0f8423b 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. From 3ca1cf09facdb6e8ec1851e70cef31ad6836c0db Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Mon, 22 Jul 2019 10:21:18 +0530 Subject: [PATCH 170/350] msm: vidc: Add platform specific data Add bengal plaform specific video data. CRs-Fixed: 2503996 Change-Id: If196563853ea06dea46b0509378e74e6361ce20e Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_internal.h | 1 + msm/vidc/msm_vidc_platform.c | 133 +++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 610df5a0c1a3..5c957a21d52e 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 { diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 65ea4cd885bb..2a4c606ca6c7 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -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}, @@ -305,6 +323,39 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192}, }; +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[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 8192, 1, 1920}, @@ -712,6 +763,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", @@ -1041,6 +1151,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, // VPU VERSION? + .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), @@ -1111,6 +1240,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, + }, {}, }; From 1b0c12bbbdb27d690ad186eec7688996955a00fe Mon Sep 17 00:00:00 2001 From: Amit Shekhar Date: Wed, 11 Sep 2019 13:49:28 -0700 Subject: [PATCH 171/350] msm: vidc: Allow all-intra encoding in CBR_CFR 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. Change-Id: Ib7cf49561f23076d136c58e0385db411e65883be Signed-off-by: Amit Shekhar --- 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 26452da8c3e8..204bb26bf613 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -4308,6 +4308,13 @@ 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; From b9733c735176427fdef53e34cff7460aa173bb04 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Tue, 30 Jul 2019 10:06:56 +0530 Subject: [PATCH 172/350] msm: vidc: Add config files for bengal Add video config files for bengal to enable video driver CRs-Fixed: 2503996 Change-Id: I0028df934fb5b409393690a5b2d69278e6a5b25c --- Makefile | 9 +++++++++ config/bengalvid.conf | 1 + config/bengalvidconf.h | 6 ++++++ 3 files changed, 16 insertions(+) create mode 100644 config/bengalvid.conf create mode 100644 config/bengalvidconf.h diff --git a/Makefile b/Makefile index 0fcf3f6df3da..0235ce884458 100644 --- a/Makefile +++ b/Makefile @@ -18,4 +18,13 @@ ifeq ($(CONFIG_ARCH_LITO), y) LINUXINCLUDE += -include $(srctree)/techpack/video/config/litovidconf.h endif +# auto-detect subdirs +ifeq ($(CONFIG_ARCH_BENGAL), y) +include $(srctree)/techpack/video/config/bengalvid.conf +endif + +ifeq ($(CONFIG_ARCH_BENGAL), y) +LINUXINCLUDE += -include $(srctree)/techpack/video/config/bengalvidconf.h +endif + obj-y +=msm/ 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 From 7ff089a3c48ba8b9950940bd85a4da1611e0447c Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 13 Sep 2019 21:12:56 +0530 Subject: [PATCH 173/350] msm: vidc: fix kw issues [1] pass __func__ to dprintk. [2] move s_vpr_h to top of put_inst to avoid possible NULL ptr dereference. Change-Id: Ic3f687cf540566574bd04599450f88264eb57864 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_cvp_internal.c | 4 ++-- msm/vidc/msm_venc.c | 2 +- msm/vidc/msm_vidc_common.c | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/msm/vidc/msm_cvp_internal.c b/msm/vidc/msm_cvp_internal.c index f0788d9ba41d..a45f60f52698 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) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 8682fbbd195a..4f097c981289 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -4367,7 +4367,7 @@ int handle_all_intra_restrictions(struct msm_vidc_inst *inst) 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_vidc_common.c b/msm/vidc/msm_vidc_common.c index 60f8d6e79d84..af194177c813 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1252,8 +1252,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( @@ -1893,8 +1893,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 +2110,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 +2160,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 +2511,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 +2688,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) From 557ca136990d2b43a04528f8e96deeab80a972c1 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Fri, 16 Aug 2019 17:00:14 -0700 Subject: [PATCH 174/350] msm: vidc: Update VSP cycle count calculation Update VSP cycle count calculation as per new system recommendations. Use of Entropy and Work Mode for more accuracy. CRs-Fixed: 2502809 Change-Id: I7fcd96c58b583a2a2ff1bc3e918233fbcb7bfa68 Signed-off-by: Chinmay Sawarkar --- msm/vidc/msm_venc.c | 2 ++ msm/vidc/msm_vidc.c | 1 + msm/vidc/msm_vidc_clocks.c | 62 +++++++++++++++++++++++------------- msm/vidc/msm_vidc_debug.c | 2 +- msm/vidc/msm_vidc_platform.c | 18 +++++------ 5 files changed, 53 insertions(+), 32 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 8682fbbd195a..12180c382c2d 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3057,6 +3057,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; } diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index f3281010fa11..42a5a335941b 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1604,6 +1604,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++) { diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index b30a21285186..544df176b853 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -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); 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_platform.c b/msm/vidc/msm_vidc_platform.c index 65ea4cd885bb..f302b161a070 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 */ From f3e936368a647aa0517630d37cf1a239f1d6c633 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 16 Sep 2019 18:36:47 +0530 Subject: [PATCH 175/350] msm: vidc: deprecate firmware buffer requirement property HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS is deprecated. So removed kernel usage. but still kept hfi parsing to support iris 1.x firmware. Change-Id: I6551c231481b519032d684c7dac645ca5624b11e Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_response_handler.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index 0a3b62f4317b..b871d82d5824 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -109,7 +109,6 @@ 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_dpb_counts *dpb_counts; struct hfi_index_extradata_input_crop_payload *crop_info; u32 rem_size,entropy_mode = 0; @@ -264,13 +263,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.fw_min_cnt = - buf_req->buffer_count_min; - s_vpr_hp(sid, "Capture Count : 0x%x\n", - event_notify.fw_min_cnt); data_ptr += sizeof(struct hfi_buffer_requirements); rem_size -= From 81b07d472979f3c25c4f12d89281681966161b02 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Mon, 16 Sep 2019 14:53:07 -0700 Subject: [PATCH 176/350] msm: vidc: Update control capabilities at SESSION_INIT stage Update control capabilities at SESSION_INIT stage instead of SESSION_INIT_DONE to make sure all control capabilities are updated before query capability is done. Change-Id: I682206671e4906c7661270852482a0c59b939765 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_vidc_common.c | 52 ++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 9e8a2fc526ec..3380b5898481 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1461,9 +1461,6 @@ 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 +1487,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 +1530,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 +1592,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, @@ -3180,7 +3191,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", @@ -3189,7 +3199,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"); From 733ea29e462a68fe2c3bf6483d9d1ba4adf89346 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Fri, 13 Sep 2019 11:54:52 +0530 Subject: [PATCH 177/350] msm: vidc: Add bengal specific functions Add bengal specific funtions. CRs-Fixed: 2503996 Change-Id: I5110ca6d95bd18e79adce59bcb32345b09de288b --- msm/vidc/hfi_common.h | 9 +++++++++ 1 file changed, 9 insertions(+) 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 From 1931ba310c69dc79d8819f3ca68ca7e9fdc5c409 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Tue, 17 Sep 2019 17:06:51 +0800 Subject: [PATCH 178/350] msm: vidc: Update bitrate constraint check Update window based average frame size constraint and add max frame size constraint check. CRs-Fixed: 2502809 Change-Id: Ia2d85d0394aec0cbda15314d227642a387ecaad4 Signed-off-by: Qiwei Liu Signed-off-by: Chinmay Sawarkar --- msm/vidc/hfi_common.c | 2 +- msm/vidc/msm_vidc_clocks.c | 12 +++++---- msm/vidc/msm_vidc_common.c | 51 +++++++++++++++++++++++++++----------- 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 162db79feff3..71d7a1658953 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -1039,7 +1039,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; } diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 544df176b853..5554519d46ed 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; } @@ -882,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; @@ -965,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; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 9e8a2fc526ec..ababd394dda2 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1670,6 +1670,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, @@ -7251,7 +7253,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) { @@ -7260,25 +7263,37 @@ 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); + /* + * MaxAvgFrameSize <= (1 + B/S) * (MaxClock / fps - 25*NumOfMacroBlockperFrame) / 1.35 + * S: Sliding window = #Frames in 40ms (av sync window) Closest point + * B: Buffer Count = B(vsp-vpp) = 2 for 2Stage, 0 for 1stage + */ - bitrate = frame_data->filled_len; + fps = inst->clk_data.frame_rate >> 16; + window_size = inst->core->resources.avsync_window_size * fps; + window_size = DIV_ROUND_CLOSEST(window_size, 1000); + window_buffer = inst->clk_data.work_mode == HFI_WORKMODE_2 ? 2 : 0; + + 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 { @@ -7304,13 +7319,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; } From 92344f3eaf50194c1c0748bcfa25e5245faab1e2 Mon Sep 17 00:00:00 2001 From: Ravi Kiran Vonteddu Date: Fri, 13 Sep 2019 14:24:43 +0530 Subject: [PATCH 179/350] msm: vidc: Add new hfi file for AR50 lite Add new hfi file for AR50 lite Change-Id: Idd79d3161b311d319c6fd532b28839e3ede5984b --- msm/Makefile | 1 + msm/vidc/hfi_ar50_lt.c | 238 +++++++++++++++++++++++++++++++++++++++++ msm/vidc/hfi_common.c | 16 +++ 3 files changed, 255 insertions(+) create mode 100644 msm/vidc/hfi_ar50_lt.c 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..22fe9a2d0743 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, @@ -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 From e52cd53e6580c3771fc3c655e8c8308c7fcaa9bf Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 21 Aug 2019 10:30:44 +0530 Subject: [PATCH 180/350] msm: vidc: use macro to get/set fields [1] Use msm_vidc_plane_reserved_field_types for setting/getting plane reserve fields. [2] Use msm_vidc_cb_event_types enum for setting/getting Seq_changed_event types. Change-Id: Ie6cb908515c9714d26f00fdd25af2dfcd875d725 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_response_handler.c | 15 --------- msm/vidc/msm_vidc.c | 20 +++++++----- msm/vidc/msm_vidc_common.c | 56 ++++++++++----------------------- msm/vidc/msm_vidc_internal.h | 8 ----- msm/vidc/vidc_hfi_api.h | 11 ------- 5 files changed, 28 insertions(+), 82 deletions(-) diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index 0a3b62f4317b..ddfceea473c7 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -111,7 +111,6 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, struct hfi_pic_struct *pic_struct; struct hfi_buffer_requirements *buf_req; struct hfi_dpb_counts *dpb_counts; - struct hfi_index_extradata_input_crop_payload *crop_info; u32 rem_size,entropy_mode = 0; u8 *data_ptr; int prop_id; @@ -281,20 +280,6 @@ 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); diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 42a5a335941b..65a48116a008 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]); } } diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 9e8a2fc526ec..796dd5f8a741 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1719,30 +1719,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,34 +1738,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[11] = event_notify->fw_min_cnt; + 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; diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 5c957a21d52e..31b9ce82ed04 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -346,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/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 6df230b90c25..98a053140c14 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -597,16 +597,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; @@ -627,7 +617,6 @@ struct msm_vidc_cb_event { u32 max_dec_buffering; u32 max_reorder_frames; u32 fw_min_cnt; - struct hal_index_extradata_input_crop_payload crop_data; }; struct msm_vidc_cb_data_done { From 533aa1cc95489b778e83ba05c1b6f567815a6555 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Wed, 18 Sep 2019 19:22:28 +0800 Subject: [PATCH 181/350] msm: vidc: don't skip set ctrl for the same value By default, v4l2 driver will skip set ctrl if the same value is set again. Add EXECUTE_ON_WRITE flag for all ctrls to make sure set ctrl is not skipped even when value is unchanged. Change-Id: I67542d648c412e4e87d82cfa9de47f679ab3a860 Signed-off-by: Qiwei Liu --- msm/vidc/msm_vidc_common.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 3e7e96d1a80f..30a1057d8512 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; @@ -7257,12 +7258,6 @@ int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, !frame_data->filled_len) return 0; - /* - * MaxAvgFrameSize <= (1 + B/S) * (MaxClock / fps - 25*NumOfMacroBlockperFrame) / 1.35 - * S: Sliding window = #Frames in 40ms (av sync window) Closest point - * B: Buffer Count = B(vsp-vpp) = 2 for 2Stage, 0 for 1stage - */ - fps = inst->clk_data.frame_rate >> 16; window_size = inst->core->resources.avsync_window_size * fps; window_size = DIV_ROUND_CLOSEST(window_size, 1000); From ea1efd0bea958ef32f3336c9d582598ee55c2553 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Mon, 16 Sep 2019 16:08:41 +0530 Subject: [PATCH 182/350] msm: vidc: Initialize core ops for bengal VPU version For bengal, core operations were falling back to default ops i.e IRIS2 VPU ops. Fix the same by initializing it to bengal specific VPU. CRs-Fixed: 2503996 Change-Id: Ie723216494814456f2905bc20b34a98df33f0cda Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_clocks.c | 8 ++++++-- msm/vidc/msm_vidc_platform.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 5554519d46ed..228b5f0eaf0a 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1682,12 +1682,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_platform.c b/msm/vidc/msm_vidc_platform.c index 43bb19f7650a..dc64f708c297 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1162,7 +1162,7 @@ static struct msm_vidc_platform_data bengal_data = { .efuse_data = NULL, .efuse_data_length = 0, .sku_version = 0, - .vpu_ver = VPU_VERSION_AR50_LITE, // VPU VERSION? + .vpu_ver = VPU_VERSION_AR50_LITE, .ubwc_config = 0x0, .codecs = bengal_codecs, .codecs_count = ARRAY_SIZE(bengal_codecs), From ad8cd1c49df2acd6d81e159fccbec47e45cd1e4d Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 20 Sep 2019 17:57:33 +0530 Subject: [PATCH 183/350] msm: vidc: delete v4l2 controls after queue release vb queue release calls stop streaming. In stop streaming, video driver may need to access the v4l2 controls. Deleting the v4l2 controls before releasing the vb queue may lead to NULL access. Change-Id: I7b64fda2fab0cbd5030ca8e88363076238b218ea Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 65a48116a008..ad80a317c02c 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1810,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); @@ -1820,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); From 46e209521101390f16656939242dbb2f6fb7f236 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Thu, 19 Sep 2019 13:54:29 -0700 Subject: [PATCH 184/350] msm: vidc: Update Kona Profile Level Capabilities Update HEVC Enc/Dec, AVC Enc/Dec and VP9 Dec profile level capabilities to allign with PRD specifications. Change-Id: If192dc7c5b7ca3bb3eaa2ab17b586f13e85b1c3f Signed-off-by: Akshata Sahukar --- msm/vidc/msm_vidc_common.c | 10 +++++++ msm/vidc/msm_vidc_platform.c | 57 ++++++++++++++++++++++++++++++++++++ msm/vidc/vidc_hfi_api.h | 3 ++ 3 files changed, 70 insertions(+) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 30a1057d8512..db607f2c8258 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1455,7 +1455,17 @@ static void msm_vidc_comm_update_ctrl_limits(struct msm_vidc_inst *inst) msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES, &inst->capability.cap[CAP_BFRAME]); + } else if (inst->session_type == MSM_VIDC_DECODER) { + msm_vidc_comm_update_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL, + &inst->capability.cap[CAP_VP9_LEVEL]); } + 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) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index dc64f708c297..d6e3d53d9835 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -247,6 +247,25 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {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}, + {CAP_VP9_LEVEL, DEC, VP9, V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_UNUSED, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6, 1, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6}, }; static struct msm_vidc_codec_capability lito_capabilities_v1[] = { @@ -321,6 +340,25 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {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}, + {CAP_VP9_LEVEL, DEC, VP9, V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_UNUSED, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6, 1, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6}, }; static struct msm_vidc_codec_capability bengal_capabilities[] = { @@ -436,6 +474,25 @@ static struct msm_vidc_codec_capability kona_capabilities[] = { {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 */ + {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}, + {CAP_VP9_LEVEL, DEC, VP9, V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_UNUSED, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6, 1, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6}, }; /* diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 98a053140c14..3733da9acbd8 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -286,6 +286,9 @@ 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_VP9_LEVEL, CAP_MAX, }; From 9d3a015f1567c99cf636b354ea74da7b9d8fdfd2 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Tue, 17 Sep 2019 15:22:09 +0530 Subject: [PATCH 185/350] msm-vidc: calculate buffer size based on 512x512 for heic For HEIC encoding, client sets output resolution = input resolution. However, driver produces tile based output. Hence, output buffer size and firmware output buffer size should be based on tile size. Change-Id: Ib1fe1c1caaf09f01b928f8b6e54e8e473c50f411 Signed-off-by: Amit Shekhar --- msm/vidc/msm_venc.c | 7 ++++++- msm/vidc/msm_vidc_buffer_calculations.c | 4 ++++ msm/vidc/msm_vidc_common.c | 15 ++++----------- msm/vidc/msm_vidc_common.h | 10 ++++++++++ 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index b96d6e9b3fa8..f7a675853bce 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, @@ -1929,6 +1929,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, diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 49d1e0f8423b..27730fc67c3e 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -980,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_common.c b/msm/vidc/msm_vidc_common.c index 30a1057d8512..70bc60f697be 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5594,15 +5594,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; @@ -5687,7 +5682,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) { @@ -5750,8 +5744,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 != diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 25ff7672713a..df6cfdacfa94 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -110,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; From 349732b1e7b7a42b4de3068a68a502a4af32f1aa Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Mon, 23 Sep 2019 11:16:18 +0800 Subject: [PATCH 186/350] msm: vidc: update LTRUse maximum limit This parameter is used as a bitmap instead of index, update the maximum limit accordingly. Change-Id: I2a06001db25c4d948a834e8758805bfcd37b0e69 Signed-off-by: Qiwei Liu --- 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 f7a675853bce..4128086b1fa7 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -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, From bc60bd650de32be9024ded66393c7b49f2339761 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Mon, 23 Sep 2019 10:30:10 -0700 Subject: [PATCH 187/350] msm: vidc: Add support of level 6.1 to VP9 decoder SM8250 supports VP9 8k@60fps decode. Hence, we need to support upto level 6.1. Change-Id: I2f6509c34fb2d26ac980ebe536baa6ff72e32e80 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_vidc_common.c | 4 ---- msm/vidc/msm_vidc_platform.c | 9 --------- msm/vidc/vidc_hfi_api.h | 1 - 3 files changed, 14 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 95e467c89cf6..f7affacbb3c7 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1455,10 +1455,6 @@ static void msm_vidc_comm_update_ctrl_limits(struct msm_vidc_inst *inst) msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES, &inst->capability.cap[CAP_BFRAME]); - } else if (inst->session_type == MSM_VIDC_DECODER) { - msm_vidc_comm_update_ctrl(inst, - V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL, - &inst->capability.cap[CAP_VP9_LEVEL]); } msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LEVEL, diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index d6e3d53d9835..2900e9917768 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -263,9 +263,6 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {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}, - {CAP_VP9_LEVEL, DEC, VP9, V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_UNUSED, - V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6, 1, - V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6}, }; static struct msm_vidc_codec_capability lito_capabilities_v1[] = { @@ -356,9 +353,6 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {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}, - {CAP_VP9_LEVEL, DEC, VP9, V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_UNUSED, - V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6, 1, - V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6}, }; static struct msm_vidc_codec_capability bengal_capabilities[] = { @@ -490,9 +484,6 @@ static struct msm_vidc_codec_capability kona_capabilities[] = { {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}, - {CAP_VP9_LEVEL, DEC, VP9, V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_UNUSED, - V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6, 1, - V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_6}, }; /* diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 3733da9acbd8..ee2bb6614785 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -288,7 +288,6 @@ enum hal_capability { CAP_HEIC_IMAGE_FRAME_HEIGHT, CAP_H264_LEVEL, CAP_HEVC_LEVEL, - CAP_VP9_LEVEL, CAP_MAX, }; From aa56c6733a9f8755ebd1fedc64b142accba79426 Mon Sep 17 00:00:00 2001 From: Amit Shekhar Date: Thu, 19 Sep 2019 15:05:58 -0700 Subject: [PATCH 188/350] msm: vidc: Set fps to 1 for image encode sessions Framework may, incorrectly, set fps to number of output tiles. As a result, MBs per second for HEIF encode can be pretty large for high resolution images. This change sets fps to 1 for image session with tiling. Disable power saving for all image sessions. Change-Id: I2ef8f638421460dc7f6b1f3b3709d0f1a9c5a705 Signed-off-by: Shi Zhongbo --- msm/vidc/msm_venc.c | 15 ++++++++++++++- msm/vidc/msm_vidc_clocks.c | 5 ++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index f7a675853bce..eef9e268adc5 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1572,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) { @@ -1847,8 +1853,15 @@ 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_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: diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 228b5f0eaf0a..6b81e6e10690 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1636,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); From e1177c2dfbc9ef373c1b99d1b566d034eb5907c8 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 23 Sep 2019 22:55:21 +0530 Subject: [PATCH 189/350] 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 f7affacbb3c7..bff591fa600e 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2402,6 +2402,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); @@ -4000,6 +4001,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; @@ -4016,6 +4020,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 31b9ce82ed04..b4a70048ca7c 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -186,6 +186,7 @@ struct recon_buf { struct eos_buf { struct list_head list; struct msm_smem smem; + u32 is_queued; }; struct internal_buf { From 6bfd15e9fa09a85b42ed77bc1416a3c8d66eec10 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 24 Sep 2019 12:11:33 -0700 Subject: [PATCH 190/350] 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 2900e9917768..7a8275f488c0 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -22,8 +22,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) \ { \ @@ -1377,8 +1377,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; } else if (!strcmp(match->compatible, "qcom,lito-vidc")) { rc = msm_vidc_read_efuse(driver_data, dev); From 14bb9459f3fb3cade54cf5d968d8559291e0246b Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Thu, 26 Sep 2019 11:32:10 +0530 Subject: [PATCH 191/350] 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 f02cbba6de0b..b979b0a858a9 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1861,6 +1861,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: @@ -1880,7 +1883,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: @@ -3622,16 +3624,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 ad80a317c02c..20787b196bda 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1609,6 +1609,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 b4a70048ca7c..da2a9a104ece 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -53,6 +53,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 @@ -568,6 +569,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 b8561ba865440eb20be951495c71438fbc1762fd Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Fri, 20 Sep 2019 15:12:08 -0700 Subject: [PATCH 192/350] 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 | 43 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 7a8275f488c0..a53ea5a9a02d 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1305,10 +1305,11 @@ static int msm_vidc_read_efuse( 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); @@ -1330,7 +1331,6 @@ static int msm_vidc_read_efuse( devm_iounmap(dev, base); } break; - default: break; } @@ -1346,6 +1346,7 @@ void *vidc_get_drv_data(struct device *dev) int rc = 0; if (!IS_ENABLED(CONFIG_OF) || !dev->of_node) { + d_vpr_e("Using default_data\n"); driver_data = &default_data; goto exit; } @@ -1355,35 +1356,23 @@ 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,sdm670-vidc")) { + + /* 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,sdm670-vidc")) { 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) { - 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; } 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 = @@ -1391,6 +1380,18 @@ void *vidc_get_drv_data(struct device *dev) driver_data->codec_caps = lito_capabilities_v1; driver_data->codec_caps_count = ARRAY_SIZE(lito_capabilities_v1); } + } else if (!strcmp(match->compatible, "qcom,kona-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->highest_bank_bit); } exit: From a132d345524a56d00041a1e363ba15cc4b84bb63 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Thu, 26 Sep 2019 17:46:57 -0700 Subject: [PATCH 193/350] msm: vidc: Fix to set correct profile levls to Video Firmware Avoid setting incorrect profile level to Video Firmware. Change-Id: I4f7af01fe77269758d7bcead383e284e995238a2 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_vidc_common.c | 4 ++++ msm/vidc/msm_vidc_platform.c | 24 ++++++++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index bff591fa600e..0a4436bee6db 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1462,6 +1462,10 @@ 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 7a8275f488c0..0beab37b71dd 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -248,7 +248,11 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {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 */ + /* 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}, @@ -256,7 +260,7 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { 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}, @@ -338,7 +342,11 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {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 */ + /* 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}, @@ -346,7 +354,7 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { 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}, @@ -469,7 +477,11 @@ static struct msm_vidc_codec_capability kona_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}, @@ -477,7 +489,7 @@ static struct msm_vidc_codec_capability kona_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 bb23deb37555615dbc2e678cc0fc7653d0694046 Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Fri, 27 Sep 2019 15:52:43 -0700 Subject: [PATCH 194/350] msm: vidc: Update encoder scratch1 size Update encoder scratch1 buffer size to match hfi ccb change for downscalar cases. Change-Id: I6d46227291d8ff3621a19c02940dd555f9103981 --- 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 27730fc67c3e..1c0582d59c66 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1588,6 +1588,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); @@ -1695,7 +1696,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 1c46a1438ff65d33b6d44f37edd9134045eb0274 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Fri, 27 Sep 2019 11:18:57 -0700 Subject: [PATCH 195/350] 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 6b81e6e10690..4f347678857e 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -469,26 +469,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, @@ -1107,11 +1108,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 04e5f91780b9d18c8130e565862a2fabdd6c5099 Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 1 Oct 2019 16:18:23 -0700 Subject: [PATCH 196/350] 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 1c0582d59c66..abe74222b5ff 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 5541224a0f43c04d12834df044a1070651e1983b Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Thu, 19 Sep 2019 14:05:02 +0530 Subject: [PATCH 197/350] 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 --- msm/vidc/msm_vidc_platform.c | 58 ++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 0beab37b71dd..6bbcbc552c74 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -181,8 +181,8 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {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}, + /* ((3840x2176)/256)@60fps */ + {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 1958400, 1, 1958400}, {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}, @@ -209,10 +209,10 @@ 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 * 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}, + /* (4096 * 2176) / 256 */ + {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 36, 34816, 1, 8160}, + /* (3840 * 2176) / 256) * 30*/ + {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 36, 979200, 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}, @@ -230,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 * 2304) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 36864, 1, 8160}, + /* (4096 * 2176) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 34816, 1, 8160}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, /* Batch Mode Decode */ @@ -273,10 +273,10 @@ 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}, + /* ((4096 * 2176) / 256) */ + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 34816, 1, 8160}, + /* UHD@30 decode + 1080@30 encode */ + {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 1224000, 1, 1224000}, {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}, @@ -324,8 +324,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 * 2304) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 36864, 1, 8160}, + /* (4096 * 2176) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 34816, 1, 8160}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, /* Batch Mode Decode */ @@ -458,8 +458,8 @@ static struct msm_vidc_codec_capability kona_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 */ @@ -545,8 +545,8 @@ static struct msm_vidc_common_data lito_common_data_v0[] = { }, { .key = "qcom,max-hw-load", - .value = 3110400,/* ((4096x2160)/256)@90fps */ - /* 4k@60 decode + 4k@30 encode */ + .value = 1958400,/* ((3840x2176)/256)@60fps */ + /* UHD@30 decode + UHD@30 encode */ }, { .key = "qcom,max-hq-mbs-per-frame", @@ -621,7 +621,7 @@ static struct msm_vidc_common_data lito_common_data_v1[] = { }, { .key = "qcom,max-hw-load", - .value = 1281600,/* 4K@30 decode + 1080@30 encode */ + .value = 1224000,/* UHD@30 decode + 1080@30 encode */ }, { .key = "qcom,max-hq-mbs-per-frame", @@ -696,31 +696,31 @@ static struct msm_vidc_common_data kona_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", @@ -911,7 +911,7 @@ static struct msm_vidc_common_data sm8150_common_data[] = { .value = 3916800, /* * 1920x1088/256 MBs@480fps. It is less * any other usecases (ex: - * 3840x2160@120fps, 4096x2160@96ps, + * 3840x2176@120fps, 4096x2176@96ps, * 7680x4320@30fps) */ }, @@ -992,7 +992,7 @@ static struct msm_vidc_common_data sdm845_common_data[] = { }, { .key = "qcom,max-hw-load", - .value = 3110400, /* 4096x2160@90 */ + .value = 3133440, /* 4096x2176@90 */ }, { .key = "qcom,max-hq-mbs-per-frame", From d37ffdd1e4e8cbb22168f0d4ac1f8958d508b5b8 Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Tue, 1 Oct 2019 21:09:53 -0700 Subject: [PATCH 198/350] 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 b979b0a858a9..5bc0697089a9 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -250,7 +250,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) @@ -1864,12 +1864,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: @@ -3054,7 +3058,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) { @@ -3066,10 +3069,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); @@ -3078,8 +3078,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; } @@ -4352,6 +4350,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; @@ -4464,6 +4484,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 c634e5c55db454581ac1b071c4ee5c33e99702e3 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Thu, 10 Oct 2019 15:27:12 -0700 Subject: [PATCH 199/350] msm: vidc: Disable Kernel to Kernel CVP usage Add support to disable kernel to kernel CVP usage. Change-Id: I8cb7fa69f0a87fba6b735b8b8aadab1059779c6c Signed-off-by: Akshata Sahukar --- msm/vidc/msm_vidc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 20787b196bda..78a2f8bc3e6d 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -782,8 +782,9 @@ bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst) is_secure_session(inst), superframe_enable->val); allowed = false; } + s_vpr_h(inst->sid, "%s: Hardcoded as cvp not allowed\n", __func__); exit: - return allowed; + return false; } static int msm_vidc_prepare_preprocess(struct msm_vidc_inst *inst) From 3e2e6a2e37c26db3153c964d95076af3bb6235ce Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 11 Oct 2019 21:25:05 +0530 Subject: [PATCH 200/350] 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 3d2560049267..3371934dd65b 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 abe74222b5ff..ee1a02de30ab 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 @@ -744,6 +747,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); @@ -792,9 +796,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 1d6a681644b098c33fb407e24de5d5979b8d0022 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Mon, 14 Oct 2019 16:27:08 +0800 Subject: [PATCH 201/350] 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 0a4436bee6db..3ae943d4f5cb 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5566,7 +5566,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, @@ -5834,7 +5834,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 b3089c34ed953de5d261b2cc92c171bf4d5b63e9 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Wed, 25 Sep 2019 12:30:54 -0700 Subject: [PATCH 202/350] 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 --- msm/vidc/msm_venc.c | 43 ++++++++++++++++++++++++++++-------- msm/vidc/msm_vidc_platform.c | 6 ++++- msm/vidc/vidc_hfi_api.h | 1 + 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 5bc0697089a9..96e5ce38ed89 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1506,6 +1506,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; @@ -1564,6 +1587,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", @@ -2645,7 +2672,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; @@ -2671,8 +2697,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, @@ -2688,12 +2713,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); @@ -2760,10 +2785,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); @@ -4485,6 +4510,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); @@ -4512,9 +4540,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 6bbcbc552c74..b72961bd0d55 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -185,6 +185,7 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 1958400, 1, 1958400}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 480, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 200000000, 1, 20000000}, + {CAP_CABAC_BITRATE, ENC, H264, 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}, @@ -279,6 +280,7 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 1224000, 1, 1224000}, {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}, @@ -406,6 +408,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_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}, @@ -438,7 +442,7 @@ static struct msm_vidc_codec_capability kona_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 ee2bb6614785..a51283b062b7 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -247,6 +247,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 a71152ba77ecaf28d6cac3f9d793dfe13bb68cfd Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Tue, 15 Oct 2019 18:52:27 -0700 Subject: [PATCH 203/350] 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 5bc0697089a9..90484dbaecf9 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1161,7 +1161,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); @@ -1601,6 +1601,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 639c5a0f79ff19ade0d77a41bd6a6482208ef3f2 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Fri, 11 Oct 2019 15:30:49 +0530 Subject: [PATCH 204/350] 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 12f645981e37..4eff2ba29378 100644 --- a/msm/vidc/msm_smem.c +++ b/msm/vidc/msm_smem.c @@ -192,6 +192,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", @@ -224,6 +225,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 73243a5742df75d32d5aa563390c5b799f373074 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Fri, 18 Oct 2019 14:53:37 +0530 Subject: [PATCH 205/350] msm-vidc: don't update capabilities for CVP session Video driver don't define capabilities for cvp, so avoid calling update capabilities for cvp domain. Change-Id: I42eb7680b8075405e19b289482392c437bc48032 Signed-off-by: Dikshita Agarwal --- msm/vidc/msm_vidc_common.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 3e7e96d1a80f..5d22e607cce8 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1480,13 +1480,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); @@ -1513,6 +1506,11 @@ static int msm_comm_update_capabilities(struct msm_vidc_inst *inst) return -EINVAL; } + if (inst->session_type == MSM_VIDC_CVP) { + s_vpr_h(inst->sid, "%s: cvp session\n", __func__); + return 0; + } + core = inst->core; codec = get_v4l2_codec(inst); From a67915e8b8e13084d4e9692b36af699f4e18d1ed Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Mon, 21 Oct 2019 13:44:32 -0700 Subject: [PATCH 206/350] 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 4f347678857e..d8abc6f14672 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -762,6 +762,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 22769d24774e2851e7004dff94a644a31c11a888 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Wed, 16 Oct 2019 22:39:56 -0700 Subject: [PATCH 207/350] 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 ee1a02de30ab..b4813f7c1866 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -764,16 +764,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 @@ -808,21 +807,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; } @@ -848,22 +847,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 @@ -871,8 +873,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 @@ -881,16 +881,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 8ffbd2fd1feab31417e98483ae7d5d3097a3ba0d Mon Sep 17 00:00:00 2001 From: Darshana Patil Date: Wed, 23 Oct 2019 15:35:59 -0700 Subject: [PATCH 208/350] 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 96e5ce38ed89..dee8427be836 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1932,11 +1932,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; } @@ -2622,15 +2622,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 ba15caff93de986b2a643ca23d074ab4c2d2edb9 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Thu, 24 Oct 2019 11:47:08 +0530 Subject: [PATCH 209/350] msm-vidc: fix if check in setup_ucregion_memory_map_iris1 function Currently video driver will try to write to SFR register even if address is 0 due to incorrect if check, fix it by removing second operand sid from if check. Change-Id: Idb5af4af70dba658e8ee3e8b00ea7112e6ae2660 Signed-off-by: Dikshita Agarwal --- msm/vidc/hfi_iris1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/hfi_iris1.c b/msm/vidc/hfi_iris1.c index b08eb68d9358..f7d2c19e379c 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) From 5e8272e41b248224ab2d99313b4bd355272f4fc3 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Fri, 4 Oct 2019 13:18:38 +0530 Subject: [PATCH 210/350] 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. CRs-Fixed: 2450395 Change-Id: Iee680fa6addf0bc1d363a69a8a7297f20abb5ee2 Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_platform.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 63bfd33c85de..f0f825842e3b 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -568,6 +568,10 @@ static struct msm_vidc_common_data lito_common_data_v0[] = { .key = "qcom,max-b-frame-mbs-per-sec", .value = 244800,/* ((1920x1088)/256) MBs@30fps */ }, + { + .key = "qcom,max-mbpf", + .value = 65280,/* (3840x2176)/256 + (3840x2176)/256 */ + }, { .key = "qcom,power-collapse-delay", .value = 1500, @@ -643,6 +647,10 @@ static struct msm_vidc_common_data lito_common_data_v1[] = { .key = "qcom,max-b-frame-mbs-per-sec", .value = 244800,/* ((1920x1088)/256) MBs@30fps */ }, + { + .key = "qcom,max-mbpf", + .value = 40800, /* (3840x2176)/256 + (1920x1088)/256 */ + }, { .key = "qcom,power-collapse-delay", .value = 1500, From c291cec21b8b23e6549e6c6d07cf4ebbe34e234f Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Wed, 23 Oct 2019 15:26:51 -0700 Subject: [PATCH 211/350] 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 3371934dd65b..47b1dd3cfa4b 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -651,6 +651,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 e4c1f173cf9d..8c27a767a90e 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1384,6 +1384,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 3656803928b76e5febf710bf1c0e69d374891e95 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 16 Oct 2019 19:54:00 +0530 Subject: [PATCH 212/350] msm: vidc: Configure work mode 2 based on rate control Existing code sets work mode as 1 for all encoder usecases. For VBR and MBR cases, work mode is required to be 2. Hence setting the same based on RC mode. Change-Id: I882807ccc4e0348e2cdfab1e74b80a55a47b754d Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_clocks.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index d8abc6f14672..66d3d773dddb 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1311,9 +1311,13 @@ static int msm_vidc_decide_work_mode_ar50(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) + pdata.video_work_mode = HFI_WORKMODE_2; + } else { return -EINVAL; } From a9ffcc81e1946b220d76151b57b4235fcc7f5dae Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Mon, 14 Oct 2019 18:28:55 +0800 Subject: [PATCH 213/350] 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 --- msm/vidc/msm_venc.c | 20 ++++++++++++++++++++ msm/vidc/msm_vidc.c | 13 +++++++++++++ 2 files changed, 33 insertions(+) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 696c2560afd0..ae5cc2abbb61 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -74,6 +74,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_VIDEO_UNKNOWN, @@ -974,6 +980,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 78a2f8bc3e6d..18053015d48e 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1519,6 +1519,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 5a05465676571e95275102bb7bf504aa437c5fcf Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Tue, 22 Oct 2019 17:26:21 -0700 Subject: [PATCH 214/350] msm: vidc: Remove support for k-k CVP usage Remove kernel to kernel CVP usage support completely. Change-Id: Ib62fa7cebbf0a85c2b7140948903676c0960c1c5 Signed-off-by: Akshata Sahukar --- msm/Makefile | 1 - msm/vidc/msm_cvp_external.c | 1499 ---------------------------------- msm/vidc/msm_cvp_external.h | 202 ----- msm/vidc/msm_venc.c | 28 +- msm/vidc/msm_vidc.c | 178 ---- msm/vidc/msm_vidc_common.c | 34 - msm/vidc/msm_vidc_internal.h | 5 - 7 files changed, 23 insertions(+), 1924 deletions(-) delete mode 100644 msm/vidc/msm_cvp_external.c delete mode 100644 msm/vidc/msm_cvp_external.h diff --git a/msm/Makefile b/msm/Makefile index df7f6020801b..c2e81708d3a3 100644 --- a/msm/Makefile +++ b/msm/Makefile @@ -10,7 +10,6 @@ msm-vidc-objs := vidc/msm_v4l2_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/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_venc.c b/msm/vidc/msm_venc.c index deab5538cbaf..d5e43ea47d9d 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -4329,11 +4329,25 @@ int msm_venc_set_extradata(struct msm_vidc_inst *inst) } } - if(!msm_vidc_cvp_usage) - inst->prop.extradata_ctrls &= ~EXTRADATA_ENC_INPUT_CVP; + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) { + struct v4l2_ctrl *max_layers = NULL; + u32 value = 0x1; - /* 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*/ + max_layers = get_ctrl(inst, + V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); + if (!msm_vidc_cvp_usage || max_layers->val > 1) { + inst->prop.extradata_ctrls &= ~EXTRADATA_ENC_INPUT_CVP; + value = 0x0; + } + 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) + s_vpr_h(inst->sid, + "%s: set CVP extradata failed\n", __func__); + } else { + s_vpr_h(inst->sid, "%s: CVP extradata not enabled\n", __func__); + } return rc; } @@ -4371,7 +4385,8 @@ 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 || + !(inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP)) return 0; capture_rate_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_CAPTURE_FRAME_RATE); @@ -4642,6 +4657,9 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst) if (rc) goto exit; rc = msm_venc_set_extradata(inst); + if (rc) + goto exit; + rc = msm_venc_set_cvp_skipratio(inst); if (rc) goto exit; rc = msm_venc_set_operating_rate(inst); diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 78a2f8bc3e6d..0eda658c2fb9 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -12,7 +12,6 @@ #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" @@ -735,144 +734,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; - } - s_vpr_h(inst->sid, "%s: Hardcoded as cvp not allowed\n", __func__); -exit: - return false; -} - -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; - u32 value = 0x0; - - if (!inst) { - d_vpr_e("%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; - - 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) { - 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; -} - static inline int start_streaming(struct msm_vidc_inst *inst) { int rc = 0; @@ -889,17 +750,6 @@ 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) { - s_vpr_e(inst->sid, "%s: no preprocessing\n", __func__); - /* ignore error */ - rc = 0; - } - if (!(msm_vidc_set_cvp_metadata(inst))) - goto fail_start; - } - b.buffer_type = HFI_BUFFER_OUTPUT; if (inst->session_type == MSM_VIDC_DECODER && is_secondary_output_mode(inst)) @@ -1124,25 +974,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; @@ -1159,11 +990,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; } @@ -1887,10 +1713,6 @@ int msm_vidc_close(void *instance) 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_common.c b/msm/vidc/msm_vidc_common.c index a2f5af7fcb6b..d835497e9939 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -15,7 +15,6 @@ #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" @@ -4121,35 +4120,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) { @@ -4501,10 +4471,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) diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index da2a9a104ece..32026f376ad8 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -59,10 +59,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 @@ -506,7 +502,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]; From adad39302da914eb72538bd601f6a25d68366063 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Mon, 14 Oct 2019 16:59:23 +0530 Subject: [PATCH 215/350] msm: vidc: Fix 32-bit compilation issues Typecast the msm_vidc_arg argument correctly CRs-Fixed: 2546421 Change-Id: I781767befa529cbe9366d67cb0773d97eb9f1beb Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_v4l2_private.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_v4l2_private.c b/msm/vidc/msm_v4l2_private.c index 7155c2d42bc3..f7428e4fb9e9 100644 --- a/msm/vidc/msm_v4l2_private.c +++ b/msm/vidc/msm_v4l2_private.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include "msm_v4l2_private.h" @@ -9,7 +9,7 @@ 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); + struct msm_vidc_arg __user *up = (struct msm_vidc_arg *)arg; if (!kp || !up) { d_vpr_e("%s: invalid params%pK %pK\n", __func__, kp, up); @@ -101,7 +101,7 @@ 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); + struct msm_vidc_arg __user *up = (struct msm_vidc_arg *)arg; if (!kp || !up) { d_vpr_e("%s: invalid params %pK %pK\n", __func__, kp, up); From a4391c040c9ff72f63668ea7ce2d25095d5a3c4d Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Thu, 31 Oct 2019 14:32:36 +0530 Subject: [PATCH 216/350] msm: vidc: Update capabilities for bengal Update few capabilities like B-frames, Max-MB's, Codecs for bengal target. CRs-Fixed: 2558188 Change-Id: I52bdf3e03ed78915aa3ca218cad89b6da938a606 Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_platform.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 63bfd33c85de..329dbcdf1fb1 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -105,12 +105,8 @@ static struct msm_vidc_codec_data sm6150_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_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), }; @@ -369,13 +365,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 */ @@ -383,7 +378,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}, @@ -394,7 +388,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 30c7f94d856aa0b46a570d7dd466a0b76d8adfd7 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Wed, 6 Nov 2019 16:37:37 +0530 Subject: [PATCH 217/350] 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 63bfd33c85de..92f4616dcb46 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1407,7 +1407,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: From 974b33620509a5cc846ec68f08a7c584bd0ef833 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 16 Oct 2019 11:38:37 +0530 Subject: [PATCH 218/350] msm: vidc: add 32 bit support in video driver The commit adds the following 1 Expose 32 bit compatibility ioctl only if the compat config is enabled. 2 Keep DMA mask aligned with api definition. 3 Replace the various division operations with 32 bit compatible modules. CRs-Fixed: 2546421 Change-Id: I7bc931ffd124ef2b0be8d2bec44fbebf29d4cfb3 Signed-off-by: Vikash Garodia --- msm/vidc/msm_v4l2_vidc.c | 2 ++ msm/vidc/msm_vidc_clocks.c | 32 ++++++++++++++++---------------- msm/vidc/msm_vidc_common.c | 8 ++++---- msm/vidc/msm_vidc_res_parse.c | 2 +- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index 22a8683a0820..4819bbd46c03 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -255,7 +255,9 @@ static const struct v4l2_file_operations msm_v4l2_vidc_fops = { .open = msm_v4l2_open, .release = msm_v4l2_close, .unlocked_ioctl = video_ioctl2, +#ifdef CONFIG_COMPAT .compat_ioctl32 = msm_v4l2_private, +#endif .poll = msm_v4l2_poll, }; diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index d8abc6f14672..4a54d2741b42 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -602,7 +602,7 @@ static unsigned long msm_vidc_calc_freq_ar50(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__); @@ -679,8 +679,8 @@ static unsigned long msm_vidc_calc_freq_iris1(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); } else if (inst->session_type == MSM_VIDC_DECODER) { vpp_cycles = mbs_per_second * inst->clk_data.entry->vpp_cycles / @@ -691,7 +691,7 @@ static unsigned long msm_vidc_calc_freq_iris1(struct msm_vidc_inst *inst, 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; + vsp_cycles += div_u64((fps * filled_len * 8 * 10), 5); } else { s_vpr_e(inst->sid, "%s: Unknown session type\n", __func__); @@ -758,17 +758,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 */ @@ -778,17 +778,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) @@ -804,18 +804,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 a2f5af7fcb6b..b0bbaf96d6c4 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7274,10 +7274,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 8ecadde92f6e..90964d42e80f 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -1007,7 +1007,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 4957c0a7ce90e500208c26f157c59b9a95cbd02a Mon Sep 17 00:00:00 2001 From: Chinmay Sawarkar Date: Tue, 5 Nov 2019 15:11:46 -0800 Subject: [PATCH 219/350] 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 4a54d2741b42..02d7f4bafa3c 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -729,6 +729,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; @@ -781,8 +782,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; @@ -807,9 +811,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 63bfd33c85de..ffde521f4ea7 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -80,13 +80,13 @@ static struct msm_vidc_codec_data lito_codec_data[] = { 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_VP8, MSM_VIDC_ENCODER, 60, 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), + CODEC_ENTRY(V4L2_PIX_FMT_VP8, MSM_VIDC_DECODER, 60, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 60, 200, 200), }; /* Update with SM6150 data */ From 80799b1ba8952f61dca1d8d0374ec4647fa7f109 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Fri, 13 Sep 2019 16:21:55 +0530 Subject: [PATCH 220/350] 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 df7f6020801b..6f184866a8af 100644 --- a/msm/Makefile +++ b/msm/Makefile @@ -23,6 +23,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_iris1.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 07a5371df699..fd81eef11d5e 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 fe49b21750b37cee0006c5957e359c0323984f5e Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Tue, 12 Nov 2019 15:07:28 +0530 Subject: [PATCH 221/350] 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 f1d9e9fbca08..65aee5d13715 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -378,6 +378,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}, @@ -390,6 +391,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 kona_capabilities[] = { From 8797296a92f4780f3ee71bcb5b4dc6033a137c8e Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Wed, 13 Nov 2019 16:48:29 +0530 Subject: [PATCH 222/350] 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 --- msm/vidc/msm_vidc_bus_ar50lite.c | 8 -------- msm/vidc/msm_vidc_clocks.c | 12 +++++++++++- 2 files changed, 11 insertions(+), 9 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; diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index d8abc6f14672..ddf6ec3f25a1 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -32,6 +32,14 @@ struct msm_vidc_core_ops core_ops_ar50 = { .calc_bw = NULL, }; +struct msm_vidc_core_ops core_ops_ar50lt = { + .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, + .calc_bw = calc_bw_ar50lt, +}; + struct msm_vidc_core_ops core_ops_iris1 = { .calc_freq = msm_vidc_calc_freq_iris1, .decide_work_route = msm_vidc_decide_work_route_iris1, @@ -1701,8 +1709,10 @@ 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) + if (vpu == VPU_VERSION_AR50) core->core_ops = &core_ops_ar50; + else if (vpu == VPU_VERSION_AR50_LITE) + core->core_ops = &core_ops_ar50lt; else if (vpu == VPU_VERSION_IRIS1) core->core_ops = &core_ops_iris1; else From 5a9f8395970f2f75a63e5ae26ed6bf54611fcebd Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Fri, 15 Nov 2019 13:35:01 +0530 Subject: [PATCH 223/350] 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 65aee5d13715..bb1c518e2b99 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -103,11 +103,11 @@ static struct msm_vidc_codec_data sm6150_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), }; /* Update with 855 data */ From 539875b3a91a3912554c3ab07178891588678cae Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Fri, 15 Nov 2019 16:13:31 +0800 Subject: [PATCH 224/350] 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 6f3c198e09fa..539f6c029e57 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1679,6 +1679,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; @@ -1918,6 +1924,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: @@ -2200,7 +2209,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) { @@ -2211,9 +2219,7 @@ int msm_venc_set_operating_rate(struct msm_vidc_inst *inst) return 0; 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 f1a4dfc1da41e2323de3dfe45c132d6d264a0e28 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Wed, 4 Sep 2019 18:52:49 +0800 Subject: [PATCH 225/350] msm: vidc: initialize port format type Initialize port format type to avoid failure when g_fmt called before s_fmt. Change-Id: I8b9c2b656e6d1a1660c3bfeff7006ed667f97214 Signed-off-by: Qiwei Liu --- 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 47b1dd3cfa4b..4d9cb82605b0 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -761,6 +761,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 = V4L2_BUF_TYPE_VIDEO_CAPTURE_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; @@ -782,6 +783,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 = V4L2_BUF_TYPE_VIDEO_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; diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 6f3c198e09fa..eeaf7e368a15 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1138,6 +1138,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) return -EINVAL; } f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; f->fmt.pix_mp.height = DEFAULT_HEIGHT; f->fmt.pix_mp.width = DEFAULT_WIDTH; f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; @@ -1157,6 +1158,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 = V4L2_BUF_TYPE_VIDEO_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; From 427ac510433a418564c5a7e6e41bcf685cd80e00 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Mon, 18 Nov 2019 10:41:24 +0800 Subject: [PATCH 226/350] 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 21c514552891..25ca641aa8a0 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -375,6 +375,12 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) 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 657e27fc8013..eed93f388974 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -974,11 +974,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; } } @@ -989,7 +986,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 c9cc72725976a2acb4d0fe6f232823f97634b209 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Fri, 22 Nov 2019 15:01:11 +0530 Subject: [PATCH 227/350] 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 bb1c518e2b99..a2a3330f4237 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -363,19 +363,20 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { 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}, @@ -386,11 +387,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 0310eb820b056ec75520785fbd2eddc85f2361bb Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Mon, 25 Nov 2019 14:13:42 +0800 Subject: [PATCH 228/350] 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 21eb629179a2..e837293d7390 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7114,7 +7114,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 22f8c0b03b00877cffac13a1e2f5236a15b92656 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Sat, 23 Nov 2019 22:42:14 +0530 Subject: [PATCH 229/350] 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 + msm/vidc/msm_vidc_platform.c | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 657e27fc8013..35a3435a65f0 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -36,7 +36,8 @@ struct msm_vidc_core_ops core_ops_ar50lt = { .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, + .decide_core_and_power_mode = + msm_vidc_decide_core_and_power_mode_ar50lt, .calc_bw = calc_bw_ar50lt, }; @@ -1614,6 +1615,12 @@ static u32 get_core_load(struct msm_vidc_core *core, return load; } +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_iris1(struct msm_vidc_inst *inst) { bool enable = false; 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); diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index bb1c518e2b99..ff546c63a8c9 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -832,7 +832,7 @@ static struct msm_vidc_common_data sm6150_common_data[] = { }, { .key = "qcom,fw-vpp-cycles", - .value = 225975, + .value = 166666, }, }; From 01e403001e3d235088e5bf8e4e3abe221b604ef4 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Tue, 26 Nov 2019 10:57:19 +0800 Subject: [PATCH 230/350] 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 f0e047a11cde..cc464d12c78e 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -2615,7 +2615,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 9a736e9f7f5947cab317a72d0a93d8ffeb7c9157 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Wed, 27 Nov 2019 13:54:10 +0800 Subject: [PATCH 231/350] 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 d6c5d4d84e49..1df95d567103 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -511,12 +511,12 @@ static struct msm_vidc_codec_capability kona_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 d806b42f3e479519ce5e51b9606d667c5ea7f7ee Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 27 Nov 2019 11:56:16 +0530 Subject: [PATCH 232/350] 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 b4813f7c1866..d8b6532603ae 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1013,15 +1013,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 6787b2d9054bf3dd355c7dff80933aab53638761 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 20 Nov 2019 11:51:50 +0530 Subject: [PATCH 233/350] 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 b4813f7c1866..621324819e90 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 @@ -799,7 +799,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 1a570a4a7f1124d4c17e8196ab33879316dfdd96 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Wed, 27 Nov 2019 18:30:39 +0530 Subject: [PATCH 234/350] 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 31a950a4d2e70241615a8c5e53f2fce944088840 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Sun, 1 Dec 2019 15:08:15 +0530 Subject: [PATCH 235/350] 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 d6c5d4d84e49..e901bd91fba0 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -398,6 +398,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 kona_capabilities[] = { From 43ebc742ff19570bdc6ebb245b1de0765d2aeca2 Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Thu, 5 Dec 2019 11:16:46 +0800 Subject: [PATCH 236/350] 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 cc464d12c78e..cdf628944db4 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1271,7 +1271,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 c6ad499d12cf6c7545c00d965c0da41bdb7a2d7d Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 11 Dec 2019 11:02:13 +0530 Subject: [PATCH 237/350] 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 61a84c954c39..f107e29af351 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -2141,34 +2141,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 void __core_clear_interrupt_common(struct venus_hfi_device *device) { u32 intr_status = 0, mask = 0; @@ -3369,8 +3341,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 4451e7de71cf46722c6ccd9ac15f5a99e8cc91bf Mon Sep 17 00:00:00 2001 From: Malathi Gottam Date: Tue, 19 Nov 2019 20:20:59 +0530 Subject: [PATCH 238/350] 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 --- msm/vidc/msm_vidc_platform.c | 155 ++++++++++++++++++++++++++++++++--- 1 file changed, 143 insertions(+), 12 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index e901bd91fba0..50a2540a3400 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -361,14 +361,74 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { V4L2_MPEG_VIDEO_HEVC_LEVEL_5}, }; -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}, @@ -858,7 +918,7 @@ static struct msm_vidc_common_data sm6150_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, @@ -873,11 +933,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", @@ -888,12 +948,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", @@ -1249,8 +1352,8 @@ static struct msm_vidc_platform_data sm6150_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, @@ -1261,8 +1364,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 struct msm_vidc_platform_data sm8150_data = { @@ -1385,6 +1488,20 @@ static int msm_vidc_read_efuse( return 0; } +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; @@ -1440,6 +1557,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: From f50e5dc8008e0ed9c85cb8aee8e84e22afa95218 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 13 Dec 2019 18:58:22 +0530 Subject: [PATCH 239/350] 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 f107e29af351..0e980db72bd1 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -3069,20 +3069,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); } @@ -3233,8 +3232,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 = { @@ -3242,8 +3239,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; @@ -3267,7 +3263,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 0c44b2d6da0942d494f93ffe652d9917b53f33d5 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Fri, 3 Jan 2020 10:03:13 -0800 Subject: [PATCH 240/350] msm: vidc: Disable HDR10 Histogram Extradata Disable HDR10 Histogram extradata by not sending the required property which enables the same. CRs-Fixed: 2595782 Change-Id: I63beab708dcdb165ed155c6c008a1170490adacf Signed-off-by: Vikash Garodia Signed-off-by: Akshata Sahukar Signed-off-by: Qiwei Liu --- msm/vidc/msm_vdec.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 4d9cb82605b0..ccb45dc95547 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 @@ -1378,11 +1378,6 @@ int msm_vdec_set_extradata(struct msm_vidc_inst *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_VDEC_HDR10_HIST_EXTRADATA, 0x1); - } - msm_comm_set_extradata(inst, HFI_PROPERTY_PARAM_VDEC_NUM_CONCEALED_MB, 0x1); if (codec == V4L2_PIX_FMT_HEVC) { From 86ab4a5af4f8d684b05d3731856f7a11bef89ff2 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Tue, 31 Dec 2019 13:06:53 +0530 Subject: [PATCH 241/350] msm: vidc: Disable NOC error recovery Disable NOC error recovery in bengal target. Made changes for bengal specific noc error info. CRs-Fixed: 2596426 Change-Id: Icfebf812c00795703529416682734aa51d9df665 Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/hfi_ar50_lt.c | 62 ++++++++++++++++++++++++++++++++++++ msm/vidc/hfi_common.c | 22 ++++++------- msm/vidc/hfi_common.h | 1 + msm/vidc/msm_vidc_platform.c | 3 ++ 4 files changed, 77 insertions(+), 11 deletions(-) diff --git a/msm/vidc/hfi_ar50_lt.c b/msm/vidc/hfi_ar50_lt.c index f883cdfc8d26..6051112c78cc 100644 --- a/msm/vidc/hfi_ar50_lt.c +++ b/msm/vidc/hfi_ar50_lt.c @@ -121,6 +121,26 @@ #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 +/* + * -------------------------------------------------------------------------- + * MODULE: vcodec noc error log registers + * -------------------------------------------------------------------------- + */ +#define VCODEC_CORE0_VIDEO_NOC_BASE_OFFS 0x00004000 +#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 + void __interrupt_init_ar50_lt(struct venus_hfi_device *device, u32 sid) { __write_register(device, VIDC_WRAPPER_INTR_MASK_AR50_LT, @@ -143,6 +163,48 @@ void __setup_ucregion_memory_map_ar50_lt(struct venus_hfi_device *device, u32 si (u32)device->qdss.align_device_addr, sid); } +void __noc_error_info_ar50_lt(struct venus_hfi_device *device) +{ + u32 val; + u32 vcodec_core_video_noc_base_offs = + VCODEC_CORE0_VIDEO_NOC_BASE_OFFS; + u32 sid = DEFAULT_SID; + + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_SWID_LOW_OFFS, sid); + d_vpr_e("NOC_ERR_SWID_LOW: %#x\n", val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_SWID_HIGH_OFFS, sid); + d_vpr_e("NOC_ERR_SWID_HIGH: %#x\n", val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_MAINCTL_LOW_OFFS, sid); + d_vpr_e("NOC_ERR_MAINCTL_LOW: %#x\n", val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_LOW_OFFS, sid); + d_vpr_e("NOC_ERR_ERRLOG0_LOW: %#x\n", val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_HIGH_OFFS, sid); + d_vpr_e("NOC_ERR_ERRLOG0_HIGH: %#x\n", val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_LOW_OFFS, sid); + d_vpr_e("NOC_ERR_ERRLOG1_LOW: %#x\n", val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_HIGH_OFFS, sid); + d_vpr_e("NOC_ERR_ERRLOG1_HIGH: %#x\n", val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_LOW_OFFS, sid); + d_vpr_e("NOC_ERR_ERRLOG2_LOW: %#x\n", val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_HIGH_OFFS, sid); + d_vpr_e("NOC_ERR_ERRLOG2_HIGH: %#x\n", val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_LOW_OFFS, sid); + d_vpr_e("NOC_ERR_ERRLOG3_LOW: %#x\n", val); + val = __read_register(device, vcodec_core_video_noc_base_offs + + VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_HIGH_OFFS, sid); + d_vpr_e("NOC_ERR_ERRLOG3_HIGH: %#x\n", val); +} + void __power_off_ar50_lt(struct venus_hfi_device *device) { if (!device->power_enabled) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 0e980db72bd1..f4b42ac35c50 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -134,17 +134,17 @@ struct venus_hfi_vpu_ops vpu4_ops = { }; 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, + .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_ar50_lt, + .core_clear_interrupt = __core_clear_interrupt_ar50_lt, + .boot_firmware = __boot_firmware_ar50_lt, }; struct venus_hfi_vpu_ops iris1_ops = { diff --git a/msm/vidc/hfi_common.h b/msm/vidc/hfi_common.h index 2ac3802aab1e..017688858812 100644 --- a/msm/vidc/hfi_common.h +++ b/msm/vidc/hfi_common.h @@ -329,5 +329,6 @@ 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); +void __noc_error_info_ar50_lt(struct venus_hfi_device *device); #endif diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 7c045d2f982e..205b19c17184 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1558,6 +1558,9 @@ void *vidc_get_drv_data(struct device *dev) ddr_type, driver_data->ubwc_config ? driver_data->ubwc_config->highest_bank_bit : -1); } else if (!strcmp(match->compatible, "qcom,bengal-vidc")) { + d_vpr_h("Disable NOC error recovery"); + msm_vidc_err_recovery_disable = + VIDC_DISABLE_NOC_ERR_RECOV; rc = msm_vidc_read_rank(driver_data, dev); if (rc) { d_vpr_e("Failed to get ddr rank, use Dual Rank DDR\n"); From c227beb8411190ef8d3c1fd9c22d2783c5e9f738 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Mon, 23 Dec 2019 11:52:37 +0800 Subject: [PATCH 242/350] msm: vidc: allow larger mbpf limit mbpf limit is mainly to limit memory consumption, no need to couple with mbps workload limit. Modify mbpf limit to larger value for lito to allow more instances with low fps or non-realtime. Change-Id: I0b781748aa27532fb1fa99833d252e727452ae26 Signed-off-by: Qiwei Liu --- 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 7c045d2f982e..c973b018d8f4 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 @@ -653,7 +653,7 @@ static struct msm_vidc_common_data lito_common_data_v0[] = { }, { .key = "qcom,max-mbpf", - .value = 65280,/* (3840x2176)/256 + (3840x2176)/256 */ + .value = 130560,/* ((3840x2176)/256) x 4 */ }, { .key = "qcom,power-collapse-delay", @@ -732,7 +732,7 @@ static struct msm_vidc_common_data lito_common_data_v1[] = { }, { .key = "qcom,max-mbpf", - .value = 40800, /* (3840x2176)/256 + (1920x1088)/256 */ + .value = 130560,/* ((3840x2176)/256) x 4 */ }, { .key = "qcom,power-collapse-delay", From cf6d8c703276e1cfad7baf2f84dc419acdc42e7d Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Thu, 26 Dec 2019 16:30:39 +0530 Subject: [PATCH 243/350] 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 f4b42ac35c50..aee155181330 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -3077,6 +3077,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 e8c1a5fb21851b3173eafc139edd777f9658db5a Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Tue, 7 Jan 2020 16:50:11 +0530 Subject: [PATCH 244/350] msm: vidc: Reject operating rate beyond specification Operating rate denote the rate at which frames are processed by video hardware. This change keeps the rate within the min,max range. There is a special handling for rate as INT_MAX. For such case, video session is configured as TURBO. Hence such case is allowed beyond the min, max range. Change-Id: Ied4be11e8b3c3f040bd8cdac23deb8e786603589 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vdec.c | 2 ++ msm/vidc/msm_venc.c | 4 +++- msm/vidc/msm_vidc_common.h | 18 +++++++++++++++++- msm/vidc/msm_vidc_platform.c | 7 ++++++- msm/vidc/vidc_hfi_api.h | 3 ++- 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index ccb45dc95547..1bb6a6645fb5 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -933,6 +933,8 @@ 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: + if (!is_valid_operating_rate(inst, ctrl->val)) + break; inst->clk_data.operating_rate = ctrl->val; inst->flags &= ~VIDC_TURBO; if (ctrl->val == INT_MAX) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index cdf628944db4..113147f3383d 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 #include "msm_venc.h" @@ -1680,6 +1680,8 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } break; case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: + if (!is_valid_operating_rate(inst, ctrl->val)) + break; inst->clk_data.operating_rate = ctrl->val; /* For HEIC image encode, set operating rate to 1 */ if (is_grid_session(inst)) { diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index df6cfdacfa94..877ba824bea2 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_ @@ -179,6 +179,22 @@ static inline int msm_comm_s_ctrl(struct msm_vidc_inst *inst, return v4l2_s_ctrl(NULL, &inst->ctrl_handler, ctrl); } +static inline bool is_valid_operating_rate(struct msm_vidc_inst *inst, s32 val) +{ + struct hal_capability_supported *cap; + + cap = &inst->capability.cap[CAP_OPERATINGRATE]; + + if (((val >> 16) < cap->min || (val >> 16) > cap->max) && + val != INT_MAX) { + s_vpr_e(inst->sid, + "Unsupported operating rate %d min %d max %d\n", + val >> 16, cap->min, cap->max); + return false; + } + return true; +} + 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); diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 205b19c17184..348bead9e98a 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 @@ -180,6 +180,7 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { /* ((3840x2176)/256)@60fps */ {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 1958400, 1, 1958400}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 480, 1, 30}, + {CAP_OPERATINGRATE, DOMAINS_ALL, CODECS_ALL, 1, 480, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 200000000, 1, 20000000}, {CAP_CABAC_BITRATE, ENC, H264, 1, 200000000, 1, 20000000}, {CAP_SCALE_X, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, @@ -275,6 +276,7 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { /* UHD@30 decode + 1080@30 encode */ {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 36, 1224000, 1, 1224000}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 240, 1, 30}, + {CAP_OPERATINGRATE, 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}, @@ -370,6 +372,7 @@ static struct msm_vidc_codec_capability bengal_capabilities_v0[] = { /* 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_OPERATINGRATE, DOMAINS_ALL, CODECS_ALL, 1, INT_MAX, 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}, @@ -430,6 +433,7 @@ static struct msm_vidc_codec_capability bengal_capabilities_v1[] = { /* 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_OPERATINGRATE, DOMAINS_ALL, CODECS_ALL, 1, INT_MAX, 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}, @@ -490,6 +494,7 @@ static struct msm_vidc_codec_capability kona_capabilities[] = { /* ((1920 * 1088) / 256) * 960 fps */ {CAP_MBS_PER_SECOND, DOMAINS_ALL, CODECS_ALL, 64, 7833600, 1, 7833600}, {CAP_FRAMERATE, DOMAINS_ALL, CODECS_ALL, 1, 960, 1, 30}, + {CAP_OPERATINGRATE, DOMAINS_ALL, CODECS_ALL, 1, INT_MAX, 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}, diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index a51283b062b7..a86e36551955 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__ @@ -244,6 +244,7 @@ enum hal_capability { CAP_MBS_PER_FRAME, CAP_MBS_PER_SECOND, CAP_FRAMERATE, + CAP_OPERATINGRATE, CAP_SCALE_X, CAP_SCALE_Y, CAP_BITRATE, From 7e2f80e26c5a3bbd52bbd9549c96fcd54055afbb Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Thu, 9 Jan 2020 13:43:36 +0530 Subject: [PATCH 245/350] msm: vidc: Update max frame rate for vp8 encoder update max frame-rate for vp8 encoder for lito target. CRs-Fixed: 2599066 Change-Id: I279ada52b598545517178c817c088ebca94872b4 Signed-off-by: Manikanta Kanamarlapudi Signed-off-by: Vikash Garodia --- 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 348bead9e98a..73cd6732370c 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -211,7 +211,7 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 36, 34816, 1, 8160}, /* (3840 * 2176) / 256) * 30*/ {CAP_MBS_PER_SECOND, ENC|DEC, VP8, 36, 979200, 1, 244800}, - {CAP_FRAMERATE, ENC|DEC, VP8, 1, 30, 1, 30}, + {CAP_FRAMERATE, ENC|DEC, VP8, 1, 240, 1, 30}, {CAP_BITRATE, ENC, VP8, 1, 100000000, 1, 20000000}, {CAP_BITRATE, DEC, VP8, 1, 100000000, 1, 20000000}, @@ -307,7 +307,7 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {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_FRAMERATE, ENC|DEC, VP8, 1, 120, 1, 30}, {CAP_BITRATE, ENC, VP8, 1, 40000000, 1, 20000000}, {CAP_BITRATE, DEC, VP8, 1, 100000000, 1, 20000000}, From 10ba1ac5f3b54774f4acefc549010a24416f59c2 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Tue, 14 Jan 2020 16:17:55 -0800 Subject: [PATCH 246/350] 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 Signed-off-by: Govindaraj Rajagopal --- 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 e837293d7390..a0aea16b3d3c 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 @@ -5574,8 +5574,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 49347560192a7bf188eed612e77ca83d128195e1 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 22 Jan 2020 18:01:48 +0530 Subject: [PATCH 247/350] msm: vidc: add all intra cap for bengal All intra capabilities for bengal is missing. As a result, usecases which looks to set all intra by setting zero GOP and zero B-frame count is failing. Change-Id: Idf75e6babfe1e2878ce6b0a7e1bb7f5c59bc18ea Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_platform.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index e155d8f96727..5530318a5847 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -396,6 +396,9 @@ static struct msm_vidc_codec_capability bengal_capabilities_v0[] = { {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}, @@ -457,6 +460,9 @@ static struct msm_vidc_codec_capability bengal_capabilities_v1[] = { {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}, From 3572dc49c7a6423f64d707b2d8f60423c34a2247 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 18 Dec 2019 11:06:24 +0530 Subject: [PATCH 248/350] msm: vidc: print cvp buffer details during sys_error Currently print_inst_info is not printing cvp buffer details. So added cvp buffer details as well as part of print_inst_info. Change-Id: Ie3b7e8d4f32a58c6ff8070a6cc2c1934ecbc4d1e Signed-off-by: Govindaraj Rajagopal --- 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 e837293d7390..56ba2c677b73 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5995,6 +5995,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 msm_vidc_cvp_buffer *cbuf; struct internal_buf *buf; bool is_decode = false; enum vidc_ports port; @@ -6049,6 +6050,15 @@ void msm_comm_print_inst_info(struct msm_vidc_inst *inst) buf->buffer_type, buf->smem.device_addr, buf->smem.size); mutex_unlock(&inst->outputbufs.lock); + + mutex_lock(&inst->cvpbufs.lock); + s_vpr_e(inst->sid, "cvp buffer list:\n"); + list_for_each_entry(cbuf, &inst->cvpbufs.list, list) + s_vpr_e(inst->sid, + "index: %u fd: %u offset: %u size: %u addr: %x\n", + cbuf->buf.index, cbuf->buf.fd, cbuf->buf.offset, + cbuf->buf.size, cbuf->smem.device_addr); + mutex_unlock(&inst->cvpbufs.lock); } int msm_comm_session_continue(void *instance) From 510cd3f02c8d766576d88aa61ccbeb09e314d32b Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Tue, 28 Jan 2020 09:14:13 +0530 Subject: [PATCH 249/350] msm: vidc: add mbpf support for bengal MBs per frame, i.e mbpf, is used to decide the number of concurrent video sessions that can be allowed. Change-Id: I5f7abf764831753f7c54cac9a4ff132a074db454 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_platform.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index e155d8f96727..7a781d9dce5d 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -944,6 +944,10 @@ static struct msm_vidc_common_data bengal_common_data_v0[] = { .key = "qcom,max-hw-load", .value = 489600, }, + { + .key = "qcom,max-mbpf", + .value = 65280,/* ((3840x2176)/256) x 2 */ + }, { .key = "qcom,max-hq-mbs-per-frame", .value = 8160, @@ -995,6 +999,10 @@ static struct msm_vidc_common_data bengal_common_data_v1[] = { .key = "qcom,max-hw-load", .value = 244800, }, + { + .key = "qcom,max-mbpf", + .value = 65280,/* ((3840x2176)/256) x 2 */ + }, { .key = "qcom,max-hq-mbs-per-frame", .value = 8160, From 7de9c20ea8fb7114b149f45328f4f1d1c1f6cbab Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 20 Jan 2020 14:42:22 +0530 Subject: [PATCH 250/350] 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 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index aee155181330..ab9f1c1849a4 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 @@ -80,7 +80,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); From fa6d7f6712daa496898281cd0e8ef76c2cd6f5e4 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 29 Jan 2020 15:17:05 +0530 Subject: [PATCH 251/350] Revert "msm: vidc: Disable HDR10 Histogram Extradata" This reverts commit 0c44b2d6da0942d494f93ffe652d9917b53f33d5. Histogram feature is being enabled now after fixing the issue in video firmware. Change-Id: I6201b47675648dd9d626a46387ae80e49b559d02 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vdec.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 1bb6a6645fb5..579898598a6f 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -1380,6 +1380,11 @@ int msm_vdec_set_extradata(struct msm_vidc_inst *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_VDEC_HDR10_HIST_EXTRADATA, 0x1); + } + msm_comm_set_extradata(inst, HFI_PROPERTY_PARAM_VDEC_NUM_CONCEALED_MB, 0x1); if (codec == V4L2_PIX_FMT_HEVC) { From 4b9b7337ac3b38a361dd2880a2326a55a05e2e3e Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Wed, 29 Jan 2020 12:04:37 -0800 Subject: [PATCH 252/350] 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 a0aea16b3d3c..9ed5201da965 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -4373,6 +4373,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); @@ -4394,10 +4395,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 3760f661930e95c1bede8fa1e7bcdf6f39e31e41 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Mon, 27 Jan 2020 15:20:46 -0800 Subject: [PATCH 253/350] 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 4819bbd46c03..502857567213 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 @@ -207,6 +207,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); +} + static long msm_v4l2_default(struct file *file, void *fh, bool valid_prio, unsigned int cmd, void *arg) { @@ -232,6 +240,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 25ca641aa8a0..2b9c4f5bdc0b 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 @@ -143,22 +143,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 44ea7c257ce1..93bada2a2365 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_ @@ -119,6 +119,7 @@ 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_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 e062be425dc6449ccd3d20adc837fb557b8fb17c Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Tue, 21 Jan 2020 19:43:39 +0530 Subject: [PATCH 254/350] msm: vidc: enable bitrate savings for 8-bit & 10-bit Currently bitrate savings enable is a boolean value. So changing that to integer. 0 -> disable bitrate savings 1 -> only for 8-bit 2 -> only for 10-bit 3 -> both 8-bit & 10-bit. Change-Id: I495eff0cc6144530e8ac8641ce3eca12a97547cc Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_venc.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 113147f3383d..b169a88043eb 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -938,10 +938,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 = 0, + .maximum = 3, + .default_value = 3, .step = 1, }, { @@ -3315,8 +3315,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; + struct v4l2_ctrl *profile; struct hfi_enable enable; + u32 codec; if (!inst || !inst->core) { d_vpr_e("%s: invalid params %pK\n", __func__, inst); @@ -3324,12 +3326,30 @@ 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) { + 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); + + /** + * Enable CAC control: + * 0x0 -> disabled, + * 0x1 -> enabled for 8 bit + * 0x2 -> enabled for 10 bit + * 0x3 -> enabled for 8 and 10 bits both + */ + enable.enable = !!cac->val; + if (cac->val == 0x1 && codec == V4L2_PIX_FMT_HEVC && + profile->val == V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10) + enable.enable = 0; + else if (cac->val == 0x2 && !(codec == V4L2_PIX_FMT_HEVC && + profile->val == V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10)) + enable.enable = 0; + + if (!cac->val && 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; + update_ctrl(cac, 3, inst->sid); } s_vpr_h(inst->sid, "%s: %d\n", __func__, enable.enable); From 3fcfd623a2ec9be2e85661ad1b8cbbe1f5507d6f Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 6 Jan 2020 19:43:41 +0530 Subject: [PATCH 255/350] msm: vidc: Add lagoon platform config data Add configurations specific to lagoon platform ex: codec config, SKU etc. Change-Id: I8cb2ec50b445416f84268dee899cfd38d4d4a179 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_platform.c | 397 +++++++++++++++++++++++++++++++++++ 1 file changed, 397 insertions(+) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index e155d8f96727..5cb630d9209b 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -89,6 +89,15 @@ static struct msm_vidc_codec_data kona_codec_data[] = { CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 60, 200, 200), }; +static struct msm_vidc_codec_data lagoon_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), +}; + /* 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), @@ -171,6 +180,12 @@ static struct msm_vidc_codec default_codecs[] = { {ENC, H264}, {ENC, HEVC}, {ENC, VP8}, }; +static struct msm_vidc_codec lagoon_codecs[] = { + /* {domain, codec} */ + {DEC, H264}, {DEC, HEVC}, {DEC, VP9}, {DEC, MPEG2}, + {ENC, H264}, {ENC, HEVC}, +}; + 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}, @@ -363,6 +378,193 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { V4L2_MPEG_VIDEO_HEVC_LEVEL_5}, }; +static struct msm_vidc_codec_capability lagoon_capabilities_v0[] = { + /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ + {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 3840, 1, 1920}, + {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 3840, 1, 1080}, + /* (3840 * 2176) / 256 */ + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 32640, 1, 8160}, + /* ((3840 * 2176) / 256) * 30 fps */ + {CAP_MBS_PER_SECOND, ENC, CODECS_ALL, 64, 979200, 1, 244800}, + /* ((3840 * 2176) / 256) * 60 fps */ + {CAP_MBS_PER_SECOND, DEC, CODECS_ALL, 64, 1958400, 1, 244800}, + {CAP_FRAMERATE, ENC, CODECS_ALL, 1, 240, 1, 30}, + {CAP_FRAMERATE, DEC, CODECS_ALL, 1, 480, 1, 30}, + {CAP_OPERATINGRATE, DOMAINS_ALL, CODECS_ALL, 1, INT_MAX, 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, 128, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, MPEG2, 128, 1920, 1, 1088}, + /* (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, 3840, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 3840, 1, 1080}, + /* (3840 * 2176) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 32640, 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, 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_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 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}, + {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 lagoon_capabilities_v1[] = { + /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ + {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 3840, 1, 1920}, + {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 3840, 1, 1080}, + /* (3840 * 2176) / 256 */ + {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 32640, 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_OPERATINGRATE, DOMAINS_ALL, CODECS_ALL, 1, INT_MAX, 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, 128, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, MPEG2, 128, 1920, 1, 1088}, + /* (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, 3840, 1, 1920}, + {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 3840, 1, 1080}, + /* (3840 * 2176) / 256 */ + {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 32640, 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, 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_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 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}, + {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_v0[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value} */ {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 1920, 1, 1920}, @@ -777,6 +979,165 @@ static struct msm_vidc_common_data lito_common_data_v1[] = { }, }; +static struct msm_vidc_common_data lagoon_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 = 1958400, /* ((3840x2176)/256)@60fps decode */ + /* UHD@30 decode + 1080@30 encode */ + }, + { + .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 = 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 = 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 = 436000, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 166667, + }, + { + .key = "qcom,avsync-window-size", + .value = 40, + }, +}; + +static struct msm_vidc_common_data lagoon_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 = 1224000, /* UHD@30 decode + 1080@30 encode */ + }, + { + .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 = 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 = 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 = 436000, + }, + { + .key = "qcom,fw-vpp-cycles", + .value = 166667, + }, + { + .key = "qcom,avsync-window-size", + .value = 40, + }, +}; + static struct msm_vidc_common_data kona_common_data[] = { { .key = "qcom,never-unload-fw", @@ -1277,6 +1638,10 @@ static struct msm_vidc_efuse_data lito_efuse_data[] = { EFUSE_ENTRY(0x00786008, 4, 0x00200000, 0x15, SKU_VERSION), }; +static struct msm_vidc_efuse_data lagoon_efuse_data[] = { + EFUSE_ENTRY(0x007801E8, 4, 0x00004000, 0x0E, SKU_VERSION), +}; + static struct msm_vidc_efuse_data sdm670_efuse_data[] = { EFUSE_ENTRY(0x007801A0, 4, 0x00008000, 0x0f, SKU_VERSION), }; @@ -1339,6 +1704,25 @@ static struct msm_vidc_platform_data kona_data = { .codec_caps_count = ARRAY_SIZE(kona_capabilities), }; +static struct msm_vidc_platform_data lagoon_data = { + .codec_data = lagoon_codec_data, + .codec_data_length = ARRAY_SIZE(lagoon_codec_data), + .common_data = lagoon_common_data_v0, + .common_data_length = ARRAY_SIZE(lagoon_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 = lagoon_efuse_data, + .efuse_data_length = ARRAY_SIZE(lagoon_efuse_data), + .sku_version = 0, + .vpu_ver = VPU_VERSION_IRIS2, + .ubwc_config = 0x0, + .codecs = lagoon_codecs, + .codecs_count = ARRAY_SIZE(lagoon_codecs), + .codec_caps = lagoon_capabilities_v0, + .codec_caps_count = ARRAY_SIZE(lagoon_capabilities_v0), +}; + static struct msm_vidc_platform_data sm6150_data = { .codec_data = sm6150_codec_data, .codec_data_length = ARRAY_SIZE(sm6150_codec_data), @@ -1447,6 +1831,10 @@ static const struct of_device_id msm_vidc_dt_match[] = { .compatible = "qcom,bengal-vidc", .data = &bengal_data, }, + { + .compatible = "qcom,lagoon-vidc", + .data = &lagoon_data, + }, {}, }; @@ -1579,6 +1967,15 @@ void *vidc_get_drv_data(struct device *dev) driver_data->codec_caps_count = ARRAY_SIZE(bengal_capabilities_v1); } + } else if (!strcmp(match->compatible, "qcom,lagoon-vidc")) { + if (driver_data->sku_version == SKU_VERSION_1) { + driver_data->common_data = lagoon_common_data_v1; + driver_data->common_data_length = + ARRAY_SIZE(lagoon_common_data_v1); + driver_data->codec_caps = lagoon_capabilities_v1; + driver_data->codec_caps_count = + ARRAY_SIZE(lagoon_capabilities_v1); + } } exit: From 892f00907df3c077402e988f8a533982ceeca85a Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Fri, 31 Jan 2020 14:56:40 +0530 Subject: [PATCH 256/350] 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 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 32026f376ad8..dbd21359e1ad 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_ @@ -35,8 +35,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 f30d360a298d5fd0951cac6f93c8d32647d2db7e Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 3 Feb 2020 16:13:39 +0530 Subject: [PATCH 257/350] 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, 19 insertions(+), 15 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index a0aea16b3d3c..0230a3829be8 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1400,6 +1400,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) { @@ -1408,29 +1409,32 @@ static int msm_vidc_comm_update_ctrl(struct msm_vidc_inst *inst, return -EINVAL; } + if (ctrl->type == V4L2_CTRL_TYPE_MENU) + 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 9ebaa6faf370c9f4bfc44d159249a66421371997 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 3 Feb 2020 12:13:55 +0530 Subject: [PATCH 258/350] msm: vidc: Add vpu version for lagoon 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 | 5 +++-- msm/vidc/msm_vidc_buffer_calculations.c | 6 ++++-- msm/vidc/msm_vidc_clocks.c | 9 ++++++++- msm/vidc/msm_vidc_internal.h | 3 ++- msm/vidc/msm_vidc_platform.c | 2 +- 6 files changed, 22 insertions(+), 10 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 113147f3383d..ec4468f076ee 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1132,11 +1132,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 = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; f->fmt.pix_mp.height = DEFAULT_HEIGHT; @@ -1162,9 +1164,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 25ca641aa8a0..b65872843122 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 @@ -1359,7 +1359,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 7299bd061638..d80afd6416db 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" @@ -603,15 +603,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 60a4a2ee8cef..471cb0e0a903 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" @@ -1244,6 +1244,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", @@ -1251,10 +1252,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 || @@ -1278,6 +1284,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 32026f376ad8..7963e905914b 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_ @@ -269,6 +269,7 @@ enum vpu_version { VPU_VERSION_AR50 = 1, VPU_VERSION_IRIS1, VPU_VERSION_IRIS2, + VPU_VERSION_IRIS2_1, VPU_VERSION_AR50_LITE, }; diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 42e7c9e25875..2edcf87d1c89 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1729,7 +1729,7 @@ static struct msm_vidc_platform_data lagoon_data = { .efuse_data = lagoon_efuse_data, .efuse_data_length = ARRAY_SIZE(lagoon_efuse_data), .sku_version = 0, - .vpu_ver = VPU_VERSION_IRIS2, + .vpu_ver = VPU_VERSION_IRIS2_1, .ubwc_config = 0x0, .codecs = lagoon_codecs, .codecs_count = ARRAY_SIZE(lagoon_codecs), From b26f8442cbd7631497c7dfdc44d6a41afa6fa740 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Tue, 4 Feb 2020 20:04:29 +0530 Subject: [PATCH 259/350] msm: vidc: Update lagoon CAP frame WxH Maximum supported resolution is 4096 x 2176. Change-Id: Ic7c8568792cb06f26be7804f312073ffe351c941 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_platform.c | 48 ++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 42e7c9e25875..1f50c8f11eab 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -380,10 +380,10 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { static struct msm_vidc_codec_capability lagoon_capabilities_v0[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ - {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 3840, 1, 1920}, - {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 3840, 1, 1080}, - /* (3840 * 2176) / 256 */ - {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 32640, 1, 8160}, + {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, ENC, CODECS_ALL, 64, 979200, 1, 244800}, /* ((3840 * 2176) / 256) * 60 fps */ @@ -425,10 +425,10 @@ static struct msm_vidc_codec_capability lagoon_capabilities_v0[] = { {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, /* Secure usecase specific */ - {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 3840, 1, 1920}, - {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 3840, 1, 1080}, - /* (3840 * 2176) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 32640, 1, 8160}, + {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 */ @@ -437,10 +437,10 @@ static struct msm_vidc_codec_capability lagoon_capabilities_v0[] = { {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}, + {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}, @@ -475,10 +475,10 @@ static struct msm_vidc_codec_capability lagoon_capabilities_v0[] = { static struct msm_vidc_codec_capability lagoon_capabilities_v1[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ - {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 3840, 1, 1920}, - {CAP_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 3840, 1, 1080}, - /* (3840 * 2176) / 256 */ - {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 32640, 1, 8160}, + {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}, @@ -517,10 +517,10 @@ static struct msm_vidc_codec_capability lagoon_capabilities_v1[] = { {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, /* Secure usecase specific */ - {CAP_SECURE_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 3840, 1, 1920}, - {CAP_SECURE_FRAME_HEIGHT, DOMAINS_ALL, CODECS_ALL, 128, 3840, 1, 1080}, - /* (3840 * 2176) / 256 */ - {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 64, 32640, 1, 8160}, + {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 */ @@ -529,10 +529,10 @@ static struct msm_vidc_codec_capability lagoon_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}, - /* (3840 * 2176)/ 256 */ - {CAP_LOSSLESS_MBS_PER_FRAME, ENC, H264|HEVC, 64, 32640, 1, 8160}, + {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}, From ddfd00c2aaf69518b8b843a3db359e7435fe797c Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 24 Jan 2020 20:06:15 +0530 Subject: [PATCH 260/350] 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 60a4a2ee8cef..90b435f7f93d 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" @@ -1698,9 +1698,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); @@ -1714,7 +1714,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 f3c5f9748661dc79e28ce8528b4953a7d583bf16 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Tue, 4 Feb 2020 13:12:12 +0530 Subject: [PATCH 261/350] msm: vidc: access CVP NOC register only for supported HW Currently, video driver is accessing CVP NOC register for all video HW which might cause invalid memory access. Fix this by accessing CVP NOC register only for HW which supports CVP. Change-Id: I5588b452455b592b8156ea4f46cb8e3171e14947 Signed-off-by: Dikshita Agarwal --- msm/vidc/hfi_ar50_lt.c | 64 +-------------------------------- msm/vidc/hfi_common.c | 76 +++++++++++++++++++++------------------- msm/vidc/hfi_common.h | 3 +- msm/vidc/hfi_io_common.h | 4 +-- 4 files changed, 43 insertions(+), 104 deletions(-) diff --git a/msm/vidc/hfi_ar50_lt.c b/msm/vidc/hfi_ar50_lt.c index 6051112c78cc..27199d24f5ab 100644 --- a/msm/vidc/hfi_ar50_lt.c +++ b/msm/vidc/hfi_ar50_lt.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" @@ -121,26 +121,6 @@ #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 -/* - * -------------------------------------------------------------------------- - * MODULE: vcodec noc error log registers - * -------------------------------------------------------------------------- - */ -#define VCODEC_CORE0_VIDEO_NOC_BASE_OFFS 0x00004000 -#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 - void __interrupt_init_ar50_lt(struct venus_hfi_device *device, u32 sid) { __write_register(device, VIDC_WRAPPER_INTR_MASK_AR50_LT, @@ -163,48 +143,6 @@ void __setup_ucregion_memory_map_ar50_lt(struct venus_hfi_device *device, u32 si (u32)device->qdss.align_device_addr, sid); } -void __noc_error_info_ar50_lt(struct venus_hfi_device *device) -{ - u32 val; - u32 vcodec_core_video_noc_base_offs = - VCODEC_CORE0_VIDEO_NOC_BASE_OFFS; - u32 sid = DEFAULT_SID; - - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_SWID_LOW_OFFS, sid); - d_vpr_e("NOC_ERR_SWID_LOW: %#x\n", val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_SWID_HIGH_OFFS, sid); - d_vpr_e("NOC_ERR_SWID_HIGH: %#x\n", val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_MAINCTL_LOW_OFFS, sid); - d_vpr_e("NOC_ERR_MAINCTL_LOW: %#x\n", val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_LOW_OFFS, sid); - d_vpr_e("NOC_ERR_ERRLOG0_LOW: %#x\n", val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_HIGH_OFFS, sid); - d_vpr_e("NOC_ERR_ERRLOG0_HIGH: %#x\n", val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_LOW_OFFS, sid); - d_vpr_e("NOC_ERR_ERRLOG1_LOW: %#x\n", val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_HIGH_OFFS, sid); - d_vpr_e("NOC_ERR_ERRLOG1_HIGH: %#x\n", val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_LOW_OFFS, sid); - d_vpr_e("NOC_ERR_ERRLOG2_LOW: %#x\n", val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_HIGH_OFFS, sid); - d_vpr_e("NOC_ERR_ERRLOG2_HIGH: %#x\n", val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_LOW_OFFS, sid); - d_vpr_e("NOC_ERR_ERRLOG3_LOW: %#x\n", val); - val = __read_register(device, vcodec_core_video_noc_base_offs + - VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_HIGH_OFFS, sid); - d_vpr_e("NOC_ERR_ERRLOG3_HIGH: %#x\n", val); -} - void __power_off_ar50_lt(struct venus_hfi_device *device) { if (!device->power_enabled) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index ab9f1c1849a4..e5529fa12200 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -142,7 +142,7 @@ struct venus_hfi_vpu_ops ar50_lite_ops = { .prepare_pc = __prepare_pc_ar50_lt, .raise_interrupt = __raise_interrupt_ar50_lt, .watchdog = __watchdog_common, - .noc_error_info = __noc_error_info_ar50_lt, + .noc_error_info = __noc_error_info_common, .core_clear_interrupt = __core_clear_interrupt_ar50_lt, .boot_firmware = __boot_firmware_ar50_lt, }; @@ -4645,74 +4645,76 @@ 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(struct venus_hfi_device *device, u32 core_type) { - u32 vcodec_core_video_noc_base_offs, val; + u32 noc_base_offs, val; u32 sid = DEFAULT_SID; if (!device) { d_vpr_e("%s: null device\n", __func__); return; } - if (!core_num) { - vcodec_core_video_noc_base_offs = + if (!core_type) { + 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 if (core_type == 1) { + noc_base_offs = + CVP_NOC_BASE_OFFS; } else { - d_vpr_e("%s: invalid core_num %u\n", __func__, core_num); + d_vpr_e("%s: invalid core_type %u\n", __func__, core_type); return; } - val = __read_register(device, vcodec_core_video_noc_base_offs + + val = __read_register(device, 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 + + d_vpr_e("CORE%d_NOC_ERR_SWID_LOW: %#x\n", core_type, val); + val = __read_register(device, 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 + + d_vpr_e("CORE%d_NOC_ERR_SWID_HIGH: %#x\n", core_type, val); + val = __read_register(device, 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 + + d_vpr_e("CORE%d_NOC_ERR_MAINCTL_LOW: %#x\n", core_type, val); + val = __read_register(device, 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 + + d_vpr_e("CORE%d_NOC_ERR_ERRLOG0_LOW: %#x\n", core_type, val); + val = __read_register(device, 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 + + d_vpr_e("CORE%d_NOC_ERR_ERRLOG0_HIGH: %#x\n", core_type, val); + val = __read_register(device, 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 + + d_vpr_e("CORE%d_NOC_ERR_ERRLOG1_LOW: %#x\n", core_type, val); + val = __read_register(device, 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 + + d_vpr_e("CORE%d_NOC_ERR_ERRLOG1_HIGH: %#x\n", core_type, val); + val = __read_register(device, 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 + + d_vpr_e("CORE%d_NOC_ERR_ERRLOG2_LOW: %#x\n", core_type, val); + val = __read_register(device, 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 + + d_vpr_e("CORE%d_NOC_ERR_ERRLOG2_HIGH: %#x\n", core_type, val); + val = __read_register(device, 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 + + d_vpr_e("CORE%d_NOC_ERR_ERRLOG3_LOW: %#x\n", core_type, val); + val = __read_register(device, 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); + d_vpr_e("CORE%d_NOC_ERR_ERRLOG3_HIGH: %#x\n", core_type, val); } static void __noc_error_info_common(struct venus_hfi_device *device) { - const u32 core0 = 0, core1 = 1; + const u32 vcodec = 0, cvp = 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); + __noc_error_info(device, vcodec); - 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); + if (device->res->vpu_ver == VPU_VERSION_IRIS1) { + if (__read_register(device, CVP_NOC_BASE_OFFS + + VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS, + DEFAULT_SID)) + __noc_error_info(device, cvp); + } } static int venus_hfi_noc_error_info(void *dev) diff --git a/msm/vidc/hfi_common.h b/msm/vidc/hfi_common.h index 017688858812..9d288c1a19f2 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__ @@ -329,6 +329,5 @@ 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); -void __noc_error_info_ar50_lt(struct venus_hfi_device *device); #endif diff --git a/msm/vidc/hfi_io_common.h b/msm/vidc/hfi_io_common.h index 2d42fdaa381e..1adc50d38e9d 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,7 +122,7 @@ * -------------------------------------------------------------------------- */ #define VCODEC_CORE0_VIDEO_NOC_BASE_OFFS 0x00004000 -#define VCODEC_CORE1_VIDEO_NOC_BASE_OFFS 0x0000C000 +#define CVP_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 From 37f9bbab112387935513bb5affef3aec86079ff3 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 30 Dec 2019 13:19:11 +0530 Subject: [PATCH 262/350] 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 579898598a6f..1d5ca592d537 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -675,15 +675,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: @@ -884,6 +876,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, @@ -905,16 +898,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) @@ -942,6 +925,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 2b9c4f5bdc0b..e0ec81b7fb22 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -881,15 +881,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 7299bd061638..9c17c8b32237 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" @@ -774,13 +774,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); @@ -871,7 +865,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 711c0e43ba22..7f8204f0e61d 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1798,9 +1798,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, @@ -2834,7 +2833,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 c89178921069dd498ea1216381f21158c63d4419 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 7 Feb 2020 22:30:50 +0530 Subject: [PATCH 263/350] 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 4eff2ba29378..eba6739a1b00 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 @@ -129,6 +129,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"); @@ -142,7 +145,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 c63a85c1571814ca011f7d5888b0556677e174f4 Mon Sep 17 00:00:00 2001 From: Jean Xiao Date: Wed, 12 Feb 2020 11:41:42 +0800 Subject: [PATCH 264/350] 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 | 45 ++-------------------------- msm/vidc/msm_vidc_debug.h | 62 ++++++++++++++++++++++++++++++++------- 2 files changed, 53 insertions(+), 54 deletions(-) diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index ce5b520219ff..59ac83e08159 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 @@ -31,7 +31,7 @@ int msm_vidc_err_recovery_disable = !1; 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; @@ -621,17 +621,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; @@ -701,33 +690,3 @@ 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 - * 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 c002662224a0..7ddc7be76378 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__ @@ -69,6 +69,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; @@ -78,13 +85,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; - -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 { \ @@ -176,9 +177,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) { @@ -201,6 +199,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 c543f70aca8d40c593b8ad342d42e913a422c552 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Fri, 14 Feb 2020 13:38:31 +0530 Subject: [PATCH 265/350] msm: vidc: Skip AON register programming for lagoon 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 e6eb40cd8f17..daceae452020 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 7061a11894ab063152b659632b51c902e8550135 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 17 Feb 2020 12:02:06 +0530 Subject: [PATCH 266/350] 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 --- msm/vidc/msm_vidc_buffer_calculations.c | 186 +++++++++++++----------- msm/vidc/msm_vidc_buffer_calculations.h | 10 +- msm/vidc/msm_vidc_internal.h | 1 + msm/vidc/msm_vidc_platform.c | 9 ++ 4 files changed, 115 insertions(+), 91 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index ce5ba87d6f46..c33278a5cc09 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -77,7 +77,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 @@ -141,10 +140,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 @@ -198,10 +196,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 @@ -294,31 +291,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); @@ -385,14 +387,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: @@ -442,7 +445,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) { @@ -502,17 +506,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: @@ -553,14 +558,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) { @@ -1082,7 +1088,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; @@ -1104,7 +1110,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) + @@ -1164,7 +1170,8 @@ static inline u32 size_h264d_vpp_cmd_buf(u32 height) SIZE_H264D_VPP_CMD_PER_BUF; } -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; @@ -1179,11 +1186,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), @@ -1206,10 +1213,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; @@ -1223,12 +1228,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; } @@ -1275,7 +1278,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; @@ -1295,9 +1299,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), @@ -1305,7 +1309,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); @@ -1323,10 +1327,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; @@ -1341,13 +1343,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; } @@ -1389,7 +1388,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; @@ -1409,7 +1408,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); @@ -1418,7 +1420,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; @@ -1426,50 +1428,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; @@ -1483,16 +1491,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), @@ -1506,22 +1515,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), @@ -1535,22 +1545,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), @@ -1564,7 +1575,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; @@ -1720,22 +1731,23 @@ 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); } 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 5df4f291b758..c94402db084d 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -304,6 +304,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 ee7fbffc4592..0fc8c2744efc 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1677,6 +1677,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, }; @@ -1692,6 +1693,7 @@ static struct msm_vidc_platform_data lito_data = { .efuse_data_length = ARRAY_SIZE(lito_efuse_data), .sku_version = 0, .vpu_ver = VPU_VERSION_IRIS1, + .num_vpp_pipes = 0x2, .ubwc_config = 0x0, .codecs = default_codecs, .codecs_count = ARRAY_SIZE(default_codecs), @@ -1711,6 +1713,7 @@ static struct msm_vidc_platform_data kona_data = { .efuse_data_length = 0, .sku_version = 0, .vpu_ver = VPU_VERSION_IRIS2, + .num_vpp_pipes = 0x4, .ubwc_config = kona_ubwc_data, .codecs = default_codecs, .codecs_count = ARRAY_SIZE(default_codecs), @@ -1730,6 +1733,7 @@ static struct msm_vidc_platform_data lagoon_data = { .efuse_data_length = ARRAY_SIZE(lagoon_efuse_data), .sku_version = 0, .vpu_ver = VPU_VERSION_IRIS2_1, + .num_vpp_pipes = 0x1, .ubwc_config = 0x0, .codecs = lagoon_codecs, .codecs_count = ARRAY_SIZE(lagoon_codecs), @@ -1749,6 +1753,7 @@ static struct msm_vidc_platform_data sm6150_data = { .efuse_data_length = 0, .sku_version = 0, .vpu_ver = VPU_VERSION_AR50, + .num_vpp_pipes = 0x1, .ubwc_config = 0x0, }; @@ -1764,6 +1769,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), @@ -1783,6 +1789,7 @@ static struct msm_vidc_platform_data sm8150_data = { .efuse_data_length = 0, .sku_version = 0, .vpu_ver = VPU_VERSION_IRIS1, + .num_vpp_pipes = 0x2, .ubwc_config = 0x0, }; @@ -1798,6 +1805,7 @@ static struct msm_vidc_platform_data sdm845_data = { .efuse_data_length = 0, .sku_version = 0, .vpu_ver = VPU_VERSION_AR50, + .num_vpp_pipes = 0x1, .ubwc_config = 0x0, }; @@ -1813,6 +1821,7 @@ static struct msm_vidc_platform_data sdm670_data = { .efuse_data_length = ARRAY_SIZE(sdm670_efuse_data), .sku_version = 0, .vpu_ver = VPU_VERSION_AR50, + .num_vpp_pipes = 0x1, .ubwc_config = 0x0, }; From 66bc050205e5a4ffd7e07813d6bef3203651919d Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 17 Feb 2020 18:22:08 +0530 Subject: [PATCH 267/350] msm: vidc: Add support for 5.7k playback on lagoon 5.7k is POR and hence update the supported width, height and MBS/frame for decoder caps on lagoon. Change-Id: I9389bd7d715b049f61b51669d146c469d2a0f516 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_platform.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index ee7fbffc4592..4311dc0204bd 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -380,16 +380,24 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { static struct msm_vidc_codec_capability lagoon_capabilities_v0[] = { /* {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}, + /* Encode spec */ + {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, ENC, CODECS_ALL, 64, 34816, 1, 8160}, /* ((3840 * 2176) / 256) * 30 fps */ {CAP_MBS_PER_SECOND, ENC, CODECS_ALL, 64, 979200, 1, 244800}, + {CAP_FRAMERATE, ENC, CODECS_ALL, 1, 240, 1, 30}, + + /* Decode spec */ + {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 128, 5760, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 128, 5760, 1, 1080}, + /* (5760 * 2880) / 256 */ + {CAP_MBS_PER_FRAME, DEC, CODECS_ALL, 64, 64800, 1, 8160}, /* ((3840 * 2176) / 256) * 60 fps */ {CAP_MBS_PER_SECOND, DEC, CODECS_ALL, 64, 1958400, 1, 244800}, - {CAP_FRAMERATE, ENC, CODECS_ALL, 1, 240, 1, 30}, {CAP_FRAMERATE, DEC, CODECS_ALL, 1, 480, 1, 30}, + {CAP_OPERATINGRATE, DOMAINS_ALL, CODECS_ALL, 1, INT_MAX, 1, 30}, {CAP_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 100000000, 1, 20000000}, {CAP_CABAC_BITRATE, ENC, H264, 1, 100000000, 1, 20000000}, From 75fa539dea521e64b96634dc2584ae1452ef8757 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 19 Feb 2020 18:25:30 +0530 Subject: [PATCH 268/350] 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 --- msm/vidc/msm_vdec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 1d5ca592d537..a4511151768f 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -918,10 +918,11 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: if (!is_valid_operating_rate(inst, ctrl->val)) break; - 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; From 0df5ab1de479899565ba856595d7642de3b662d1 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 29 Jan 2020 21:25:28 +0530 Subject: [PATCH 269/350] msm: vidc: adjust max hw_load to support additional 1 fps usecases add target supported max resolution mbs with hw_load to support additional 1 fps usecases(heic/thumbnail). Change-Id: I7d8f394aaa19ccfe6dc3291f0019ccdf5dbb72d3 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_platform.c | 40 ++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 4311dc0204bd..fb22a8ed3339 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -853,8 +853,11 @@ static struct msm_vidc_common_data lito_common_data_v0[] = { }, { .key = "qcom,max-hw-load", - .value = 1958400,/* ((3840x2176)/256)@60fps */ - /* UHD@30 decode + UHD@30 encode */ + .value = 2220544, + /** + * ((3840x2176)/256)@60 + ((8192x8192)/256)@1fps + * UHD@30 decode + UHD@30 encode + ((8192x8192)/256)@1fps + */ }, { .key = "qcom,max-hq-mbs-per-frame", @@ -933,7 +936,10 @@ static struct msm_vidc_common_data lito_common_data_v1[] = { }, { .key = "qcom,max-hw-load", - .value = 1224000,/* UHD@30 decode + 1080@30 encode */ + .value = 1486144, + /** + * UHD@30 decode + 1080@30 encode + ((8192x8192)/256)@1fps + */ }, { .key = "qcom,max-hq-mbs-per-frame", @@ -1012,8 +1018,11 @@ static struct msm_vidc_common_data lagoon_common_data_v0[] = { }, { .key = "qcom,max-hw-load", - .value = 1958400, /* ((3840x2176)/256)@60fps decode */ - /* UHD@30 decode + 1080@30 encode */ + .value = 2220544, + /** + * ((3840x2176)/256)@60fps decode + ((8192x8192)/256)@1fps + * UHD@30 decode + 1080@30 encode + ((8192x8192)/256)@1fps + */ }, { .key = "qcom,max-mbpf", @@ -1092,7 +1101,8 @@ static struct msm_vidc_common_data lagoon_common_data_v1[] = { }, { .key = "qcom,max-hw-load", - .value = 1224000, /* UHD@30 decode + 1080@30 encode */ + .value = 1486144, + /* UHD@30 decode + 1080@30 encode + ((8192x8192)/256)@1fps */ }, { .key = "qcom,max-mbpf", @@ -1171,11 +1181,13 @@ static struct msm_vidc_common_data kona_common_data[] = { }, { .key = "qcom,max-hw-load", - .value = 7833600, /* - * 7680x4320@60fps, 3840x2176@240fps - * Greater than 4096x2176@120fps, - * 8192x4320@48fps - */ + .value = 8882176, + /** + * (7680x4320@60fps, 3840x2176@240fps + * Greater than 4096x2176@120fps, + * 8192x4320@48fps) + ((16384x16384)/256)@1fps + */ + }, { .key = "qcom,max-mbpf", @@ -1317,7 +1329,8 @@ static struct msm_vidc_common_data bengal_common_data_v0[] = { }, { .key = "qcom,max-hw-load", - .value = 489600, + .value = 751744, + /* ((1088x1920)/256)@60fps + ((8192x8192)/256)@1fps */ }, { .key = "qcom,max-mbpf", @@ -1372,7 +1385,8 @@ static struct msm_vidc_common_data bengal_common_data_v1[] = { }, { .key = "qcom,max-hw-load", - .value = 244800, + .value = 506944, + /* ((1088x1920)/256)@30fps + ((8192x8192)/256)@1fps */ }, { .key = "qcom,max-mbpf", From f724f1cb7e96f9c5a24746ecc2f19a8cc7f8c135 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Mon, 17 Feb 2020 17:39:54 +0530 Subject: [PATCH 270/350] msm:vidc: Reduce decoder input buffer size & count Default input buffer size is calculated based on 4k. For the targets that doesn't support 4k, calculate the buffer size for the highest resolution it supported. Input buffer count is defined considering HFR(240, 480,...) usecase, but low spec targets like bengal max HFR is 120 and may not require high buffer count. Reduced the count for low tier targets. CRs-Fixed: 2617714 Change-Id: Ica78e5d3393a90f1d0ae2556cb14881451525ded Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_buffer_calculations.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index ce5ba87d6f46..b497d4937bf3 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -19,11 +19,12 @@ /* total input buffers in case of decoder batch */ #define BATCH_DEC_TOTAL_INPUT_BUFFERS 6 -/* total input buffers for decoder HFR usecase (fps > 480) */ +/* total input buffers for decoder HFR usecase (fps capability > 480) */ #define MAX_HFR_DEC_TOTAL_INPUT_BUFFERS 12 -/* total input buffers for decoder HFR usecase */ -#define HFR_DEC_TOTAL_INPUT_BUFFERS 12 +/* total input buffers for decoder HFR usecase (fps capablity <= 480) */ +#define MIN_HFR_DEC_TOTAL_INPUT_BUFFERS 8 + /* extra output buffers in case of decoder batch */ #define BATCH_DEC_EXTRA_OUTPUT_BUFFERS 6 @@ -749,7 +750,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; + int max_fps = 0; if (!inst || !inst->core) { d_vpr_e("%s: invalid params %pK\n", __func__, inst); @@ -791,15 +792,15 @@ 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; + max_fps = inst->capability.cap[CAP_FRAMERATE].max; inst->is_perf_eligible_session = true; - if (fps > 480) + if (max_fps > 480) extra_input_count = (MAX_HFR_DEC_TOTAL_INPUT_BUFFERS - MIN_INPUT_BUFFERS); else extra_input_count = - (HFR_DEC_TOTAL_INPUT_BUFFERS - + (MIN_HFR_DEC_TOTAL_INPUT_BUFFERS - MIN_INPUT_BUFFERS); } } else if (is_encode_session(inst)) { @@ -909,7 +910,9 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) div_factor = 4; base_res_mbs = inst->capability.cap[CAP_MBS_PER_FRAME].max; } else { - base_res_mbs = NUM_MBS_4k; + base_res_mbs = min_t(unsigned int, + inst->capability.cap[CAP_MBS_PER_FRAME].max, + NUM_MBS_4k); if (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_VP9) div_factor = 1; else From 7e9996444d5896b9705ce0957d8256abd314c9fc Mon Sep 17 00:00:00 2001 From: Shi Zhongbo Date: Mon, 17 Feb 2020 12:26:33 +0800 Subject: [PATCH 271/350] 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 113147f3383d..0476b68309d2 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3097,9 +3097,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 7299bd061638..8af3d01fd5c0 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -640,6 +640,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 dbb89d61e8a23ce2acdbfaf2426abca9fb81892d Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 18 Dec 2019 17:00:22 +0530 Subject: [PATCH 272/350] 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 | 319 ++++++++++++++++++++++++++++++---- 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, 335 insertions(+), 33 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 5628eb393991..ef79b6c9b65a 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -800,8 +800,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); @@ -840,6 +847,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 c9ce75b80e0d..5b57fce38e0f 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -3214,6 +3214,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_actual; + + sz_o = oplane->plane_fmt[0].sizeimage; + sz_o_e = oplane->plane_fmt[1].sizeimage; + cnt_o = out_f->count_actual; + + 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; @@ -3589,27 +3768,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) @@ -4697,14 +4875,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)); /* @@ -4733,8 +4903,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; @@ -4750,16 +4925,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)); } @@ -5569,6 +5735,95 @@ 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 i, memory_limit = 0, memory_size = 0; + u32 memory_limit_mbytes = 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_actual; + + /* 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_actual; + + /* 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 877ba824bea2..fa9e4d6c0193 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -167,6 +167,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) { @@ -359,4 +371,6 @@ 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_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 90964d42e80f..2b69b90bb2e0 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -18,6 +18,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; @@ -757,6 +766,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->fw_name = "venus"; diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 443e07be14b1..b06419acd057 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -107,6 +107,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; @@ -144,6 +149,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 17faad938b1e7e493d8310bf889557a43461fd60 Mon Sep 17 00:00:00 2001 From: Malathi Gottam Date: Wed, 29 Jan 2020 13:29:51 +0530 Subject: [PATCH 273/350] msm: vidc: determine sku version based on obtained ddr rank Based on the ddr rank info obtained from api, sku version is set. CRs-Fixed: 2619648 Change-Id: I8a69569c6d731e73b8cba346aff7141f963f58e5 Signed-off-by: Malathi Gottam --- msm/vidc/msm_vidc_platform.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 56aa96c67b37..430f2fb7dda4 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1929,14 +1929,22 @@ static int msm_vidc_read_efuse( static int msm_vidc_read_rank( struct msm_vidc_platform_data *data, struct device *dev) { - uint32_t num_ranks; + uint32_t num_ranks = 0; + /*default channel is ch0 for bengal*/ + uint32_t channel = 0; - num_ranks = 0; //TO-DO Read Rank API to be added + /*default sku-version*/ data->sku_version = SKU_VERSION_0; + num_ranks = of_fdt_get_ddrrank(channel); - if (num_ranks == 1) + if (num_ranks == -ENOENT) { + d_vpr_e("Failed to get ddr rank of device\n"); + return num_ranks; + } else if (num_ranks == 1) data->sku_version = SKU_VERSION_1; + d_vpr_h("DDR Rank of device: %u", num_ranks); + return 0; } From 0e594de0c0de60bbe2fda18ae908da72a8ee4814 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Mon, 24 Feb 2020 12:34:50 +0530 Subject: [PATCH 274/350] 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 5a04dcc7ac47..0a6cd78969d1 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1709,16 +1709,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 56aa96c67b37..2f63369cfac6 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1195,11 +1195,11 @@ static struct msm_vidc_common_data kona_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 9de5ec1c5f7def55eee48694479f58df9faeb5fc Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Thu, 27 Feb 2020 11:28:01 -0800 Subject: [PATCH 275/350] 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 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_clocks.c | 2 +- msm/vidc/msm_vidc_debug.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 5a04dcc7ac47..828b52ad38fe 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1035,7 +1035,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 59ac83e08159..e95c2e58fafa 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -479,7 +479,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) { @@ -491,14 +491,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 5592aeb5cf00702a3f18c39d434e9195f6e2d366 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 28 Feb 2020 17:42:40 +0530 Subject: [PATCH 276/350] 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 | 48 +++----------- 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(+), 161 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 5628eb393991..f691c83955e7 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -368,7 +368,6 @@ 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; @@ -407,16 +406,15 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) } 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 @@ -447,8 +445,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", @@ -479,34 +475,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->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; @@ -1467,7 +1444,6 @@ 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); @@ -1585,7 +1561,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); @@ -1655,8 +1630,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); @@ -1713,7 +1686,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 c9ce75b80e0d..19046377d7ad 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2101,7 +2101,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; } @@ -2570,6 +2569,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"); @@ -2633,8 +2633,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) @@ -6883,120 +6886,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); @@ -7013,6 +6912,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; @@ -7023,6 +6923,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 877ba824bea2..06dade8afb01 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -330,16 +330,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 c94402db084d..7e43d88b9869 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -213,12 +213,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; @@ -541,7 +535,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 4cd787503015c10ff08cea038143e23afba8ded8 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 4 Mar 2020 17:42:13 +0530 Subject: [PATCH 277/350] msm: vidc: NOC registers for bengal In Bengal, avoid reading NOC registers during NOC issue. The same is done for below reasons, 1. NOC registers, in Bengal, are not populated with the required info. 2. During CPU NOC issue, it is not advised to access vcodec registers as vcodec could be in power collapsed state. Change-Id: I27baf63ea3ddf0ea6b820799e9714a8f67169c56 Signed-off-by: Vikash Garodia --- 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 e5529fa12200..11d2f343c575 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -142,7 +142,7 @@ struct venus_hfi_vpu_ops ar50_lite_ops = { .prepare_pc = __prepare_pc_ar50_lt, .raise_interrupt = __raise_interrupt_ar50_lt, .watchdog = __watchdog_common, - .noc_error_info = __noc_error_info_common, + .noc_error_info = NULL, .core_clear_interrupt = __core_clear_interrupt_ar50_lt, .boot_firmware = __boot_firmware_ar50_lt, }; From 5f987cf292b68490e2b18d749a5efb5c5937f46d Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Mon, 24 Feb 2020 23:28:40 +0530 Subject: [PATCH 278/350] msm: vidc: Add platform capabilities for scuba Add platform specific capabilities for scuba target. CRs-Fixed: 2631707 Change-Id: I537fe33ac6808a8c29fc15a9c0617dcb72ecebf1 Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_platform.c | 158 +++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index f5586586e1d0..36120af548ea 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -119,6 +119,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 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), +}; + /* 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), @@ -174,6 +182,12 @@ static struct msm_vidc_codec bengal_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, VP8}, {DEC, VP9}, {DEC, MPEG2}, @@ -701,6 +715,70 @@ static struct msm_vidc_codec_capability bengal_capabilities_v1[] = { 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, 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_OPERATINGRATE, DOMAINS_ALL, CODECS_ALL, 1, INT_MAX, 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}, + + /* 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 kona_capabilities[] = { /* {cap_type, domains, codecs, min, max, step_size, default_value,} */ {CAP_FRAME_WIDTH, DOMAINS_ALL, CODECS_ALL, 128, 8192, 1, 1920}, @@ -1422,6 +1500,62 @@ static struct msm_vidc_common_data bengal_common_data_v1[] = { }, }; +static struct msm_vidc_common_data scuba_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 = 506944, + /* ((1088x1920)/256)@30fps + ((8192x8192)/256)@1fps */ + }, + { + .key = "qcom,max-mbpf", + .value = 65280,/* ((3840x2176)/256) x 2 */ + }, + { + .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,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", @@ -1799,6 +1933,26 @@ static struct msm_vidc_platform_data bengal_data = { .codec_caps_count = ARRAY_SIZE(bengal_capabilities_v0), }; +static struct msm_vidc_platform_data scuba_data = { + .codec_data = scuba_codec_data, + .codec_data_length = ARRAY_SIZE(scuba_codec_data), + .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), +}; + static struct msm_vidc_platform_data sm8150_data = { .codec_data = sm8150_codec_data, .codec_data_length = ARRAY_SIZE(sm8150_codec_data), @@ -1880,6 +2034,10 @@ static const struct of_device_id msm_vidc_dt_match[] = { .compatible = "qcom,lagoon-vidc", .data = &lagoon_data, }, + { + .compatible = "qcom,scuba-vidc", + .data = &scuba_data, + }, {}, }; From 94a532c12658c38c15b57ff2aca627db5f689717 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Thu, 5 Mar 2020 20:29:04 +0530 Subject: [PATCH 279/350] 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 | 15 +++++----- msm/vidc/msm_vidc_resources.h | 3 +- 7 files changed, 65 insertions(+), 16 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index e5529fa12200..fde43324b2cd 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -3956,6 +3956,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")) { desc.args[1] = memprot.cp_size = @@ -3974,6 +3975,7 @@ static int __protect_cp_mem(struct venus_hfi_device *device) memprot.cp_nonpixel_size); } } + mutex_unlock(&device->res->cb_lock); desc.arginfo = SCM_ARGS(4); rc = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, diff --git a/msm/vidc/msm_smem.c b/msm/vidc/msm_smem.c index eba6739a1b00..33e89fbf7b17 100644 --- a/msm/vidc/msm_smem.c +++ b/msm/vidc/msm_smem.c @@ -591,6 +591,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) { @@ -598,6 +599,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 502857567213..0fd761e87343 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -313,6 +313,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); @@ -697,6 +698,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 cfadf2db3337..a3582711f2ae 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5765,26 +5765,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_actual; /* 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_actual; /* dpb buffers memory size */ @@ -5801,29 +5804,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; } @@ -6342,6 +6365,23 @@ void msm_comm_print_inst_info(struct msm_vidc_inst *inst) mutex_unlock(&inst->cvpbufs.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 0ac36f08ee2d..e4d5f1bda950 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -295,6 +295,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 2b69b90bb2e0..e7280b81681e 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 @@ -902,7 +902,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; @@ -1054,12 +1053,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(inst->core); /* * Return -EINVAL to elicit the default behaviour of smmu driver. * If we return -EINVAL, then smmu driver assumes page fault handler @@ -1089,7 +1084,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) { @@ -1169,7 +1167,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 b06419acd057..6ac9226827b9 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__ @@ -171,6 +171,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 a9a15b136f9aa4bfec2fc2aaf7e3a65d32419cea Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Sat, 14 Mar 2020 15:46:28 +0530 Subject: [PATCH 280/350] 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 cfadf2db3337..7279ce2b25ad 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -3247,6 +3247,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 b57724e8397f60eefcd37655e32631850fb18ee0 Mon Sep 17 00:00:00 2001 From: Indranil Chakraborty Date: Mon, 23 Mar 2020 14:59:28 +0530 Subject: [PATCH 281/350] msm: vidc: Enable AVG QP extradata Enable the HFI to request firmware to add average QP extradata for use cases requiring the enablement of average QP statistics. Change-Id: Ia628068fdd3608cf29c28fa7603c7fc9e3f95a41 Signed-off-by: Indranil Chakraborty --- msm/vidc/msm_venc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 990d1984666e..acbda5cbc30e 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -4366,10 +4366,13 @@ int msm_venc_set_extradata(struct msm_vidc_inst *inst) } } - if (inst->prop.extradata_ctrls & EXTRADATA_ADVANCED) + if (inst->prop.extradata_ctrls & EXTRADATA_ADVANCED) { // Enable Advanced Extradata - LTR Info msm_comm_set_extradata(inst, HFI_PROPERTY_PARAM_VENC_LTR_INFO, 0x1); + 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 From c929cb838be20f740330505dfd587878014873bc Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 23 Mar 2020 17:12:37 +0530 Subject: [PATCH 282/350] msm: vidc: Update profile level as per lagoon spec Update profile level in the capabilities as per maximum supported spec for both the lagoon SKUs. Change-Id: I9815e87a79f120f32063e9efbb8892df4a3a72f4 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_platform.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index f5586586e1d0..d01a88c148f7 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -466,19 +466,19 @@ static struct msm_vidc_codec_capability lagoon_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_6_0, 1, - V4L2_MPEG_VIDEO_H264_LEVEL_6_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_6, 1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_6}, + 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_1, 1, - V4L2_MPEG_VIDEO_H264_LEVEL_5_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_6_1, 1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5}, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, }; static struct msm_vidc_codec_capability lagoon_capabilities_v1[] = { @@ -558,19 +558,19 @@ static struct msm_vidc_codec_capability lagoon_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_6_0, 1, - V4L2_MPEG_VIDEO_H264_LEVEL_6_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_6, 1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_6}, + 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_1, 1, - V4L2_MPEG_VIDEO_H264_LEVEL_5_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_6_1, 1, - V4L2_MPEG_VIDEO_HEVC_LEVEL_5}, + V4L2_MPEG_VIDEO_HEVC_LEVEL_5, 1, + V4L2_MPEG_VIDEO_HEVC_LEVEL_4}, }; static struct msm_vidc_codec_capability bengal_capabilities_v0[] = { From 211938a66ec0887c47dbebfd5fc8e1c85e38cb84 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Thu, 20 Feb 2020 20:10:14 +0530 Subject: [PATCH 283/350] msm: venc: 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: I852c4ea8b30c736b3596c3b9bd5960b68904e359 Signed-off-by: Vikash Garodia --- msm/vidc/msm_venc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 990d1984666e..f62afdbee81a 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1683,16 +1683,17 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: if (!is_valid_operating_rate(inst, ctrl->val)) break; - 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 6de1162fd6f7f2295944c8494fbf6451428a7077 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 1 Apr 2020 13:13:42 +0530 Subject: [PATCH 284/350] 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 032552f45a15..d7e42c808ad6 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -1171,7 +1171,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 d442afe23bd93ae381ea9a921f3db172cf23acb1 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Fri, 3 Apr 2020 10:51:46 +0530 Subject: [PATCH 285/350] msm: vidc: Update adaptive b caps for lagoon Update max-b-frames-per-sec from 1080p@30 to 1080p@60 as per latest recommendations. Change-Id: Ib82b44f43fae96c0ffa54068453f9c7564e5b986 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 5e86203ec592..4c8bbe271071 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1120,7 +1120,7 @@ static struct msm_vidc_common_data lagoon_common_data_v0[] = { }, { .key = "qcom,max-b-frame-mbs-per-sec", - .value = 244800, /* ((1920x1088)/256) MBs@30fps */ + .value = 489600, /* ((1920x1088)/256) MBs@60fps */ }, { .key = "qcom,power-collapse-delay", @@ -1200,7 +1200,7 @@ static struct msm_vidc_common_data lagoon_common_data_v1[] = { }, { .key = "qcom,max-b-frame-mbs-per-sec", - .value = 244800, /* ((1920x1088)/256) MBs@30fps */ + .value = 489600, /* ((1920x1088)/256) MBs@60fps */ }, { .key = "qcom,power-collapse-delay", From dfe35953aedfb834ced15e6ca71564ba36e6b8df Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Thu, 12 Mar 2020 19:20:18 +0530 Subject: [PATCH 286/350] msm: vidc: update index from unsigned to signed number [1] if target ramsize value is higher than mentioned in memory_limit_tbl_mbytes table, then index value will reach zero in msm_comm_get_memory_limit. [2] currently index is u32, so for nex iteration index value will become huge positive value instead of -1. [3] It will lead to OOB access at memory_limits_tbl[i].ddr_size. and it will go in infinite loop. Change-Id: I0bfcb98660af65a1e1852f9a67c2f26dcbdac232 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_vidc_common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 55e3916db69b..f3d05a210709 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5743,8 +5743,9 @@ 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 i, memory_limit = 0, memory_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; From 4a6e8610daf0f1c8fa9f8ee4a4524cc8fc80cd6c Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Thu, 9 Apr 2020 12:41:58 +0530 Subject: [PATCH 287/350] msm: vidc: Fix print core info Remove 'inst' variable as it is not required to print the core info. Change-Id: I0867ed1c80ff1b96b62b035b0e73c5d50d398261 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_res_parse.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index e7280b81681e..deaf111d9314 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -1034,7 +1034,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", @@ -1054,7 +1053,7 @@ int msm_vidc_smmu_fault_handler(struct iommu_domain *domain, d_vpr_e("%s: faulting address: %lx\n", __func__, iova); core->smmu_fault_handled = true; - msm_comm_print_insts_info(inst->core); + 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 From 124887699c42b96bd8e598968aaf1b628570a965 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Thu, 9 Apr 2020 23:07:42 +0530 Subject: [PATCH 288/350] msm:vidc: Modify input buffer size calculation calculate buffer size as per the max resolution for the targets that doesn't 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 | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 1862f4e07f43..6e37b05bd5b4 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -922,15 +922,24 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) div_factor = 4; base_res_mbs = inst->capability.cap[CAP_MBS_PER_FRAME].max; } else { - base_res_mbs = min_t(unsigned int, - inst->capability.cap[CAP_MBS_PER_FRAME].max, - NUM_MBS_4k); + base_res_mbs = NUM_MBS_4k; if (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_VP9) div_factor = 1; else 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 */ @@ -938,9 +947,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 730fc7cd25639e7d6952c55b828b875d5de1e9a0 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Sun, 5 Apr 2020 16:33:43 +0530 Subject: [PATCH 289/350] 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 d7e42c808ad6..0764cd4ad654 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -391,6 +391,8 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) 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]; @@ -1483,6 +1485,7 @@ 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->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 765ceda4c14d..0d450203878c 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -16,6 +16,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(struct msm_vidc_inst *inst); static unsigned long msm_vidc_calc_freq_ar50(struct msm_vidc_inst *inst, u32 filled_len); @@ -172,6 +174,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) { @@ -265,12 +280,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) { @@ -295,6 +312,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; @@ -865,8 +888,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__); @@ -895,6 +920,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) @@ -1018,6 +1049,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"); @@ -1029,6 +1066,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 7e43d88b9869..e4c3642e108a 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -560,6 +560,8 @@ struct msm_vidc_inst { bool is_perf_eligible_session; u32 max_filled_len; int full_range; + u64 last_qbuf_time_ns; + bool active; }; extern struct msm_vidc_drv *vidc_driver; From e543a787241afd850a6509e814a936d84ccd4b74 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 23 Mar 2020 12:59:09 +0530 Subject: [PATCH 290/350] msm: vidc: change cvp buffer add sequence [1] Due to race between cvp_register & cvp_unregister on same cvp buffer lead to Use-After-Free issue. [2] To address this issue, add cvp buffer into a list inst->cvpbufs.list only after completing all required steps on registration sequence. Change-Id: If9f22d17e64f003528d5653f81404f3fcc6e88f5 Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_cvp_internal.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/msm/vidc/msm_cvp_internal.c b/msm/vidc/msm_cvp_internal.c index 36a74ded11b7..48efca59d755 100644 --- a/msm/vidc/msm_cvp_internal.c +++ b/msm/vidc/msm_cvp_internal.c @@ -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. */ #include "msm_cvp_internal.h" @@ -364,9 +364,6 @@ static int msm_cvp_register_buffer(struct msm_vidc_inst *inst, 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, @@ -393,14 +390,14 @@ static int msm_cvp_register_buffer(struct msm_vidc_inst *inst, print_cvp_buffer(VIDC_ERR, "register failed", inst, cbuf); goto exit; } + mutex_lock(&inst->cvpbufs.lock); + list_add_tail(&cbuf->list, &inst->cvpbufs.list); + mutex_unlock(&inst->cvpbufs.lock); 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; From 88896322bd16ca66223b921c8e741739d735cd16 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Mon, 6 Apr 2020 15:17:19 +0530 Subject: [PATCH 291/350] 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 | 68 +++++++++++++++++++++-------- msm/vidc/msm_vidc_res_parse.c | 3 ++ msm/vidc/msm_vidc_resources.h | 1 + 6 files changed, 128 insertions(+), 40 deletions(-) diff --git a/msm/vidc/msm_vidc.h b/msm/vidc/msm_vidc.h index 93bada2a2365..7fb249184c13 100644 --- a/msm/vidc/msm_vidc.h +++ b/msm/vidc/msm_vidc.h @@ -96,6 +96,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 f3d05a210709..e83a241402b5 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -824,7 +824,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; @@ -836,7 +837,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); @@ -3448,8 +3454,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) { @@ -3468,18 +3475,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; } @@ -5854,19 +5876,37 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_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 e4d5f1bda950..1a220831ceaf 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -120,6 +120,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; @@ -282,7 +287,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 4c8bbe271071..13316b486d7b 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -931,12 +931,16 @@ static struct msm_vidc_common_data lito_common_data_v0[] = { }, { .key = "qcom,max-hw-load", - .value = 2220544, + .value = 1958400, /** - * ((3840x2176)/256)@60 + ((8192x8192)/256)@1fps - * UHD@30 decode + UHD@30 encode + ((8192x8192)/256)@1fps + * ((3840x2176)/256)@60 + * UHD@30 decode + UHD@30 encode */ }, + { + .key = "qcom,max-image-load", + .value = 262144, /* ((8192x8192)/256)@1fps */ + }, { .key = "qcom,max-hq-mbs-per-frame", .value = 8160,/* ((1920x1088)/256) */ @@ -1014,10 +1018,14 @@ static struct msm_vidc_common_data lito_common_data_v1[] = { }, { .key = "qcom,max-hw-load", - .value = 1486144, + .value = 1224000, /** - * UHD@30 decode + 1080@30 encode + ((8192x8192)/256)@1fps + * UHD@30 decode + 1080@30 encode */ + }, + { + .key = "qcom,max-image-load", + .value = 262144, /* ((8192x8192)/256)@1fps */ }, { .key = "qcom,max-hq-mbs-per-frame", @@ -1096,12 +1104,16 @@ static struct msm_vidc_common_data lagoon_common_data_v0[] = { }, { .key = "qcom,max-hw-load", - .value = 2220544, + .value = 1958400, /** - * ((3840x2176)/256)@60fps decode + ((8192x8192)/256)@1fps - * UHD@30 decode + 1080@30 encode + ((8192x8192)/256)@1fps + * ((3840x2176)/256)@60 + * UHD@30 decode + UHD@30 encode */ }, + { + .key = "qcom,max-image-load", + .value = 262144,/* ((8192x8192)/256)@1fps */ + }, { .key = "qcom,max-mbpf", .value = 130560, /* ((3840x2176)/256) x 4 */ @@ -1179,8 +1191,14 @@ static struct msm_vidc_common_data lagoon_common_data_v1[] = { }, { .key = "qcom,max-hw-load", - .value = 1486144, - /* UHD@30 decode + 1080@30 encode + ((8192x8192)/256)@1fps */ + .value = 1224000, + /** + * UHD@30 decode + 1080@30 encode + */ + }, + { + .key = "qcom,max-image-load", + .value = 262144, /* ((8192x8192)/256)@1fps */ }, { .key = "qcom,max-mbpf", @@ -1259,14 +1277,18 @@ static struct msm_vidc_common_data kona_common_data[] = { }, { .key = "qcom,max-hw-load", - .value = 8882176, + .value = 7833600, /** * (7680x4320@60fps, 3840x2176@240fps * Greater than 4096x2176@120fps, - * 8192x4320@48fps) + ((16384x16384)/256)@1fps + * 8192x4320@48fps) */ }, + { + .key = "qcom,max-image-load", + .value = 1048576, /* ((16384x16384)/256)@1fps */ + }, { .key = "qcom,max-mbpf", .value = 173056, /* (8192x4320)/256 + (4096x2176)/256*/ @@ -1407,8 +1429,11 @@ static struct msm_vidc_common_data bengal_common_data_v0[] = { }, { .key = "qcom,max-hw-load", - .value = 751744, - /* ((1088x1920)/256)@60fps + ((8192x8192)/256)@1fps */ + .value = 489600, /* ((1088x1920)/256)@60fps */ + }, + { + .key = "qcom,max-image-load", + .value = 262144, /* ((8192x8192)/256)@1fps */ }, { .key = "qcom,max-mbpf", @@ -1463,8 +1488,11 @@ static struct msm_vidc_common_data bengal_common_data_v1[] = { }, { .key = "qcom,max-hw-load", - .value = 506944, - /* ((1088x1920)/256)@30fps + ((8192x8192)/256)@1fps */ + .value = 244800, /* ((1088x1920)/256)@30fps */ + }, + { + .key = "qcom,max-image-load", + .value = 262144, /* ((8192x8192)/256)@1fps */ }, { .key = "qcom,max-mbpf", @@ -1519,8 +1547,12 @@ static struct msm_vidc_common_data scuba_common_data[] = { }, { .key = "qcom,max-hw-load", - .value = 506944, - /* ((1088x1920)/256)@30fps + ((8192x8192)/256)@1fps */ + .value = 352800, + /* ((1088x1920)/256)@30fps + ((720x1280)/256)@30fps*/ + }, + { + .key = "qcom,max-image-load", + .value = 262144, /* ((8192x8192)/256)@1fps */ }, { .key = "qcom,max-mbpf", diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index e7280b81681e..8f083c2c64ee 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_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 6ac9226827b9..6e1f46f095bc 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -158,6 +158,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 fd1b6cd8c2877e7261fb6eb442dd5e5b9625d9d5 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Wed, 15 Apr 2020 21:14:30 +0530 Subject: [PATCH 292/350] 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 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 765ceda4c14d..23b8d28e2a1b 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1337,7 +1337,8 @@ static int msm_vidc_decide_work_mode_ar50(struct msm_vidc_inst *inst) pdata.video_work_mode = HFI_WORKMODE_1; 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_MBR_VFR || + inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) pdata.video_work_mode = HFI_WORKMODE_2; } else { return -EINVAL; From 707573b4630574fdee9971bb02d2a375c0fce25b Mon Sep 17 00:00:00 2001 From: Mihir Ganu Date: Thu, 9 Apr 2020 11:36:41 -0700 Subject: [PATCH 293/350] 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 Signed-off-by: Santhosh Behara --- 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 a4511151768f..24bd53ca1290 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -632,7 +632,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 ef4700624064f67dd9c84dd585a605a9b4f13981 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Sat, 14 Mar 2020 20:30:01 +0530 Subject: [PATCH 294/350] 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 27199d24f5ab..db709a0d0281 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 804e918cda36293db0a65caa1e40dec747e3bf74 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 17 Apr 2020 23:02:20 +0530 Subject: [PATCH 295/350] 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 f3d05a210709..10f77f2bb79d 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -3414,7 +3414,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)); @@ -3425,6 +3425,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 f0ed1cdbad63b9adb77a3eaf5c8e107fe3d8f554 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Thu, 9 Apr 2020 13:18:08 +0800 Subject: [PATCH 296/350] 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 --- msm/vidc/msm_vidc_common.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index f3d05a210709..26420a7b3e5f 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1968,9 +1968,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)) { @@ -1989,11 +1999,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) { + if (buffers_owned_by_driver != dpb->buffer_count_actual) { s_vpr_e(inst->sid, "OUTPUT 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 b4c03d6f84721ad0410882351ca0e87d74186a7c Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 15 Apr 2020 20:13:54 +0530 Subject: [PATCH 297/350] msm: vidc: Remove support for noc error info registers on lagoon 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 daceae452020..d0a093e06a56 100644 --- a/msm/vidc/hfi_iris2.c +++ b/msm/vidc/hfi_iris2.c @@ -331,6 +331,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 79ede51ddfb397fefa3b0f16d2e59d910c2cb7f9 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 20 Apr 2020 14:17:23 +0530 Subject: [PATCH 298/350] msm: vidc: Increase poll time out for boot FW Increase the number of tries for booting up the firmware, since the repsonse from FW is intermittently slow on lagoon. Change-Id: I499efc5d50ac9ef5357bd823d3b9c5a3da561852 Signed-off-by: Priyanka Gujjula --- msm/vidc/hfi_iris2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/hfi_iris2.c b/msm/vidc/hfi_iris2.c index daceae452020..969714549c3e 100644 --- a/msm/vidc/hfi_iris2.c +++ b/msm/vidc/hfi_iris2.c @@ -389,7 +389,7 @@ void __core_clear_interrupt_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; + u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 5000; ctrl_init_val = BIT(0); if (device->res->cvp_internal) From f1d9eb86ee60aad9f90bdec76076c5c039b950ac Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 27 Apr 2020 17:29:33 +0530 Subject: [PATCH 299/350] msm: vidc: Update base cycles for lagoon Update base cycles as per vperf recommendation Change-Id: I540cae899fb27c8df58adb13a102d5a36c39c083 Signed-off-by: Priyanka Gujjula --- 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 13316b486d7b..f0983db3fd0a 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -90,12 +90,12 @@ static struct msm_vidc_codec_data kona_codec_data[] = { }; static struct msm_vidc_codec_data lagoon_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), }; /* Update with SM6150 data */ From cdf413bd99711466fe57f8d66e7f643c3f7da498 Mon Sep 17 00:00:00 2001 From: Prateek Sood Date: Fri, 17 Apr 2020 13:15:25 +0530 Subject: [PATCH 300/350] 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: Prateek Sood --- 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 e95c2e58fafa..e803269aa6bd 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -271,7 +271,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; } @@ -492,6 +493,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 d94bcd5ae9826f920bf6de59c19e2e34fb50c8ed Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 27 Apr 2020 12:07:31 +0530 Subject: [PATCH 301/350] msm: vidc: Update HFI enc_scratch1_size 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 | 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 6e37b05bd5b4..74323724f4fa 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1615,6 +1615,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); @@ -1680,8 +1682,8 @@ 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); + h265e_colrcbuf_size = (((width_mb_num + 7) >> 3) * + 16 * 2 * height_mb_num); if (num_vpp_pipes > 1) h265e_colrcbuf_size = ALIGN(h265e_colrcbuf_size, VENUS_DMA_ALIGNMENT) * num_vpp_pipes; From 1318ca3eb02435c4968907f22f789df82aecac8a Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Mon, 11 May 2020 14:07:10 +0530 Subject: [PATCH 302/350] msm: vidc: Enable NOC Error recovery Enable NOC error recovery for bengal. Change-Id: Ib58d556fa186e4393c99e0f24470a8e598ba4491 Signed-off-by: Manikanta Kanamarlapudi --- msm/vidc/msm_vidc_platform.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 13316b486d7b..6254246a6d49 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -2194,9 +2194,6 @@ void *vidc_get_drv_data(struct device *dev) ddr_type, driver_data->ubwc_config ? driver_data->ubwc_config->highest_bank_bit : -1); } else if (!strcmp(match->compatible, "qcom,bengal-vidc")) { - d_vpr_h("Disable NOC error recovery"); - msm_vidc_err_recovery_disable = - VIDC_DISABLE_NOC_ERR_RECOV; rc = msm_vidc_read_rank(driver_data, dev); if (rc) { d_vpr_e("Failed to get ddr rank, use Dual Rank DDR\n"); From ef2de6dcc20031a940b79e80436846839569e828 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 11 Mar 2020 17:38:20 -0700 Subject: [PATCH 303/350] 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 Signed-off-by: Govindaraj Rajagopal --- 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 f48a52e83658..0dd92af1109e 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -6743,40 +6743,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; } } @@ -6811,26 +6804,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 @@ -6838,7 +6831,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 db0e597b304211c0939e3f134189cfce78700137 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Mon, 27 Apr 2020 12:38:36 +0530 Subject: [PATCH 304/350] 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 mode 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 | 37 +++++++++++++++++++++++++++++++++++++ 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 | 4 +++- 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 24bd53ca1290..ec6da38267aa 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_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", @@ -928,6 +937,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; @@ -1304,6 +1315,29 @@ 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); + + 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; @@ -1439,6 +1473,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 495b0e8ed6c2..086e03dbb10b 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1081,6 +1081,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 f48a52e83658..4d198cdd89d9 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1701,6 +1701,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, @@ -2860,6 +2869,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 1a220831ceaf..1c64e3ceeef9 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -132,6 +132,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 76cfb7e0924f..5fd937757e50 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__ @@ -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_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 40ae77987c885d2e5660541d0afcc91aa91e9429 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Tue, 26 May 2020 23:49:51 +0530 Subject: [PATCH 305/350] 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 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 5b0a6156822c..1b9e9942cb44 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 @@ -1012,6 +1013,13 @@ 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. + */ + if (!strcmp(cb->name, "venus_ns")) + 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 a7855724b47c2ab9a5d9dc43584b330ef2a9623b Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Thu, 28 May 2020 09:12:10 +0530 Subject: [PATCH 306/350] msm: vdec: set hfi property when set by client The property to configure dynamic low latency to firmware is set by driver during start streaming. Set the property only when userspace has enabled the feature. Change-Id: Ic89b131c8e06adf95ad70a9acf2041535a273c57 Signed-off-by: Vikash Garodia --- msm/vidc/msm_vdec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index ec6da38267aa..54923e18b3a0 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -1328,6 +1328,9 @@ int msm_vdec_set_seqchng_at_syncframe(struct msm_vidc_inst *inst) 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, From 84680815ec3133869903562c46b3e935c325c9b2 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Tue, 26 May 2020 10:28:51 +0530 Subject: [PATCH 307/350] msm: vidc: Disable DCVS for 720p@240 enc on lagoon 1. Camera creates an internal batch based on hfr/preview_fps i.e 8 for 240fps usecases. Hence camera sends 8 ETB's in single shot and then waits for 25-30ms, which causes the side effect at FW. Either FW is always waiting for input or loaded with input buffers. 2. Being a HFR use case (<480), DCVS max_threshold for this usecase (i.e max number of input buffers that can held by encoder) is 8, due to which 20% of the usecase runs in DCVS high corner. For this use case, DCVS_high is turbo. Since DDR runs at Nominal and there would not be much savings when clocks runs at SVS_L1, disabling DCVS for this usecase on lagoon. Change-Id: Ifcc7da11cf4347655dbf3e39e41b4bceb5854167 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_clocks.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 086e03dbb10b..466fdbf59f9c 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1072,10 +1072,18 @@ 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) { + bool disable_hfr_dcvs = false; + if (!inst || !inst->core) { d_vpr_e("%s: Invalid args: %pK\n", __func__, inst); return -EINVAL; } + if (inst->core->platform_data->vpu_ver == VPU_VERSION_IRIS2_1) { + /* 720p@240 encode */ + if (is_encode_session(inst) && msm_vidc_get_fps(inst) >= 240 + && msm_vidc_get_mbs_per_frame(inst) >= 3600) + disable_hfr_dcvs = true; + } inst->clk_data.dcvs_mode = !(msm_vidc_clock_voting || @@ -1085,7 +1093,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 || + disable_hfr_dcvs); s_vpr_hp(inst->sid, "DCVS %s: %pK\n", inst->clk_data.dcvs_mode ? "enabled" : "disabled", inst); From 65316e79a0ac7768f53f6875e3f2ea61e7998900 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 3 Jun 2020 15:36:44 +0530 Subject: [PATCH 308/350] 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 | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 0764cd4ad654..016ec327d767 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -418,10 +418,11 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) } /* - * 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; q = msm_comm_get_vb2q(inst, b->type); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index e8fff21299e6..fca469e97ec0 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -799,9 +799,9 @@ int msm_comm_get_inst_load(struct msm_vidc_inst *inst, * ----------------|----------------------------| */ - 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 eaad7c00f6d7b460d9fd8ba8fe8bc4aacc0b7b83 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 3 Jun 2020 23:18:17 +0530 Subject: [PATCH 309/350] msm: vidc: Update DCVS thresholds for sufficient seq change During sequence change change event, FW notifies the maximum the number of DPB bufferes required for the clip. Hence for seq change sufficient event, update the same in driver in order to update the DCVS thresholds accordingly. Change-Id: Icae0c1577cf08d8d91aa8c9e20f810ff307940fe Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_clocks.c | 65 ++++++++++++++++++++++---------------- msm/vidc/msm_vidc_clocks.h | 3 +- msm/vidc/msm_vidc_common.c | 25 ++++++++++++--- 3 files changed, 60 insertions(+), 33 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 466fdbf59f9c..5fdfe530d608 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1102,6 +1102,40 @@ 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; + 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); +} + int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst) { int rc = 0, j = 0; @@ -1147,8 +1181,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", @@ -1158,35 +1190,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 5d649ab9f301..7515a4b49d68 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_ @@ -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 e8fff21299e6..6885d935a509 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1637,7 +1637,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; int extra_buff_count = 0; u32 codec; @@ -1690,15 +1689,25 @@ 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; } else { + if (fmt->count_min < event_notify->fw_min_cnt) { + s_vpr_e(inst->sid, + "%s: Firmware min count %d cannot be greater than driver min count %d\n", + __func__, event_notify->fw_min_cnt, + fmt->count_min); + msm_vidc_queue_v4l2_event(inst, + V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED); + goto err_bad_event; + } inst->entropy_mode = event_notify->entropy_mode; /* configure work mode considering low latency*/ @@ -1710,6 +1719,12 @@ static void handle_event_change(enum hal_command_response cmd, void *data) "%s: Failed to decide work mode\n", __func__); } + /* Update driver buffer counts */ + 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; + msm_dcvs_reset(inst); s_vpr_h(inst->sid, "seq: No parameter change continue session\n"); rc = call_hfi_op(hdev, session_continue, @@ -1783,7 +1798,6 @@ static void handle_event_change(enum hal_command_response cmd, void *data) 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\n", event_notify->height, event_notify->width); @@ -1826,6 +1840,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data) HAL_BUFFER_OUTPUT, fmt->count_min, fmt->count_min_host); } + ptr[MSM_VIDC_FW_MIN_COUNT] = fmt->count_min_host; rc = msm_vidc_check_session_supported(inst); if (!rc) { From c55e08843467be8bcd2644a6b23deef2776cf2a1 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 4 Mar 2020 19:39:40 +0530 Subject: [PATCH 310/350] 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 | 76 ++++++++++++++++++++++++++++++++++++++ msm/vidc/vidc_hfi_helper.h | 9 ++++- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 179749937632..0ad13a833435 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -944,6 +944,15 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = 3, .step = 1, }, + { + .id = V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET, + .name = "Chroma QP Index Offset", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = -12, + .maximum = 0, + .default_value = 0, + .step = 1, + }, { .id = V4L2_CID_MPEG_VIDEO_VBV_DELAY, .name = "Set Vbv Delay", @@ -1978,6 +1987,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_VIDEO_H264_CHROMA_QP_INDEX_OFFSET: case V4L2_CID_MPEG_VIDC_SUPERFRAME: s_vpr_h(sid, "Control set: ID : 0x%x Val : %d\n", ctrl->id, ctrl->val); @@ -3369,6 +3379,69 @@ int msm_venc_set_bitrate_savings_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 != -12) + 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_loop_filter_mode(struct msm_vidc_inst *inst) { int rc = 0; @@ -4711,6 +4784,9 @@ 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; + 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 02c3619333a1..1448d4aad561 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__ @@ -350,6 +350,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_CONFIG_VENC_COMMON_START \ (HFI_DOMAIN_BASE_VENC + HFI_ARCH_COMMON_OFFSET + 0x6000) @@ -518,6 +520,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 b6cccdfd0be998b6606c6875422d7a0372407f3d Mon Sep 17 00:00:00 2001 From: Chandrakant I Viraktamath Date: Wed, 10 Jun 2020 10:26:51 +0530 Subject: [PATCH 311/350] 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 b4f91c7ed1b2..d501c42fe1b4 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5775,8 +5775,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 8eae74252cede9d48500f9424dc3327ac5aa6246 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Thu, 18 Jun 2020 14:33:21 +0530 Subject: [PATCH 312/350] msm: vidc: update memory limit check based on min_host_count msm_comm_check_memory_supported is depends on actual_count. Codec2 configures vb2 queues for 64 buffers, but during video usecase, only limited number of buffers were allocated and same willbe reused from buffer pool. Only those buffers would be consuming memory. So changed logic to estimate memory consumption based on min_host_count instead of actual_count. Change-Id: I447dee68f8480dad38c285c40af5583f00b91d8f 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 b4f91c7ed1b2..997e37fbe79f 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -3407,11 +3407,11 @@ static void msm_comm_print_mem_usage(struct msm_vidc_core *core) } sz_i = iplane->plane_fmt[0].sizeimage; sz_i_e = iplane->plane_fmt[1].sizeimage; - cnt_i = inp_f->count_actual; + 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_actual; + 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 + @@ -5842,14 +5842,14 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst) f = &fmt->v4l2_fmt; for (i = 0; i < f->fmt.pix_mp.num_planes; i++) inst_mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage * - fmt->count_actual; + 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++) inst_mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage * - fmt->count_actual; + fmt->count_min_host; /* dpb buffers memory size */ if (msm_comm_get_stream_output_mode(inst) == From d6f58ecf270d0edd5b6bceef1dc4f311a3c3349a Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Thu, 25 Jun 2020 13:30:53 +0530 Subject: [PATCH 313/350] msm: vidc: Relax driver and FW min cnt check during sufficient event We cannot have the sanity check at this moment since FW raises insufficient event only if actual count is greater than FW min count. This needs to be corrected in FW before having the sanity check. Change-Id: Icb06b440424c37c4aee397ba24b776eb715b0332 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_common.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index dfde34675ac6..e943d9414319 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1699,15 +1699,6 @@ static void handle_event_change(enum hal_command_response cmd, void *data) if (event_fields_changed) { event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT; } else { - if (fmt->count_min < event_notify->fw_min_cnt) { - s_vpr_e(inst->sid, - "%s: Firmware min count %d cannot be greater than driver min count %d\n", - __func__, event_notify->fw_min_cnt, - fmt->count_min); - msm_vidc_queue_v4l2_event(inst, - V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED); - goto err_bad_event; - } inst->entropy_mode = event_notify->entropy_mode; /* configure work mode considering low latency*/ @@ -1719,11 +1710,8 @@ static void handle_event_change(enum hal_command_response cmd, void *data) "%s: Failed to decide work mode\n", __func__); } - /* Update driver buffer counts */ - extra_buff_count = msm_vidc_get_extra_buff_count(inst, - HAL_BUFFER_OUTPUT); + /* Update driver buffer count */ fmt->count_min = event_notify->fw_min_cnt; - fmt->count_min_host = fmt->count_min + extra_buff_count; msm_dcvs_reset(inst); s_vpr_h(inst->sid, "seq: No parameter change continue session\n"); From 0e1430c333a5343ff02e67796192bce156f0af68 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 24 Jun 2020 20:31:31 +0530 Subject: [PATCH 314/350] 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 | 29 +++++++++++------------ msm/vidc/msm_vidc_common.c | 45 +++++++++++++++++++++++------------- msm/vidc/msm_vidc_internal.h | 2 +- msm/vidc/vidc_hfi_api.h | 7 +++--- 4 files changed, 47 insertions(+), 36 deletions(-) diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 016ec327d767..cbb46852cbb9 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -384,13 +384,21 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) 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++) { @@ -413,7 +421,8 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) 0, inst->sid); if (rc) { s_vpr_e(inst->sid, "Failed to store input tag"); - return -EINVAL; + rc = -EINVAL; + goto unlock; } } @@ -425,18 +434,11 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) && b->type == INPUT_MPLANE) b->flags |= V4L2_BUF_FLAG_PERF_MODE; - 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, 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; } @@ -1452,7 +1454,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); INIT_MSM_VIDC_LIST(&inst->scratchbufs); INIT_MSM_VIDC_LIST(&inst->input_crs); @@ -1571,7 +1572,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); @@ -1714,7 +1714,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 e943d9414319..21adfe4d560e 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2086,7 +2086,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) { @@ -2136,7 +2139,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); } @@ -2348,7 +2354,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) { @@ -2364,7 +2370,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; @@ -2379,6 +2384,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", @@ -2393,16 +2399,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; @@ -2418,9 +2427,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) @@ -5581,7 +5591,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"); @@ -5604,7 +5613,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; @@ -5660,7 +5672,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"); @@ -6725,7 +6740,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); @@ -6733,7 +6747,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; } @@ -7079,7 +7092,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 */ @@ -7168,7 +7181,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 e4c3642e108a..8fdbf3434fca 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -493,7 +493,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 a86e36551955..212b227b1821 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -414,10 +414,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 404a60ceaa1b6a328f93d5d8cca0bd18eaedcb5f Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Tue, 16 Jun 2020 14:45:00 +0530 Subject: [PATCH 315/350] msm: vidc: Ignore single rank ddr Ignore the ddr rank and make bengal with default spec of primary sku. CRs-Fixed: 2720876 Change-Id: I7a9ba1a896264d1becd5b986610b0386fecfe5de Signed-off-by: Manikanta Kanamarlapudi --- 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 34a3c8f984ab..56f8d0e08e57 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -2131,7 +2131,7 @@ static int msm_vidc_read_rank( d_vpr_e("Failed to get ddr rank of device\n"); return num_ranks; } else if (num_ranks == 1) - data->sku_version = SKU_VERSION_1; + data->sku_version = SKU_VERSION_0; d_vpr_h("DDR Rank of device: %u", num_ranks); From aa2b1b38142b0d2a08bc1c019f9f6779d9c2593f Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Mon, 3 Aug 2020 15:19:22 +0530 Subject: [PATCH 316/350] msm: vidc: Restrict secure buffer size optimization for higher resolution For secure usecase, video driver reduces the estimated size by half. This is done as secure decode spec is in general half of the non secure spec. As a result, the worst case size get half for secure mode. Based on this new restriction, the impact on buffer size would be for FWVGA and below = 6MB, which was earlier 3MB. CRs-Fixed: 2745960 Change-Id: I4a3be87e3f4beef7e8949cfb85e3341187e4b8b7 Signed-off-by: Vikash Garodia --- 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 74323724f4fa..c7af4a276421 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -929,7 +929,7 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) div_factor = 2; } - if (is_secure_session(inst)) + if (is_secure_session(inst) && num_mbs >= NUM_MBS_720P) div_factor = div_factor << 1; /* For targets that doesn't support 4k, consider max mb's for that From a06876ad7664835c925a6351e05af2ee5c3d15f6 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Tue, 4 Aug 2020 17:17:48 +0530 Subject: [PATCH 317/350] msm: vidc: Handle race condition for accessing session head During CVP internal session, CVP close done calls for session clean. session_clean API acquires the device lock and destroys the cvp hal_session. At the same time, if decoder session is also in the verge of close, since session_end does not have a device lock, there is high chance to access corrupted hal_session values. Change-Id: I34593e6507da9bad13c6d92faf40c4d790825d39 Signed-off-by: Priyanka Gujjula --- 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 7728d8e6d8a5..d7223d8287b3 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -2371,18 +2371,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 1b266d728ba8d9127d13511c8306d0a17b440576 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Mon, 3 Aug 2020 15:19:22 +0530 Subject: [PATCH 318/350] msm: vidc: Restrict secure buffer size optimization for higher resolution For secure usecase, video driver reduces the estimated size by half. This is done as secure decode spec is in general half of the non secure spec. As a result, the worst case size get half for secure mode. Based on this new restriction, the impact on buffer size would be for FWVGA and below = 6MB, which was earlier 3MB. CRs-Fixed: 2745960 Change-Id: I4a3be87e3f4beef7e8949cfb85e3341187e4b8b7 Signed-off-by: Vikash Garodia --- 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 74323724f4fa..c7af4a276421 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -929,7 +929,7 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) div_factor = 2; } - if (is_secure_session(inst)) + if (is_secure_session(inst) && num_mbs >= NUM_MBS_720P) div_factor = div_factor << 1; /* For targets that doesn't support 4k, consider max mb's for that From 941aefc924c634ee59ca9dc1403c410fc42c45d9 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Thu, 13 Aug 2020 15:46:50 +0530 Subject: [PATCH 319/350] msm: vidc: Optimize enc scratch and scratch_2 calc for >=8k Optimize the encoder scratch and scratch_2 buffer size calculations for >=(7680x4320) usecases. Change-Id: Ibefd6fa105c2dbecd5e163b52f68f14c39d5a100 Signed-off-by: Priyanka Gujjula --- 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 c7af4a276421..b0de7c16cc61 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -1423,7 +1423,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 >= 7680 * 4320) + size_singlePipe = bitbin_size / 4; + else if (num_vpp_pipes > 2) size_singlePipe = bitbin_size / 2; else size_singlePipe = bitbin_size; @@ -1831,7 +1833,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)); From 53c614981cdfb43a823e5a345874935b901c86d4 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 7 Sep 2020 12:16:15 +0530 Subject: [PATCH 320/350] msm: vidc: acquire lock for complete register sequence Register pkt is queued to firmware, and it is processed and register_done is getting called from reverse thread before buffer is added to list in forward thread. To avoid this race issue, acquired the cvpbuf.lock before posting register command to firmware. Signed-off-by: Govindaraj Rajagopal --- msm/vidc/msm_cvp_internal.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_cvp_internal.c b/msm/vidc/msm_cvp_internal.c index 48efca59d755..3432484ceaac 100644 --- a/msm/vidc/msm_cvp_internal.c +++ b/msm/vidc/msm_cvp_internal.c @@ -377,6 +377,7 @@ static int msm_cvp_register_buffer(struct msm_vidc_inst *inst, goto exit; } + mutex_lock(&inst->cvpbufs.lock); memset(&vbuf, 0, sizeof(struct vidc_register_buffer)); vbuf.index = buf->index; vbuf.type = get_hal_buftype(__func__, buf->type, inst->sid); @@ -388,9 +389,9 @@ static int msm_cvp_register_buffer(struct msm_vidc_inst *inst, (void *)inst->session, &vbuf); if (rc) { print_cvp_buffer(VIDC_ERR, "register failed", inst, cbuf); + mutex_unlock(&inst->cvpbufs.lock); goto exit; } - mutex_lock(&inst->cvpbufs.lock); list_add_tail(&cbuf->list, &inst->cvpbufs.list); mutex_unlock(&inst->cvpbufs.lock); return rc; From f5bd05d90d0561d9d1f43c3a686ef84fd16b346f Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Thu, 17 Sep 2020 17:42:15 +0530 Subject: [PATCH 321/350] 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. CRs-Fixed: 2759646 Change-Id: I0a0247e95bb040635c92404c5a342c92c340154c Signed-off-by: Vikash Garodia --- 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 56f8d0e08e57..c93865c44257 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -621,7 +621,7 @@ static struct msm_vidc_codec_capability bengal_capabilities_v0[] = { {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, 1, 512}, @@ -685,7 +685,7 @@ static struct msm_vidc_codec_capability bengal_capabilities_v1[] = { {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, 1, 512}, From 5a6c8f99e250e8484affcbc6ee1cf6c485f2e5db Mon Sep 17 00:00:00 2001 From: Malathi Gottam Date: Mon, 28 Sep 2020 22:19:18 +0530 Subject: [PATCH 322/350] 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 c7af4a276421..6f7ff954e28e 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -938,6 +938,8 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) 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; + if (num_mbs < NUM_MBS_720P) + base_res_mbs = base_res_mbs * 2; } frame_size = base_res_mbs * MB_SIZE_IN_PIXEL * 3 / 2 / div_factor; From 955a07f486e2bcc35511cddd67269171637bcf3b Mon Sep 17 00:00:00 2001 From: Malathi Gottam Date: Thu, 15 Oct 2020 16:33:27 +0530 Subject: [PATCH 323/350] 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 26e48d55ddbc..fbe9b9537202 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -935,7 +935,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; if (num_mbs < NUM_MBS_720P) From 83222df7212ad4c5bd5420dc19a5713a5f5cf274 Mon Sep 17 00:00:00 2001 From: Malathi Gottam Date: Thu, 15 Oct 2020 16:33:27 +0530 Subject: [PATCH 324/350] 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 26e48d55ddbc..fbe9b9537202 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -935,7 +935,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; if (num_mbs < NUM_MBS_720P) From 22f63c240e1fc88e65de7110a0d3b6b423db0f1d Mon Sep 17 00:00:00 2001 From: Uma Mehta Date: Wed, 21 Oct 2020 13:32:30 +0530 Subject: [PATCH 325/350] msm: vidc: change default step size change default step size for encoders on lito target to 2. Change-Id: I3775cbaa883c428db4bbfd95b63e4b33874f8ede Signed-off-by: Uma Mehta --- msm/vidc/msm_vidc_platform.c | 52 ++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index c93865c44257..3b97cc23dcd5 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -202,8 +202,10 @@ static struct msm_vidc_codec lagoon_codecs[] = { 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}, + {CAP_FRAME_WIDTH, DEC, CODECS_ALL, 96, 5760, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 5760, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, CODECS_ALL, 96, 5760, 2, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 96, 5760, 2, 1080}, /* ((5760 * 2880) / 256) */ {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 64800, 1, 8160}, /* ((3840x2176)/256)@60fps */ @@ -234,8 +236,10 @@ 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, 4096, 1, 1920}, - {CAP_FRAME_HEIGHT, ENC|DEC, VP8, 96, 4096, 1, 1080}, + {CAP_FRAME_WIDTH, DEC, VP8, 96, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, VP8, 96, 4096, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, VP8, 96, 4096, 2, 1920}, + {CAP_FRAME_HEIGHT, ENC, VP8, 96, 4096, 2, 1080}, /* (4096 * 2176) / 256 */ {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 36, 34816, 1, 8160}, /* (3840 * 2176) / 256) * 30*/ @@ -255,8 +259,10 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {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}, + {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, 96, 4096, 2, 1920}, + {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 96, 4096, 2, 1080}, /* (4096 * 2176) / 256 */ {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 34816, 1, 8160}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, @@ -270,10 +276,10 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { {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}, + {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 @@ -298,8 +304,10 @@ static struct msm_vidc_codec_capability lito_capabilities_v0[] = { 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}, + {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, 96, 4096, 2, 1920}, + {CAP_FRAME_HEIGHT, ENC, CODECS_ALL, 96, 4096, 2, 1080}, /* ((4096 * 2176) / 256) */ {CAP_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 34816, 1, 8160}, /* UHD@30 decode + 1080@30 encode */ @@ -330,8 +338,10 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {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}, + {CAP_FRAME_WIDTH, DEC, VP8, 96, 1920, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, VP8, 96, 1920, 1, 1080}, + {CAP_FRAME_WIDTH, ENC, VP8, 96, 1920, 2, 1920}, + {CAP_FRAME_HEIGHT, ENC, VP8, 96, 1920, 2, 1080}, /* (1920 * 1088) / 256 */ {CAP_MBS_PER_FRAME, ENC|DEC, VP8, 36, 8160, 1, 8160}, /* ((1920 * 1088) / 256) * 60*/ @@ -351,8 +361,10 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {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}, + {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, 96, 4096, 2, 1920}, + {CAP_SECURE_FRAME_HEIGHT, ENC, CODECS_ALL, 96, 4096, 2, 1080}, /* (4096 * 2176) / 256 */ {CAP_SECURE_MBS_PER_FRAME, DOMAINS_ALL, CODECS_ALL, 36, 34816, 1, 8160}, {CAP_SECURE_BITRATE, DOMAINS_ALL, CODECS_ALL, 1, 40000000, 1, 20000000}, @@ -366,10 +378,10 @@ static struct msm_vidc_codec_capability lito_capabilities_v1[] = { {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}, + {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 From 04d4d8400024bdaf0198ecc9e2e79abde0d9bfe3 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 14 Oct 2020 19:38:41 +0530 Subject: [PATCH 326/350] 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 | 58 ++++++++++++++++++++----- 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, 69 insertions(+), 32 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 0ad13a833435..80e8e00f3dd4 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1113,26 +1113,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 fbe9b9537202..6596cb16618b 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -324,7 +324,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); @@ -508,9 +509,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) { @@ -537,18 +539,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 calc are based on rotated wxh */ + 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; @@ -574,7 +588,8 @@ 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) { @@ -1809,8 +1824,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; @@ -1835,7 +1850,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)); @@ -1868,7 +1882,29 @@ 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; + } + 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 aligned for 8-bit + * and 192 x 16 aligned for 10-bit + */ + 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 a94bc485e32b..3525a4429080 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 21adfe4d560e..2619d1f89d41 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -693,6 +693,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 1c64e3ceeef9..a7e1cc23b50c 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -223,6 +223,7 @@ static inline bool is_valid_operating_rate(struct msm_vidc_inst *inst, s32 val) return true; } +bool vidc_scalar_enabled(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); From 7bb3f3fb0c3b794b82511ad80e3f58c0a2c83ec8 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Thu, 5 Nov 2020 21:11:27 +0530 Subject: [PATCH 327/350] msm: vidc: Inline driver HP num_ref calc with FW Update encoder num_ref_frames calculations for HIERP with FW calculations. Change-Id: Iad1deaf757a8aa3715b2dce861b1454faeed7a39 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_buffer_calculations.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index fbe9b9537202..90f3562e65cc 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -493,13 +493,13 @@ int msm_vidc_get_num_ref_frames(struct msm_vidc_inst *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); + 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 if ((codec == V4L2_PIX_FMT_H264) && (num_hp_layers < 4)) + num_ref = (num_hp_layers - 1) + ltr_count; else - num_ref = ((num_hp_layers + 1) / 2) + ltr_count; + num_ref = num_hp_layers + ltr_count; } return num_ref; } From a6ce5b5581f6ef4cb2c4de3837cda3a484445298 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Mon, 30 Nov 2020 19:31:33 +0530 Subject: [PATCH 328/350] 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 | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index fbe9b9537202..45f6a4d6192c 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -273,6 +273,7 @@ #define HFI_VENUS_HEIGHT_ALIGNMENT 32 #define SYSTEM_LAL_TILE10 192 +#define NUM_MBS_480P (((640 + 15) >> 4) * ((480 + 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) @@ -1004,8 +1005,9 @@ 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 resolution < 720p : YUVsize * 4 - * For resolution > 720p & <= 4K : YUVsize / 2 + * For CQ or heic session : YUVsize * 2 + * For resolution <= 480p : YUVsize * 2 + * For resolution > 480p & <= 4K : YUVsize / 2 * For resolution > 4k : YUVsize / 4 * Initially frame_size = YUVsize * 2; */ @@ -1018,24 +1020,29 @@ 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 (mbs_per_frame < NUM_MBS_720P) - frame_size = frame_size << 1; + 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_480P) + goto calc_done; /* Default frame_size = YUVsize * 2 */ 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)) + 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 a7472da220c82927fce030330b12cc23092b6416 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 14 Oct 2020 19:38:41 +0530 Subject: [PATCH 329/350] 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 | 58 ++++++++++++++++++++----- 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, 69 insertions(+), 32 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 0ad13a833435..80e8e00f3dd4 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -1113,26 +1113,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 fbe9b9537202..6596cb16618b 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -324,7 +324,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); @@ -508,9 +509,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) { @@ -537,18 +539,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 calc are based on rotated wxh */ + 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; @@ -574,7 +588,8 @@ 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) { @@ -1809,8 +1824,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; @@ -1835,7 +1850,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)); @@ -1868,7 +1882,29 @@ 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; + } + 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 aligned for 8-bit + * and 192 x 16 aligned for 10-bit + */ + 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 a94bc485e32b..3525a4429080 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 21adfe4d560e..2619d1f89d41 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -693,6 +693,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 1c64e3ceeef9..a7e1cc23b50c 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -223,6 +223,7 @@ static inline bool is_valid_operating_rate(struct msm_vidc_inst *inst, s32 val) return true; } +bool vidc_scalar_enabled(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); From 4e0a2b29983440af14e6f98e80bf76f174ef77d3 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Wed, 16 Dec 2020 17:55:42 +0530 Subject: [PATCH 330/350] 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 Signed-off-by: Priyanka Gujjula --- 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 50c4146075fc..8f480e554e23 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -492,10 +492,10 @@ int msm_vidc_get_num_ref_frames(struct msm_vidc_inst *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 (num_hp_layers > 1) { /* LTR and B - frame not supported with hybrid HP */ if (inst->hybrid_hp) - num_ref = num_hp_layers >> 1; + num_ref = (num_hp_layers + 1) >> 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)) From 33ad49349853f0b2e0474a5d594b3e0f8e45b05b Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Tue, 29 Dec 2020 21:22:58 +0530 Subject: [PATCH 331/350] msm: vidc: Update num_ref calculation for VP8 Vp8 follows default num_ref value 2 as per FW calculation. Change-Id: Ibb00a3db49d1467605e63abf681061a69ec8557f Signed-off-by: Priyanka Gujjula --- 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 8f480e554e23..a2d2aa35f700 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -477,6 +477,10 @@ int msm_vidc_get_num_ref_frames(struct msm_vidc_inst *inst) struct v4l2_ctrl *layer_ctrl; u32 codec; + codec = get_v4l2_codec(inst); + if (codec == V4L2_PIX_FMT_VP8) + num_ref = num_ref << 1; + bframe_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); num_bframes = bframe_ctrl->val; if (num_bframes > 0) @@ -491,7 +495,6 @@ int msm_vidc_get_num_ref_frames(struct msm_vidc_inst *inst) layer_ctrl = 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 > 1) { /* LTR and B - frame not supported with hybrid HP */ if (inst->hybrid_hp) From e3dbdab5325a4bdf347dcbad71db126e4a67d296 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Tue, 29 Dec 2020 21:22:58 +0530 Subject: [PATCH 332/350] msm: vidc: Update num_ref calculation for VP8 Vp8 follows default num_ref value 2 as per FW calculation. Change-Id: Ibb00a3db49d1467605e63abf681061a69ec8557f Signed-off-by: Priyanka Gujjula --- 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 8f480e554e23..a2d2aa35f700 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -477,6 +477,10 @@ int msm_vidc_get_num_ref_frames(struct msm_vidc_inst *inst) struct v4l2_ctrl *layer_ctrl; u32 codec; + codec = get_v4l2_codec(inst); + if (codec == V4L2_PIX_FMT_VP8) + num_ref = num_ref << 1; + bframe_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES); num_bframes = bframe_ctrl->val; if (num_bframes > 0) @@ -491,7 +495,6 @@ int msm_vidc_get_num_ref_frames(struct msm_vidc_inst *inst) layer_ctrl = 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 > 1) { /* LTR and B - frame not supported with hybrid HP */ if (inst->hybrid_hp) From f31d17c6e9f05cf77bd429615c8f6136838cfba0 Mon Sep 17 00:00:00 2001 From: "Mahesh Voorugonda(Temp)" Date: Tue, 19 Jan 2021 12:40:46 +0530 Subject: [PATCH 333/350] msm: vidc: increase max instance support to 24 Increase max video instances support from 16 to 24. Change-Id: Id21a6eb76640b5d97834d925aae4459ec19270d0 Signed-off-by: Mahesh Voorugonda(Temp) --- 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 8fdbf3434fca..363571997e90 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-2020, 2021 The Linux Foundation. All rights reserved. */ #ifndef _MSM_VIDC_INTERNAL_H_ @@ -47,7 +47,7 @@ #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 +#define MAX_SUPPORTED_INSTANCES 24 /* Maintains the number of FTB's between each FBD over a window */ #define DCVS_FTB_WINDOW 16 From aa1c413105ca879fdd52ce8ffe79126a44d1cd7e Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Tue, 23 Feb 2021 17:28:36 +0800 Subject: [PATCH 334/350] 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 Signed-off-by: Sanjay Singh --- msm/vidc/msm_venc.c | 7 +++++-- msm/vidc/msm_vidc_internal.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 80e8e00f3dd4..b68e83d41304 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-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #include #include "msm_venc.h" @@ -1205,6 +1205,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->hdr10_sei_enabled = false; return rc; } @@ -1699,6 +1700,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) { @@ -4383,7 +4385,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 363571997e90..bf1ec79fb0f2 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -551,6 +551,7 @@ struct msm_vidc_inst { bool static_rotation_flip_enabled; 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 65f83fc481b605a3222e8313e92987294f94e90b Mon Sep 17 00:00:00 2001 From: Pradosh Das Date: Thu, 4 Mar 2021 00:16:53 +0530 Subject: [PATCH 335/350] Revert "msm: vidc: increase max instance support to 24" This reverts commit f31d17c6e9f05cf77bd429615c8f6136838cfba0. Change-Id: I74a35afffcf646ceb1305baed61e43b19d62ee56 Signed-off-by: Pradosh Das --- 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 363571997e90..8fdbf3434fca 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, 2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef _MSM_VIDC_INTERNAL_H_ @@ -47,7 +47,7 @@ #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 24 +#define MAX_SUPPORTED_INSTANCES 16 /* Maintains the number of FTB's between each FBD over a window */ #define DCVS_FTB_WINDOW 16 From 67e04152d6eb7fbfaae884d22d9dad353433795a Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Tue, 23 Mar 2021 18:50:37 +0530 Subject: [PATCH 336/350] 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 2619d1f89d41..3bc3d5126f8a 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 @@ -6186,10 +6186,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 6f2e749e57c75ba11e065cde280a207847859f6e Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 7 Apr 2021 19:08:01 +0530 Subject: [PATCH 337/350] msm: vidc: Fix MBs per frame to derive slices per frame Video driver calculates MBs per frame considering per MB as 16x16. HEVC would have lcu size as 32 and hence per MB would be 32x32. As a result of this, MBs per slice is being set more. Since there is a limit of number of MBs feasible to get a slice within a tile, crossing the limit would eventually end up with no slices. Change-Id: I062655ac08b905c20afc913b99333365826fd2dd Signed-off-by: Vikash Garodia --- msm/vidc/msm_venc.c | 4 ++++ msm/vidc/msm_vidc_internal.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index b68e83d41304..02c924a5976b 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3208,6 +3208,10 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst) /* Update Slice Config */ mb_per_frame = NUM_MBS_PER_FRAME(output_height, output_width); + if (codec == V4L2_PIX_FMT_HEVC) + mb_per_frame = + NUM_MBS_PER_FRAME_HEVC(output_height, output_width); + mbps = NUM_MBS_PER_SEC(output_height, output_width, fps); if (slice_mode == HFI_MULTI_SLICE_BY_MB_COUNT) { diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index bf1ec79fb0f2..7bdcb88587c5 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -79,6 +79,9 @@ #define NUM_MBS_PER_FRAME(__height, __width) \ ((ALIGN(__height, 16) / 16) * (ALIGN(__width, 16) / 16)) +#define NUM_MBS_PER_FRAME_HEVC(__height, __width) \ + ((ALIGN(__height, 32) / 32) * (ALIGN(__width, 32) / 32)) + #define call_core_op(c, op, ...) \ (((c) && (c)->core_ops && (c)->core_ops->op) ? \ ((c)->core_ops->op(__VA_ARGS__)) : 0) From 390d6a9fc17653c1aa3adbda85875c275bb4c867 Mon Sep 17 00:00:00 2001 From: Sayantan Majumder Date: Thu, 8 Apr 2021 18:26:20 +0530 Subject: [PATCH 338/350] msm: vidc: enable 24 sessions for IOT specific targets Enabling 24 sessions only for IOT specific targets. Change-Id: Ifdb7cd99ba27f322bc201a44ca2fe0e808cb972a Signed-off-by: Sayantan Majumder --- msm/vidc/msm_v4l2_vidc.c | 9 ++++++++- msm/vidc/msm_vidc_common.c | 3 +-- 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 | 22 +++++++++++++++++++++- msm/vidc/msm_vidc_res_parse.c | 3 ++- 7 files changed, 63 insertions(+), 35 deletions(-) diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index 0fd761e87343..b8b70389d495 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 @@ -491,6 +491,11 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) core->platform_data = vidc_get_drv_data(&pdev->dev); dev_set_drvdata(&pdev->dev, core); + vidc_driver->ctxt = kcalloc(core->platform_data->max_inst_count, + sizeof(*vidc_driver->ctxt), GFP_KERNEL); + if (!vidc_driver->ctxt) + return -ENOMEM; + vidc_driver->num_ctxt = core->platform_data->max_inst_count; rc = msm_vidc_initialize_core(pdev, core); if (rc) { d_vpr_e("Failed to init core\n"); @@ -620,6 +625,7 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) err_core_init: dev_set_drvdata(&pdev->dev, NULL); kfree(core); + kfree(vidc_driver->ctxt); return rc; } @@ -701,6 +707,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 2619d1f89d41..b5798d3f6628 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 @@ -3074,7 +3074,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 e803269aa6bd..75b6d2e96e12 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_err_recovery_disable = !1; 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; @@ -611,16 +609,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) @@ -629,7 +627,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); } @@ -685,10 +683,10 @@ 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'; } diff --git a/msm/vidc/msm_vidc_debug.h b/msm/vidc/msm_vidc_debug.h index 7ddc7be76378..080b7f64c530 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__ @@ -69,13 +69,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; @@ -85,7 +78,6 @@ 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 struct log_cookie ctxt[MAX_SUPPORTED_INSTANCES]; #define dprintk(__level, sid, __fmt, ...) \ do { \ @@ -213,10 +205,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; @@ -224,21 +216,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 bf1ec79fb0f2..8ebad2652205 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -47,7 +47,8 @@ #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 24 +#define MAX_SUPPORTED_INSTANCES 16 +#define MAX_SUPPORTED_INSTANCES_24 24 /* Maintains the number of FTB's between each FBD over a window */ #define DCVS_FTB_WINDOW 16 @@ -300,6 +301,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 { @@ -326,6 +328,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; @@ -333,6 +342,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 3b97cc23dcd5..979c2254b19c 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 @@ -2054,6 +2054,10 @@ static const struct of_device_id msm_vidc_dt_match[] = { .compatible = "qcom,kona-vidc", .data = &kona_data, }, + { + .compatible = "qcom,qcs8250-vidc", + .data = &kona_data, + }, { .compatible = "qcom,sm6150-vidc", .data = &sm6150_data, @@ -2178,6 +2182,7 @@ void *vidc_get_drv_data(struct device *dev) goto exit; } + driver_data->max_inst_count = MAX_SUPPORTED_INSTANCES; if (!strcmp(match->compatible, "qcom,sdm670-vidc")) { if (driver_data->sku_version == SKU_VERSION_1) { driver_data->common_data = sdm670_common_data_v1; @@ -2205,6 +2210,21 @@ 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,qcs8250-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); + + driver_data->max_inst_count = MAX_SUPPORTED_INSTANCES_24; } else if (!strcmp(match->compatible, "qcom,bengal-vidc")) { rc = msm_vidc_read_rank(driver_data, dev); if (rc) { diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 1b9e9942cb44..2f84f960f2f6 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 @@ -846,6 +846,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 b91b91bea5a37fc0f1de84e51fc3b3578986b66c Mon Sep 17 00:00:00 2001 From: Mahesh Voorugonda Date: Tue, 27 Apr 2021 15:54:39 +0530 Subject: [PATCH 339/350] msm: vidc: Fix possible NULL pointer dereference Added NULL pointer check for platform_data structure to avoid NULL pointer dereference error. platform_data is initialized with return value (driver_data) of vidc_get_drv_data() fucntion where driver_data is initialized with NULL pointer at the beginning. Change-Id: I24743cc6ed7ffcfa40feca2307c9b1728b5bc152 Signed-off-by: Mahesh Voorugonda --- msm/vidc/msm_v4l2_vidc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index 0fd761e87343..161661b2cc4f 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 @@ -490,6 +490,11 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) return -ENOMEM; core->platform_data = vidc_get_drv_data(&pdev->dev); + if(!core->platform_data) { + d_vpr_e("Failed to get platform data\n"); + rc = -EINVAL; + goto err_core_init; + } dev_set_drvdata(&pdev->dev, core); rc = msm_vidc_initialize_core(pdev, core); if (rc) { From 722eb72b144c6db816a220363de4dc7ce78bad7e Mon Sep 17 00:00:00 2001 From: Sanjay Singh Date: Fri, 4 Jun 2021 14:17:28 +0530 Subject: [PATCH 340/350] msm: vidc: Increase 10-bit enc o/p buffer size for <=480p Increase 10-bit enc bistream buffer size for <=480p. 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 Signed-off-by: Sanjay Singh --- 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 a2d2aa35f700..1382255e8a98 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-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. */ #include "msm_vidc_debug.h" @@ -1043,7 +1043,7 @@ u32 msm_vidc_calculate_enc_output_frame_size(struct msm_vidc_inst *inst) goto calc_done; if (mbs_per_frame <= NUM_MBS_480P) - 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 27205f81ba6ac843c462de21865455073381c4d4 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Wed, 19 May 2021 18:21:44 +0530 Subject: [PATCH 341/350] msm: vidc: Initialize max instances count For various video platform data, initialize it with the default count of 16. For specific platform, the same can be overwritten to desired value. Change-Id: I8a0ebe8a4dea4b1ea30028e170992e70cd6d835b Signed-off-by: Vikash Garodia --- msm/vidc/msm_vidc_platform.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index 979c2254b19c..90a63ec710bd 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -1879,6 +1879,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 lito_data = { @@ -1899,6 +1900,7 @@ static struct msm_vidc_platform_data lito_data = { .codecs_count = ARRAY_SIZE(default_codecs), .codec_caps = lito_capabilities_v0, .codec_caps_count = ARRAY_SIZE(lito_capabilities_v0), + .max_inst_count = MAX_SUPPORTED_INSTANCES, }; static struct msm_vidc_platform_data kona_data = { @@ -1919,6 +1921,7 @@ static struct msm_vidc_platform_data kona_data = { .codecs_count = ARRAY_SIZE(default_codecs), .codec_caps = kona_capabilities, .codec_caps_count = ARRAY_SIZE(kona_capabilities), + .max_inst_count = MAX_SUPPORTED_INSTANCES, }; static struct msm_vidc_platform_data lagoon_data = { @@ -1939,6 +1942,7 @@ static struct msm_vidc_platform_data lagoon_data = { .codecs_count = ARRAY_SIZE(lagoon_codecs), .codec_caps = lagoon_capabilities_v0, .codec_caps_count = ARRAY_SIZE(lagoon_capabilities_v0), + .max_inst_count = MAX_SUPPORTED_INSTANCES, }; static struct msm_vidc_platform_data sm6150_data = { @@ -1955,6 +1959,7 @@ static struct msm_vidc_platform_data sm6150_data = { .vpu_ver = VPU_VERSION_AR50, .num_vpp_pipes = 0x1, .ubwc_config = 0x0, + .max_inst_count = MAX_SUPPORTED_INSTANCES, }; static struct msm_vidc_platform_data bengal_data = { @@ -1975,6 +1980,7 @@ 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), + .max_inst_count = MAX_SUPPORTED_INSTANCES, }; static struct msm_vidc_platform_data scuba_data = { @@ -1995,6 +2001,7 @@ static struct msm_vidc_platform_data scuba_data = { .codecs_count = ARRAY_SIZE(scuba_codecs), .codec_caps = scuba_capabilities, .codec_caps_count = ARRAY_SIZE(scuba_capabilities), + .max_inst_count = MAX_SUPPORTED_INSTANCES, }; static struct msm_vidc_platform_data sm8150_data = { @@ -2011,6 +2018,7 @@ static struct msm_vidc_platform_data sm8150_data = { .vpu_ver = VPU_VERSION_IRIS1, .num_vpp_pipes = 0x2, .ubwc_config = 0x0, + .max_inst_count = MAX_SUPPORTED_INSTANCES, }; static struct msm_vidc_platform_data sdm845_data = { @@ -2027,6 +2035,7 @@ static struct msm_vidc_platform_data sdm845_data = { .vpu_ver = VPU_VERSION_AR50, .num_vpp_pipes = 0x1, .ubwc_config = 0x0, + .max_inst_count = MAX_SUPPORTED_INSTANCES, }; static struct msm_vidc_platform_data sdm670_data = { @@ -2043,6 +2052,7 @@ static struct msm_vidc_platform_data sdm670_data = { .vpu_ver = VPU_VERSION_AR50, .num_vpp_pipes = 0x1, .ubwc_config = 0x0, + .max_inst_count = MAX_SUPPORTED_INSTANCES, }; static const struct of_device_id msm_vidc_dt_match[] = { @@ -2182,7 +2192,6 @@ void *vidc_get_drv_data(struct device *dev) goto exit; } - driver_data->max_inst_count = MAX_SUPPORTED_INSTANCES; if (!strcmp(match->compatible, "qcom,sdm670-vidc")) { if (driver_data->sku_version == SKU_VERSION_1) { driver_data->common_data = sdm670_common_data_v1; From bfbb4c1ac82c05e51630d434ddffbaad9d731e5d Mon Sep 17 00:00:00 2001 From: Sayantan Majumder Date: Thu, 8 Apr 2021 18:26:20 +0530 Subject: [PATCH 342/350] msm: vidc: enabling dynamic session context for IOT specific targets Enabling dynamic session context only for IOT specific targets. Change-Id: I465d28ef50dfe493fc4f11b9e40ef9231a57ad9a Signed-off-by: Sayantan Majumder --- msm/vidc/msm_v4l2_vidc.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index dda23429e601..5f6a82acd47f 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -496,11 +496,6 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) goto err_core_init; } dev_set_drvdata(&pdev->dev, core); - vidc_driver->ctxt = kcalloc(core->platform_data->max_inst_count, - sizeof(*vidc_driver->ctxt), GFP_KERNEL); - if (!vidc_driver->ctxt) - return -ENOMEM; - vidc_driver->num_ctxt = core->platform_data->max_inst_count; rc = msm_vidc_initialize_core(pdev, core); if (rc) { d_vpr_e("Failed to init core\n"); @@ -514,6 +509,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"); @@ -626,11 +627,12 @@ 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); kfree(core); - kfree(vidc_driver->ctxt); return rc; } From e5c1ae80cabf566753583730dc3f6ba109964032 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 16 Jul 2021 21:44:33 +0530 Subject: [PATCH 343/350] 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 Signed-off-by: Vikash Garodia --- msm/vidc/hfi_common.c | 49 ++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index d7223d8287b3..ae412f28cf88 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 @@ -990,20 +990,22 @@ 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; - uint64_t ab = 0; + uint64_t ab = 0, ib = 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); + ab = ab_kbps * 1000; + ib = ib_kbps * 1000; + s_vpr_p(sid, "Voting bus %s to ab %llu ib %llu bps\n", + bus->name, ab, ib); + rc = msm_bus_scale_update_bw(bus->client, ab, ib); if (rc) - s_vpr_e(sid, "Failed voting bus %s to ab %llu, rc=%d\n", - bus->name, ab, rc); - + s_vpr_e(sid, + "Failed voting bus %s to ab %llu ib %llu bps rc=%d\n", + bus->name, ab, ib, rc); return rc; } @@ -1015,7 +1017,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; } @@ -1029,7 +1031,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) { @@ -1037,33 +1039,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 5f86b4121c564532b6e5456920e200f9d68b4170 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 24 Sep 2021 14:13:40 +0530 Subject: [PATCH 344/350] msm: vdec: Update power resources with updated operating rate Client may choose to configure the session to TURBO mode and reset it on per frame basis. For such clients, video driver need not wait for next buffer to scale the power resources. Doing so, it would lead to a case of high power during the time video hardware remains idle after processing a frame. Update the video power resource in alignment with operating rate to achieve power benefits. Change-Id: I521ef569cb1ca9287b9b5627d90daacc2051082d Signed-off-by: Vikash Garodia --- msm/vidc/msm_cvp_internal.c | 6 ++--- msm/vidc/msm_vdec.c | 11 ++++++++- msm/vidc/msm_vidc_clocks.c | 45 ++++++++++++++++++++++++++----------- msm/vidc/msm_vidc_clocks.h | 7 +++--- 4 files changed, 49 insertions(+), 20 deletions(-) diff --git a/msm/vidc/msm_cvp_internal.c b/msm/vidc/msm_cvp_internal.c index 3432484ceaac..82fc710a9644 100644 --- a/msm/vidc/msm_cvp_internal.c +++ b/msm/vidc/msm_cvp_internal.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ #include "msm_cvp_internal.h" @@ -233,14 +233,14 @@ static int msm_cvp_scale_clocks_and_bus(struct msm_vidc_inst *inst) return -EINVAL; } - rc = msm_vidc_set_clocks(inst->core, inst->sid); + rc = msm_vidc_set_clocks(inst->core, inst->sid, false); 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); + rc = msm_comm_vote_bus(inst, false); if (rc) { s_vpr_e(inst->sid, "%s: failed vote_bus for inst %pK\n", __func__, inst); diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 54923e18b3a0..7b7b52cba75e 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-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #include @@ -927,6 +927,15 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: if (!is_valid_operating_rate(inst, ctrl->val)) break; + /* + * reset the resources like clock and bus as per the updated + * flag. When switch from TURBO to normal, need not wait for + * next qbuf to scale down the resources. + */ + if ((inst->flags & VIDC_TURBO) && (ctrl->val != INT_MAX)) { + inst->flags &= ~VIDC_TURBO; + msm_comm_reset_clocks_and_bus(inst); + } inst->flags &= ~VIDC_TURBO; if (ctrl->val == INT_MAX) inst->flags |= VIDC_TURBO; diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 5fdfe530d608..f06ace0f4592 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-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #include "msm_vidc_common.h" @@ -274,7 +274,7 @@ static int fill_dynamic_stats(struct msm_vidc_inst *inst, return 0; } -int msm_comm_set_buses(struct msm_vidc_core *core, u32 sid) +int msm_comm_set_buses(struct msm_vidc_core *core, u32 sid, bool force_reset) { int rc = 0; struct msm_vidc_inst *inst = NULL; @@ -306,7 +306,7 @@ int msm_comm_set_buses(struct msm_vidc_core *core, u32 sid) } mutex_unlock(&inst->registeredbufs.lock); - if ((!filled_len || !device_addr) && + if ((!filled_len || !device_addr) && !force_reset && (inst->session_type != MSM_VIDC_CVP)) { s_vpr_l(sid, "%s: no input\n", __func__); continue; @@ -333,7 +333,7 @@ int msm_comm_set_buses(struct msm_vidc_core *core, u32 sid) return rc; } -int msm_comm_vote_bus(struct msm_vidc_inst *inst) +int msm_comm_vote_bus(struct msm_vidc_inst *inst, bool force_reset) { int rc = 0; struct msm_vidc_core *core; @@ -368,7 +368,7 @@ int msm_comm_vote_bus(struct msm_vidc_inst *inst) } mutex_unlock(&inst->registeredbufs.lock); - if ((!filled_len || !device_addr) && + if ((!filled_len || !device_addr) && !force_reset && (inst->session_type != MSM_VIDC_CVP)) { s_vpr_l(inst->sid, "%s: no input\n", __func__); return 0; @@ -457,7 +457,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, inst->sid); + rc = msm_comm_set_buses(core, inst->sid, force_reset); return rc; } @@ -877,7 +877,7 @@ static unsigned long msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, return (unsigned long) freq; } -int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid) +int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid, bool force_reset) { struct hfi_device *hdev; unsigned long freq_core_1 = 0, freq_core_2 = 0, rate = 0; @@ -915,7 +915,7 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid) } mutex_unlock(&inst->registeredbufs.lock); - if (!filled_len || !device_addr) { + if ((!filled_len || !device_addr) && !force_reset) { s_vpr_l(sid, "%s: no input\n", __func__); continue; } @@ -988,7 +988,7 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid) return rc; } -int msm_comm_scale_clocks(struct msm_vidc_inst *inst) +int msm_comm_scale_clocks(struct msm_vidc_inst *inst, bool force_reset) { struct msm_vidc_buffer *temp, *next; unsigned long freq = 0; @@ -1013,7 +1013,7 @@ int msm_comm_scale_clocks(struct msm_vidc_inst *inst) } mutex_unlock(&inst->registeredbufs.lock); - if (!filled_len || !device_addr) { + if ((!filled_len || !device_addr) && !force_reset) { s_vpr_l(inst->sid, "%s: no input\n", __func__); return 0; } @@ -1032,7 +1032,7 @@ int msm_comm_scale_clocks(struct msm_vidc_inst *inst) msm_dcvs_scale_clocks(inst, freq); } - msm_vidc_set_clocks(inst->core, inst->sid); + msm_vidc_set_clocks(inst->core, inst->sid, force_reset); return 0; } @@ -1055,13 +1055,13 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc) inst->active = true; } - if (msm_comm_scale_clocks(inst)) { + if (msm_comm_scale_clocks(inst, false)) { s_vpr_e(inst->sid, "Failed to scale clocks. May impact performance\n"); } if (do_bw_calc) { - if (msm_comm_vote_bus(inst)) { + if (msm_comm_vote_bus(inst, false)) { s_vpr_e(inst->sid, "Failed to scale DDR bus. May impact perf\n"); } @@ -1070,6 +1070,25 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc) return 0; } +int msm_comm_reset_clocks_and_bus(struct msm_vidc_inst *inst) +{ + if (!inst) { + d_vpr_e("%s: invalid params %pK\n", __func__, inst); + return -EINVAL; + } + + if (msm_comm_scale_clocks(inst, true)) { + s_vpr_e(inst->sid, + "Failed to reset clocks. May impact performance\n"); + } + + if (msm_comm_vote_bus(inst, true)) { + s_vpr_e(inst->sid, + "Failed to reset DDR bus. May impact perf\n"); + } + return 0; +} + int msm_dcvs_try_enable(struct msm_vidc_inst *inst) { bool disable_hfr_dcvs = false; diff --git a/msm/vidc/msm_vidc_clocks.h b/msm/vidc/msm_vidc_clocks.h index 7515a4b49d68..0cb30379b5fb 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-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ #ifndef _MSM_VIDC_CLOCKS_H_ @@ -9,8 +9,8 @@ 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_vidc_set_clocks(struct msm_vidc_core *core, u32 sid, bool force_reset); +int msm_comm_vote_bus(struct msm_vidc_inst *inst, bool force_reset); 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); @@ -21,6 +21,7 @@ bool res_is_greater_than_or_equal_to(u32 width, u32 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, bool do_bw_calc); +int msm_comm_reset_clocks_and_bus(struct msm_vidc_inst *inst); int msm_comm_init_clocks_and_bus_data(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); From aa2310c7bed07019f5a1f6a91a4ffce372d28959 Mon Sep 17 00:00:00 2001 From: Vasantha Balla Date: Sat, 16 Oct 2021 12:19:46 +0530 Subject: [PATCH 345/350] msm: vidc: Queue buffers till max batch size in decode batching As per current decoder batching logic, output buffers are queued only till it finds current buffer in registered buffer list. If current buffer is registered long back and its reference has not yet come from firmware, it will stop queuing other deferred buffers in batching which causes firmware to starve for output buffers. So change is added to queue buffers till max batch size. Change-Id: Ie688fa260aa0f900e7d199df00fb44d34f917345 --- msm/vidc/msm_vidc_common.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 358cce8f55a5..207908b7c94e 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -4826,6 +4826,7 @@ int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, int rc = 0; struct msm_vidc_buffer *buf; int do_bw_calc = 0; + int num_buffers_queued = 0; do_bw_calc = mbuf ? mbuf->vvb.vb2_buf.type == INPUT_MPLANE : 0; rc = msm_comm_scale_clocks_and_bus(inst, do_bw_calc); @@ -4851,10 +4852,13 @@ int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, __func__, rc); break; } + num_buffers_queued++; loop_end: - /* Queue pending buffers till the current buffer only */ - if (buf == mbuf) + /* Queue pending buffers till batch size */ + if (num_buffers_queued == inst->batch.size) { + s_vpr_e(inst->sid, "%s: Queue buffers till batch size\n"); break; + } } mutex_unlock(&inst->registeredbufs.lock); From 82f00c04cac26f80072132f53f82847282b39cf8 Mon Sep 17 00:00:00 2001 From: Vasantha Balla Date: Mon, 15 Nov 2021 23:25:17 +0530 Subject: [PATCH 346/350] msm: vidc: Allow NRT session above max load Allow session even if load > max load for NRT session. Change-Id: Ie56a301a72d8af30af19918b817e6903ac005374 Signed-off-by: Vasantha Balla --- msm/vidc/msm_vidc_clocks.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 5fdfe530d608..e23055f4e4e3 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1751,8 +1751,12 @@ int msm_vidc_decide_core_and_power_mode_iris1(struct msm_vidc_inst *inst) 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; + if (!is_realtime_session(inst)) { + s_vpr_h(inst->sid, "Supporting NRT session"); + } else { + s_vpr_e(inst->sid, "Core cannot support this load\n"); + return -EINVAL; + } } inst->clk_data.core_id = VIDC_CORE_ID_1; From 9dd3d3e874fcf955751b45809f98c9e7f1ad05a8 Mon Sep 17 00:00:00 2001 From: Vasantha Balla Date: Fri, 17 Dec 2021 14:48:52 +0530 Subject: [PATCH 347/350] msm: vidc: Add clock/bus votes for eos/flush commands If voting is not added for eos and flush command processing, Firmware is processing only high priority session commands which causes non real time session to wait for completion of realtime session for its eos processing. So adding votes for eos and flush commands. Change-Id: I9de8c1d0dc79e93d991d34d2d687e2fa1910531b Signed-off-by: Vasantha Balla --- msm/vidc/msm_vidc_clocks.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 5fdfe530d608..fda08711e599 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -309,7 +309,15 @@ int msm_comm_set_buses(struct msm_vidc_core *core, u32 sid) if ((!filled_len || !device_addr) && (inst->session_type != MSM_VIDC_CVP)) { s_vpr_l(sid, "%s: no input\n", __func__); - continue; + mutex_lock(&inst->eosbufs.lock); + if (list_empty(&inst->eosbufs.list) && + !inst->in_flush && !inst->out_flush) { + s_vpr_l(sid, "%s:No pending eos/flush cmds\n", + __func__); + mutex_unlock(&inst->eosbufs.lock); + continue; + } + mutex_unlock(&inst->eosbufs.lock); } /* skip inactive session bus bandwidth */ @@ -917,7 +925,15 @@ int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid) if (!filled_len || !device_addr) { s_vpr_l(sid, "%s: no input\n", __func__); - continue; + mutex_lock(&inst->eosbufs.lock); + if (list_empty(&inst->eosbufs.list) && !inst->in_flush + && !inst->out_flush) { + s_vpr_l(sid, "%s:No pending eos/flush cmds\n", + __func__); + mutex_unlock(&inst->eosbufs.lock); + continue; + } + mutex_unlock(&inst->eosbufs.lock); } /* skip inactive session clock rate */ From 4e1052e87a79791f8d263ba152cfe5c9158313f0 Mon Sep 17 00:00:00 2001 From: Vasantha Balla Date: Tue, 28 Dec 2021 15:10:48 +0530 Subject: [PATCH 348/350] msm: vidc: Update log level for debug print Log level is changed for debug print to use correct log level. Change-Id: I973972c7407ec9eb12c133ca2964ea950e4cf5ea Signed-off-by: Vasantha Balla --- 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 207908b7c94e..9872a3e05800 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -4856,7 +4856,7 @@ int msm_comm_qbufs_batch(struct msm_vidc_inst *inst, loop_end: /* Queue pending buffers till batch size */ if (num_buffers_queued == inst->batch.size) { - s_vpr_e(inst->sid, "%s: Queue buffers till batch size\n"); + s_vpr_l(inst->sid, "Queue buffers till batch size\n"); break; } } From 97a944da4cef072c15b63d5d5dac0cecbcb92381 Mon Sep 17 00:00:00 2001 From: Anand Abhishek Date: Tue, 6 Sep 2022 17:29:05 +0530 Subject: [PATCH 349/350] msm: vidc: Enable intra cyclic refresh Refresh rate is hardcoded to random. This change allows to set user configured refresh rate. Change-Id: I572a400551b59105c221b77f6028cb9d9d1652b8 Signed-off-by: Anand Abhishek --- 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 02c924a5976b..5fc5bc6b0a35 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -3277,7 +3277,6 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst) inst->rc_type == 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); @@ -3296,6 +3295,7 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst) } else { ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB); + intra_refresh.mode = HFI_INTRA_REFRESH_CYCLIC; intra_refresh.mbs = ctrl->val; } if (!intra_refresh.mbs) { From 677a59787a3ca90f7e7f72c98a7cde35700c85e2 Mon Sep 17 00:00:00 2001 From: Anand Abhishek Date: Mon, 5 Sep 2022 18:35:36 +0530 Subject: [PATCH 350/350] msm: vidc: Update maximum supported slice count Change the slice from 10 to 128 for Byte and MB mode Change-Id: If5c81917089e5ca5514bc301b37db9e5b9bb018c Signed-off-by: Anand Abhishek --- 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 90a63ec710bd..4da338b15612 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -820,9 +820,9 @@ static struct msm_vidc_codec_capability kona_capabilities[] = { {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}, + /* 128 slices */ + {CAP_SLICE_BYTE, ENC, H264|HEVC, 1, 128, 1, 10}, + {CAP_SLICE_MB, ENC, H264|HEVC, 1, 128, 1, 10}, {CAP_MAX_VIDEOCORES, DOMAINS_ALL, CODECS_ALL, 0, 1, 1, 1}, /* VP8 specific */