diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 8fcf2e3a1a3f..69ea753bea22 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -2331,6 +2331,8 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
 			rc = -ENOTSUPP;
 			break;
 		}
+
+		msm_dcvs_try_enable(inst);
 		msm_comm_scale_clocks_and_bus(inst);
 		break;
 	case V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_INPUT:
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 36b24b90b0e2..57b2b9373af7 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -1665,7 +1665,6 @@ static inline int msm_venc_power_save_mode_enable(struct msm_vidc_inst *inst)
 			goto fail_power_mode_set;
 		}
 		inst->flags |= VIDC_LOW_POWER;
-		msm_dcvs_enc_set_power_save_mode(inst, true);
 		dprintk(VIDC_INFO, "Power Save Mode set for inst: %pK\n", inst);
 	}
 
@@ -2940,6 +2939,7 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
 			break;
 		}
 
+		msm_dcvs_try_enable(inst);
 		msm_comm_scale_clocks_and_bus(inst);
 		break;
 	case V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_BITSTREAM_RESTRICT:
@@ -3053,8 +3053,6 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
 		}
 		pdata = &venc_mode;
 
-		msm_dcvs_enc_set_power_save_mode(inst,
-			ctrl->val == V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE);
 		break;
 	case V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS:
 		if (inst->fmts[CAPTURE_PORT]->fourcc != V4L2_PIX_FMT_HEVC) {
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 69c4211768e5..595a2ae25a15 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -1237,8 +1237,6 @@ static void handle_event_change(enum hal_command_response cmd, void *data)
 			inst->prop.width[OUTPUT_PORT] = event_notify->width;
 	}
 
-	inst->seqchanged_count++;
-
 	if (inst->session_type == MSM_VIDC_DECODER)
 		msm_dcvs_init_load(inst);
 
@@ -2225,11 +2223,32 @@ void handle_cmd_response(enum hal_command_response cmd, void *data)
 
 int msm_comm_scale_clocks(struct msm_vidc_core *core)
 {
-	int num_mbs_per_sec =
-		msm_comm_get_load(core, MSM_VIDC_ENCODER, LOAD_CALC_NO_QUIRKS) +
+	int num_mbs_per_sec, enc_mbs_per_sec, dec_mbs_per_sec;
+
+	enc_mbs_per_sec =
+		msm_comm_get_load(core, MSM_VIDC_ENCODER, LOAD_CALC_NO_QUIRKS);
+	dec_mbs_per_sec	=
 		msm_comm_get_load(core, MSM_VIDC_DECODER, LOAD_CALC_NO_QUIRKS);
+
+	if (enc_mbs_per_sec >= dec_mbs_per_sec) {
+	/*
+	 * If Encoder load is higher, use that load. Encoder votes for higher
+	 * clock. Since Encoder and Deocder run on parallel cores, this clock
+	 * should suffice decoder usecases.
+	 */
+		num_mbs_per_sec = enc_mbs_per_sec;
+	} else {
+	/*
+	 * If Decoder load is higher, it's tricky to decide clock. Decoder
+	 * higher load might results less clocks than Encoder smaller load.
+	 * At this point driver doesn't know which clock to vote. Hence use
+	 * total load.
+	 */
+		num_mbs_per_sec = enc_mbs_per_sec + dec_mbs_per_sec;
+	}
+
 	return msm_comm_scale_clocks_load(core, num_mbs_per_sec,
-				LOAD_CALC_NO_QUIRKS);
+			LOAD_CALC_NO_QUIRKS);
 }
 
 int msm_comm_scale_clocks_load(struct msm_vidc_core *core,
@@ -4894,6 +4913,9 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
 		return -ENOTSUPP;
 	}
 
+	if (!rc)
+		msm_dcvs_try_enable(inst);
+
 	if (!rc) {
 		if (inst->prop.width[CAPTURE_PORT] < capability->width.min ||
 			inst->prop.height[CAPTURE_PORT] <
@@ -5203,6 +5225,7 @@ int msm_vidc_comm_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
 			msm_dcvs_init_load(inst);
 		}
 		msm_comm_scale_clocks_and_bus(inst);
+		msm_dcvs_try_enable(inst);
 	}
 exit:
 	return rc;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_dcvs.c b/drivers/media/platform/msm/vidc/msm_vidc_dcvs.c
index c03f887be6f6..9e67ef096c63 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_dcvs.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_dcvs.c
@@ -20,10 +20,19 @@
 		((__cur_mbpf) >= (__min_mbpf))
 
 static bool msm_dcvs_check_supported(struct msm_vidc_inst *inst);
-static bool msm_dcvs_enc_check(struct msm_vidc_inst *inst);
 static int msm_dcvs_enc_scale_clocks(struct msm_vidc_inst *inst);
 static int msm_dcvs_dec_scale_clocks(struct msm_vidc_inst *inst, bool fbd);
 
+int msm_dcvs_try_enable(struct msm_vidc_inst *inst)
+{
+	if (!inst) {
+		dprintk(VIDC_ERR, "%s: Invalid args: %p\n", __func__, inst);
+		return -EINVAL;
+	}
+	inst->dcvs_mode = msm_dcvs_check_supported(inst);
+	return 0;
+}
+
 static inline int msm_dcvs_get_mbs_per_frame(struct msm_vidc_inst *inst)
 {
 	int height, width;
@@ -41,20 +50,27 @@ static inline int msm_dcvs_get_mbs_per_frame(struct msm_vidc_inst *inst)
 	return NUM_MBS_PER_FRAME(height, width);
 }
 
-static inline int msm_dcvs_count_active_instances(struct msm_vidc_core *core)
+static inline int msm_dcvs_count_active_instances(struct msm_vidc_core *core,
+	enum session_type session_type)
 {
 	int active_instances = 0;
-	struct msm_vidc_inst *inst = NULL;
+	struct msm_vidc_inst *temp = NULL;
 
 	if (!core) {
 		dprintk(VIDC_ERR, "%s: Invalid args: %pK\n", __func__, core);
 		return -EINVAL;
 	}
 
+	/* DCVS condition is as following
+	 * Decoder DCVS : Only for ONE decoder session.
+	 * Encoder DCVS : Only for ONE encoder session + ONE decoder session
+	 */
 	mutex_lock(&core->lock);
-	list_for_each_entry(inst, &core->instances, list) {
-		if (inst->state >= MSM_VIDC_OPEN_DONE &&
-			inst->state < MSM_VIDC_STOP_DONE)
+	list_for_each_entry(temp, &core->instances, list) {
+		if (temp->state >= MSM_VIDC_OPEN_DONE &&
+			temp->state < MSM_VIDC_STOP_DONE &&
+			(temp->session_type == session_type ||
+			 temp->session_type == MSM_VIDC_ENCODER))
 			active_instances++;
 	}
 	mutex_unlock(&core->lock);
@@ -112,17 +128,12 @@ static void msm_dcvs_enc_check_and_scale_clocks(struct msm_vidc_inst *inst)
 {
 	int rc = 0;
 
-	if (inst->session_type == MSM_VIDC_ENCODER && msm_vidc_enc_dcvs_mode) {
-		inst->dcvs_mode = msm_dcvs_check_supported(inst);
-		dprintk(VIDC_DBG, "%s: session DCVS %s supported\n",
-				__func__, inst->dcvs_mode ? "" : "not");
-
-		if (inst->dcvs_mode) {
-			rc = msm_dcvs_enc_scale_clocks(inst);
-			if (rc) {
-				dprintk(VIDC_DBG,
+	if (inst->session_type == MSM_VIDC_ENCODER &&
+		msm_vidc_enc_dcvs_mode) {
+		rc = msm_dcvs_enc_scale_clocks(inst);
+		if (rc) {
+			dprintk(VIDC_DBG,
 				"ENC_DCVS: error while scaling clocks\n");
-			}
 		}
 	}
 }
@@ -131,28 +142,14 @@ static void msm_dcvs_dec_check_and_scale_clocks(struct msm_vidc_inst *inst)
 {
 	int rc = 0;
 
-	if (inst->session_type != MSM_VIDC_DECODER || !msm_vidc_dec_dcvs_mode)
-		return;
-
-	if (msm_dcvs_check_supported(inst)) {
-		inst->dcvs_mode = true;
-		dprintk(VIDC_DBG,
-			"%s: session DCVS supported, decode_dcvs_mode = %d\n",
-			__func__, inst->dcvs_mode);
-	} else {
-		inst->dcvs_mode = false;
-		dprintk(VIDC_DBG,
-			"%s: session DCVS not supported, decode_dcvs_mode = %d\n",
-			__func__, inst->dcvs_mode);
-	}
-
-	if (msm_vidc_dec_dcvs_mode && inst->dcvs_mode) {
+	if (inst->session_type == MSM_VIDC_DECODER &&
+		msm_vidc_dec_dcvs_mode) {
 		msm_dcvs_monitor_buffer(inst);
 		rc = msm_dcvs_dec_scale_clocks(inst, false);
 		if (rc) {
 			dprintk(VIDC_ERR,
-				"%s: Failed to scale clocks in DCVS: %d\n",
-				__func__, rc);
+					"%s: Failed to scale clocks in DCVS: %d\n",
+					__func__, rc);
 		}
 	}
 }
@@ -163,6 +160,11 @@ void msm_dcvs_check_and_scale_clocks(struct msm_vidc_inst *inst, bool is_etb)
 		dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst);
 		return;
 	}
+	msm_dcvs_try_enable(inst);
+	if (!inst->dcvs_mode) {
+		dprintk(VIDC_DBG, "DCVS is not enabled\n");
+		return;
+	}
 
 	if (is_etb)
 		msm_dcvs_enc_check_and_scale_clocks(inst);
@@ -531,48 +533,6 @@ static int msm_dcvs_dec_scale_clocks(struct msm_vidc_inst *inst, bool fbd)
 	return rc;
 }
 
-static bool msm_dcvs_enc_check(struct msm_vidc_inst *inst)
-{
-	int num_mbs_per_frame = 0;
-	long int instance_load = 0;
-	long int dcvs_limit = 0;
-	bool dcvs_check_passed = false, is_codec_supported  = false;
-	struct msm_vidc_platform_resources *res = NULL;
-
-	if (!inst || !inst->core) {
-		dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
-		return dcvs_check_passed;
-	}
-
-	res = &inst->core->resources;
-	if (!res->dcvs_limit) {
-		dprintk(VIDC_ERR,
-			"%s Dcvs limit table uninitialized\n", __func__);
-		return false;
-	}
-
-	is_codec_supported =
-		msm_dcvs_check_codec_supported(
-				inst->fmts[CAPTURE_PORT]->fourcc,
-				inst->dcvs.supported_codecs,
-				inst->session_type);
-
-	num_mbs_per_frame = msm_dcvs_get_mbs_per_frame(inst);
-	instance_load = msm_comm_get_inst_load(inst, LOAD_CALC_NO_QUIRKS);
-	dcvs_limit =
-		(long int)res->dcvs_limit[inst->session_type].min_mbpf *
-		res->dcvs_limit[inst->session_type].fps;
-
-	if (msm_vidc_enc_dcvs_mode && is_codec_supported &&
-		inst->dcvs.is_power_save_mode &&
-		IS_VALID_DCVS_SESSION(num_mbs_per_frame,
-			res->dcvs_limit[inst->session_type].min_mbpf) &&
-		IS_VALID_DCVS_SESSION(instance_load, dcvs_limit)) {
-		dcvs_check_passed = true;
-	}
-	return dcvs_check_passed;
-}
-
 static bool msm_dcvs_check_supported(struct msm_vidc_inst *inst)
 {
 	int num_mbs_per_frame = 0, instance_count = 0;
@@ -583,6 +543,7 @@ static bool msm_dcvs_check_supported(struct msm_vidc_inst *inst)
 	struct hal_buffer_requirements *output_buf_req;
 	struct dcvs_stats *dcvs;
 	bool is_codec_supported = false;
+	bool is_dcvs_supported = true;
 	struct msm_vidc_platform_resources *res = NULL;
 
 	if (!inst || !inst->core || !inst->core->device) {
@@ -599,104 +560,88 @@ static bool msm_dcvs_check_supported(struct msm_vidc_inst *inst)
 				"%s: dcvs limit table not found\n", __func__);
 		return false;
 	}
-	instance_count = msm_dcvs_count_active_instances(core);
+	instance_count = msm_dcvs_count_active_instances(core,
+		inst->session_type);
+	num_mbs_per_frame = msm_dcvs_get_mbs_per_frame(inst);
+	instance_load = msm_comm_get_inst_load(inst, LOAD_CALC_NO_QUIRKS);
+	dcvs_limit =
+		(long int)res->dcvs_limit[inst->session_type].min_mbpf *
+		res->dcvs_limit[inst->session_type].fps;
+	inst->dcvs.extra_buffer_count = 0;
 
-	if (instance_count == 1 && inst->session_type == MSM_VIDC_DECODER &&
-		!msm_comm_turbo_session(inst)) {
-		num_mbs_per_frame = msm_dcvs_get_mbs_per_frame(inst);
-		instance_load = msm_comm_get_inst_load(inst,
-			LOAD_CALC_NO_QUIRKS);
+	if (!IS_VALID_DCVS_SESSION(num_mbs_per_frame,
+				res->dcvs_limit[inst->session_type].min_mbpf)) {
+		inst->dcvs.extra_buffer_count = 0;
+		is_dcvs_supported = false;
+		goto dcvs_decision_done;
+
+	}
+
+	if (inst->session_type == MSM_VIDC_DECODER) {
+		inst->dcvs.extra_buffer_count = DCVS_DEC_EXTRA_OUTPUT_BUFFERS;
 		output_buf_req = get_buff_req_buffer(inst,
-			msm_comm_get_hal_output_buffer(inst));
-		dcvs_limit =
-			(long int)res->dcvs_limit[inst->session_type].min_mbpf *
-			res->dcvs_limit[inst->session_type].fps;
-		is_codec_supported =
-			msm_dcvs_check_codec_supported(
-					inst->fmts[OUTPUT_PORT]->fourcc,
-					inst->dcvs.supported_codecs,
-					inst->session_type);
-		if (!is_codec_supported ||
-			!IS_VALID_DCVS_SESSION(num_mbs_per_frame,
-				res->dcvs_limit[inst->session_type].min_mbpf) ||
-			!IS_VALID_DCVS_SESSION(instance_load, dcvs_limit) ||
-			inst->seqchanged_count > 1)
-			return false;
-
+				msm_comm_get_hal_output_buffer(inst));
 		if (!output_buf_req) {
 			dprintk(VIDC_ERR,
-				"%s: No buffer requirement for buffer type %x\n",
-				__func__, HAL_BUFFER_OUTPUT);
+					"%s: No buffer requirement for buffer type %x\n",
+					__func__, HAL_BUFFER_OUTPUT);
 			return false;
 		}
-	} else if (instance_count == 1 &&
-			inst->session_type == MSM_VIDC_ENCODER &&
-			!msm_comm_turbo_session(inst)) {
-		if (!msm_dcvs_enc_check(inst))
-			return false;
-	} else {
-		/*
-		* For multiple instance use case with 4K, clocks will be scaled
-		* as per load in streamon, but the clocks may be scaled
-		* down as DCVS is running for first playback instance
-		* Rescaling the core clock for multiple instance use case
-		*/
-		if (!dcvs->is_clock_scaled) {
-			if (!msm_comm_scale_clocks(core)) {
-				dcvs->is_clock_scaled = true;
-				dprintk(VIDC_DBG,
-					"%s: Scaled clocks = %d\n",
-					__func__, dcvs->is_clock_scaled);
-			} else {
-				dprintk(VIDC_DBG,
-					"%s: Failed to Scale clocks. Perf might be impacted\n",
-					__func__);
-			}
+		is_codec_supported =
+			msm_dcvs_check_codec_supported(
+				inst->fmts[OUTPUT_PORT]->fourcc,
+				inst->dcvs.supported_codecs,
+				inst->session_type);
+		if (!is_codec_supported ||
+				!msm_vidc_dec_dcvs_mode) {
+			inst->dcvs.extra_buffer_count = 0;
+			is_dcvs_supported = false;
+			goto dcvs_decision_done;
 		}
-		/*
-		* For multiple instance use case turn OFF DCVS algorithm
-		* immediately
-		*/
+		if (msm_comm_turbo_session(inst) ||
+			!IS_VALID_DCVS_SESSION(instance_load, dcvs_limit ||
+			instance_count > 1))
+			is_dcvs_supported = false;
+	}
+	if (inst->session_type == MSM_VIDC_ENCODER) {
+		inst->dcvs.extra_buffer_count = DCVS_ENC_EXTRA_OUTPUT_BUFFERS;
+		is_codec_supported =
+			msm_dcvs_check_codec_supported(
+				inst->fmts[CAPTURE_PORT]->fourcc,
+				inst->dcvs.supported_codecs,
+				inst->session_type);
+		if (!is_codec_supported ||
+				!msm_vidc_enc_dcvs_mode) {
+			inst->dcvs.extra_buffer_count = 0;
+			is_dcvs_supported = false;
+			goto dcvs_decision_done;
+		}
+		if (msm_comm_turbo_session(inst) ||
+			!IS_VALID_DCVS_SESSION(instance_load, dcvs_limit ||
+				instance_count > 1))
+			is_dcvs_supported = false;
+	}
+dcvs_decision_done:
+	if (!is_dcvs_supported) {
+		msm_comm_scale_clocks(core);
 		if (instance_count > 1) {
 			mutex_lock(&core->lock);
 			list_for_each_entry(temp, &core->instances, list)
 				temp->dcvs_mode = false;
 			mutex_unlock(&core->lock);
 		}
-
-		return false;
 	}
-
-	return true;
+	return is_dcvs_supported;
 }
 
 int msm_dcvs_get_extra_buff_count(struct msm_vidc_inst *inst)
 {
-	int extra_buffer = 0;
-
 	if (!inst) {
 		dprintk(VIDC_ERR, "%s Invalid args\n", __func__);
 		return 0;
 	}
 
-	if (inst->session_type == MSM_VIDC_ENCODER) {
-		if (msm_dcvs_enc_check(inst))
-			extra_buffer = DCVS_ENC_EXTRA_OUTPUT_BUFFERS;
-	} else if (inst->session_type == MSM_VIDC_DECODER) {
-		if (msm_dcvs_check_supported(inst))
-			extra_buffer = DCVS_DEC_EXTRA_OUTPUT_BUFFERS;
-	}
-	return extra_buffer;
+	return inst->dcvs.extra_buffer_count;
 }
 
 
-void msm_dcvs_enc_set_power_save_mode(struct msm_vidc_inst *inst,
-					bool is_power_save_mode)
-{
-	if (!inst) {
-		dprintk(VIDC_ERR, "%s Invalid args\n", __func__);
-		return;
-	}
-
-	inst->dcvs.is_power_save_mode = is_power_save_mode;
-}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_dcvs.h b/drivers/media/platform/msm/vidc/msm_vidc_dcvs.h
index 17040166b1e4..d40473976ebb 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_dcvs.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_dcvs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -36,6 +36,5 @@ void msm_dcvs_init_load(struct msm_vidc_inst *inst);
 void msm_dcvs_monitor_buffer(struct msm_vidc_inst *inst);
 void msm_dcvs_check_and_scale_clocks(struct msm_vidc_inst *inst, bool is_etb);
 int  msm_dcvs_get_extra_buff_count(struct msm_vidc_inst *inst);
-void msm_dcvs_enc_set_power_save_mode(struct msm_vidc_inst *inst,
-		bool is_power_save_mode);
+int msm_dcvs_try_enable(struct msm_vidc_inst *inst);
 #endif
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 72c1ddcf3a70..b6e74715ad07 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -204,9 +204,9 @@ struct dcvs_stats {
 	int load_high;
 	int min_threshold;
 	int max_threshold;
-	bool is_clock_scaled;
 	int etb_counter;
 	bool is_power_save_mode;
+	unsigned int extra_buffer_count;
 	u32 supported_codecs;
 };
 
@@ -279,7 +279,6 @@ struct msm_vidc_inst {
 	bool in_reconfig;
 	u32 reconfig_width;
 	u32 reconfig_height;
-	u32 seqchanged_count;
 	struct dentry *debugfs_root;
 	void *priv;
 	struct msm_vidc_debug debug;