Эх сурвалжийг харах

Fast Forward video driver project video-kernel.lnx.1.0' into video-kernel.lnx.4.0

* origin/video-kernel.lnx.1.0:
  video: driver: allow turbo for av1 and concurrent sessions
  video: driver: Modify Min QP in CAP_TO_8BIT_QP macro
  video: driver: Modify Min QP for 8 and 10 bit usecase
  video: driver: fix possible memory corruption issue
  video: Allow slice configuration for VBR
  video: driver: buffer tracing changes
  video: driver: fix order of fence node delete and put
  video: driver: fix faulty msm_vidc_vmem_alloc() failures
  video: driver: vp9 1080p decoder needs to reach 180fps
  video: driver: update bitstream buffer size calculation
  video: driver: initialize local variables
  video: use DLKM flag instead of QMAA flag to compile driver
  video: driver: Calculate AV1 VSP cycles using perf model
  video: driver: fix for initial input_rate calculation
  video: driver: Add missing capabilites
  video: driver: Adjust bandwidth votes for AV1 film grain
  video: driver: Optimize HEVC Bin buffer allocation
  video: driver:  Use max bitrate depending upon session
  video-driver: add to support DolbyVision metadata
  video: driver: fix slice mode support
  video: driver: introduce lock for set & get volatile controls
  video: driver: fix incorrect crop resolution
  video: driver: Use vzalloc instead of kzalloc
  video: driver: introduce client lock
  video-driver: Add support for subframe_input
  video: driver: Optimize encoder bin buffer size
  driver: video: Remove calls to power features during priority handling
  video: driver: Fix realtime load calculation
  video: driver: Add Complexity vs. Operating Rate handling
  video: driver: support upto level 6.2 for AVC and HEVC dec
  video: driver: enable transcode stat for decoder
  video: driver: Create and use single spin lock for dma fence

Change-Id: I167e6c6347d478cdb7435b3574a5b839b60c49c7
Tanya Kashyap(Temp) 3 жил өмнө
parent
commit
111e2c9603
33 өөрчлөгдсөн 847 нэмэгдсэн , 383 устгасан
  1. 5 4
      Android.mk
  2. 6 5
      driver/platform/common/src/msm_vidc_platform.c
  3. 86 16
      driver/platform/kalama/src/msm_vidc_kalama.c
  4. 77 24
      driver/platform/waipio/src/msm_vidc_waipio.c
  5. 18 13
      driver/variant/iris3/inc/hfi_buffer_iris3.h
  6. 44 6
      driver/variant/iris3/src/msm_vidc_buffer_iris3.c
  7. 21 5
      driver/variant/iris3/src/msm_vidc_iris3.c
  8. 86 27
      driver/variant/iris3/src/msm_vidc_power_iris3.c
  9. 6 0
      driver/vidc/inc/hfi_property.h
  10. 2 0
      driver/vidc/inc/msm_vidc_buffer.h
  11. 4 0
      driver/vidc/inc/msm_vidc_driver.h
  12. 1 0
      driver/vidc/inc/msm_vidc_inst.h
  13. 16 5
      driver/vidc/inc/msm_vidc_internal.h
  14. 2 1
      driver/vidc/inc/msm_vidc_memory.h
  15. 1 0
      driver/vidc/src/msm_vdec.c
  16. 2 5
      driver/vidc/src/msm_venc.c
  17. 11 11
      driver/vidc/src/msm_vidc.c
  18. 28 6
      driver/vidc/src/msm_vidc_buffer.c
  19. 87 47
      driver/vidc/src/msm_vidc_control.c
  20. 13 18
      driver/vidc/src/msm_vidc_debug.c
  21. 126 81
      driver/vidc/src/msm_vidc_driver.c
  22. 10 10
      driver/vidc/src/msm_vidc_dt.c
  23. 10 28
      driver/vidc/src/msm_vidc_fence.c
  24. 31 7
      driver/vidc/src/msm_vidc_memory.c
  25. 9 0
      driver/vidc/src/msm_vidc_power.c
  26. 18 22
      driver/vidc/src/msm_vidc_probe.c
  27. 48 0
      driver/vidc/src/msm_vidc_v4l2.c
  28. 31 20
      driver/vidc/src/msm_vidc_vb2.c
  29. 3 5
      driver/vidc/src/venus_hfi.c
  30. 24 9
      driver/vidc/src/venus_hfi_response.c
  31. 11 0
      include/uapi/vidc/media/v4l2_vidc_extensions.h
  32. 5 4
      video_kernel_board.mk
  33. 5 4
      video_kernel_product.mk

+ 5 - 4
Android.mk

@@ -1,9 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0-only
 TARGET_VIDC_ENABLE := false
-ifeq ($(TARGET_USES_QMAA),false)
-TARGET_VIDC_ENABLE := true
-endif
-ifeq ($(TARGET_USES_QMAA_OVERRIDE_VIDEO),true)
+ifeq ($(TARGET_KERNEL_DLKM_DISABLE), true)
+	ifeq ($(TARGET_KERNEL_DLKM_VIDEO_OVERRIDE), true)
+		TARGET_VIDC_ENABLE := true
+	endif
+else
 TARGET_VIDC_ENABLE := true
 endif
 

+ 6 - 5
driver/platform/common/src/msm_vidc_platform.c

@@ -342,14 +342,14 @@ int msm_vidc_deinit_platform(struct platform_device *pdev)
 	msm_vidc_deinit_vpu(core, &pdev->dev);
 	msm_vidc_deinit_platform_variant(core, &pdev->dev);
 
-	kfree(core->platform);
+	msm_vidc_vmem_free((void **)&core->platform);
 	return 0;
 }
 
 int msm_vidc_init_platform(struct platform_device *pdev)
 {
 	int rc = 0;
-	struct msm_vidc_platform *platform;
+	struct msm_vidc_platform *platform = NULL;
 	struct msm_vidc_core *core;
 
 	if (!pdev) {
@@ -366,9 +366,10 @@ int msm_vidc_init_platform(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	platform = kzalloc(sizeof(struct msm_vidc_platform), GFP_KERNEL);
-	if (!platform)
-		return -ENOMEM;
+	rc = msm_vidc_vmem_alloc(sizeof(struct msm_vidc_platform),
+			(void **)&platform, __func__);
+	if (rc)
+		return rc;
 
 	core->platform = platform;
 	platform->core = core;

+ 86 - 16
driver/platform/kalama/src/msm_vidc_kalama.c

@@ -19,12 +19,10 @@
 #define MAX_LTR_FRAME_COUNT     2
 #define MAX_BASE_LAYER_PRIORITY_ID 63
 #define MAX_OP_POINT            31
-#define MAX_BITRATE             220000000
+#define MAX_BITRATE             245000000
 #define DEFAULT_BITRATE         20000000
 #define MINIMUM_FPS             1
 #define MAXIMUM_FPS             480
-#define MIN_QP_10BIT            -12
-#define MIN_QP_8BIT             0
 #define MAX_QP                  51
 #define DEFAULT_QP              20
 #define MAX_CONSTANT_QUALITY    100
@@ -42,7 +40,7 @@
 #define AV1     MSM_VIDC_AV1
 #define HEIC    MSM_VIDC_HEIC
 #define CODECS_ALL     (H264 | HEVC | VP9 | HEIC | AV1)
-#define MAXIMUM_OVERRIDE_VP9_FPS 120
+#define MAXIMUM_OVERRIDE_VP9_FPS 180
 
 static struct msm_platform_core_capability core_data_kalama[] = {
 	/* {type, value} */
@@ -66,7 +64,7 @@ static struct msm_platform_core_capability core_data_kalama[] = {
 	{MAX_MBPS_HQ, 489600}, /* ((1920x1088)/256)@60fps */
 	{MAX_MBPF_B_FRAME, 32640}, /* 3840x2176/256 */
 	{MAX_MBPS_B_FRAME, 1958400}, /* 3840x2176/256 MBs@60fps */
-	{MAX_MBPS_ALL_INTRA, 1958400}, /* 3840x2176/256 MBs@60fps */
+	{MAX_MBPS_ALL_INTRA, 2088960}, /* 4096x2176/256 MBs@60fps */
 	{MAX_ENH_LAYER_COUNT, 5},
 	{NUM_VPP_PIPE, 4},
 	{SW_PC, 1},
@@ -320,6 +318,10 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
 
 	{MB_CYCLES_FW_VPP, DEC, CODECS_ALL, 66234, 66234, 1, 66234},
 
+	{CLIENT_ID, ENC|DEC, CODECS_ALL,
+		INVALID_CLIENT_ID, INT_MAX, 1, INVALID_CLIENT_ID,
+		V4L2_CID_MPEG_VIDC_CLIENT_ID},
+
 	{SECURE_MODE, ENC|DEC, H264|HEVC|VP9|AV1,
 		V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE,
 		1, V4L2_MPEG_MSM_VIDC_DISABLE,
@@ -483,6 +485,18 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
 		HFI_PROP_RATE_CONTROL,
 		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU},
 
+	{CABAC_MAX_BITRATE, ENC, H264|HEVC, 0,
+		160000000, 1, 160000000},
+
+	{CAVLC_MAX_BITRATE, ENC, H264, 0,
+		220000000, 1, 220000000},
+
+	{ALLINTRA_MAX_BITRATE, ENC, H264|HEVC, 0,
+		245000000, 1, 245000000},
+
+	{LOWLATENCY_MAX_BITRATE, ENC, H264|HEVC, 0,
+		70000000, 1, 70000000},
+
 	{LOSSLESS, ENC, HEVC,
 		V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE,
 		1, V4L2_MPEG_MSM_VIDC_DISABLE,
@@ -1084,7 +1098,8 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
 		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
 		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
 		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) |
-		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1),
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2),
 		V4L2_MPEG_VIDEO_H264_LEVEL_6_1,
 		V4L2_CID_MPEG_VIDEO_H264_LEVEL,
 		HFI_PROP_LEVEL,
@@ -1104,7 +1119,8 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
 		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1) |
 		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2) |
 		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6) |
-		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1),
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1)|
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2),
 		V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1,
 		V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
 		HFI_PROP_LEVEL,
@@ -1234,14 +1250,23 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
 		0,
 		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU},
 
-	{SLICE_MAX_BYTES, ENC, H264|HEVC|HEIC,
+	{SLICE_MODE, ENC, HEIC,
+		V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
+		V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
+		BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE),
+		V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
+		V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
+		0,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU},
+
+	{SLICE_MAX_BYTES, ENC, H264|HEVC,
 		MIN_SLICE_BYTE_SIZE, MAX_SLICE_BYTE_SIZE,
 		1, MIN_SLICE_BYTE_SIZE,
 		V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
 		HFI_PROP_MULTI_SLICE_BYTES_COUNT,
 		CAP_FLAG_OUTPUT_PORT},
 
-	{SLICE_MAX_MB, ENC, H264|HEVC|HEIC,
+	{SLICE_MAX_MB, ENC, H264|HEVC,
 		1, MAX_SLICE_MB_SIZE, 1, 1,
 		V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
 		HFI_PROP_MULTI_SLICE_MB_COUNT,
@@ -1532,6 +1557,22 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
 		HFI_PROP_HISTOGRAM_INFO,
 		CAP_FLAG_BITMASK},
 
+	{META_TRANSCODING_STAT_INFO, DEC, HEVC|H264,
+		V4L2_MPEG_VIDC_META_DISABLE,
+		V4L2_MPEG_VIDC_META_ENABLE | V4L2_MPEG_VIDC_META_RX_OUTPUT,
+		0, V4L2_MPEG_VIDC_META_DISABLE,
+		V4L2_CID_MPEG_VIDC_METADATA_TRANSCODE_STAT_INFO,
+		HFI_PROP_TRANSCODING_STAT_INFO,
+		CAP_FLAG_BITMASK},
+
+	{META_TRANSCODING_STAT_INFO, ENC, HEVC|H264,
+		V4L2_MPEG_VIDC_META_DISABLE,
+		V4L2_MPEG_VIDC_META_ENABLE | V4L2_MPEG_VIDC_META_TX_INPUT,
+		0, V4L2_MPEG_VIDC_META_DISABLE,
+		V4L2_CID_MPEG_VIDC_METADATA_TRANSCODE_STAT_INFO,
+		HFI_PROP_TRANSCODING_STAT_INFO,
+		CAP_FLAG_BITMASK},
+
 	{META_PICTURE_TYPE, DEC, CODECS_ALL,
 		V4L2_MPEG_VIDC_META_DISABLE,
 		V4L2_MPEG_VIDC_META_ENABLE | V4L2_MPEG_VIDC_META_RX_INPUT,
@@ -1591,6 +1632,22 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
 		HFI_PROP_SEI_HDR10PLUS_USERDATA,
 		CAP_FLAG_BITMASK},
 
+	{META_DOLBY_RPU, ENC, HEVC,
+		V4L2_MPEG_VIDC_META_DISABLE,
+		V4L2_MPEG_VIDC_META_ENABLE | V4L2_MPEG_VIDC_META_TX_INPUT,
+		0, V4L2_MPEG_VIDC_META_DISABLE,
+		V4L2_CID_MPEG_VIDC_METADATA_DOLBY_RPU,
+		HFI_PROP_DOLBY_RPU_METADATA,
+		CAP_FLAG_BITMASK},
+
+	{META_DOLBY_RPU, DEC, H264|HEVC,
+		V4L2_MPEG_VIDC_META_DISABLE,
+		V4L2_MPEG_VIDC_META_ENABLE | V4L2_MPEG_VIDC_META_RX_OUTPUT,
+		0, V4L2_MPEG_VIDC_META_DISABLE,
+		V4L2_CID_MPEG_VIDC_METADATA_DOLBY_RPU,
+		HFI_PROP_DOLBY_RPU_METADATA,
+		CAP_FLAG_BITMASK},
+
 	{META_EVA_STATS, ENC, CODECS_ALL,
 		V4L2_MPEG_VIDC_META_DISABLE,
 		V4L2_MPEG_VIDC_META_ENABLE | V4L2_MPEG_VIDC_META_TX_INPUT,
@@ -1819,9 +1876,16 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
 		NULL,
 		msm_vidc_set_req_sync_frame},
 
-	{BIT_RATE, ENC, H264|HEVC,
-		{ENH_LAYER_COUNT, BITRATE_MODE},
-		{PEAK_BITRATE},
+	{BIT_RATE, ENC, H264,
+		{ENH_LAYER_COUNT, BITRATE_MODE, ENTROPY_MODE,
+			ALL_INTRA, LOWLATENCY_MODE},
+		{PEAK_BITRATE, BITRATE_BOOST},
+		msm_vidc_adjust_bitrate,
+		msm_vidc_set_bitrate},
+
+	{BIT_RATE, ENC, HEVC,
+		{ENH_LAYER_COUNT, BITRATE_MODE, ALL_INTRA, LOWLATENCY_MODE},
+		{PEAK_BITRATE, BITRATE_BOOST},
 		msm_vidc_adjust_bitrate,
 		msm_vidc_set_bitrate},
 
@@ -1901,7 +1965,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
 
 	{LOWLATENCY_MODE, ENC, H264 | HEVC,
 		{BITRATE_MODE, DELIVERY_MODE},
-		{STAGE},
+		{STAGE, BIT_RATE},
 		msm_vidc_adjust_enc_lowlatency_mode,
 		NULL},
 
@@ -1960,7 +2024,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
 		msm_vidc_set_preprocess},
 
 	{BITRATE_BOOST, ENC, H264|HEVC,
-		{BITRATE_MODE, MIN_QUALITY},
+		{BITRATE_MODE, MIN_QUALITY, BIT_RATE},
 		{0},
 		msm_vidc_adjust_bitrate_boost_iris3,
 		msm_vidc_set_vbr_related_properties},
@@ -2108,7 +2172,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
 
 	{ENTROPY_MODE, ENC, H264,
 		{PROFILE},
-		{0},
+		{BIT_RATE},
 		msm_vidc_adjust_entropy_mode,
 		msm_vidc_set_u32},
 
@@ -2172,6 +2236,12 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
 		msm_vidc_adjust_slice_count,
 		msm_vidc_set_slice_count},
 
+	{SLICE_MODE, ENC, HEIC,
+		{0},
+		{0},
+		msm_vidc_adjust_slice_count,
+		msm_vidc_set_slice_count},
+
 	{TRANSFORM_8X8, ENC, H264,
 		{PROFILE},
 		{0},
@@ -2312,7 +2382,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
 
 	{ALL_INTRA, ENC, H264|HEVC,
 		{GOP_SIZE, B_FRAME},
-		{LTR_COUNT, IR_PERIOD, SLICE_MODE},
+		{LTR_COUNT, IR_PERIOD, SLICE_MODE, BIT_RATE},
 		msm_vidc_adjust_all_intra,
 		NULL},
 

+ 77 - 24
driver/platform/waipio/src/msm_vidc_waipio.c

@@ -12,6 +12,7 @@
 #include "msm_vidc_internal.h"
 #include "msm_vidc_control.h"
 #include "hfi_property.h"
+#include "hfi_command.h"
 
 #define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8020010
 #define MAX_LTR_FRAME_COUNT     2
@@ -20,8 +21,6 @@
 #define DEFAULT_BITRATE         20000000
 #define MINIMUM_FPS             1
 #define MAXIMUM_FPS             480
-#define MIN_QP_10BIT            -12
-#define MIN_QP_8BIT             0
 #define MAX_QP                  51
 #define DEFAULT_QP              20
 #define MAX_CONSTANT_QUALITY    100
@@ -38,7 +37,7 @@
 #define VP9     MSM_VIDC_VP9
 #define HEIC    MSM_VIDC_HEIC
 #define CODECS_ALL     (H264 | HEVC | VP9 | HEIC)
-#define MAXIMUM_OVERRIDE_VP9_FPS 120
+#define MAXIMUM_OVERRIDE_VP9_FPS 180
 
 static struct msm_platform_core_capability core_data_waipio[] = {
 	/* {type, value} */
@@ -46,12 +45,12 @@ static struct msm_platform_core_capability core_data_waipio[] = {
 	{DEC_CODECS, H264|HEVC|VP9|HEIC},
 	{MAX_SESSION_COUNT, 16},
 	{MAX_NUM_720P_SESSIONS, 16},
-	{MAX_NUM_1080P_SESSIONS, 8},
-	{MAX_NUM_4K_SESSIONS, 4},
+	{MAX_NUM_1080P_SESSIONS, 16},
+	{MAX_NUM_4K_SESSIONS, 8},
 	{MAX_NUM_8K_SESSIONS, 2},
 	{MAX_SECURE_SESSION_COUNT, 3},
-	{MAX_RT_MBPF, 173056},	/* (8192x4320)/256 + (4096x2176)/256*/
-	{MAX_MBPF, 276480}, /* ((8192x4320)/256) * 2 */
+	{MAX_RT_MBPF, 174080},	/* (8192x4352)/256 + (4096x2176)/256*/
+	{MAX_MBPF, 278528}, /* ((8192x4352)/256) * 2 */
 	{MAX_MBPS, 7833600},	/* max_load
 					 * 7680x4320@60fps or 3840x2176@240fps
 					 * which is greater than 4096x2176@120fps,
@@ -321,6 +320,14 @@ static struct msm_platform_inst_capability instance_cap_data_waipio[] = {
 		HFI_PROP_SECURE,
 		CAP_FLAG_NONE},
 
+	{META_OUTBUF_FENCE, DEC, H264|HEVC|VP9,
+		V4L2_MPEG_VIDC_META_DISABLE,
+		V4L2_MPEG_VIDC_META_DISABLE,
+		0, V4L2_MPEG_VIDC_META_DISABLE,
+		0,
+		0,
+		CAP_FLAG_BITMASK},
+
 	{TS_REORDER, DEC, H264|HEVC,
 		V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE,
 		1, V4L2_MPEG_MSM_VIDC_DISABLE,
@@ -1141,14 +1148,23 @@ static struct msm_platform_inst_capability instance_cap_data_waipio[] = {
 		0,
 		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU},
 
-	{SLICE_MAX_BYTES, ENC, H264|HEVC|HEIC,
+	{SLICE_MODE, ENC, HEIC,
+		V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
+		V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
+		BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE),
+		V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
+		V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
+		0,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU},
+
+	{SLICE_MAX_BYTES, ENC, H264|HEVC,
 		MIN_SLICE_BYTE_SIZE, MAX_SLICE_BYTE_SIZE,
 		1, MIN_SLICE_BYTE_SIZE,
 		V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
 		HFI_PROP_MULTI_SLICE_BYTES_COUNT,
 		CAP_FLAG_OUTPUT_PORT},
 
-	{SLICE_MAX_MB, ENC, H264|HEVC|HEIC,
+	{SLICE_MAX_MB, ENC, H264|HEVC,
 		1, MAX_SLICE_MB_SIZE, 1, 1,
 		V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
 		HFI_PROP_MULTI_SLICE_MB_COUNT,
@@ -1235,7 +1251,9 @@ static struct msm_platform_inst_capability instance_cap_data_waipio[] = {
 		0,
 		HFI_PROP_PIPE},
 
-	{POC, DEC, H264, 0, 18, 1, 1},
+	{POC, DEC, H264, 0, 2, 1, 1,
+		0,
+		HFI_PROP_PIC_ORDER_CNT_TYPE},
 
 	{QUALITY_MODE, ENC, CODECS_ALL,
 		MSM_VIDC_MAX_QUALITY_MODE,
@@ -1287,7 +1305,7 @@ static struct msm_platform_inst_capability instance_cap_data_waipio[] = {
 		CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED},
 
 	{PRIORITY, DEC|ENC, CODECS_ALL,
-		0, 2, 1, 1,
+		0, 1 + NRT_PRIORITY_OFFSET, 1, 1 + NRT_PRIORITY_OFFSET,
 		V4L2_CID_MPEG_VIDC_PRIORITY,
 		HFI_PROP_SESSION_PRIORITY,
 		CAP_FLAG_DYNAMIC_ALLOWED},
@@ -1411,7 +1429,8 @@ static struct msm_platform_inst_capability instance_cap_data_waipio[] = {
 
 	{META_SEI_MASTERING_DISP, DEC, HEVC|HEIC,
 		V4L2_MPEG_VIDC_META_DISABLE,
-		V4L2_MPEG_VIDC_META_ENABLE | V4L2_MPEG_VIDC_META_RX_OUTPUT,
+		V4L2_MPEG_VIDC_META_ENABLE | V4L2_MPEG_VIDC_META_RX_INPUT |
+			V4L2_MPEG_VIDC_META_RX_OUTPUT,
 		0, V4L2_MPEG_VIDC_META_DISABLE,
 		V4L2_CID_MPEG_VIDC_METADATA_SEI_MASTERING_DISPLAY_COLOUR,
 		HFI_PROP_SEI_MASTERING_DISPLAY_COLOUR,
@@ -1427,7 +1446,8 @@ static struct msm_platform_inst_capability instance_cap_data_waipio[] = {
 
 	{META_SEI_CLL, DEC, HEVC|HEIC,
 		V4L2_MPEG_VIDC_META_DISABLE,
-		V4L2_MPEG_VIDC_META_ENABLE | V4L2_MPEG_VIDC_META_RX_OUTPUT,
+		V4L2_MPEG_VIDC_META_ENABLE | V4L2_MPEG_VIDC_META_RX_INPUT |
+			V4L2_MPEG_VIDC_META_RX_OUTPUT,
 		0, V4L2_MPEG_VIDC_META_DISABLE,
 		V4L2_CID_MPEG_VIDC_METADATA_SEI_CONTENT_LIGHT_LEVEL,
 		HFI_PROP_SEI_CONTENT_LIGHT_LEVEL,
@@ -1443,7 +1463,8 @@ static struct msm_platform_inst_capability instance_cap_data_waipio[] = {
 
 	{META_HDR10PLUS, DEC, HEVC|HEIC,
 		V4L2_MPEG_VIDC_META_DISABLE,
-		V4L2_MPEG_VIDC_META_ENABLE | V4L2_MPEG_VIDC_META_RX_OUTPUT,
+		V4L2_MPEG_VIDC_META_ENABLE | V4L2_MPEG_VIDC_META_RX_INPUT |
+			V4L2_MPEG_VIDC_META_RX_OUTPUT,
 		0, V4L2_MPEG_VIDC_META_DISABLE,
 		V4L2_CID_MPEG_VIDC_METADATA_HDR10PLUS,
 		HFI_PROP_SEI_HDR10PLUS_USERDATA,
@@ -1469,7 +1490,8 @@ static struct msm_platform_inst_capability instance_cap_data_waipio[] = {
 	{META_BUF_TAG, DEC, CODECS_ALL,
 		V4L2_MPEG_VIDC_META_DISABLE,
 		V4L2_MPEG_VIDC_META_ENABLE | V4L2_MPEG_VIDC_META_TX_INPUT |
-			V4L2_MPEG_VIDC_META_TX_OUTPUT | V4L2_MPEG_VIDC_META_RX_OUTPUT,
+			V4L2_MPEG_VIDC_META_TX_OUTPUT | V4L2_MPEG_VIDC_META_RX_INPUT |
+			V4L2_MPEG_VIDC_META_RX_OUTPUT,
 		0, V4L2_MPEG_VIDC_META_DISABLE,
 		V4L2_CID_MPEG_VIDC_METADATA_BUFFER_TAG,
 		HFI_PROP_BUFFER_TAG,
@@ -1598,6 +1620,12 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_waip
 		NULL,
 		msm_vidc_set_u32},
 
+	{META_OUTBUF_FENCE, DEC, H264|HEVC|VP9,
+		{OUTPUT_ORDER},
+		{LOWLATENCY_MODE},
+		NULL,
+		NULL},
+
 	{HFLIP, ENC, CODECS_ALL,
 		{0},
 		{0},
@@ -1703,7 +1731,8 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_waip
 		msm_vidc_set_u32},
 
 	{BLUR_TYPES, ENC, H264|HEVC,
-		{PIX_FMTS, BITRATE_MODE, CONTENT_ADAPTIVE_CODING, MIN_QUALITY},
+		{PIX_FMTS, BITRATE_MODE, MIN_QUALITY,
+			CONTENT_ADAPTIVE_CODING, META_ROI_INFO},
 		{BLUR_RESOLUTION},
 		msm_vidc_adjust_blur_type_iris2,
 		msm_vidc_set_u32_enum},
@@ -1723,7 +1752,13 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_waip
 	{LOWLATENCY_MODE, ENC, H264 | HEVC,
 		{BITRATE_MODE},
 		{STAGE},
-		msm_vidc_adjust_lowlatency_mode,
+		msm_vidc_adjust_enc_lowlatency_mode,
+		NULL},
+
+	{LOWLATENCY_MODE, DEC, H264|HEVC|VP9,
+		{META_OUTBUF_FENCE},
+		{STAGE},
+		msm_vidc_adjust_dec_lowlatency_mode,
 		NULL},
 
 	{LTR_COUNT, ENC, H264|HEVC,
@@ -1745,7 +1780,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_waip
 		msm_vidc_set_use_and_mark_ltr},
 
 	{IR_PERIOD, ENC, H264|HEVC,
-		{BITRATE_MODE, ALL_INTRA},
+		{BITRATE_MODE, ALL_INTRA, META_ROI_INFO, PIX_FMTS},
 		{0},
 		msm_vidc_adjust_ir_period,
 		msm_vidc_set_ir_period},
@@ -1764,10 +1799,16 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_waip
 
 	{CONTENT_ADAPTIVE_CODING, ENC, H264|HEVC,
 		{BITRATE_MODE, LAYER_ENABLE, LAYER_TYPE},
-		{BLUR_TYPES},
+		{REQUEST_PREPROCESS},
 		msm_vidc_adjust_brs,
 		msm_vidc_set_vbr_related_properties},
 
+	{REQUEST_PREPROCESS, ENC, H264|HEVC,
+		{CONTENT_ADAPTIVE_CODING, META_EVA_STATS},
+		{0},
+		msm_vidc_adjust_preprocess,
+		NULL},
+
 	{BITRATE_BOOST, ENC, H264|HEVC,
 		{BITRATE_MODE, MIN_QUALITY},
 		{0},
@@ -1776,14 +1817,14 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_waip
 
 	{MIN_QUALITY, ENC, H264,
 		{BITRATE_MODE, ENH_LAYER_COUNT, META_ROI_INFO},
-		{CONTENT_ADAPTIVE_CODING, BITRATE_BOOST, BLUR_TYPES},
+		{BLUR_TYPES},
 		msm_vidc_adjust_min_quality,
 		msm_vidc_set_vbr_related_properties},
 
 	{MIN_QUALITY, ENC, HEVC,
 		{BITRATE_MODE, PIX_FMTS, ENH_LAYER_COUNT,
 			META_ROI_INFO},
-		{CONTENT_ADAPTIVE_CODING, BITRATE_BOOST, BLUR_TYPES},
+		{BLUR_TYPES},
 		msm_vidc_adjust_min_quality,
 		msm_vidc_set_vbr_related_properties},
 
@@ -1965,6 +2006,12 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_waip
 
 	{SLICE_MODE, ENC, H264|HEVC,
 		{BITRATE_MODE, ALL_INTRA},
+		{STAGE},
+		msm_vidc_adjust_slice_count,
+		msm_vidc_set_slice_count},
+
+	{SLICE_MODE, ENC, HEIC,
+		{0},
 		{0},
 		msm_vidc_adjust_slice_count,
 		msm_vidc_set_slice_count},
@@ -1995,7 +2042,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_waip
 
 	{OUTPUT_ORDER, DEC, H264|HEVC|VP9,
 		{THUMBNAIL_MODE, DISPLAY_DELAY, DISPLAY_DELAY_ENABLE},
-		{0},
+		{META_OUTBUF_FENCE},
 		msm_vidc_adjust_output_order,
 		msm_vidc_set_u32},
 
@@ -2035,13 +2082,19 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_waip
 		NULL,
 		msm_vidc_set_u32_packed},
 
-	{STAGE, DEC|ENC, CODECS_ALL,
+	{STAGE, ENC|DEC, CODECS_ALL,
 		{0},
 		{0},
 		NULL,
 		msm_vidc_set_stage},
 
 	{STAGE, ENC, H264|HEVC,
+		{LOWLATENCY_MODE, SLICE_MODE},
+		{0},
+		NULL,
+		msm_vidc_set_stage},
+
+	{STAGE, DEC, H264|HEVC|VP9,
 		{LOWLATENCY_MODE},
 		{0},
 		NULL,
@@ -2115,7 +2168,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_waip
 
 	{META_EVA_STATS, ENC, CODECS_ALL,
 		{0},
-		{ENH_LAYER_COUNT}},
+		{ENH_LAYER_COUNT, REQUEST_PREPROCESS}},
 
 	{META_ROI_INFO, ENC, H264|HEVC,
 		{BITRATE_MODE, PIX_FMTS},

+ 18 - 13
driver/variant/iris3/inc/hfi_buffer_iris3.h

@@ -514,10 +514,13 @@ typedef HFI_U32 HFI_BOOL;
 #define SIZE_SEI_USERDATA (4096)
 #define H264_NUM_FRM_INFO (66)
 #define H264_DISPLAY_BUF_SIZE (3328)
-#define HFI_BUFFER_PERSIST_H264D(_size) \
+#define SIZE_DOLBY_RPU_METADATA (41 * 1024)
+#define HFI_BUFFER_PERSIST_H264D(_size, rpu_enabled) \
 	_size = HFI_ALIGN((SIZE_SLIST_BUF_H264 * NUM_SLIST_BUF_H264 + \
 	H264_DISPLAY_BUF_SIZE * H264_NUM_FRM_INFO + \
-	NUM_HW_PIC_BUF * SIZE_SEI_USERDATA), VENUS_DMA_ALIGNMENT)
+	NUM_HW_PIC_BUF * SIZE_SEI_USERDATA + \
+	rpu_enabled * NUM_HW_PIC_BUF * SIZE_DOLBY_RPU_METADATA), \
+	VENUS_DMA_ALIGNMENT)
 
 #define LCU_MAX_SIZE_PELS 64
 #define LCU_MIN_SIZE_PELS 16
@@ -717,10 +720,11 @@ typedef HFI_U32 HFI_BOOL;
 #define H265_NUM_TILE (H265_NUM_TILE_ROW * H265_NUM_TILE_COL + 1)
 #define H265_NUM_FRM_INFO (48)
 #define H265_DISPLAY_BUF_SIZE (3072)
-#define HFI_BUFFER_PERSIST_H265D(_size) \
+#define HFI_BUFFER_PERSIST_H265D(_size, rpu_enabled) \
 	_size = HFI_ALIGN((SIZE_SLIST_BUF_H265 * NUM_SLIST_BUF_H265 + \
 	H265_NUM_FRM_INFO * H265_DISPLAY_BUF_SIZE + \
-	H265_NUM_TILE * sizeof(HFI_U32) + NUM_HW_PIC_BUF * SIZE_SEI_USERDATA),\
+	H265_NUM_TILE * sizeof(HFI_U32) + NUM_HW_PIC_BUF * SIZE_SEI_USERDATA + \
+	rpu_enabled * NUM_HW_PIC_BUF * SIZE_DOLBY_RPU_METADATA),\
 	VENUS_DMA_ALIGNMENT)
 
 #define SIZE_VPXD_LB_FE_LEFT_CTRL(frame_width, frame_height)   \
@@ -1356,7 +1360,7 @@ _yuv_bufcount_min, is_opb, num_vpp_pipes)           \
 	} while (0)
 
 #define SIZE_BIN_BITSTREAM_ENC(_size, rc_type, frame_width, frame_height, \
-		work_mode, lcu_size) \
+		work_mode, lcu_size, profile) \
 	do \
 	{ \
 		HFI_U32 size_aligned_width = 0, size_aligned_height = 0; \
@@ -1387,7 +1391,8 @@ _yuv_bufcount_min, is_opb, num_vpp_pipes)           \
 				{ \
 					bitstream_size_eval >>= 2; \
 				} \
-				if (lcu_size == 32) \
+				if (profile == HFI_H265_PROFILE_MAIN_10 || \
+					profile == HFI_H265_PROFILE_MAIN_10_STILL_PICTURE) \
 				{ \
 					bitstream_size_eval = (bitstream_size_eval * 5 >> 2); \
 				} \
@@ -1439,17 +1444,17 @@ _yuv_bufcount_min, is_opb, num_vpp_pipes)           \
 	} while (0)
 
 #define HFI_BUFFER_BIN_ENC(_size, rc_type, frame_width, frame_height, lcu_size, \
-				work_mode, num_vpp_pipes)           \
+				work_mode, num_vpp_pipes, profile)           \
 	do \
 	{ \
 		HFI_U32 bitstream_size = 0, total_bitbin_buffers = 0, \
 			size_single_pipe = 0, bitbin_size = 0; \
 		SIZE_BIN_BITSTREAM_ENC(bitstream_size, rc_type, frame_width, \
-			frame_height, work_mode, lcu_size);         \
+			frame_height, work_mode, lcu_size, profile);         \
 		if (work_mode == HFI_WORKMODE_2) \
 		{ \
 			total_bitbin_buffers = 3; \
-			bitbin_size = bitstream_size * 17 / 10; \
+			bitbin_size = bitstream_size * 12 / 10; \
 			bitbin_size = HFI_ALIGN(bitbin_size, \
 				VENUS_DMA_ALIGNMENT); \
 		} \
@@ -1474,19 +1479,19 @@ _yuv_bufcount_min, is_opb, num_vpp_pipes)           \
 	} while (0)
 
 #define HFI_BUFFER_BIN_H264E(_size, rc_type, frame_width, frame_height, \
-				work_mode, num_vpp_pipes)    \
+				work_mode, num_vpp_pipes, profile)    \
 	do \
 	{ \
 		HFI_BUFFER_BIN_ENC(_size, rc_type, frame_width, frame_height, 16, \
-				work_mode, num_vpp_pipes); \
+				work_mode, num_vpp_pipes, profile); \
 	} while (0)
 
 #define HFI_BUFFER_BIN_H265E(_size, rc_type, frame_width, frame_height, \
-				work_mode, num_vpp_pipes)    \
+				work_mode, num_vpp_pipes, profile)    \
 	do \
 	{ \
 		HFI_BUFFER_BIN_ENC(_size, rc_type, frame_width, frame_height, 32,\
-				work_mode, num_vpp_pipes); \
+				work_mode, num_vpp_pipes, profile); \
 	} while (0)
 
 #define SIZE_ENC_SLICE_INFO_BUF(num_lcu_in_frame) HFI_ALIGN((256 + \

+ 44 - 6
driver/variant/iris3/src/msm_vidc_buffer_iris3.c

@@ -220,16 +220,20 @@ static u32 msm_vidc_decoder_partial_data_size_iris3(struct msm_vidc_inst *inst)
 static u32 msm_vidc_decoder_persist_size_iris3(struct msm_vidc_inst *inst)
 {
 	u32 size = 0;
+	u32 rpu_enabled = 0;
 
 	if (!inst) {
 		d_vpr_e("%s: invalid params\n", __func__);
 		return size;
 	}
 
+	if (inst->capabilities->cap[META_DOLBY_RPU].value)
+		rpu_enabled = 1;
+
 	if (inst->codec == MSM_VIDC_H264) {
-		HFI_BUFFER_PERSIST_H264D(size);
+		HFI_BUFFER_PERSIST_H264D(size, rpu_enabled);
 	} else if (inst->codec == MSM_VIDC_HEVC || inst->codec == MSM_VIDC_HEIC) {
-		HFI_BUFFER_PERSIST_H265D(size);
+		HFI_BUFFER_PERSIST_H265D(size, rpu_enabled);
 	} else if (inst->codec == MSM_VIDC_VP9) {
 		HFI_BUFFER_PERSIST_VP9D(size);
 	} else if (inst->codec == MSM_VIDC_AV1) {
@@ -310,7 +314,7 @@ static u32 msm_vidc_encoder_bin_size_iris3(struct msm_vidc_inst *inst)
 {
 	struct msm_vidc_core *core;
 	u32 size = 0;
-	u32 width, height, num_vpp_pipes, stage;
+	u32 width, height, num_vpp_pipes, stage, profile;
 	struct v4l2_format *f;
 
 	if (!inst || !inst->core || !inst->capabilities) {
@@ -327,13 +331,14 @@ static u32 msm_vidc_encoder_bin_size_iris3(struct msm_vidc_inst *inst)
 	f = &inst->fmts[OUTPUT_PORT];
 	width = f->fmt.pix_mp.width;
 	height = f->fmt.pix_mp.height;
+	profile = inst->capabilities->cap[PROFILE].value;
 
 	if (inst->codec == MSM_VIDC_H264)
 		HFI_BUFFER_BIN_H264E(size, inst->hfi_rc_type, width,
-			height, stage, num_vpp_pipes);
+			height, stage, num_vpp_pipes, profile);
 	else if (inst->codec == MSM_VIDC_HEVC || inst->codec == MSM_VIDC_HEIC)
 		HFI_BUFFER_BIN_H265E(size, inst->hfi_rc_type, width,
-			height, stage, num_vpp_pipes);
+			height, stage, num_vpp_pipes, profile);
 
 	i_vpr_l(inst, "%s: size %d\n", __func__, size);
 	return size;
@@ -541,6 +546,39 @@ static u32 msm_vidc_encoder_vpss_size_iris3(struct msm_vidc_inst* inst)
 	return size;
 }
 
+static u32 msm_vidc_encoder_output_size_iris3(struct msm_vidc_inst *inst)
+{
+	u32 frame_size;
+	struct v4l2_format *f;
+	bool is_ten_bit = false;
+	int bitrate_mode, frame_rc;
+	u32 hfi_rc_type = HFI_RC_VBR_CFR;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	f = &inst->fmts[OUTPUT_PORT];
+	if (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_HEVC ||
+		f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_HEIC)
+		is_ten_bit = true;
+
+	bitrate_mode = inst->capabilities->cap[BITRATE_MODE].value;
+	frame_rc = inst->capabilities->cap[FRAME_RC_ENABLE].value;
+	if (!frame_rc && !is_image_session(inst))
+		hfi_rc_type = HFI_RC_OFF;
+	else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ)
+		hfi_rc_type = HFI_RC_CQ;
+
+	HFI_BUFFER_BITSTREAM_ENC(frame_size, f->fmt.pix_mp.width,
+		f->fmt.pix_mp.height, hfi_rc_type, is_ten_bit);
+
+	frame_size = msm_vidc_enc_delivery_mode_based_output_buf_size(inst, frame_size);
+
+	return frame_size;
+}
+
 struct msm_vidc_buf_type_handle {
 	enum msm_vidc_buffer_type type;
 	u32 (*handle)(struct msm_vidc_inst *inst);
@@ -567,7 +605,7 @@ int msm_buffer_size_iris3(struct msm_vidc_inst *inst,
 	};
 	static const struct msm_vidc_buf_type_handle enc_buf_type_handle[] = {
 		{MSM_VIDC_BUF_INPUT,           msm_vidc_encoder_input_size              },
-		{MSM_VIDC_BUF_OUTPUT,          msm_vidc_encoder_output_size             },
+		{MSM_VIDC_BUF_OUTPUT,          msm_vidc_encoder_output_size_iris3       },
 		{MSM_VIDC_BUF_INPUT_META,      msm_vidc_encoder_input_meta_size         },
 		{MSM_VIDC_BUF_OUTPUT_META,     msm_vidc_encoder_output_meta_size        },
 		{MSM_VIDC_BUF_BIN,             msm_vidc_encoder_bin_size_iris3          },

+ 21 - 5
driver/variant/iris3/src/msm_vidc_iris3.c

@@ -1110,8 +1110,9 @@ int msm_vidc_decide_quality_mode_iris3(struct msm_vidc_inst* inst)
 	if (!is_encode_session(inst))
 		return 0;
 
-	/* image session or lossless encode always runs at quality mode */
-	if (is_image_session(inst) || capability->cap[LOSSLESS].value) {
+	/* image or lossless or all intra runs at quality mode */
+	if (is_image_session(inst) || capability->cap[LOSSLESS].value ||
+		capability->cap[ALL_INTRA].value) {
 		mode = MSM_VIDC_MAX_QUALITY_MODE;
 		goto decision_done;
 	}
@@ -1128,9 +1129,13 @@ int msm_vidc_decide_quality_mode_iris3(struct msm_vidc_inst* inst)
 	max_hq_mbpf = core->capabilities[MAX_MBPF_HQ].value;;
 	max_hq_mbps = core->capabilities[MAX_MBPS_HQ].value;;
 
-	if (!is_realtime_session(inst) && mbpf <= max_hq_mbpf) {
-		mode = MSM_VIDC_MAX_QUALITY_MODE;
-		goto decision_done;
+	if (!is_realtime_session(inst)) {
+		if (((capability->cap[COMPLEXITY].flags & CAP_FLAG_CLIENT_SET) &&
+			(capability->cap[COMPLEXITY].value >= DEFAULT_COMPLEXITY)) ||
+			mbpf <= max_hq_mbpf) {
+			mode = MSM_VIDC_MAX_QUALITY_MODE;
+			goto decision_done;
+		}
 	}
 
 	if (mbpf <= max_hq_mbpf && mbps <= max_hq_mbps)
@@ -1150,6 +1155,7 @@ int msm_vidc_adjust_bitrate_boost_iris3(void* instance, struct v4l2_ctrl *ctrl)
 	s32 rc_type = -1;
 	u32 width, height, frame_rate;
 	struct v4l2_format *f;
+	u32 max_bitrate = 0, bitrate = 0;
 
 	if (!inst || !inst->capabilities) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -1197,6 +1203,16 @@ int msm_vidc_adjust_bitrate_boost_iris3(void* instance, struct v4l2_ctrl *ctrl)
 			adjusted_value = 0;
 	}
 
+	max_bitrate = msm_vidc_get_max_bitrate(inst);
+	bitrate = inst->capabilities->cap[BIT_RATE].value;
+	if (adjusted_value) {
+		if ((bitrate + bitrate / (100 / adjusted_value)) > max_bitrate) {
+			i_vpr_h(inst,
+				"%s: bitrate %d is beyond max bitrate %d, remove bitrate boost\n",
+				__func__, max_bitrate, bitrate);
+			adjusted_value = 0;
+		}
+	}
 adjust:
 	msm_vidc_update_cap_value(inst, BITRATE_BOOST, adjusted_value, __func__);
 

+ 86 - 27
driver/variant/iris3/src/msm_vidc_power_iris3.c

@@ -29,7 +29,7 @@ u64 msm_vidc_calc_freq_iris3(struct msm_vidc_inst *inst, u32 data_size)
 	}
 
 	core = inst->core;
-	if (!core->dt) {
+	if (!core->dt || !core->dt->allowed_clks_tbl) {
 		d_vpr_e("%s: invalid params\n", __func__);
 		return freq;
 	}
@@ -139,38 +139,87 @@ u64 msm_vidc_calc_freq_iris3(struct msm_vidc_inst *inst, u32 data_size)
 		}
 
 		/* VSP */
-		base_cycles = inst->has_bframe ?
-				80 : inst->capabilities->cap[MB_CYCLES_VSP].value;
-		bitrate = fps * data_size * 8;
-		vsp_cycles = bitrate;
+		if (inst->codec == MSM_VIDC_AV1) {
+			/*
+			 * For AV1: Use VSP calculations from Kalama perf model.
+			 * For legacy codecs, use vsp_cycles based on legacy MB_CYCLES_VSP.
+			 */
+			u32 decoder_vsp_fw_overhead = 105;
+			u32 fw_sw_vsp_offset = 1055;
+			u64 vsp_hw_min_frequency = 0;
+			u32 input_bitrate_mbps = 0;
+			u32 bitrate_2stage[2] = {130, 120};
+			u32 bitrate_1stage = 100;
+			u32 width, height;
+			u32 bitrate_entry, freq_entry, frequency_table_value;
+			struct allowed_clock_rates_table *allowed_clks_tbl;
+			struct v4l2_format *out_f = &inst->fmts[OUTPUT_PORT];
+
+			width = out_f->fmt.pix_mp.width;
+			height = out_f->fmt.pix_mp.height;
+
+			bitrate_entry = 1;
+			/* 8KUHD60, UHD240, 1080p960 */
+			if (width * height * fps >= 3840 * 2160 * 240)
+				bitrate_entry = 0;
+
+			freq_entry = bitrate_entry;
+
+			allowed_clks_tbl = core->dt->allowed_clks_tbl;
+			frequency_table_value = allowed_clks_tbl[freq_entry].clock_rate / 1000000;
+
+			input_bitrate_mbps = fps * data_size * 8 / (1024 * 1024);
+			vsp_hw_min_frequency = frequency_table_value * 1000 * input_bitrate_mbps;
+
+			if (inst->capabilities->cap[STAGE].value == MSM_VIDC_STAGE_2) {
+				vsp_hw_min_frequency +=
+					(bitrate_2stage[bitrate_entry] * fw_sw_vsp_offset - 1);
+				vsp_hw_min_frequency = div_u64(vsp_hw_min_frequency,
+					(bitrate_2stage[bitrate_entry] * fw_sw_vsp_offset));
+				/* VSP fw overhead 1.05 */
+				vsp_hw_min_frequency = div_u64(vsp_hw_min_frequency *
+					decoder_vsp_fw_overhead + 99, 100);
+			} else {
+				vsp_hw_min_frequency += (bitrate_1stage * fw_sw_vsp_offset - 1);
+				vsp_hw_min_frequency = div_u64(vsp_hw_min_frequency,
+					(bitrate_1stage * fw_sw_vsp_offset));
+			}
 
-		if (inst->codec == MSM_VIDC_VP9) {
-			vsp_cycles = div_u64(vsp_cycles * 170, 100);
-		} else if (inst->capabilities->cap[ENTROPY_MODE].value ==
-			V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC) {
-			vsp_cycles = div_u64(vsp_cycles * 135, 100);
+			vsp_cycles = vsp_hw_min_frequency * 1000000;
 		} else {
-			base_cycles = 0;
-			vsp_cycles = div_u64(vsp_cycles, 2);
-		}
-		/* VSP FW overhead 1.05 */
-		vsp_cycles = div_u64(vsp_cycles * 21, 20);
+			base_cycles = inst->has_bframe ?
+					80 : inst->capabilities->cap[MB_CYCLES_VSP].value;
+			bitrate = fps * data_size * 8;
+			vsp_cycles = bitrate;
+
+			if (inst->codec == MSM_VIDC_VP9) {
+				vsp_cycles = div_u64(vsp_cycles * 170, 100);
+			} else if (inst->capabilities->cap[ENTROPY_MODE].value ==
+				V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC) {
+				vsp_cycles = div_u64(vsp_cycles * 135, 100);
+			} else {
+				base_cycles = 0;
+				vsp_cycles = div_u64(vsp_cycles, 2);
+			}
+			/* VSP FW overhead 1.05 */
+			vsp_cycles = div_u64(vsp_cycles * 21, 20);
 
-		if (inst->capabilities->cap[STAGE].value == MSM_VIDC_STAGE_1)
-			vsp_cycles = vsp_cycles * 3;
+			if (inst->capabilities->cap[STAGE].value == MSM_VIDC_STAGE_1)
+				vsp_cycles = vsp_cycles * 3;
 
-		vsp_cycles += mbs_per_second * base_cycles;
+			vsp_cycles += mbs_per_second * base_cycles;
 
-		/* Add 25 percent extra for 960fps use case */
-		if (fps >= 960)
-			vsp_cycles += div_u64(vpp_cycles * 25, 100);
+			/* Add 25 percent extra for 960fps use case */
+			if (fps >= 960)
+				vsp_cycles += div_u64(vpp_cycles * 25, 100);
 
-		if (inst->codec == MSM_VIDC_VP9 &&
-				inst->capabilities->cap[STAGE].value ==
-					MSM_VIDC_STAGE_2 &&
-				inst->capabilities->cap[PIPE].value == 4 &&
-				bitrate > 90000000)
-			vsp_cycles = msm_vidc_max_freq(inst);
+			if (inst->codec == MSM_VIDC_VP9 &&
+					inst->capabilities->cap[STAGE].value ==
+						MSM_VIDC_STAGE_2 &&
+					inst->capabilities->cap[PIPE].value == 4 &&
+					bitrate > 90000000)
+				vsp_cycles = msm_vidc_max_freq(inst);
+		}
 	} else {
 		i_vpr_e(inst, "%s: Unknown session type\n", __func__);
 		return msm_vidc_max_freq(inst);
@@ -179,6 +228,16 @@ u64 msm_vidc_calc_freq_iris3(struct msm_vidc_inst *inst, u32 data_size)
 	freq = max(vpp_cycles, vsp_cycles);
 	freq = max(freq, fw_cycles);
 
+	if (inst->codec != MSM_VIDC_AV1) {
+		/*
+		 * for non-AV1 codecs limit the frequency to NOM only
+		 * index 0 is TURBO, index 1 is NOM clock rate
+		 */
+		if (core->dt->allowed_clks_tbl_size >= 2 &&
+		    freq > core->dt->allowed_clks_tbl[1].clock_rate)
+			freq = core->dt->allowed_clks_tbl[1].clock_rate;
+	}
+
 	i_vpr_p(inst, "%s: filled len %d, required freq %llu, fps %u, mbpf %u\n",
 		__func__, data_size, freq, fps, mbpf);
 

+ 6 - 0
driver/vidc/inc/hfi_property.h

@@ -543,6 +543,8 @@ enum hfi_nal_length_field_type {
 
 #define HFI_PROP_AV1_OP_POINT                                   0x03000182
 
+#define HFI_PROP_SUBFRAME_INPUT                                 0x03000183
+
 #define HFI_PROP_OPB_ENABLE                                     0x03000184
 
 #define HFI_PROP_AV1_DRAP_CONFIG                                0x03000189
@@ -559,6 +561,10 @@ enum hfi_saliency_type {
 
 #define HFI_PROP_UBWC_STRIDE_SCANLINE                           0x03000190
 
+#define HFI_PROP_TRANSCODING_STAT_INFO                          0x03000191
+
+#define HFI_PROP_DOLBY_RPU_METADATA                             0x03000192
+
 #define HFI_PROP_END                                            0x03FFFFFF
 
 #define HFI_SESSION_ERROR_BEGIN                                 0x04000000

+ 2 - 0
driver/vidc/inc/msm_vidc_buffer.h

@@ -31,5 +31,7 @@ u32 msm_vidc_encoder_input_size(struct msm_vidc_inst *inst);
 u32 msm_vidc_encoder_output_size(struct msm_vidc_inst *inst);
 u32 msm_vidc_encoder_input_meta_size(struct msm_vidc_inst *inst);
 u32 msm_vidc_encoder_output_meta_size(struct msm_vidc_inst *inst);
+u32 msm_vidc_enc_delivery_mode_based_output_buf_size(struct msm_vidc_inst *inst,
+	u32 frame_size);
 
 #endif // __H_MSM_VIDC_BUFFER_H__

+ 4 - 0
driver/vidc/inc/msm_vidc_driver.h

@@ -510,6 +510,7 @@ int msm_vidc_state_change_start(struct msm_vidc_inst *inst);
 int msm_vidc_state_change_input_psc(struct msm_vidc_inst *inst);
 int msm_vidc_state_change_last_flag(struct msm_vidc_inst *inst);
 int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst);
+u32 msm_vidc_get_max_bitrate(struct msm_vidc_inst* inst);
 int msm_vidc_get_fps(struct msm_vidc_inst *inst);
 int msm_vidc_num_buffers(struct msm_vidc_inst *inst,
 	enum msm_vidc_buffer_type type, enum msm_vidc_buffer_attributes attr);
@@ -519,6 +520,9 @@ bool core_lock_check(struct msm_vidc_core *core, const char *function);
 void inst_lock(struct msm_vidc_inst *inst, const char *function);
 void inst_unlock(struct msm_vidc_inst *inst, const char *function);
 bool inst_lock_check(struct msm_vidc_inst *inst, const char *function);
+bool client_lock_check(struct msm_vidc_inst *inst, const char *func);
+void client_lock(struct msm_vidc_inst *inst, const char *function);
+void client_unlock(struct msm_vidc_inst *inst, const char *function);
 int msm_vidc_update_bitstream_buffer_size(struct msm_vidc_inst *inst);
 int msm_vidc_update_meta_port_settings(struct msm_vidc_inst *inst);
 int msm_vidc_update_buffer_count(struct msm_vidc_inst *inst, u32 port);

+ 1 - 0
driver/vidc/inc/msm_vidc_inst.h

@@ -98,6 +98,7 @@ struct msm_vidc_inst {
 	struct list_head                   list;
 	struct mutex                       lock;
 	struct mutex                       request_lock;
+	struct mutex                       client_lock;
 	enum msm_vidc_inst_state           state;
 	enum msm_vidc_domain_type          domain;
 	enum msm_vidc_codec_type           codec;

+ 16 - 5
driver/vidc/inc/msm_vidc_internal.h

@@ -63,7 +63,10 @@
 #define MAX_SUPPORTED_MIN_QUALITY            70
 #define MIN_CHROMA_QP_OFFSET                -12
 #define MAX_CHROMA_QP_OFFSET                  0
+#define MIN_QP_10BIT                        -11
+#define MIN_QP_8BIT                           1
 #define INVALID_FD                           -1
+#define INVALID_CLIENT_ID                    -1
 
 #define DCVS_WINDOW 16
 #define ENC_FPS_WINDOW 3
@@ -82,7 +85,7 @@
 #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)
+#define VIDC_IFACEQ_VAR_HUGE_PKT_SIZE          (1024*4)
 
 #define NUM_MBS_PER_SEC(__height, __width, __fps) \
 	(NUM_MBS_PER_FRAME(__height, __width) * __fps)
@@ -383,6 +386,8 @@ enum msm_vidc_inst_capability_type {
 	META_EVA_STATS,
 	META_ROI_INFO,
 	META_SALIENCY_INFO,
+	META_TRANSCODING_STAT_INFO,
+	META_DOLBY_RPU,
 	META_CAP_MAX,
 	/* end of metadata caps */
 	FRAME_WIDTH,
@@ -412,6 +417,7 @@ enum msm_vidc_inst_capability_type {
 	MB_CYCLES_LP,
 	MB_CYCLES_FW,
 	MB_CYCLES_FW_VPP,
+	CLIENT_ID,
 	SECURE_MODE,
 	FENCE_ID,
 	FENCE_FD,
@@ -490,6 +496,10 @@ enum msm_vidc_inst_capability_type {
 	INPUT_META_VIA_REQUEST,
 	ENC_IP_CR,
 	COMPLEXITY,
+	CABAC_MAX_BITRATE,
+	CAVLC_MAX_BITRATE,
+	ALLINTRA_MAX_BITRATE,
+	LOWLATENCY_MAX_BITRATE,
 	/* place all root(no parent) enums before this line */
 
 	PROFILE,
@@ -762,6 +772,7 @@ struct msm_vidc_subscription_params {
 struct msm_vidc_hfi_frame_info {
 	u32                    picture_type;
 	u32                    no_output;
+	u32                    subframe_input;
 	u32                    cr;
 	u32                    cf;
 	u32                    data_corrupt;
@@ -827,16 +838,16 @@ struct msm_vidc_power {
 };
 
 struct msm_vidc_fence_context {
-        char name[MAX_NAME_LENGTH];
-        u64 ctx_num;
-        u64 seq_num;
+	char                      name[MAX_NAME_LENGTH];
+	u64                       ctx_num;
+	u64                       seq_num;
+	spinlock_t                lock;
 };
 
 struct msm_vidc_fence {
 	struct list_head            list;
 	struct dma_fence            dma_fence;
 	char                        name[MAX_NAME_LENGTH];
-	spinlock_t                  lock;
 	struct sync_file            *sync_file;
 	int                         fd;
 };

+ 2 - 1
driver/vidc/inc/msm_vidc_memory.h

@@ -63,5 +63,6 @@ void msm_memory_pools_deinit(struct msm_vidc_inst *inst);
 void *msm_memory_pool_alloc(struct msm_vidc_inst *inst,
 	enum msm_memory_pool_type type);
 void msm_memory_pool_free(struct msm_vidc_inst *inst, void *vidc_buf);
-
+int msm_vidc_vmem_alloc(unsigned long size, void **mem, const char *msg);
+void msm_vidc_vmem_free(void **addr);
 #endif // _MSM_VIDC_MEMORY_H_

+ 1 - 0
driver/vidc/src/msm_vdec.c

@@ -71,6 +71,7 @@ static const u32 msm_vdec_subscribe_for_psc_av1[] = {
 
 static const u32 msm_vdec_input_subscribe_for_properties[] = {
 	HFI_PROP_NO_OUTPUT,
+	HFI_PROP_SUBFRAME_INPUT,
 };
 
 static const u32 msm_vdec_output_subscribe_for_properties[] = {

+ 2 - 5
driver/vidc/src/msm_venc.c

@@ -1227,11 +1227,8 @@ static int msm_venc_s_fmt_input(struct msm_vidc_inst *inst, struct v4l2_format *
 	height = f->fmt.pix_mp.height;
 
 	if (is_image_session(inst)) {
-		width = ALIGN(f->fmt.pix_mp.width, HEIC_GRID_DIMENSION);
-		height = ALIGN(f->fmt.pix_mp.height, HEIC_GRID_DIMENSION);
-		inst->crop.width = ALIGN(inst->crop.width, HEIC_GRID_DIMENSION);
-		inst->crop.height = ALIGN(inst->crop.height, HEIC_GRID_DIMENSION);
-		bytesperline = width * (is_10bit_colorformat(pix_fmt) ? 2 : 1);
+		bytesperline = ALIGN(f->fmt.pix_mp.width, HEIC_GRID_DIMENSION) *
+			(is_10bit_colorformat(pix_fmt) ? 2 : 1);
 	} else if (is_rgba_colorformat(pix_fmt)) {
 		bytesperline = VIDEO_RGB_STRIDE_BYTES(f->fmt.pix_mp.pixelformat,
 				f->fmt.pix_mp.width);

+ 11 - 11
driver/vidc/src/msm_vidc.c

@@ -855,7 +855,7 @@ EXPORT_SYMBOL(msm_vidc_dqevent);
 void *msm_vidc_open(void *vidc_core, u32 session_type)
 {
 	int rc = 0;
-	struct msm_vidc_inst *inst;
+	struct msm_vidc_inst *inst = NULL;
 	struct msm_vidc_core *core;
 	int i = 0;
 
@@ -881,11 +881,10 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
 	if (rc)
 		return NULL;
 
-	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
-	if (!inst) {
-		d_vpr_e("%s: failed to allocate inst memory\n", __func__);
+	rc = msm_vidc_vmem_alloc(sizeof(*inst), (void **)&inst, "inst memory");
+	if (rc)
 		return NULL;
-	}
+
 	inst->core = core;
 	inst->domain = session_type;
 	inst->session_id = hash32_ptr(inst);
@@ -899,13 +898,14 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
 	kref_init(&inst->kref);
 	mutex_init(&inst->lock);
 	mutex_init(&inst->request_lock);
+	mutex_init(&inst->client_lock);
 	msm_vidc_update_debug_str(inst);
 	i_vpr_h(inst, "Opening video instance: %d\n", session_type);
 
 	rc = msm_memory_pools_init(inst);
 	if (rc) {
 		i_vpr_e(inst, "%s: failed to init pool buffers\n", __func__);
-		kfree(inst);
+		msm_vidc_vmem_free((void **)&inst);
 		return NULL;
 	}
 	INIT_LIST_HEAD(&inst->response_works);
@@ -969,12 +969,10 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
 	INIT_DELAYED_WORK(&inst->stats_work, msm_vidc_stats_handler);
 	INIT_WORK(&inst->stability_work, msm_vidc_stability_handler);
 
-	inst->capabilities = kzalloc(sizeof(struct msm_vidc_inst_capability), GFP_KERNEL);
-	if (!inst->capabilities) {
-		i_vpr_e(inst,
-			"%s: inst capability allocation failed\n", __func__);
+	rc = msm_vidc_vmem_alloc(sizeof(struct msm_vidc_inst_capability),
+		(void **)&inst->capabilities, "inst capability");
+	if (rc)
 		goto error;
-	}
 
 	rc = msm_vidc_event_queue_init(inst);
 	if (rc)
@@ -1035,6 +1033,7 @@ int msm_vidc_close(void *instance)
 	core = inst->core;
 
 	i_vpr_h(inst, "%s()\n", __func__);
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	/* print final stats */
 	msm_vidc_print_stats(inst);
@@ -1042,6 +1041,7 @@ int msm_vidc_close(void *instance)
 	msm_vidc_remove_session(inst);
 	msm_vidc_destroy_buffers(inst);
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	cancel_response_work_sync(inst);
 	cancel_stability_work_sync(inst);
 	cancel_stats_work_sync(inst);

+ 28 - 6
driver/vidc/src/msm_vidc_buffer.c

@@ -287,22 +287,33 @@ u32 msm_vidc_decoder_input_meta_size(struct msm_vidc_inst *inst)
 
 u32 msm_vidc_decoder_output_meta_size(struct msm_vidc_inst *inst)
 {
-	return MSM_VIDC_METADATA_SIZE;
+	u32 size = MSM_VIDC_METADATA_SIZE;
+
+	if (inst->capabilities->cap[META_DOLBY_RPU].value)
+		size += MSM_VIDC_METADATA_DOLBY_RPU_SIZE;
+
+	return ALIGN(size, SZ_4K);
 }
 
 u32 msm_vidc_encoder_input_size(struct msm_vidc_inst *inst)
 {
 	u32 size;
 	struct v4l2_format *f;
+	u32 width, height;
 
 	f = &inst->fmts[INPUT_PORT];
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+	if (is_image_session(inst)) {
+		width = ALIGN(width, HEIC_GRID_DIMENSION);
+		height = ALIGN(height, HEIC_GRID_DIMENSION);
+	}
 	size = VIDEO_RAW_BUFFER_SIZE(f->fmt.pix_mp.pixelformat,
-			f->fmt.pix_mp.width,
-			f->fmt.pix_mp.height, true);
+			width, height, true);
 	return size;
 }
 
-static u32 msm_vidc_enc_delivery_mode_based_output_buf_size(struct msm_vidc_inst *inst,
+u32 msm_vidc_enc_delivery_mode_based_output_buf_size(struct msm_vidc_inst *inst,
 	u32 frame_size)
 {
 	u32 slice_size;
@@ -415,6 +426,7 @@ u32 msm_vidc_encoder_input_meta_size(struct msm_vidc_inst *inst)
 	u32 size = 0;
 	u32 lcu_size = 0;
 	struct v4l2_format *f;
+	u32 width, height;
 
 	if (!inst || !inst->capabilities) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -434,8 +446,18 @@ u32 msm_vidc_encoder_input_meta_size(struct msm_vidc_inst *inst)
 			lcu_size = 32;
 
 		f = &inst->fmts[INPUT_PORT];
-		size += ROI_METADATA_SIZE(f->fmt.pix_mp.width,
-			f->fmt.pix_mp.height, lcu_size);
+		width = f->fmt.pix_mp.width;
+		height = f->fmt.pix_mp.height;
+		if (is_image_session(inst)) {
+			width = ALIGN(width, HEIC_GRID_DIMENSION);
+			height = ALIGN(height, HEIC_GRID_DIMENSION);
+		}
+		size += ROI_METADATA_SIZE(width, height, lcu_size);
+		size = ALIGN(size, SZ_4K);
+	}
+
+	if (inst->capabilities->cap[META_DOLBY_RPU].value) {
+		size += MSM_VIDC_METADATA_DOLBY_RPU_SIZE;
 		size = ALIGN(size, SZ_4K);
 	}
 	return size;

+ 87 - 47
driver/vidc/src/msm_vidc_control.c

@@ -15,10 +15,12 @@
 #include "msm_vidc_platform.h"
 
 #define CAP_TO_8BIT_QP(a) {          \
-	if ((a) < 0)                 \
-		(a) = 0;             \
+	if ((a) < MIN_QP_8BIT)                 \
+		(a) = MIN_QP_8BIT;             \
 }
 
+extern struct msm_vidc_core *g_core;
+
 static bool is_priv_ctrl(u32 id)
 {
 	bool private = false;
@@ -254,19 +256,19 @@ static inline bool is_all_parents_visited(
 
 static int add_node_list(struct list_head *list, enum msm_vidc_inst_capability_type cap_id)
 {
-	struct msm_vidc_inst_cap_entry *entry;
+	int rc = 0;
+	struct msm_vidc_inst_cap_entry *entry = NULL;
 
-	entry = kzalloc(sizeof(struct msm_vidc_inst_cap_entry), GFP_KERNEL);
-	if (!entry) {
-		d_vpr_e("%s: msm_vidc_inst_cap_entry alloc failed\n", __func__);
-		return -EINVAL;
-	}
+	rc = msm_vidc_vmem_alloc(sizeof(struct msm_vidc_inst_cap_entry),
+			(void **)&entry, __func__);
+	if (rc)
+		return rc;
 
 	INIT_LIST_HEAD(&entry->list);
 	entry->cap_id = cap_id;
 	list_add_tail(&entry->list, list);
 
-	return 0;
+	return rc;
 }
 
 static int add_node(
@@ -696,7 +698,7 @@ static int msm_vidc_adjust_dynamic_property(struct msm_vidc_inst *inst,
 		}
 
 		list_del_init(&entry->list);
-		kfree(entry);
+		msm_vidc_vmem_free((void **)&entry);
 	}
 
 	/* expecting children_list to be empty */
@@ -711,12 +713,12 @@ error:
 	list_for_each_entry_safe(entry, temp, &inst->children_list, list) {
 		i_vpr_e(inst, "%s: child list: %s\n", __func__, cap_name(entry->cap_id));
 		list_del_init(&entry->list);
-		kfree(entry);
+		msm_vidc_vmem_free((void **)&entry);
 	}
 	list_for_each_entry_safe(entry, temp, &inst->firmware_list, list) {
 		i_vpr_e(inst, "%s: fw list: %s\n", __func__, cap_name(entry->cap_id));
 		list_del_init(&entry->list);
-		kfree(entry);
+		msm_vidc_vmem_free((void **)&entry);
 	}
 
 	return rc;
@@ -739,7 +741,7 @@ static int msm_vidc_set_dynamic_property(struct msm_vidc_inst *inst)
 			goto error;
 
 		list_del_init(&entry->list);
-		kfree(entry);
+		msm_vidc_vmem_free((void **)&entry);
 	}
 
 	return 0;
@@ -747,7 +749,7 @@ error:
 	list_for_each_entry_safe(entry, temp, &inst->firmware_list, list) {
 		i_vpr_e(inst, "%s: fw list: %s\n", __func__, cap_name(entry->cap_id));
 		list_del_init(&entry->list);
-		kfree(entry);
+		msm_vidc_vmem_free((void **)&entry);
 	}
 
 	return rc;
@@ -771,7 +773,7 @@ int msm_vidc_ctrl_deinit(struct msm_vidc_inst *inst)
 	i_vpr_h(inst, "%s(): num ctrls %d\n", __func__, inst->num_ctrls);
 	v4l2_ctrl_handler_free(&inst->ctrl_handler);
 	memset(&inst->ctrl_handler, 0, sizeof(struct v4l2_ctrl_handler));
-	kfree(inst->ctrls);
+	msm_vidc_vmem_free((void **)&inst->ctrls);
 	inst->ctrls = NULL;
 
 	return 0;
@@ -807,12 +809,10 @@ int msm_vidc_ctrl_init(struct msm_vidc_inst *inst)
 			__func__);
 		return -EINVAL;
 	}
-	inst->ctrls = kcalloc(num_ctrls,
-		sizeof(struct v4l2_ctrl *), GFP_KERNEL);
-	if (!inst->ctrls) {
-		i_vpr_e(inst, "%s: failed to allocate ctrl\n", __func__);
-		return -ENOMEM;
-	}
+	rc = msm_vidc_vmem_alloc(num_ctrls * sizeof(struct v4l2_ctrl *),
+			(void **)&inst->ctrls, __func__);
+	if (rc)
+		return rc;
 
 	rc = v4l2_ctrl_handler_init(&inst->ctrl_handler, num_ctrls);
 	if (rc) {
@@ -1038,19 +1038,29 @@ int msm_v4l2_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 
 	inst = container_of(ctrl->handler,
 			    struct msm_vidc_inst, ctrl_handler);
+	inst = get_inst_ref(g_core, inst);
 	if (!inst) {
-		d_vpr_e("%s: could not find inst for ctrl %s id %#x\n", __func__, ctrl->name, ctrl->id);
+		d_vpr_e("%s: could not find inst for ctrl %s id %#x\n",
+			__func__, ctrl->name, ctrl->id);
 		return -EINVAL;
 	}
+	client_lock(inst, __func__);
+	inst_lock(inst, __func__);
 
 	rc = msm_vidc_get_control(inst, ctrl);
-	if (rc)
+	if (rc) {
 		i_vpr_e(inst, "%s: failed for ctrl %s id %#x\n",
 			__func__, ctrl->name, ctrl->id);
-	else
+		goto unlock;
+	} else {
 		i_vpr_h(inst, "%s: ctrl %s id %#x, value %d\n",
 			__func__, ctrl->name, ctrl->id, ctrl->val);
+	}
 
+unlock:
+	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
+	put_inst(inst);
 	return rc;
 }
 
@@ -1067,6 +1077,12 @@ static int msm_vidc_update_static_property(struct msm_vidc_inst *inst,
 	/* update value to db */
 	msm_vidc_update_cap_value(inst, cap_id, ctrl->val, __func__);
 
+	if (ctrl->id == V4L2_CID_MPEG_VIDC_CLIENT_ID) {
+		rc = msm_vidc_update_debug_str(inst);
+		if (rc)
+			return rc;
+	}
+
 	if (ctrl->id == V4L2_CID_MPEG_VIDC_SECURE) {
 		if (ctrl->val) {
 			rc = msm_vidc_allow_secure_session(inst);
@@ -1107,11 +1123,8 @@ static int msm_vidc_update_static_property(struct msm_vidc_inst *inst,
 			return rc;
 	}
 
-	if (ctrl->id == V4L2_CID_MPEG_VIDC_CRITICAL_PRIORITY) {
-		inst->decode_batch.enable = msm_vidc_allow_decode_batch(inst);
-		msm_vidc_allow_dcvs(inst);
+	if (ctrl->id == V4L2_CID_MPEG_VIDC_CRITICAL_PRIORITY)
 		msm_vidc_update_cap_value(inst, PRIORITY, 0, __func__);
-	}
 
 	if (ctrl->id == V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER) {
 		u32 enable;
@@ -1152,25 +1165,30 @@ int msm_v4l2_op_s_ctrl(struct v4l2_ctrl *ctrl)
 
 	inst = container_of(ctrl->handler,
 		struct msm_vidc_inst, ctrl_handler);
-
+	inst = get_inst_ref(g_core, inst);
 	if (!inst || !inst->capabilities) {
 		d_vpr_e("%s: invalid parameters for inst\n", __func__);
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
+	inst_lock(inst, __func__);
 	capability = inst->capabilities;
 
 	i_vpr_h(inst, FMT_STRING_SET_CTRL,
 		__func__, state_name(inst->state), ctrl->name, ctrl->id, ctrl->val);
 
-	if (!msm_vidc_allow_s_ctrl(inst, ctrl->id))
-		return -EINVAL;
+	if (!msm_vidc_allow_s_ctrl(inst, ctrl->id)) {
+		rc = -EINVAL;
+		goto unlock;
+	}
 
 	cap_id = msm_vidc_get_cap_id(inst, ctrl->id);
 	if (!is_valid_cap_id(cap_id)) {
 		i_vpr_e(inst, "%s: could not find cap_id for ctrl %s\n",
 			__func__, ctrl->name);
-		return -EINVAL;
+		rc = -EINVAL;
+		goto unlock;
 	}
 
 	if (ctrl->id == V4L2_CID_MPEG_VIDC_INPUT_METADATA_FD) {
@@ -1178,16 +1196,18 @@ int msm_v4l2_op_s_ctrl(struct v4l2_ctrl *ctrl)
 			i_vpr_e(inst,
 				"%s: client configured invalid input metadata fd %d\n",
 				__func__, ctrl->val);
-			return 0;
+			rc = 0;
+			goto unlock;
 		}
 		if (!capability->cap[INPUT_META_VIA_REQUEST].value) {
 			i_vpr_e(inst,
 				"%s: input metadata not enabled via request\n", __func__);
-			return -EINVAL;
+			rc = -EINVAL;
+			goto unlock;
 		}
 		rc = msm_vidc_create_input_metadata_buffer(inst, ctrl->val);
 		if (rc)
-			return rc;
+			goto unlock;
 	}
 
 	/* mark client set flag */
@@ -1198,18 +1218,22 @@ int msm_v4l2_op_s_ctrl(struct v4l2_ctrl *ctrl)
 		/* static case */
 		rc = msm_vidc_update_static_property(inst, cap_id, ctrl);
 		if (rc)
-			return rc;
+			goto unlock;
 	} else {
 		/* dynamic case */
 		rc = msm_vidc_adjust_dynamic_property(inst, cap_id, ctrl);
 		if (rc)
-			return rc;
+			goto unlock;
 
 		rc = msm_vidc_set_dynamic_property(inst);
 		if (rc)
-			return rc;
+			goto unlock;
 	}
 
+unlock:
+	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
+	put_inst(inst);
 	return rc;
 }
 
@@ -1718,20 +1742,21 @@ int msm_vidc_adjust_slice_count(void *instance, struct v4l2_ctrl *ctrl)
 	slice_mode = ctrl ? ctrl->val :
 		capability->cap[SLICE_MODE].value;
 
+	if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE)
+		return 0;
+
 	if (msm_vidc_get_parent_value(inst, SLICE_MODE,
 		BITRATE_MODE, &rc_type, __func__) ||
 		msm_vidc_get_parent_value(inst, SLICE_MODE,
 		ALL_INTRA, &all_intra, __func__))
 		return -EINVAL;
 
-	if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE)
-		return 0;
-
 	fps = capability->cap[FRAME_RATE].value >> 16;
 	if (fps > MAX_SLICES_FRAME_RATE ||
 		(rc_type != HFI_RC_OFF &&
 		rc_type != HFI_RC_CBR_CFR &&
-		rc_type != HFI_RC_CBR_VFR) ||
+		rc_type != HFI_RC_CBR_VFR &&
+		rc_type != HFI_RC_VBR_CFR) ||
 		all_intra) {
 		adjusted_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
 		update_cap = SLICE_MODE;
@@ -2061,9 +2086,10 @@ int msm_vidc_adjust_bitrate(void *instance, struct v4l2_ctrl *ctrl)
 	int i, rc = 0;
 	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
 	struct msm_vidc_inst_capability *capability;
-	s32 adjusted_value, max_bitrate, enh_layer_count;
+	s32 adjusted_value, enh_layer_count;
 	u32 cumulative_bitrate = 0, cap_id = 0, cap_value = 0;
 	u32 layer_br_caps[6] = {L0_BR, L1_BR, L2_BR, L3_BR, L4_BR, L5_BR};
+	u32 max_bitrate = 0;
 
 	if (!inst || !inst->capabilities) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -2092,7 +2118,10 @@ int msm_vidc_adjust_bitrate(void *instance, struct v4l2_ctrl *ctrl)
 		ENH_LAYER_COUNT, &enh_layer_count, __func__))
 		return -EINVAL;
 
-	max_bitrate = inst->capabilities->cap[BIT_RATE].max;
+	/* get max bit rate for current session config*/
+	max_bitrate = msm_vidc_get_max_bitrate(inst);
+	if (inst->capabilities->cap[BIT_RATE].value > max_bitrate)
+		msm_vidc_update_cap_value(inst, BIT_RATE, max_bitrate, __func__);
 
 	/*
 	 * ENH_LAYER_COUNT cap max is positive only if
@@ -2566,6 +2595,7 @@ int msm_vidc_adjust_bitrate_boost(void *instance, struct v4l2_ctrl *ctrl)
 	s32 adjusted_value;
 	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
 	s32 min_quality = -1, rc_type = -1;
+	u32 max_bitrate = 0, bitrate = 0;
 
 	if (!inst || !inst->capabilities) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -2599,6 +2629,17 @@ int msm_vidc_adjust_bitrate_boost(void *instance, struct v4l2_ctrl *ctrl)
 		goto adjust;
 	}
 
+	max_bitrate = msm_vidc_get_max_bitrate(inst);
+	bitrate = inst->capabilities->cap[BIT_RATE].value;
+	if (adjusted_value) {
+		if ((bitrate + bitrate / (100 / adjusted_value)) > max_bitrate) {
+			i_vpr_h(inst,
+				"%s: bitrate %d is beyond max bitrate %d, remove bitrate boost\n",
+				__func__, max_bitrate, bitrate);
+			adjusted_value = 0;
+		}
+	}
+
 adjust:
 	msm_vidc_update_cap_value(inst, BITRATE_BOOST,
 		adjusted_value, __func__);
@@ -3165,12 +3206,12 @@ error:
 	list_for_each_entry_safe(entry, temp, &opt_list, list) {
 		i_vpr_e(inst, "%s: opt_list: %s\n", __func__, cap_name(entry->cap_id));
 		list_del_init(&entry->list);
-		kfree(entry);
+		msm_vidc_vmem_free((void **)&entry);
 	}
 	list_for_each_entry_safe(entry, temp, &root_list, list) {
 		i_vpr_e(inst, "%s: root_list: %s\n", __func__, cap_name(entry->cap_id));
 		list_del_init(&entry->list);
-		kfree(entry);
+		msm_vidc_vmem_free((void **)&entry);
 	}
 	return rc;
 }
@@ -4004,7 +4045,6 @@ int msm_vidc_set_preprocess(void *instance,
 	struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
 	u32 hfi_value;
 
-	d_vpr_e("%s: \n", __func__);
 	if (!inst || !inst->capabilities) {
 		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;

+ 13 - 18
driver/vidc/src/msm_vidc_debug.c

@@ -165,19 +165,19 @@ 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;
-	char* dbuf, * cur, * end;
+	char *cur, *end, *dbuf = NULL;
 	ssize_t len = 0;
+	int rc = 0;
 
 	if (!core || !core->dt) {
 		d_vpr_e("%s: invalid params %pK\n", __func__, core);
 		return 0;
 	}
 
-	dbuf = kzalloc(MAX_DBG_BUF_SIZE, GFP_KERNEL);
-	if (!dbuf) {
-		d_vpr_e("%s: Allocation failed!\n", __func__);
-		return -ENOMEM;
-	}
+	rc = msm_vidc_vmem_alloc(MAX_DBG_BUF_SIZE, (void **)&dbuf, __func__);
+	if (rc)
+		return rc;
+
 	cur = dbuf;
 	end = cur + MAX_DBG_BUF_SIZE;
 
@@ -194,7 +194,7 @@ static ssize_t core_info_read(struct file* file, char __user* buf,
 	len = simple_read_from_buffer(buf, count, ppos,
 		dbuf, cur - dbuf);
 
-	kfree(dbuf);
+	msm_vidc_vmem_free((void **)&dbuf);
 	return len;
 }
 
@@ -432,7 +432,7 @@ static ssize_t inst_info_read(struct file *file, char __user *buf,
 	struct core_inst_pair *idata = file->private_data;
 	struct msm_vidc_core *core;
 	struct msm_vidc_inst *inst;
-	char *dbuf, *cur, *end;
+	char *cur, *end, *dbuf = NULL;
 	int i, j;
 	ssize_t len = 0;
 	struct v4l2_format *f;
@@ -452,9 +452,7 @@ static ssize_t inst_info_read(struct file *file, char __user *buf,
 		return 0;
 	}
 
-	dbuf = kzalloc(MAX_DBG_BUF_SIZE, GFP_KERNEL);
-	if (!dbuf) {
-		i_vpr_e(inst, "%s: Allocation failed!\n", __func__);
+	if (msm_vidc_vmem_alloc(MAX_DBG_BUF_SIZE, (void **)&dbuf, __func__)) {
 		len = -ENOMEM;
 		goto failed_alloc;
 	}
@@ -510,7 +508,7 @@ static ssize_t inst_info_read(struct file *file, char __user *buf,
 	len = simple_read_from_buffer(buf, count, ppos,
 		dbuf, cur - dbuf);
 
-	kfree(dbuf);
+	msm_vidc_vmem_free((void **)&dbuf);
 failed_alloc:
 	put_inst(inst);
 	return len;
@@ -542,11 +540,8 @@ struct dentry *msm_vidc_debugfs_init_inst(void *instance, struct dentry *parent)
 	}
 	snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%d", inst->session_id);
 
-	idata = kzalloc(sizeof(struct core_inst_pair), GFP_KERNEL);
-	if (!idata) {
-		i_vpr_e(inst, "%s: Allocation failed!\n", __func__);
+	if (msm_vidc_vmem_alloc(sizeof(struct core_inst_pair), (void **)&idata, __func__))
 		goto exit;
-	}
 
 	idata->core = inst->core;
 	idata->inst = inst;
@@ -576,7 +571,7 @@ failed_create_file:
 	debugfs_remove_recursive(dir);
 	dir = NULL;
 failed_create_dir:
-	kfree(idata);
+	msm_vidc_vmem_free((void **)&idata);
 exit:
 	return dir;
 }
@@ -593,7 +588,7 @@ void msm_vidc_debugfs_deinit_inst(void *instance)
 	if (dentry->d_inode) {
 		i_vpr_l(inst, "%s: Destroy %pK\n",
 			__func__, dentry->d_inode->i_private);
-		kfree(dentry->d_inode->i_private);
+		msm_vidc_vmem_free(&dentry->d_inode->i_private);
 		dentry->d_inode->i_private = NULL;
 	}
 	debugfs_remove_recursive(dentry);

+ 126 - 81
driver/vidc/src/msm_vidc_driver.c

@@ -82,6 +82,8 @@ static const struct msm_vidc_cap_name cap_name_arr[] = {
 	{META_EVA_STATS,                 "META_EVA_STATS"             },
 	{META_ROI_INFO,                  "META_ROI_INFO"              },
 	{META_SALIENCY_INFO,             "META_SALIENCY_INFO"         },
+	{META_TRANSCODING_STAT_INFO,     "META_TRANSCODING_STAT_INFO" },
+	{META_DOLBY_RPU,                 "META_DOLBY_RPU"             },
 	{META_CAP_MAX,                   "META_CAP_MAX"               },
 	{FRAME_WIDTH,                    "FRAME_WIDTH"                },
 	{LOSSLESS_FRAME_WIDTH,           "LOSSLESS_FRAME_WIDTH"       },
@@ -110,6 +112,7 @@ static const struct msm_vidc_cap_name cap_name_arr[] = {
 	{MB_CYCLES_LP,                   "MB_CYCLES_LP"               },
 	{MB_CYCLES_FW,                   "MB_CYCLES_FW"               },
 	{MB_CYCLES_FW_VPP,               "MB_CYCLES_FW_VPP"           },
+	{CLIENT_ID,                      "CLIENT_ID"                  },
 	{SECURE_MODE,                    "SECURE_MODE"                },
 	{FENCE_ID,                       "FENCE_ID"                   },
 	{FENCE_FD,                       "FENCE_FD"                   },
@@ -188,6 +191,10 @@ static const struct msm_vidc_cap_name cap_name_arr[] = {
 	{INPUT_META_VIA_REQUEST,         "INPUT_META_VIA_REQUEST"     },
 	{ENC_IP_CR,                      "ENC_IP_CR"                  },
 	{COMPLEXITY,                     "COMPLEXITY"                 },
+	{CABAC_MAX_BITRATE,              "CABAC_MAX_BITRATE"          },
+	{CAVLC_MAX_BITRATE,              "CAVLC_MAX_BITRATE"          },
+	{ALLINTRA_MAX_BITRATE,           "ALLINTRA_MAX_BITRATE"       },
+	{LOWLATENCY_MAX_BITRATE,         "LOWLATENCY_MAX_BITRATE"     },
 	{PROFILE,                        "PROFILE"                    },
 	{ENH_LAYER_COUNT,                "ENH_LAYER_COUNT"            },
 	{BIT_RATE,                       "BIT_RATE"                   },
@@ -1767,8 +1774,8 @@ static int msm_vidc_flush_pending_last_flag(struct msm_vidc_inst *inst)
 				return rc;
 			}
 			list_del(&resp_work->list);
-			kfree(resp_work->data);
-			kfree(resp_work);
+			msm_vidc_vmem_free((void **)&resp_work->data);
+			msm_vidc_vmem_free((void **)&resp_work);
 		}
 	}
 
@@ -1794,8 +1801,8 @@ static int msm_vidc_discard_pending_opsc(struct msm_vidc_inst *inst)
 			i_vpr_h(inst,
 				"%s: discard pending output psc\n", __func__);
 			list_del(&resp_work->list);
-			kfree(resp_work->data);
-			kfree(resp_work);
+			msm_vidc_vmem_free((void **)&resp_work->data);
+			msm_vidc_vmem_free((void **)&resp_work);
 		}
 	}
 
@@ -1825,8 +1832,8 @@ static int msm_vidc_discard_pending_ipsc(struct msm_vidc_inst *inst)
 			inst->ipsc_properties_set = false;
 
 			list_del(&resp_work->list);
-			kfree(resp_work->data);
-			kfree(resp_work);
+			msm_vidc_vmem_free((void **)&resp_work->data);
+			msm_vidc_vmem_free((void **)&resp_work);
 		}
 	}
 
@@ -1863,8 +1870,8 @@ static int msm_vidc_process_pending_ipsc(struct msm_vidc_inst *inst,
 				}
 			}
 			list_del(&resp_work->list);
-			kfree(resp_work->data);
-			kfree(resp_work);
+			msm_vidc_vmem_free((void **)&resp_work->data);
+			msm_vidc_vmem_free((void **)&resp_work);
 			/* list contains max only one ipsc at anytime */
 			break;
 		}
@@ -2413,7 +2420,7 @@ int msm_vidc_update_input_rate(struct msm_vidc_inst *inst, u64 time_us)
 		prev_timer = input_timer;
 	}
 
-	if (input_timer_sum_us)
+	if (input_timer_sum_us && counter >= INPUT_TIMER_LIST_SIZE)
 		inst->capabilities->cap[INPUT_RATE].value =
 			(s32)(DIV64_U64_ROUND_CLOSEST(counter * 1000000,
 				input_timer_sum_us) << 16);
@@ -3211,7 +3218,7 @@ exit:
 
 static void msm_vidc_update_input_cr(struct msm_vidc_inst *inst, u32 idx, u32 cr)
 {
-	struct msm_vidc_input_cr_data *temp, *next;
+	struct msm_vidc_input_cr_data *temp = NULL, *next = NULL;
 	bool found = false;
 
 	list_for_each_entry_safe(temp, next, &inst->enc_input_crs, list) {
@@ -3222,11 +3229,10 @@ static void msm_vidc_update_input_cr(struct msm_vidc_inst *inst, u32 idx, u32 cr
 		}
 	}
 	if (!found) {
-		temp = kzalloc(sizeof(*temp), GFP_KERNEL);
-		if (!temp) {
-			i_vpr_e(inst, "%s: malloc failure.\n", __func__);
+		temp = NULL;
+		if (msm_vidc_vmem_alloc(sizeof(*temp), (void **)&temp, __func__))
 			return;
-		}
+
 		temp->index = idx;
 		temp->input_cr = cr;
 		list_add_tail(&temp->list, &inst->enc_input_crs);
@@ -3239,7 +3245,7 @@ static void msm_vidc_free_input_cr_list(struct msm_vidc_inst *inst)
 
 	list_for_each_entry_safe(temp, next, &inst->enc_input_crs, list) {
 		list_del(&temp->list);
-		kfree(temp);
+		msm_vidc_vmem_free((void **)&temp);
 	}
 	INIT_LIST_HEAD(&inst->enc_input_crs);
 }
@@ -3902,7 +3908,6 @@ static int msm_vidc_vb2_buffer_done(struct msm_vidc_inst *inst,
 	vbuf->flags = buf->flags;
 	vb2->timestamp = buf->timestamp;
 	vb2->planes[0].bytesused = buf->data_size + vb2->planes[0].data_offset;
-	v4l2_ctrl_request_complete(vb2->req_obj.req, &inst->ctrl_handler);
 	vb2_buffer_done(vb2, state);
 
 	return 0;
@@ -4098,22 +4103,20 @@ int msm_vidc_vb2_queue_init(struct msm_vidc_inst *inst)
 	}
 	inst->event_handler.m2m_ctx = inst->m2m_ctx;
 
-	inst->bufq[INPUT_META_PORT].vb2q = kzalloc(sizeof(struct vb2_queue), GFP_KERNEL);
-	if (!inst->bufq[INPUT_META_PORT].vb2q) {
-		i_vpr_e(inst, "%s: queue allocation failed for input meta port\n", __func__);
+	rc = msm_vidc_vmem_alloc(sizeof(struct vb2_queue),
+			(void **)&inst->bufq[INPUT_META_PORT].vb2q, "input meta port");
+	if (rc)
 		goto fail_in_meta_alloc;
-	}
 
 	/* do input meta port queues initialization */
 	rc = vb2q_init(inst, inst->bufq[INPUT_META_PORT].vb2q, INPUT_META_PLANE);
 	if (rc)
 		goto fail_in_meta_vb2q_init;
 
-	inst->bufq[OUTPUT_META_PORT].vb2q = kzalloc(sizeof(struct vb2_queue), GFP_KERNEL);
-	if (!inst->bufq[OUTPUT_META_PORT].vb2q) {
-		i_vpr_e(inst, "%s: queue allocation failed for output meta port\n", __func__);
+	rc = msm_vidc_vmem_alloc(sizeof(struct vb2_queue),
+			(void **)&inst->bufq[OUTPUT_META_PORT].vb2q, "output meta port");
+	if (rc)
 		goto fail_out_meta_alloc;
-	}
 
 	/* do output meta port queues initialization */
 	rc = vb2q_init(inst, inst->bufq[OUTPUT_META_PORT].vb2q, OUTPUT_META_PLANE);
@@ -4124,12 +4127,12 @@ int msm_vidc_vb2_queue_init(struct msm_vidc_inst *inst)
 	return 0;
 
 fail_out_meta_vb2q_init:
-	kfree(inst->bufq[OUTPUT_META_PORT].vb2q);
+	msm_vidc_vmem_free((void **)&inst->bufq[OUTPUT_META_PORT].vb2q);
 	inst->bufq[OUTPUT_META_PORT].vb2q = NULL;
 fail_out_meta_alloc:
 	vb2_queue_release(inst->bufq[INPUT_META_PORT].vb2q);
 fail_in_meta_vb2q_init:
-	kfree(inst->bufq[INPUT_META_PORT].vb2q);
+	msm_vidc_vmem_free((void **)&inst->bufq[INPUT_META_PORT].vb2q);
 	inst->bufq[INPUT_META_PORT].vb2q = NULL;
 fail_in_meta_alloc:
 	v4l2_m2m_ctx_release(inst->m2m_ctx);
@@ -4155,10 +4158,10 @@ int msm_vidc_vb2_queue_deinit(struct msm_vidc_inst *inst)
 	}
 
 	vb2_queue_release(inst->bufq[OUTPUT_META_PORT].vb2q);
-	kfree(inst->bufq[OUTPUT_META_PORT].vb2q);
+	msm_vidc_vmem_free((void **)&inst->bufq[OUTPUT_META_PORT].vb2q);
 	inst->bufq[OUTPUT_META_PORT].vb2q = NULL;
 	vb2_queue_release(inst->bufq[INPUT_META_PORT].vb2q);
-	kfree(inst->bufq[INPUT_META_PORT].vb2q);
+	msm_vidc_vmem_free((void **)&inst->bufq[INPUT_META_PORT].vb2q);
 	inst->bufq[INPUT_META_PORT].vb2q = NULL;
 	/*
 	 * vb2_queue_release() for input and output queues
@@ -4282,11 +4285,9 @@ int msm_vidc_session_open(struct msm_vidc_inst *inst)
 	}
 
 	inst->packet_size = 4096;
-	inst->packet = kzalloc(inst->packet_size, GFP_KERNEL);
-	if (!inst->packet) {
-		i_vpr_e(inst, "%s(): inst packet allocation failed\n", __func__);
-		return -ENOMEM;
-	}
+	rc = msm_vidc_vmem_alloc(inst->packet_size, (void **)&inst->packet, __func__);
+	if (rc)
+		return rc;
 
 	rc = venus_hfi_session_open(inst);
 	if (rc)
@@ -4295,7 +4296,7 @@ int msm_vidc_session_open(struct msm_vidc_inst *inst)
 	return 0;
 error:
 	i_vpr_e(inst, "%s(): session open failed\n", __func__);
-	kfree(inst->packet);
+	msm_vidc_vmem_free((void **)&inst->packet);
 	inst->packet = NULL;
 	return rc;
 }
@@ -4480,7 +4481,7 @@ int msm_vidc_session_close(struct msm_vidc_inst *inst)
 
 	/* we are not supposed to send any more commands after close */
 	i_vpr_h(inst, "%s: free session packet data\n", __func__);
-	kfree(inst->packet);
+	msm_vidc_vmem_free((void **)&inst->packet);
 	inst->packet = NULL;
 
 	core = inst->core;
@@ -4559,7 +4560,7 @@ int msm_vidc_deinit_core_caps(struct msm_vidc_core *core)
 		return -EINVAL;
 	}
 
-	kfree(core->capabilities);
+	msm_vidc_vmem_free((void **)&core->capabilities);
 	core->capabilities = NULL;
 	d_vpr_h("%s: Core capabilities freed\n", __func__);
 
@@ -4586,15 +4587,10 @@ int msm_vidc_init_core_caps(struct msm_vidc_core *core)
 			goto exit;
 	}
 
-	core->capabilities = kcalloc(1,
-		(sizeof(struct msm_vidc_core_capability) *
-		(CORE_CAP_MAX + 1)), GFP_KERNEL);
-	if (!core->capabilities) {
-		d_vpr_e("%s: failed to allocate core capabilities\n",
-			__func__);
-		rc = -ENOMEM;
+	rc = msm_vidc_vmem_alloc((sizeof(struct msm_vidc_core_capability) *
+		(CORE_CAP_MAX + 1)), (void **)&core->capabilities, __func__);
+	if (rc)
 		goto exit;
-	}
 
 	num_platform_caps = core->platform->data.core_data_size;
 
@@ -4663,7 +4659,7 @@ int msm_vidc_deinit_instance_caps(struct msm_vidc_core *core)
 		return -EINVAL;
 	}
 
-	kfree(core->inst_caps);
+	msm_vidc_vmem_free((void **)&core->inst_caps);
 	core->inst_caps = NULL;
 	d_vpr_h("%s: core->inst_caps freed\n", __func__);
 
@@ -4713,15 +4709,10 @@ int msm_vidc_init_instance_caps(struct msm_vidc_core *core)
 	COUNT_BITS(count_bits, codecs_count);
 
 	core->codecs_count = codecs_count;
-	core->inst_caps = kcalloc(codecs_count,
-		sizeof(struct msm_vidc_inst_capability),
-		GFP_KERNEL);
-	if (!core->inst_caps) {
-		d_vpr_e("%s: failed to allocate core capabilities\n",
-			__func__);
-		rc = -ENOMEM;
+	rc = msm_vidc_vmem_alloc(codecs_count * sizeof(struct msm_vidc_inst_capability),
+		(void **)&core->inst_caps, __func__);
+	if (rc)
 		goto error;
-	}
 
 	check_bit = 0;
 	/* determine codecs for enc domain */
@@ -5558,25 +5549,25 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
 
 	list_for_each_entry_safe(work, dummy_work, &inst->response_works, list) {
 		list_del(&work->list);
-		kfree(work->data);
-		kfree(work);
+		msm_vidc_vmem_free((void **)&work->data);
+		msm_vidc_vmem_free((void **)&work);
 	}
 
 	list_for_each_entry_safe(entry, dummy_entry, &inst->firmware_list, list) {
 		i_vpr_e(inst, "%s: fw list: %s\n", __func__, cap_name(entry->cap_id));
 		list_del(&entry->list);
-		kfree(entry);
+		msm_vidc_vmem_free((void **)&entry);
 	}
 
 	list_for_each_entry_safe(entry, dummy_entry, &inst->children_list, list) {
 		i_vpr_e(inst, "%s: child list: %s\n", __func__, cap_name(entry->cap_id));
 		list_del(&entry->list);
-		kfree(entry);
+		msm_vidc_vmem_free((void **)&entry);
 	}
 
 	list_for_each_entry_safe(entry, dummy_entry, &inst->caps_list, list) {
 		list_del(&entry->list);
-		kfree(entry);
+		msm_vidc_vmem_free((void **)&entry);
 	}
 
 	list_for_each_entry_safe(fence, dummy_fence, &inst->fence_list, list) {
@@ -5606,10 +5597,11 @@ static void msm_vidc_close_helper(struct kref *kref)
 	if (inst->response_workq)
 		destroy_workqueue(inst->response_workq);
 	msm_vidc_remove_dangling_session(inst);
+	mutex_destroy(&inst->client_lock);
 	mutex_destroy(&inst->request_lock);
 	mutex_destroy(&inst->lock);
-	kfree(inst->capabilities);
-	kfree(inst);
+	msm_vidc_vmem_free((void **)&inst->capabilities);
+	msm_vidc_vmem_free((void **)&inst);
 }
 
 struct msm_vidc_inst *get_inst_ref(struct msm_vidc_core *core,
@@ -5698,6 +5690,21 @@ void inst_unlock(struct msm_vidc_inst *inst, const char *function)
 	mutex_unlock(&inst->lock);
 }
 
+bool client_lock_check(struct msm_vidc_inst *inst, const char *func)
+{
+	return mutex_is_locked(&inst->client_lock);
+}
+
+void client_lock(struct msm_vidc_inst *inst, const char *function)
+{
+	mutex_lock(&inst->client_lock);
+}
+
+void client_unlock(struct msm_vidc_inst *inst, const char *function)
+{
+	mutex_unlock(&inst->client_lock);
+}
+
 int msm_vidc_update_bitstream_buffer_size(struct msm_vidc_inst *inst)
 {
 	struct msm_vidc_core *core;
@@ -5853,8 +5860,8 @@ void msm_vidc_schedule_core_deinit(struct msm_vidc_core *core)
 static const char *get_codec_str(enum msm_vidc_codec_type type)
 {
 	switch (type) {
-	case MSM_VIDC_H264: return "h264";
-	case MSM_VIDC_HEVC: return "h265";
+	case MSM_VIDC_H264: return " avc";
+	case MSM_VIDC_HEVC: return "hevc";
 	case MSM_VIDC_VP9:  return " vp9";
 	case MSM_VIDC_AV1:  return " av1";
 	case MSM_VIDC_HEIC: return "heic";
@@ -5866,8 +5873,8 @@ static const char *get_codec_str(enum msm_vidc_codec_type type)
 static const char *get_domain_str(enum msm_vidc_domain_type type)
 {
 	switch (type) {
-	case MSM_VIDC_ENCODER: return "e";
-	case MSM_VIDC_DECODER: return "d";
+	case MSM_VIDC_ENCODER: return "E";
+	case MSM_VIDC_DECODER: return "D";
 	}
 
 	return ".";
@@ -5876,6 +5883,7 @@ static const char *get_domain_str(enum msm_vidc_domain_type type)
 int msm_vidc_update_debug_str(struct msm_vidc_inst *inst)
 {
 	u32 sid;
+	int client_id = INVALID_CLIENT_ID;
 	const char *codec;
 	const char *domain;
 
@@ -5883,10 +5891,20 @@ int msm_vidc_update_debug_str(struct msm_vidc_inst *inst)
 		d_vpr_e("%s: Invalid params\n", __func__);
 		return -EINVAL;
 	}
+
+	if (inst->capabilities)
+		client_id = inst->capabilities->cap[CLIENT_ID].value;
+
 	sid = inst->session_id;
 	codec = get_codec_str(inst->codec);
 	domain = get_domain_str(inst->domain);
-	snprintf(inst->debug_str, sizeof(inst->debug_str), "%08x: %s%s", sid, codec, domain);
+	if (client_id != INVALID_CLIENT_ID) {
+		snprintf(inst->debug_str, sizeof(inst->debug_str), "%08x: %s%s_%d",
+			sid, codec, domain, client_id);
+	} else {
+		snprintf(inst->debug_str, sizeof(inst->debug_str), "%08x: %s%s",
+			sid, codec, domain);
+	}
 	d_vpr_h("%s: sid: %08x, codec: %s, domain: %s, final: %s\n",
 		__func__, sid, codec, domain, inst->debug_str);
 
@@ -5991,7 +6009,7 @@ int msm_vidc_check_core_mbps(struct msm_vidc_inst *inst)
 			continue;
 
 		/* ignore thumbnail, image, and non realtime sessions */
-		if (msm_vidc_ignore_session_load(inst))
+		if (msm_vidc_ignore_session_load(instance))
 			continue;
 
 		mbps = msm_vidc_get_inst_load(instance);
@@ -6016,10 +6034,10 @@ int msm_vidc_check_core_mbps(struct msm_vidc_inst *inst)
 			core_lock(core, __func__);
 			list_for_each_entry(instance, &core->instances, list) {
 				/* reduce realtime decode sessions priority */
-				if (is_decode_session(inst) && is_realtime_session(inst)) {
+				if (is_decode_session(instance) && is_realtime_session(instance)) {
 					instance->adjust_priority = RT_DEC_DOWN_PRORITY_OFFSET;
 					i_vpr_h(inst, "%s: pending adjust priority by %d\n",
-						__func__, inst->adjust_priority);
+						__func__, instance->adjust_priority);
 				}
 			}
 			core_unlock(core, __func__);
@@ -6092,7 +6110,7 @@ int msm_vidc_check_core_mbpf(struct msm_vidc_inst *inst)
 	core_lock(core, __func__);
 	/* check real-time video sessions max limit */
 	list_for_each_entry(instance, &core->instances, list) {
-		if (msm_vidc_ignore_session_load(inst))
+		if (msm_vidc_ignore_session_load(instance))
 			continue;
 
 		video_rt_mbpf += msm_vidc_get_mbs_per_frame(instance);
@@ -6137,6 +6155,43 @@ static int msm_vidc_check_inst_mbpf(struct msm_vidc_inst *inst)
 	return 0;
 }
 
+u32 msm_vidc_get_max_bitrate(struct msm_vidc_inst* inst)
+{
+	struct msm_vidc_inst_capability *capability;
+	u32 max_bitrate = 0x7fffffff;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+
+	if (inst->capabilities->cap[LOWLATENCY_MODE].value)
+		max_bitrate = min(max_bitrate,
+			(u32)inst->capabilities->cap[LOWLATENCY_MAX_BITRATE].max);
+
+	if (inst->capabilities->cap[ALL_INTRA].value)
+		max_bitrate = min(max_bitrate,
+			(u32)inst->capabilities->cap[ALLINTRA_MAX_BITRATE].max);
+
+	if (inst->codec == MSM_VIDC_HEVC) {
+		max_bitrate = min(max_bitrate,
+			(u32)inst->capabilities->cap[CABAC_MAX_BITRATE].max);
+	} else if (inst->codec == MSM_VIDC_H264) {
+		if (inst->capabilities->cap[ENTROPY_MODE].value ==
+			V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC)
+			max_bitrate = min(max_bitrate,
+				(u32)inst->capabilities->cap[CAVLC_MAX_BITRATE].max);
+		else
+			max_bitrate = min(max_bitrate,
+				(u32)inst->capabilities->cap[CABAC_MAX_BITRATE].max);
+	}
+	if (max_bitrate == 0x7fffffff || !max_bitrate)
+		max_bitrate = min(max_bitrate, (u32)inst->capabilities->cap[BIT_RATE].max);
+
+	return max_bitrate;
+}
+
 static bool msm_vidc_allow_image_encode_session(struct msm_vidc_inst *inst)
 {
 	struct msm_vidc_inst_capability *capability;
@@ -6180,16 +6235,6 @@ static bool msm_vidc_allow_image_encode_session(struct msm_vidc_inst *inst)
 		goto exit;
 	}
 
-	/* is input grid aligned */
-	fmt = &inst->fmts[INPUT_PORT];
-	allow = IS_ALIGNED(fmt->fmt.pix_mp.width, HEIC_GRID_DIMENSION);
-	allow &= IS_ALIGNED(fmt->fmt.pix_mp.height, HEIC_GRID_DIMENSION);
-	if (!allow) {
-		i_vpr_e(inst, "%s: input is not grid aligned: %u x %u\n", __func__,
-			fmt->fmt.pix_mp.width, fmt->fmt.pix_mp.height);
-		goto exit;
-	}
-
 	/* is output grid dimension */
 	fmt = &inst->fmts[OUTPUT_PORT];
 	allow = fmt->fmt.pix_mp.width == HEIC_GRID_DIMENSION;
@@ -6201,7 +6246,7 @@ static bool msm_vidc_allow_image_encode_session(struct msm_vidc_inst *inst)
 	}
 
 	/* is bitrate mode CQ */
-	allow = capability->cap[BITRATE_MODE].value == HFI_RC_CQ;
+	allow = capability->cap[BITRATE_MODE].value == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ;
 	if (!allow) {
 		i_vpr_e(inst, "%s: bitrate mode is not CQ: %#x\n", __func__,
 			capability->cap[BITRATE_MODE].value);
@@ -6334,7 +6379,7 @@ static int msm_vidc_check_max_sessions(struct msm_vidc_inst *inst)
 	core_lock(core, __func__);
 	list_for_each_entry(i, &core->instances, list) {
 		/* skip image sessions count */
-		if (is_image_session(inst))
+		if (is_image_session(i))
 			continue;
 
 		if (is_decode_session(i)) {

+ 10 - 10
driver/vidc/src/msm_vidc_dt.c

@@ -344,11 +344,10 @@ static int msm_vidc_load_bus_table(struct msm_vidc_core *core)
 	buses->count = num_buses;
 	d_vpr_h("Found %d bus interconnects\n", num_buses);
 
-	bus_ranges = kzalloc(2 * num_buses * sizeof(*bus_ranges), GFP_KERNEL);
-	if (!bus_ranges) {
-		d_vpr_e("No memory to read bus ranges\n");
-		return -ENOMEM;
-	}
+	rc = msm_vidc_vmem_alloc(2 * num_buses * sizeof(*bus_ranges),
+					(void **)&bus_ranges, " for bus ranges");
+	if (rc)
+		return rc;
 
 	rc = of_property_read_u32_array(pdev->dev.of_node,
 				"qcom,bus-range-kbps", bus_ranges,
@@ -385,7 +384,7 @@ static int msm_vidc_load_bus_table(struct msm_vidc_core *core)
 	}
 
 exit:
-	kfree(bus_ranges);
+	msm_vidc_vmem_free((void **) &bus_ranges);
 	return rc;
 }
 
@@ -942,12 +941,13 @@ void msm_vidc_deinit_dt(struct platform_device *pdev)
 	msm_vidc_free_qdss_addr_table(core->dt);
 	msm_vidc_free_bus_table(core->dt);
 	msm_vidc_free_buffer_usage_table(core->dt);
+	msm_vidc_vmem_free((void **)&core->dt);
 }
 
 int msm_vidc_init_dt(struct platform_device *pdev)
 {
 	int rc = 0;
-	struct msm_vidc_dt *dt;
+	struct msm_vidc_dt *dt = NULL;
 	struct msm_vidc_core *core;
 
 	if (!pdev) {
@@ -962,9 +962,9 @@ int msm_vidc_init_dt(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	dt = kzalloc(sizeof(struct msm_vidc_dt), GFP_KERNEL);
-	if (!dt)
-		return -ENOMEM;
+	rc = msm_vidc_vmem_alloc(sizeof(struct msm_vidc_dt), (void **)&dt, __func__);
+	if (rc)
+		return rc;
 
 	core->dt = dt;
 	dt->core = core;

+ 10 - 28
driver/vidc/src/msm_vidc_fence.c

@@ -38,7 +38,7 @@ static void msm_vidc_dma_fence_release(struct dma_fence *df)
 	if (df) {
 		fence = container_of(df, struct msm_vidc_fence, dma_fence);
 		d_vpr_l("%s: name %s\n", __func__, fence->name);
-		kfree(fence);
+		msm_vidc_vmem_free((void **)&fence);
 	} else {
 		d_vpr_e("%s: invalid fence\n", __func__);
 	}
@@ -52,24 +52,21 @@ static const struct dma_fence_ops msm_vidc_dma_fence_ops = {
 
 struct msm_vidc_fence *msm_vidc_fence_create(struct msm_vidc_inst *inst)
 {
-	struct msm_vidc_fence *fence;
+	struct msm_vidc_fence *fence = NULL;
+	int rc = 0;
 
 	if (!inst) {
 		d_vpr_e("%s: invalid params\n", __func__);
 		return NULL;
 	}
 
-	fence = kzalloc(sizeof(*fence), GFP_KERNEL);
-	if (!fence) {
-		i_vpr_e(inst, "%s: failed to allocate memory for fence\n",
-			__func__);
+	rc = msm_vidc_vmem_alloc(sizeof(*fence), (void **)&fence, __func__);
+	if (rc)
 		return NULL;
-	}
 
 	fence->fd = INVALID_FD;
-	spin_lock_init(&fence->lock);
 	dma_fence_init(&fence->dma_fence, &msm_vidc_dma_fence_ops,
-		&fence->lock, inst->fence_context.ctx_num,
+		&inst->fence_context.lock, inst->fence_context.ctx_num,
 		++inst->fence_context.seq_num);
 	snprintf(fence->name, sizeof(fence->name), "%s: %llu",
 		inst->fence_context.name, inst->fence_context.seq_num);
@@ -95,18 +92,6 @@ int msm_vidc_create_fence_fd(struct msm_vidc_inst *inst,
 		return -EINVAL;
 	}
 
-	/*
-	 * Acquire inst->lock for fence fd creation
-	 * to avoid sync_file_create() and sync_file_poll()
-	 * race conditions in e2e playback usecase.
-	 */
-	inst = get_inst_ref(g_core, inst);
-	if (!inst) {
-		d_vpr_e("%s: invalid params\n", __func__);
-		return -EINVAL;
-	}
-	inst_lock(inst, __func__);
-
 	fence->fd = get_unused_fd_flags(0);
 	if (fence->fd < 0) {
 		i_vpr_e(inst, "%s: getting fd (%d) failed\n", __func__,
@@ -125,15 +110,11 @@ int msm_vidc_create_fence_fd(struct msm_vidc_inst *inst,
 	i_vpr_l(inst, "%s: created fd %d for fence %s\n", __func__,
 		fence->fd, fence->name);
 
-	inst_unlock(inst, __func__);
-	put_inst(inst);
 	return 0;
 
 err_sync_file:
 	put_unused_fd(fence->fd);
 err_fd:
-	inst_unlock(inst, __func__);
-	put_inst(inst);
 	return rc;
 }
 
@@ -173,16 +154,16 @@ int msm_vidc_fence_signal(struct msm_vidc_inst *inst, u32 fence_id)
 
 	fence = msm_vidc_get_fence_from_id(inst, fence_id);
 	if (!fence) {
-		i_vpr_e(inst, "%s: no fence available to signal with id: %u",
+		i_vpr_e(inst, "%s: no fence available to signal with id: %u\n",
 			__func__, fence_id);
 		rc = -EINVAL;
 		goto exit;
 	}
 
 	i_vpr_l(inst, "%s: fence %s\n", __func__, fence->name);
+	list_del_init(&fence->list);
 	dma_fence_signal(&fence->dma_fence);
 	dma_fence_put(&fence->dma_fence);
-	list_del_init(&fence->list);
 
 exit:
 	return rc;
@@ -204,10 +185,10 @@ void msm_vidc_fence_destroy(struct msm_vidc_inst *inst, u32 fence_id)
 	}
 
 	i_vpr_e(inst, "%s: fence %s\n", __func__, fence->name);
+	list_del_init(&fence->list);
 	dma_fence_set_error(&fence->dma_fence, -EINVAL);
 	dma_fence_signal(&fence->dma_fence);
 	dma_fence_put(&fence->dma_fence);
-	list_del_init(&fence->list);
 }
 
 int msm_vidc_fence_init(struct msm_vidc_inst *inst)
@@ -220,6 +201,7 @@ int msm_vidc_fence_init(struct msm_vidc_inst *inst)
 	}
 
 	inst->fence_context.ctx_num = dma_fence_context_alloc(1);
+	spin_lock_init(&inst->fence_context.lock);
 	snprintf(inst->fence_context.name, sizeof(inst->fence_context.name),
 		"msm_vidc_fence: %s: %llu", inst->debug_str,
 		inst->fence_context.ctx_num);

+ 31 - 7
driver/vidc/src/msm_vidc_memory.c

@@ -314,6 +314,31 @@ exit:
 	return rc;
 }
 
+int msm_vidc_vmem_alloc(unsigned long size, void **mem, const char *msg)
+{
+	int rc = 0;
+	if (*mem) {
+		d_vpr_e("%s: error: double alloc\n", msg);
+		rc = -EINVAL;
+	}
+
+	*mem = vzalloc(size);
+	if (!*mem) {
+		d_vpr_e("allocation failed for %s\n", msg);
+		rc = -ENOMEM;
+	}
+
+	return rc;
+}
+
+void msm_vidc_vmem_free(void **addr)
+{
+	if (addr && *addr) {
+		vfree(*addr);
+		*addr = NULL;
+	}
+}
+
 int msm_vidc_memory_alloc(struct msm_vidc_core *core, struct msm_vidc_alloc *mem)
 {
 	int rc = 0;
@@ -448,7 +473,7 @@ int msm_vidc_memory_free(struct msm_vidc_core *core, struct msm_vidc_alloc *mem)
 
 void *msm_memory_pool_alloc(struct msm_vidc_inst *inst, enum msm_memory_pool_type type)
 {
-	struct msm_memory_alloc_header *hdr;
+	struct msm_memory_alloc_header *hdr = NULL;
 	struct msm_memory_pool *pool;
 
 	if (!inst || type < 0 || type >= MSM_MEM_POOL_MAX) {
@@ -475,11 +500,10 @@ void *msm_memory_pool_alloc(struct msm_vidc_inst *inst, enum msm_memory_pool_typ
 		return hdr->buf;
 	}
 
-	hdr = kzalloc(pool->size + sizeof(struct msm_memory_alloc_header), GFP_KERNEL);
-	if (!hdr) {
-		i_vpr_e(inst, "%s: buffer allocation failed\n", __func__);
+	if (msm_vidc_vmem_alloc(pool->size + sizeof(struct msm_memory_alloc_header),
+			(void **)&hdr, __func__))
 		return NULL;
-	}
+
 	INIT_LIST_HEAD(&hdr->list);
 	hdr->type = type;
 	hdr->busy = true;
@@ -549,14 +573,14 @@ static void msm_vidc_destroy_pool_buffers(struct msm_vidc_inst *inst,
 	/* destroy all free buffers */
 	list_for_each_entry_safe(hdr, dummy, &pool->free_pool, list) {
 		list_del(&hdr->list);
-		kfree(hdr);
+		msm_vidc_vmem_free((void **)&hdr);
 		fcount++;
 	}
 
 	/* destroy all busy buffers */
 	list_for_each_entry_safe(hdr, dummy, &pool->busy_pool, list) {
 		list_del(&hdr->list);
-		kfree(hdr);
+		msm_vidc_vmem_free((void **)&hdr);
 		bcount++;
 	}
 

+ 9 - 0
driver/vidc/src/msm_vidc_power.c

@@ -270,6 +270,15 @@ int msm_vidc_scale_buses(struct msm_vidc_inst *inst)
 				vote_data->color_formats[0] = MSM_VIDC_FMT_NV12;
 			}
 			vote_data->color_formats[1] = color_format;
+		} else if (inst->codec == MSM_VIDC_AV1 &&
+			inst->capabilities->cap[FILM_GRAIN].value) {
+			/*
+			 * UBWC formats with AV1 film grain requires dpb-opb
+			 * split mode
+			 */
+			vote_data->num_formats = 2;
+			vote_data->color_formats[0] =
+				vote_data->color_formats[1] = color_format;
 		} else {
 			vote_data->num_formats = 1;
 			vote_data->color_formats[0] = color_format;

+ 18 - 22
driver/vidc/src/msm_vidc_probe.c

@@ -16,6 +16,7 @@
 #include "msm_vidc_dt.h"
 #include "msm_vidc_platform.h"
 #include "msm_vidc_core.h"
+#include "msm_vidc_memory.h"
 #include "venus_hfi.h"
 #include "video_generated_h"
 
@@ -262,8 +263,8 @@ static int msm_vidc_deinitialize_core(struct msm_vidc_core *core)
 	mutex_destroy(&core->lock);
 	msm_vidc_change_core_state(core, MSM_VIDC_CORE_DEINIT, __func__);
 
-	kfree(core->response_packet);
-	kfree(core->packet);
+	msm_vidc_vmem_free((void **)&core->response_packet);
+	msm_vidc_vmem_free((void **)&core->packet);
 	core->response_packet = NULL;
 	core->packet = NULL;
 
@@ -305,21 +306,16 @@ static int msm_vidc_initialize_core(struct msm_vidc_core *core)
 		goto exit;
 	}
 
-	core->packet_size = 4096;
-	core->packet = kzalloc(core->packet_size, GFP_KERNEL);
-	if (!core->packet) {
-		d_vpr_e("%s(): core packet allocation failed\n", __func__);
-		rc = -ENOMEM;
+	core->packet_size = VIDC_IFACEQ_VAR_HUGE_PKT_SIZE;
+	rc = msm_vidc_vmem_alloc(core->packet_size,
+			(void **)&core->packet, "core packet");
+	if (rc)
 		goto exit;
-	}
 
-	core->response_packet = kzalloc(core->packet_size, GFP_KERNEL);
-	if (!core->response_packet) {
-		d_vpr_e("%s(): core response packet allocation failed\n",
-			__func__);
-		rc = -ENOMEM;
+	rc = msm_vidc_vmem_alloc(core->packet_size,
+			(void **)&core->response_packet, "core response packet");
+	if (rc)
 		goto exit;
-	}
 
 	mutex_init(&core->lock);
 	INIT_LIST_HEAD(&core->instances);
@@ -331,8 +327,8 @@ static int msm_vidc_initialize_core(struct msm_vidc_core *core)
 
 	return 0;
 exit:
-	kfree(core->response_packet);
-	kfree(core->packet);
+	msm_vidc_vmem_free((void **)&core->response_packet);
+	msm_vidc_vmem_free((void **)&core->packet);
 	core->response_packet = NULL;
 	core->packet = NULL;
 	if (core->batch_workq)
@@ -396,7 +392,7 @@ static int msm_vidc_remove_video_device(struct platform_device *pdev)
 
 	dev_set_drvdata(&pdev->dev, NULL);
 	debugfs_remove_recursive(core->debugfs_parent);
-	kfree(core);
+	msm_vidc_vmem_free((void **)&core);
 	g_core = NULL;
 
 	return 0;
@@ -432,14 +428,14 @@ static int msm_vidc_remove(struct platform_device *pdev)
 static int msm_vidc_probe_video_device(struct platform_device *pdev)
 {
 	int rc = 0;
-	struct msm_vidc_core *core;
+	struct msm_vidc_core *core = NULL;
 	int nr = BASE_DEVICE_NUMBER;
 
 	d_vpr_h("%s()\n", __func__);
 
-	core = kzalloc(sizeof(*core), GFP_KERNEL);
-	if (!core)
-		return -ENOMEM;
+	rc = msm_vidc_vmem_alloc(sizeof(*core), (void **)&core, __func__);
+	if (rc)
+		return rc;
 	g_core = core;
 
 	core->debugfs_parent = msm_vidc_debugfs_init_drv();
@@ -589,7 +585,7 @@ init_dt_failed:
 init_core_failed:
 	dev_set_drvdata(&pdev->dev, NULL);
 	debugfs_remove_recursive(core->debugfs_parent);
-	kfree(core);
+	msm_vidc_vmem_free((void **)&core);
 	g_core = NULL;
 
 	return rc;

+ 48 - 0
driver/vidc/src/msm_vidc_v4l2.c

@@ -76,6 +76,7 @@ int msm_v4l2_querycap(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	rc = msm_vidc_querycap((void *)inst, cap);
 	if (rc)
@@ -83,6 +84,7 @@ int msm_v4l2_querycap(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -100,6 +102,7 @@ int msm_v4l2_enum_fmt(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	rc = msm_vidc_enum_fmt((void *)inst, f);
 	if (rc)
@@ -107,6 +110,7 @@ int msm_v4l2_enum_fmt(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -123,6 +127,7 @@ int msm_v4l2_try_fmt(struct file *filp, void *fh, struct v4l2_format *f)
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	if (is_session_error(inst)) {
 		i_vpr_e(inst, "%s: inst in error state\n", __func__);
@@ -135,6 +140,7 @@ int msm_v4l2_try_fmt(struct file *filp, void *fh, struct v4l2_format *f)
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -152,6 +158,7 @@ int msm_v4l2_s_fmt(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	if (is_session_error(inst)) {
 		i_vpr_e(inst, "%s: inst in error state\n", __func__);
@@ -164,6 +171,7 @@ int msm_v4l2_s_fmt(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -181,6 +189,7 @@ int msm_v4l2_g_fmt(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	rc = msm_vidc_g_fmt((void *)inst, f);
 	if (rc)
@@ -188,6 +197,7 @@ int msm_v4l2_g_fmt(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -205,6 +215,7 @@ int msm_v4l2_s_selection(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	if (is_session_error(inst)) {
 		i_vpr_e(inst, "%s: inst in error state\n", __func__);
@@ -217,6 +228,7 @@ int msm_v4l2_s_selection(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -234,6 +246,7 @@ int msm_v4l2_g_selection(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	rc = msm_vidc_g_selection((void *)inst, s);
 	if (rc)
@@ -241,6 +254,7 @@ int msm_v4l2_g_selection(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -258,6 +272,7 @@ int msm_v4l2_s_parm(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	if (is_session_error(inst)) {
 		i_vpr_e(inst, "%s: inst in error state\n", __func__);
@@ -270,6 +285,7 @@ int msm_v4l2_s_parm(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -287,6 +303,7 @@ int msm_v4l2_g_parm(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	rc = msm_vidc_g_param((void *)inst, a);
 	if (rc)
@@ -294,6 +311,7 @@ int msm_v4l2_g_parm(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -311,6 +329,7 @@ int msm_v4l2_reqbufs(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	rc = msm_vidc_reqbufs((void *)inst, b);
 	if (rc)
@@ -318,6 +337,7 @@ int msm_v4l2_reqbufs(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -335,6 +355,7 @@ int msm_v4l2_querybuf(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	rc = msm_vidc_querybuf((void *)inst, b);
 	if (rc)
@@ -342,6 +363,7 @@ int msm_v4l2_querybuf(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -360,12 +382,14 @@ int msm_v4l2_create_bufs(struct file *filp, void *fh,
 	}
 
 	inst_lock(inst, __func__);
+	client_lock(inst, __func__);
 	rc = msm_vidc_create_bufs((void *)inst, b);
 	if (rc)
 		goto unlock;
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -384,6 +408,7 @@ int msm_v4l2_prepare_buf(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	rc = msm_vidc_prepare_buf((void *)inst, vdev->v4l2_dev->mdev, b);
 	if (rc)
@@ -391,6 +416,7 @@ int msm_v4l2_prepare_buf(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -439,6 +465,7 @@ int msm_v4l2_dqbuf(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	rc = msm_vidc_dqbuf(inst, b);
 	if (rc)
@@ -446,6 +473,7 @@ int msm_v4l2_dqbuf(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -508,6 +536,7 @@ int msm_v4l2_subscribe_event(struct v4l2_fh *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	if (is_session_error(inst)) {
 		i_vpr_e(inst, "%s: inst in error state\n", __func__);
@@ -520,6 +549,7 @@ int msm_v4l2_subscribe_event(struct v4l2_fh *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -538,6 +568,7 @@ int msm_v4l2_unsubscribe_event(struct v4l2_fh *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	rc = msm_vidc_unsubscribe_event((void *)inst, sub);
 	if (rc)
@@ -545,6 +576,7 @@ int msm_v4l2_unsubscribe_event(struct v4l2_fh *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -562,6 +594,7 @@ int msm_v4l2_try_decoder_cmd(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	if (is_session_error(inst)) {
 		i_vpr_e(inst, "%s: inst in error state\n", __func__);
@@ -574,6 +607,7 @@ int msm_v4l2_try_decoder_cmd(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -591,6 +625,7 @@ int msm_v4l2_decoder_cmd(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	if (is_session_error(inst)) {
 		i_vpr_e(inst, "%s: inst in error state\n", __func__);
@@ -603,6 +638,7 @@ int msm_v4l2_decoder_cmd(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -620,6 +656,7 @@ int msm_v4l2_try_encoder_cmd(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	if (is_session_error(inst)) {
 		i_vpr_e(inst, "%s: inst in error state\n", __func__);
@@ -632,6 +669,7 @@ int msm_v4l2_try_encoder_cmd(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -649,6 +687,7 @@ int msm_v4l2_encoder_cmd(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	if (is_session_error(inst)) {
 		i_vpr_e(inst, "%s: inst in error state\n", __func__);
@@ -661,6 +700,7 @@ int msm_v4l2_encoder_cmd(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -678,6 +718,7 @@ int msm_v4l2_enum_framesizes(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	rc = msm_vidc_enum_framesizes((void *)inst, fsize);
 	if (rc)
@@ -685,6 +726,7 @@ int msm_v4l2_enum_framesizes(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -702,6 +744,7 @@ int msm_v4l2_enum_frameintervals(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	rc = msm_vidc_enum_frameintervals((void *)inst, fival);
 	if (rc)
@@ -709,6 +752,7 @@ int msm_v4l2_enum_frameintervals(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -726,6 +770,7 @@ int msm_v4l2_queryctrl(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	rc = msm_vidc_query_ctrl((void *)inst, ctrl);
 	if (rc)
@@ -733,6 +778,7 @@ int msm_v4l2_queryctrl(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;
@@ -750,6 +796,7 @@ int msm_v4l2_querymenu(struct file *filp, void *fh,
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	rc = msm_vidc_query_menu((void *)inst, qmenu);
 	if (rc)
@@ -757,6 +804,7 @@ int msm_v4l2_querymenu(struct file *filp, void *fh,
 
 unlock:
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 
 	return rc;

+ 31 - 20
driver/vidc/src/msm_vidc_vb2.c

@@ -204,6 +204,7 @@ int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count)
 		return -EINVAL;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	if (is_session_error(inst)) {
 		i_vpr_e(inst, "%s: inst in error state\n", __func__);
@@ -337,6 +338,7 @@ unlock:
 		msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
 	}
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 	return rc;
 }
@@ -358,6 +360,7 @@ void msm_vidc_stop_streaming(struct vb2_queue *q)
 		return;
 	}
 
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
 	if (q->type == INPUT_META_PLANE || q->type == OUTPUT_META_PLANE) {
 		i_vpr_h(inst, "%s: nothing to stop on %s\n",
@@ -420,6 +423,7 @@ unlock:
 		msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
 	}
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 	return;
 }
@@ -443,7 +447,33 @@ void msm_vidc_buf_queue(struct vb2_buffer *vb2)
 		return;
 	}
 
+	/*
+	 * As part of every qbuf initalise request to true.
+	 * If there are any dynamic controls associated with qbuf,
+	 * they will set as part s_ctrl() from v4l2_ctrl_request_setup().
+	 * Once v4l2_ctrl_request_setup() is done, reset request variable.
+	 * If the buffer does not have any requests with it, then
+	 * v4l2_ctrl_request_setup() will return 0.
+	 */
+	inst->request = true;
+	rc = v4l2_ctrl_request_setup(vb2->req_obj.req,
+			&inst->ctrl_handler);
+	inst->request = false;
+	v4l2_ctrl_request_complete(vb2->req_obj.req, &inst->ctrl_handler);
+	/*
+	 * call request_setup and request_complete without acquiring lock
+	 * to avoid deadlock issues because request_setup or request_complete
+	 * would call .s_ctrl and .g_volatile_ctrl respectively which acquire
+	 * lock too.
+	 */
+	client_lock(inst, __func__);
 	inst_lock(inst, __func__);
+	if (rc) {
+		i_vpr_e(inst, "%s: request setup failed, error %d\n",
+			__func__, rc);
+		goto unlock;
+	}
+
 	if (is_session_error(inst)) {
 		i_vpr_e(inst, "%s: inst in error state\n", __func__);
 		rc = -EINVAL;
@@ -482,25 +512,6 @@ void msm_vidc_buf_queue(struct vb2_buffer *vb2)
 			goto unlock;
 	}
 
-	/*
-	 * As part of every qbuf initalise request to true.
-	 * If there are any dynamic controls associated with qbuf,
-	 * they will set as part s_ctrl() from v4l2_ctrl_request_setup().
-	 * Once v4l2_ctrl_request_setup() is done, reset request variable.
-	 * If the buffer does not have any requests with it, then
-	 * v4l2_ctrl_request_setup() will return 0.
-	 */
-	inst->request = true;
-	rc = v4l2_ctrl_request_setup(vb2->req_obj.req,
-			&inst->ctrl_handler);
-	if (rc) {
-		inst->request = false;
-		i_vpr_e(inst, "%s: request setup failed, error %d\n",
-			__func__, rc);
-		goto unlock;
-	}
-	inst->request = false;
-
 	if (inst->capabilities->cap[INPUT_META_VIA_REQUEST].value) {
 		rc = msm_vidc_update_input_meta_buffer_index(inst, vb2);
 		if (rc)
@@ -521,10 +532,10 @@ void msm_vidc_buf_queue(struct vb2_buffer *vb2)
 unlock:
 	if (rc) {
 		msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
-		v4l2_ctrl_request_complete(vb2->req_obj.req, &inst->ctrl_handler);
 		vb2_buffer_done(vb2, VB2_BUF_STATE_ERROR);
 	}
 	inst_unlock(inst, __func__);
+	client_unlock(inst, __func__);
 	put_inst(inst);
 }
 

+ 3 - 5
driver/vidc/src/venus_hfi.c

@@ -1110,11 +1110,9 @@ static void __flush_debug_queue(struct msm_vidc_core *core,
 	}
 
 	if (!packet || !packet_size) {
-		packet = kzalloc(VIDC_IFACEQ_VAR_HUGE_PKT_SIZE, GFP_KERNEL);
-		if (!packet) {
-			d_vpr_e("%s: fail to allocate\n", __func__);
+		if (msm_vidc_vmem_alloc(VIDC_IFACEQ_VAR_HUGE_PKT_SIZE,
+			(void **)&packet, __func__))
 			return;
-		}
 		packet_size = VIDC_IFACEQ_VAR_HUGE_PKT_SIZE;
 
 		local_packet = true;
@@ -1153,7 +1151,7 @@ static void __flush_debug_queue(struct msm_vidc_core *core,
 	}
 
 	if (local_packet)
-		kfree(packet);
+		msm_vidc_vmem_free((void **)&packet);
 }
 
 static int __sys_set_debug(struct msm_vidc_core *core, u32 debug)

+ 24 - 9
driver/vidc/src/venus_hfi_response.c

@@ -338,6 +338,10 @@ static int handle_session_info(struct msm_vidc_inst *inst,
 		info = "data corrupt";
 		inst->hfi_frame_info.data_corrupt = 1;
 		break;
+	case HFI_INFO_BUFFER_OVERFLOW:
+		info = "buffer overflow";
+		inst->hfi_frame_info.overflow = 1;
+		break;
 	default:
 		info = "unknown";
 		break;
@@ -607,6 +611,10 @@ static int get_driver_buffer_flags(struct msm_vidc_inst *inst, u32 hfi_flags)
 			driver_flags |= MSM_VIDC_BUF_FLAG_ERROR;
 	}
 
+	if (inst->hfi_frame_info.subframe_input)
+		if (inst->capabilities->cap[META_BUF_TAG].value)
+			driver_flags |= MSM_VIDC_BUF_FLAG_ERROR;
+
 	if (hfi_flags & HFI_BUF_FW_FLAG_CODEC_CONFIG)
 		driver_flags |= MSM_VIDC_BUF_FLAG_CODECCONFIG;
 
@@ -1499,6 +1507,15 @@ static int handle_property_with_payload(struct msm_vidc_inst *inst,
 		if (inst->hfi_frame_info.picture_type & HFI_PICTURE_B)
 			inst->has_bframe = true;
 		break;
+	case HFI_PROP_SUBFRAME_INPUT:
+		if (port != INPUT_PORT) {
+			i_vpr_e(inst,
+				"%s: invalid port: %d for property %#x\n",
+				__func__, pkt->port, pkt->type);
+			break;
+		}
+		inst->hfi_frame_info.subframe_input = 1;
+		break;
 	case HFI_PROP_WORST_COMPRESSION_RATIO:
 		inst->hfi_frame_info.cr = payload_ptr[0];
 		break;
@@ -1854,8 +1871,8 @@ void handle_session_response_work_handler(struct work_struct *work)
 			break;
 		}
 		list_del(&resp_work->list);
-		kfree(resp_work->data);
-		kfree(resp_work);
+		msm_vidc_vmem_free((void **)&resp_work->data);
+		msm_vidc_vmem_free((void **)&resp_work);
 	}
 	inst_unlock(inst, __func__);
 
@@ -1865,16 +1882,14 @@ void handle_session_response_work_handler(struct work_struct *work)
 static int queue_response_work(struct msm_vidc_inst *inst,
 	enum response_work_type type, void *hdr, u32 hdr_size)
 {
-	struct response_work *work;
+	struct response_work *work = NULL;
 
-	work = kzalloc(sizeof(struct response_work), GFP_KERNEL);
-	if (!work)
+	if (msm_vidc_vmem_alloc(sizeof(struct response_work), (void **)&work, __func__))
 		return -ENOMEM;
 	INIT_LIST_HEAD(&work->list);
 	work->type = type;
 	work->data_size = hdr_size;
-	work->data = kzalloc(hdr_size, GFP_KERNEL);
-	if (!work->data)
+	if (msm_vidc_vmem_alloc(hdr_size, (void **)&work->data, "Work data"))
 		return -ENOMEM;
 	memcpy(work->data, hdr, hdr_size);
 	list_add_tail(&work->list, &inst->response_works);
@@ -1895,8 +1910,8 @@ int cancel_response_work(struct msm_vidc_inst *inst)
 
 	list_for_each_entry_safe(work, dummy_work, &inst->response_works, list) {
 		list_del(&work->list);
-		kfree(work->data);
-		kfree(work);
+		msm_vidc_vmem_free((void **)&work->data);
+		msm_vidc_vmem_free((void **)&work);
 	}
 
 	return 0;

+ 11 - 0
include/uapi/vidc/media/v4l2_vidc_extensions.h

@@ -149,6 +149,8 @@ enum v4l2_mpeg_vidc_metadata_bits {
 	(V4L2_CID_MPEG_VIDC_BASE + 0x25)
 #define V4L2_CID_MPEG_VIDC_METADATA_SALIENCY_INFO                             \
 	(V4L2_CID_MPEG_VIDC_BASE + 0x26)
+#define V4L2_CID_MPEG_VIDC_METADATA_TRANSCODE_STAT_INFO                       \
+	(V4L2_CID_MPEG_VIDC_BASE + 0x27)
 
 /* Encoder Super frame control */
 #define V4L2_CID_MPEG_VIDC_SUPERFRAME           (V4L2_CID_MPEG_VIDC_BASE + 0x28)
@@ -260,6 +262,12 @@ enum v4l2_h264_encode_delivery_mode {
 #define V4L2_CID_MPEG_VIDC_RESERVE_DURATION                                  \
 	(V4L2_CID_MPEG_VIDC_BASE + 0x3F)
 
+#define V4L2_CID_MPEG_VIDC_METADATA_DOLBY_RPU                                 \
+	(V4L2_CID_MPEG_VIDC_BASE + 0x40)
+
+#define V4L2_CID_MPEG_VIDC_CLIENT_ID                                          \
+	(V4L2_CID_MPEG_VIDC_BASE + 0x41)
+
 /* add new controls above this line */
 /* Deprecate below controls once availble in gki and gsi bionic header */
 #ifndef V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID
@@ -401,6 +409,8 @@ enum v4l2_mpeg_vidc_metadata {
 	METADATA_MAX_NUM_REORDER_FRAMES       = 0x03000127,
 	METADATA_SALIENCY_INFO                = 0x0300018A,
 	METADATA_FENCE                        = 0x0300018B,
+	METADATA_TRANSCODING_STAT_INFO        = 0x03000191,
+	METADATA_DV_RPU                       = 0x03000192,
 };
 enum meta_interlace_info {
 	META_INTERLACE_INFO_NONE                            = 0x00000000,
@@ -457,5 +467,6 @@ struct v4l2_event_vidc_metadata {
 #define MSM_VIDC_METADATA_SIZE           (4 * 4096) /* 16 KB */
 #define ENCODE_INPUT_METADATA_SIZE       (512 * 4096) /* 2 MB */
 #define DECODE_INPUT_METADATA_SIZE       MSM_VIDC_METADATA_SIZE
+#define MSM_VIDC_METADATA_DOLBY_RPU_SIZE  (41 * 1024) /* 41 KB */
 
 #endif

+ 5 - 4
video_kernel_board.mk

@@ -1,9 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0-only
 TARGET_VIDC_ENABLE := false
-ifeq ($(TARGET_USES_QMAA),false)
-TARGET_VIDC_ENABLE := true
-endif
-ifeq ($(TARGET_USES_QMAA_OVERRIDE_VIDEO),true)
+ifeq ($(TARGET_KERNEL_DLKM_DISABLE), true)
+	ifeq ($(TARGET_KERNEL_DLKM_VIDEO_OVERRIDE), true)
+		TARGET_VIDC_ENABLE := true
+	endif
+else
 TARGET_VIDC_ENABLE := true
 endif
 

+ 5 - 4
video_kernel_product.mk

@@ -1,9 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0-only
 TARGET_VIDC_ENABLE := false
-ifeq ($(TARGET_USES_QMAA),false)
-TARGET_VIDC_ENABLE := true
-endif
-ifeq ($(TARGET_USES_QMAA_OVERRIDE_VIDEO),true)
+ifeq ($(TARGET_KERNEL_DLKM_DISABLE), true)
+	ifeq ($(TARGET_KERNEL_DLKM_VIDEO_OVERRIDE), true)
+		TARGET_VIDC_ENABLE := true
+	endif
+else
 TARGET_VIDC_ENABLE := true
 endif