msm: vidc: Fix resolution checks in work mode and route

New helper functions to check resolution. Also, set
low latency only for Encoder.

CRs-Fixed: 2384822
Change-Id: Ib8fdcf7adcbca8ebfa9ca2ecd11351b4adb55f4b
Signed-off-by: Chinmay Sawarkar <chinmays@codeaurora.org>
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
index b0006ac..e3d9b39 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
@@ -84,6 +84,34 @@
 	return compression_ratio;
 }
 
+bool res_is_less_than(u32 width, u32 height,
+			u32 ref_width, u32 ref_height)
+{
+	u32 num_mbs = NUM_MBS_PER_FRAME(height, width);
+	u32 max_side = max(ref_width, ref_height);
+
+	if (num_mbs < NUM_MBS_PER_FRAME(ref_height, ref_width) &&
+		width < max_side &&
+		height < max_side)
+		return true;
+	else
+		return false;
+}
+
+bool res_is_greater_than(u32 width, u32 height,
+				u32 ref_width, u32 ref_height)
+{
+	u32 num_mbs = NUM_MBS_PER_FRAME(height, width);
+	u32 max_side = max(ref_width, ref_height);
+
+	if (num_mbs > NUM_MBS_PER_FRAME(ref_height, ref_width) ||
+		width > max_side ||
+		height > max_side)
+		return true;
+	else
+		return false;
+}
+
 int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst)
 {
 	int height, width;
@@ -1290,19 +1318,15 @@
 			inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE)
 			pdata.video_work_route = 1;
 	} else if (inst->session_type == MSM_VIDC_ENCODER) {
-		u32 slice_mode, output_width, output_height, num_mbs;
+		u32 slice_mode, width, height;
 		bool is_1080p_above;
 
 		slice_mode =  msm_comm_g_ctrl_for_id(inst,
 				V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE);
-		output_height = inst->prop.height[OUTPUT_PORT];
-		output_width = inst->prop.width[OUTPUT_PORT];
-		num_mbs = NUM_MBS_PER_FRAME(output_height, output_width);
+		height = inst->prop.height[OUTPUT_PORT];
+		width = inst->prop.width[OUTPUT_PORT];
 
-		is_1080p_above =
-			((output_height > 1088 && output_width > 1920) ||
-			 (output_height > 1920 && output_width > 1088) ||
-			 num_mbs > NUM_MBS_PER_FRAME(1088, 1920));
+		is_1080p_above = res_is_greater_than(width, height, 1920, 1088);
 
 		if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES ||
 			inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8 ||
@@ -1316,13 +1340,14 @@
 	dprintk(VIDC_DBG, "Configurng work route = %u",
 			pdata.video_work_route);
 
-	inst->clk_data.work_route = pdata.video_work_route;
 	rc = call_hfi_op(hdev, session_set_property,
 			(void *)inst->session, HFI_PROPERTY_PARAM_WORK_ROUTE,
 			(void *)&pdata, sizeof(pdata));
 	if (rc)
 		dprintk(VIDC_WARN,
 			" Failed to configure work route %pK\n", inst);
+	else
+		inst->clk_data.work_route = pdata.video_work_route;
 
 	return rc;
 }
@@ -1480,8 +1505,8 @@
 	struct hfi_device *hdev;
 	struct hfi_video_work_mode pdata;
 	struct hfi_enable latency;
-	u32 num_mbs = 0;
 	u32 width, height;
+	bool res_ok = false;
 
 	if (!inst || !inst->core || !inst->core->device) {
 		dprintk(VIDC_ERR,
@@ -1497,24 +1522,19 @@
 	if (inst->session_type == MSM_VIDC_DECODER) {
 		height = inst->prop.height[CAPTURE_PORT];
 		width = inst->prop.width[CAPTURE_PORT];
-		num_mbs = NUM_MBS_PER_FRAME(height, width);
+		res_ok = res_is_less_than(width, height, 1280, 720);
 		if (inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_MPEG2 ||
 			inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE ||
-			inst->clk_data.low_latency_mode ||
-			(width < 1280 && height < 720) ||
-			(width < 720 && height < 1280) ||
-			num_mbs < NUM_MBS_PER_FRAME(720, 1280)) {
+			inst->clk_data.low_latency_mode || res_ok) {
 			pdata.video_work_mode = HFI_WORKMODE_1;
 		}
 	} else if (inst->session_type == MSM_VIDC_ENCODER) {
 		height = inst->prop.height[OUTPUT_PORT];
 		width = inst->prop.width[OUTPUT_PORT];
-		num_mbs = NUM_MBS_PER_FRAME(height, width);
-		if ((num_mbs >= NUM_MBS_PER_FRAME(2160, 4096) ||
-			(width < 4096 && height < 2160) ||
-			(width < 2160 && height < 4096)) &&
+		res_ok = !res_is_greater_than(width, height, 4096, 2160);
+		if (res_ok &&
 			(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8 ||
-			 inst->clk_data.low_latency_mode)) {
+			  inst->clk_data.low_latency_mode)) {
 			pdata.video_work_mode = HFI_WORKMODE_1;
 			/* For WORK_MODE_1, set Low Latency mode by default */
 			latency.enable = true;
@@ -1524,27 +1544,29 @@
 	}
 
 	dprintk(VIDC_DBG, "Configuring work mode = %u low latency = %u",
-			inst->clk_data.work_mode,
+			pdata.video_work_mode,
 			latency.enable);
 
-	rc = call_hfi_op(hdev, session_set_property,
-		(void *)inst->session,
-		HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE,
-		(void *)&latency, sizeof(latency));
-	if (rc)
-		dprintk(VIDC_WARN,
-			" Failed to configure low latency %pK\n", inst);
-	else
-		inst->clk_data.low_latency_mode = latency.enable;
+	if (inst->session_type == MSM_VIDC_ENCODER) {
+		rc = call_hfi_op(hdev, session_set_property,
+			(void *)inst->session,
+			HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE,
+			(void *)&latency, sizeof(latency));
+		if (rc)
+			dprintk(VIDC_WARN,
+				" Failed to configure low latency %pK\n", inst);
+		else
+			inst->clk_data.low_latency_mode = latency.enable;
+	}
 
-
-	inst->clk_data.work_mode = pdata.video_work_mode;
 	rc = call_hfi_op(hdev, session_set_property,
 			(void *)inst->session, HFI_PROPERTY_PARAM_WORK_MODE,
 			(void *)&pdata, sizeof(pdata));
 	if (rc)
 		dprintk(VIDC_WARN,
 			" Failed to configure Work Mode %pK\n", inst);
+	else
+		inst->clk_data.work_mode = pdata.video_work_mode;
 
 	return rc;
 }