diff --git a/drivers/media/platform/msm/cvp/cvp.c b/drivers/media/platform/msm/cvp/cvp.c index 09280360976f..27242ba6582f 100644 --- a/drivers/media/platform/msm/cvp/cvp.c +++ b/drivers/media/platform/msm/cvp/cvp.c @@ -572,10 +572,9 @@ static int __init msm_cvp_init(void) } cvp_driver->msg_cache = KMEM_CACHE(cvp_session_msg, 0); - cvp_driver->fence_data_cache = KMEM_CACHE(msm_cvp_fence_thread_data, 0); cvp_driver->frame_cache = KMEM_CACHE(msm_cvp_frame, 0); - cvp_driver->frame_buf_cache = KMEM_CACHE(msm_cvp_frame_buf, 0); - cvp_driver->internal_buf_cache = KMEM_CACHE(msm_cvp_internal_buffer, 0); + cvp_driver->buf_cache = KMEM_CACHE(cvp_internal_buf, 0); + cvp_driver->smem_cache = KMEM_CACHE(msm_cvp_smem, 0); rc = cvp_dsp_device_init(); if (rc) @@ -588,10 +587,9 @@ static void __exit msm_cvp_exit(void) { cvp_dsp_device_exit(); kmem_cache_destroy(cvp_driver->msg_cache); - kmem_cache_destroy(cvp_driver->fence_data_cache); kmem_cache_destroy(cvp_driver->frame_cache); - kmem_cache_destroy(cvp_driver->frame_buf_cache); - kmem_cache_destroy(cvp_driver->internal_buf_cache); + kmem_cache_destroy(cvp_driver->buf_cache); + kmem_cache_destroy(cvp_driver->smem_cache); platform_driver_unregister(&msm_cvp_driver); debugfs_remove_recursive(cvp_driver->debugfs_root); diff --git a/drivers/media/platform/msm/cvp/cvp_hfi.c b/drivers/media/platform/msm/cvp/cvp_hfi.c index e8e125b33ae2..0f20d31dd185 100644 --- a/drivers/media/platform/msm/cvp/cvp_hfi.c +++ b/drivers/media/platform/msm/cvp/cvp_hfi.c @@ -809,9 +809,7 @@ static int __smem_alloc(struct iris_hfi_device *dev, struct cvp_mem_addr *mem, } dprintk(CVP_INFO, "start to alloc size: %d, flags: %d\n", size, flags); - rc = msm_cvp_smem_alloc( - size, align, flags, 1, (void *)dev->res, - MSM_CVP_UNKNOWN, alloc); + rc = msm_cvp_smem_alloc(size, align, flags, 1, (void *)dev->res, alloc); if (rc) { dprintk(CVP_ERR, "Alloc failed\n"); rc = -ENOMEM; @@ -1512,7 +1510,7 @@ static int __interface_dsp_queues_init(struct iris_hfi_device *dev) dprintk(CVP_ERR, "%s: failed dma allocation\n", __func__); goto fail_dma_alloc; } - cb = msm_cvp_smem_get_context_bank(MSM_CVP_UNKNOWN, 0, dev->res, 0); + cb = msm_cvp_smem_get_context_bank(0, dev->res, 0); if (!cb) { dprintk(CVP_ERR, "%s: failed to get context bank\n", __func__); @@ -1533,7 +1531,7 @@ static int __interface_dsp_queues_init(struct iris_hfi_device *dev) mem_data->device_addr = iova; mem_data->dma_handle = dma_handle; mem_data->size = q_size; - mem_data->buffer_type = 0; + mem_data->ion_flags = 0; mem_data->mapping_info.cb_info = cb; if (!is_iommu_present(dev->res)) @@ -1621,8 +1619,7 @@ static void __interface_queues_release(struct iris_hfi_device *device) } mem_map = (struct cvp_hfi_mem_map *)(qdss + 1); - cb = msm_cvp_smem_get_context_bank(MSM_CVP_UNKNOWN, - false, device->res, 0); + cb = msm_cvp_smem_get_context_bank(false, device->res, 0); for (i = 0; cb && i < num_entries; i++) { iommu_unmap(cb->domain, @@ -1846,8 +1843,7 @@ static int __interface_queues_init(struct iris_hfi_device *dev) qdss->mem_map_table_base_addr = mem_map_table_base_addr; mem_map = (struct cvp_hfi_mem_map *)(qdss + 1); - cb = msm_cvp_smem_get_context_bank(MSM_CVP_UNKNOWN, false, - dev->res, 0); + cb = msm_cvp_smem_get_context_bank(false, dev->res, 0); if (!cb) { dprintk(CVP_ERR, "%s: failed to get context bank\n", __func__); @@ -2344,15 +2340,14 @@ static int iris_hfi_session_abort(void *sess) return rc; } -static int iris_hfi_session_set_buffers(void *sess, - struct cvp_buffer_addr_info *buffer_info) +static int iris_hfi_session_set_buffers(void *sess, u32 iova, u32 size) { struct cvp_hfi_cmd_session_set_buffers_packet pkt; int rc = 0; struct cvp_hal_session *session = sess; struct iris_hfi_device *device; - if (!session || !session->device || !buffer_info) { + if (!session || !session->device || !iova || !size) { dprintk(CVP_ERR, "Invalid Params\n"); return -EINVAL; } @@ -2366,13 +2361,12 @@ static int iris_hfi_session_set_buffers(void *sess, } rc = call_hfi_pkt_op(device, session_set_buffers, - &pkt, session, buffer_info); + &pkt, session, iova, size); if (rc) { dprintk(CVP_ERR, "set buffers: failed to create packet\n"); goto err_create_pkt; } - dprintk(CVP_DBG, "set buffers: %#x\n", buffer_info->buffer_type); if (__iface_cmdq_write(session->device, &pkt)) rc = -ENOTEMPTY; @@ -2381,15 +2375,14 @@ err_create_pkt: return rc; } -static int iris_hfi_session_release_buffers(void *sess, - struct cvp_buffer_addr_info *buffer_info) +static int iris_hfi_session_release_buffers(void *sess) { struct cvp_session_release_buffers_packet pkt; int rc = 0; struct cvp_hal_session *session = sess; struct iris_hfi_device *device; - if (!session || !session->device || !buffer_info) { + if (!session || !session->device) { dprintk(CVP_ERR, "Invalid Params\n"); return -EINVAL; } @@ -2402,8 +2395,7 @@ static int iris_hfi_session_release_buffers(void *sess, goto err_create_pkt; } - rc = call_hfi_pkt_op(device, session_release_buffers, - &pkt, session, buffer_info); + rc = call_hfi_pkt_op(device, session_release_buffers, &pkt, session); if (rc) { dprintk(CVP_ERR, "release buffers: failed to create packet\n"); goto err_create_pkt; @@ -2878,14 +2870,12 @@ static void **get_session_id(struct msm_cvp_cb_info *info) case HAL_SESSION_FD_CONFIG_CMD_DONE: case HAL_SESSION_MODEL_BUF_CMD_DONE: case HAL_SESSION_PROPERTY_INFO: + case HAL_SESSION_EVENT_CHANGE: session_id = &info->response.cmd.session_id; break; case HAL_SESSION_ERROR: session_id = &info->response.data.session_id; break; - case HAL_SESSION_EVENT_CHANGE: - session_id = &info->response.event.session_id; - break; case HAL_RESPONSE_UNUSED: default: session_id = NULL; diff --git a/drivers/media/platform/msm/cvp/cvp_hfi_api.h b/drivers/media/platform/msm/cvp/cvp_hfi_api.h index a2fe140d7af8..e1eb9d4e96fe 100644 --- a/drivers/media/platform/msm/cvp/cvp_hfi_api.h +++ b/drivers/media/platform/msm/cvp/cvp_hfi_api.h @@ -162,22 +162,6 @@ struct cvp_resource_hdr { void *resource_handle; }; -struct cvp_buffer_addr_info { - enum hal_buffer buffer_type; - u32 buffer_size; - u32 num_buffers; - u32 align_device_addr; - u32 extradata_addr; - u32 extradata_size; - u32 response_required; -}; - -/* Needs to be exactly the same as hfi_buffer_info */ -struct cvp_hal_buffer_info { - u32 buffer_addr; - u32 extra_data_addr; -}; - struct cvp_hal_fw_info { char version[CVP_VERSION_LENGTH]; phys_addr_t base_addr; @@ -186,13 +170,6 @@ struct cvp_hal_fw_info { int irq; }; -enum hal_flush { - HAL_FLUSH_INPUT, - HAL_FLUSH_OUTPUT, - HAL_FLUSH_ALL, - HAL_UNUSED_FLUSH = 0x10000000, -}; - enum hal_event_type { HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES, HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES, @@ -282,56 +259,24 @@ struct msm_cvp_cb_cmd_done { union { struct cvp_hfi_msg_session_hdr msg_hdr; struct cvp_resource_hdr resource_hdr; - struct cvp_buffer_addr_info buffer_addr_info; struct cvp_hal_sys_init_done sys_init_done; struct cvp_hal_session_init_done session_init_done; - struct cvp_hal_buffer_info buffer_info; - enum hal_flush flush_type; + u32 buffer_addr; } data; }; -struct cvp_hal_index_extradata_input_crop_payload { - u32 size; - u32 version; - u32 port_index; - u32 left; - u32 top; - u32 width; - u32 height; -}; - -struct msm_cvp_cb_event { - u32 device_id; - void *session_id; - enum cvp_status status; - u32 height; - u32 width; - int bit_depth; - u32 hal_event_type; - u32 packet_buffer; - u32 extra_data_buffer; - u32 pic_struct; - u32 colour_space; - u32 profile; - u32 level; - u32 entropy_mode; - u32 capture_buf_count; - struct cvp_hal_index_extradata_input_crop_payload crop_data; -}; - struct msm_cvp_cb_data_done { u32 device_id; void *session_id; enum cvp_status status; u32 size; - u32 clnt_data; + u32 client_data; }; struct msm_cvp_cb_info { enum hal_command_response response_type; union { struct msm_cvp_cb_cmd_done cmd; - struct msm_cvp_cb_event event; struct msm_cvp_cb_data_done data; } response; }; @@ -393,10 +338,8 @@ struct cvp_hfi_device { int (*session_init)(void *device, void *session_id, void **new_session); int (*session_end)(void *session); int (*session_abort)(void *session); - int (*session_set_buffers)(void *sess, - struct cvp_buffer_addr_info *buffer_info); - int (*session_release_buffers)(void *sess, - struct cvp_buffer_addr_info *buffer_info); + int (*session_set_buffers)(void *sess, u32 iova, u32 size); + int (*session_release_buffers)(void *sess); int (*session_send)(void *sess, struct cvp_kmd_hfi_packet *in_pkt); int (*scale_clocks)(void *dev, u32 freq); diff --git a/drivers/media/platform/msm/cvp/cvp_hfi_helper.h b/drivers/media/platform/msm/cvp/cvp_hfi_helper.h index 52d5bee69152..0c79b47e9b54 100644 --- a/drivers/media/platform/msm/cvp/cvp_hfi_helper.h +++ b/drivers/media/platform/msm/cvp/cvp_hfi_helper.h @@ -291,7 +291,7 @@ struct cvp_hfi_client { } __packed; struct cvp_hfi_buf_type { - s32 fd; + u32 iova; u32 size; u32 offset; u32 flags; @@ -369,12 +369,6 @@ struct cvp_hfi_msg_session_op_cfg_packet { u32 op_conf_id; } __packed; -struct cvp_hfi_msg_release_buffer_ref_event_packet { - u32 packet_buffer; - u32 extra_data_buffer; - u32 output_tag; -}; - struct cvp_hfi_msg_sys_init_done_packet { u32 size; u32 packet_type; diff --git a/drivers/media/platform/msm/cvp/hfi_packetization.c b/drivers/media/platform/msm/cvp/hfi_packetization.c index 3394115a519b..846b2208dee3 100644 --- a/drivers/media/platform/msm/cvp/hfi_packetization.c +++ b/drivers/media/platform/msm/cvp/hfi_packetization.c @@ -300,7 +300,8 @@ int cvp_create_pkt_cmd_sys_power_control( int cvp_create_pkt_cmd_session_set_buffers( void *cmd, struct cvp_hal_session *session, - struct cvp_buffer_addr_info *buffer_info) + u32 iova, + u32 size) { int rc = 0; struct cvp_hfi_cmd_session_set_buffers_packet *pkt; @@ -311,8 +312,8 @@ int cvp_create_pkt_cmd_session_set_buffers( pkt = (struct cvp_hfi_cmd_session_set_buffers_packet *)cmd; pkt->packet_type = HFI_CMD_SESSION_CVP_SET_BUFFERS; pkt->session_id = hash32_ptr(session); - pkt->buf_type.fd = buffer_info->align_device_addr; - pkt->buf_type.size = buffer_info->buffer_size; + pkt->buf_type.iova = iova; + pkt->buf_type.size = size; pkt->size = sizeof(struct cvp_hfi_cmd_session_set_buffers_packet); return rc; @@ -320,8 +321,7 @@ int cvp_create_pkt_cmd_session_set_buffers( int cvp_create_pkt_cmd_session_release_buffers( void *cmd, - struct cvp_hal_session *session, - struct cvp_buffer_addr_info *buffer_info) + struct cvp_hal_session *session) { struct cvp_session_release_buffers_packet *pkt; @@ -331,16 +331,10 @@ int cvp_create_pkt_cmd_session_release_buffers( pkt = (struct cvp_session_release_buffers_packet *)cmd; pkt->packet_type = HFI_CMD_SESSION_CVP_RELEASE_BUFFERS; pkt->session_id = hash32_ptr(session); - pkt->num_buffers = buffer_info->num_buffers; - pkt->buffer_type = buffer_info->buffer_type; + pkt->num_buffers = 1; + pkt->buffer_type = 0; pkt->size = sizeof(struct cvp_session_release_buffers_packet) + - ((buffer_info->num_buffers - 1) * sizeof(u32)); - - if (buffer_info->buffer_type == HAL_BUFFER_OUTPUT || - buffer_info->buffer_type == HAL_BUFFER_OUTPUT2) { - dprintk(CVP_ERR, "%s: deprecated buffer_type\n", __func__); - return -EINVAL; - } + ((pkt->num_buffers - 1) * sizeof(u32)); return 0; } diff --git a/drivers/media/platform/msm/cvp/hfi_packetization.h b/drivers/media/platform/msm/cvp/hfi_packetization.h index dcadde46f319..757fe7b96ae0 100644 --- a/drivers/media/platform/msm/cvp/hfi_packetization.h +++ b/drivers/media/platform/msm/cvp/hfi_packetization.h @@ -53,16 +53,14 @@ struct cvp_hfi_packetization_ops { int (*session_set_buffers)( void *pkt, struct cvp_hal_session *session, - struct cvp_buffer_addr_info *buffer_info); + u32 iova, + u32 size); int (*session_release_buffers)( void *pkt, - struct cvp_hal_session *session, - struct cvp_buffer_addr_info *buffer_info); + struct cvp_hal_session *session); int (*session_get_buf_req)( struct cvp_hfi_cmd_session_get_property_packet *pkt, struct cvp_hal_session *session); - int (*session_flush)(struct cvp_hfi_cmd_session_flush_packet *pkt, - struct cvp_hal_session *session, enum hal_flush flush_mode); int (*session_sync_process)( struct cvp_hfi_cmd_session_sync_process_packet *pkt, struct cvp_hal_session *session); diff --git a/drivers/media/platform/msm/cvp/msm_cvp.c b/drivers/media/platform/msm/cvp/msm_cvp.c index 677307dbdc9e..3c9b74ba36ec 100644 --- a/drivers/media/platform/msm/cvp/msm_cvp.c +++ b/drivers/media/platform/msm/cvp/msm_cvp.c @@ -14,23 +14,35 @@ struct cvp_power_level { }; void print_internal_buffer(u32 tag, const char *str, - struct msm_cvp_inst *inst, struct msm_cvp_internal_buffer *cbuf) + struct msm_cvp_inst *inst, struct cvp_internal_buf *cbuf) { if (!(tag & msm_cvp_debug) || !inst || !cbuf) return; - if (cbuf->smem.dma_buf) { + if (cbuf->smem->dma_buf) { dprintk(tag, - "%s: %x : idx %2d fd %d off %d %s size %d flags %#x iova %#x", - str, hash32_ptr(inst->session), cbuf->buf.index, cbuf->buf.fd, - cbuf->buf.offset, cbuf->smem.dma_buf->name, cbuf->buf.size, - cbuf->buf.flags, cbuf->smem.device_addr); + "%s: %x : fd %d off %d %s size %d iova %#x", + str, hash32_ptr(inst->session), cbuf->fd, + cbuf->offset, cbuf->smem->dma_buf->name, cbuf->size, + cbuf->smem->device_addr); } else { dprintk(tag, - "%s: %x : idx %2d fd %d off %d size %d flags %#x iova %#x", - str, hash32_ptr(inst->session), cbuf->buf.index, cbuf->buf.fd, - cbuf->buf.offset, cbuf->buf.size, cbuf->buf.flags, - cbuf->smem.device_addr); + "%s: %x : idx %2d fd %d off %d size %d iova %#x", + str, hash32_ptr(inst->session), cbuf->fd, + cbuf->offset, cbuf->size, cbuf->smem->device_addr); + } +} + +void print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, + struct msm_cvp_smem *smem) +{ + if (!(tag & msm_cvp_debug) || !inst || !smem) + return; + + if (smem->dma_buf) { + dprintk(tag, "%s: %x : %s size %d flags %#x iova %#x", str, + hash32_ptr(inst->session), smem->dma_buf->name, smem->size, + smem->flags, smem->device_addr); } } @@ -58,48 +70,26 @@ static int msm_cvp_get_session_info(struct msm_cvp_inst *inst, return rc; } -static int msm_cvp_session_get_iova_addr( - struct msm_cvp_inst *inst, - struct cvp_buf_type *in_buf, - unsigned int *iova) -{ - struct msm_cvp_internal_buffer *cbuf; - - if (!inst | !iova) { - dprintk(CVP_ERR, "%s: invalid params\n", __func__); - return -EINVAL; - } - - mutex_lock(&inst->cvpcpubufs.lock); - list_for_each_entry(cbuf, &inst->cvpcpubufs.list, list) { - if (cbuf->smem.dma_buf == in_buf->dbuf && - cbuf->buf.size == in_buf->size && - cbuf->buf.offset == in_buf->offset) { - *iova = cbuf->smem.device_addr + cbuf->buf.offset; - print_internal_buffer(CVP_DBG, "found", inst, cbuf); - mutex_unlock(&inst->cvpcpubufs.lock); - return 0; - } - } - mutex_unlock(&inst->cvpcpubufs.lock); - *iova = 0; - - return -ENOENT; -} - static int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, - struct cvp_kmd_buffer *buf) + struct cvp_kmd_buffer *buf) { int rc = 0; - bool found; - struct msm_cvp_internal_buffer *cbuf; + bool found = false; + struct cvp_internal_buf *cbuf; + struct msm_cvp_smem *smem = NULL; struct cvp_hal_session *session; + struct dma_buf *dma_buf = NULL; if (!inst || !inst->core || !buf) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); return -EINVAL; } + if (buf->fd < 0) { + dprintk(CVP_ERR, "%s: Invalid fd = %d", __func__, buf->fd); + return 0; + } + if (buf->offset) { dprintk(CVP_ERR, "%s: offset is deprecated, set to 0.\n", @@ -108,11 +98,11 @@ static int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, } session = (struct cvp_hal_session *)inst->session; + mutex_lock(&inst->cvpdspbufs.lock); - found = false; list_for_each_entry(cbuf, &inst->cvpdspbufs.list, list) { - if (cbuf->buf.fd == buf->fd) { - if (cbuf->buf.size != buf->size) { + if (cbuf->fd == buf->fd) { + if (cbuf->size != buf->size) { dprintk(CVP_ERR, "%s: buf size mismatch\n", __func__); mutex_unlock(&inst->cvpdspbufs.lock); @@ -128,18 +118,25 @@ static int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, return -EINVAL; } - cbuf = kmem_cache_zalloc(cvp_driver->internal_buf_cache, GFP_KERNEL); + dma_buf = msm_cvp_smem_get_dma_buf(buf->fd); + if (!dma_buf) { + dprintk(CVP_ERR, "%s: Invalid fd = %d", __func__, buf->fd); + return 0; + } + + cbuf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); if (!cbuf) return -ENOMEM; - memcpy(&cbuf->buf, buf, sizeof(struct cvp_kmd_buffer)); - cbuf->smem.buffer_type = 0; - cbuf->smem.fd = buf->fd; - cbuf->smem.offset = buf->offset; - cbuf->smem.size = buf->size; - cbuf->smem.flags = buf->flags; + smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); + if (!smem) { + kmem_cache_free(cvp_driver->buf_cache, cbuf); + return -ENOMEM; + } - rc = msm_cvp_smem_map_dma_buf(inst, &cbuf->smem); + smem->dma_buf = dma_buf; + dprintk(CVP_ERR, "%s: dma_buf = %llx\n", __func__, dma_buf); + rc = msm_cvp_map_smem(inst, smem); if (rc) { print_client_buffer(CVP_ERR, "map failed", inst, buf); goto exit; @@ -147,8 +144,8 @@ static int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, if (buf->index) { rc = cvp_dsp_register_buffer(hash32_ptr(session), buf->fd, - cbuf->smem.dma_buf->size, buf->size, buf->offset, - buf->index, (uint32_t)cbuf->smem.device_addr); + smem->dma_buf->size, buf->size, buf->offset, + buf->index, (uint32_t)smem->device_addr); if (rc) { dprintk(CVP_ERR, "%s: failed dsp registration for fd=%d rc=%d", @@ -156,12 +153,18 @@ static int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, goto exit; } } else { - dprintk(CVP_ERR, "%s: buf index is 0 fd=%d", - __func__, buf->fd); + dprintk(CVP_ERR, "%s: buf index is 0 fd=%d", __func__, buf->fd); rc = -EINVAL; goto exit; } + cbuf->smem = smem; + cbuf->fd = buf->fd; + cbuf->size = buf->size; + cbuf->offset = buf->offset; + cbuf->ownership = CLIENT; + cbuf->index = buf->index; + mutex_lock(&inst->cvpdspbufs.lock); list_add_tail(&cbuf->list, &inst->cvpdspbufs.list); mutex_unlock(&inst->cvpdspbufs.lock); @@ -169,11 +172,12 @@ static int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, return rc; exit: - if (cbuf->smem.device_addr) - msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem); - kmem_cache_free(cvp_driver->internal_buf_cache, cbuf); + if (smem->device_addr) + msm_cvp_unmap_smem(smem); + kmem_cache_free(cvp_driver->buf_cache, cbuf); cbuf = NULL; - + kmem_cache_free(cvp_driver->smem_cache, smem); + smem = NULL; return rc; } @@ -182,7 +186,7 @@ static int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, { int rc = 0; bool found; - struct msm_cvp_internal_buffer *cbuf; + struct cvp_internal_buf *cbuf; struct cvp_hal_session *session; if (!inst || !inst->core || !buf) { @@ -199,7 +203,7 @@ static int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, mutex_lock(&inst->cvpdspbufs.lock); found = false; list_for_each_entry(cbuf, &inst->cvpdspbufs.list, list) { - if (cbuf->buf.fd == buf->fd) { + if (cbuf->fd == buf->fd) { found = true; break; } @@ -212,8 +216,8 @@ static int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, if (buf->index) { rc = cvp_dsp_deregister_buffer(hash32_ptr(session), buf->fd, - cbuf->smem.dma_buf->size, buf->size, buf->offset, - buf->index, (uint32_t)cbuf->smem.device_addr); + cbuf->smem->dma_buf->size, buf->size, buf->offset, + buf->index, (uint32_t)cbuf->smem->device_addr); if (rc) { dprintk(CVP_ERR, "%s: failed dsp deregistration fd=%d rc=%d", @@ -222,27 +226,29 @@ static int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, } } - if (cbuf->smem.device_addr) - msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem); + if (cbuf->smem->device_addr) + msm_cvp_unmap_smem(cbuf->smem); mutex_lock(&inst->cvpdspbufs.lock); list_del(&cbuf->list); mutex_unlock(&inst->cvpdspbufs.lock); - kmem_cache_free(cvp_driver->internal_buf_cache, cbuf); + kmem_cache_free(cvp_driver->smem_cache, cbuf->smem); + kmem_cache_free(cvp_driver->buf_cache, cbuf); return rc; } -static void __msm_cvp_cache_operations(struct msm_cvp_internal_buffer *cbuf) +static void msm_cvp_cache_operations(struct msm_cvp_smem *smem, u32 type, + u32 offset, u32 size) { enum smem_cache_ops cache_op; - if (!cbuf) { + if (!smem) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); return; } - switch (cbuf->buf.type) { + switch (type) { case CVP_KMD_BUFTYPE_INPUT: cache_op = SMEM_CACHE_CLEAN; break; @@ -253,202 +259,228 @@ static void __msm_cvp_cache_operations(struct msm_cvp_internal_buffer *cbuf) cache_op = SMEM_CACHE_CLEAN_INVALIDATE; } - msm_cvp_smem_cache_operations(cbuf->smem.dma_buf, cache_op, - cbuf->buf.offset, cbuf->buf.size); + msm_cvp_smem_cache_operations(smem->dma_buf, cache_op, offset, size); } -static int msm_cvp_map_buf_user_persist(struct msm_cvp_inst *inst, - struct cvp_buf_type *in_buf, - u32 *iova) +static struct msm_cvp_smem *msm_cvp_session_find_smem( + struct msm_cvp_inst *inst, + struct dma_buf *dma_buf) { - int rc = 0; - struct cvp_internal_buf *cbuf; - struct dma_buf *dma_buf; + struct msm_cvp_smem *smem; - if (!inst || !iova) { - dprintk(CVP_ERR, "%s: invalid params\n", __func__); - return -EINVAL; - } - - if (in_buf->fd > 0) { - dma_buf = msm_cvp_smem_get_dma_buf(in_buf->fd); - if (!dma_buf) { - dprintk(CVP_ERR, "%s: Invalid fd=%d", __func__, - in_buf->fd); - return -EINVAL; + mutex_lock(&inst->cpusmems.lock); + list_for_each_entry(smem, &inst->cpusmems.list, list) { + if (smem->dma_buf == dma_buf) { + atomic_inc(&smem->refcount); + /* + * If we find it, it means we already increased + * refcount before, so we put it to avoid double + * incremental. + */ + msm_cvp_smem_put_dma_buf(smem->dma_buf); + mutex_unlock(&inst->cpusmems.lock); + print_smem(CVP_DBG, "found", inst, smem); + return smem; } - in_buf->dbuf = dma_buf; - msm_cvp_smem_put_dma_buf(dma_buf); } + mutex_unlock(&inst->cpusmems.lock); - rc = msm_cvp_session_get_iova_addr(inst, in_buf, iova); - if (!rc && *iova != 0) - return 0; - cbuf = kzalloc(sizeof(*cbuf), GFP_KERNEL); - if (!cbuf) - return -ENOMEM; - - cbuf->smem.buffer_type = in_buf->flags; - cbuf->smem.fd = in_buf->fd; - cbuf->smem.size = in_buf->size; - cbuf->smem.flags = 0; - cbuf->smem.offset = 0; - cbuf->smem.dma_buf = in_buf->dbuf; - cbuf->buffer_ownership = CLIENT; - - rc = msm_cvp_smem_map_dma_buf(inst, &cbuf->smem); - if (rc) { - dprintk(CVP_ERR, - "%s: %x : fd %d size %d", - "map persist failed", hash32_ptr(inst->session), cbuf->smem.fd, - cbuf->smem.size); - goto exit; - } - - /* Assign mapped dma_buf back because it could be zero previously */ - in_buf->dbuf = cbuf->smem.dma_buf; - - mutex_lock(&inst->persistbufs.lock); - list_add_tail(&cbuf->list, &inst->persistbufs.list); - mutex_unlock(&inst->persistbufs.lock); - - *iova = cbuf->smem.device_addr; - - dprintk(CVP_DBG, - "%s: %x : fd %d %s size %d", "map persist", hash32_ptr(inst->session), - cbuf->smem.fd, cbuf->smem.dma_buf->name, cbuf->smem.size); - return rc; - -exit: - kfree(cbuf); - cbuf = NULL; - - return rc; + return NULL; } -static int msm_cvp_map_buf_cpu(struct msm_cvp_inst *inst, - struct cvp_buf_type *in_buf, - u32 *iova, - struct msm_cvp_frame *frame) +static int msm_cvp_session_add_smem(struct msm_cvp_inst *inst, + struct msm_cvp_smem *smem) +{ + struct msm_cvp_smem *smem2, *d; + int found = false; + + mutex_lock(&inst->cpusmems.lock); + if (inst->cpusmems.nr == inst->cpusmems.maxnr) { + list_for_each_entry_safe(smem2, d, &inst->cpusmems.list, list) { + if (atomic_read(&smem2->refcount) == 0) { + found = true; + list_del(&smem2->list); + + msm_cvp_unmap_smem(smem2); + msm_cvp_smem_put_dma_buf(smem2->dma_buf); + kmem_cache_free(cvp_driver->smem_cache, smem2); + smem2 = NULL; + + break; + } + } + + if (!found) { + dprintk(CVP_ERR, "%s: not enough memory\n", __func__); + mutex_unlock(&inst->cpusmems.lock); + return -ENOMEM; + } + inst->cpusmems.nr--; + } + + atomic_inc(&smem->refcount); + list_add_tail(&smem->list, &inst->cpusmems.list); + inst->cpusmems.nr++; + mutex_unlock(&inst->cpusmems.lock); + + return 0; +} + +static struct msm_cvp_smem *msm_cvp_session_get_smem( + struct msm_cvp_inst *inst, + struct cvp_buf_type *buf) { int rc = 0; - struct msm_cvp_internal_buffer *cbuf; - struct msm_cvp_frame_buf *frame_buf; - struct dma_buf *dma_buf; + struct msm_cvp_smem *smem = NULL; + struct dma_buf *dma_buf = NULL; - if (!inst || !iova || !frame) { - dprintk(CVP_ERR, "%s: invalid params\n", __func__); - return -EINVAL; + if (buf->fd < 0) { + dprintk(CVP_ERR, "%s: Invalid fd = %d", __func__, buf->fd); + return NULL; } - if (in_buf->fd > 0) { - dma_buf = msm_cvp_smem_get_dma_buf(in_buf->fd); - if (!dma_buf) { - dprintk(CVP_ERR, "%s: Invalid fd=%d", __func__, - in_buf->fd); - return -EINVAL; - } - in_buf->dbuf = dma_buf; - msm_cvp_smem_put_dma_buf(dma_buf); + dma_buf = msm_cvp_smem_get_dma_buf(buf->fd); + if (!dma_buf) { + dprintk(CVP_ERR, "%s: Invalid fd = %d", __func__, buf->fd); + return NULL; } - rc = msm_cvp_session_get_iova_addr(inst, in_buf, iova); - if (!rc && *iova != 0) - return 0; + smem = msm_cvp_session_find_smem(inst, dma_buf); + if (!smem) { + smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); + if (!smem) + return NULL; - cbuf = kmem_cache_zalloc(cvp_driver->internal_buf_cache, GFP_KERNEL); - if (!cbuf) - return -ENOMEM; + smem->dma_buf = dma_buf; + rc = msm_cvp_map_smem(inst, smem); + if (rc) + goto exit; - cbuf->buf.fd = in_buf->fd; - cbuf->buf.size = in_buf->size; - cbuf->buf.offset = in_buf->offset; - cbuf->buf.flags = in_buf->flags; - cbuf->buf.type = CVP_KMD_BUFTYPE_INPUT | CVP_KMD_BUFTYPE_OUTPUT; - - cbuf->smem.buffer_type = in_buf->flags; - cbuf->smem.fd = cbuf->buf.fd; - cbuf->smem.size = cbuf->buf.size; - cbuf->smem.flags = 0; - cbuf->smem.offset = in_buf->offset; - cbuf->smem.dma_buf = in_buf->dbuf; - - rc = msm_cvp_smem_map_dma_buf(inst, &cbuf->smem); - if (rc) { - print_internal_buffer(CVP_ERR, "map failed", inst, cbuf); - goto exit; + rc = msm_cvp_session_add_smem(inst, smem); + if (rc) + goto exit2; } - /* Assign mapped dma_buf back because it could be zero previously */ - in_buf->dbuf = cbuf->smem.dma_buf; - - mutex_lock(&inst->cvpcpubufs.lock); - list_add_tail(&cbuf->list, &inst->cvpcpubufs.list); - mutex_unlock(&inst->cvpcpubufs.lock); - - __msm_cvp_cache_operations(cbuf); - - *iova = cbuf->smem.device_addr + cbuf->buf.offset; - - frame_buf = kmem_cache_zalloc(cvp_driver->frame_buf_cache, GFP_KERNEL); - if (!frame_buf) { - rc = -ENOMEM; + if (buf->size > smem->size || buf->size > smem->size - buf->offset) { + dprintk(CVP_ERR, "%s: invalid offset %d or size %d\n", + __func__, buf->offset, buf->size); goto exit2; } - memcpy(&frame_buf->buf, in_buf, sizeof(frame_buf->buf)); - - mutex_lock(&frame->bufs.lock); - list_add_tail(&frame_buf->list, &frame->bufs.list); - mutex_unlock(&frame->bufs.lock); - - print_internal_buffer(CVP_DBG, "map", inst, cbuf); - return rc; + return smem; exit2: - if (cbuf->smem.device_addr) - msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem); - mutex_lock(&inst->cvpcpubufs.lock); - list_del(&cbuf->list); - mutex_unlock(&inst->cvpcpubufs.lock); + msm_cvp_unmap_smem(smem); exit: - kmem_cache_free(cvp_driver->internal_buf_cache, cbuf); - cbuf = NULL; - - return rc; + msm_cvp_smem_put_dma_buf(dma_buf); + kmem_cache_free(cvp_driver->smem_cache, smem); + smem = NULL; + return smem; } -static void __unmap_buf(struct msm_cvp_inst *inst, - struct msm_cvp_frame_buf *frame_buf) +static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, + struct cvp_buf_type *buf) { - struct msm_cvp_internal_buffer *cbuf, *dummy; - struct cvp_buf_type *buf; + u32 iova = 0; + struct msm_cvp_smem *smem = NULL; + struct cvp_internal_buf *pbuf; - if (!inst || !frame_buf) { + if (!inst) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); - return; + return -EINVAL; } - buf = &frame_buf->buf; - mutex_lock(&inst->cvpcpubufs.lock); - list_for_each_entry_safe(cbuf, dummy, &inst->cvpcpubufs.list, list) { - if (cbuf->smem.dma_buf == buf->dbuf && - cbuf->buf.size == buf->size && - cbuf->buf.offset == buf->offset) { - list_del(&cbuf->list); - print_internal_buffer(CVP_DBG, "unmap", inst, cbuf); - msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem); - kmem_cache_free(cvp_driver->internal_buf_cache, cbuf); - break; - } - } - mutex_unlock(&inst->cvpcpubufs.lock); + pbuf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); + if (!pbuf) + return 0; + + smem = msm_cvp_session_get_smem(inst, buf); + if (!smem) + goto exit; + + pbuf->smem = smem; + pbuf->fd = buf->fd; + pbuf->size = buf->size; + pbuf->offset = buf->offset; + pbuf->ownership = CLIENT; + + mutex_lock(&inst->persistbufs.lock); + list_add_tail(&pbuf->list, &inst->persistbufs.list); + mutex_unlock(&inst->persistbufs.lock); + + print_internal_buffer(CVP_DBG, "map persist", inst, pbuf); + + iova = smem->device_addr + buf->offset; + + return iova; + +exit: + kmem_cache_free(cvp_driver->buf_cache, pbuf); + return 0; } -void msm_cvp_unmap_buf_cpu(struct msm_cvp_inst *inst, u64 ktid) +static u32 msm_cvp_map_buf_cpu(struct msm_cvp_inst *inst, + struct cvp_buf_type *buf, + struct msm_cvp_frame *frame) +{ + u32 iova = 0; + struct msm_cvp_smem *smem = NULL; + u32 nr; + u32 type; + + if (!inst || !frame) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return 0; + } + + nr = frame->nr; + if (nr == MAX_FRAME_BUFFER_NUMS) { + dprintk(CVP_ERR, "%s: max frame buffer reached\n", __func__); + return 0; + } + + smem = msm_cvp_session_get_smem(inst, buf); + if (!smem) + return 0; + + frame->bufs[nr].smem = smem; + frame->bufs[nr].size = buf->size; + frame->bufs[nr].offset = buf->offset; + + print_internal_buffer(CVP_DBG, "map cpu", inst, &frame->bufs[nr]); + + frame->nr++; + + type = CVP_KMD_BUFTYPE_INPUT | CVP_KMD_BUFTYPE_OUTPUT; + msm_cvp_cache_operations(smem, type, buf->size, buf->offset); + + iova = smem->device_addr + buf->offset; + + return iova; +} + +static void msm_cvp_unmap_buf_cpu(struct msm_cvp_frame *frame) +{ + u32 i; + u32 type; + struct msm_cvp_smem *smem = NULL; + struct cvp_internal_buf *buf; + + type = CVP_KMD_BUFTYPE_OUTPUT; + + for (i = 0; i < frame->nr; ++i) { + buf = &frame->bufs[i]; + smem = buf->smem; + msm_cvp_cache_operations(smem, type, buf->size, buf->offset); + atomic_dec(&smem->refcount); + } + + kmem_cache_free(cvp_driver->frame_cache, frame); +} + +static void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid) { struct msm_cvp_frame *frame, *dummy1; - struct msm_cvp_frame_buf *frame_buf, *dummy2; bool found; if (!inst) { @@ -465,26 +497,15 @@ void msm_cvp_unmap_buf_cpu(struct msm_cvp_inst *inst, u64 ktid) if (frame->ktid == ktid) { found = true; list_del(&frame->list); - mutex_lock(&frame->bufs.lock); - list_for_each_entry_safe(frame_buf, dummy2, - &frame->bufs.list, list) { - list_del(&frame_buf->list); - __unmap_buf(inst, frame_buf); - kmem_cache_free(cvp_driver->frame_buf_cache, - frame_buf); - } - mutex_unlock(&frame->bufs.lock); - DEINIT_MSM_CVP_LIST(&frame->bufs); - kmem_cache_free(cvp_driver->frame_cache, frame); break; } } mutex_unlock(&inst->frames.lock); - if (!found) { - dprintk(CVP_WARN, "%s frame %#llx not found!\n", - __func__, ktid); - } + if (found) + msm_cvp_unmap_buf_cpu(frame); + else + dprintk(CVP_WARN, "%s frame %llu not found!\n", __func__, ktid); } static bool cvp_msg_pending(struct cvp_session_queue *sq, @@ -557,7 +578,7 @@ static int cvp_wait_process_message(struct msm_cvp_inst *inst, goto exit; } - msm_cvp_unmap_buf_cpu(inst, msg->pkt.client_data.kdata); + msm_cvp_unmap_frame(inst, msg->pkt.client_data.kdata); if (out) memcpy(out, &msg->pkt, sizeof(struct cvp_hfi_msg_session_hdr)); @@ -601,44 +622,36 @@ static int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, { struct cvp_buf_type *buf; struct cvp_hfi_cmd_session_hdr *cmd_hdr; - struct cvp_internal_buf *cbuf, *dummy; + struct cvp_internal_buf *pbuf, *dummy; u64 ktid; int i, rc = 0; + struct msm_cvp_smem *smem = NULL; if (!offset || !buf_num) return 0; cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; - ktid = cmd_hdr->client_data.kdata; + ktid = cmd_hdr->client_data.kdata & (FENCE_BIT - 1); for (i = 0; i < buf_num; i++) { buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; offset += sizeof(*buf) >> 2; mutex_lock(&inst->persistbufs.lock); - list_for_each_entry_safe(cbuf, dummy, &inst->persistbufs.list, + list_for_each_entry_safe(pbuf, dummy, &inst->persistbufs.list, list) { - if (cbuf->ktid == ktid) { - list_del(&cbuf->list); - dprintk(CVP_DBG, - "unmap persist: %x %d %d %#x", - hash32_ptr(inst->session), - cbuf->smem.fd, - cbuf->smem.size, - cbuf->smem.device_addr); - msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem); - kfree(cbuf); - rc = 1; + if (pbuf->ktid == ktid) { + list_del(&pbuf->list); + smem = pbuf->smem; + atomic_dec(&smem->refcount); + + dprintk(CVP_DBG, "unmap persist: %x %d %d %#x", + hash32_ptr(inst->session), pbuf->fd, + pbuf->size, smem->device_addr); + kmem_cache_free(cvp_driver->buf_cache, pbuf); break; } } mutex_unlock(&inst->persistbufs.lock); - if (!rc) { - dprintk(CVP_ERR, "%s, failed unmapi %llx\n", - __func__, ktid); - rc = -EFAULT; - break; - } - rc = 0; } return rc; } @@ -648,7 +661,7 @@ static int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, unsigned int offset, unsigned int buf_num) { struct cvp_hfi_cmd_session_hdr *cmd_hdr; - struct cvp_internal_buf *cbuf, *dummy; + struct cvp_internal_buf *pbuf, *dummy; u64 ktid; struct cvp_buf_type *buf; int i, rc = 0; @@ -665,16 +678,14 @@ static int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; offset += sizeof(*buf) >> 2; - /* Validate buffer descriptor */ - if (buf->fd <= 0 || !buf->size) + if (buf->fd < 0 || !buf->size) continue; mutex_lock(&inst->persistbufs.lock); - list_for_each_entry_safe(cbuf, dummy, &inst->persistbufs.list, + list_for_each_entry_safe(pbuf, dummy, &inst->persistbufs.list, list) { - if (cbuf->smem.fd == buf->fd && - cbuf->smem.size == buf->size && - cbuf->buffer_ownership == CLIENT) { + if (pbuf->fd == buf->fd && pbuf->size == buf->size && + pbuf->ownership == CLIENT) { rc = 1; break; } @@ -686,8 +697,8 @@ static int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, rc = -EFAULT; break; } - buf->fd = cbuf->smem.device_addr; - cbuf->ktid = ktid; + buf->fd = pbuf->smem->device_addr; + pbuf->ktid = ktid; rc = 0; } return rc; @@ -698,8 +709,8 @@ static int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, unsigned int offset, unsigned int buf_num) { struct cvp_buf_type *buf; - int i, rc = 0; - unsigned int iova; + int i; + u32 iova; if (!offset || !buf_num) return 0; @@ -708,44 +719,29 @@ static int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; offset += sizeof(*buf) >> 2; - /* - * Make sure fd or dma_buf field doesn't have any - * garbage value. - */ - if (inst->session_type == MSM_CVP_USER) { - buf->dbuf = NULL; - } else if (inst->session_type == MSM_CVP_KERNEL) { - buf->fd = 0; - } else if (inst->session_type >= MSM_CVP_UNKNOWN) { - dprintk(CVP_ERR, - "%s: unknown session type %d\n", - __func__, inst->session_type); - return -EINVAL; - } - - if (buf->fd <= 0 && !buf->dbuf) + if (buf->fd < 0 || !buf->size) continue; - rc = msm_cvp_map_buf_user_persist(inst, buf, &iova); - if (rc) { + iova = msm_cvp_map_user_persist_buf(inst, buf); + if (!iova) { dprintk(CVP_ERR, "%s: buf %d register failed.\n", __func__, i); - return rc; + return -EINVAL; } buf->fd = iova; } - return rc; + return 0; } -static int msm_cvp_map_buf(struct msm_cvp_inst *inst, +static int msm_cvp_map_frame(struct msm_cvp_inst *inst, struct cvp_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num) { struct cvp_buf_type *buf; - int i, rc = 0; - unsigned int iova; + int i; + u32 iova; u64 ktid; struct msm_cvp_frame *frame; struct cvp_hfi_cmd_session_hdr *cmd_hdr; @@ -762,52 +758,24 @@ static int msm_cvp_map_buf(struct msm_cvp_inst *inst, if (!frame) return -ENOMEM; - INIT_MSM_CVP_LIST(&frame->bufs); frame->ktid = ktid; - + frame->nr = 0; for (i = 0; i < buf_num; i++) { buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; offset += sizeof(*buf) >> 2; - /* - * Make sure fd or dma_buf field doesn't have any - * garbage value. - */ - if (inst->session_type == MSM_CVP_USER) { - buf->dbuf = NULL; - } else if (inst->session_type == MSM_CVP_KERNEL) { - buf->fd = 0; - } else if (inst->session_type >= MSM_CVP_UNKNOWN) { - dprintk(CVP_ERR, - "%s: unknown session type %d\n", - __func__, inst->session_type); - return -EINVAL; - } - - if (buf->fd <= 0 && !buf->dbuf) + if (buf->fd < 0 || !buf->size) continue; - rc = msm_cvp_map_buf_cpu(inst, buf, &iova, frame); - if (rc) { - struct msm_cvp_frame_buf *frame_buf, *dummy; - + iova = msm_cvp_map_buf_cpu(inst, buf, frame); + if (!iova) { dprintk(CVP_ERR, "%s: buf %d register failed.\n", __func__, i); - list_for_each_entry_safe(frame_buf, - dummy, &frame->bufs.list, list) { - list_del(&frame_buf->list); - __unmap_buf(inst, frame_buf); - kmem_cache_free( - cvp_driver->frame_buf_cache, - frame_buf); - } - DEINIT_MSM_CVP_LIST(&frame->bufs); - kmem_cache_free(cvp_driver->frame_cache, - frame); - return rc; + msm_cvp_unmap_buf_cpu(frame); + return -EINVAL; } buf->fd = iova; } @@ -817,7 +785,7 @@ static int msm_cvp_map_buf(struct msm_cvp_inst *inst, mutex_unlock(&inst->frames.lock); dprintk(CVP_DBG, "%s: map frame %llu\n", __func__, ktid); - return rc; + return 0; } static int msm_cvp_session_process_hfi( @@ -881,7 +849,7 @@ static int msm_cvp_session_process_hfi( else if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS) rc = msm_cvp_mark_user_persist(inst, in_pkt, offset, buf_num); else - rc = msm_cvp_map_buf(inst, in_pkt, offset, buf_num); + rc = msm_cvp_map_frame(inst, in_pkt, offset, buf_num); if (rc) goto exit; @@ -1338,7 +1306,7 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, buf_num = cvp_hfi_defs[idx].buf_num; } - rc = msm_cvp_map_buf(inst, (struct cvp_kmd_hfi_packet *)pkt, offset, + rc = msm_cvp_map_frame(inst, (struct cvp_kmd_hfi_packet *)pkt, offset, buf_num); if (rc) goto exit; @@ -2262,9 +2230,9 @@ int msm_cvp_session_deinit(struct msm_cvp_inst *inst) { int rc = 0; struct cvp_hal_session *session; - struct msm_cvp_internal_buffer *cbuf, *dummy; + struct cvp_internal_buf *cbuf, *dummy; struct msm_cvp_frame *frame, *dummy1; - struct msm_cvp_frame_buf *frame_buf, *dummy2; + struct msm_cvp_smem *smem, *dummy3; if (!inst || !inst->core) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); @@ -2281,62 +2249,48 @@ int msm_cvp_session_deinit(struct msm_cvp_inst *inst) if (rc) dprintk(CVP_ERR, "%s: close failed\n", __func__); - mutex_lock(&inst->cvpcpubufs.lock); - list_for_each_entry_safe(cbuf, dummy, &inst->cvpcpubufs.list, - list) { - print_internal_buffer(CVP_DBG, "remove from cvpcpubufs", inst, - cbuf); - msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem); - list_del(&cbuf->list); - kmem_cache_free(cvp_driver->internal_buf_cache, cbuf); + mutex_lock(&inst->frames.lock); + list_for_each_entry_safe(frame, dummy1, &inst->frames.list, list) { + list_del(&frame->list); + msm_cvp_unmap_buf_cpu(frame); } - mutex_unlock(&inst->cvpcpubufs.lock); + mutex_unlock(&inst->frames.lock); + + mutex_lock(&inst->cpusmems.lock); + list_for_each_entry_safe(smem, dummy3, &inst->cpusmems.list, list) { + if (atomic_read(&smem->refcount) == 0) { + list_del(&smem->list); + print_smem(CVP_DBG, "free", inst, smem); + msm_cvp_unmap_smem(smem); + msm_cvp_smem_put_dma_buf(smem->dma_buf); + kmem_cache_free(cvp_driver->smem_cache, smem); + smem = NULL; + } else { + print_smem(CVP_WARN, "in use", inst, smem); + } + } + mutex_unlock(&inst->cpusmems.lock); mutex_lock(&inst->cvpdspbufs.lock); list_for_each_entry_safe(cbuf, dummy, &inst->cvpdspbufs.list, list) { - print_internal_buffer(CVP_DBG, "remove from cvpdspbufs", inst, - cbuf); + print_internal_buffer(CVP_DBG, "remove dspbufs", inst, cbuf); rc = cvp_dsp_deregister_buffer(hash32_ptr(session), - cbuf->buf.fd, cbuf->smem.dma_buf->size, cbuf->buf.size, - cbuf->buf.offset, cbuf->buf.index, - (uint32_t)cbuf->smem.device_addr); + cbuf->fd, cbuf->smem->dma_buf->size, cbuf->size, + cbuf->offset, cbuf->index, + (uint32_t)cbuf->smem->device_addr); if (rc) dprintk(CVP_ERR, "%s: failed dsp deregistration fd=%d rc=%d", - __func__, cbuf->buf.fd, rc); + __func__, cbuf->fd, rc); - msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem); + msm_cvp_unmap_smem(cbuf->smem); + msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); list_del(&cbuf->list); - kmem_cache_free(cvp_driver->internal_buf_cache, cbuf); + kmem_cache_free(cvp_driver->buf_cache, cbuf); } mutex_unlock(&inst->cvpdspbufs.lock); - mutex_lock(&inst->frames.lock); - list_for_each_entry_safe(frame, dummy1, &inst->frames.list, list) { - list_del(&frame->list); - mutex_lock(&frame->bufs.lock); - list_for_each_entry_safe(frame_buf, dummy2, &frame->bufs.list, - list) { - struct cvp_buf_type *buf = &frame_buf->buf; - - dprintk(CVP_DBG, - "%s: %x : fd %d off %d size %d %s\n", - "remove from frame list", - hash32_ptr(inst->session), - buf->fd, buf->offset, buf->size, - buf->dbuf->name); - - list_del(&frame_buf->list); - kmem_cache_free(cvp_driver->frame_buf_cache, - frame_buf); - } - mutex_unlock(&frame->bufs.lock); - DEINIT_MSM_CVP_LIST(&frame->bufs); - kmem_cache_free(cvp_driver->frame_cache, frame); - } - mutex_unlock(&inst->frames.lock); - return rc; } diff --git a/drivers/media/platform/msm/cvp/msm_cvp_common.c b/drivers/media/platform/msm/cvp/msm_cvp_common.c index 2f4e6fe96824..4093960b3284 100644 --- a/drivers/media/platform/msm/cvp/msm_cvp_common.c +++ b/drivers/media/platform/msm/cvp/msm_cvp_common.c @@ -287,7 +287,6 @@ static void handle_session_release_buf_done(enum hal_command_response cmd, struct msm_cvp_inst *inst; struct cvp_internal_buf *buf; struct list_head *ptr, *next; - struct cvp_hal_buffer_info *buffer; u32 buf_found = false; u32 address; @@ -305,15 +304,14 @@ static void handle_session_release_buf_done(enum hal_command_response cmd, return; } - buffer = &response->data.buffer_info; - address = buffer->buffer_addr; + address = response->data.buffer_addr; mutex_lock(&inst->persistbufs.lock); list_for_each_safe(ptr, next, &inst->persistbufs.list) { buf = list_entry(ptr, struct cvp_internal_buf, list); - if (address == buf->smem.device_addr) { + if (address == buf->smem->device_addr + buf->offset) { dprintk(CVP_DBG, "releasing persist: %#x\n", - buf->smem.device_addr); + buf->smem->device_addr); buf_found = true; } } @@ -1519,17 +1517,16 @@ void msm_cvp_fw_unload_handler(struct work_struct *work) } void print_cvp_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, - struct msm_cvp_internal_buffer *cbuf) + struct cvp_internal_buf *cbuf) { dprintk(tag, "%s addr: %x size %u\n", str, - cbuf->smem.device_addr, cbuf->smem.size); + cbuf->smem->device_addr, cbuf->size); } void msm_cvp_comm_print_inst_info(struct msm_cvp_inst *inst) { - struct msm_cvp_internal_buffer *cbuf; struct cvp_internal_buf *buf; - bool is_secure = false; + struct msm_cvp_smem *smem; if (!inst) { dprintk(CVP_ERR, "%s - invalid param %pK\n", @@ -1538,57 +1535,35 @@ void msm_cvp_comm_print_inst_info(struct msm_cvp_inst *inst) } dprintk(CVP_ERR, "active session cmd %d\n", inst->cur_cmd_type); - is_secure = inst->flags & CVP_SECURE; dprintk(CVP_ERR, "---Buffer details for inst: %pK of type: %d---\n", inst, inst->session_type); - mutex_lock(&inst->cvpcpubufs.lock); - dprintk(CVP_ERR, "cpu buffer list:\n"); - list_for_each_entry(cbuf, &inst->cvpcpubufs.list, list) - print_cvp_buffer(CVP_ERR, "bufdump", inst, cbuf); - mutex_unlock(&inst->cvpcpubufs.lock); + mutex_lock(&inst->cpusmems.lock); + dprintk(CVP_ERR, "smem list:\n"); + list_for_each_entry(smem, &inst->cpusmems.list, list) + print_smem(CVP_ERR, "bufdump", inst, smem); + mutex_unlock(&inst->cpusmems.lock); mutex_lock(&inst->cvpdspbufs.lock); dprintk(CVP_ERR, "dsp buffer list:\n"); - list_for_each_entry(cbuf, &inst->cvpdspbufs.list, list) - print_cvp_buffer(CVP_ERR, "bufdump", inst, cbuf); + list_for_each_entry(buf, &inst->cvpdspbufs.list, list) + print_cvp_buffer(CVP_ERR, "bufdump", inst, buf); mutex_unlock(&inst->cvpdspbufs.lock); mutex_lock(&inst->persistbufs.lock); dprintk(CVP_ERR, "persist buffer list:\n"); list_for_each_entry(buf, &inst->persistbufs.list, list) - dprintk(CVP_ERR, "type: %d addr: %x size: %u\n", - buf->buffer_type, buf->smem.device_addr, - buf->smem.size); + print_cvp_buffer(CVP_ERR, "bufdump", inst, buf); mutex_unlock(&inst->persistbufs.lock); } -int msm_cvp_comm_unmap_cvp_buffer(struct msm_cvp_inst *inst, - struct msm_cvp_internal_buffer *cbuf) -{ - int rc = 0; - - if (!inst || !cbuf) { - dprintk(CVP_ERR, "%s: invalid params %pK %pK\n", - __func__, inst, cbuf); - return -EINVAL; - } - - rc = msm_cvp_smem_unmap_dma_buf(inst, &cbuf->smem); - if (rc) { - print_cvp_buffer(CVP_ERR, - "unmap failed for buf", inst, cbuf); - } - - return rc; -} - static int set_internal_buf_on_fw(struct msm_cvp_inst *inst, - struct msm_cvp_smem *handle, bool reuse) + struct msm_cvp_smem *handle) { - struct cvp_buffer_addr_info buffer_info; struct cvp_hfi_device *hdev; int rc = 0; + u32 iova; + u32 size; if (!inst || !inst->core || !inst->core->device || !handle) { dprintk(CVP_ERR, "%s - invalid params\n", __func__); @@ -1597,17 +1572,13 @@ static int set_internal_buf_on_fw(struct msm_cvp_inst *inst, hdev = inst->core->device; - buffer_info.buffer_size = handle->size; - buffer_info.buffer_type = 0; - buffer_info.num_buffers = 1; - buffer_info.align_device_addr = handle->device_addr; - dprintk(CVP_DBG, "%s %s buffer : %x\n", - reuse ? "Reusing" : "Allocated", - "INTERNAL_PERSIST_1", - buffer_info.align_device_addr); + iova = handle->device_addr; + size = handle->size; + + dprintk(CVP_DBG, "%s: allocated ARP buffer : %x\n", __func__, iova); rc = call_hfi_op(hdev, session_set_buffers, - (void *) inst->session, &buffer_info); + (void *) inst->session, iova, size); if (rc) { dprintk(CVP_ERR, "cvp_session_set_buffers failed\n"); return rc; @@ -1618,7 +1589,7 @@ static int set_internal_buf_on_fw(struct msm_cvp_inst *inst, static int allocate_and_set_internal_bufs(struct msm_cvp_inst *inst, u32 buffer_size, struct msm_cvp_list *buf_list) { - struct cvp_internal_buf *binfo; + struct cvp_internal_buf *buf; u32 smem_flags = SMEM_UNCACHED; int rc = 0; @@ -1633,37 +1604,45 @@ static int allocate_and_set_internal_bufs(struct msm_cvp_inst *inst, /* PERSIST buffer requires secure mapping */ smem_flags |= SMEM_SECURE | SMEM_NON_PIXEL; - binfo = kzalloc(sizeof(*binfo), GFP_KERNEL); - if (!binfo) { + buf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); + if (!buf) { + dprintk(CVP_ERR, "%s Out of memory\n", __func__); + rc = -ENOMEM; + goto fail_kzalloc; + } + + buf->smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); + if (!buf->smem) { dprintk(CVP_ERR, "%s Out of memory\n", __func__); rc = -ENOMEM; goto fail_kzalloc; } rc = msm_cvp_smem_alloc(buffer_size, 1, smem_flags, 0, - &(inst->core->resources), inst->session_type, - &binfo->smem); + &(inst->core->resources), buf->smem); if (rc) { dprintk(CVP_ERR, "Failed to allocate ARP memory\n"); goto err_no_mem; } - binfo->buffer_type = HFI_BUFFER_INTERNAL_PERSIST_1; - binfo->buffer_ownership = DRIVER; + buf->size = buf->smem->size; + buf->type = HFI_BUFFER_INTERNAL_PERSIST_1; + buf->ownership = DRIVER; - rc = set_internal_buf_on_fw(inst, &binfo->smem, false); + rc = set_internal_buf_on_fw(inst, buf->smem); if (rc) goto fail_set_buffers; mutex_lock(&buf_list->lock); - list_add_tail(&binfo->list, &buf_list->list); + list_add_tail(&buf->list, &buf_list->list); mutex_unlock(&buf_list->lock); return rc; fail_set_buffers: - msm_cvp_smem_free(&binfo->smem); + msm_cvp_smem_free(buf->smem); + kmem_cache_free(cvp_driver->smem_cache, buf->smem); err_no_mem: - kfree(binfo); + kmem_cache_free(cvp_driver->buf_cache, buf); fail_kzalloc: return rc; } @@ -1699,10 +1678,9 @@ error: int cvp_comm_release_persist_buffers(struct msm_cvp_inst *inst) { - struct msm_cvp_smem *handle; + struct msm_cvp_smem *smem; struct list_head *ptr, *next; struct cvp_internal_buf *buf; - struct cvp_buffer_addr_info buffer_info; int rc = 0; struct msm_cvp_core *core; struct cvp_hfi_device *hdev; @@ -1730,8 +1708,8 @@ int cvp_comm_release_persist_buffers(struct msm_cvp_inst *inst) mutex_lock(&inst->persistbufs.lock); list_for_each_safe(ptr, next, &inst->persistbufs.list) { buf = list_entry(ptr, struct cvp_internal_buf, list); - handle = &buf->smem; - if (!handle) { + smem = buf->smem; + if (!smem) { dprintk(CVP_ERR, "%s invalid smem\n", __func__); mutex_unlock(&inst->persistbufs.lock); return -EINVAL; @@ -1739,13 +1717,8 @@ int cvp_comm_release_persist_buffers(struct msm_cvp_inst *inst) /* Workaround for FW: release buffer means release all */ if (inst->state <= MSM_CVP_CLOSE_DONE && !all_released) { - buffer_info.buffer_size = handle->size; - buffer_info.buffer_type = buf->buffer_type; - buffer_info.num_buffers = 1; - buffer_info.align_device_addr = handle->device_addr; - buffer_info.response_required = true; rc = call_hfi_op(hdev, session_release_buffers, - (void *)inst->session, &buffer_info); + (void *)inst->session); if (!rc) { mutex_unlock(&inst->persistbufs.lock); rc = wait_for_sess_signal_receipt(inst, @@ -1758,28 +1731,37 @@ int cvp_comm_release_persist_buffers(struct msm_cvp_inst *inst) } else { dprintk(CVP_WARN, "Rel prst buf fail:%x, %d\n", - buffer_info.align_device_addr, - buffer_info.buffer_size); + smem->device_addr, + smem->size); } all_released = 1; } list_del(&buf->list); - if (buf->buffer_ownership == DRIVER) { + if (buf->ownership == DRIVER) { dprintk(CVP_DBG, "%s: %x : fd %d %s size %d", - "free arp", hash32_ptr(inst->session), buf->smem.fd, - buf->smem.dma_buf->name, buf->smem.size); - msm_cvp_smem_free(handle); - } else if (buf->buffer_ownership == CLIENT) { - dprintk(CVP_ERR, + "free arp", hash32_ptr(inst->session), buf->fd, + smem->dma_buf->name, buf->size); + msm_cvp_smem_free(smem); + kmem_cache_free(cvp_driver->smem_cache, smem); + } else if (buf->ownership == CLIENT) { + dprintk(CVP_DBG, "%s: %x : fd %d %s size %d", "unmap persist", hash32_ptr(inst->session), - buf->smem.fd, buf->smem.dma_buf->name, buf->smem.size); - msm_cvp_smem_unmap_dma_buf(inst, &buf->smem); - } + buf->fd, smem->dma_buf->name, buf->size); - kfree(buf); + mutex_lock(&inst->cpusmems.lock); + if (atomic_read(&smem->refcount) == 0) { + list_del(&smem->list); + msm_cvp_unmap_smem(smem); + dma_buf_put(smem->dma_buf); + kfree(smem); + buf->smem = NULL; + } + mutex_unlock(&inst->cpusmems.lock); + } + kmem_cache_free(cvp_driver->buf_cache, buf); } mutex_unlock(&inst->persistbufs.lock); return rc; diff --git a/drivers/media/platform/msm/cvp/msm_cvp_common.h b/drivers/media/platform/msm/cvp/msm_cvp_common.h index 4ac19fdd4b52..1af001f4d076 100644 --- a/drivers/media/platform/msm/cvp/msm_cvp_common.h +++ b/drivers/media/platform/msm/cvp/msm_cvp_common.h @@ -8,13 +8,6 @@ #define _MSM_CVP_COMMON_H_ #include "msm_cvp_internal.h" -enum load_calc_quirks { - LOAD_CALC_NO_QUIRKS = 0, - LOAD_CALC_IGNORE_TURBO_LOAD = 1 << 0, - LOAD_CALC_IGNORE_THUMBNAIL_LOAD = 1 << 1, - LOAD_CALC_IGNORE_NON_REALTIME_LOAD = 1 << 2, -}; - void cvp_put_inst(struct msm_cvp_inst *inst); struct msm_cvp_inst *cvp_get_inst(struct msm_cvp_core *core, void *session_id); @@ -34,16 +27,15 @@ int msm_cvp_comm_smem_cache_operations(struct msm_cvp_inst *inst, struct msm_cvp_smem *mem, enum smem_cache_ops cache_ops); int msm_cvp_comm_check_core_init(struct msm_cvp_core *core); void msm_cvp_comm_print_inst_info(struct msm_cvp_inst *inst); -int msm_cvp_comm_unmap_cvp_buffer(struct msm_cvp_inst *inst, - struct msm_cvp_internal_buffer *cbuf); void print_cvp_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, - struct msm_cvp_internal_buffer *cbuf); + struct cvp_internal_buf *cbuf); int wait_for_sess_signal_receipt(struct msm_cvp_inst *inst, enum hal_command_response cmd); int cvp_comm_set_arp_buffers(struct msm_cvp_inst *inst); int cvp_comm_release_persist_buffers(struct msm_cvp_inst *inst); void print_client_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, struct cvp_kmd_buffer *cbuf); -void msm_cvp_unmap_buf_cpu(struct msm_cvp_inst *inst, u64 ktid); +void print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, + struct msm_cvp_smem *smem); #endif diff --git a/drivers/media/platform/msm/cvp/msm_cvp_core.c b/drivers/media/platform/msm/cvp/msm_cvp_core.c index deda0eec3387..cb5bbe34a536 100644 --- a/drivers/media/platform/msm/cvp/msm_cvp_core.c +++ b/drivers/media/platform/msm/cvp/msm_cvp_core.c @@ -313,7 +313,7 @@ void *msm_cvp_open(int core_id, int session_type) spin_lock_init(&inst->event_handler.lock); INIT_MSM_CVP_LIST(&inst->persistbufs); - INIT_MSM_CVP_LIST(&inst->cvpcpubufs); + INIT_MSM_CVP_LIST(&inst->cpusmems); INIT_MSM_CVP_LIST(&inst->cvpdspbufs); INIT_MSM_CVP_LIST(&inst->frames); @@ -330,6 +330,7 @@ void *msm_cvp_open(int core_id, int session_type) inst->clk_data.sys_cache_bw = 0; inst->clk_data.bitrate = 0; inst->clk_data.core_id = 0; + inst->cpusmems.maxnr = MAX_DMABUF_NUMS; for (i = SESSION_MSG_INDEX(SESSION_MSG_START); i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) { @@ -368,7 +369,7 @@ fail_init: mutex_destroy(&inst->lock); DEINIT_MSM_CVP_LIST(&inst->persistbufs); - DEINIT_MSM_CVP_LIST(&inst->cvpcpubufs); + DEINIT_MSM_CVP_LIST(&inst->cpusmems); DEINIT_MSM_CVP_LIST(&inst->cvpdspbufs); DEINIT_MSM_CVP_LIST(&inst->frames); @@ -408,7 +409,7 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) mutex_unlock(&core->lock); DEINIT_MSM_CVP_LIST(&inst->persistbufs); - DEINIT_MSM_CVP_LIST(&inst->cvpcpubufs); + DEINIT_MSM_CVP_LIST(&inst->cpusmems); DEINIT_MSM_CVP_LIST(&inst->cvpdspbufs); DEINIT_MSM_CVP_LIST(&inst->frames); diff --git a/drivers/media/platform/msm/cvp/msm_cvp_core.h b/drivers/media/platform/msm/cvp/msm_cvp_core.h index 1ea31691a39c..ff74f64fb1e5 100644 --- a/drivers/media/platform/msm/cvp/msm_cvp_core.h +++ b/drivers/media/platform/msm/cvp/msm_cvp_core.h @@ -11,15 +11,10 @@ #include #include #include +#include #include #include -#define HAL_BUFFER_MAX 0xe - -enum smem_type { - SMEM_DMA = 1, -}; - enum smem_prop { SMEM_UNCACHED = 0x1, SMEM_CACHED = 0x2, @@ -28,27 +23,6 @@ enum smem_prop { SMEM_NON_PIXEL = 0x10 }; -/* NOTE: if you change this enum you MUST update the - * "buffer-type-tz-usage-table" for any affected target - * in arch/arm/boot/dts/.dtsi - */ -enum hal_buffer { - HAL_BUFFER_NONE = 0x0, - HAL_BUFFER_INPUT = 0x1, - HAL_BUFFER_OUTPUT = 0x2, - HAL_BUFFER_OUTPUT2 = 0x4, - HAL_BUFFER_EXTRADATA_INPUT = 0x8, - HAL_BUFFER_EXTRADATA_OUTPUT = 0x10, - HAL_BUFFER_EXTRADATA_OUTPUT2 = 0x20, - HAL_BUFFER_INTERNAL_SCRATCH = 0x40, - HAL_BUFFER_INTERNAL_SCRATCH_1 = 0x80, - HAL_BUFFER_INTERNAL_SCRATCH_2 = 0x100, - HAL_BUFFER_INTERNAL_PERSIST = 0x200, - HAL_BUFFER_INTERNAL_PERSIST_1 = 0x400, - HAL_BUFFER_INTERNAL_CMD_QUEUE = 0x800, - HAL_BUFFER_INTERNAL_RECON = 0x1000, -}; - struct cvp_dma_mapping_info { struct device *dev; struct iommu_domain *domain; @@ -59,16 +33,15 @@ struct cvp_dma_mapping_info { }; struct msm_cvp_smem { - u32 refcount; - s32 fd; + struct list_head list; + atomic_t refcount; struct dma_buf *dma_buf; void *kvaddr; u32 device_addr; dma_addr_t dma_handle; - u32 offset; u32 size; u32 flags; - u32 buffer_type; + u32 ion_flags; struct cvp_dma_mapping_info mapping_info; }; diff --git a/drivers/media/platform/msm/cvp/msm_cvp_internal.h b/drivers/media/platform/msm/cvp/msm_cvp_internal.h index 8c9ae465ce8f..a9b666394d7d 100644 --- a/drivers/media/platform/msm/cvp/msm_cvp_internal.h +++ b/drivers/media/platform/msm/cvp/msm_cvp_internal.h @@ -37,6 +37,9 @@ #define FENCE_DME_DS_IDX 1 #define FENCE_DME_OUTPUT_IDX 7 +#define MAX_FRAME_BUFFER_NUMS 10 +#define MAX_DMABUF_NUMS 30 + #define SYS_MSG_START HAL_SYS_INIT_DONE #define SYS_MSG_END HAL_SYS_ERROR #define SESSION_MSG_START HAL_SESSION_EVENT_CHANGE @@ -83,12 +86,15 @@ enum dsp_state { struct msm_cvp_list { struct list_head list; struct mutex lock; + u32 nr; + u32 maxnr; }; static inline void INIT_MSM_CVP_LIST(struct msm_cvp_list *mlist) { mutex_init(&mlist->lock); INIT_LIST_HEAD(&mlist->list); + mlist->nr = 0; } static inline void DEINIT_MSM_CVP_LIST(struct msm_cvp_list *mlist) @@ -103,19 +109,16 @@ enum buffer_owner { MAX_OWNER }; -struct cvp_freq_data { - struct list_head list; - u32 device_addr; - unsigned long freq; - bool turbo; -}; - struct cvp_internal_buf { struct list_head list; - u32 buffer_type; - struct msm_cvp_smem smem; - enum buffer_owner buffer_ownership; + s32 fd; + u32 size; + u32 offset; + u32 type; + u32 index; u64 ktid; + enum buffer_owner ownership; + struct msm_cvp_smem *smem; }; struct msm_cvp_common_data { @@ -167,10 +170,9 @@ struct msm_cvp_drv { int thermal_level; u32 sku_version; struct kmem_cache *msg_cache; - struct kmem_cache *fence_data_cache; struct kmem_cache *frame_cache; - struct kmem_cache *frame_buf_cache; - struct kmem_cache *internal_buf_cache; + struct kmem_cache *buf_cache; + struct kmem_cache *smem_cache; char fw_version[CVP_VERSION_LENGTH]; }; @@ -191,7 +193,6 @@ struct cvp_clock_data { int load_high; int min_threshold; int max_threshold; - enum hal_buffer buffer_type; unsigned long bitrate; unsigned long min_freq; unsigned long curr_freq; @@ -334,7 +335,7 @@ struct msm_cvp_inst { enum instance_state state; struct msm_cvp_list freqs; struct msm_cvp_list persistbufs; - struct msm_cvp_list cvpcpubufs; + struct msm_cvp_list cpusmems; struct msm_cvp_list cvpdspbufs; struct msm_cvp_list frames; struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1]; @@ -351,13 +352,6 @@ struct msm_cvp_inst { struct cvp_fence_queue fence_cmd_queue; }; -struct msm_cvp_fence_thread_data { - struct msm_cvp_inst *inst; - unsigned int device_id; - struct cvp_kmd_hfi_fence_packet in_fence_pkt; - unsigned int arg_type; -}; - struct cvp_fence_type { s32 h_synx; u32 secure_key; @@ -370,42 +364,29 @@ struct cvp_fence_command { struct cvp_hfi_cmd_session_hdr *pkt; }; +struct msm_cvp_frame { + struct list_head list; + struct cvp_internal_buf bufs[MAX_FRAME_BUFFER_NUMS]; + u32 nr; + u64 ktid; +}; + extern struct msm_cvp_drv *cvp_driver; void cvp_handle_cmd_response(enum hal_command_response cmd, void *data); int msm_cvp_trigger_ssr(struct msm_cvp_core *core, enum hal_ssr_trigger_type type); int msm_cvp_noc_error_info(struct msm_cvp_core *core); - -struct msm_cvp_internal_buffer { - struct list_head list; - struct msm_cvp_smem smem; - struct cvp_kmd_buffer buf; -}; - -struct msm_cvp_frame_buf { - struct list_head list; - struct cvp_buf_type buf; -}; - -struct msm_cvp_frame { - struct list_head list; - struct msm_cvp_list bufs; - u64 ktid; -}; - void msm_cvp_comm_handle_thermal_event(void); int msm_cvp_smem_alloc(size_t size, u32 align, u32 flags, int map_kernel, - void *res, u32 session_type, struct msm_cvp_smem *smem); + void *res, struct msm_cvp_smem *smem); int msm_cvp_smem_free(struct msm_cvp_smem *smem); -struct context_bank_info *msm_cvp_smem_get_context_bank(u32 session_type, - bool is_secure, struct msm_cvp_platform_resources *res, - unsigned long ion_flags); -int msm_cvp_smem_map_dma_buf(struct msm_cvp_inst *inst, +struct context_bank_info *msm_cvp_smem_get_context_bank(bool is_secure, + struct msm_cvp_platform_resources *res, unsigned long ion_flags); +int msm_cvp_map_smem(struct msm_cvp_inst *inst, struct msm_cvp_smem *smem); -int msm_cvp_smem_unmap_dma_buf(struct msm_cvp_inst *inst, - struct msm_cvp_smem *smem); +int msm_cvp_unmap_smem(struct msm_cvp_smem *smem); struct dma_buf *msm_cvp_smem_get_dma_buf(int fd); void msm_cvp_smem_put_dma_buf(void *dma_buf); int msm_cvp_smem_cache_operations(struct dma_buf *dbuf, diff --git a/drivers/media/platform/msm/cvp/msm_smem.c b/drivers/media/platform/msm/cvp/msm_smem.c index ef1d5a453170..52fb9d9030ba 100644 --- a/drivers/media/platform/msm/cvp/msm_smem.c +++ b/drivers/media/platform/msm/cvp/msm_smem.c @@ -17,8 +17,8 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, - dma_addr_t *iova, u32 *buffer_size, u32 flags, unsigned long ion_flags, - u32 session_type, struct msm_cvp_platform_resources *res, + dma_addr_t *iova, u32 flags, unsigned long ion_flags, + struct msm_cvp_platform_resources *res, struct cvp_dma_mapping_info *mapping_info) { int rc = 0; @@ -26,15 +26,14 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, struct sg_table *table = NULL; struct context_bank_info *cb = NULL; - if (!dbuf || !iova || !buffer_size || !mapping_info) { - dprintk(CVP_ERR, "Invalid params: %pK, %pK, %pK, %pK\n", - dbuf, iova, buffer_size, mapping_info); + if (!dbuf || !iova || !mapping_info) { + dprintk(CVP_ERR, "Invalid params: %pK, %pK, %pK\n", + dbuf, iova, mapping_info); return -EINVAL; } if (is_iommu_present(res)) { - cb = msm_cvp_smem_get_context_bank( - session_type, (flags & SMEM_SECURE), + cb = msm_cvp_smem_get_context_bank((flags & SMEM_SECURE), res, ion_flags); if (!cb) { dprintk(CVP_ERR, @@ -44,17 +43,6 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, goto mem_map_failed; } - /* Check if the dmabuf size matches expected size */ - if (dbuf->size < *buffer_size) { - rc = -EINVAL; - dprintk(CVP_ERR, - "Size mismatch: Dmabuf size: %zu Expected Size: %lu", - dbuf->size, *buffer_size); - msm_cvp_res_handle_fatal_hw_error(res, - true); - goto mem_buf_size_mismatch; - } - /* Prepare a dma buf for dma on the given device */ attach = dma_buf_attach(dbuf, cb->dev); if (IS_ERR_OR_NULL(attach)) { @@ -88,7 +76,6 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, if (table->sgl) { *iova = table->sgl->dma_address; - *buffer_size = table->sgl->dma_length; } else { dprintk(CVP_ERR, "sgl is NULL\n"); rc = -ENOMEM; @@ -101,7 +88,6 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, mapping_info->attach = attach; mapping_info->buf = dbuf; mapping_info->cb_info = (void *)cb; - } else { dprintk(CVP_DBG, "iommu not present, use phys mem addr\n"); } @@ -111,7 +97,6 @@ mem_map_sg_failed: dma_buf_unmap_attachment(attach, table, DMA_BIDIRECTIONAL); mem_map_table_failed: dma_buf_detach(dbuf, attach); -mem_buf_size_mismatch: mem_buf_attach_failed: mem_map_failed: return rc; @@ -173,16 +158,15 @@ void msm_cvp_smem_put_dma_buf(void *dma_buf) dma_buf_put((struct dma_buf *)dma_buf); } -int msm_cvp_smem_map_dma_buf(struct msm_cvp_inst *inst, - struct msm_cvp_smem *smem) +int msm_cvp_map_smem(struct msm_cvp_inst *inst, + struct msm_cvp_smem *smem) { int rc = 0; dma_addr_t iova = 0; u32 temp = 0; - u32 buffer_size = 0; u32 align = SZ_4K; - struct dma_buf *dbuf; + struct dma_buf *dma_buf; unsigned long ion_flags = 0; if (!inst || !smem) { @@ -191,26 +175,8 @@ int msm_cvp_smem_map_dma_buf(struct msm_cvp_inst *inst, return -EINVAL; } - if (smem->refcount) { - smem->refcount++; - return rc; - } - - if (smem->fd > 0) { - dbuf = msm_cvp_smem_get_dma_buf(smem->fd); - if (!dbuf) { - rc = -EINVAL; - dprintk(CVP_ERR, "%s: Invalid fd=%d", __func__, - smem->fd); - return rc; - } - smem->dma_buf = dbuf; - } else { - dbuf = smem->dma_buf; - get_dma_buf(dbuf); - } - - rc = dma_buf_get_flags(dbuf, &ion_flags); + dma_buf = smem->dma_buf; + rc = dma_buf_get_flags(dma_buf, &ion_flags); if (rc) { dprintk(CVP_ERR, "Failed to get dma buf flags: %d\n", rc); goto exit; @@ -221,19 +187,9 @@ int msm_cvp_smem_map_dma_buf(struct msm_cvp_inst *inst, if (ion_flags & ION_FLAG_SECURE) smem->flags |= SMEM_SECURE; - buffer_size = smem->size; - if (smem->offset > dbuf->size - 1 || - smem->offset + buffer_size > dbuf->size) { - dprintk(CVP_WARN, "%s: invalid offset %d or size %d\n", - __func__, smem->offset, buffer_size); - rc = -EINVAL; - goto exit; - } - - /* Ignore the buffer_type from user space. Only use ion flags */ - rc = msm_dma_get_device_address(dbuf, align, &iova, &buffer_size, - smem->flags, ion_flags, inst->session_type, - &(inst->core->resources), &smem->mapping_info); + rc = msm_dma_get_device_address(dma_buf, align, &iova, smem->flags, + ion_flags, &(inst->core->resources), + &smem->mapping_info); if (rc) { dprintk(CVP_ERR, "Failed to get device address: %d\n", rc); goto exit; @@ -245,61 +201,41 @@ int msm_cvp_smem_map_dma_buf(struct msm_cvp_inst *inst, goto exit; } + smem->size = dma_buf->size; smem->device_addr = (u32)iova; - smem->refcount++; return rc; exit: - dma_buf_put(dbuf); smem->device_addr = 0x0; - smem->dma_buf = NULL; return rc; } -int msm_cvp_smem_unmap_dma_buf(struct msm_cvp_inst *inst, - struct msm_cvp_smem *smem) +int msm_cvp_unmap_smem(struct msm_cvp_smem *smem) { int rc = 0; - if (!inst || !smem) { - dprintk(CVP_ERR, "%s: Invalid params: %pK %pK\n", - __func__, inst, smem); + if (!smem) { + dprintk(CVP_ERR, "%s: Invalid params: %pK\n", __func__, smem); rc = -EINVAL; goto exit; } - if (smem->refcount) { - smem->refcount--; - } else { - dprintk(CVP_WARN, - "unmap called while refcount is zero already\n"); - return -EINVAL; - } - - if (smem->refcount) - goto exit; - rc = msm_dma_put_device_address(smem->flags, &smem->mapping_info); if (rc) { dprintk(CVP_ERR, "Failed to put device address: %d\n", rc); goto exit; } - msm_cvp_smem_put_dma_buf(smem->dma_buf); - smem->device_addr = 0x0; - smem->dma_buf = NULL; exit: return rc; } static int alloc_dma_mem(size_t size, u32 align, u32 flags, int map_kernel, - struct msm_cvp_platform_resources *res, u32 session_type, - struct msm_cvp_smem *mem) + struct msm_cvp_platform_resources *res, struct msm_cvp_smem *mem) { dma_addr_t iova = 0; - u32 buffer_size = 0; unsigned long heap_mask = 0; int rc = 0; int ion_flags = 0; @@ -348,14 +284,13 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, int map_kernel, } mem->flags = flags; - mem->buffer_type = ion_flags; - mem->offset = 0; + mem->ion_flags = ion_flags; mem->size = size; mem->dma_buf = dbuf; mem->kvaddr = NULL; - rc = msm_dma_get_device_address(dbuf, align, &iova, &buffer_size, flags, - ion_flags, session_type, res, &mem->mapping_info); + rc = msm_dma_get_device_address(dbuf, align, &iova, flags, + ion_flags, res, &mem->mapping_info); if (rc) { dprintk(CVP_ERR, "Failed to get device address: %d\n", rc); @@ -380,9 +315,9 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, int map_kernel, } dprintk(CVP_DBG, - "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, buffer_type = %#x, flags = %#lx\n", + "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, ion_flags = %#x, flags = %#lx\n", __func__, mem->dma_buf, mem->device_addr, mem->size, - mem->kvaddr, mem->buffer_type, mem->flags); + mem->kvaddr, mem->ion_flags, mem->flags); return rc; fail_map: @@ -397,9 +332,9 @@ fail_shared_mem_alloc: static int free_dma_mem(struct msm_cvp_smem *mem) { dprintk(CVP_DBG, - "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, buffer_type = %#x\n", + "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, ion_flags = %#x\n", __func__, mem->dma_buf, mem->device_addr, mem->size, - mem->kvaddr, mem->buffer_type); + mem->kvaddr, mem->ion_flags); if (mem->device_addr) { msm_dma_put_device_address(mem->flags, &mem->mapping_info); @@ -421,7 +356,7 @@ static int free_dma_mem(struct msm_cvp_smem *mem) } int msm_cvp_smem_alloc(size_t size, u32 align, u32 flags, int map_kernel, - void *res, u32 session_type, struct msm_cvp_smem *smem) + void *res, struct msm_cvp_smem *smem) { int rc = 0; @@ -433,7 +368,7 @@ int msm_cvp_smem_alloc(size_t size, u32 align, u32 flags, int map_kernel, rc = alloc_dma_mem(size, align, flags, map_kernel, (struct msm_cvp_platform_resources *)res, - session_type, smem); + smem); return rc; } @@ -500,9 +435,8 @@ int msm_cvp_smem_cache_operations(struct dma_buf *dbuf, return rc; } -struct context_bank_info *msm_cvp_smem_get_context_bank(u32 session_type, - bool is_secure, struct msm_cvp_platform_resources *res, - unsigned long ion_flags) +struct context_bank_info *msm_cvp_smem_get_context_bank(bool is_secure, + struct msm_cvp_platform_resources *res, unsigned long ion_flags) { struct context_bank_info *cb = NULL, *match = NULL; char *search_str; @@ -527,7 +461,7 @@ struct context_bank_info *msm_cvp_smem_get_context_bank(u32 session_type, if (!match) dprintk(CVP_ERR, - "%s: cb not found for buffer_type %x, is_secure %d\n", + "%s: cb not found for ion_flags %x, is_secure %d\n", __func__, ion_flags, is_secure); return match;