Merge changes I4b7123e9,I74fa8f0e into msm-3.4

* changes:
  msm: vidc: Adds bus scaling for video codecs
  msm: vidc: Change configuration flag for video.
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 956a043..e0de38d 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -214,7 +214,7 @@
 
 obj-$(CONFIG_MSM_CAMERA) += msm/
 obj-$(CONFIG_ARCH_OMAP)	+= omap/
-obj-$(CONFIG_MSM_VIDC) += msm_vidc/
+obj-$(CONFIG_MSM_VIDC_V4L2) += msm_vidc/
 
 ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
diff --git a/drivers/media/video/msm_vidc/Kconfig b/drivers/media/video/msm_vidc/Kconfig
index 2957d45..6428180 100644
--- a/drivers/media/video/msm_vidc/Kconfig
+++ b/drivers/media/video/msm_vidc/Kconfig
@@ -2,7 +2,7 @@
 # VIDEO CORE
 #
 
-menuconfig MSM_VIDC
+menuconfig MSM_VIDC_V4L2
 	bool "Qualcomm MSM Video Core Driver"
 		depends on ARCH_MSM8974 && VIDEO_V4L2
 		default y
diff --git a/drivers/media/video/msm_vidc/Makefile b/drivers/media/video/msm_vidc/Makefile
index 12c61c9..e145229 100644
--- a/drivers/media/video/msm_vidc/Makefile
+++ b/drivers/media/video/msm_vidc/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_MSM_VIDC) := 	msm_v4l2_vidc.o \
+obj-$(CONFIG_MSM_VIDC_V4L2) := 	msm_v4l2_vidc.o \
 				msm_vidc_common.o \
 				msm_vidc.o \
 				msm_vdec.o \
diff --git a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
index 4bc2a87..817caf5 100644
--- a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
@@ -32,6 +32,129 @@
 #define BASE_DEVICE_NUMBER 32
 #define MAX_EVENTS 30
 
+
+static struct msm_bus_vectors ocmem_init_vectors[]  = {
+	{
+		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = 0,
+	},
+};
+
+static struct msm_bus_vectors ocmem_perf0_vectors[]  = {
+	{
+		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
+		.dst = MSM_BUS_SLAVE_OCMEM,
+		.ab = 176900000,
+		.ib = 221125000,
+	},
+};
+
+static struct msm_bus_vectors ocmem_perf1_vectors[]  = {
+	{
+		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
+		.dst = MSM_BUS_SLAVE_OCMEM,
+		.ab = 456200000,
+		.ib = 570250000,
+	},
+};
+
+static struct msm_bus_vectors ocmem_perf2_vectors[]  = {
+	{
+		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
+		.dst = MSM_BUS_SLAVE_OCMEM,
+		.ab = 864800000,
+		.ib = 1081000000,
+	},
+};
+
+static struct msm_bus_paths ocmem_perf_vectors[]  = {
+	{
+		ARRAY_SIZE(ocmem_init_vectors),
+		ocmem_init_vectors,
+	},
+	{
+		ARRAY_SIZE(ocmem_perf0_vectors),
+		ocmem_perf0_vectors,
+	},
+	{
+		ARRAY_SIZE(ocmem_perf1_vectors),
+		ocmem_perf1_vectors,
+	},
+	{
+		ARRAY_SIZE(ocmem_perf2_vectors),
+		ocmem_perf2_vectors,
+	},
+};
+
+static struct msm_bus_scale_pdata ocmem_bus_data = {
+	.usecase = ocmem_perf_vectors,
+	.num_usecases = ARRAY_SIZE(ocmem_perf_vectors),
+	.name = "msm_vidc_ocmem",
+};
+
+static struct msm_bus_vectors vcodec_init_vectors[]  = {
+	{
+		.src = MSM_BUS_MASTER_VIDEO_P0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = 0,
+	},
+};
+
+static struct msm_bus_vectors vcodec_perf0_vectors[]  = {
+	{
+		.src = MSM_BUS_MASTER_VIDEO_P0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 110000000,
+		.ib = 137500000,
+	},
+};
+
+static struct msm_bus_vectors vcodec_perf1_vectors[]  = {
+	{
+		.src = MSM_BUS_MASTER_VIDEO_P0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 268000000,
+		.ib = 335000000,
+	},
+};
+
+static struct msm_bus_vectors vcodec_perf2_vectors[]  = {
+	{
+		.src = MSM_BUS_MASTER_VIDEO_P0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 505000000,
+		.ib = 631250000,
+	},
+};
+
+static struct msm_bus_paths vcodec_perf_vectors[]  = {
+	{
+		ARRAY_SIZE(vcodec_init_vectors),
+		vcodec_init_vectors,
+	},
+	{
+		ARRAY_SIZE(vcodec_perf0_vectors),
+		vcodec_perf0_vectors,
+	},
+	{
+		ARRAY_SIZE(vcodec_perf1_vectors),
+		vcodec_perf1_vectors,
+	},
+	{
+		ARRAY_SIZE(vcodec_perf2_vectors),
+		vcodec_perf2_vectors,
+	},
+};
+
+static struct msm_bus_scale_pdata vcodec_bus_data = {
+	.usecase = vcodec_perf_vectors,
+	.num_usecases = ARRAY_SIZE(vcodec_perf_vectors),
+	.name = "msm_vidc_vcodec",
+};
+
 struct msm_vidc_drv *vidc_driver;
 
 struct buffer_info {
@@ -613,6 +736,18 @@
 		rc = -ENODEV;
 		goto core_init_failed;
 	}
+	core->resources.bus_info.vcodec_handle =
+		msm_bus_scale_register_client(&vcodec_bus_data);
+	if (!core->resources.bus_info.vcodec_handle) {
+		pr_err("Failed to register bus scale client\n");
+		goto fail_register_vcodec_bus;
+	}
+	core->resources.bus_info.ocmem_handle =
+		msm_bus_scale_register_client(&ocmem_bus_data);
+	if (!core->resources.bus_info.ocmem_handle) {
+		pr_err("Failed to register bus scale client\n");
+		goto fail_register_ocmem;
+	}
 	rc = register_iommu_domains(pdev, core);
 	if (rc) {
 		pr_err("Failed to register iommu domains: %d\n", rc);
@@ -620,6 +755,12 @@
 	}
 	return rc;
 fail_register_domains:
+	msm_bus_scale_unregister_client(
+		core->resources.bus_info.ocmem_handle);
+fail_register_ocmem:
+	msm_bus_scale_unregister_client(
+		core->resources.bus_info.vcodec_handle);
+fail_register_vcodec_bus:
 	msm_vidc_deinit_clocks(core);
 core_init_failed:
 	return rc;
@@ -714,6 +855,8 @@
 {
 	int rc = 0;
 	struct msm_vidc_core *core = pdev->dev.platform_data;
+	msm_bus_scale_unregister_client(core->resources.bus_info.vcodec_handle);
+	msm_bus_scale_unregister_client(core->resources.bus_info.ocmem_handle);
 	vidc_hal_delete_device(core->device);
 	video_unregister_device(&core->vdev[MSM_VIDC_ENCODER].vdev);
 	video_unregister_device(&core->vdev[MSM_VIDC_DECODER].vdev);
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 329dfd8..fa9608d 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -38,6 +38,89 @@
 	(__height >> 4) * (__width >> 4) * __fps; \
 })
 
+#define VIDC_BUS_LOAD(__height, __width, __fps, __br) ({\
+	__height * __width * __fps; \
+})
+
+/*While adding entries to this array make sure
+ * they are in descending order.
+ * Look @ msm_comm_get_load function*/
+static const u32 clocks_table[][2] = {
+	{979200, 410000000},
+	{560145, 266670000},
+	{421161, 200000000},
+	{243000, 133330000},
+	{108000, 100000000},
+	{36000, 50000000},
+};
+
+static const u32 bus_table[] = {
+	0,
+	9216000,
+	27648000,
+	62208000,
+};
+
+static int msm_comm_get_bus_load(struct msm_vidc_core *core)
+{
+	struct msm_vidc_inst *inst = NULL;
+	int load = 0;
+	if (!core) {
+		pr_err("Invalid args: %p\n", core);
+		return -EINVAL;
+	}
+	list_for_each_entry(inst, &core->instances, list) {
+		load += VIDC_BUS_LOAD(inst->prop.height,
+				inst->prop.width, inst->prop.fps,
+				2000000);
+	}
+	return load;
+}
+
+static int get_bus_vector(int load)
+{
+	int num_rows = sizeof(bus_table)/(sizeof(u32));
+	int i;
+	for (i = num_rows - 1; i > 0; i--) {
+		if ((load >= bus_table[i]) || (i == 1))
+			break;
+	}
+	pr_err("Required bus = %d\n", i);
+	return i;
+}
+
+int msm_comm_scale_bus(struct msm_vidc_core *core)
+{
+	int load;
+	int rc = 0;
+	if (!core) {
+		pr_err("Invalid args: %p\n", core);
+		return -EINVAL;
+	}
+	load = msm_comm_get_bus_load(core);
+	if (load <= 0) {
+		pr_err("Failed to scale bus for %d load\n",
+			load);
+		goto fail_scale_bus;
+	}
+	rc = msm_bus_scale_client_update_request(
+			core->resources.bus_info.vcodec_handle,
+			get_bus_vector(load));
+	if (rc) {
+		pr_err("Failed to scale bus: %d\n", rc);
+		goto fail_scale_bus;
+	}
+	rc = msm_bus_scale_client_update_request(
+			core->resources.bus_info.ocmem_handle,
+			get_bus_vector(load));
+	if (rc) {
+		pr_err("Failed to scale bus: %d\n", rc);
+		goto fail_scale_bus;
+	}
+fail_scale_bus:
+	return rc;
+}
+
 static int msm_comm_get_load(struct msm_vidc_core *core)
 {
 	struct msm_vidc_inst *inst = NULL;
@@ -564,6 +647,9 @@
 		pr_err("Failed to set clock rate: %d\n", rc);
 		goto fail_clk_set_rate;
 	}
+	rc = msm_comm_scale_bus(core);
+	if (rc)
+		pr_err("Failed to scale bus bandwidth\n");
 fail_clk_set_rate:
 	return rc;
 }
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
index d5ac6fb..58d7290 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_internal.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_internal.h
@@ -19,6 +19,8 @@
 #include <linux/types.h>
 #include <linux/completion.h>
 #include <linux/clk.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
 #include <media/v4l2-dev.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
@@ -146,16 +148,23 @@
 	struct load_freq_table load_freq_tbl[8];
 };
 
+struct vidc_bus_info {
+	u32 vcodec_handle;
+	u32 ocmem_handle;
+};
+
 struct msm_vidc_resources {
 	struct msm_vidc_fw fw;
 	struct iommu_info io_map[MAX_MAP];
 	struct core_clock clock[VCODEC_MAX_CLKS];
+	struct vidc_bus_info bus_info;
 };
 
 struct session_prop {
 	u32 width;
 	u32 height;
 	u32 fps;
+	u32 bitrate;
 };
 
 struct msm_vidc_core {