Merge "video: driver: implement memory_ops for upstream"

This commit is contained in:
qctecmdr
2022-12-27 10:58:45 -08:00
committed by Gerrit - the friendly Code Review server
10 changed files with 242 additions and 341 deletions

View File

@@ -37,8 +37,7 @@ struct msm_vidc_mem_addr {
u32 align_device_addr; u32 align_device_addr;
u8 *align_virtual_addr; u8 *align_virtual_addr;
u32 mem_size; u32 mem_size;
struct msm_vidc_map map; struct msm_vidc_mem mem;
struct msm_vidc_alloc alloc;
}; };
struct msm_vidc_iface_q_info { struct msm_vidc_iface_q_info {

View File

@@ -463,9 +463,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); 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, struct msm_vidc_buffers *msm_vidc_get_buffers(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type, const char *func); enum msm_vidc_buffer_type buffer_type, const char *func);
struct msm_vidc_mappings *msm_vidc_get_mappings(struct msm_vidc_inst *inst, struct msm_vidc_mem_list *msm_vidc_get_mem_info(
enum msm_vidc_buffer_type buffer_type, const char *func);
struct msm_vidc_allocations *msm_vidc_get_allocations(
struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type, struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type,
const char *func); const char *func);
struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst,

View File

@@ -39,28 +39,16 @@ struct msm_vidc_session_ops {
int (*extra_count)(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type type); int (*extra_count)(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type type);
}; };
struct msm_vidc_allocations_info { struct msm_vidc_mem_list_info {
struct msm_vidc_allocations bin; struct msm_vidc_mem_list bin;
struct msm_vidc_allocations arp; struct msm_vidc_mem_list arp;
struct msm_vidc_allocations comv; struct msm_vidc_mem_list comv;
struct msm_vidc_allocations non_comv; struct msm_vidc_mem_list non_comv;
struct msm_vidc_allocations line; struct msm_vidc_mem_list line;
struct msm_vidc_allocations dpb; struct msm_vidc_mem_list dpb;
struct msm_vidc_allocations persist; struct msm_vidc_mem_list persist;
struct msm_vidc_allocations vpss; struct msm_vidc_mem_list vpss;
struct msm_vidc_allocations partial_data; struct msm_vidc_mem_list 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_buffers_info { struct msm_vidc_buffers_info {
@@ -136,8 +124,7 @@ struct msm_vidc_inst {
struct vidc_bus_vote_data bus_data; struct vidc_bus_vote_data bus_data;
struct msm_memory_pool pool[MSM_MEM_POOL_MAX]; struct msm_memory_pool pool[MSM_MEM_POOL_MAX];
struct msm_vidc_buffers_info buffers; struct msm_vidc_buffers_info buffers;
struct msm_vidc_mappings_info mappings; struct msm_vidc_mem_list_info mem_info;
struct msm_vidc_allocations_info allocations;
struct msm_vidc_timestamps timestamps; struct msm_vidc_timestamps timestamps;
struct msm_vidc_timestamps ts_reorder; /* list of struct msm_vidc_timestamp */ struct msm_vidc_timestamps ts_reorder; /* list of struct msm_vidc_timestamp */
bool subscribed_input_psc; bool subscribed_input_psc;

View File

@@ -847,7 +847,7 @@ struct msm_vidc_fence {
int fd; int fd;
}; };
struct msm_vidc_alloc { struct msm_vidc_mem {
struct list_head list; struct list_head list;
enum msm_vidc_buffer_type type; enum msm_vidc_buffer_type type;
enum msm_vidc_buffer_region region; enum msm_vidc_buffer_region region;
@@ -865,25 +865,15 @@ struct msm_vidc_alloc {
struct dma_buf_map dmabuf_map; struct dma_buf_map dmabuf_map;
#endif #endif
void *kvaddr; void *kvaddr;
}; dma_addr_t device_addr;
unsigned long attrs;
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;
u32 refcount; u32 refcount;
u64 device_addr;
struct sg_table *table; struct sg_table *table;
struct dma_buf_attachment *attach; struct dma_buf_attachment *attach;
}; };
struct msm_vidc_mappings { struct msm_vidc_mem_list {
struct list_head list; // list of "struct msm_vidc_map" struct list_head list; // list of "struct msm_vidc_mem"
}; };
struct msm_vidc_buffer { struct msm_vidc_buffer {

View File

@@ -21,8 +21,7 @@ struct msm_memory_dmabuf {
enum msm_memory_pool_type { enum msm_memory_pool_type {
MSM_MEM_POOL_BUFFER = 0, MSM_MEM_POOL_BUFFER = 0,
MSM_MEM_POOL_MAP, MSM_MEM_POOL_ALLOC_MAP,
MSM_MEM_POOL_ALLOC,
MSM_MEM_POOL_TIMESTAMP, MSM_MEM_POOL_TIMESTAMP,
MSM_MEM_POOL_DMABUF, MSM_MEM_POOL_DMABUF,
MSM_MEM_POOL_PACKET, MSM_MEM_POOL_PACKET,
@@ -72,14 +71,10 @@ struct msm_vidc_memory_ops {
struct dma_buf_attachment *attach); struct dma_buf_attachment *attach);
int (*dma_buf_unmap_attachment)(struct msm_vidc_core *core, int (*dma_buf_unmap_attachment)(struct msm_vidc_core *core,
struct dma_buf_attachment *attach, struct sg_table *table); struct dma_buf_attachment *attach, struct sg_table *table);
int (*memory_map)(struct msm_vidc_core *core, int (*memory_alloc_map)(struct msm_vidc_core *core,
struct msm_vidc_map *map); struct msm_vidc_mem *mem);
int (*memory_unmap)(struct msm_vidc_core *core, int (*memory_unmap_free)(struct msm_vidc_core *core,
struct msm_vidc_map *map); struct msm_vidc_mem *mem);
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);
u32 (*buffer_region)(struct msm_vidc_inst *inst, u32 (*buffer_region)(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type); enum msm_vidc_buffer_type buffer_type);
}; };

View File

@@ -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.persist.list);
INIT_LIST_HEAD(&inst->buffers.vpss.list); INIT_LIST_HEAD(&inst->buffers.vpss.list);
INIT_LIST_HEAD(&inst->buffers.partial_data.list); INIT_LIST_HEAD(&inst->buffers.partial_data.list);
INIT_LIST_HEAD(&inst->allocations.bin.list); INIT_LIST_HEAD(&inst->mem_info.bin.list);
INIT_LIST_HEAD(&inst->allocations.arp.list); INIT_LIST_HEAD(&inst->mem_info.arp.list);
INIT_LIST_HEAD(&inst->allocations.comv.list); INIT_LIST_HEAD(&inst->mem_info.comv.list);
INIT_LIST_HEAD(&inst->allocations.non_comv.list); INIT_LIST_HEAD(&inst->mem_info.non_comv.list);
INIT_LIST_HEAD(&inst->allocations.line.list); INIT_LIST_HEAD(&inst->mem_info.line.list);
INIT_LIST_HEAD(&inst->allocations.dpb.list); INIT_LIST_HEAD(&inst->mem_info.dpb.list);
INIT_LIST_HEAD(&inst->allocations.persist.list); INIT_LIST_HEAD(&inst->mem_info.persist.list);
INIT_LIST_HEAD(&inst->allocations.vpss.list); INIT_LIST_HEAD(&inst->mem_info.vpss.list);
INIT_LIST_HEAD(&inst->allocations.partial_data.list); INIT_LIST_HEAD(&inst->mem_info.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->children_list); INIT_LIST_HEAD(&inst->children_list);
INIT_LIST_HEAD(&inst->firmware_list); INIT_LIST_HEAD(&inst->firmware_list);
INIT_LIST_HEAD(&inst->enc_input_crs); INIT_LIST_HEAD(&inst->enc_input_crs);

View File

@@ -873,59 +873,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, struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type,
const char *func) const char *func)
{ {
switch (buffer_type) { switch (buffer_type) {
case MSM_VIDC_BUF_BIN: case MSM_VIDC_BUF_BIN:
return &inst->mappings.bin; return &inst->mem_info.bin;
case MSM_VIDC_BUF_ARP: case MSM_VIDC_BUF_ARP:
return &inst->mappings.arp; return &inst->mem_info.arp;
case MSM_VIDC_BUF_COMV: case MSM_VIDC_BUF_COMV:
return &inst->mappings.comv; return &inst->mem_info.comv;
case MSM_VIDC_BUF_NON_COMV: case MSM_VIDC_BUF_NON_COMV:
return &inst->mappings.non_comv; return &inst->mem_info.non_comv;
case MSM_VIDC_BUF_LINE: case MSM_VIDC_BUF_LINE:
return &inst->mappings.line; return &inst->mem_info.line;
case MSM_VIDC_BUF_DPB: case MSM_VIDC_BUF_DPB:
return &inst->mappings.dpb; return &inst->mem_info.dpb;
case MSM_VIDC_BUF_PERSIST: case MSM_VIDC_BUF_PERSIST:
return &inst->mappings.persist; return &inst->mem_info.persist;
case MSM_VIDC_BUF_VPSS: case MSM_VIDC_BUF_VPSS:
return &inst->mappings.vpss; return &inst->mem_info.vpss;
case MSM_VIDC_BUF_PARTIAL_DATA: case MSM_VIDC_BUF_PARTIAL_DATA:
return &inst->mappings.partial_data; return &inst->mem_info.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;
default: default:
i_vpr_e(inst, "%s: invalid driver buffer type %d\n", i_vpr_e(inst, "%s: invalid driver buffer type %d\n",
func, buffer_type); func, buffer_type);
@@ -3402,10 +3372,8 @@ int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
struct msm_vidc_buffer *buffer) struct msm_vidc_buffer *buffer)
{ {
struct msm_vidc_buffers *buffers; struct msm_vidc_buffers *buffers;
struct msm_vidc_allocations *allocations; struct msm_vidc_mem_list *mem_list;
struct msm_vidc_mappings *mappings; struct msm_vidc_mem *mem, *mem_dummy;
struct msm_vidc_alloc *alloc, *alloc_dummy;
struct msm_vidc_map *map, *map_dummy;
struct msm_vidc_buffer *buf, *dummy; struct msm_vidc_buffer *buf, *dummy;
struct msm_vidc_core *core; struct msm_vidc_core *core;
@@ -3427,27 +3395,15 @@ int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
buffers = msm_vidc_get_buffers(inst, buffer->type, __func__); buffers = msm_vidc_get_buffers(inst, buffer->type, __func__);
if (!buffers) if (!buffers)
return -EINVAL; return -EINVAL;
allocations = msm_vidc_get_allocations(inst, buffer->type, __func__); mem_list = msm_vidc_get_mem_info(inst, buffer->type, __func__);
if (!allocations) if (!mem_list)
return -EINVAL;
mappings = msm_vidc_get_mappings(inst, buffer->type, __func__);
if (!mappings)
return -EINVAL; return -EINVAL;
list_for_each_entry_safe(map, map_dummy, &mappings->list, list) { list_for_each_entry_safe(mem, mem_dummy, &mem_list->list, list) {
if (map->dmabuf == buffer->dmabuf) { if (mem->dmabuf == buffer->dmabuf) {
call_mem_op(core, memory_unmap, core, map); call_mem_op(core, memory_unmap_free, core, mem);
list_del(&map->list); list_del(&mem->list);
msm_vidc_pool_free(inst, map); msm_vidc_pool_free(inst, mem);
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);
break; break;
} }
} }
@@ -3506,11 +3462,9 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
{ {
int rc = 0; int rc = 0;
struct msm_vidc_buffers *buffers; struct msm_vidc_buffers *buffers;
struct msm_vidc_allocations *allocations; struct msm_vidc_mem_list *mem_list;
struct msm_vidc_mappings *mappings;
struct msm_vidc_buffer *buffer; struct msm_vidc_buffer *buffer;
struct msm_vidc_alloc *alloc; struct msm_vidc_mem *mem;
struct msm_vidc_map *map;
struct msm_vidc_core *core; struct msm_vidc_core *core;
if (!inst || !inst->core) { if (!inst || !inst->core) {
@@ -3527,11 +3481,8 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
buffers = msm_vidc_get_buffers(inst, buffer_type, __func__); buffers = msm_vidc_get_buffers(inst, buffer_type, __func__);
if (!buffers) if (!buffers)
return -EINVAL; return -EINVAL;
allocations = msm_vidc_get_allocations(inst, buffer_type, __func__); mem_list = msm_vidc_get_mem_info(inst, buffer_type, __func__);
if (!allocations) if (!mem_list)
return -EINVAL;
mappings = msm_vidc_get_mappings(inst, buffer_type, __func__);
if (!mappings)
return -EINVAL; return -EINVAL;
if (!buffers->size) if (!buffers->size)
@@ -3548,37 +3499,23 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
buffer->buffer_size = buffers->size; buffer->buffer_size = buffers->size;
list_add_tail(&buffer->list, &buffers->list); list_add_tail(&buffer->list, &buffers->list);
alloc = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_ALLOC); mem = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_ALLOC_MAP);
if (!alloc) { if (!mem) {
i_vpr_e(inst, "%s: alloc failed\n", __func__); i_vpr_e(inst, "%s: mem poo alloc failed\n", __func__);
return -ENOMEM; return -ENOMEM;
} }
INIT_LIST_HEAD(&alloc->list); INIT_LIST_HEAD(&mem->list);
alloc->type = buffer_type; mem->type = buffer_type;
alloc->region = call_mem_op(core, buffer_region, inst, buffer_type); mem->region = call_mem_op(core, buffer_region, inst, buffer_type);
alloc->size = buffer->buffer_size; mem->size = buffer->buffer_size;
alloc->secure = is_secure_region(alloc->region); mem->secure = is_secure_region(mem->region);
rc = call_mem_op(core, memory_alloc, core, alloc); rc = call_mem_op(core, memory_alloc_map, core, mem);
if (rc) if (rc)
return -ENOMEM; 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); buffer->dmabuf = mem->dmabuf;
if (!map) { buffer->device_addr = mem->device_addr;
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;
i_vpr_h(inst, "%s: create: type: %8s, size: %9u, device_addr %#llx\n", __func__, i_vpr_h(inst, "%s: create: type: %8s, size: %9u, device_addr %#llx\n", __func__,
buf_name(buffer_type), buffers->size, buffer->device_addr); buf_name(buffer_type), buffers->size, buffer->device_addr);

View File

@@ -28,8 +28,7 @@ struct msm_vidc_type_size_name {
static const struct msm_vidc_type_size_name buftype_size_name_arr[] = { 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_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_MAP, sizeof(struct msm_vidc_mem), "MSM_MEM_POOL_ALLOC_MAP" },
{MSM_MEM_POOL_ALLOC, sizeof(struct msm_vidc_alloc), "MSM_MEM_POOL_ALLOC" },
{MSM_MEM_POOL_TIMESTAMP, sizeof(struct msm_vidc_timestamp), "MSM_MEM_POOL_TIMESTAMP" }, {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_DMABUF, sizeof(struct msm_memory_dmabuf), "MSM_MEM_POOL_DMABUF" },
{MSM_MEM_POOL_PACKET, sizeof(struct hfi_pending_packet) + MSM_MEM_POOL_PACKET_SIZE, {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; 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; int size = 0;
struct dma_buf_attachment *attach = NULL;
struct sg_table *table = NULL;
struct context_bank_info *cb = NULL; struct context_bank_info *cb = NULL;
if (!core || !map) { if (!mem) {
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) {
d_vpr_e("%s: invalid params\n", __func__); d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL; return -EINVAL;
} }
if (map->refcount) { size = ALIGN(mem->size, SZ_4K);
map->refcount--; mem->attrs = DMA_ATTR_WRITE_COMBINE;
} else {
d_vpr_e("unmap called while refcount is zero already\n"); 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; return -EINVAL;
} }
d_vpr_l( d_vpr_h(
"%s: type %11s, device_addr %#llx, refcount %d, region %d\n", "%s: dmabuf %pK, size %d, kvaddr %pK, buffer_type %s, secure %d, region %d\n",
__func__, buf_name(map->type), map->device_addr, map->refcount, map->region); __func__, mem->device_addr, mem->size, mem->kvaddr, buf_name(mem->type),
mem->secure, mem->region);
if (map->refcount) cb = msm_vidc_get_context_bank_for_region(core, mem->region);
goto exit; 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); dma_free_attrs(cb->dev, mem->size, mem->kvaddr, mem->device_addr,
msm_vidc_dma_buf_detach(core, map->dmabuf, map->attach); mem->attrs);
map->device_addr = 0x0; mem->kvaddr = NULL;
map->attach = NULL; mem->device_addr = 0;
map->table = NULL;
exit:
return rc; 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, static u32 msm_vidc_buffer_region(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type) 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_detach = msm_vidc_dma_buf_detach,
.dma_buf_map_attachment = msm_vidc_dma_buf_map_attachment, .dma_buf_map_attachment = msm_vidc_dma_buf_map_attachment,
.dma_buf_unmap_attachment = msm_vidc_dma_buf_unmap_attachment, .dma_buf_unmap_attachment = msm_vidc_dma_buf_unmap_attachment,
.memory_map = msm_vidc_memory_map, .memory_alloc_map = msm_vidc_memory_alloc_map,
.memory_unmap = msm_vidc_memory_unmap, .memory_unmap_free = msm_vidc_memory_unmap_free,
.memory_alloc = msm_vidc_memory_alloc,
.memory_free = msm_vidc_memory_free,
.buffer_region = msm_vidc_buffer_region, .buffer_region = msm_vidc_buffer_region,
}; };

View File

@@ -79,7 +79,7 @@ static struct dma_buf_attachment *msm_vidc_dma_buf_attach_ext(struct msm_vidc_co
return attach; 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; int rc = 0;
@@ -114,7 +114,7 @@ static int msm_vidc_memory_free_ext(struct msm_vidc_core *core, struct msm_vidc_
return rc; 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 rc = 0;
int size = 0; int size = 0;
@@ -224,39 +224,39 @@ error:
return rc; 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; int rc = 0;
struct dma_buf_attachment *attach = NULL; struct dma_buf_attachment *attach = NULL;
struct sg_table *table = NULL; struct sg_table *table = NULL;
struct context_bank_info *cb = NULL; struct context_bank_info *cb = NULL;
if (!core || !map) { if (!core || !mem) {
d_vpr_e("%s: invalid params\n", __func__); d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL; return -EINVAL;
} }
if (map->refcount) { if (mem->refcount) {
map->refcount++; mem->refcount++;
goto exit; goto exit;
} }
/* reject non-secure mapping request for a secure buffer(or vice versa) */ /* 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 (mem->region == MSM_VIDC_NON_SECURE || mem->region == MSM_VIDC_NON_SECURE_PIXEL) {
if (!is_non_secure_buffer(map->dmabuf)) { if (!is_non_secure_buffer(mem->dmabuf)) {
d_vpr_e("%s: secure buffer mapping to non-secure region %d not allowed\n", d_vpr_e("%s: secure buffer mapping to non-secure region %d not allowed\n",
__func__, map->region); __func__, mem->region);
return -EINVAL; return -EINVAL;
} }
} else { } 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", d_vpr_e("%s: non-secure buffer mapping to secure region %d not allowed\n",
__func__, map->region); __func__, mem->region);
return -EINVAL; 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) { if (!cb) {
d_vpr_e("%s: Failed to get context bank device\n", d_vpr_e("%s: Failed to get context bank device\n",
__func__); __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 */ /* 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)) { if (IS_ERR_OR_NULL(attach)) {
rc = PTR_ERR(attach) ? PTR_ERR(attach) : -ENOMEM; rc = PTR_ERR(attach) ? PTR_ERR(attach) : -ENOMEM;
d_vpr_e("Failed to attach dmabuf\n"); 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; goto error_table;
} }
map->device_addr = sg_dma_address(table->sgl); mem->device_addr = sg_dma_address(table->sgl);
map->table = table; mem->table = table;
map->attach = attach; mem->attach = attach;
map->refcount++; mem->refcount++;
exit: exit:
d_vpr_l("%s: type %11s, device_addr %#llx, refcount %d, region %d\n", 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; return 0;
error_table: 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_attach:
error_cb: error_cb:
return rc; 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, static u32 msm_vidc_buffer_region_ext(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type) 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; 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 *get_mem_ops_ext(void)
{ {
struct msm_vidc_memory_ops *mem_ops = get_mem_ops(); struct msm_vidc_memory_ops *mem_ops = get_mem_ops();
static struct msm_vidc_memory_ops mem_ops_ext; static struct msm_vidc_memory_ops mem_ops_ext;
memcpy(&mem_ops_ext, mem_ops, sizeof(struct msm_vidc_memory_ops)); 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.dma_buf_attach = msm_vidc_dma_buf_attach_ext;
mem_ops_ext.memory_free = msm_vidc_memory_free_ext; mem_ops_ext.memory_alloc_map = msm_vidc_memory_alloc_map_ext;
mem_ops_ext.memory_alloc = msm_vidc_memory_alloc_ext; mem_ops_ext.memory_unmap_free = msm_vidc_memory_unmap_free_ext;
mem_ops_ext.memory_map = msm_vidc_memory_map_ext; mem_ops_ext.buffer_region = msm_vidc_buffer_region_ext;
mem_ops_ext.buffer_region = msm_vidc_buffer_region_ext;
return &mem_ops_ext; return &mem_ops_ext;
} }

View File

@@ -424,10 +424,8 @@ void venus_hfi_queue_deinit(struct msm_vidc_core *core)
return; return;
} }
call_mem_op(core, memory_unmap, core, &core->iface_q_table.map); call_mem_op(core, memory_unmap_free, core, &core->iface_q_table.mem);
call_mem_op(core, memory_free, core, &core->iface_q_table.alloc); call_mem_op(core, memory_unmap_free, core, &core->sfr.mem);
call_mem_op(core, memory_unmap, core, &core->sfr.map);
call_mem_op(core, memory_free, core, &core->sfr.alloc);
for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) { for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) {
core->iface_queues[i].q_hdr = NULL; 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_table_header *q_tbl_hdr;
struct hfi_queue_header *q_hdr; struct hfi_queue_header *q_hdr;
struct msm_vidc_iface_q_info *iface_q; struct msm_vidc_iface_q_info *iface_q;
struct msm_vidc_alloc alloc; struct msm_vidc_mem mem;
struct msm_vidc_map map;
int offset = 0; int offset = 0;
u32 i; u32 i;
@@ -500,39 +497,28 @@ int venus_hfi_queue_init(struct msm_vidc_core *core)
return 0; return 0;
} }
memset(&alloc, 0, sizeof(alloc)); memset(&mem, 0, sizeof(mem));
alloc.type = MSM_VIDC_BUF_QUEUE; mem.type = MSM_VIDC_BUF_QUEUE;
alloc.region = MSM_VIDC_NON_SECURE; mem.region = MSM_VIDC_NON_SECURE;
alloc.size = TOTAL_QSIZE; mem.size = TOTAL_QSIZE;
alloc.secure = false; mem.secure = false;
alloc.map_kernel = true; mem.map_kernel = true;
rc = call_mem_op(core, memory_alloc, core, &alloc); rc = call_mem_op(core, memory_alloc_map, core, &mem);
if (rc) { if (rc) {
d_vpr_e("%s: alloc failed\n", __func__); d_vpr_e("%s: alloc and map failed\n", __func__);
goto fail_alloc_queue; goto fail_alloc_queue;
} }
core->iface_q_table.align_virtual_addr = alloc.kvaddr; core->iface_q_table.align_virtual_addr = mem.kvaddr;
core->iface_q_table.alloc = alloc; core->iface_q_table.align_device_addr = mem.device_addr;
core->iface_q_table.mem = mem;
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.mem_size = VIDC_IFACEQ_TABLE_SIZE; core->iface_q_table.mem_size = VIDC_IFACEQ_TABLE_SIZE;
offset += core->iface_q_table.mem_size; offset += core->iface_q_table.mem_size;
for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) { for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) {
iface_q = &core->iface_queues[i]; iface_q = &core->iface_queues[i];
iface_q->q_array.align_device_addr = map.device_addr + offset; iface_q->q_array.align_device_addr = mem.device_addr + offset;
iface_q->q_array.align_virtual_addr = (void*)((char*)alloc.kvaddr + offset); iface_q->q_array.align_virtual_addr = (void *)((char *)mem.kvaddr + offset);
iface_q->q_array.mem_size = VIDC_IFACEQ_QUEUE_SIZE; iface_q->q_array.mem_size = VIDC_IFACEQ_QUEUE_SIZE;
offset += iface_q->q_array.mem_size; offset += iface_q->q_array.mem_size;
iface_q->q_hdr = VIDC_IFACEQ_GET_QHDR_START_ADDR( 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; q_hdr->qhdr_rx_req = 0;
/* sfr buffer */ /* sfr buffer */
memset(&alloc, 0, sizeof(alloc)); memset(&mem, 0, sizeof(mem));
alloc.type = MSM_VIDC_BUF_QUEUE; mem.type = MSM_VIDC_BUF_QUEUE;
alloc.region = MSM_VIDC_NON_SECURE; mem.region = MSM_VIDC_NON_SECURE;
alloc.size = ALIGNED_SFR_SIZE; mem.size = ALIGNED_SFR_SIZE;
alloc.secure = false; mem.secure = false;
alloc.map_kernel = true; mem.map_kernel = true;
rc = call_mem_op(core, memory_alloc, core, &alloc); rc = call_mem_op(core, memory_alloc_map, core, &mem);
if (rc) { 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; goto fail_alloc_queue;
} }
core->sfr.align_virtual_addr = alloc.kvaddr; core->sfr.align_virtual_addr = mem.kvaddr;
core->sfr.alloc = alloc; core->sfr.align_device_addr = mem.device_addr;
core->sfr.mem = mem;
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.mem_size = ALIGNED_SFR_SIZE; core->sfr.mem_size = ALIGNED_SFR_SIZE;
/* write sfr buffer size in first word */ /* write sfr buffer size in first word */