diff --git a/Kbuild b/Kbuild index 7217ca5daa..f62bf008ce 100644 --- a/Kbuild +++ b/Kbuild @@ -88,6 +88,7 @@ msm_video-objs += driver/vidc/src/msm_vidc_v4l2.o \ driver/vidc/src/firmware.o \ driver/vidc/src/msm_vidc_debug.o \ driver/vidc/src/msm_vidc_memory.o \ + driver/vidc/src/msm_vidc_memory_ext.o \ driver/vidc/src/msm_vidc_fence.o \ driver/vidc/src/venus_hfi.o \ driver/vidc/src/venus_hfi_queue.o \ diff --git a/driver/platform/common/inc/msm_vidc_platform.h b/driver/platform/common/inc/msm_vidc_platform.h index 2e0a012d14..820f216ac2 100644 --- a/driver/platform/common/inc/msm_vidc_platform.h +++ b/driver/platform/common/inc/msm_vidc_platform.h @@ -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; diff --git a/driver/platform/common/src/msm_vidc_platform.c b/driver/platform/common/src/msm_vidc_platform.c index ea099e87f5..3e0b16011f 100644 --- a/driver/platform/common/src/msm_vidc_platform.c +++ b/driver/platform/common/src/msm_vidc_platform.c @@ -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; } diff --git a/driver/platform/kalama/src/msm_vidc_kalama.c b/driver/platform/kalama/src/msm_vidc_kalama.c index 8b0196d7ce..8386afa88d 100644 --- a/driver/platform/kalama/src/msm_vidc_kalama.c +++ b/driver/platform/kalama/src/msm_vidc_kalama.c @@ -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; diff --git a/driver/platform/pineapple/src/msm_vidc_pineapple.c b/driver/platform/pineapple/src/msm_vidc_pineapple.c index bf86f88a97..57497665bc 100644 --- a/driver/platform/pineapple/src/msm_vidc_pineapple.c +++ b/driver/platform/pineapple/src/msm_vidc_pineapple.c @@ -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; diff --git a/driver/vidc/inc/msm_vidc_driver.h b/driver/vidc/inc/msm_vidc_driver.h index 8dc658684d..d12f909b53 100644 --- a/driver/vidc/inc/msm_vidc_driver.h +++ b/driver/vidc/inc/msm_vidc_driver.h @@ -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_ diff --git a/driver/vidc/inc/msm_vidc_internal.h b/driver/vidc/inc/msm_vidc_internal.h index d3af40132e..476d3871c5 100644 --- a/driver/vidc/inc/msm_vidc_internal.h +++ b/driver/vidc/inc/msm_vidc_internal.h @@ -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_ diff --git a/driver/vidc/inc/msm_vidc_memory.h b/driver/vidc/inc/msm_vidc_memory.h index c01dae35f1..2af6aa4294 100644 --- a/driver/vidc/inc/msm_vidc_memory.h +++ b/driver/vidc/inc/msm_vidc_memory.h @@ -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_ \ No newline at end of file diff --git a/driver/vidc/inc/msm_vidc_memory_ext.h b/driver/vidc/inc/msm_vidc_memory_ext.h new file mode 100644 index 0000000000..0d95ec52e1 --- /dev/null +++ b/driver/vidc/inc/msm_vidc_memory_ext.h @@ -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_ \ No newline at end of file diff --git a/driver/vidc/src/msm_vidc.c b/driver/vidc/src/msm_vidc.c index 11eea75c86..645a173bb0 100644 --- a/driver/vidc/src/msm_vidc.c +++ b/driver/vidc/src/msm_vidc.c @@ -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); diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index 6273594983..305c1b9530 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -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; +} diff --git a/driver/vidc/src/msm_vidc_memory.c b/driver/vidc/src/msm_vidc_memory.c index 3efe5a676d..5b2b73d39e 100644 --- a/driver/vidc/src/msm_vidc_memory.c +++ b/driver/vidc/src/msm_vidc_memory.c @@ -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; +} \ No newline at end of file diff --git a/driver/vidc/src/msm_vidc_memory_ext.c b/driver/vidc/src/msm_vidc_memory_ext.c new file mode 100644 index 0000000000..1abd35b8d8 --- /dev/null +++ b/driver/vidc/src/msm_vidc_memory_ext.c @@ -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 +#include +#include +#include +#include + +#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; +} diff --git a/driver/vidc/src/msm_vidc_probe.c b/driver/vidc/src/msm_vidc_probe.c index 401aa1b226..01cfa57626 100644 --- a/driver/vidc/src/msm_vidc_probe.c +++ b/driver/vidc/src/msm_vidc_probe.c @@ -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)); diff --git a/driver/vidc/src/msm_vidc_vb2.c b/driver/vidc/src/msm_vidc_vb2.c index f74565326d..602ee39c9a 100644 --- a/driver/vidc/src/msm_vidc_vb2.c +++ b/driver/vidc/src/msm_vidc_vb2.c @@ -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__); diff --git a/driver/vidc/src/venus_hfi.c b/driver/vidc/src/venus_hfi.c index e620c9069c..9d64f754f6 100644 --- a/driver/vidc/src/venus_hfi.c +++ b/driver/vidc/src/venus_hfi.c @@ -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; } diff --git a/driver/vidc/src/venus_hfi_queue.c b/driver/vidc/src/venus_hfi_queue.c index a8b2e8aaf0..4fea4fa357 100644 --- a/driver/vidc/src/venus_hfi_queue.c +++ b/driver/vidc/src/venus_hfi_queue.c @@ -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; diff --git a/driver/vidc/src/venus_hfi_response.c b/driver/vidc/src/venus_hfi_response.c index d3a1a5edfd..81d2566be7 100644 --- a/driver/vidc/src/venus_hfi_response.c +++ b/driver/vidc/src/venus_hfi_response.c @@ -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; } }