diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c index 868df6f3580..9f0e285458c 100644 --- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c +++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c @@ -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)