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 {