vidc: Map firmware buffers after memory clocks are ON.

Change will delay mapping of buffers until bus bandwidth is
requested by video driver

Change-Id: Ibb6867baf6b3e821ec3ceafcdcab1e9225a5b109
Signed-off-by: Gopikrishnaiah Anandan <gopikr@codeaurora.org>
This commit is contained in:
Gopikrishnaiah Anandan
2012-01-10 18:43:50 -08:00
committed by Rajeshwar Kurapaty
parent 7ed41d531c
commit cc5d20d1c1

View File

@@ -28,6 +28,8 @@
static unsigned int vidc_clk_table[3] = {
48000000, 133330000, 200000000
};
static unsigned int restrk_mmu_subsystem[] = {
MSM_SUBSYSTEM_VIDEO, MSM_SUBSYSTEM_VIDEO_FWARE};
static struct res_trk_context resource_context;
#define VIDC_FW "vidc_1080p.fw"
@@ -49,6 +51,129 @@ u32 vidc_video_codec_fw_size;
static u32 res_trk_get_clk(void);
static void res_trk_put_clk(void);
static void *res_trk_pmem_map
(struct ddl_buf_addr *addr, size_t sz, u32 alignment)
{
u32 offset = 0, flags = 0;
u32 index = 0;
struct ddl_context *ddl_context;
struct msm_mapped_buffer *mapped_buffer = NULL;
ddl_context = ddl_get_context();
if (!addr->alloced_phys_addr) {
pr_err(" %s() alloced addres NULL", __func__);
goto bail_out;
}
flags = MSM_SUBSYSTEM_MAP_IOVA | MSM_SUBSYSTEM_MAP_KADDR;
if (alignment == DDL_KILO_BYTE(128))
index = 1;
else if (alignment > SZ_4K)
flags |= MSM_SUBSYSTEM_ALIGN_IOVA_8K;
addr->mapped_buffer =
msm_subsystem_map_buffer((unsigned long)addr->alloced_phys_addr,
sz, flags, &restrk_mmu_subsystem[index],
sizeof(restrk_mmu_subsystem[index])/sizeof(unsigned int));
if (IS_ERR(addr->mapped_buffer)) {
pr_err(" %s() buffer map failed", __func__);
goto bail_out;
}
mapped_buffer = addr->mapped_buffer;
if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) {
pr_err("%s() map buffers failed\n", __func__);
goto bail_out;
}
addr->physical_base_addr = (u8 *)mapped_buffer->iova[0];
addr->virtual_base_addr = mapped_buffer->vaddr;
addr->align_physical_addr = (u8 *) DDL_ALIGN((u32)
addr->physical_base_addr, alignment);
offset = (u32)(addr->align_physical_addr -
addr->physical_base_addr);
addr->align_virtual_addr = addr->virtual_base_addr + offset;
addr->buffer_size = sz;
return addr->virtual_base_addr;
bail_out:
return NULL;
}
static void *res_trk_pmem_alloc
(struct ddl_buf_addr *addr, size_t sz, u32 alignment)
{
u32 alloc_size;
struct ddl_context *ddl_context;
int rc = -EINVAL;
ion_phys_addr_t phyaddr = 0;
size_t len = 0;
DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz);
if (!addr) {
DDL_MSG_ERROR("\n%s() Invalid Parameters", __func__);
goto bail_out;
}
ddl_context = ddl_get_context();
res_trk_set_mem_type(addr->mem_type);
alloc_size = (sz + alignment);
if (res_trk_get_enable_ion()) {
if (!ddl_context->video_ion_client)
ddl_context->video_ion_client =
res_trk_get_ion_client();
if (!ddl_context->video_ion_client) {
DDL_MSG_ERROR("%s() :DDL ION Client Invalid handle\n",
__func__);
goto bail_out;
}
addr->alloc_handle = ion_alloc(
ddl_context->video_ion_client, alloc_size, SZ_4K,
res_trk_get_mem_type());
if (IS_ERR_OR_NULL(addr->alloc_handle)) {
DDL_MSG_ERROR("%s() :DDL ION alloc failed\n",
__func__);
goto bail_out;
}
rc = ion_phys(ddl_context->video_ion_client,
addr->alloc_handle, &phyaddr,
&len);
if (rc || !phyaddr) {
DDL_MSG_ERROR("%s():DDL ION client physical failed\n",
__func__);
goto free_acm_ion_alloc;
}
addr->alloced_phys_addr = phyaddr;
} else {
addr->alloced_phys_addr = (phys_addr_t)
allocate_contiguous_memory_nomap(alloc_size,
res_trk_get_mem_type(), SZ_4K);
if (!addr->alloced_phys_addr) {
DDL_MSG_ERROR("%s() : acm alloc failed (%d)\n",
__func__, alloc_size);
goto bail_out;
}
}
addr->buffer_size = sz;
return (void *)addr->alloced_phys_addr;
free_acm_ion_alloc:
if (ddl_context->video_ion_client) {
if (addr->alloc_handle) {
ion_free(ddl_context->video_ion_client,
addr->alloc_handle);
addr->alloc_handle = NULL;
}
}
bail_out:
return NULL;
}
static void res_trk_pmem_unmap(struct ddl_buf_addr *addr)
{
if (!addr) {
pr_err("%s() invalid args\n", __func__);
return;
}
if (addr->mapped_buffer)
msm_subsystem_unmap_buffer(addr->mapped_buffer);
addr->mapped_buffer = NULL;
}
static u32 res_trk_get_clk()
{
if (resource_context.vcodec_clk ||
@@ -263,6 +388,7 @@ u32 res_trk_power_up(void)
u32 res_trk_power_down(void)
{
VCDRES_MSG_LOW("clk_regime_rail_disable");
res_trk_pmem_unmap(&resource_context.firmware_addr);
#ifdef CONFIG_MSM_BUS_SCALING
msm_bus_scale_client_update_request(resource_context.pcl, 0);
msm_bus_scale_unregister_client(resource_context.pcl);
@@ -310,7 +436,6 @@ int res_trk_update_bus_perf_level(struct vcd_dev_ctxt *dev_ctxt, u32 perf_level)
if (dev_ctxt->reqd_perf_lvl + dev_ctxt->curr_perf_lvl == 0)
bus_clk_index = 2;
bus_clk_index = (bus_clk_index << 1) + (client_type + 1);
VCDRES_MSG_LOW("%s(), bus_clk_index = %d", __func__, bus_clk_index);
VCDRES_MSG_LOW("%s(),context.pcl = %x", __func__, resource_context.pcl);
@@ -465,7 +590,7 @@ void res_trk_init(struct device *device, u32 irq)
}
resource_context.core_type = VCD_CORE_1080P;
resource_context.firmware_addr.mem_type = DDL_FW_MEM;
if (!ddl_pmem_alloc(&resource_context.firmware_addr,
if (!res_trk_pmem_alloc(&resource_context.firmware_addr,
VIDC_FW_SIZE, DDL_KILO_BYTE(128))) {
pr_err("%s() Firmware buffer allocation failed",
__func__);
@@ -481,13 +606,20 @@ u32 res_trk_get_core_type(void){
u32 res_trk_get_firmware_addr(struct ddl_buf_addr *firm_addr)
{
int status = -1;
if (resource_context.firmware_addr.mapped_buffer) {
memcpy(firm_addr, &resource_context.firmware_addr,
sizeof(struct ddl_buf_addr));
status = 0;
if (!firm_addr || resource_context.firmware_addr.mapped_buffer) {
pr_err("%s() invalid params", __func__);
return -EINVAL;
}
return status;
if (!res_trk_pmem_map(&resource_context.firmware_addr,
resource_context.firmware_addr.buffer_size,
DDL_KILO_BYTE(128))) {
pr_err("%s() Firmware buffer mapping failed",
__func__);
return -EINVAL;
}
memcpy(firm_addr, &resource_context.firmware_addr,
sizeof(struct ddl_buf_addr));
return 0;
}
u32 res_trk_get_mem_type(void)