video: driver: add memory ops support

add memory ops support so that different
implementations can exist for memory_alloc,
memory_free, memory_map and memory_unmap,
dma buf attach, detach, map, unmap and
get buffer region in upstream and downstream
drivers.

Change-Id: Ifabc34e7a8b0284579c1bc4a8f477fe558d068f4
Signed-off-by: Darshana Patil <quic_darshana@quicinc.com>
This commit is contained in:
Darshana Patil
2022-10-19 16:30:45 -07:00
committed by Gerrit - the friendly Code Review server
orang tua 02ed467c8a
melakukan 4250372925
18 mengubah file dengan 776 tambahan dan 610 penghapusan

Melihat File

@@ -11,6 +11,7 @@
#include "msm_vidc_internal.h"
#include "msm_vidc_core.h"
#include "msm_vidc_memory.h"
#define DDR_TYPE_LPDDR4 0x6
#define DDR_TYPE_LPDDR4X 0x7
@@ -219,6 +220,42 @@ struct msm_vidc_platform {
struct msm_vidc_platform_data data;
};
#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_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_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_map)(struct msm_vidc_core *core,
struct msm_vidc_map *map);
int (*memory_unmap)(struct msm_vidc_core *core,
struct msm_vidc_map *map);
u32 (*buffer_region)(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type);
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);
int (*pools_init)(struct msm_vidc_inst *inst);
void (*pools_deinit)(struct msm_vidc_inst *inst);
void *(*pool_alloc)(struct msm_vidc_inst *inst,
enum msm_memory_pool_type type);
void (*pool_free)(struct msm_vidc_inst *inst, void *vidc_buf);
};
static inline bool is_sys_cache_present(struct msm_vidc_core *core)
{
return !!core->platform->data.subcache_tbl_size;

Melihat File

@@ -15,6 +15,8 @@
#include "msm_vidc_core.h"
#include "msm_vidc_debug.h"
#include "msm_vidc_internal.h"
#include "msm_vidc_memory.h"
#if defined(CONFIG_MSM_VIDC_WAIPIO)
#include "msm_vidc_waipio.h"
#endif
@@ -185,6 +187,25 @@ static struct v4l2_m2m_ops msm_v4l2_m2m_ops = {
.job_abort = msm_v4l2_m2m_job_abort,
};
static struct msm_vidc_memory_ops msm_mem_ops = {
.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_alloc = msm_vidc_memory_alloc,
.memory_free = msm_vidc_memory_free,
.memory_map = msm_vidc_memory_map,
.memory_unmap = msm_vidc_memory_unmap,
.buffer_region = msm_vidc_buffer_region,
.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,
.pools_init = msm_vidc_pools_init,
.pools_deinit = msm_vidc_pools_deinit,
.pool_alloc = msm_vidc_pool_alloc,
.pool_free = msm_vidc_pool_free,
};
static int msm_vidc_init_ops(struct msm_vidc_core *core)
{
if (!core) {
@@ -201,6 +222,7 @@ static int msm_vidc_init_ops(struct msm_vidc_core *core)
core->vb2_mem_ops = &msm_vb2_mem_ops;
core->media_device_ops = &msm_v4l2_media_ops;
core->v4l2_m2m_ops = &msm_v4l2_m2m_ops;
core->mem_ops = &msm_mem_ops;
return 0;
}

Melihat File

@@ -16,6 +16,7 @@
#include "msm_vidc_debug.h"
#include "msm_vidc_internal.h"
#include "msm_vidc_control_ext.h"
#include "msm_vidc_memory_ext.h"
#include "hfi_property.h"
#include "msm_vidc_iris3.h"
#include "hfi_command.h"
@@ -2764,6 +2765,25 @@ static const struct msm_vidc_platform_data kalama_data_v2 = {
.format_data = &format_data_kalama,
};
static struct msm_vidc_memory_ops kalama_msm_mem_ops = {
.dma_buf_attach = msm_vidc_dma_buf_attach_ext,
.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_alloc = msm_vidc_memory_alloc_ext,
.memory_free = msm_vidc_memory_free_ext,
.memory_map = msm_vidc_memory_map_ext,
.memory_unmap = msm_vidc_memory_unmap,
.buffer_region = msm_vidc_buffer_region_ext,
.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,
.pools_init = msm_vidc_pools_init,
.pools_deinit = msm_vidc_pools_deinit,
.pool_alloc = msm_vidc_pool_alloc,
.pool_free = msm_vidc_pool_free,
};
int msm_vidc_kalama_check_ddr_type(void)
{
u32 ddr_type;
@@ -2794,6 +2814,7 @@ static int msm_vidc_init_data(struct msm_vidc_core *core, struct device *dev)
else
core->platform->data = kalama_data;
core->mem_ops = &kalama_msm_mem_ops;
rc = msm_vidc_kalama_check_ddr_type();
if (rc)
return rc;

Melihat File

@@ -16,6 +16,7 @@
#include "msm_vidc_debug.h"
#include "msm_vidc_internal.h"
#include "msm_vidc_control_ext.h"
#include "msm_vidc_memory_ext.h"
#include "hfi_property.h"
#include "msm_vidc_iris33.h"
#include "hfi_command.h"
@@ -2720,6 +2721,25 @@ static const struct msm_vidc_platform_data pineapple_data = {
.format_data = &format_data_pineapple,
};
static struct msm_vidc_memory_ops pineapple_msm_mem_ops = {
.dma_buf_attach = msm_vidc_dma_buf_attach_ext,
.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_alloc = msm_vidc_memory_alloc_ext,
.memory_free = msm_vidc_memory_free_ext,
.memory_map = msm_vidc_memory_map_ext,
.memory_unmap = msm_vidc_memory_unmap,
.buffer_region = msm_vidc_buffer_region_ext,
.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,
.pools_init = msm_vidc_pools_init,
.pools_deinit = msm_vidc_pools_deinit,
.pool_alloc = msm_vidc_pool_alloc,
.pool_free = msm_vidc_pool_free,
};
int msm_vidc_pineapple_check_ddr_type(void)
{
u32 ddr_type;
@@ -2746,6 +2766,7 @@ static int msm_vidc_init_data(struct msm_vidc_core *core)
d_vpr_h("%s: initialize pineapple data\n", __func__);
core->platform->data = pineapple_data;
core->mem_ops = &pineapple_msm_mem_ops;
rc = msm_vidc_pineapple_check_ddr_type();
if (rc)
return rc;

Melihat File

@@ -457,8 +457,6 @@ int msm_vidc_event_queue_deinit(struct msm_vidc_inst *inst);
int msm_vidc_vb2_queue_init(struct msm_vidc_inst *inst);
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);
u32 msm_vidc_get_buffer_region(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type, const char *func);
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,
@@ -595,5 +593,9 @@ int msm_vidc_alloc_and_queue_input_internal_buffers(struct msm_vidc_inst *inst);
int vb2_buffer_to_driver(struct vb2_buffer *vb2, struct msm_vidc_buffer *buf);
struct msm_vidc_buffer *msm_vidc_fetch_buffer(struct msm_vidc_inst *inst,
struct vb2_buffer *vb2);
struct context_bank_info *msm_vidc_get_context_bank_for_region(struct msm_vidc_core *core,
enum msm_vidc_buffer_region region);
struct context_bank_info *msm_vidc_get_context_bank_for_device(
struct msm_vidc_core *core, struct device *dev);
#endif // _MSM_VIDC_DRIVER_H_

Melihat File

@@ -955,17 +955,4 @@ struct msm_vidc_sfr {
u8 rg_data[1];
};
#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 {
int (*allocate)(void *inst, struct msm_vidc_buffer *mbuf);
int (*dma_map)(void *inst, struct msm_vidc_buffer *mbuf);
int (*dma_unmap)(void *inst, struct msm_vidc_buffer *mbuf);
int (*free)(void *inst, struct msm_vidc_buffer *mbuf);
int (*cache_op)(void *inst, struct msm_vidc_buffer *mbuf,
enum msm_vidc_cache_op cache_op);
};
#endif // _MSM_VIDC_INTERNAL_H_

Melihat File

@@ -53,28 +53,28 @@ 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_memory_get_dmabuf(struct msm_vidc_inst *inst,
struct dma_buf *msm_vidc_dma_buf_get(struct msm_vidc_inst *inst,
int fd);
void msm_vidc_memory_put_dmabuf(struct msm_vidc_inst *inst,
void msm_vidc_dma_buf_put(struct msm_vidc_inst *inst,
struct dma_buf *dmabuf);
void msm_vidc_memory_put_dmabuf_completely(struct msm_vidc_inst *inst,
void msm_vidc_dma_buf_put_completely(struct msm_vidc_inst *inst,
struct msm_memory_dmabuf *buf);
int msm_memory_pools_init(struct msm_vidc_inst *inst);
void msm_memory_pools_deinit(struct msm_vidc_inst *inst);
void *msm_memory_pool_alloc(struct msm_vidc_inst *inst,
int msm_vidc_pools_init(struct msm_vidc_inst *inst);
void msm_vidc_pools_deinit(struct msm_vidc_inst *inst);
void *msm_vidc_pool_alloc(struct msm_vidc_inst *inst,
enum msm_memory_pool_type type);
void msm_memory_pool_free(struct msm_vidc_inst *inst, void *vidc_buf);
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 context_bank_info *msm_vidc_get_context_bank(struct msm_vidc_core *core,
enum msm_vidc_buffer_region region);
struct dma_buf_attachment *msm_vidc_dma_buf_attach(struct dma_buf *dbuf,
struct device *dev);
int msm_vidc_dma_buf_detach(struct dma_buf *dbuf,
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 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 dma_buf_attachment *attach,
struct sg_table *table);
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);
#endif // _MSM_VIDC_MEMORY_H_

Melihat File

@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _MSM_VIDC_MEMORY_EXT_H_
#define _MSM_VIDC_MEMORY_EXT_H_
#include "msm_vidc_memory.h"
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);
#endif // _MSM_VIDC_MEMORY_EXT_H_

Melihat File

@@ -21,6 +21,7 @@
#include "msm_vidc_memory.h"
#include "venus_hfi_response.h"
#include "msm_vidc.h"
#include "msm_vidc_platform.h"
extern const char video_banner[];
@@ -910,7 +911,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 = msm_memory_pools_init(inst);
rc = call_mem_op(core, pools_init, inst);
if (rc) {
i_vpr_e(inst, "%s: failed to init pool buffers\n", __func__);
msm_vidc_vmem_free((void **)&inst);

Melihat File

@@ -547,11 +547,13 @@ int msm_vidc_add_buffer_stats(struct msm_vidc_inst *inst,
struct msm_vidc_buffer *buf)
{
struct msm_vidc_buffer_stats *stats = NULL;
struct msm_vidc_core *core;
if (!inst || !buf) {
if (!inst || !inst->core || !buf) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
/* stats applicable only to input & output buffers */
if (buf->type != MSM_VIDC_BUF_INPUT && buf->type != MSM_VIDC_BUF_OUTPUT)
@@ -564,7 +566,7 @@ int msm_vidc_add_buffer_stats(struct msm_vidc_inst *inst,
if (buf->type != MSM_VIDC_BUF_INPUT)
return 0;
stats = msm_memory_pool_alloc(inst, MSM_MEM_POOL_BUF_STATS);
stats = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_BUF_STATS);
if (!stats)
return -ENOMEM;
INIT_LIST_HEAD(&stats->list);
@@ -583,11 +585,13 @@ int msm_vidc_remove_buffer_stats(struct msm_vidc_inst *inst,
struct msm_vidc_buffer *buf)
{
struct msm_vidc_buffer_stats *stats = NULL, *dummy_stats = NULL;
struct msm_vidc_core *core;
if (!inst || !buf) {
if (!inst || !inst->core || !buf) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
/* stats applicable only to input & output buffers */
if (buf->type != MSM_VIDC_BUF_INPUT && buf->type != MSM_VIDC_BUF_OUTPUT)
@@ -610,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);
msm_memory_pool_free(inst, stats);
call_mem_op(core, pool_free, inst, stats);
}
} else if (buf->type == MSM_VIDC_BUF_OUTPUT) {
/* skip - ebd not arrived(single input - multiple output case) */
@@ -627,7 +631,7 @@ int msm_vidc_remove_buffer_stats(struct msm_vidc_inst *inst,
print_buffer_stats(VIDC_STAT, "stat", inst, stats);
msm_memory_pool_free(inst, stats);
call_mem_op(core, pool_free, inst, stats);
}
}
}
@@ -638,16 +642,18 @@ int msm_vidc_remove_buffer_stats(struct msm_vidc_inst *inst,
int msm_vidc_flush_buffer_stats(struct msm_vidc_inst *inst)
{
struct msm_vidc_buffer_stats *stats, *dummy_stats;
struct msm_vidc_core *core;
if (!inst) {
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
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);
msm_memory_pool_free(inst, stats);
call_mem_op(core, pool_free, inst, stats);
}
/* reset initial ts as well to avoid huge delta */
@@ -1042,88 +1048,6 @@ int v4l2_type_to_driver_port(struct msm_vidc_inst *inst, u32 type,
return port;
}
u32 msm_vidc_get_buffer_region(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type, const char *func)
{
u32 region = MSM_VIDC_NON_SECURE;
if (!is_secure_session(inst)) {
switch (buffer_type) {
case MSM_VIDC_BUF_ARP:
region = MSM_VIDC_SECURE_NONPIXEL;
break;
case MSM_VIDC_BUF_INPUT:
if (is_encode_session(inst))
region = MSM_VIDC_NON_SECURE_PIXEL;
else
region = MSM_VIDC_NON_SECURE;
break;
case MSM_VIDC_BUF_OUTPUT:
if (is_encode_session(inst))
region = MSM_VIDC_NON_SECURE;
else
region = MSM_VIDC_NON_SECURE_PIXEL;
break;
case MSM_VIDC_BUF_DPB:
case MSM_VIDC_BUF_VPSS:
case MSM_VIDC_BUF_PARTIAL_DATA:
region = MSM_VIDC_NON_SECURE_PIXEL;
break;
case MSM_VIDC_BUF_INPUT_META:
case MSM_VIDC_BUF_OUTPUT_META:
case MSM_VIDC_BUF_BIN:
case MSM_VIDC_BUF_COMV:
case MSM_VIDC_BUF_NON_COMV:
case MSM_VIDC_BUF_LINE:
case MSM_VIDC_BUF_PERSIST:
region = MSM_VIDC_NON_SECURE;
break;
default:
i_vpr_e(inst, "%s: invalid driver buffer type %d\n",
func, buffer_type);
}
} else {
switch (buffer_type) {
case MSM_VIDC_BUF_INPUT:
if (is_encode_session(inst))
region = MSM_VIDC_SECURE_PIXEL;
else
region = MSM_VIDC_SECURE_BITSTREAM;
break;
case MSM_VIDC_BUF_OUTPUT:
if (is_encode_session(inst))
region = MSM_VIDC_SECURE_BITSTREAM;
else
region = MSM_VIDC_SECURE_PIXEL;
break;
case MSM_VIDC_BUF_INPUT_META:
case MSM_VIDC_BUF_OUTPUT_META:
region = MSM_VIDC_NON_SECURE;
break;
case MSM_VIDC_BUF_DPB:
case MSM_VIDC_BUF_VPSS:
case MSM_VIDC_BUF_PARTIAL_DATA:
region = MSM_VIDC_SECURE_PIXEL;
break;
case MSM_VIDC_BUF_BIN:
region = MSM_VIDC_SECURE_BITSTREAM;
break;
case MSM_VIDC_BUF_ARP:
case MSM_VIDC_BUF_COMV:
case MSM_VIDC_BUF_NON_COMV:
case MSM_VIDC_BUF_LINE:
case MSM_VIDC_BUF_PERSIST:
region = MSM_VIDC_SECURE_NONPIXEL;
break;
default:
i_vpr_e(inst, "%s: invalid driver buffer type %d\n",
func, buffer_type);
}
}
return region;
}
struct msm_vidc_buffers *msm_vidc_get_buffers(
struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buffer_type,
const char *func)
@@ -2490,11 +2414,13 @@ int msm_vidc_process_readonly_buffers(struct msm_vidc_inst *inst,
{
int rc = 0;
struct msm_vidc_buffer *ro_buf, *dummy;
struct msm_vidc_core *core;
if (!inst || !buf) {
if (!inst || !inst->core || !buf) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
if (!is_decode_session(inst) || !is_output_buffer(buf->type))
return 0;
@@ -2529,19 +2455,21 @@ int msm_vidc_process_readonly_buffers(struct msm_vidc_inst *inst,
print_vidc_buffer(VIDC_LOW, "low ", "ro buf removed", inst, ro_buf);
/* unmap the buffer if driver holds mapping */
if (ro_buf->sg_table && ro_buf->attach) {
msm_vidc_dma_buf_unmap_attachment(ro_buf->attach, ro_buf->sg_table);
msm_vidc_dma_buf_detach(ro_buf->dmabuf, ro_buf->attach);
call_mem_op(core, dma_buf_unmap_attachment, core,
ro_buf->attach, ro_buf->sg_table);
call_mem_op(core, dma_buf_detach, core,
ro_buf->dmabuf, ro_buf->attach);
ro_buf->dmabuf = NULL;
ro_buf->attach = NULL;
}
if (ro_buf->dbuf_get) {
msm_vidc_memory_put_dmabuf(inst, ro_buf->dmabuf);
call_mem_op(core, dma_buf_put, inst, ro_buf->dmabuf);
ro_buf->dmabuf = NULL;
ro_buf->dbuf_get = 0;
}
list_del_init(&ro_buf->list);
msm_memory_pool_free(inst, ro_buf);
call_mem_op(core, pool_free, inst, ro_buf);
}
return rc;
@@ -2613,15 +2541,17 @@ int msm_vidc_update_input_rate(struct msm_vidc_inst *inst, u64 time_us)
{
struct msm_vidc_input_timer *input_timer;
struct msm_vidc_input_timer *prev_timer = NULL;
struct msm_vidc_core *core;
u64 counter = 0;
u64 input_timer_sum_us = 0;
if (!inst || !inst->capabilities) {
if (!inst || !inst->core || !inst->capabilities) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
input_timer = msm_memory_pool_alloc(inst, MSM_MEM_POOL_BUF_TIMER);
input_timer = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_BUF_TIMER);
if (!input_timer)
return -ENOMEM;
@@ -2646,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);
msm_memory_pool_free(inst, input_timer);
call_mem_op(core, pool_free, inst, input_timer);
}
return 0;
@@ -2655,16 +2585,18 @@ int msm_vidc_update_input_rate(struct msm_vidc_inst *inst, u64 time_us)
int msm_vidc_flush_input_timer(struct msm_vidc_inst *inst)
{
struct msm_vidc_input_timer *input_timer, *dummy_timer;
struct msm_vidc_core *core;
if (!inst || !inst->capabilities) {
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
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);
msm_memory_pool_free(inst, input_timer);
call_mem_op(core, pool_free, inst, input_timer);
}
return 0;
}
@@ -2771,17 +2703,19 @@ static struct msm_vidc_timestamp *msm_vidc_get_least_rank_ts(struct msm_vidc_ins
int msm_vidc_flush_ts(struct msm_vidc_inst *inst)
{
struct msm_vidc_timestamp *temp, *ts = NULL;
struct msm_vidc_core *core;
if (!inst) {
d_vpr_e("%s: Invalid params\n", __func__);
if (!inst || !inst->core ) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
list_for_each_entry_safe(ts, temp, &inst->timestamps.list, sort.list) {
i_vpr_l(inst, "%s: flushing ts: val %llu, rank %llu\n",
__func__, ts->sort.val, ts->rank);
list_del(&ts->sort.list);
msm_memory_pool_free(inst, ts);
call_mem_op(core, pool_free, inst, ts);
}
inst->timestamps.count = 0;
inst->timestamps.rank = 0;
@@ -2792,18 +2726,20 @@ int msm_vidc_flush_ts(struct msm_vidc_inst *inst)
int msm_vidc_update_timestamp_rate(struct msm_vidc_inst *inst, u64 timestamp)
{
struct msm_vidc_timestamp *ts, *prev = NULL;
struct msm_vidc_core *core;
int rc = 0;
u32 window_size = 0;
u32 timestamp_rate = 0;
u64 ts_ms = 0;
u32 counter = 0;
if (!inst) {
d_vpr_e("%s: Invalid params\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
ts = msm_memory_pool_alloc(inst, MSM_MEM_POOL_TIMESTAMP);
ts = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_TIMESTAMP);
if (!ts) {
i_vpr_e(inst, "%s: ts alloc failed\n", __func__);
return -ENOMEM;
@@ -2831,7 +2767,7 @@ int msm_vidc_update_timestamp_rate(struct msm_vidc_inst *inst, u64 timestamp)
}
inst->timestamps.count--;
list_del(&ts->sort.list);
msm_memory_pool_free(inst, ts);
call_mem_op(core, pool_free, inst, ts);
}
/* Calculate timestamp rate */
@@ -2855,15 +2791,17 @@ int msm_vidc_update_timestamp_rate(struct msm_vidc_inst *inst, u64 timestamp)
int msm_vidc_ts_reorder_insert_timestamp(struct msm_vidc_inst *inst, u64 timestamp)
{
struct msm_vidc_timestamp *ts;
struct msm_vidc_core *core;
int rc = 0;
if (!inst) {
d_vpr_e("%s: Invalid params\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
/* allocate ts from pool */
ts = msm_memory_pool_alloc(inst, MSM_MEM_POOL_TIMESTAMP);
ts = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_TIMESTAMP);
if (!ts) {
i_vpr_e(inst, "%s: ts alloc failed\n", __func__);
return -ENOMEM;
@@ -2883,18 +2821,20 @@ int msm_vidc_ts_reorder_insert_timestamp(struct msm_vidc_inst *inst, u64 timesta
int msm_vidc_ts_reorder_remove_timestamp(struct msm_vidc_inst *inst, u64 timestamp)
{
struct msm_vidc_timestamp *ts, *temp;
struct msm_vidc_core *core;
if (!inst) {
d_vpr_e("%s: Invalid params\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
/* remove matching node */
list_for_each_entry_safe(ts, temp, &inst->ts_reorder.list, sort.list) {
if (ts->sort.val == timestamp) {
list_del_init(&ts->sort.list);
inst->ts_reorder.count--;
msm_memory_pool_free(inst, ts);
call_mem_op(core, pool_free, inst, ts);
break;
}
}
@@ -2905,11 +2845,13 @@ int msm_vidc_ts_reorder_remove_timestamp(struct msm_vidc_inst *inst, u64 timesta
int msm_vidc_ts_reorder_get_first_timestamp(struct msm_vidc_inst *inst, u64 *timestamp)
{
struct msm_vidc_timestamp *ts;
struct msm_vidc_core *core;
if (!inst || !timestamp) {
if (!inst || !inst->core || !timestamp) {
d_vpr_e("%s: Invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
/* check if list empty */
if (list_empty(&inst->ts_reorder.list)) {
@@ -2926,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--;
msm_memory_pool_free(inst, ts);
call_mem_op(core, pool_free, inst, ts);
return 0;
}
@@ -2934,17 +2876,19 @@ int msm_vidc_ts_reorder_get_first_timestamp(struct msm_vidc_inst *inst, u64 *tim
int msm_vidc_ts_reorder_flush(struct msm_vidc_inst *inst)
{
struct msm_vidc_timestamp *temp, *ts = NULL;
struct msm_vidc_core *core;
if (!inst) {
if (!inst || !inst->core) {
d_vpr_e("%s: Invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
/* flush all entries */
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);
msm_memory_pool_free(inst, ts);
call_mem_op(core, pool_free, inst, ts);
}
inst->ts_reorder.count = 0;
@@ -2956,11 +2900,13 @@ struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst,
{
int rc = 0;
struct msm_vidc_buffer *buf;
struct msm_vidc_core *core;
if (!inst || !vb2) {
d_vpr_e("%s: invalid params\n", __func__);
if (!inst || !inst->core || !vb2) {
d_vpr_e("%s: Invalid params\n", __func__);
return NULL;
}
core = inst->core;
buf = msm_vidc_fetch_buffer(inst, vb2);
if (!buf) {
@@ -2978,7 +2924,7 @@ struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst,
if (is_decode_session(inst) && is_output_buffer(buf->type)) {
/* get a reference */
if (!buf->dbuf_get) {
buf->dmabuf = msm_vidc_memory_get_dmabuf(inst, buf->fd);
buf->dmabuf = call_mem_op(core, dma_buf_get, inst, buf->fd);
if (!buf->dmabuf)
return NULL;
buf->dbuf_get = 1;
@@ -2998,18 +2944,20 @@ int msm_vidc_allocate_buffers(struct msm_vidc_inst *inst,
int idx = 0;
struct msm_vidc_buffer *buf = NULL;
struct msm_vidc_buffers *buffers;
struct msm_vidc_core *core;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: Invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
buffers = msm_vidc_get_buffers(inst, buf_type, __func__);
if (!buffers)
return -EINVAL;
for (idx = 0; idx < num_buffers; idx++) {
buf = msm_memory_pool_alloc(inst, MSM_MEM_POOL_BUFFER);
buf = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_BUFFER);
if (!buf) {
i_vpr_e(inst, "%s: alloc failed\n", __func__);
return -EINVAL;
@@ -3032,11 +2980,13 @@ int msm_vidc_free_buffers(struct msm_vidc_inst *inst,
int buf_count = 0;
struct msm_vidc_buffer *buf, *dummy;
struct msm_vidc_buffers *buffers;
struct msm_vidc_core *core;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: Invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
buffers = msm_vidc_get_buffers(inst, buf_type, __func__);
if (!buffers)
@@ -3046,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);
msm_memory_pool_free(inst, buf);
call_mem_op(core, pool_free, inst, buf);
}
i_vpr_h(inst, "%s: freed %d buffers for type %s\n",
__func__, buf_count, buf_name(buf_type));
@@ -3650,11 +3600,13 @@ int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
struct msm_vidc_alloc *alloc, *alloc_dummy;
struct msm_vidc_map *map, *map_dummy;
struct msm_vidc_buffer *buf, *dummy;
struct msm_vidc_core *core;
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
if (!is_internal_buffer(buffer->type)) {
i_vpr_e(inst, "%s: type: %s is not internal\n",
@@ -3677,18 +3629,18 @@ int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
list_for_each_entry_safe(map, map_dummy, &mappings->list, list) {
if (map->dmabuf == buffer->dmabuf) {
msm_vidc_memory_unmap(inst->core, map);
call_mem_op(core, memory_unmap, core, map);
list_del(&map->list);
msm_memory_pool_free(inst, map);
call_mem_op(core, pool_free, inst, map);
break;
}
}
list_for_each_entry_safe(alloc, alloc_dummy, &allocations->list, list) {
if (alloc->dmabuf == buffer->dmabuf) {
msm_vidc_memory_free(inst->core, alloc);
call_mem_op(core, memory_free, core, alloc);
list_del(&alloc->list);
msm_memory_pool_free(inst, alloc);
call_mem_op(core, pool_free, inst, alloc);
break;
}
}
@@ -3696,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);
msm_memory_pool_free(inst, buf);
call_mem_op(core, pool_free, inst, buf);
break;
}
}
@@ -3752,11 +3704,13 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
struct msm_vidc_buffer *buffer;
struct msm_vidc_alloc *alloc;
struct msm_vidc_map *map;
struct msm_vidc_core *core;
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
if (!is_internal_buffer(buffer_type)) {
i_vpr_e(inst, "%s: type %s is not internal\n",
__func__, buf_name(buffer_type));
@@ -3776,7 +3730,7 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
if (!buffers->size)
return 0;
buffer = msm_memory_pool_alloc(inst, MSM_MEM_POOL_BUFFER);
buffer = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_BUFFER);
if (!buffer) {
i_vpr_e(inst, "%s: buf alloc failed\n", __func__);
return -ENOMEM;
@@ -3787,23 +3741,22 @@ 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_memory_pool_alloc(inst, MSM_MEM_POOL_ALLOC);
alloc = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_ALLOC);
if (!alloc) {
i_vpr_e(inst, "%s: alloc failed\n", __func__);
return -ENOMEM;
}
INIT_LIST_HEAD(&alloc->list);
alloc->type = buffer_type;
alloc->region = msm_vidc_get_buffer_region(inst,
buffer_type, __func__);
alloc->region = call_mem_op(core, buffer_region, inst, buffer_type);
alloc->size = buffer->buffer_size;
alloc->secure = is_secure_region(alloc->region);
rc = msm_vidc_memory_alloc(inst->core, alloc);
rc = call_mem_op(core, memory_alloc, core, alloc);
if (rc)
return -ENOMEM;
list_add_tail(&alloc->list, &allocations->list);
map = msm_memory_pool_alloc(inst, MSM_MEM_POOL_MAP);
map = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_MAP);
if (!map) {
i_vpr_e(inst, "%s: map alloc failed\n", __func__);
return -ENOMEM;
@@ -3812,7 +3765,7 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
map->type = alloc->type;
map->region = alloc->region;
map->dmabuf = alloc->dmabuf;
rc = msm_vidc_memory_map(inst->core, map);
rc = call_mem_op(core, memory_map, core, map);
if (rc)
return -ENOMEM;
list_add_tail(&map->list, &mappings->list);
@@ -5408,15 +5361,17 @@ int msm_vidc_flush_buffers(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type type)
{
int rc = 0;
struct msm_vidc_core *core;
struct msm_vidc_buffers *buffers;
struct msm_vidc_buffer *buf, *dummy;
enum msm_vidc_buffer_type buffer_type[2];
int i;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: Invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
if (type == MSM_VIDC_BUF_INPUT) {
buffer_type[0] = MSM_VIDC_BUF_INPUT_META;
@@ -5442,7 +5397,7 @@ int msm_vidc_flush_buffers(struct msm_vidc_inst *inst,
if (!(buf->attr & MSM_VIDC_ATTR_BUFFER_DONE)) {
if (is_decode_session(inst) && is_output_buffer(buf->type)) {
if (buf->dbuf_get) {
msm_vidc_memory_put_dmabuf(inst, buf->dmabuf);
call_mem_op(core, dma_buf_put, inst, buf->dmabuf);
buf->dbuf_get = 0;
}
}
@@ -5461,11 +5416,13 @@ int msm_vidc_flush_read_only_buffers(struct msm_vidc_inst *inst,
{
int rc = 0;
struct msm_vidc_buffer *ro_buf, *dummy;
struct msm_vidc_core *core;
if (!inst) {
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
if (!is_decode_session(inst) || !is_output_buffer(type))
return 0;
@@ -5475,18 +5432,20 @@ int msm_vidc_flush_read_only_buffers(struct msm_vidc_inst *inst,
continue;
print_vidc_buffer(VIDC_ERR, "high", "flush ro buf", inst, ro_buf);
if (ro_buf->attach && ro_buf->sg_table)
msm_vidc_dma_buf_unmap_attachment(ro_buf->attach, ro_buf->sg_table);
call_mem_op(core, dma_buf_unmap_attachment, core,
ro_buf->attach, ro_buf->sg_table);
if (ro_buf->attach && ro_buf->dmabuf)
msm_vidc_dma_buf_detach(ro_buf->dmabuf, ro_buf->attach);
call_mem_op(core, dma_buf_detach, core,
ro_buf->dmabuf, ro_buf->attach);
if (ro_buf->dbuf_get)
msm_vidc_memory_put_dmabuf(inst, ro_buf->dmabuf);
call_mem_op(core, dma_buf_put, inst, ro_buf->dmabuf);
ro_buf->attach = NULL;
ro_buf->sg_table = NULL;
ro_buf->dmabuf = NULL;
ro_buf->dbuf_get = 0;
ro_buf->device_addr = 0x0;
list_del_init(&ro_buf->list);
msm_memory_pool_free(inst, ro_buf);
call_mem_op(core, pool_free, inst, ro_buf);
}
return rc;
@@ -5502,6 +5461,7 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
struct msm_vidc_buffer_stats *stats, *dummy_stats;
struct msm_vidc_inst_cap_entry *entry, *dummy_entry;
struct msm_vidc_fence *fence, *dummy_fence;
struct msm_vidc_core *core;
static const enum msm_vidc_buffer_type ext_buf_types[] = {
MSM_VIDC_BUF_INPUT,
@@ -5522,10 +5482,11 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
};
int i;
if (!inst) {
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return;
}
core = inst->core;
for (i = 0; i < ARRAY_SIZE(internal_buf_types); i++) {
buffers = msm_vidc_get_buffers(inst, internal_buf_types[i], __func__);
@@ -5547,13 +5508,14 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
list_for_each_entry_safe(buf, dummy, &inst->buffers.read_only.list, list) {
print_vidc_buffer(VIDC_ERR, "err ", "destroying ro buf", inst, buf);
if (buf->attach && buf->sg_table)
msm_vidc_dma_buf_unmap_attachment(buf->attach, buf->sg_table);
call_mem_op(core, dma_buf_unmap_attachment, core,
buf->attach, buf->sg_table);
if (buf->attach && buf->dmabuf)
msm_vidc_dma_buf_detach(buf->dmabuf, buf->attach);
call_mem_op(core, dma_buf_detach, core, buf->dmabuf, buf->attach);
if (buf->dbuf_get)
msm_vidc_memory_put_dmabuf(inst, buf->dmabuf);
call_mem_op(core, dma_buf_put, inst, buf->dmabuf);
list_del_init(&buf->list);
msm_memory_pool_free(inst, buf);
call_mem_op(core, pool_free, inst, buf);
}
for (i = 0; i < ARRAY_SIZE(ext_buf_types); i++) {
@@ -5563,15 +5525,16 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
list_for_each_entry_safe(buf, dummy, &buffers->list, list) {
if (buf->attach && buf->sg_table)
msm_vidc_dma_buf_unmap_attachment(buf->attach, buf->sg_table);
call_mem_op(core, dma_buf_unmap_attachment, core,
buf->attach, buf->sg_table);
if (buf->attach && buf->dmabuf)
msm_vidc_dma_buf_detach(buf->dmabuf, buf->attach);
call_mem_op(core, dma_buf_detach, core, buf->dmabuf, buf->attach);
if (buf->dbuf_get) {
print_vidc_buffer(VIDC_ERR, "err ", "destroying: put dmabuf", inst, buf);
msm_vidc_memory_put_dmabuf(inst, buf->dmabuf);
call_mem_op(core, dma_buf_put, inst, buf->dmabuf);
}
list_del_init(&buf->list);
msm_memory_pool_free(inst, buf);
call_mem_op(core, pool_free, inst, buf);
}
}
@@ -5579,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);
msm_memory_pool_free(inst, ts);
call_mem_op(core, 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);
msm_memory_pool_free(inst, ts);
call_mem_op(core, 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);
msm_memory_pool_free(inst, timer);
call_mem_op(core, 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);
msm_memory_pool_free(inst, stats);
call_mem_op(core, pool_free, inst, stats);
}
list_for_each_entry_safe(dbuf, dummy_dbuf, &inst->dmabuf_tracker, list) {
@@ -5616,7 +5579,7 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
}
i_vpr_e(inst, "%s: removing dma_buf %#lx, inode %lu, refcount %u\n",
__func__, dbuf->dmabuf, inode_num, dbuf->refcount);
msm_vidc_memory_put_dmabuf_completely(inst, dbuf);
call_mem_op(core, dma_buf_put_completely, inst, dbuf);
}
list_for_each_entry_safe(entry, dummy_entry, &inst->firmware_list, list) {
@@ -5642,7 +5605,7 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
}
/* destroy buffers from pool */
msm_memory_pools_deinit(inst);
call_mem_op(core, pools_deinit, inst);
}
static void msm_vidc_close_helper(struct kref *kref)
@@ -6647,3 +6610,47 @@ int msm_vidc_get_properties(struct msm_vidc_inst *inst)
return 0;
}
struct context_bank_info *msm_vidc_get_context_bank_for_region(
struct msm_vidc_core *core, enum msm_vidc_buffer_region region)
{
struct context_bank_info *cb = NULL, *match = NULL;
if (!region || region >= MSM_VIDC_REGION_MAX) {
d_vpr_e("Invalid region %#x\n", region);
return NULL;
}
venus_hfi_for_each_context_bank(core, cb) {
if (cb->region == region) {
match = cb;
break;
}
}
if (!match)
d_vpr_e("cb not found for region %#x\n", region);
return match;
}
struct context_bank_info *msm_vidc_get_context_bank_for_device(
struct msm_vidc_core *core, struct device *dev)
{
struct context_bank_info *cb = NULL, *match = NULL;
if (!core || !dev) {
d_vpr_e("%s: invalid params\n", __func__);
return NULL;
}
venus_hfi_for_each_context_bank(core, cb) {
if (of_device_is_compatible(dev->of_node, cb->name)) {
match = cb;
break;
}
}
if (!match)
d_vpr_e("cb not found for dev %s\n", dev_name(dev));
return match;
}

Melihat File

@@ -23,34 +23,7 @@
MODULE_IMPORT_NS(DMA_BUF);
#endif
struct msm_vidc_buf_region_name {
enum msm_vidc_buffer_region region;
char *name;
};
struct context_bank_info *msm_vidc_get_context_bank(struct msm_vidc_core *core,
enum msm_vidc_buffer_region region)
{
struct context_bank_info *cb = NULL, *match = NULL;
if (!region || region >= MSM_VIDC_REGION_MAX) {
d_vpr_e("Invalid region %#x\n", region);
return NULL;
}
venus_hfi_for_each_context_bank(core, cb) {
if (cb->region == region) {
match = cb;
break;
}
}
if (!match)
d_vpr_e("cb not found for region %#x\n", region);
return match;
}
struct dma_buf *msm_vidc_memory_get_dmabuf(struct msm_vidc_inst *inst, int fd)
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;
@@ -84,7 +57,7 @@ struct dma_buf *msm_vidc_memory_get_dmabuf(struct msm_vidc_inst *inst, int fd)
}
/* get tracker instance from pool */
buf = msm_memory_pool_alloc(inst, MSM_MEM_POOL_DMABUF);
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);
@@ -101,7 +74,7 @@ struct dma_buf *msm_vidc_memory_get_dmabuf(struct msm_vidc_inst *inst, int fd)
return dmabuf;
}
void msm_vidc_memory_put_dmabuf(struct msm_vidc_inst *inst, struct dma_buf *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;
@@ -135,10 +108,10 @@ void msm_vidc_memory_put_dmabuf(struct msm_vidc_inst *inst, struct dma_buf *dmab
dma_buf_put(buf->dmabuf);
/* put tracker instance back to pool */
msm_memory_pool_free(inst, buf);
msm_vidc_pool_free(inst, buf);
}
void msm_vidc_memory_put_dmabuf_completely(struct msm_vidc_inst *inst,
void msm_vidc_dma_buf_put_completely(struct msm_vidc_inst *inst,
struct msm_memory_dmabuf *buf)
{
if (!inst || !buf) {
@@ -156,17 +129,12 @@ void msm_vidc_memory_put_dmabuf_completely(struct msm_vidc_inst *inst,
dma_buf_put(buf->dmabuf);
/* put tracker instance back to pool */
msm_memory_pool_free(inst, buf);
msm_vidc_pool_free(inst, buf);
break;
}
}
}
static bool is_non_secure_buffer(struct dma_buf *dmabuf)
{
return mem_buf_dma_buf_exclusive_owner(dmabuf);
}
int msm_vidc_memory_map(struct msm_vidc_core *core, struct msm_vidc_map *map)
{
int rc = 0;
@@ -184,22 +152,7 @@ int msm_vidc_memory_map(struct msm_vidc_core *core, struct msm_vidc_map *map)
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)) {
d_vpr_e("%s: secure buffer mapping to non-secure region %d not allowed\n",
__func__, map->region);
return -EINVAL;
}
} else {
if (is_non_secure_buffer(map->dmabuf)) {
d_vpr_e("%s: non-secure buffer mapping to secure region %d not allowed\n",
__func__, map->region);
return -EINVAL;
}
}
cb = msm_vidc_get_context_bank(core, map->region);
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__);
@@ -208,41 +161,19 @@ int msm_vidc_memory_map(struct msm_vidc_core *core, struct msm_vidc_map *map)
}
/* Prepare a dma buf for dma on the given device */
attach = dma_buf_attach(map->dmabuf, cb->dev);
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;
}
/*
* Get the scatterlist for the given attachment
* Mapping of sg is taken care by map attachment
*/
attach->dma_map_attrs |= DMA_ATTR_DELAYED_UNMAP;
/*
* We do not need dma_map function to perform cache operations
* on the whole buffer size and hence pass skip sync flag.
* We do the required cache operations separately for the
* required buffer size
*/
attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;
if (is_sys_cache_present(core))
attach->dma_map_attrs |=
DMA_ATTR_IOMMU_USE_UPSTREAM_HINT;
table = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
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;
}
if (!table->sgl) {
d_vpr_e("sgl is NULL\n");
rc = -ENOMEM;
goto error_sg;
}
map->device_addr = table->sgl->dma_address;
map->table = table;
@@ -256,10 +187,8 @@ exit:
return 0;
error_sg:
dma_buf_unmap_attachment(attach, table, DMA_BIDIRECTIONAL);
error_table:
dma_buf_detach(map->dmabuf, attach);
msm_vidc_dma_buf_detach(core, map->dmabuf, attach);
error_attach:
error_cb:
return rc;
@@ -289,8 +218,8 @@ int msm_vidc_memory_unmap(struct msm_vidc_core *core,
if (map->refcount)
goto exit;
dma_buf_unmap_attachment(map->attach, map->table, DMA_BIDIRECTIONAL);
dma_buf_detach(map->dmabuf, map->attach);
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;
@@ -300,13 +229,13 @@ exit:
return rc;
}
struct dma_buf_attachment *msm_vidc_dma_buf_attach(struct dma_buf *dbuf,
struct device *dev)
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 (!dbuf || !dev) {
if (!core || !dbuf || !dev) {
d_vpr_e("%s: invalid params\n", __func__);
return NULL;
}
@@ -318,11 +247,17 @@ struct dma_buf_attachment *msm_vidc_dma_buf_attach(struct dma_buf *dbuf,
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 dma_buf *dbuf,
struct dma_buf_attachment *attach)
int msm_vidc_dma_buf_detach(struct msm_vidc_core *core,
struct dma_buf *dbuf, struct dma_buf_attachment *attach)
{
int rc = 0;
@@ -337,7 +272,7 @@ int msm_vidc_dma_buf_detach(struct dma_buf *dbuf,
}
struct sg_table *msm_vidc_dma_buf_map_attachment(
struct dma_buf_attachment *attach)
struct msm_vidc_core *core, struct dma_buf_attachment *attach)
{
int rc = 0;
struct sg_table *table = NULL;
@@ -353,12 +288,17 @@ struct sg_table *msm_vidc_dma_buf_map_attachment(
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 dma_buf_attachment *attach,
struct sg_table *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;
@@ -399,150 +339,17 @@ void msm_vidc_vmem_free(void **addr)
int msm_vidc_memory_alloc(struct msm_vidc_core *core, struct msm_vidc_alloc *mem)
{
int rc = 0;
int size = 0;
struct dma_heap *heap;
char *heap_name = NULL;
struct mem_buf_lend_kernel_arg lend_arg;
int vmids[1];
int perms[1];
if (!mem) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
size = ALIGN(mem->size, SZ_4K);
if (mem->secure) {
switch (mem->region) {
case MSM_VIDC_SECURE_PIXEL:
heap_name = "qcom,secure-pixel";
break;
case MSM_VIDC_SECURE_NONPIXEL:
heap_name = "qcom,secure-non-pixel";
break;
case MSM_VIDC_SECURE_BITSTREAM:
heap_name = "qcom,system";
break;
default:
d_vpr_e("invalid secure region : %#x\n", mem->region);
return -EINVAL;
}
} else {
heap_name = "qcom,system";
}
heap = dma_heap_find(heap_name);
mem->dmabuf = dma_heap_buffer_alloc(heap, size, 0, 0);
if (IS_ERR_OR_NULL(mem->dmabuf)) {
d_vpr_e("%s: dma heap %s alloc failed\n", __func__, heap_name);
mem->dmabuf = NULL;
rc = -ENOMEM;
goto error;
}
if (mem->secure && mem->type == MSM_VIDC_BUF_BIN)
{
vmids[0] = VMID_CP_BITSTREAM;
perms[0] = PERM_READ | PERM_WRITE;
lend_arg.nr_acl_entries = ARRAY_SIZE(vmids);
lend_arg.vmids = vmids;
lend_arg.perms = perms;
rc = mem_buf_lend(mem->dmabuf, &lend_arg);
if (rc) {
d_vpr_e("%s: BIN dmabuf %pK LEND failed, rc %d heap %s\n",
__func__, mem->dmabuf, rc, heap_name);
goto error;
}
}
if (mem->map_kernel) {
dma_buf_begin_cpu_access(mem->dmabuf, DMA_BIDIRECTIONAL);
/*
* Waipio uses Kernel version 5.10.x,
* Kalama uses Kernel Version 5.15.x,
* Pineapple uses Kernel Version 5.18.x
*/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0))
mem->kvaddr = dma_buf_vmap(mem->dmabuf);
if (!mem->kvaddr) {
d_vpr_e("%s: kernel map failed\n", __func__);
rc = -EIO;
goto error;
}
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(5,16,0))
rc = dma_buf_vmap(mem->dmabuf, &mem->dmabuf_map);
if (rc) {
d_vpr_e("%s: kernel map failed\n", __func__);
rc = -EIO;
goto error;
}
mem->kvaddr = mem->dmabuf_map.vaddr;
#else
rc = dma_buf_vmap(mem->dmabuf, &mem->dmabuf_map);
if (rc) {
d_vpr_e("%s: kernel map failed\n", __func__);
rc = -EIO;
goto error;
}
mem->kvaddr = mem->dmabuf_map.vaddr;
#endif
}
d_vpr_h(
"%s: dmabuf %pK, size %d, kvaddr %pK, buffer_type %s, secure %d, region %d\n",
__func__, mem->dmabuf, mem->size, mem->kvaddr, buf_name(mem->type),
mem->secure, mem->region);
trace_msm_vidc_dma_buffer("ALLOC", mem->dmabuf, mem->size, mem->kvaddr,
buf_name(mem->type), mem->secure, mem->region);
return 0;
error:
msm_vidc_memory_free(core, mem);
return rc;
d_vpr_e("%s: unsupported\n", __func__);
return -EINVAL;
}
int msm_vidc_memory_free(struct msm_vidc_core *core, struct msm_vidc_alloc *mem)
{
int rc = 0;
d_vpr_e("%s: unsupported\n", __func__);
return -EINVAL;
}
if (!mem || !mem->dmabuf) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
d_vpr_h(
"%s: dmabuf %pK, size %d, kvaddr %pK, buffer_type %s, secure %d, region %d\n",
__func__, mem->dmabuf, mem->size, mem->kvaddr, buf_name(mem->type),
mem->secure, mem->region);
trace_msm_vidc_dma_buffer("FREE", mem->dmabuf, mem->size, mem->kvaddr,
buf_name(mem->type), mem->secure, mem->region);
if (mem->kvaddr) {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0))
dma_buf_vunmap(mem->dmabuf, mem->kvaddr);
#else
dma_buf_vunmap(mem->dmabuf, &mem->dmabuf_map);
#endif
mem->kvaddr = NULL;
dma_buf_end_cpu_access(mem->dmabuf, DMA_BIDIRECTIONAL);
}
if (mem->dmabuf) {
dma_heap_buffer_free(mem->dmabuf);
mem->dmabuf = NULL;
}
return rc;
};
void *msm_memory_pool_alloc(struct msm_vidc_inst *inst, enum msm_memory_pool_type type)
void *msm_vidc_pool_alloc(struct msm_vidc_inst *inst, enum msm_memory_pool_type type)
{
struct msm_memory_alloc_header *hdr = NULL;
struct msm_memory_pool *pool;
@@ -584,7 +391,7 @@ void *msm_memory_pool_alloc(struct msm_vidc_inst *inst, enum msm_memory_pool_typ
return hdr->buf;
}
void msm_memory_pool_free(struct msm_vidc_inst *inst, void *vidc_buf)
void msm_vidc_pool_free(struct msm_vidc_inst *inst, void *vidc_buf)
{
struct msm_memory_alloc_header *hdr;
struct msm_memory_pool *pool;
@@ -659,7 +466,7 @@ static void msm_vidc_destroy_pool_buffers(struct msm_vidc_inst *inst,
__func__, pool->name, fcount, bcount);
}
void msm_memory_pools_deinit(struct msm_vidc_inst *inst)
void msm_vidc_pools_deinit(struct msm_vidc_inst *inst)
{
u32 i = 0;
@@ -691,7 +498,7 @@ static const struct msm_vidc_type_size_name buftype_size_name_arr[] = {
{MSM_MEM_POOL_BUF_STATS, sizeof(struct msm_vidc_buffer_stats), "MSM_MEM_POOL_BUF_STATS"},
};
int msm_memory_pools_init(struct msm_vidc_inst *inst)
int msm_vidc_pools_init(struct msm_vidc_inst *inst)
{
u32 i;
@@ -721,129 +528,8 @@ int msm_memory_pools_init(struct msm_vidc_inst *inst)
return 0;
}
/*
int msm_memory_cache_operations(struct msm_vidc_inst *inst,
struct dma_buf *dbuf, enum smem_cache_ops cache_op,
unsigned long offset, unsigned long size, u32 sid)
u32 msm_vidc_buffer_region(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type)
{
int rc = 0;
unsigned long flags = 0;
if (!inst) {
d_vpr_e("%s: invalid parameters\n", __func__);
return -EINVAL;
}
if (!dbuf) {
i_vpr_e(inst, "%s: invalid params\n", __func__);
return -EINVAL;
}
rc = dma_buf_get_flags(dbuf, &flags);
if (rc) {
i_vpr_e(inst, "%s: dma_buf_get_flags failed, err %d\n",
__func__, rc);
return rc;
} else if (!(flags & ION_FLAG_CACHED)) {
return rc;
}
switch (cache_op) {
case SMEM_CACHE_CLEAN:
case SMEM_CACHE_CLEAN_INVALIDATE:
rc = dma_buf_begin_cpu_access_partial(dbuf, DMA_TO_DEVICE,
offset, size);
if (rc)
break;
rc = dma_buf_end_cpu_access_partial(dbuf, DMA_TO_DEVICE,
offset, size);
break;
case SMEM_CACHE_INVALIDATE:
rc = dma_buf_begin_cpu_access_partial(dbuf, DMA_TO_DEVICE,
offset, size);
if (rc)
break;
rc = dma_buf_end_cpu_access_partial(dbuf, DMA_FROM_DEVICE,
offset, size);
break;
default:
i_vpr_e(inst, "%s: cache (%d) operation not supported\n",
__func__, cache_op);
rc = -EINVAL;
break;
}
return rc;
}
int msm_smem_memory_prefetch(struct msm_vidc_inst *inst)
{
int i, rc = 0;
struct memory_regions *vidc_regions = NULL;
struct ion_prefetch_region ion_region[MEMORY_REGIONS_MAX];
if (!inst) {
d_vpr_e("%s: invalid parameters\n", __func__);
return -EINVAL;
}
vidc_regions = &inst->regions;
if (vidc_regions->num_regions > MEMORY_REGIONS_MAX) {
i_vpr_e(inst, "%s: invalid num_regions %d, max %d\n",
__func__, vidc_regions->num_regions,
MEMORY_REGIONS_MAX);
return -EINVAL;
}
memset(ion_region, 0, sizeof(ion_region));
for (i = 0; i < vidc_regions->num_regions; i++) {
ion_region[i].size = vidc_regions->region[i].size;
ion_region[i].vmid = vidc_regions->region[i].vmid;
}
rc = msm_ion_heap_prefetch(ION_SECURE_HEAP_ID, ion_region,
vidc_regions->num_regions);
if (rc)
i_vpr_e(inst, "%s: prefetch failed, ret: %d\n",
__func__, rc);
else
i_vpr_l(inst, "%s: prefetch succeeded\n", __func__);
return rc;
}
int msm_smem_memory_drain(struct msm_vidc_inst *inst)
{
int i, rc = 0;
struct memory_regions *vidc_regions = NULL;
struct ion_prefetch_region ion_region[MEMORY_REGIONS_MAX];
if (!inst) {
d_vpr_e("%s: invalid parameters\n", __func__);
return -EINVAL;
}
vidc_regions = &inst->regions;
if (vidc_regions->num_regions > MEMORY_REGIONS_MAX) {
i_vpr_e(inst, "%s: invalid num_regions %d, max %d\n",
__func__, vidc_regions->num_regions,
MEMORY_REGIONS_MAX);
return -EINVAL;
}
memset(ion_region, 0, sizeof(ion_region));
for (i = 0; i < vidc_regions->num_regions; i++) {
ion_region[i].size = vidc_regions->region[i].size;
ion_region[i].vmid = vidc_regions->region[i].vmid;
}
rc = msm_ion_heap_drain(ION_SECURE_HEAP_ID, ion_region,
vidc_regions->num_regions);
if (rc)
i_vpr_e(inst, "%s: drain failed, ret: %d\n", __func__, rc);
else
i_vpr_l(inst, "%s: drain succeeded\n", __func__);
return rc;
}
*/
return MSM_VIDC_NON_SECURE;
}

Melihat File

@@ -0,0 +1,379 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/dma-buf.h>
#include <linux/dma-heap.h>
#include <linux/qcom-dma-mapping.h>
#include <linux/mem-buf.h>
#include <soc/qcom/secure_buffer.h>
#include "msm_vidc_core.h"
#include "msm_vidc_debug.h"
#include "msm_vidc_driver.h"
#include "msm_vidc_events.h"
#include "msm_vidc_platform.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,
struct dma_buf *dbuf, struct device *dev)
{
int rc = 0;
struct dma_buf_attachment *attach = NULL;
struct context_bank_info *cb = NULL;
if (!core || !dbuf || !dev) {
d_vpr_e("%s: invalid params\n", __func__);
return NULL;
}
cb = msm_vidc_get_context_bank_for_device(core, dev);
if (!cb) {
d_vpr_e("%s: Failed to get context bank device for %s\n",
__func__, dev_name(dev));
return NULL;
}
/* reject non-secure mapping request for a secure buffer(or vice versa) */
if (cb->region == MSM_VIDC_NON_SECURE || cb->region == MSM_VIDC_NON_SECURE_PIXEL) {
if (!is_non_secure_buffer(dbuf)) {
d_vpr_e("%s: secure buffer mapping to non-secure region %d not allowed\n",
__func__, cb->region);
return NULL;
}
} else {
if (is_non_secure_buffer(dbuf)) {
d_vpr_e("%s: non-secure buffer mapping to secure region %d not allowed\n",
__func__, cb->region);
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;
/*
* Get the scatterlist for the given attachment
* Mapping of sg is taken care by map attachment
*/
attach->dma_map_attrs |= DMA_ATTR_DELAYED_UNMAP;
if (is_sys_cache_present(core))
attach->dma_map_attrs |= DMA_ATTR_IOMMU_USE_UPSTREAM_HINT;
return attach;
}
int msm_vidc_memory_free_ext(struct msm_vidc_core *core, struct msm_vidc_alloc *mem)
{
int rc = 0;
if (!mem || !mem->dmabuf) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
d_vpr_h(
"%s: dmabuf %pK, size %d, kvaddr %pK, buffer_type %s, secure %d, region %d\n",
__func__, mem->dmabuf, mem->size, mem->kvaddr, buf_name(mem->type),
mem->secure, mem->region);
trace_msm_vidc_dma_buffer("FREE", mem->dmabuf, mem->size, mem->kvaddr,
buf_name(mem->type), mem->secure, mem->region);
if (mem->kvaddr) {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0))
dma_buf_vunmap(mem->dmabuf, mem->kvaddr);
#else
dma_buf_vunmap(mem->dmabuf, &mem->dmabuf_map);
#endif
mem->kvaddr = NULL;
dma_buf_end_cpu_access(mem->dmabuf, DMA_BIDIRECTIONAL);
}
if (mem->dmabuf) {
dma_heap_buffer_free(mem->dmabuf);
mem->dmabuf = NULL;
}
return rc;
}
int msm_vidc_memory_alloc_ext(struct msm_vidc_core *core, struct msm_vidc_alloc *mem)
{
int rc = 0;
int size = 0;
struct dma_heap *heap;
char *heap_name = NULL;
struct mem_buf_lend_kernel_arg lend_arg;
int vmids[1];
int perms[1];
if (!mem) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
size = ALIGN(mem->size, SZ_4K);
if (mem->secure) {
switch (mem->region) {
case MSM_VIDC_SECURE_PIXEL:
heap_name = "qcom,secure-pixel";
break;
case MSM_VIDC_SECURE_NONPIXEL:
heap_name = "qcom,secure-non-pixel";
break;
case MSM_VIDC_SECURE_BITSTREAM:
heap_name = "qcom,system";
break;
default:
d_vpr_e("invalid secure region : %#x\n", mem->region);
return -EINVAL;
}
} else {
heap_name = "qcom,system";
}
heap = dma_heap_find(heap_name);
mem->dmabuf = dma_heap_buffer_alloc(heap, size, 0, 0);
if (IS_ERR_OR_NULL(mem->dmabuf)) {
d_vpr_e("%s: dma heap %s alloc failed\n", __func__, heap_name);
mem->dmabuf = NULL;
rc = -ENOMEM;
goto error;
}
if (mem->secure && mem->type == MSM_VIDC_BUF_BIN)
{
vmids[0] = VMID_CP_BITSTREAM;
perms[0] = PERM_READ | PERM_WRITE;
lend_arg.nr_acl_entries = ARRAY_SIZE(vmids);
lend_arg.vmids = vmids;
lend_arg.perms = perms;
rc = mem_buf_lend(mem->dmabuf, &lend_arg);
if (rc) {
d_vpr_e("%s: BIN dmabuf %pK LEND failed, rc %d heap %s\n",
__func__, mem->dmabuf, rc, heap_name);
goto error;
}
}
if (mem->map_kernel) {
dma_buf_begin_cpu_access(mem->dmabuf, DMA_BIDIRECTIONAL);
/*
* Waipio uses Kernel version 5.10.x,
* Kalama uses Kernel Version 5.15.x,
* Pineapple uses Kernel Version 5.18.x
*/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0))
mem->kvaddr = dma_buf_vmap(mem->dmabuf);
if (!mem->kvaddr) {
d_vpr_e("%s: kernel map failed\n", __func__);
rc = -EIO;
goto error;
}
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(5,16,0))
rc = dma_buf_vmap(mem->dmabuf, &mem->dmabuf_map);
if (rc) {
d_vpr_e("%s: kernel map failed\n", __func__);
rc = -EIO;
goto error;
}
mem->kvaddr = mem->dmabuf_map.vaddr;
#else
rc = dma_buf_vmap(mem->dmabuf, &mem->dmabuf_map);
if (rc) {
d_vpr_e("%s: kernel map failed\n", __func__);
rc = -EIO;
goto error;
}
mem->kvaddr = mem->dmabuf_map.vaddr;
#endif
}
d_vpr_h(
"%s: dmabuf %pK, size %d, kvaddr %pK, buffer_type %s, secure %d, region %d\n",
__func__, mem->dmabuf, mem->size, mem->kvaddr, buf_name(mem->type),
mem->secure, mem->region);
trace_msm_vidc_dma_buffer("ALLOC", mem->dmabuf, mem->size, mem->kvaddr,
buf_name(mem->type), mem->secure, mem->region);
return 0;
error:
msm_vidc_memory_free_ext(core, mem);
return rc;
}
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;
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;
}
/* 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)) {
d_vpr_e("%s: secure buffer mapping to non-secure region %d not allowed\n",
__func__, map->region);
return -EINVAL;
}
} else {
if (is_non_secure_buffer(map->dmabuf)) {
d_vpr_e("%s: non-secure buffer mapping to secure region %d not allowed\n",
__func__, map->region);
return -EINVAL;
}
}
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_ext(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;
}
u32 msm_vidc_buffer_region_ext(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type)
{
u32 region = MSM_VIDC_NON_SECURE;
if (!is_secure_session(inst)) {
switch (buffer_type) {
case MSM_VIDC_BUF_ARP:
region = MSM_VIDC_SECURE_NONPIXEL;
break;
case MSM_VIDC_BUF_INPUT:
if (is_encode_session(inst))
region = MSM_VIDC_NON_SECURE_PIXEL;
else
region = MSM_VIDC_NON_SECURE;
break;
case MSM_VIDC_BUF_OUTPUT:
if (is_encode_session(inst))
region = MSM_VIDC_NON_SECURE;
else
region = MSM_VIDC_NON_SECURE_PIXEL;
break;
case MSM_VIDC_BUF_DPB:
case MSM_VIDC_BUF_VPSS:
case MSM_VIDC_BUF_PARTIAL_DATA:
region = MSM_VIDC_NON_SECURE_PIXEL;
break;
case MSM_VIDC_BUF_INPUT_META:
case MSM_VIDC_BUF_OUTPUT_META:
case MSM_VIDC_BUF_BIN:
case MSM_VIDC_BUF_COMV:
case MSM_VIDC_BUF_NON_COMV:
case MSM_VIDC_BUF_LINE:
case MSM_VIDC_BUF_PERSIST:
region = MSM_VIDC_NON_SECURE;
break;
default:
i_vpr_e(inst, "%s: invalid driver buffer type %d\n",
__func__, buffer_type);
}
} else {
switch (buffer_type) {
case MSM_VIDC_BUF_INPUT:
if (is_encode_session(inst))
region = MSM_VIDC_SECURE_PIXEL;
else
region = MSM_VIDC_SECURE_BITSTREAM;
break;
case MSM_VIDC_BUF_OUTPUT:
if (is_encode_session(inst))
region = MSM_VIDC_SECURE_BITSTREAM;
else
region = MSM_VIDC_SECURE_PIXEL;
break;
case MSM_VIDC_BUF_INPUT_META:
case MSM_VIDC_BUF_OUTPUT_META:
region = MSM_VIDC_NON_SECURE;
break;
case MSM_VIDC_BUF_DPB:
case MSM_VIDC_BUF_VPSS:
case MSM_VIDC_BUF_PARTIAL_DATA:
region = MSM_VIDC_SECURE_PIXEL;
break;
case MSM_VIDC_BUF_BIN:
region = MSM_VIDC_SECURE_BITSTREAM;
break;
case MSM_VIDC_BUF_ARP:
case MSM_VIDC_BUF_COMV:
case MSM_VIDC_BUF_NON_COMV:
case MSM_VIDC_BUF_LINE:
case MSM_VIDC_BUF_PERSIST:
region = MSM_VIDC_SECURE_NONPIXEL;
break;
default:
i_vpr_e(inst, "%s: invalid driver buffer type %d\n",
__func__, buffer_type);
}
}
return region;
}

Melihat File

@@ -354,28 +354,6 @@ exit:
return rc;
}
static struct context_bank_info *get_context_bank(
struct msm_vidc_core *core, struct device *dev)
{
struct context_bank_info *cb = NULL, *match = NULL;
if (!core || !dev) {
d_vpr_e("%s: invalid params\n", __func__);
return NULL;
}
venus_hfi_for_each_context_bank(core, cb) {
if (of_device_is_compatible(dev->of_node, cb->name)) {
match = cb;
break;
}
}
if (!match)
d_vpr_e("cb not found for dev %s\n", dev_name(dev));
return match;
}
static int msm_vidc_setup_context_bank(struct msm_vidc_core *core,
struct device *dev)
{
@@ -387,7 +365,7 @@ static int msm_vidc_setup_context_bank(struct msm_vidc_core *core,
return -EINVAL;
}
cb = get_context_bank(core, dev);
cb = msm_vidc_get_context_bank_for_device(core, dev);
if (!cb) {
d_vpr_e("%s: Failed to get context bank device for %s\n",
__func__, dev_name(dev));

Melihat File

@@ -92,19 +92,12 @@ void *msm_vb2_attach_dmabuf(struct vb2_buffer *vb, struct device *dev,
}
buf->inst = inst;
buf->attach = msm_vidc_dma_buf_attach(dbuf, dev);
buf->attach = call_mem_op(core, dma_buf_attach, core, dbuf, dev);
if (!buf->attach) {
buf->attach = NULL;
buf = NULL;
goto exit;
}
buf->attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;
buf->attach->dma_map_attrs |= DMA_ATTR_DELAYED_UNMAP;
if (is_sys_cache_present(core))
buf->attach->dma_map_attrs |=
DMA_ATTR_IOMMU_USE_UPSTREAM_HINT;
buf->dmabuf = dbuf;
print_vidc_buffer(VIDC_LOW, "low ", "attach", inst, buf);
@@ -129,6 +122,7 @@ void msm_vb2_detach_dmabuf(void *buf_priv)
{
struct msm_vidc_buffer *vbuf = buf_priv;
struct msm_vidc_buffer *ro_buf, *dummy;
struct msm_vidc_core *core;
struct msm_vidc_inst *inst;
if (!vbuf || !vbuf->inst) {
@@ -141,6 +135,7 @@ void msm_vb2_detach_dmabuf(void *buf_priv)
d_vpr_e("%s: invalid params %pK\n", __func__, inst);
return;
}
core = inst->core;
if (is_decode_session(inst) && is_output_buffer(vbuf->type)) {
list_for_each_entry_safe(ro_buf, dummy, &inst->buffers.read_only.list, list) {
@@ -155,7 +150,7 @@ void msm_vb2_detach_dmabuf(void *buf_priv)
print_vidc_buffer(VIDC_LOW, "low ", "detach", inst, vbuf);
if (vbuf->attach && vbuf->dmabuf) {
msm_vidc_dma_buf_detach(vbuf->dmabuf, vbuf->attach);
call_mem_op(core, dma_buf_detach, core, vbuf->dmabuf, vbuf->attach);
vbuf->attach = NULL;
vbuf->dmabuf = NULL;
vbuf->inst = NULL;
@@ -171,6 +166,7 @@ int msm_vb2_map_dmabuf(void *buf_priv)
{
int rc = 0;
struct msm_vidc_buffer *buf = buf_priv;
struct msm_vidc_core *core;
struct msm_vidc_inst *inst;
if (!buf || !buf->inst) {
@@ -183,20 +179,14 @@ int msm_vb2_map_dmabuf(void *buf_priv)
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
buf->sg_table = msm_vidc_dma_buf_map_attachment(buf->attach);
if (!buf->sg_table) {
buf->sg_table = call_mem_op(core, dma_buf_map_attachment, core, buf->attach);
if (!buf->sg_table || !buf->sg_table->sgl) {
buf->sg_table = NULL;
rc = -ENOMEM;
goto exit;
}
if (!buf->sg_table->sgl) {
i_vpr_e(inst, "%s: sgl is NULL\n", __func__);
rc = -ENOMEM;
goto exit;
}
buf->device_addr = buf->sg_table->sgl->dma_address;
print_vidc_buffer(VIDC_HIGH, "high", "map", inst, buf);
@@ -211,6 +201,7 @@ void msm_vb2_unmap_dmabuf(void *buf_priv)
{
struct msm_vidc_buffer *vbuf = buf_priv;
struct msm_vidc_buffer *ro_buf, *dummy;
struct msm_vidc_core *core;
struct msm_vidc_inst *inst;
if (!vbuf || !vbuf->inst) {
@@ -223,6 +214,7 @@ void msm_vb2_unmap_dmabuf(void *buf_priv)
d_vpr_e("%s: invalid params %pK\n", __func__, inst);
return;
}
core = inst->core;
if (is_decode_session(inst) && is_output_buffer(vbuf->type)) {
list_for_each_entry_safe(ro_buf, dummy, &inst->buffers.read_only.list, list) {
@@ -239,7 +231,7 @@ void msm_vb2_unmap_dmabuf(void *buf_priv)
print_vidc_buffer(VIDC_HIGH, "high", "unmap", inst, vbuf);
if (vbuf->attach && vbuf->sg_table) {
msm_vidc_dma_buf_unmap_attachment(vbuf->attach, vbuf->sg_table);
call_mem_op(core, dma_buf_unmap_attachment, core, vbuf->attach, vbuf->sg_table);
vbuf->sg_table = NULL;
vbuf->device_addr = 0x0;
}
@@ -361,8 +353,8 @@ int msm_vidc_queue_setup(struct vb2_queue *q,
return rc;
}
region = msm_vidc_get_buffer_region(inst, buffer_type, __func__);
cb = msm_vidc_get_context_bank(core, region);
region = call_mem_op(core, buffer_region, inst, buffer_type);
cb = msm_vidc_get_context_bank_for_region(core, region);
if (!cb) {
d_vpr_e("%s: Failed to get context bank device\n",
__func__);

Melihat File

@@ -1300,11 +1300,13 @@ static int venus_hfi_cache_packet(struct msm_vidc_inst *inst)
int rc = 0;
struct hfi_header *hdr;
struct hfi_pending_packet *packet;
struct msm_vidc_core *core;
if (!inst->packet) {
if (!inst || !inst->core || !inst->packet) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
hdr = (struct hfi_header *)inst->packet;
if (hdr->size < sizeof(struct hfi_header)) {
@@ -1312,7 +1314,7 @@ static int venus_hfi_cache_packet(struct msm_vidc_inst *inst)
return -EINVAL;
}
packet = msm_memory_pool_alloc(inst, MSM_MEM_POOL_PACKET);
packet = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_PACKET);
if (!packet) {
i_vpr_e(inst, "%s: failed to allocate pending packet\n", __func__);
return -ENOMEM;
@@ -1811,11 +1813,13 @@ static int venus_hfi_add_pending_packets(struct msm_vidc_inst *inst)
struct hfi_pending_packet *pkt_info, *dummy;
struct hfi_header *hdr, *src_hdr;
struct hfi_packet *src_pkt;
struct msm_vidc_core *core;
if (!inst || !inst->packet) {
if (!inst || !inst->core || !inst->packet) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
hdr = (struct hfi_header *)inst->packet;
if (hdr->size < sizeof(struct hfi_header)) {
@@ -1841,7 +1845,7 @@ static int venus_hfi_add_pending_packets(struct msm_vidc_inst *inst)
}
}
list_del(&pkt_info->list);
msm_memory_pool_free(inst, pkt_info);
call_mem_op(core, pool_free, inst, pkt_info);
}
return rc;
}

Melihat File

@@ -8,6 +8,7 @@
#include "msm_vidc_debug.h"
#include "msm_vidc_core.h"
#include "msm_vidc_memory.h"
#include "msm_vidc_platform.h"
static int __strict_check(struct msm_vidc_core *core, const char *function)
{
@@ -428,10 +429,10 @@ void venus_hfi_queue_deinit(struct msm_vidc_core *core)
return;
}
msm_vidc_memory_unmap(core, &core->iface_q_table.map);
msm_vidc_memory_free(core, &core->iface_q_table.alloc);
msm_vidc_memory_unmap(core, &core->sfr.map);
msm_vidc_memory_free(core, &core->sfr.alloc);
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);
for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) {
core->iface_queues[i].q_hdr = NULL;
@@ -510,7 +511,7 @@ int venus_hfi_queue_init(struct msm_vidc_core *core)
alloc.size = TOTAL_QSIZE;
alloc.secure = false;
alloc.map_kernel = true;
rc = msm_vidc_memory_alloc(core, &alloc);
rc = call_mem_op(core, memory_alloc, core, &alloc);
if (rc) {
d_vpr_e("%s: alloc failed\n", __func__);
goto fail_alloc_queue;
@@ -522,7 +523,7 @@ int venus_hfi_queue_init(struct msm_vidc_core *core)
map.type = alloc.type;
map.region = alloc.region;
map.dmabuf = alloc.dmabuf;
rc = msm_vidc_memory_map(core, &map);
rc = call_mem_op(core, memory_map, core, &map);
if (rc) {
d_vpr_e("%s: alloc failed\n", __func__);
goto fail_alloc_queue;
@@ -582,7 +583,7 @@ int venus_hfi_queue_init(struct msm_vidc_core *core)
alloc.size = ALIGNED_SFR_SIZE;
alloc.secure = false;
alloc.map_kernel = true;
rc = msm_vidc_memory_alloc(core, &alloc);
rc = call_mem_op(core, memory_alloc, core, &alloc);
if (rc) {
d_vpr_e("%s: sfr alloc failed\n", __func__);
goto fail_alloc_queue;
@@ -594,7 +595,7 @@ int venus_hfi_queue_init(struct msm_vidc_core *core)
map.type = alloc.type;
map.region = alloc.region;
map.dmabuf = alloc.dmabuf;
rc = msm_vidc_memory_map(core, &map);
rc = call_mem_op(core, memory_map, core, &map);
if (rc) {
d_vpr_e("%s: sfr map failed\n", __func__);
goto fail_alloc_queue;

Melihat File

@@ -14,6 +14,7 @@
#include "msm_vidc_control.h"
#include "msm_vidc_memory.h"
#include "msm_vidc_fence.h"
#include "msm_vidc_platform.h"
#define in_range(range, val) (((range.begin) < (val)) && ((range.end) > (val)))
@@ -657,12 +658,14 @@ static int handle_read_only_buffer(struct msm_vidc_inst *inst,
struct msm_vidc_buffer *buf)
{
struct msm_vidc_buffer *ro_buf;
struct msm_vidc_core *core;
bool found = false;
if (!inst || !buf) {
if (!inst || !inst->core || !buf) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
if (!is_decode_session(inst) || !is_output_buffer(buf->type))
return 0;
@@ -681,7 +684,7 @@ static int handle_read_only_buffer(struct msm_vidc_inst *inst,
* if present, do nothing
*/
if (!found) {
ro_buf = msm_memory_pool_alloc(inst, MSM_MEM_POOL_BUFFER);
ro_buf = call_mem_op(core, pool_alloc, inst, MSM_MEM_POOL_BUFFER);
if (!ro_buf) {
i_vpr_e(inst, "%s: buffer alloc failed\n", __func__);
return -ENOMEM;
@@ -857,12 +860,14 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
int rc = 0;
struct msm_vidc_buffers *buffers;
struct msm_vidc_buffer *buf;
struct msm_vidc_core *core;
bool found, fatal = false;
if (!inst || !inst->capabilities) {
d_vpr_e("%s: Invalid params\n", __func__);
if (!inst || !inst->core || !inst->capabilities) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
/* handle drain last flag buffer */
if (buffer->flags & HFI_BUF_FW_FLAG_LAST) {
@@ -982,7 +987,7 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
}
if (buf->dbuf_get) {
msm_vidc_memory_put_dmabuf(inst, buf->dmabuf);
call_mem_op(core, dma_buf_put, inst, buf->dmabuf);
buf->dbuf_get = 0;
}
}