Merge changes Ie8fbb382,If8aede0e into msm-3.4

* changes:
  msm: 8974: Adds load-freq table for video
  msm: vidc: Adds clock scaling
diff --git a/Documentation/devicetree/bindings/media/video/msm-vidc.txt b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
index dbbe46d..79a3ab5 100644
--- a/Documentation/devicetree/bindings/media/video/msm-vidc.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
@@ -11,6 +11,8 @@
 - vidc-ns-map : start and size of device virtual address range for non-secure buffers.
   Video hardware uses this address range to identify if the buffers are secure
   or non-secure.
+- load-freq-tbl : load (in macroblocks/sec) and corresponding vcodec clock
+  required for optimal performance in descending order.
 
 Example:
 
@@ -21,4 +23,10 @@
 		interrupts = <0 44 0>;
 		vidc-cp-map = <0x1000000 0x40000000>;
 		vidc-ns-map = <0x40000000 0x40000000>;
+		load-freq-tbl = <979200 410000000>,
+				<560145 266670000>,
+				<421161 200000000>,
+				<243000 133330000>,
+				<108000 100000000>,
+				<36000 50000000>;
 	};
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index edb86be..719eb4e 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -48,6 +48,12 @@
 		interrupts = <0 44 0>;
 		vidc-cp-map = <0x1000000 0x40000000>;
 		vidc-ns-map = <0x40000000 0x40000000>;
+		load-freq-tbl = <979200 410000000>,
+				<560145 266670000>,
+				<421161 200000000>,
+				<243000 133330000>,
+				<108000 100000000>,
+				<36000 50000000>;
 	};
 
 	serial@f991f000 {
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 6b58257..7948143 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -4790,6 +4790,10 @@
 	CLK_LOOKUP("iface_clk",  venus0_ahb_clk.c, "fdce0000.qcom,venus"),
 	CLK_LOOKUP("bus_clk",  venus0_axi_clk.c, "fdce0000.qcom,venus"),
 	CLK_LOOKUP("mem_clk",  venus0_ocmemnoc_clk.c, "fdce0000.qcom,venus"),
+	CLK_LOOKUP("core_clk", venus0_vcodec0_clk.c, "fdc00000.qcom,vidc"),
+	CLK_LOOKUP("iface_clk",  venus0_ahb_clk.c, "fdc00000.qcom,vidc"),
+	CLK_LOOKUP("bus_clk",  venus0_axi_clk.c, "fdc00000.qcom,vidc"),
+	CLK_LOOKUP("mem_clk",  venus0_ocmemnoc_clk.c, "fdc00000.qcom,vidc"),
 
 
 	/* LPASS clocks */
diff --git a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
index e1a71ce..4bc2a87 100644
--- a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
@@ -381,6 +381,7 @@
 	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
 	return msm_vidc_decoder_cmd((void *)vidc_inst, dec);
 }
+
 static const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
 	.vidioc_querycap = msm_v4l2_querycap,
 	.vidioc_enum_fmt_vid_cap_mplane = msm_v4l2_enum_fmt,
@@ -504,6 +505,76 @@
 	return rc;
 }
 
+static inline int msm_vidc_init_clocks(struct platform_device *pdev,
+		struct msm_vidc_core *core)
+{
+	struct core_clock *cl;
+	int i;
+	int rc = 0;
+	struct core_clock *clock;
+	if (!core) {
+		pr_err("Invalid params: %p\n", core);
+		return -EINVAL;
+	}
+	clock = core->resources.clock;
+	strlcpy(clock[VCODEC_CLK].name, "core_clk",
+		sizeof(clock[VCODEC_CLK].name));
+	strlcpy(clock[VCODEC_AHB_CLK].name, "iface_clk",
+		sizeof(clock[VCODEC_AHB_CLK].name));
+	strlcpy(clock[VCODEC_AXI_CLK].name, "bus_clk",
+		sizeof(clock[VCODEC_AXI_CLK].name));
+	strlcpy(clock[VCODEC_OCMEM_CLK].name, "mem_clk",
+		sizeof(clock[VCODEC_OCMEM_CLK].name));
+
+	clock[VCODEC_CLK].count = read_u32_array(pdev,
+		"load-freq-tbl", (u32 *)clock[VCODEC_CLK].load_freq_tbl,
+		(sizeof(clock[VCODEC_CLK].load_freq_tbl)/sizeof(u32)));
+	clock[VCODEC_CLK].count /= 2;
+	pr_err("NOTE: Count = %d\n", clock[VCODEC_CLK].count);
+	if (!clock[VCODEC_CLK].count) {
+		pr_err("Failed to read clock frequency\n");
+		goto fail_init_clocks;
+	}
+	for (i = 0; i <	clock[VCODEC_CLK].count; i++) {
+		pr_err("NOTE: load = %d, freq = %d\n",
+				clock[VCODEC_CLK].load_freq_tbl[i].load,
+				clock[VCODEC_CLK].load_freq_tbl[i].freq
+			  );
+	}
+
+	for (i = 0; i < VCODEC_MAX_CLKS; i++) {
+		cl = &core->resources.clock[i];
+		if (!cl->clk) {
+			cl->clk = devm_clk_get(&pdev->dev, cl->name);
+			if (IS_ERR_OR_NULL(cl->clk)) {
+				pr_err("Failed to get clock: %s\n", cl->name);
+				rc = PTR_ERR(cl->clk);
+				break;
+			}
+		}
+	}
+
+	if (i < VCODEC_MAX_CLKS) {
+		for (--i; i >= 0; i--) {
+			cl = &core->resources.clock[i];
+			clk_put(cl->clk);
+		}
+	}
+fail_init_clocks:
+	return rc;
+}
+
+static inline void msm_vidc_deinit_clocks(struct msm_vidc_core *core)
+{
+	int i;
+	if (!core) {
+		pr_err("Invalid args\n");
+		return;
+	}
+	for (i = 0; i < VCODEC_MAX_CLKS; i++)
+		clk_put(core->resources.clock[i].clk);
+}
+
 static int msm_vidc_initialize_core(struct platform_device *pdev,
 				struct msm_vidc_core *core)
 {
@@ -515,14 +586,16 @@
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		pr_err("Failed to get IORESOURCE_MEM\n");
-		return -ENODEV;
+		rc = -ENODEV;
+		goto core_init_failed;
 	}
 	core->register_base = res->start;
 	core->register_size = resource_size(res);
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!res) {
 		pr_err("Failed to get IORESOURCE_IRQ\n");
-		return -ENODEV;
+		rc = -ENODEV;
+		goto core_init_failed;
 	}
 	core->irq = res->start;
 	INIT_LIST_HEAD(&core->instances);
@@ -534,12 +607,21 @@
 		i <= SYS_MSG_INDEX(SYS_MSG_END); i++) {
 		init_completion(&core->completions[i]);
 	}
+	rc = msm_vidc_init_clocks(pdev, core);
+	if (rc) {
+		pr_err("Failed to init clocks\n");
+		rc = -ENODEV;
+		goto core_init_failed;
+	}
 	rc = register_iommu_domains(pdev, core);
 	if (rc) {
 		pr_err("Failed to register iommu domains: %d\n", rc);
-		goto fail_domain_register;
+		goto fail_register_domains;
 	}
-fail_domain_register:
+	return rc;
+fail_register_domains:
+	msm_vidc_deinit_clocks(core);
+core_init_failed:
 	return rc;
 }
 
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index a8c6428..d2b1acd 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -467,8 +467,8 @@
 		return -EINVAL;
 	}
 	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		inst->width = f->fmt.pix_mp.width;
-		inst->height = f->fmt.pix_mp.height;
+		inst->prop.width = f->fmt.pix_mp.width;
+		inst->prop.height = f->fmt.pix_mp.height;
 		fmt = msm_comm_get_pixel_fmt_fourcc(vdec_formats,
 			ARRAY_SIZE(vdec_formats), f->fmt.pix_mp.pixelformat,
 			CAPTURE_PORT);
@@ -593,8 +593,8 @@
 			break;
 		}
 		frame_sz.buffer_type = HAL_BUFFER_OUTPUT;
-		frame_sz.width = inst->width;
-		frame_sz.height = inst->height;
+		frame_sz.width = inst->prop.width;
+		frame_sz.height = inst->prop.height;
 		pr_debug("width = %d, height = %d\n",
 				frame_sz.width, frame_sz.height);
 		rc = vidc_hal_session_set_property((void *)inst->session,
@@ -617,7 +617,7 @@
 				inst->buff_req.buffer[1].buffer_alignment);
 		for (i = 0; i < *num_planes; i++) {
 			sizes[i] = inst->fmts[CAPTURE_PORT]->get_frame_size(
-					i, inst->height, inst->width);
+					i, inst->prop.height, inst->prop.width);
 		}
 
 		break;
@@ -682,11 +682,14 @@
 	pr_debug("Streamon called on: %d capability\n", q->type);
 	switch (q->type) {
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		if (msm_comm_scale_clocks(inst->core))
+			pr_err("Failed to scale clocks. Performance/power might be impacted\n");
 		if (inst->vb2_bufq[CAPTURE_PORT].streaming)
 			rc = start_streaming(inst);
 		break;
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-		inst->in_reconfig = false;
+		if (msm_comm_scale_clocks(inst->core))
+			pr_err("Failed to scale clocks. Performance/power might be impacted\n");
 		if (inst->vb2_bufq[OUTPUT_PORT].streaming)
 			rc = start_streaming(inst);
 		break;
@@ -757,8 +760,9 @@
 	}
 	inst->fmts[OUTPUT_PORT] = &vdec_formats[1];
 	inst->fmts[CAPTURE_PORT] = &vdec_formats[0];
-	inst->height = DEFAULT_HEIGHT;
-	inst->width = DEFAULT_WIDTH;
+	inst->prop.height = DEFAULT_HEIGHT;
+	inst->prop.width = DEFAULT_WIDTH;
+	inst->prop.fps = 30;
 	return rc;
 }
 
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
index 72c6685..fbd3378 100644
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -561,7 +561,7 @@
 			*num_buffers = MIN_NUM_OUTPUT_BUFFERS;
 		for (i = 0; i < *num_planes; i++) {
 			sizes[i] = inst->fmts[OUTPUT_PORT]->get_frame_size(
-					i, inst->height, inst->width);
+					i, inst->prop.height, inst->prop.width);
 		}
 		break;
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
@@ -571,8 +571,8 @@
 			break;
 		}
 		frame_sz.buffer_type = HAL_BUFFER_INPUT;
-		frame_sz.width = inst->width;
-		frame_sz.height = inst->height;
+		frame_sz.width = inst->prop.width;
+		frame_sz.height = inst->prop.height;
 		pr_debug("width = %d, height = %d\n",
 				frame_sz.width, frame_sz.height);
 		rc = vidc_hal_session_set_property((void *)inst->session,
@@ -603,7 +603,7 @@
 				inst->buff_req.buffer[0].buffer_count_actual);
 		for (i = 0; i < *num_planes; i++) {
 			sizes[i] = inst->fmts[CAPTURE_PORT]->get_frame_size(
-					i, inst->height, inst->width);
+					i, inst->prop.height, inst->prop.width);
 		}
 
 		break;
@@ -663,10 +663,14 @@
 	pr_debug("Streamon called on: %d capability\n", q->type);
 	switch (q->type) {
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		if (msm_comm_scale_clocks(inst->core))
+			pr_err("Failed to scale clocks. Performance/power might be impacted\n");
 		if (inst->vb2_bufq[CAPTURE_PORT].streaming)
 			rc = start_streaming(inst);
 		break;
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		if (msm_comm_scale_clocks(inst->core))
+			pr_err("Failed to scale clocks. Performance/power might be impacted\n");
 		if (inst->vb2_bufq[OUTPUT_PORT].streaming)
 			rc = start_streaming(inst);
 		break;
@@ -1195,8 +1199,9 @@
 	}
 	inst->fmts[CAPTURE_PORT] = &venc_formats[1];
 	inst->fmts[OUTPUT_PORT] = &venc_formats[0];
-	inst->height = DEFAULT_HEIGHT;
-	inst->width = DEFAULT_WIDTH;
+	inst->prop.height = DEFAULT_HEIGHT;
+	inst->prop.width = DEFAULT_WIDTH;
+	inst->prop.height = 30;
 	return rc;
 }
 
@@ -1275,8 +1280,8 @@
 			goto exit;
 		}
 	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-		inst->width = f->fmt.pix_mp.width;
-		inst->height = f->fmt.pix_mp.height;
+		inst->prop.width = f->fmt.pix_mp.width;
+		inst->prop.height = f->fmt.pix_mp.height;
 		fmt = msm_comm_get_pixel_fmt_fourcc(venc_formats,
 			ARRAY_SIZE(venc_formats), f->fmt.pix_mp.pixelformat,
 			OUTPUT_PORT);
@@ -1327,11 +1332,12 @@
 
 	if (fmt) {
 		f->fmt.pix_mp.pixelformat = fmt->fourcc;
-		f->fmt.pix_mp.height = inst->height;
-		f->fmt.pix_mp.width = inst->width;
+		f->fmt.pix_mp.height = inst->prop.height;
+		f->fmt.pix_mp.width = inst->prop.width;
 		for (i = 0; i < fmt->num_planes; ++i) {
 			f->fmt.pix_mp.plane_fmt[i].sizeimage =
-			fmt->get_frame_size(i, inst->height, inst->width);
+			fmt->get_frame_size(i, inst->prop.height,
+					inst->prop.width);
 		}
 	} else {
 		pr_err("Buf type not recognized, type = %d\n",
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index cd330316..329dfd8 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -34,6 +34,40 @@
 #define V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT \
 		V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT
 
+#define NUM_MBS_PER_SEC(__height, __width, __fps) ({\
+	(__height >> 4) * (__width >> 4) * __fps; \
+})
+
+static int msm_comm_get_load(struct msm_vidc_core *core)
+{
+	struct msm_vidc_inst *inst = NULL;
+	int num_mbs_per_sec = 0;
+	if (!core) {
+		pr_err("Invalid args: %p\n", core);
+		return -EINVAL;
+	}
+	list_for_each_entry(inst, &core->instances, list)
+		num_mbs_per_sec += NUM_MBS_PER_SEC(inst->prop.height,
+				inst->prop.width, inst->prop.fps);
+	return num_mbs_per_sec;
+}
+
+static unsigned long get_clock_rate(struct core_clock *clock,
+	int num_mbs_per_sec)
+{
+	int num_rows = clock->count;
+	struct load_freq_table *table = clock->load_freq_tbl;
+	unsigned long ret = table[num_rows-1].freq;
+	int i;
+	for (i = 0; i < num_rows; i++) {
+		if (num_mbs_per_sec > table[i].load)
+			break;
+		ret = table[i].freq;
+	}
+	pr_err("Required clock rate = %lu\n", ret);
+	return ret;
+}
+
 struct msm_vidc_core *get_vidc_core(int core_id)
 {
 	struct msm_vidc_core *core;
@@ -512,6 +546,70 @@
 		break;
 	}
 }
+
+int msm_comm_scale_clocks(struct msm_vidc_core *core)
+{
+	int num_mbs_per_sec;
+	int rc = 0;
+	if (!core) {
+		pr_err("Invalid args: %p\n", core);
+		return -EINVAL;
+	}
+	num_mbs_per_sec = msm_comm_get_load(core);
+	pr_err("num_mbs_per_sec = %d\n", num_mbs_per_sec);
+	rc = clk_set_rate(core->resources.clock[VCODEC_CLK].clk,
+			get_clock_rate(&core->resources.clock[VCODEC_CLK],
+				num_mbs_per_sec));
+	if (rc) {
+		pr_err("Failed to set clock rate: %d\n", rc);
+		goto fail_clk_set_rate;
+	}
+fail_clk_set_rate:
+	return rc;
+}
+
+static inline int msm_comm_enable_clks(struct msm_vidc_core *core)
+{
+	int i;
+	struct core_clock *cl;
+	int rc = 0;
+	if (!core) {
+		pr_err("Invalid params: %p\n", core);
+		return -EINVAL;
+	}
+	for (i = 0; i < VCODEC_MAX_CLKS; i++) {
+		cl = &core->resources.clock[i];
+		rc = clk_prepare_enable(cl->clk);
+		if (rc) {
+			pr_err("Failed to enable clocks\n");
+			goto fail_clk_enable;
+		} else {
+			pr_err("Clock: %s enabled\n", cl->name);
+		}
+	}
+	return rc;
+fail_clk_enable:
+	for (; i >= 0; i--) {
+		cl = &core->resources.clock[i];
+		clk_disable_unprepare(cl->clk);
+	}
+	return rc;
+}
+
+static inline void msm_comm_disable_clks(struct msm_vidc_core *core)
+{
+	int i;
+	struct core_clock *cl;
+	if (!core) {
+		pr_err("Invalid params: %p\n", core);
+		return;
+	}
+	for (i = 0; i < VCODEC_MAX_CLKS; i++) {
+		cl = &core->resources.clock[i];
+		clk_disable_unprepare(cl->clk);
+	}
+}
+
 static int msm_comm_load_fw(struct msm_vidc_core *core)
 {
 	int rc = 0;
@@ -519,6 +617,11 @@
 		pr_err("Invalid paramter: %p\n", core);
 		return -EINVAL;
 	}
+	rc = msm_comm_scale_clocks(core);
+	if (rc) {
+		pr_err("Failed to set clock rate: %d\n", rc);
+		goto fail_pil_get;
+	}
 
 	if (!core->resources.fw.cookie)
 		core->resources.fw.cookie = pil_get("venus");
@@ -528,6 +631,13 @@
 		rc = -ENOMEM;
 		goto fail_pil_get;
 	}
+
+	rc = msm_comm_enable_clks(core);
+	if (rc) {
+		pr_err("Failed to enable clocks: %d\n", rc);
+		goto fail_enable_clks;
+	}
+
 	rc = msm_comm_iommu_attach(core);
 	if (rc) {
 		pr_err("Failed to attach iommu");
@@ -535,6 +645,8 @@
 	}
 	return rc;
 fail_iommu_attach:
+	msm_comm_disable_clks(core);
+fail_enable_clks:
 	pil_put(core->resources.fw.cookie);
 	core->resources.fw.cookie = NULL;
 fail_pil_get:
@@ -551,6 +663,7 @@
 		pil_put(core->resources.fw.cookie);
 		core->resources.fw.cookie = NULL;
 		msm_comm_iommu_detach(core);
+		msm_comm_disable_clks(core);
 	}
 }
 
@@ -601,7 +714,7 @@
 	rc = msm_comm_load_fw(core);
 	if (rc) {
 		pr_err("Failed to load video firmware\n");
-		goto fail_fw_download;
+		goto fail_load_fw;
 	}
 	init_completion(&core->completions[SYS_MSG_INDEX(SYS_INIT_DONE)]);
 	rc = vidc_hal_core_init(core->device,
@@ -619,7 +732,7 @@
 	return rc;
 fail_core_init:
 	msm_comm_unload_fw(core);
-fail_fw_download:
+fail_load_fw:
 	mutex_unlock(&core->sync_lock);
 	return rc;
 }
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.h b/drivers/media/video/msm_vidc/msm_vidc_common.h
index 2fafa79..2009ca6 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.h
@@ -29,6 +29,7 @@
 int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst);
 int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst);
 int msm_comm_qbuf(struct vb2_buffer *vb);
+int msm_comm_scale_clocks(struct msm_vidc_core *core);
 #define IS_PRIV_CTRL(idx) (\
 		(V4L2_CTRL_ID2CLASS(idx) == V4L2_CTRL_CLASS_MPEG) && \
 		V4L2_CTRL_DRIVER_PRIV(idx))
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
index 151fb21..d5ac6fb 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_internal.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_internal.h
@@ -18,6 +18,7 @@
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/completion.h>
+#include <linux/clk.h>
 #include <media/v4l2-dev.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
@@ -42,6 +43,7 @@
 #define SYS_MSG_INDEX(__msg) (__msg - SYS_MSG_START)
 #define SESSION_MSG_INDEX(__msg) (__msg - SESSION_MSG_START)
 
+#define MAX_NAME_LENGTH 64
 enum vidc_ports {
 	OUTPUT_PORT,
 	CAPTURE_PORT,
@@ -86,7 +88,7 @@
 };
 
 struct msm_vidc_format {
-	char name[64];
+	char name[MAX_NAME_LENGTH];
 	u8 description[32];
 	u32 fourcc;
 	int num_planes;
@@ -112,8 +114,8 @@
 
 struct iommu_info {
 	u32 addr_range[2];
-	char name[64];
-	char ctx[64];
+	char name[MAX_NAME_LENGTH];
+	char ctx[MAX_NAME_LENGTH];
 	int domain;
 	int partition;
 };
@@ -124,9 +126,36 @@
 	MAX_MAP
 };
 
+enum vidc_clocks {
+	VCODEC_CLK,
+	VCODEC_AHB_CLK,
+	VCODEC_AXI_CLK,
+	VCODEC_OCMEM_CLK,
+	VCODEC_MAX_CLKS
+};
+
+struct load_freq_table {
+	u32 load;
+	u32 freq;
+};
+
+struct core_clock {
+	char name[MAX_NAME_LENGTH];
+	struct clk *clk;
+	u32 count;
+	struct load_freq_table load_freq_tbl[8];
+};
+
 struct msm_vidc_resources {
 	struct msm_vidc_fw fw;
 	struct iommu_info io_map[MAX_MAP];
+	struct core_clock clock[VCODEC_MAX_CLKS];
+};
+
+struct session_prop {
+	u32 width;
+	u32 height;
+	u32 fps;
 };
 
 struct msm_vidc_core {
@@ -154,6 +183,7 @@
 	struct msm_vidc_core *core;
 	int session_type;
 	void *session;
+	struct session_prop prop;
 	u32 width;
 	u32 height;
 	int state;
@@ -167,17 +197,17 @@
 	struct v4l2_ctrl_handler ctrl_handler;
 	struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1];
 	struct v4l2_fh event_handler;
+	struct msm_smem *extradata_handle;
 	bool in_reconfig;
 	u32 reconfig_width;
 	u32 reconfig_height;
-	struct msm_smem *extradata_handle;
 };
 
 extern struct msm_vidc_drv *vidc_driver;
 
 struct msm_vidc_ctrl {
 	u32 id;
-	char name[64];
+	char name[MAX_NAME_LENGTH];
 	enum v4l2_ctrl_type type;
 	s32 minimum;
 	s32 maximum;
diff --git a/drivers/media/video/msm_vidc/vidc_hal.c b/drivers/media/video/msm_vidc/vidc_hal.c
index 9052a63..646a0b8 100644
--- a/drivers/media/video/msm_vidc/vidc_hal.c
+++ b/drivers/media/video/msm_vidc/vidc_hal.c
@@ -15,6 +15,7 @@
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/delay.h>
 #include <asm/memory.h>
 #include "vidc_hal.h"
 #include "vidc_hal_io.h"
@@ -586,6 +587,7 @@
 		ctrl_status = read_register(
 		device->hal_data->register_base_addr,
 		VIDC_CPU_CS_SCIACMDARG0);
+		usleep_range(500, 1000);
 		count++;
 	}
 	if (count >= 25)