Merge "msm: cvp: buffer managerment optimization for Lahaina"

This commit is contained in:
qctecmdr 2020-02-18 14:35:52 -08:00 • committed by Gerrit - the friendly Code Review server
commit 7a3a08b2a4
13 changed files with 489 additions and 755 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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);

File diff suppressed because it is too large Load diff

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -11,15 +11,10 @@
#include <linux/dma-buf.h>
#include <linux/ion.h>
#include <linux/msm_ion.h>
#include <linux/refcount.h>
#include <media/msm_cvp_private.h>
#include <media/msm_cvp_vidc.h>
#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/<arch>.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;
};

View file

@ -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,

View file

@ -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;