video: driver: implement memory_ops for upstream
- Implement upstream specific memory_alloc/map and memory_unmap/free API based on standard dma_alloc_attr() and dma_free_attr() APIs which allocates and map dma buffer. - Combine alloc and map, unmap and free. Change-Id: Ie85914beb72c3976febdc9e6a11c9199f2ea4192 Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
This commit is contained in:
@@ -42,8 +42,7 @@ struct msm_vidc_mem_addr {
|
||||
u32 align_device_addr;
|
||||
u8 *align_virtual_addr;
|
||||
u32 mem_size;
|
||||
struct msm_vidc_map map;
|
||||
struct msm_vidc_alloc alloc;
|
||||
struct msm_vidc_mem mem;
|
||||
};
|
||||
|
||||
struct msm_vidc_iface_q_info {
|
||||
|
@@ -474,9 +474,7 @@ int msm_vidc_vb2_queue_deinit(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl);
|
||||
struct msm_vidc_buffers *msm_vidc_get_buffers(struct msm_vidc_inst *inst,
|
||||
enum msm_vidc_buffer_type buffer_type, const char *func);
|
||||
struct msm_vidc_mappings *msm_vidc_get_mappings(struct msm_vidc_inst *inst,
|
||||
enum msm_vidc_buffer_type buffer_type, const char *func);
|
||||
struct msm_vidc_allocations *msm_vidc_get_allocations(
|
||||
struct msm_vidc_mem_list *msm_vidc_get_mem_info(
|
||||
struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type,
|
||||
const char *func);
|
||||
struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst,
|
||||
|
@@ -39,28 +39,16 @@ struct msm_vidc_session_ops {
|
||||
int (*extra_count)(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type type);
|
||||
};
|
||||
|
||||
struct msm_vidc_allocations_info {
|
||||
struct msm_vidc_allocations bin;
|
||||
struct msm_vidc_allocations arp;
|
||||
struct msm_vidc_allocations comv;
|
||||
struct msm_vidc_allocations non_comv;
|
||||
struct msm_vidc_allocations line;
|
||||
struct msm_vidc_allocations dpb;
|
||||
struct msm_vidc_allocations persist;
|
||||
struct msm_vidc_allocations vpss;
|
||||
struct msm_vidc_allocations partial_data;
|
||||
};
|
||||
|
||||
struct msm_vidc_mappings_info {
|
||||
struct msm_vidc_mappings bin;
|
||||
struct msm_vidc_mappings arp;
|
||||
struct msm_vidc_mappings comv;
|
||||
struct msm_vidc_mappings non_comv;
|
||||
struct msm_vidc_mappings line;
|
||||
struct msm_vidc_mappings dpb;
|
||||
struct msm_vidc_mappings persist;
|
||||
struct msm_vidc_mappings vpss;
|
||||
struct msm_vidc_mappings partial_data;
|
||||
struct msm_vidc_mem_list_info {
|
||||
struct msm_vidc_mem_list bin;
|
||||
struct msm_vidc_mem_list arp;
|
||||
struct msm_vidc_mem_list comv;
|
||||
struct msm_vidc_mem_list non_comv;
|
||||
struct msm_vidc_mem_list line;
|
||||
struct msm_vidc_mem_list dpb;
|
||||
struct msm_vidc_mem_list persist;
|
||||
struct msm_vidc_mem_list vpss;
|
||||
struct msm_vidc_mem_list partial_data;
|
||||
};
|
||||
|
||||
struct msm_vidc_buffers_info {
|
||||
@@ -136,8 +124,7 @@ struct msm_vidc_inst {
|
||||
struct vidc_bus_vote_data bus_data;
|
||||
struct msm_memory_pool pool[MSM_MEM_POOL_MAX];
|
||||
struct msm_vidc_buffers_info buffers;
|
||||
struct msm_vidc_mappings_info mappings;
|
||||
struct msm_vidc_allocations_info allocations;
|
||||
struct msm_vidc_mem_list_info mem_info;
|
||||
struct msm_vidc_timestamps timestamps;
|
||||
struct msm_vidc_timestamps ts_reorder; /* list of struct msm_vidc_timestamp */
|
||||
bool subscribed_input_psc;
|
||||
|
@@ -836,7 +836,7 @@ struct msm_vidc_fence {
|
||||
int fd;
|
||||
};
|
||||
|
||||
struct msm_vidc_alloc {
|
||||
struct msm_vidc_mem {
|
||||
struct list_head list;
|
||||
enum msm_vidc_buffer_type type;
|
||||
enum msm_vidc_buffer_region region;
|
||||
@@ -854,25 +854,15 @@ struct msm_vidc_alloc {
|
||||
struct dma_buf_map dmabuf_map;
|
||||
#endif
|
||||
void *kvaddr;
|
||||
};
|
||||
|
||||
struct msm_vidc_allocations {
|
||||
struct list_head list; // list of "struct msm_vidc_alloc"
|
||||
};
|
||||
|
||||
struct msm_vidc_map {
|
||||
struct list_head list;
|
||||
enum msm_vidc_buffer_type type;
|
||||
enum msm_vidc_buffer_region region;
|
||||
struct dma_buf *dmabuf;
|
||||
dma_addr_t device_addr;
|
||||
unsigned long attrs;
|
||||
u32 refcount;
|
||||
u64 device_addr;
|
||||
struct sg_table *table;
|
||||
struct dma_buf_attachment *attach;
|
||||
};
|
||||
|
||||
struct msm_vidc_mappings {
|
||||
struct list_head list; // list of "struct msm_vidc_map"
|
||||
struct msm_vidc_mem_list {
|
||||
struct list_head list; // list of "struct msm_vidc_mem"
|
||||
};
|
||||
|
||||
struct msm_vidc_buffer {
|
||||
|
@@ -21,8 +21,7 @@ struct msm_memory_dmabuf {
|
||||
|
||||
enum msm_memory_pool_type {
|
||||
MSM_MEM_POOL_BUFFER = 0,
|
||||
MSM_MEM_POOL_MAP,
|
||||
MSM_MEM_POOL_ALLOC,
|
||||
MSM_MEM_POOL_ALLOC_MAP,
|
||||
MSM_MEM_POOL_TIMESTAMP,
|
||||
MSM_MEM_POOL_DMABUF,
|
||||
MSM_MEM_POOL_PACKET,
|
||||
@@ -72,14 +71,10 @@ struct msm_vidc_memory_ops {
|
||||
struct dma_buf_attachment *attach);
|
||||
int (*dma_buf_unmap_attachment)(struct msm_vidc_core *core,
|
||||
struct dma_buf_attachment *attach, struct sg_table *table);
|
||||
int (*memory_map)(struct msm_vidc_core *core,
|
||||
struct msm_vidc_map *map);
|
||||
int (*memory_unmap)(struct msm_vidc_core *core,
|
||||
struct msm_vidc_map *map);
|
||||
int (*memory_alloc)(struct msm_vidc_core *core,
|
||||
struct msm_vidc_alloc *alloc);
|
||||
int (*memory_free)(struct msm_vidc_core *core,
|
||||
struct msm_vidc_alloc *alloc);
|
||||
int (*memory_alloc_map)(struct msm_vidc_core *core,
|
||||
struct msm_vidc_mem *mem);
|
||||
int (*memory_unmap_free)(struct msm_vidc_core *core,
|
||||
struct msm_vidc_mem *mem);
|
||||
u32 (*buffer_region)(struct msm_vidc_inst *inst,
|
||||
enum msm_vidc_buffer_type buffer_type);
|
||||
};
|
||||
|
@@ -934,24 +934,15 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
|
||||
INIT_LIST_HEAD(&inst->buffers.persist.list);
|
||||
INIT_LIST_HEAD(&inst->buffers.vpss.list);
|
||||
INIT_LIST_HEAD(&inst->buffers.partial_data.list);
|
||||
INIT_LIST_HEAD(&inst->allocations.bin.list);
|
||||
INIT_LIST_HEAD(&inst->allocations.arp.list);
|
||||
INIT_LIST_HEAD(&inst->allocations.comv.list);
|
||||
INIT_LIST_HEAD(&inst->allocations.non_comv.list);
|
||||
INIT_LIST_HEAD(&inst->allocations.line.list);
|
||||
INIT_LIST_HEAD(&inst->allocations.dpb.list);
|
||||
INIT_LIST_HEAD(&inst->allocations.persist.list);
|
||||
INIT_LIST_HEAD(&inst->allocations.vpss.list);
|
||||
INIT_LIST_HEAD(&inst->allocations.partial_data.list);
|
||||
INIT_LIST_HEAD(&inst->mappings.bin.list);
|
||||
INIT_LIST_HEAD(&inst->mappings.arp.list);
|
||||
INIT_LIST_HEAD(&inst->mappings.comv.list);
|
||||
INIT_LIST_HEAD(&inst->mappings.non_comv.list);
|
||||
INIT_LIST_HEAD(&inst->mappings.line.list);
|
||||
INIT_LIST_HEAD(&inst->mappings.dpb.list);
|
||||
INIT_LIST_HEAD(&inst->mappings.persist.list);
|
||||
INIT_LIST_HEAD(&inst->mappings.vpss.list);
|
||||
INIT_LIST_HEAD(&inst->mappings.partial_data.list);
|
||||
INIT_LIST_HEAD(&inst->mem_info.bin.list);
|
||||
INIT_LIST_HEAD(&inst->mem_info.arp.list);
|
||||
INIT_LIST_HEAD(&inst->mem_info.comv.list);
|
||||
INIT_LIST_HEAD(&inst->mem_info.non_comv.list);
|
||||
INIT_LIST_HEAD(&inst->mem_info.line.list);
|
||||
INIT_LIST_HEAD(&inst->mem_info.dpb.list);
|
||||
INIT_LIST_HEAD(&inst->mem_info.persist.list);
|
||||
INIT_LIST_HEAD(&inst->mem_info.vpss.list);
|
||||
INIT_LIST_HEAD(&inst->mem_info.partial_data.list);
|
||||
INIT_LIST_HEAD(&inst->children_list);
|
||||
INIT_LIST_HEAD(&inst->firmware_list);
|
||||
INIT_LIST_HEAD(&inst->enc_input_crs);
|
||||
|
@@ -905,59 +905,29 @@ struct msm_vidc_buffers *msm_vidc_get_buffers(
|
||||
}
|
||||
}
|
||||
|
||||
struct msm_vidc_mappings *msm_vidc_get_mappings(
|
||||
struct msm_vidc_mem_list *msm_vidc_get_mem_info(
|
||||
struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type,
|
||||
const char *func)
|
||||
{
|
||||
switch (buffer_type) {
|
||||
case MSM_VIDC_BUF_BIN:
|
||||
return &inst->mappings.bin;
|
||||
return &inst->mem_info.bin;
|
||||
case MSM_VIDC_BUF_ARP:
|
||||
return &inst->mappings.arp;
|
||||
return &inst->mem_info.arp;
|
||||
case MSM_VIDC_BUF_COMV:
|
||||
return &inst->mappings.comv;
|
||||
return &inst->mem_info.comv;
|
||||
case MSM_VIDC_BUF_NON_COMV:
|
||||
return &inst->mappings.non_comv;
|
||||
return &inst->mem_info.non_comv;
|
||||
case MSM_VIDC_BUF_LINE:
|
||||
return &inst->mappings.line;
|
||||
return &inst->mem_info.line;
|
||||
case MSM_VIDC_BUF_DPB:
|
||||
return &inst->mappings.dpb;
|
||||
return &inst->mem_info.dpb;
|
||||
case MSM_VIDC_BUF_PERSIST:
|
||||
return &inst->mappings.persist;
|
||||
return &inst->mem_info.persist;
|
||||
case MSM_VIDC_BUF_VPSS:
|
||||
return &inst->mappings.vpss;
|
||||
return &inst->mem_info.vpss;
|
||||
case MSM_VIDC_BUF_PARTIAL_DATA:
|
||||
return &inst->mappings.partial_data;
|
||||
default:
|
||||
i_vpr_e(inst, "%s: invalid driver buffer type %d\n",
|
||||
func, buffer_type);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct msm_vidc_allocations *msm_vidc_get_allocations(
|
||||
struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type,
|
||||
const char *func)
|
||||
{
|
||||
switch (buffer_type) {
|
||||
case MSM_VIDC_BUF_BIN:
|
||||
return &inst->allocations.bin;
|
||||
case MSM_VIDC_BUF_ARP:
|
||||
return &inst->allocations.arp;
|
||||
case MSM_VIDC_BUF_COMV:
|
||||
return &inst->allocations.comv;
|
||||
case MSM_VIDC_BUF_NON_COMV:
|
||||
return &inst->allocations.non_comv;
|
||||
case MSM_VIDC_BUF_LINE:
|
||||
return &inst->allocations.line;
|
||||
case MSM_VIDC_BUF_DPB:
|
||||
return &inst->allocations.dpb;
|
||||
case MSM_VIDC_BUF_PERSIST:
|
||||
return &inst->allocations.persist;
|
||||
case MSM_VIDC_BUF_VPSS:
|
||||
return &inst->allocations.vpss;
|
||||
case MSM_VIDC_BUF_PARTIAL_DATA:
|
||||
return &inst->allocations.partial_data;
|
||||
return &inst->mem_info.partial_data;
|
||||
default:
|
||||
i_vpr_e(inst, "%s: invalid driver buffer type %d\n",
|
||||
func, buffer_type);
|
||||
@@ -3496,10 +3466,8 @@ int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_buffer *buffer)
|
||||
{
|
||||
struct msm_vidc_buffers *buffers;
|
||||
struct msm_vidc_allocations *allocations;
|
||||
struct msm_vidc_mappings *mappings;
|
||||
struct msm_vidc_alloc *alloc, *alloc_dummy;
|
||||
struct msm_vidc_map *map, *map_dummy;
|
||||
struct msm_vidc_mem_list *mem_list;
|
||||
struct msm_vidc_mem *mem, *mem_dummy;
|
||||
struct msm_vidc_buffer *buf, *dummy;
|
||||
struct msm_vidc_core *core;
|
||||
|
||||
@@ -3521,27 +3489,15 @@ int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
|
||||
buffers = msm_vidc_get_buffers(inst, buffer->type, __func__);
|
||||
if (!buffers)
|
||||
return -EINVAL;
|
||||
allocations = msm_vidc_get_allocations(inst, buffer->type, __func__);
|
||||
if (!allocations)
|
||||
return -EINVAL;
|
||||
mappings = msm_vidc_get_mappings(inst, buffer->type, __func__);
|
||||
if (!mappings)
|
||||
mem_list = msm_vidc_get_mem_info(inst, buffer->type, __func__);
|
||||
if (!mem_list)
|
||||
return -EINVAL;
|
||||
|
||||
list_for_each_entry_safe(map, map_dummy, &mappings->list, list) {
|
||||
if (map->dmabuf == buffer->dmabuf) {
|
||||
call_mem_op(core, memory_unmap, core, map);
|
||||
list_del(&map->list);
|
||||
msm_vidc_pool_free(inst, map);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(alloc, alloc_dummy, &allocations->list, list) {
|
||||
if (alloc->dmabuf == buffer->dmabuf) {
|
||||
call_mem_op(core, memory_free, core, alloc);
|
||||
list_del(&alloc->list);
|
||||
msm_vidc_pool_free(inst, alloc);
|
||||
list_for_each_entry_safe(mem, mem_dummy, &mem_list->list, list) {
|
||||
if (mem->dmabuf == buffer->dmabuf) {
|
||||
call_mem_op(core, memory_unmap_free, core, mem);
|
||||
list_del(&mem->list);
|
||||
msm_vidc_pool_free(inst, mem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3600,11 +3556,9 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_buffers *buffers;
|
||||
struct msm_vidc_allocations *allocations;
|
||||
struct msm_vidc_mappings *mappings;
|
||||
struct msm_vidc_mem_list *mem_list;
|
||||
struct msm_vidc_buffer *buffer;
|
||||
struct msm_vidc_alloc *alloc;
|
||||
struct msm_vidc_map *map;
|
||||
struct msm_vidc_mem *mem;
|
||||
struct msm_vidc_core *core;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
@@ -3621,11 +3575,8 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
|
||||
buffers = msm_vidc_get_buffers(inst, buffer_type, __func__);
|
||||
if (!buffers)
|
||||
return -EINVAL;
|
||||
allocations = msm_vidc_get_allocations(inst, buffer_type, __func__);
|
||||
if (!allocations)
|
||||
return -EINVAL;
|
||||
mappings = msm_vidc_get_mappings(inst, buffer_type, __func__);
|
||||
if (!mappings)
|
||||
mem_list = msm_vidc_get_mem_info(inst, buffer_type, __func__);
|
||||
if (!mem_list)
|
||||
return -EINVAL;
|
||||
|
||||
if (!buffers->size)
|
||||
@@ -3642,37 +3593,23 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
|
||||
buffer->buffer_size = buffers->size;
|
||||
list_add_tail(&buffer->list, &buffers->list);
|
||||
|
||||
alloc = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_ALLOC);
|
||||
if (!alloc) {
|
||||
i_vpr_e(inst, "%s: alloc failed\n", __func__);
|
||||
mem = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_ALLOC_MAP);
|
||||
if (!mem) {
|
||||
i_vpr_e(inst, "%s: mem poo alloc failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
INIT_LIST_HEAD(&alloc->list);
|
||||
alloc->type = buffer_type;
|
||||
alloc->region = call_mem_op(core, buffer_region, inst, buffer_type);
|
||||
alloc->size = buffer->buffer_size;
|
||||
alloc->secure = is_secure_region(alloc->region);
|
||||
rc = call_mem_op(core, memory_alloc, core, alloc);
|
||||
INIT_LIST_HEAD(&mem->list);
|
||||
mem->type = buffer_type;
|
||||
mem->region = call_mem_op(core, buffer_region, inst, buffer_type);
|
||||
mem->size = buffer->buffer_size;
|
||||
mem->secure = is_secure_region(mem->region);
|
||||
rc = call_mem_op(core, memory_alloc_map, core, mem);
|
||||
if (rc)
|
||||
return -ENOMEM;
|
||||
list_add_tail(&alloc->list, &allocations->list);
|
||||
list_add_tail(&mem->list, &mem_list->list);
|
||||
|
||||
map = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_MAP);
|
||||
if (!map) {
|
||||
i_vpr_e(inst, "%s: map alloc failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
INIT_LIST_HEAD(&map->list);
|
||||
map->type = alloc->type;
|
||||
map->region = alloc->region;
|
||||
map->dmabuf = alloc->dmabuf;
|
||||
rc = call_mem_op(core, memory_map, core, map);
|
||||
if (rc)
|
||||
return -ENOMEM;
|
||||
list_add_tail(&map->list, &mappings->list);
|
||||
|
||||
buffer->dmabuf = alloc->dmabuf;
|
||||
buffer->device_addr = map->device_addr;
|
||||
buffer->dmabuf = mem->dmabuf;
|
||||
buffer->device_addr = mem->device_addr;
|
||||
i_vpr_h(inst, "%s: create: type: %8s, size: %9u, device_addr %#llx\n", __func__,
|
||||
buf_name(buffer_type), buffers->size, buffer->device_addr);
|
||||
|
||||
|
@@ -28,8 +28,7 @@ struct msm_vidc_type_size_name {
|
||||
|
||||
static const struct msm_vidc_type_size_name buftype_size_name_arr[] = {
|
||||
{MSM_MEM_POOL_BUFFER, sizeof(struct msm_vidc_buffer), "MSM_MEM_POOL_BUFFER" },
|
||||
{MSM_MEM_POOL_MAP, sizeof(struct msm_vidc_map), "MSM_MEM_POOL_MAP" },
|
||||
{MSM_MEM_POOL_ALLOC, sizeof(struct msm_vidc_alloc), "MSM_MEM_POOL_ALLOC" },
|
||||
{MSM_MEM_POOL_ALLOC_MAP, sizeof(struct msm_vidc_mem), "MSM_MEM_POOL_ALLOC_MAP" },
|
||||
{MSM_MEM_POOL_TIMESTAMP, sizeof(struct msm_vidc_timestamp), "MSM_MEM_POOL_TIMESTAMP" },
|
||||
{MSM_MEM_POOL_DMABUF, sizeof(struct msm_memory_dmabuf), "MSM_MEM_POOL_DMABUF" },
|
||||
{MSM_MEM_POOL_PACKET, sizeof(struct hfi_pending_packet) + MSM_MEM_POOL_PACKET_SIZE,
|
||||
@@ -410,112 +409,72 @@ static struct sg_table *msm_vidc_dma_buf_map_attachment(
|
||||
return table;
|
||||
}
|
||||
|
||||
static int msm_vidc_memory_map(struct msm_vidc_core *core, struct msm_vidc_map *map)
|
||||
static int msm_vidc_memory_alloc_map(struct msm_vidc_core *core, struct msm_vidc_mem *mem)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dma_buf_attachment *attach = NULL;
|
||||
struct sg_table *table = NULL;
|
||||
int size = 0;
|
||||
struct context_bank_info *cb = NULL;
|
||||
|
||||
if (!core || !map) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (map->refcount) {
|
||||
map->refcount++;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
cb = msm_vidc_get_context_bank_for_region(core, map->region);
|
||||
if (!cb) {
|
||||
d_vpr_e("%s: Failed to get context bank device\n",
|
||||
__func__);
|
||||
rc = -EIO;
|
||||
goto error_cb;
|
||||
}
|
||||
|
||||
/* Prepare a dma buf for dma on the given device */
|
||||
attach = msm_vidc_dma_buf_attach(core, map->dmabuf, cb->dev);
|
||||
if (IS_ERR_OR_NULL(attach)) {
|
||||
rc = PTR_ERR(attach) ? PTR_ERR(attach) : -ENOMEM;
|
||||
d_vpr_e("Failed to attach dmabuf\n");
|
||||
goto error_attach;
|
||||
}
|
||||
|
||||
table = msm_vidc_dma_buf_map_attachment(core, attach);
|
||||
if (IS_ERR_OR_NULL(table)) {
|
||||
rc = PTR_ERR(table) ? PTR_ERR(table) : -ENOMEM;
|
||||
d_vpr_e("Failed to map table\n");
|
||||
goto error_table;
|
||||
}
|
||||
|
||||
map->device_addr = sg_dma_address(table->sgl);
|
||||
map->table = table;
|
||||
map->attach = attach;
|
||||
map->refcount++;
|
||||
|
||||
exit:
|
||||
d_vpr_l(
|
||||
"%s: type %11s, device_addr %#llx, refcount %d, region %d\n",
|
||||
__func__, buf_name(map->type), map->device_addr, map->refcount, map->region);
|
||||
|
||||
return 0;
|
||||
|
||||
error_table:
|
||||
msm_vidc_dma_buf_detach(core, map->dmabuf, attach);
|
||||
error_attach:
|
||||
error_cb:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_memory_unmap(struct msm_vidc_core *core,
|
||||
struct msm_vidc_map *map)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!core || !map) {
|
||||
if (!mem) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (map->refcount) {
|
||||
map->refcount--;
|
||||
} else {
|
||||
d_vpr_e("unmap called while refcount is zero already\n");
|
||||
size = ALIGN(mem->size, SZ_4K);
|
||||
mem->attrs = DMA_ATTR_WRITE_COMBINE;
|
||||
|
||||
cb = msm_vidc_get_context_bank_for_region(core, mem->region);
|
||||
if (!cb) {
|
||||
d_vpr_e("%s: Failed to get context bank device\n",
|
||||
__func__);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
mem->kvaddr = dma_alloc_attrs(cb->dev, size, &mem->device_addr, GFP_KERNEL,
|
||||
mem->attrs);
|
||||
if (!mem->kvaddr) {
|
||||
d_vpr_e("%s: dma_alloc_attrs returned NULL\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
d_vpr_h(
|
||||
"%s: dmabuf %pK, size %d, buffer_type %s, secure %d, region %d\n",
|
||||
__func__, mem->kvaddr, mem->size, buf_name(mem->type),
|
||||
mem->secure, mem->region);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_vidc_memory_unmap_free(struct msm_vidc_core *core, struct msm_vidc_mem *mem)
|
||||
{
|
||||
int rc = 0;
|
||||
struct context_bank_info *cb = NULL;
|
||||
|
||||
if (!mem || !mem->device_addr || !mem->kvaddr) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
d_vpr_l(
|
||||
"%s: type %11s, device_addr %#llx, refcount %d, region %d\n",
|
||||
__func__, buf_name(map->type), map->device_addr, map->refcount, map->region);
|
||||
d_vpr_h(
|
||||
"%s: dmabuf %pK, size %d, kvaddr %pK, buffer_type %s, secure %d, region %d\n",
|
||||
__func__, mem->device_addr, mem->size, mem->kvaddr, buf_name(mem->type),
|
||||
mem->secure, mem->region);
|
||||
|
||||
if (map->refcount)
|
||||
goto exit;
|
||||
cb = msm_vidc_get_context_bank_for_region(core, mem->region);
|
||||
if (!cb) {
|
||||
d_vpr_e("%s: Failed to get context bank device\n",
|
||||
__func__);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
msm_vidc_dma_buf_unmap_attachment(core, map->attach, map->table);
|
||||
msm_vidc_dma_buf_detach(core, map->dmabuf, map->attach);
|
||||
dma_free_attrs(cb->dev, mem->size, mem->kvaddr, mem->device_addr,
|
||||
mem->attrs);
|
||||
|
||||
map->device_addr = 0x0;
|
||||
map->attach = NULL;
|
||||
map->table = NULL;
|
||||
mem->kvaddr = NULL;
|
||||
mem->device_addr = 0;
|
||||
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_memory_alloc(struct msm_vidc_core *core, struct msm_vidc_alloc *mem)
|
||||
{
|
||||
d_vpr_e("%s: unsupported\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int msm_vidc_memory_free(struct msm_vidc_core *core, struct msm_vidc_alloc *mem)
|
||||
{
|
||||
d_vpr_e("%s: unsupported\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static u32 msm_vidc_buffer_region(struct msm_vidc_inst *inst,
|
||||
enum msm_vidc_buffer_type buffer_type)
|
||||
{
|
||||
@@ -530,10 +489,8 @@ static struct msm_vidc_memory_ops msm_mem_ops = {
|
||||
.dma_buf_detach = msm_vidc_dma_buf_detach,
|
||||
.dma_buf_map_attachment = msm_vidc_dma_buf_map_attachment,
|
||||
.dma_buf_unmap_attachment = msm_vidc_dma_buf_unmap_attachment,
|
||||
.memory_map = msm_vidc_memory_map,
|
||||
.memory_unmap = msm_vidc_memory_unmap,
|
||||
.memory_alloc = msm_vidc_memory_alloc,
|
||||
.memory_free = msm_vidc_memory_free,
|
||||
.memory_alloc_map = msm_vidc_memory_alloc_map,
|
||||
.memory_unmap_free = msm_vidc_memory_unmap_free,
|
||||
.buffer_region = msm_vidc_buffer_region,
|
||||
};
|
||||
|
||||
|
@@ -79,7 +79,7 @@ static struct dma_buf_attachment *msm_vidc_dma_buf_attach_ext(struct msm_vidc_co
|
||||
return attach;
|
||||
}
|
||||
|
||||
static int msm_vidc_memory_free_ext(struct msm_vidc_core *core, struct msm_vidc_alloc *mem)
|
||||
static int msm_vidc_memory_free_ext(struct msm_vidc_core *core, struct msm_vidc_mem *mem)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
@@ -114,7 +114,7 @@ static int msm_vidc_memory_free_ext(struct msm_vidc_core *core, struct msm_vidc_
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_memory_alloc_ext(struct msm_vidc_core *core, struct msm_vidc_alloc *mem)
|
||||
static int msm_vidc_memory_alloc_ext(struct msm_vidc_core *core, struct msm_vidc_mem *mem)
|
||||
{
|
||||
int rc = 0;
|
||||
int size = 0;
|
||||
@@ -224,39 +224,39 @@ error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_memory_map_ext(struct msm_vidc_core *core, struct msm_vidc_map *map)
|
||||
static int msm_vidc_memory_map_ext(struct msm_vidc_core *core, struct msm_vidc_mem *mem)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dma_buf_attachment *attach = NULL;
|
||||
struct sg_table *table = NULL;
|
||||
struct context_bank_info *cb = NULL;
|
||||
|
||||
if (!core || !map) {
|
||||
if (!core || !mem) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (map->refcount) {
|
||||
map->refcount++;
|
||||
if (mem->refcount) {
|
||||
mem->refcount++;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* reject non-secure mapping request for a secure buffer(or vice versa) */
|
||||
if (map->region == MSM_VIDC_NON_SECURE || map->region == MSM_VIDC_NON_SECURE_PIXEL) {
|
||||
if (!is_non_secure_buffer(map->dmabuf)) {
|
||||
if (mem->region == MSM_VIDC_NON_SECURE || mem->region == MSM_VIDC_NON_SECURE_PIXEL) {
|
||||
if (!is_non_secure_buffer(mem->dmabuf)) {
|
||||
d_vpr_e("%s: secure buffer mapping to non-secure region %d not allowed\n",
|
||||
__func__, map->region);
|
||||
__func__, mem->region);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (is_non_secure_buffer(map->dmabuf)) {
|
||||
if (is_non_secure_buffer(mem->dmabuf)) {
|
||||
d_vpr_e("%s: non-secure buffer mapping to secure region %d not allowed\n",
|
||||
__func__, map->region);
|
||||
__func__, mem->region);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
cb = msm_vidc_get_context_bank_for_region(core, map->region);
|
||||
cb = msm_vidc_get_context_bank_for_region(core, mem->region);
|
||||
if (!cb) {
|
||||
d_vpr_e("%s: Failed to get context bank device\n",
|
||||
__func__);
|
||||
@@ -265,7 +265,7 @@ static int msm_vidc_memory_map_ext(struct msm_vidc_core *core, struct msm_vidc_m
|
||||
}
|
||||
|
||||
/* Prepare a dma buf for dma on the given device */
|
||||
attach = msm_vidc_dma_buf_attach_ext(core, map->dmabuf, cb->dev);
|
||||
attach = msm_vidc_dma_buf_attach_ext(core, mem->dmabuf, cb->dev);
|
||||
if (IS_ERR_OR_NULL(attach)) {
|
||||
rc = PTR_ERR(attach) ? PTR_ERR(attach) : -ENOMEM;
|
||||
d_vpr_e("Failed to attach dmabuf\n");
|
||||
@@ -279,24 +279,59 @@ static int msm_vidc_memory_map_ext(struct msm_vidc_core *core, struct msm_vidc_m
|
||||
goto error_table;
|
||||
}
|
||||
|
||||
map->device_addr = sg_dma_address(table->sgl);
|
||||
map->table = table;
|
||||
map->attach = attach;
|
||||
map->refcount++;
|
||||
mem->device_addr = sg_dma_address(table->sgl);
|
||||
mem->table = table;
|
||||
mem->attach = attach;
|
||||
mem->refcount++;
|
||||
|
||||
exit:
|
||||
d_vpr_l("%s: type %11s, device_addr %#llx, refcount %d, region %d\n",
|
||||
__func__, buf_name(map->type), map->device_addr, map->refcount, map->region);
|
||||
__func__, buf_name(mem->type), mem->device_addr, mem->refcount, mem->region);
|
||||
|
||||
return 0;
|
||||
|
||||
error_table:
|
||||
call_mem_op(core, dma_buf_detach, core, map->dmabuf, attach);
|
||||
call_mem_op(core, dma_buf_detach, core, mem->dmabuf, attach);
|
||||
error_attach:
|
||||
error_cb:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_memory_unmap_ext(struct msm_vidc_core *core,
|
||||
struct msm_vidc_mem *mem)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!core || !mem) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mem->refcount) {
|
||||
mem->refcount--;
|
||||
} else {
|
||||
d_vpr_e("unmap called while refcount is zero already\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
d_vpr_l(
|
||||
"%s: type %11s, device_addr %#llx, refcount %d, region %d\n",
|
||||
__func__, buf_name(mem->type), mem->device_addr, mem->refcount, mem->region);
|
||||
|
||||
if (mem->refcount)
|
||||
goto exit;
|
||||
|
||||
call_mem_op(core, dma_buf_unmap_attachment, core, mem->attach, mem->table);
|
||||
call_mem_op(core, dma_buf_detach, core, mem->dmabuf, mem->attach);
|
||||
|
||||
mem->device_addr = 0x0;
|
||||
mem->attach = NULL;
|
||||
mem->table = NULL;
|
||||
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static u32 msm_vidc_buffer_region_ext(struct msm_vidc_inst *inst,
|
||||
enum msm_vidc_buffer_type buffer_type)
|
||||
{
|
||||
@@ -379,17 +414,54 @@ static u32 msm_vidc_buffer_region_ext(struct msm_vidc_inst *inst,
|
||||
return region;
|
||||
}
|
||||
|
||||
static int msm_vidc_memory_alloc_map_ext(struct msm_vidc_core *core, struct msm_vidc_mem *mem)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc = msm_vidc_memory_alloc_ext(core, mem);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: memory_alloc failed\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = msm_vidc_memory_map_ext(core, mem);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: memory_map failed\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_memory_unmap_free_ext(struct msm_vidc_core *core, struct msm_vidc_mem *mem)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc = msm_vidc_memory_unmap_ext(core, mem);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: memory_unmap failed\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = msm_vidc_memory_free_ext(core, mem);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: memory_free failed\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct msm_vidc_memory_ops *get_mem_ops_ext(void)
|
||||
{
|
||||
struct msm_vidc_memory_ops *mem_ops = get_mem_ops();
|
||||
static struct msm_vidc_memory_ops mem_ops_ext;
|
||||
|
||||
memcpy(&mem_ops_ext, mem_ops, sizeof(struct msm_vidc_memory_ops));
|
||||
mem_ops_ext.dma_buf_attach = msm_vidc_dma_buf_attach_ext;
|
||||
mem_ops_ext.memory_free = msm_vidc_memory_free_ext;
|
||||
mem_ops_ext.memory_alloc = msm_vidc_memory_alloc_ext;
|
||||
mem_ops_ext.memory_map = msm_vidc_memory_map_ext;
|
||||
mem_ops_ext.buffer_region = msm_vidc_buffer_region_ext;
|
||||
mem_ops_ext.dma_buf_attach = msm_vidc_dma_buf_attach_ext;
|
||||
mem_ops_ext.memory_alloc_map = msm_vidc_memory_alloc_map_ext;
|
||||
mem_ops_ext.memory_unmap_free = msm_vidc_memory_unmap_free_ext;
|
||||
mem_ops_ext.buffer_region = msm_vidc_buffer_region_ext;
|
||||
|
||||
return &mem_ops_ext;
|
||||
}
|
||||
|
@@ -424,10 +424,8 @@ void venus_hfi_queue_deinit(struct msm_vidc_core *core)
|
||||
return;
|
||||
}
|
||||
|
||||
call_mem_op(core, memory_unmap, core, &core->iface_q_table.map);
|
||||
call_mem_op(core, memory_free, core, &core->iface_q_table.alloc);
|
||||
call_mem_op(core, memory_unmap, core, &core->sfr.map);
|
||||
call_mem_op(core, memory_free, core, &core->sfr.alloc);
|
||||
call_mem_op(core, memory_unmap_free, core, &core->iface_q_table.mem);
|
||||
call_mem_op(core, memory_unmap_free, core, &core->sfr.mem);
|
||||
|
||||
for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) {
|
||||
core->iface_queues[i].q_hdr = NULL;
|
||||
@@ -487,8 +485,7 @@ int venus_hfi_queue_init(struct msm_vidc_core *core)
|
||||
struct hfi_queue_table_header *q_tbl_hdr;
|
||||
struct hfi_queue_header *q_hdr;
|
||||
struct msm_vidc_iface_q_info *iface_q;
|
||||
struct msm_vidc_alloc alloc;
|
||||
struct msm_vidc_map map;
|
||||
struct msm_vidc_mem mem;
|
||||
int offset = 0;
|
||||
u32 i;
|
||||
|
||||
@@ -500,39 +497,28 @@ int venus_hfi_queue_init(struct msm_vidc_core *core)
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&alloc, 0, sizeof(alloc));
|
||||
alloc.type = MSM_VIDC_BUF_QUEUE;
|
||||
alloc.region = MSM_VIDC_NON_SECURE;
|
||||
alloc.size = TOTAL_QSIZE;
|
||||
alloc.secure = false;
|
||||
alloc.map_kernel = true;
|
||||
rc = call_mem_op(core, memory_alloc, core, &alloc);
|
||||
memset(&mem, 0, sizeof(mem));
|
||||
mem.type = MSM_VIDC_BUF_QUEUE;
|
||||
mem.region = MSM_VIDC_NON_SECURE;
|
||||
mem.size = TOTAL_QSIZE;
|
||||
mem.secure = false;
|
||||
mem.map_kernel = true;
|
||||
rc = call_mem_op(core, memory_alloc_map, core, &mem);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: alloc failed\n", __func__);
|
||||
d_vpr_e("%s: alloc and map failed\n", __func__);
|
||||
goto fail_alloc_queue;
|
||||
}
|
||||
core->iface_q_table.align_virtual_addr = alloc.kvaddr;
|
||||
core->iface_q_table.alloc = alloc;
|
||||
|
||||
memset(&map, 0, sizeof(map));
|
||||
map.type = alloc.type;
|
||||
map.region = alloc.region;
|
||||
map.dmabuf = alloc.dmabuf;
|
||||
rc = call_mem_op(core, memory_map, core, &map);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: alloc failed\n", __func__);
|
||||
goto fail_alloc_queue;
|
||||
}
|
||||
core->iface_q_table.align_device_addr = map.device_addr;
|
||||
core->iface_q_table.map = map;
|
||||
core->iface_q_table.align_virtual_addr = mem.kvaddr;
|
||||
core->iface_q_table.align_device_addr = mem.device_addr;
|
||||
core->iface_q_table.mem = mem;
|
||||
|
||||
core->iface_q_table.mem_size = VIDC_IFACEQ_TABLE_SIZE;
|
||||
offset += core->iface_q_table.mem_size;
|
||||
|
||||
for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) {
|
||||
iface_q = &core->iface_queues[i];
|
||||
iface_q->q_array.align_device_addr = map.device_addr + offset;
|
||||
iface_q->q_array.align_virtual_addr = (void*)((char*)alloc.kvaddr + offset);
|
||||
iface_q->q_array.align_device_addr = mem.device_addr + offset;
|
||||
iface_q->q_array.align_virtual_addr = (void *)((char *)mem.kvaddr + offset);
|
||||
iface_q->q_array.mem_size = VIDC_IFACEQ_QUEUE_SIZE;
|
||||
offset += iface_q->q_array.mem_size;
|
||||
iface_q->q_hdr = VIDC_IFACEQ_GET_QHDR_START_ADDR(
|
||||
@@ -572,31 +558,20 @@ int venus_hfi_queue_init(struct msm_vidc_core *core)
|
||||
q_hdr->qhdr_rx_req = 0;
|
||||
|
||||
/* sfr buffer */
|
||||
memset(&alloc, 0, sizeof(alloc));
|
||||
alloc.type = MSM_VIDC_BUF_QUEUE;
|
||||
alloc.region = MSM_VIDC_NON_SECURE;
|
||||
alloc.size = ALIGNED_SFR_SIZE;
|
||||
alloc.secure = false;
|
||||
alloc.map_kernel = true;
|
||||
rc = call_mem_op(core, memory_alloc, core, &alloc);
|
||||
memset(&mem, 0, sizeof(mem));
|
||||
mem.type = MSM_VIDC_BUF_QUEUE;
|
||||
mem.region = MSM_VIDC_NON_SECURE;
|
||||
mem.size = ALIGNED_SFR_SIZE;
|
||||
mem.secure = false;
|
||||
mem.map_kernel = true;
|
||||
rc = call_mem_op(core, memory_alloc_map, core, &mem);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: sfr alloc failed\n", __func__);
|
||||
d_vpr_e("%s: sfr alloc and map failed\n", __func__);
|
||||
goto fail_alloc_queue;
|
||||
}
|
||||
core->sfr.align_virtual_addr = alloc.kvaddr;
|
||||
core->sfr.alloc = alloc;
|
||||
|
||||
memset(&map, 0, sizeof(map));
|
||||
map.type = alloc.type;
|
||||
map.region = alloc.region;
|
||||
map.dmabuf = alloc.dmabuf;
|
||||
rc = call_mem_op(core, memory_map, core, &map);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: sfr map failed\n", __func__);
|
||||
goto fail_alloc_queue;
|
||||
}
|
||||
core->sfr.align_device_addr = map.device_addr;
|
||||
core->sfr.map = map;
|
||||
core->sfr.align_virtual_addr = mem.kvaddr;
|
||||
core->sfr.align_device_addr = mem.device_addr;
|
||||
core->sfr.mem = mem;
|
||||
|
||||
core->sfr.mem_size = ALIGNED_SFR_SIZE;
|
||||
/* write sfr buffer size in first word */
|
||||
|
Reference in New Issue
Block a user