video: driver: code re-structure memory ops support

Re-structure the memory_ops code so that
upstream driver use mem_ops defined on
msm_vidc_memory.c and downstream driver
use mem_ops defined on msm_vidc_memory_ext.c.
It helps to modularize the code even further.

Change-Id: Id00b0872d7a902a8540500df5efb5f546a9dbe41
Signed-off-by: Ankush Mitra <quic_ankumitr@quicinc.com>
This commit is contained in:
Ankush Mitra
2022-10-26 15:52:45 +05:30
vanhempi 4250372925
commit 6b0dcb4a4f
12 muutettua tiedostoa jossa 453 lisäystä ja 510 poistoa

Näytä tiedosto

@@ -45,36 +45,45 @@ struct msm_memory_pool {
struct list_head busy_pool; /* list of struct msm_memory_alloc_header */
};
int msm_vidc_memory_alloc(struct msm_vidc_core *core,
struct msm_vidc_alloc *alloc);
int msm_vidc_memory_free(struct msm_vidc_core *core,
struct msm_vidc_alloc *alloc);
int msm_vidc_memory_map(struct msm_vidc_core *core,
struct msm_vidc_map *map);
int msm_vidc_memory_unmap(struct msm_vidc_core *core,
struct msm_vidc_map *map);
struct dma_buf *msm_vidc_dma_buf_get(struct msm_vidc_inst *inst,
int fd);
void msm_vidc_dma_buf_put(struct msm_vidc_inst *inst,
struct dma_buf *dmabuf);
void msm_vidc_dma_buf_put_completely(struct msm_vidc_inst *inst,
struct msm_memory_dmabuf *buf);
int msm_vidc_pools_init(struct msm_vidc_inst *inst);
void msm_vidc_pools_deinit(struct msm_vidc_inst *inst);
int msm_vidc_vmem_alloc(unsigned long size, void **mem, const char *msg);
void msm_vidc_vmem_free(void **addr);
void *msm_vidc_pool_alloc(struct msm_vidc_inst *inst,
enum msm_memory_pool_type type);
void msm_vidc_pool_free(struct msm_vidc_inst *inst, void *vidc_buf);
int msm_vidc_vmem_alloc(unsigned long size, void **mem, const char *msg);
void msm_vidc_vmem_free(void **addr);
struct dma_buf_attachment *msm_vidc_dma_buf_attach(struct msm_vidc_core *core,
struct dma_buf *dbuf, struct device *dev);
int msm_vidc_dma_buf_detach(struct msm_vidc_core *core, struct dma_buf *dbuf,
struct dma_buf_attachment *attach);
struct sg_table *msm_vidc_dma_buf_map_attachment(struct msm_vidc_core *core,
struct dma_buf_attachment *attach);
int msm_vidc_dma_buf_unmap_attachment(struct msm_vidc_core *core,
struct dma_buf_attachment *attach, struct sg_table *table);
u32 msm_vidc_buffer_region(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type);
int msm_vidc_pools_init(struct msm_vidc_inst *inst);
void msm_vidc_pools_deinit(struct msm_vidc_inst *inst);
#define call_mem_op(c, op, ...) \
(((c) && (c)->mem_ops && (c)->mem_ops->op) ? \
((c)->mem_ops->op(__VA_ARGS__)) : 0)
struct msm_vidc_memory_ops {
struct dma_buf *(*dma_buf_get)(struct msm_vidc_inst *inst,
int fd);
void (*dma_buf_put)(struct msm_vidc_inst *inst,
struct dma_buf *dmabuf);
void (*dma_buf_put_completely)(struct msm_vidc_inst *inst,
struct msm_memory_dmabuf *buf);
struct dma_buf_attachment *(*dma_buf_attach)(struct msm_vidc_core *core,
struct dma_buf *dbuf, struct device *dev);
int (*dma_buf_detach)(struct msm_vidc_core *core, struct dma_buf *dbuf,
struct dma_buf_attachment *attach);
struct sg_table *(*dma_buf_map_attachment)(struct msm_vidc_core *core,
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);
u32 (*buffer_region)(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type);
};
struct msm_vidc_memory_ops *get_mem_ops(void);
#endif // _MSM_VIDC_MEMORY_H_

Näytä tiedosto

@@ -7,16 +7,8 @@
#ifndef _MSM_VIDC_MEMORY_EXT_H_
#define _MSM_VIDC_MEMORY_EXT_H_
#include "msm_vidc_memory.h"
struct msm_vidc_memory_ops;
struct dma_buf_attachment *msm_vidc_dma_buf_attach_ext(struct msm_vidc_core *core,
struct dma_buf *dbuf, struct device *dev);
int msm_vidc_memory_alloc_ext(struct msm_vidc_core *core,
struct msm_vidc_alloc *alloc);
int msm_vidc_memory_free_ext(struct msm_vidc_core *core, struct msm_vidc_alloc *mem);
int msm_vidc_memory_map_ext(struct msm_vidc_core *core,
struct msm_vidc_map *map);
u32 msm_vidc_buffer_region_ext(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type);
struct msm_vidc_memory_ops *get_mem_ops_ext(void);
#endif // _MSM_VIDC_MEMORY_EXT_H_

Näytä tiedosto

@@ -21,7 +21,6 @@
#include "msm_vidc_memory.h"
#include "venus_hfi_response.h"
#include "msm_vidc.h"
#include "msm_vidc_platform.h"
extern const char video_banner[];
@@ -911,7 +910,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
msm_vidc_update_debug_str(inst);
i_vpr_h(inst, "Opening video instance: %d\n", session_type);
rc = call_mem_op(core, pools_init, inst);
rc = msm_vidc_pools_init(inst);
if (rc) {
i_vpr_e(inst, "%s: failed to init pool buffers\n", __func__);
msm_vidc_vmem_free((void **)&inst);

Näytä tiedosto

@@ -566,7 +566,7 @@ int msm_vidc_add_buffer_stats(struct msm_vidc_inst *inst,
if (buf->type != MSM_VIDC_BUF_INPUT)
return 0;
stats = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_BUF_STATS);
stats = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_BUF_STATS);
if (!stats)
return -ENOMEM;
INIT_LIST_HEAD(&stats->list);
@@ -614,7 +614,7 @@ int msm_vidc_remove_buffer_stats(struct msm_vidc_inst *inst,
/* remove entry - no output attached */
if (stats->flags & MSM_VIDC_STATS_FLAG_NO_OUTPUT) {
list_del_init(&stats->list);
call_mem_op(core, pool_free, inst, stats);
msm_vidc_pool_free(inst, stats);
}
} else if (buf->type == MSM_VIDC_BUF_OUTPUT) {
/* skip - ebd not arrived(single input - multiple output case) */
@@ -631,7 +631,7 @@ int msm_vidc_remove_buffer_stats(struct msm_vidc_inst *inst,
print_buffer_stats(VIDC_STAT, "stat", inst, stats);
call_mem_op(core, pool_free, inst, stats);
msm_vidc_pool_free(inst, stats);
}
}
}
@@ -653,7 +653,7 @@ int msm_vidc_flush_buffer_stats(struct msm_vidc_inst *inst)
i_vpr_l(inst, "%s: flush buffer_stats list\n", __func__);
list_for_each_entry_safe(stats, dummy_stats, &inst->buffer_stats_list, list) {
list_del_init(&stats->list);
call_mem_op(core, pool_free, inst, stats);
msm_vidc_pool_free(inst, stats);
}
/* reset initial ts as well to avoid huge delta */
@@ -2469,7 +2469,7 @@ int msm_vidc_process_readonly_buffers(struct msm_vidc_inst *inst,
}
list_del_init(&ro_buf->list);
call_mem_op(core, pool_free, inst, ro_buf);
msm_vidc_pool_free(inst, ro_buf);
}
return rc;
@@ -2551,7 +2551,7 @@ int msm_vidc_update_input_rate(struct msm_vidc_inst *inst, u64 time_us)
}
core = inst->core;
input_timer = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_BUF_TIMER);
input_timer = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_BUF_TIMER);
if (!input_timer)
return -ENOMEM;
@@ -2576,7 +2576,7 @@ int msm_vidc_update_input_rate(struct msm_vidc_inst *inst, u64 time_us)
input_timer = list_first_entry(&inst->input_timer_list,
struct msm_vidc_input_timer, list);
list_del_init(&input_timer->list);
call_mem_op(core, pool_free, inst, input_timer);
msm_vidc_pool_free(inst, input_timer);
}
return 0;
@@ -2596,7 +2596,7 @@ int msm_vidc_flush_input_timer(struct msm_vidc_inst *inst)
i_vpr_l(inst, "%s: flush input_timer list\n", __func__);
list_for_each_entry_safe(input_timer, dummy_timer, &inst->input_timer_list, list) {
list_del_init(&input_timer->list);
call_mem_op(core, pool_free, inst, input_timer);
msm_vidc_pool_free(inst, input_timer);
}
return 0;
}
@@ -2715,7 +2715,7 @@ int msm_vidc_flush_ts(struct msm_vidc_inst *inst)
i_vpr_l(inst, "%s: flushing ts: val %llu, rank %llu\n",
__func__, ts->sort.val, ts->rank);
list_del(&ts->sort.list);
call_mem_op(core, pool_free, inst, ts);
msm_vidc_pool_free(inst, ts);
}
inst->timestamps.count = 0;
inst->timestamps.rank = 0;
@@ -2739,7 +2739,7 @@ int msm_vidc_update_timestamp_rate(struct msm_vidc_inst *inst, u64 timestamp)
}
core = inst->core;
ts = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_TIMESTAMP);
ts = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_TIMESTAMP);
if (!ts) {
i_vpr_e(inst, "%s: ts alloc failed\n", __func__);
return -ENOMEM;
@@ -2767,7 +2767,7 @@ int msm_vidc_update_timestamp_rate(struct msm_vidc_inst *inst, u64 timestamp)
}
inst->timestamps.count--;
list_del(&ts->sort.list);
call_mem_op(core, pool_free, inst, ts);
msm_vidc_pool_free(inst, ts);
}
/* Calculate timestamp rate */
@@ -2801,7 +2801,7 @@ int msm_vidc_ts_reorder_insert_timestamp(struct msm_vidc_inst *inst, u64 timesta
core = inst->core;
/* allocate ts from pool */
ts = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_TIMESTAMP);
ts = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_TIMESTAMP);
if (!ts) {
i_vpr_e(inst, "%s: ts alloc failed\n", __func__);
return -ENOMEM;
@@ -2834,7 +2834,7 @@ int msm_vidc_ts_reorder_remove_timestamp(struct msm_vidc_inst *inst, u64 timesta
if (ts->sort.val == timestamp) {
list_del_init(&ts->sort.list);
inst->ts_reorder.count--;
call_mem_op(core, pool_free, inst, ts);
msm_vidc_pool_free(inst, ts);
break;
}
}
@@ -2868,7 +2868,7 @@ int msm_vidc_ts_reorder_get_first_timestamp(struct msm_vidc_inst *inst, u64 *tim
*timestamp = ts->sort.val;
inst->ts_reorder.count--;
call_mem_op(core, pool_free, inst, ts);
msm_vidc_pool_free(inst, ts);
return 0;
}
@@ -2888,7 +2888,7 @@ int msm_vidc_ts_reorder_flush(struct msm_vidc_inst *inst)
list_for_each_entry_safe(ts, temp, &inst->ts_reorder.list, sort.list) {
i_vpr_l(inst, "%s: flushing ts: val %lld\n", __func__, ts->sort.val);
list_del(&ts->sort.list);
call_mem_op(core, pool_free, inst, ts);
msm_vidc_pool_free(inst, ts);
}
inst->ts_reorder.count = 0;
@@ -2957,7 +2957,7 @@ int msm_vidc_allocate_buffers(struct msm_vidc_inst *inst,
return -EINVAL;
for (idx = 0; idx < num_buffers; idx++) {
buf = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_BUFFER);
buf = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_BUFFER);
if (!buf) {
i_vpr_e(inst, "%s: alloc failed\n", __func__);
return -EINVAL;
@@ -2996,7 +2996,7 @@ int msm_vidc_free_buffers(struct msm_vidc_inst *inst,
buf_count++;
print_vidc_buffer(VIDC_LOW, "low ", "free buffer", inst, buf);
list_del_init(&buf->list);
call_mem_op(core, pool_free, inst, buf);
msm_vidc_pool_free(inst, buf);
}
i_vpr_h(inst, "%s: freed %d buffers for type %s\n",
__func__, buf_count, buf_name(buf_type));
@@ -3631,7 +3631,7 @@ int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
if (map->dmabuf == buffer->dmabuf) {
call_mem_op(core, memory_unmap, core, map);
list_del(&map->list);
call_mem_op(core, pool_free, inst, map);
msm_vidc_pool_free(inst, map);
break;
}
}
@@ -3640,7 +3640,7 @@ int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
if (alloc->dmabuf == buffer->dmabuf) {
call_mem_op(core, memory_free, core, alloc);
list_del(&alloc->list);
call_mem_op(core, pool_free, inst, alloc);
msm_vidc_pool_free(inst, alloc);
break;
}
}
@@ -3648,7 +3648,7 @@ int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
list_for_each_entry_safe(buf, dummy, &buffers->list, list) {
if (buf->dmabuf == buffer->dmabuf) {
list_del(&buf->list);
call_mem_op(core, pool_free, inst, buf);
msm_vidc_pool_free(inst, buf);
break;
}
}
@@ -3730,7 +3730,7 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
if (!buffers->size)
return 0;
buffer = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_BUFFER);
buffer = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_BUFFER);
if (!buffer) {
i_vpr_e(inst, "%s: buf alloc failed\n", __func__);
return -ENOMEM;
@@ -3741,7 +3741,7 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
buffer->buffer_size = buffers->size;
list_add_tail(&buffer->list, &buffers->list);
alloc = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_ALLOC);
alloc = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_ALLOC);
if (!alloc) {
i_vpr_e(inst, "%s: alloc failed\n", __func__);
return -ENOMEM;
@@ -3756,7 +3756,7 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
return -ENOMEM;
list_add_tail(&alloc->list, &allocations->list);
map = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_MAP);
map = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_MAP);
if (!map) {
i_vpr_e(inst, "%s: map alloc failed\n", __func__);
return -ENOMEM;
@@ -5445,7 +5445,7 @@ int msm_vidc_flush_read_only_buffers(struct msm_vidc_inst *inst,
ro_buf->dbuf_get = 0;
ro_buf->device_addr = 0x0;
list_del_init(&ro_buf->list);
call_mem_op(core, pool_free, inst, ro_buf);
msm_vidc_pool_free(inst, ro_buf);
}
return rc;
@@ -5515,7 +5515,7 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
if (buf->dbuf_get)
call_mem_op(core, dma_buf_put, inst, buf->dmabuf);
list_del_init(&buf->list);
call_mem_op(core, pool_free, inst, buf);
msm_vidc_pool_free(inst, buf);
}
for (i = 0; i < ARRAY_SIZE(ext_buf_types); i++) {
@@ -5534,7 +5534,7 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
call_mem_op(core, dma_buf_put, inst, buf->dmabuf);
}
list_del_init(&buf->list);
call_mem_op(core, pool_free, inst, buf);
msm_vidc_pool_free(inst, buf);
}
}
@@ -5542,27 +5542,27 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
i_vpr_e(inst, "%s: removing ts: val %lld, rank %lld\n",
__func__, ts->sort.val, ts->rank);
list_del(&ts->sort.list);
call_mem_op(core, pool_free, inst, ts);
msm_vidc_pool_free(inst, ts);
}
list_for_each_entry_safe(ts, dummy_ts, &inst->ts_reorder.list, sort.list) {
i_vpr_e(inst, "%s: removing reorder ts: val %lld\n",
__func__, ts->sort.val);
list_del(&ts->sort.list);
call_mem_op(core, pool_free, inst, ts);
msm_vidc_pool_free(inst, ts);
}
list_for_each_entry_safe(timer, dummy_timer, &inst->input_timer_list, list) {
i_vpr_e(inst, "%s: removing input_timer %lld\n",
__func__, timer->time_us);
list_del(&timer->list);
call_mem_op(core, pool_free, inst, timer);
msm_vidc_pool_free(inst, timer);
}
list_for_each_entry_safe(stats, dummy_stats, &inst->buffer_stats_list, list) {
print_buffer_stats(VIDC_ERR, "err ", inst, stats);
list_del(&stats->list);
call_mem_op(core, pool_free, inst, stats);
msm_vidc_pool_free(inst, stats);
}
list_for_each_entry_safe(dbuf, dummy_dbuf, &inst->dmabuf_tracker, list) {
@@ -5605,7 +5605,7 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
}
/* destroy buffers from pool */
call_mem_op(core, pools_deinit, inst);
msm_vidc_pools_deinit(inst);
}
static void msm_vidc_close_helper(struct kref *kref)

Näytä tiedosto

@@ -23,298 +23,28 @@
MODULE_IMPORT_NS(DMA_BUF);
#endif
struct dma_buf *msm_vidc_dma_buf_get(struct msm_vidc_inst *inst, int fd)
{
struct msm_memory_dmabuf *buf = NULL;
struct dma_buf *dmabuf = NULL;
bool found = false;
struct msm_vidc_type_size_name {
enum msm_memory_pool_type type;
u32 size;
char *name;
};
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return NULL;
}
/* get local dmabuf ref for tracking */
dmabuf = dma_buf_get(fd);
if (IS_ERR_OR_NULL(dmabuf)) {
d_vpr_e("Failed to get dmabuf for %d, error %ld\n",
fd, PTR_ERR(dmabuf));
return NULL;
}
/* track dmabuf - inc refcount if already present */
list_for_each_entry(buf, &inst->dmabuf_tracker, list) {
if (buf->dmabuf == dmabuf) {
buf->refcount++;
found = true;
break;
}
}
if (found) {
/* put local dmabuf ref */
dma_buf_put(dmabuf);
return dmabuf;
}
/* get tracker instance from pool */
buf = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_DMABUF);
if (!buf) {
i_vpr_e(inst, "%s: dmabuf alloc failed\n", __func__);
dma_buf_put(dmabuf);
return NULL;
}
/* hold dmabuf strong ref in tracker */
buf->dmabuf = dmabuf;
buf->refcount = 1;
INIT_LIST_HEAD(&buf->list);
/* add new dmabuf entry to tracker */
list_add_tail(&buf->list, &inst->dmabuf_tracker);
return dmabuf;
}
void msm_vidc_dma_buf_put(struct msm_vidc_inst *inst, struct dma_buf *dmabuf)
{
struct msm_memory_dmabuf *buf = NULL;
bool found = false;
if (!inst || !dmabuf) {
d_vpr_e("%s: invalid params\n", __func__);
return;
}
/* track dmabuf - dec refcount if already present */
list_for_each_entry(buf, &inst->dmabuf_tracker, list) {
if (buf->dmabuf == dmabuf) {
buf->refcount--;
found = true;
break;
}
}
if (!found) {
i_vpr_e(inst, "%s: invalid dmabuf %#x\n", __func__, dmabuf);
return;
}
/* non-zero refcount - do nothing */
if (buf->refcount)
return;
/* remove dmabuf entry from tracker */
list_del(&buf->list);
/* release dmabuf strong ref from tracker */
dma_buf_put(buf->dmabuf);
/* put tracker instance back to pool */
msm_vidc_pool_free(inst, buf);
}
void msm_vidc_dma_buf_put_completely(struct msm_vidc_inst *inst,
struct msm_memory_dmabuf *buf)
{
if (!inst || !buf) {
d_vpr_e("%s: invalid params\n", __func__);
return;
}
while (buf->refcount) {
buf->refcount--;
if (!buf->refcount) {
/* remove dmabuf entry from tracker */
list_del(&buf->list);
/* release dmabuf strong ref from tracker */
dma_buf_put(buf->dmabuf);
/* put tracker instance back to pool */
msm_vidc_pool_free(inst, buf);
break;
}
}
}
int msm_vidc_memory_map(struct msm_vidc_core *core, struct msm_vidc_map *map)
{
int rc = 0;
struct dma_buf_attachment *attach = NULL;
struct sg_table *table = NULL;
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 = table->sgl->dma_address;
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;
}
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__);
return -EINVAL;
}
if (map->refcount) {
map->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(map->type), map->device_addr, map->refcount, map->region);
if (map->refcount)
goto exit;
msm_vidc_dma_buf_unmap_attachment(core, map->attach, map->table);
msm_vidc_dma_buf_detach(core, map->dmabuf, map->attach);
map->device_addr = 0x0;
map->attach = NULL;
map->table = NULL;
exit:
return rc;
}
struct dma_buf_attachment *msm_vidc_dma_buf_attach(struct msm_vidc_core *core,
struct dma_buf *dbuf, struct device *dev)
{
int rc = 0;
struct dma_buf_attachment *attach = NULL;
if (!core || !dbuf || !dev) {
d_vpr_e("%s: invalid params\n", __func__);
return NULL;
}
attach = dma_buf_attach(dbuf, dev);
if (IS_ERR_OR_NULL(attach)) {
rc = PTR_ERR(attach) ? PTR_ERR(attach) : -1;
d_vpr_e("Failed to attach dmabuf, error %d\n", rc);
return NULL;;
}
/*
* We do not need dma_map function to perform cache operations
* on the whole buffer size and hence pass skip sync flag.
*/
attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;
return attach;
}
int msm_vidc_dma_buf_detach(struct msm_vidc_core *core,
struct dma_buf *dbuf, struct dma_buf_attachment *attach)
{
int rc = 0;
if (!dbuf || !attach) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
dma_buf_detach(dbuf, attach);
return rc;
}
struct sg_table *msm_vidc_dma_buf_map_attachment(
struct msm_vidc_core *core, struct dma_buf_attachment *attach)
{
int rc = 0;
struct sg_table *table = NULL;
if (!attach) {
d_vpr_e("%s: invalid params\n", __func__);
return NULL;
}
table = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
if (IS_ERR_OR_NULL(table)) {
rc = PTR_ERR(table) ? PTR_ERR(table) : -1;
d_vpr_e("Failed to map table, error %d\n", rc);
return NULL;
}
if (!table->sgl) {
d_vpr_e("%s: sgl is NULL\n", __func__);
msm_vidc_dma_buf_unmap_attachment(core, attach, table);
return NULL;
}
return table;
}
int msm_vidc_dma_buf_unmap_attachment(struct msm_vidc_core *core,
struct dma_buf_attachment *attach, struct sg_table *table)
{
int rc = 0;
if (!attach || !table) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
dma_buf_unmap_attachment(attach, table, DMA_BIDIRECTIONAL);
return rc;
}
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_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,
"MSM_MEM_POOL_PACKET"},
{MSM_MEM_POOL_BUF_TIMER, sizeof(struct msm_vidc_input_timer), "MSM_MEM_POOL_BUF_TIMER" },
{MSM_MEM_POOL_BUF_STATS, sizeof(struct msm_vidc_buffer_stats), "MSM_MEM_POOL_BUF_STATS"},
};
int msm_vidc_vmem_alloc(unsigned long size, void **mem, const char *msg)
{
int rc = 0;
if (*mem) {
d_vpr_e("%s: error: double alloc\n", msg);
rc = -EINVAL;
@@ -337,18 +67,6 @@ void msm_vidc_vmem_free(void **addr)
}
}
int msm_vidc_memory_alloc(struct msm_vidc_core *core, struct msm_vidc_alloc *mem)
{
d_vpr_e("%s: unsupported\n", __func__);
return -EINVAL;
}
int msm_vidc_memory_free(struct msm_vidc_core *core, struct msm_vidc_alloc *mem)
{
d_vpr_e("%s: unsupported\n", __func__);
return -EINVAL;
}
void *msm_vidc_pool_alloc(struct msm_vidc_inst *inst, enum msm_memory_pool_type type)
{
struct msm_memory_alloc_header *hdr = NULL;
@@ -466,38 +184,6 @@ static void msm_vidc_destroy_pool_buffers(struct msm_vidc_inst *inst,
__func__, pool->name, fcount, bcount);
}
void msm_vidc_pools_deinit(struct msm_vidc_inst *inst)
{
u32 i = 0;
if (!inst) {
d_vpr_e("%s: Invalid params\n", __func__);
return;
}
/* destroy all buffers from all pool types */
for (i = 0; i < MSM_MEM_POOL_MAX; i++)
msm_vidc_destroy_pool_buffers(inst, i);
}
struct msm_vidc_type_size_name {
enum msm_memory_pool_type type;
u32 size;
char *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_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,
"MSM_MEM_POOL_PACKET"},
{MSM_MEM_POOL_BUF_TIMER, sizeof(struct msm_vidc_input_timer), "MSM_MEM_POOL_BUF_TIMER" },
{MSM_MEM_POOL_BUF_STATS, sizeof(struct msm_vidc_buffer_stats), "MSM_MEM_POOL_BUF_STATS"},
};
int msm_vidc_pools_init(struct msm_vidc_inst *inst)
{
u32 i;
@@ -528,8 +214,343 @@ int msm_vidc_pools_init(struct msm_vidc_inst *inst)
return 0;
}
u32 msm_vidc_buffer_region(struct msm_vidc_inst *inst,
void msm_vidc_pools_deinit(struct msm_vidc_inst *inst)
{
u32 i = 0;
if (!inst) {
d_vpr_e("%s: Invalid params\n", __func__);
return;
}
/* destroy all buffers from all pool types */
for (i = 0; i < MSM_MEM_POOL_MAX; i++)
msm_vidc_destroy_pool_buffers(inst, i);
}
static struct dma_buf *msm_vidc_dma_buf_get(struct msm_vidc_inst *inst, int fd)
{
struct msm_memory_dmabuf *buf = NULL;
struct dma_buf *dmabuf = NULL;
bool found = false;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return NULL;
}
/* get local dmabuf ref for tracking */
dmabuf = dma_buf_get(fd);
if (IS_ERR_OR_NULL(dmabuf)) {
d_vpr_e("Failed to get dmabuf for %d, error %ld\n",
fd, PTR_ERR(dmabuf));
return NULL;
}
/* track dmabuf - inc refcount if already present */
list_for_each_entry(buf, &inst->dmabuf_tracker, list) {
if (buf->dmabuf == dmabuf) {
buf->refcount++;
found = true;
break;
}
}
if (found) {
/* put local dmabuf ref */
dma_buf_put(dmabuf);
return dmabuf;
}
/* get tracker instance from pool */
buf = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_DMABUF);
if (!buf) {
i_vpr_e(inst, "%s: dmabuf alloc failed\n", __func__);
dma_buf_put(dmabuf);
return NULL;
}
/* hold dmabuf strong ref in tracker */
buf->dmabuf = dmabuf;
buf->refcount = 1;
INIT_LIST_HEAD(&buf->list);
/* add new dmabuf entry to tracker */
list_add_tail(&buf->list, &inst->dmabuf_tracker);
return dmabuf;
}
static void msm_vidc_dma_buf_put(struct msm_vidc_inst *inst, struct dma_buf *dmabuf)
{
struct msm_memory_dmabuf *buf = NULL;
bool found = false;
if (!inst || !dmabuf) {
d_vpr_e("%s: invalid params\n", __func__);
return;
}
/* track dmabuf - dec refcount if already present */
list_for_each_entry(buf, &inst->dmabuf_tracker, list) {
if (buf->dmabuf == dmabuf) {
buf->refcount--;
found = true;
break;
}
}
if (!found) {
i_vpr_e(inst, "%s: invalid dmabuf %#x\n", __func__, dmabuf);
return;
}
/* non-zero refcount - do nothing */
if (buf->refcount)
return;
/* remove dmabuf entry from tracker */
list_del(&buf->list);
/* release dmabuf strong ref from tracker */
dma_buf_put(buf->dmabuf);
/* put tracker instance back to pool */
msm_vidc_pool_free(inst, buf);
}
static void msm_vidc_dma_buf_put_completely(struct msm_vidc_inst *inst,
struct msm_memory_dmabuf *buf)
{
if (!inst || !buf) {
d_vpr_e("%s: invalid params\n", __func__);
return;
}
while (buf->refcount) {
buf->refcount--;
if (!buf->refcount) {
/* remove dmabuf entry from tracker */
list_del(&buf->list);
/* release dmabuf strong ref from tracker */
dma_buf_put(buf->dmabuf);
/* put tracker instance back to pool */
msm_vidc_pool_free(inst, buf);
break;
}
}
}
static struct dma_buf_attachment *msm_vidc_dma_buf_attach(struct msm_vidc_core *core,
struct dma_buf *dbuf, struct device *dev)
{
int rc = 0;
struct dma_buf_attachment *attach = NULL;
if (!core || !dbuf || !dev) {
d_vpr_e("%s: invalid params\n", __func__);
return NULL;
}
attach = dma_buf_attach(dbuf, dev);
if (IS_ERR_OR_NULL(attach)) {
rc = PTR_ERR(attach) ? PTR_ERR(attach) : -1;
d_vpr_e("Failed to attach dmabuf, error %d\n", rc);
return NULL;
}
/*
* We do not need dma_map function to perform cache operations
* on the whole buffer size and hence pass skip sync flag.
*/
attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;
return attach;
}
static int msm_vidc_dma_buf_detach(struct msm_vidc_core *core,
struct dma_buf *dbuf, struct dma_buf_attachment *attach)
{
int rc = 0;
if (!dbuf || !attach) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
dma_buf_detach(dbuf, attach);
return rc;
}
static int msm_vidc_dma_buf_unmap_attachment(struct msm_vidc_core *core,
struct dma_buf_attachment *attach, struct sg_table *table)
{
int rc = 0;
if (!attach || !table) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
dma_buf_unmap_attachment(attach, table, DMA_BIDIRECTIONAL);
return rc;
}
static struct sg_table *msm_vidc_dma_buf_map_attachment(
struct msm_vidc_core *core, struct dma_buf_attachment *attach)
{
int rc = 0;
struct sg_table *table = NULL;
if (!attach) {
d_vpr_e("%s: invalid params\n", __func__);
return NULL;
}
table = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
if (IS_ERR_OR_NULL(table)) {
rc = PTR_ERR(table) ? PTR_ERR(table) : -1;
d_vpr_e("Failed to map table, error %d\n", rc);
return NULL;
}
if (!table->sgl) {
d_vpr_e("%s: sgl is NULL\n", __func__);
msm_vidc_dma_buf_unmap_attachment(core, attach, table);
return NULL;
}
return table;
}
static int msm_vidc_memory_map(struct msm_vidc_core *core, struct msm_vidc_map *map)
{
int rc = 0;
struct dma_buf_attachment *attach = NULL;
struct sg_table *table = NULL;
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 = table->sgl->dma_address;
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__);
return -EINVAL;
}
if (map->refcount) {
map->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(map->type), map->device_addr, map->refcount, map->region);
if (map->refcount)
goto exit;
msm_vidc_dma_buf_unmap_attachment(core, map->attach, map->table);
msm_vidc_dma_buf_detach(core, map->dmabuf, map->attach);
map->device_addr = 0x0;
map->attach = NULL;
map->table = NULL;
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)
{
return MSM_VIDC_NON_SECURE;
}
static struct msm_vidc_memory_ops msm_mem_ops = {
.dma_buf_get = msm_vidc_dma_buf_get,
.dma_buf_put = msm_vidc_dma_buf_put,
.dma_buf_put_completely = msm_vidc_dma_buf_put_completely,
.dma_buf_attach = msm_vidc_dma_buf_attach,
.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,
.buffer_region = msm_vidc_buffer_region,
};
struct msm_vidc_memory_ops *get_mem_ops(void)
{
return &msm_mem_ops;
}

Näytä tiedosto

@@ -15,13 +15,14 @@
#include "msm_vidc_driver.h"
#include "msm_vidc_events.h"
#include "msm_vidc_platform.h"
#include "msm_vidc_memory.h"
static bool is_non_secure_buffer(struct dma_buf *dmabuf)
{
return mem_buf_dma_buf_exclusive_owner(dmabuf);
}
struct dma_buf_attachment *msm_vidc_dma_buf_attach_ext(struct msm_vidc_core *core,
static struct dma_buf_attachment *msm_vidc_dma_buf_attach_ext(struct msm_vidc_core *core,
struct dma_buf *dbuf, struct device *dev)
{
int rc = 0;
@@ -78,7 +79,7 @@ struct dma_buf_attachment *msm_vidc_dma_buf_attach_ext(struct msm_vidc_core *cor
return attach;
}
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_alloc *mem)
{
int rc = 0;
@@ -113,7 +114,7 @@ int msm_vidc_memory_free_ext(struct msm_vidc_core *core, struct msm_vidc_alloc *
return rc;
}
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_alloc *mem)
{
int rc = 0;
int size = 0;
@@ -223,7 +224,7 @@ error:
return rc;
}
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_map *map)
{
int rc = 0;
struct dma_buf_attachment *attach = NULL;
@@ -271,7 +272,7 @@ int msm_vidc_memory_map_ext(struct msm_vidc_core *core, struct msm_vidc_map *map
goto error_attach;
}
table = msm_vidc_dma_buf_map_attachment(core, attach);
table = call_mem_op(core, 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");
@@ -290,13 +291,13 @@ exit:
return 0;
error_table:
msm_vidc_dma_buf_detach(core, map->dmabuf, attach);
call_mem_op(core, dma_buf_detach, core, map->dmabuf, attach);
error_attach:
error_cb:
return rc;
}
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)
{
u32 region = MSM_VIDC_NON_SECURE;
@@ -377,3 +378,18 @@ u32 msm_vidc_buffer_region_ext(struct msm_vidc_inst *inst,
return region;
}
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;
return &mem_ops_ext;
}

Näytä tiedosto

@@ -1314,7 +1314,7 @@ static int venus_hfi_cache_packet(struct msm_vidc_inst *inst)
return -EINVAL;
}
packet = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_PACKET);
packet = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_PACKET);
if (!packet) {
i_vpr_e(inst, "%s: failed to allocate pending packet\n", __func__);
return -ENOMEM;
@@ -1845,7 +1845,7 @@ static int venus_hfi_add_pending_packets(struct msm_vidc_inst *inst)
}
}
list_del(&pkt_info->list);
call_mem_op(core, pool_free, inst, pkt_info);
msm_vidc_pool_free(inst, pkt_info);
}
return rc;
}

Näytä tiedosto

@@ -684,7 +684,7 @@ static int handle_read_only_buffer(struct msm_vidc_inst *inst,
* if present, do nothing
*/
if (!found) {
ro_buf = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_BUFFER);
ro_buf = msm_vidc_pool_alloc(inst, MSM_MEM_POOL_BUFFER);
if (!ro_buf) {
i_vpr_e(inst, "%s: buffer alloc failed\n", __func__);
return -ENOMEM;