vpu: windsor encoder: porting from 4.19 rc3 release

updating source in drivers/mxc/vpu_windsor

Signed-off-by: Zhou Peng <eagle.zhou@nxp.com>
This commit is contained in:
Zhou Peng 2019-06-04 12:26:13 +08:00 committed by Dong Aisheng
parent fbfef11442
commit 6c775159dd
8 changed files with 1107 additions and 471 deletions

View File

@ -2,13 +2,13 @@
# Codec configuration
#
menu "MXC VPU(Video Processing Unit) WINDSOR support"
menu "MXC VPU(Video Processing Unit) WINDSOR ENCODER support"
config MXC_VPU_WINDSOR
tristate "Support for MXC VPU(Video Processing Unit) ENCODER"
select MEDIA_SUPPORT
select VIDEO_DEV
select VIDEO_V4L2
tristate "Support for MXC VPU(Video Processing Unit) WINDSOR ENCODER"
depends on MEDIA_SUPPORT
depends on VIDEO_DEV
depends on VIDEO_V4L2
select VIDEOBUF2_DMA_CONTIG
select VIDEOBUF2_VMALLOC
default y
@ -16,10 +16,10 @@ config MXC_VPU_WINDSOR
The VPU codec device provides codec function for H.264 etc.
config MXC_VPU_WINDSOR_DEBUG
bool "MXC VPU ENCODER debugging"
bool "MXC VPU WINDSOR ENCODER debugging"
depends on MXC_VPU_WINDSOR != n
help
This is an option for the developers; most people should
say N here. This enables MXC VPU driver debugging.
say N here. This enables MXC VPU WINDSOR Encoder driver debugging.
endmenu

File diff suppressed because it is too large Load Diff

View File

@ -27,9 +27,9 @@
#include <media/v4l2-device.h>
#include <media/v4l2-fh.h>
#include <media/videobuf2-v4l2.h>
//#include <soc/imx8/sc/svc/irq/api.h>
//#include <soc/imx8/sc/ipc.h>
//#include <soc/imx8/sc/sci.h>
#include <soc/imx8/sc/svc/irq/api.h>
#include <soc/imx8/sc/ipc.h>
#include <soc/imx8/sc/sci.h>
#include <linux/mx8_mu.h>
#include <media/v4l2-event.h>
#include "vpu_encoder_rpc.h"
@ -174,7 +174,7 @@ struct vpu_v4l2_fmt {
struct vb2_data_req {
struct list_head list;
struct vb2_buffer *vb2_buf;
int id;
u_int32 sequence;
u_int32 buffer_flags;
};
@ -186,10 +186,7 @@ enum ENC_RW_FLAG {
struct queue_data {
unsigned int width;
unsigned int height;
unsigned int bytesperline;
unsigned int sizeimage[3];
unsigned int fourcc;
unsigned int vdec_std;
unsigned int sizeimage[VB2_MAX_PLANES];
struct v4l2_rect rect;
int buf_type; // v4l2_buf_type
bool vb2_q_inited;
@ -206,6 +203,7 @@ struct queue_data {
atomic64_t frame_count;
struct list_head frame_idle;
struct vpu_ctx *ctx;
char desc[64];
};
struct vpu_strip_info {
@ -239,6 +237,7 @@ struct vpu_statistic {
} strip_sts;
bool fps_sts_enable;
struct vpu_fps_sts fps[VPU_FPS_STS_CNT];
unsigned long timestamp_overwrite;
};
struct vpu_attr {
@ -260,6 +259,16 @@ struct vpu_attr {
bool created;
};
struct print_buf_desc {
u32 start_h_phy;
u32 start_h_vir;
u32 start_m;
u32 bytes;
u32 read;
u32 write;
char buffer[0];
};
struct core_device {
void *m0_p_fw_space_vir;
u_int32 m0_p_fw_space_phy;
@ -270,6 +279,7 @@ struct core_device {
u32 rpc_buf_size;
u32 print_buf_size;
u32 rpc_actual_size;
struct print_buf_desc *print_buf;
struct mutex cmd_mutex;
bool fw_is_ready;
@ -302,6 +312,23 @@ struct core_device {
unsigned long reset_times;
};
struct vpu_enc_mem_item {
struct list_head list;
void *virt_addr;
unsigned long phy_addr;
unsigned long size;
unsigned long offset;
};
struct vpu_enc_mem_info {
void *virt_addr;
unsigned long phy_addr;
unsigned long size;
unsigned long bytesused;
struct list_head memorys;
spinlock_t lock;
};
struct vpu_dev {
struct device *generic_dev;
struct v4l2_device v4l2_dev;
@ -334,9 +361,7 @@ struct vpu_dev {
u32 max;
u32 step;
} supported_fps;
struct device *pd_vpu;
struct device *pd_enc;
struct device *pd_mu;
struct vpu_enc_mem_info reserved_mem;
};
struct buffer_addr {
@ -347,6 +372,8 @@ struct buffer_addr {
enum {
VPU_ENC_STATUS_INITIALIZED,
VPU_ENC_STATUS_OUTPUT_READY = 18,
VPU_ENC_STATUS_DATA_READY = 19,
VPU_ENC_STATUS_SNAPSHOT = 20,
VPU_ENC_STATUS_FORCE_RELEASE = 21,
VPU_ENC_STATUS_EOS_SEND = 22,
@ -391,14 +418,25 @@ struct vpu_ctx {
struct vpu_statistic sts;
unsigned int frozen_count;
u_int32 sequence;
s64 timestams[VPU_ENC_SEQ_CAPACITY];
};
#define LVL_DEBUG 4
#define LVL_INFO 3
#define LVL_IRQ 2
#define LVL_ALL 1
#define LVL_WARN 1
#define LVL_ERR 0
#define LVL_ERR (1 << 0)
#define LVL_WARN (1 << 1)
#define LVL_ALL (1 << 2)
#define LVL_IRQ (1 << 3)
#define LVL_INFO (1 << 4)
#define LVL_CMD (1 << 5)
#define LVL_EVT (1 << 6)
#define LVL_DEBUG (1 << 7)
#define LVL_CTRL (1 << 8)
#define LVL_RPC (1 << 9)
#define LVL_MSG (1 << 10)
#define LVL_MEM (1 << 11)
#define LVL_BUF (1 << 12)
#define LVL_FRAME (1 << 13)
#define LVL_FUNC (1 << 16)
#ifndef TAG
#define TAG "[VPU Encoder]\t "
@ -406,14 +444,25 @@ struct vpu_ctx {
#define vpu_dbg(level, fmt, arg...) \
do { \
if (vpu_dbg_level_encoder >= (level)) \
if ((vpu_dbg_level_encoder & (level)) || ((level) & LVL_ERR)) \
pr_info(TAG""fmt, ## arg); \
} while (0)
#define vpu_err(fmt, arg...) vpu_dbg(LVL_ERR, fmt, ##arg)
#define vpu_log_func() vpu_dbg(LVL_FUNC, "%s()\n", __func__)
u32 cpu_phy_to_mu(struct core_device *dev, u32 addr);
struct vpu_attr *get_vpu_ctx_attr(struct vpu_ctx *ctx);
struct vpu_ctx *get_vpu_attr_ctx(struct vpu_attr *attr);
#ifndef VPU_SAFE_RELEASE
#define VPU_SAFE_RELEASE(p, func) \
do {\
if (p) {\
func(p);\
p = NULL;\
} \
} while (0)
#endif
#endif

View File

@ -12,7 +12,7 @@
#define _VPU_ENCODER_CONFIG_H
#define VPU_ENC_WIDTH_MAX 1920
#define VPU_ENC_HEIGHT_MAX 1080
#define VPU_ENC_HEIGHT_MAX 1920
#define VPU_ENC_WIDTH_MIN 64
#define VPU_ENC_HEIGHT_MIN 48
#define VPU_ENC_WIDTH_STEP 16
@ -44,4 +44,8 @@
#define VPU_DETAIL_INDEX_DFT 0xffff
#define VPU_MU_MAX_ADDRESS 0x40000000
#define VPU_ENC_SEQ_CAPACITY 32
#define VPU_ENC_INVALID_TIMESTAMP 0
#endif

View File

@ -13,6 +13,7 @@
* Author Ming Qian<ming.qian@nxp.com>
*/
#define TAG "[VPU Encoder Ctrl]\t "
#include <media/v4l2-ctrls.h>
#include "vpu_encoder_b0.h"
@ -47,16 +48,19 @@ static int set_h264_profile(struct v4l2_ctrl *ctrl)
mutex_lock(&ctx->instance_mutex);
switch (ctrl->val) {
case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
vpu_dbg(LVL_CTRL, "set h264 profile baseline\n");
param->eProfile = MEDIAIP_ENC_PROF_H264_BP;
break;
case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
vpu_dbg(LVL_CTRL, "set h264 profile main\n");
param->eProfile = MEDIAIP_ENC_PROF_H264_MP;
break;
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
vpu_dbg(LVL_CTRL, "set h264 profile high\n");
param->eProfile = MEDIAIP_ENC_PROF_H264_HP;
break;
default:
vpu_dbg(LVL_ERR, "not support H264 profile %d, set to main\n",
vpu_err("not support H264 profile %d, set to main\n",
ctrl->val);
param->eProfile = MEDIAIP_ENC_PROF_H264_MP;
break;
@ -76,7 +80,8 @@ static int set_h264_level(struct v4l2_ctrl *ctrl)
param->uLevel = h264_level[ctrl->val];
mutex_unlock(&ctx->instance_mutex);
vpu_dbg(LVL_DEBUG, "set h264 level to %d\n", ctrl->val);
vpu_dbg(LVL_CTRL, "set h264 level to %d (%d)\n",
ctrl->val, h264_level[ctrl->val]);
return 0;
}
@ -90,14 +95,16 @@ static int set_bitrate_mode(struct v4l2_ctrl *ctrl)
mutex_lock(&ctx->instance_mutex);
switch (ctrl->val) {
case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
vpu_dbg(LVL_CTRL, "set bitrate mode VBR\n");
param->eBitRateMode =
MEDIAIP_ENC_BITRATECONTROLMODE_CONSTANT_QP;
break;
case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
vpu_dbg(LVL_CTRL, "set bitrate mode CBR\n");
param->eBitRateMode = MEDIAIP_ENC_BITRATECONTROLMODE_CBR;
break;
default:
vpu_dbg(LVL_ERR, "not support bitrate mode %d, set to cbr\n",
vpu_err("not support bitrate mode %d, set to cbr\n",
ctrl->val);
param->eBitRateMode = MEDIAIP_ENC_BITRATECONTROLMODE_CBR;
break;
@ -113,6 +120,7 @@ static int set_bitrate(struct v4l2_ctrl *ctrl)
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
pMEDIAIP_ENC_PARAM param = &attr->param;
vpu_dbg(LVL_CTRL, "set bitrate %d\n", ctrl->val);
mutex_lock(&ctx->instance_mutex);
param->uTargetBitrate = ctrl->val / BITRATE_COEF;
if (param->uMaxBitRate < param->uTargetBitrate)
@ -128,6 +136,7 @@ static int set_bitrate_peak(struct v4l2_ctrl *ctrl)
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
pMEDIAIP_ENC_PARAM param = &attr->param;
vpu_dbg(LVL_CTRL, "set peak bitrate %d\n", ctrl->val);
mutex_lock(&ctx->instance_mutex);
param->uMaxBitRate = ctrl->val / BITRATE_COEF;
if (param->uTargetBitrate > param->uMaxBitRate)
@ -143,6 +152,7 @@ static int set_gop_size(struct v4l2_ctrl *ctrl)
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
pMEDIAIP_ENC_PARAM param = &attr->param;
vpu_dbg(LVL_CTRL, "set gop size %d\n", ctrl->val);
mutex_lock(&ctx->instance_mutex);
param->uIFrameInterval = ctrl->val;
mutex_unlock(&ctx->instance_mutex);
@ -156,6 +166,7 @@ static int set_i_period(struct v4l2_ctrl *ctrl)
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
pMEDIAIP_ENC_PARAM param = &attr->param;
vpu_dbg(LVL_CTRL, "set iframe interval %d\n", ctrl->val);
mutex_lock(&ctx->instance_mutex);
param->uIFrameInterval = ctrl->val;
mutex_unlock(&ctx->instance_mutex);
@ -169,6 +180,7 @@ static int get_gop_size(struct v4l2_ctrl *ctrl)
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
pMEDIAIP_ENC_PARAM param = &attr->param;
vpu_dbg(LVL_CTRL, "get gop size\n");
ctrl->val = param->uIFrameInterval;
return 0;
@ -180,6 +192,7 @@ static int set_b_frames(struct v4l2_ctrl *ctrl)
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
pMEDIAIP_ENC_PARAM param = &attr->param;
vpu_dbg(LVL_CTRL, "set bframes %d\n", ctrl->val);
mutex_lock(&ctx->instance_mutex);
param->uGopBLength = ctrl->val;
mutex_unlock(&ctx->instance_mutex);
@ -193,6 +206,7 @@ static int set_qp(struct v4l2_ctrl *ctrl)
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
pMEDIAIP_ENC_PARAM param = &attr->param;
vpu_dbg(LVL_CTRL, "set qp %d\n", ctrl->val);
mutex_lock(&ctx->instance_mutex);
param->uInitSliceQP = ctrl->val;
mutex_unlock(&ctx->instance_mutex);
@ -202,7 +216,7 @@ static int set_qp(struct v4l2_ctrl *ctrl)
static int get_min_buffers_for_output(struct v4l2_ctrl *ctrl)
{
vpu_dbg(LVL_DEBUG, "get min buffers for output\n");
vpu_dbg(LVL_CTRL, "get min buffers for output\n");
ctrl->val = MIN_BUFFER_COUNT;
@ -215,6 +229,7 @@ static int set_display_re_ordering(struct v4l2_ctrl *ctrl)
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
pMEDIAIP_ENC_PARAM param = &attr->param;
vpu_dbg(LVL_CTRL, "set lowlatencymode %d\n", ctrl->val);
mutex_lock(&ctx->instance_mutex);
if (ctrl->val)
param->uLowLatencyMode = 1;
@ -229,6 +244,7 @@ static int set_force_key_frame(struct v4l2_ctrl *ctrl)
{
struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
vpu_dbg(LVL_CTRL, "force key frame\n");
set_bit(VPU_ENC_STATUS_KEY_FRAME, &ctx->status);
return 0;
@ -248,7 +264,7 @@ static int add_ctrl_h264_profile(struct vpu_ctx *ctx)
0xa,
V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE);
if (!ctrl) {
vpu_dbg(LVL_ERR, "add ctrl h264 profile fail\n");
vpu_err("add ctrl h264 profile fail\n");
return -EINVAL;
}
@ -269,7 +285,7 @@ static int add_ctrl_h264_level(struct vpu_ctx *ctx)
0x0,
V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
if (!ctrl) {
vpu_dbg(LVL_ERR, "add ctrl h264 level fail\n");
vpu_err("add ctrl h264 level fail\n");
return -EINVAL;
}
@ -290,7 +306,7 @@ static int add_ctrl_bitrate_mode(struct vpu_ctx *ctx)
0x0,
V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
if (!ctrl) {
vpu_dbg(LVL_ERR, "add ctrl bitrate mode fail\n");
vpu_err("add ctrl bitrate mode fail\n");
return -EINVAL;
}
@ -312,7 +328,7 @@ static int add_ctrl_bitrate(struct vpu_ctx *ctx)
BITRATE_COEF,
BITRATE_DEFAULT_TARGET * BITRATE_COEF);
if (!ctrl) {
vpu_dbg(LVL_ERR, "add ctrl bitrate fail\n");
vpu_err("add ctrl bitrate fail\n");
return -EINVAL;
}
@ -334,7 +350,7 @@ static int add_ctrl_bitrate_peak(struct vpu_ctx *ctx)
BITRATE_COEF,
BITRATE_DEFAULT_PEAK * BITRATE_COEF);
if (!ctrl) {
vpu_dbg(LVL_ERR, "add ctrl bitrate peak fail\n");
vpu_err("add ctrl bitrate peak fail\n");
return -EINVAL;
}
@ -357,7 +373,7 @@ static int add_ctrl_gop_size(struct vpu_ctx *ctx)
1,
GOP_DEFAULT);
if (!ctrl) {
vpu_dbg(LVL_ERR, "add ctrl gop size fail\n");
vpu_err("add ctrl gop size fail\n");
return -EINVAL;
}
@ -384,7 +400,7 @@ static int add_ctrl_i_period(struct vpu_ctx *ctx)
GOP_DEFAULT);
if (!ctrl) {
vpu_dbg(LVL_ERR, "add ctrl i period fail\n");
vpu_err("add ctrl i period fail\n");
return -EINVAL;
}
@ -410,7 +426,7 @@ static int add_ctrl_b_frames(struct vpu_ctx *ctx)
BFRAMES_DEFAULT);
if (!ctrl) {
vpu_dbg(LVL_ERR, "add ctrl b frames fail\n");
vpu_err("add ctrl b frames fail\n");
return -EINVAL;
}
@ -432,7 +448,7 @@ static int add_ctrl_i_frame_qp(struct vpu_ctx *ctx)
1,
QP_DEFAULT);
if (!ctrl) {
vpu_dbg(LVL_ERR, "add ctrl h264 I frame qp fail\n");
vpu_err("add ctrl h264 I frame qp fail\n");
return -EINVAL;
}
@ -454,7 +470,7 @@ static int add_ctrl_p_frame_qp(struct vpu_ctx *ctx)
1,
QP_DEFAULT);
if (!ctrl) {
vpu_dbg(LVL_ERR, "add ctrl h264 P frame qp fail\n");
vpu_err("add ctrl h264 P frame qp fail\n");
return -EINVAL;
}
@ -476,7 +492,7 @@ static int add_ctrl_b_frame_qp(struct vpu_ctx *ctx)
1,
QP_DEFAULT);
if (!ctrl) {
vpu_dbg(LVL_ERR, "add ctrl h264 B frame qp fail\n");
vpu_err("add ctrl h264 B frame qp fail\n");
return -EINVAL;
}
@ -498,7 +514,7 @@ static int add_ctrl_min_buffers_for_output(struct vpu_ctx *ctx)
1,
MIN_BUFFER_COUNT);
if (!ctrl) {
vpu_dbg(LVL_ERR, "add ctrl min buffers for output fail\n");
vpu_err("add ctrl min buffers for output fail\n");
return -EINVAL;
}
@ -519,7 +535,7 @@ static int add_ctrl_display_re_ordering(struct vpu_ctx *ctx)
V4L2_CID_MPEG_VIDEO_H264_ASO,
0, 1, 1, 1);
if (!ctrl) {
vpu_dbg(LVL_ERR, "add ctrl display re ordering fail\n");
vpu_err("add ctrl display re ordering fail\n");
return -EINVAL;
}
@ -538,7 +554,7 @@ static int add_ctrl_force_key_frame(struct vpu_ctx *ctx)
V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME,
0, 0, 0, 0);
if (!ctrl) {
vpu_dbg(LVL_ERR, "add ctrl force key frame fail\n");
vpu_err("add ctrl force key frame fail\n");
return -EINVAL;
}
@ -567,10 +583,12 @@ static int vpu_enc_register_ctrls(struct vpu_ctx *ctx)
int vpu_enc_setup_ctrls(struct vpu_ctx *ctx)
{
vpu_log_func();
v4l2_ctrl_handler_init(&ctx->ctrl_handler, 11);
vpu_enc_register_ctrls(ctx);
if (ctx->ctrl_handler.error) {
vpu_dbg(LVL_ERR, "control initialization error (%d)\n",
vpu_err("control initialization error (%d)\n",
ctx->ctrl_handler.error);
return -EINVAL;
}
@ -580,6 +598,8 @@ int vpu_enc_setup_ctrls(struct vpu_ctx *ctx)
int vpu_enc_free_ctrls(struct vpu_ctx *ctx)
{
vpu_log_func();
if (ctx->ctrl_inited) {
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
ctx->ctrl_inited = false;

View File

@ -9,12 +9,148 @@
* Author Ming Qian<ming.qian@nxp.com>
*/
#define TAG "[VPU Encoder Mem]\t "
#include <linux/kernel.h>
#include <linux/dma-mapping.h>
#include "vpu_encoder_config.h"
#include "vpu_encoder_b0.h"
#include "vpu_encoder_mem.h"
int vpu_enc_init_reserved_memory(struct vpu_enc_mem_info *info)
{
if (!info || !info->phy_addr || !info->size)
return -EINVAL;
info->virt_addr = ioremap_wc(info->phy_addr, info->size);
if (!info->virt_addr)
return -EINVAL;
memset_io(info->virt_addr, 0, info->size);
info->bytesused = 0;
INIT_LIST_HEAD(&info->memorys);
spin_lock_init(&info->lock);
return 0;
}
void vpu_enc_release_reserved_memory(struct vpu_enc_mem_info *info)
{
struct vpu_enc_mem_item *item = NULL;
struct vpu_enc_mem_item *tmp = NULL;
if (!info)
return;
spin_lock(&info->lock);
list_for_each_entry_safe(item, tmp, &info->memorys, list) {
list_del_init(&item->list);
info->bytesused -= item->size;
vpu_dbg(LVL_MEM, "free reserved memory %ld\n", item->size);
VPU_SAFE_RELEASE(item, vfree);
}
spin_unlock(&info->lock);
if (info->virt_addr) {
iounmap(info->virt_addr);
info->virt_addr = NULL;
}
}
int vpu_enc_alloc_reserved_mem(struct vpu_enc_mem_info *info,
struct buffer_addr *buffer)
{
struct vpu_enc_mem_item *item = NULL;
struct list_head *pos = NULL;
unsigned long offset = 0;
int ret;
if (!info || !buffer)
return -EINVAL;
spin_lock(&info->lock);
if (buffer->size + info->bytesused > info->size) {
ret = -ENOMEM;
goto exit;
}
list_for_each_entry(item, &info->memorys, list) {
if (item->offset - offset >= buffer->size) {
pos = &item->list;
break;
}
offset = item->offset + item->size;
}
if (!pos && info->size - offset >= buffer->size)
pos = &info->memorys;
if (!pos) {
ret = -ENOMEM;
goto exit;
}
item = vzalloc(sizeof(*item));
if (!item) {
ret = -EINVAL;
goto exit;
}
item->offset = offset;
item->virt_addr = info->virt_addr + offset;
item->phy_addr = info->phy_addr + offset;
item->size = buffer->size;
list_add_tail(&item->list, pos);
info->bytesused += buffer->size;
vpu_dbg(LVL_MEM, "alloc reserved memory <0x%lx 0x%lx(%ld)>\n",
item->phy_addr, item->size, item->size);
buffer->virt_addr = item->virt_addr;
buffer->phy_addr = item->phy_addr;
ret = 0;
exit:
spin_unlock(&info->lock);
return ret;
}
int vpu_enc_free_reserved_mem(struct vpu_enc_mem_info *info,
struct buffer_addr *buffer)
{
struct vpu_enc_mem_item *item = NULL;
struct vpu_enc_mem_item *tmp = NULL;
unsigned long offset;
int ret = -EINVAL;
if (!info || !buffer)
return -EINVAL;
if (!buffer->virt_addr)
return 0;
if (buffer->phy_addr < info->phy_addr) {
vpu_err("invalid reserved memory addr : 0x%llx %d\n",
buffer->phy_addr, buffer->size);
return -EINVAL;
}
offset = buffer->phy_addr - info->phy_addr;
if (offset + buffer->size > info->size) {
vpu_err("invalid reserved memory addr : 0x%llx %d\n",
buffer->phy_addr, buffer->size);
return -EINVAL;
}
spin_lock(&info->lock);
list_for_each_entry_safe(item, tmp, &info->memorys, list) {
if (offset < item->offset)
continue;
if (offset + buffer->size > item->offset + item->size)
continue;
list_del_init(&item->list);
info->bytesused -= item->size;
vpu_dbg(LVL_MEM, "free reserved memory <0x%lx 0x%lx(%ld)>\n",
item->phy_addr, item->size, item->size);
VPU_SAFE_RELEASE(item, vfree);
ret = 0;
break;
}
spin_unlock(&info->lock);
return ret;
}
void vpu_enc_add_dma_size(struct vpu_attr *attr, unsigned long size)
{
if (!attr)
@ -36,12 +172,13 @@ int vpu_enc_alloc_dma_buffer(struct vpu_ctx *ctx, struct buffer_addr *buffer)
if (!ctx || !ctx->dev || !buffer || !buffer->size)
return -EINVAL;
vpu_dbg(LVL_MEM, "alloc coherent dma %d\n", buffer->size);
buffer->virt_addr = dma_alloc_coherent(ctx->dev->generic_dev,
buffer->size,
(dma_addr_t *)&buffer->phy_addr,
GFP_KERNEL | GFP_DMA32);
if (!buffer->virt_addr) {
vpu_dbg(LVL_ERR, "encoder alloc coherent dma(%d) fail\n",
vpu_err("encoder alloc coherent dma(%d) fail\n",
buffer->size);
return -ENOMEM;
}
@ -69,6 +206,7 @@ int vpu_enc_free_dma_buffer(struct vpu_ctx *ctx, struct buffer_addr *buffer)
if (!buffer->virt_addr)
return 0;
vpu_dbg(LVL_MEM, "free coherent dma %d\n", buffer->size);
vpu_enc_sub_dma_size(get_vpu_ctx_attr(ctx), buffer->size);
dma_free_coherent(ctx->dev->generic_dev, buffer->size,
buffer->virt_addr, buffer->phy_addr);
@ -78,6 +216,17 @@ int vpu_enc_free_dma_buffer(struct vpu_ctx *ctx, struct buffer_addr *buffer)
return 0;
}
static bool check_mem_resource_is_valid(MEDIAIP_ENC_MEM_RESOURCE *resource)
{
if (!resource)
return false;
if (resource->uMemVirtAddr >= VPU_MU_MAX_ADDRESS)
return false;
if (resource->uMemVirtAddr + resource->uMemSize > VPU_MU_MAX_ADDRESS)
return false;
return true;
}
static u32 get_enc_alloc_size(u32 size)
{
u32 esize = ALIGN(size, PAGE_SIZE);
@ -128,10 +277,54 @@ static int free_mem_res(struct vpu_ctx *ctx, struct buffer_addr *buffer,
return 0;
}
static int alloc_reserved_mem_res(struct vpu_ctx *ctx,
struct buffer_addr *buffer,
MEDIAIP_ENC_MEM_RESOURCE *resource,
u32 size)
{
int ret;
if (!ctx || !ctx->dev || !buffer || !resource)
return -EINVAL;
if (!size) {
vpu_err("invalid memory resource size : %d\n", size);
return -EINVAL;
}
buffer->size = get_enc_alloc_size(size);
ret = vpu_enc_alloc_reserved_mem(&ctx->dev->reserved_mem, buffer);
if (ret)
return ret;
resource->uMemPhysAddr = buffer->phy_addr;
resource->uMemVirtAddr = cpu_phy_to_mu(ctx->core_dev, buffer->phy_addr);
resource->uMemSize = size;
return 0;
}
static int free_reserved_mem_res(struct vpu_ctx *ctx,
struct buffer_addr *buffer,
MEDIAIP_ENC_MEM_RESOURCE *resource)
{
if (!ctx || !ctx->dev || !buffer || !resource)
return -EINVAL;
vpu_enc_free_reserved_mem(&ctx->dev->reserved_mem, buffer);
resource->uMemPhysAddr = 0;
resource->uMemVirtAddr = 0;
resource->uMemSize = 0;
return 0;
}
static int free_enc_frames(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
{
int i;
vpu_log_func();
for (i = 0; i < ctx->mem_req.uEncFrmNum; i++)
free_mem_res(ctx, &ctx->encFrame[i],
&pool->tEncFrameBuffers[i]);
@ -144,6 +337,7 @@ static int alloc_enc_frames(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
int i;
int ret;
vpu_log_func();
for (i = 0; i < ctx->mem_req.uEncFrmNum; i++) {
ret = alloc_mem_res(ctx,
&ctx->encFrame[i],
@ -153,7 +347,7 @@ static int alloc_enc_frames(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
vpu_err("alloc enc frame[%d] fail\n", i);
goto error;
}
vpu_dbg(LVL_INFO, "encFrame[%d]: 0x%llx,%d(%d)\n", i,
vpu_dbg(LVL_MEM, "encFrame[%d]: 0x%llx,%d(%d)\n", i,
ctx->encFrame[i].phy_addr,
ctx->mem_req.uEncFrmSize,
ctx->encFrame[i].size);
@ -169,6 +363,7 @@ static int free_ref_frames(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
{
int i;
vpu_log_func();
for (i = 0; i < ctx->mem_req.uRefFrmNum; i++)
free_mem_res(ctx, &ctx->refFrame[i],
&pool->tRefFrameBuffers[i]);
@ -181,6 +376,7 @@ static int alloc_ref_frames(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
int i;
int ret;
vpu_log_func();
for (i = 0; i < ctx->mem_req.uRefFrmNum; i++) {
ret = alloc_mem_res(ctx,
&ctx->refFrame[i],
@ -190,7 +386,7 @@ static int alloc_ref_frames(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
vpu_err("alloc ref frame[%d] fail\n", i);
goto error;
}
vpu_dbg(LVL_INFO, "refFrame[%d]: 0x%llx,%d(%d)\n", i,
vpu_dbg(LVL_MEM, "refFrame[%d]: 0x%llx,%d(%d)\n", i,
ctx->refFrame[i].phy_addr,
ctx->mem_req.uRefFrmSize,
ctx->refFrame[i].size);
@ -207,7 +403,8 @@ static int free_act_frame(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
if (!ctx || !pool)
return -EINVAL;
free_mem_res(ctx, &ctx->actFrame, &pool->tActFrameBufferArea);
vpu_log_func();
free_reserved_mem_res(ctx, &ctx->actFrame, &pool->tActFrameBufferArea);
return 0;
}
@ -216,7 +413,8 @@ static int alloc_act_frame(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
{
int ret = 0;
ret = alloc_mem_res(ctx,
vpu_log_func();
ret = alloc_reserved_mem_res(ctx,
&ctx->actFrame,
&pool->tActFrameBufferArea,
ctx->mem_req.uActBufSize);
@ -225,7 +423,16 @@ static int alloc_act_frame(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
return ret;
}
vpu_dbg(LVL_INFO, "actFrame: 0x%llx, %d(%d)\n",
if (!check_mem_resource_is_valid(&pool->tActFrameBufferArea)) {
vpu_err("invalid actFrames address, 0x%x, 0x%x, 0x%x\n",
pool->tActFrameBufferArea.uMemPhysAddr,
pool->tActFrameBufferArea.uMemVirtAddr,
pool->tActFrameBufferArea.uMemSize);
free_act_frame(ctx, pool);
return -EINVAL;
}
vpu_dbg(LVL_MEM, "actFrame: 0x%llx, %d(%d)\n",
ctx->actFrame.phy_addr,
ctx->mem_req.uActBufSize,
ctx->actFrame.size);
@ -397,10 +604,10 @@ int vpu_enc_alloc_stream(struct vpu_ctx *ctx)
ctx->encoder_stream.size = STREAM_SIZE;
ret = vpu_enc_alloc_dma_buffer(ctx, &ctx->encoder_stream);
if (ret) {
vpu_dbg(LVL_ERR, "alloc encoder stream buffer fail\n");
vpu_err("alloc encoder stream buffer fail\n");
return -ENOMEM;
}
vpu_dbg(LVL_INFO, "encoder_stream: 0x%llx, %d\n",
vpu_dbg(LVL_MEM, "encoder_stream: 0x%llx, %d\n",
ctx->encoder_stream.phy_addr, ctx->encoder_stream.size);
return 0;

View File

@ -13,6 +13,8 @@
#include "vpu_encoder_b0.h"
int vpu_enc_init_reserved_memory(struct vpu_enc_mem_info *info);
void vpu_enc_release_reserved_memory(struct vpu_enc_mem_info *info);
void vpu_enc_add_dma_size(struct vpu_attr *attr, unsigned long size);
void vpu_enc_sub_dma_size(struct vpu_attr *attr, unsigned long size);
int vpu_enc_alloc_dma_buffer(struct vpu_ctx *ctx, struct buffer_addr *buffer);

View File

@ -8,6 +8,7 @@
*
* Author Ming Qian<ming.qian@nxp.com>
*/
#define TAG "[VPU Encoder Msg]\t "
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/vmalloc.h>
@ -32,7 +33,7 @@ static void free_event_msg(struct vpu_event_msg *msg)
return;
free_msg_ext_buffer(msg);
vfree(msg);
VPU_SAFE_RELEASE(msg, vfree);
}
static void set_msg_count(struct vpu_ctx *ctx, unsigned long count)
@ -77,18 +78,19 @@ void cleanup_ctx_msg_queue(struct vpu_ctx *ctx)
WARN_ON(!ctx);
vpu_log_func();
mutex_lock(&ctx->instance_mutex);
list_for_each_entry_safe(msg, tmp, &ctx->msg_q, list) {
list_del_init(&msg->list);
vpu_dbg(LVL_WARN, "drop core[%d] ctx[%d] msg:[%d]\n",
vpu_dbg(LVL_MSG, "drop core[%d] ctx[%d] msg:[%d]\n",
ctx->core_dev->id, ctx->str_index, msg->msgid);
free_event_msg(msg);
VPU_SAFE_RELEASE(msg, free_event_msg);
dec_msg_count(ctx);
}
list_for_each_entry_safe(msg, tmp, &ctx->idle_q, list) {
list_del_init(&msg->list);
free_event_msg(msg);
VPU_SAFE_RELEASE(msg, free_event_msg);
dec_msg_count(ctx);
}
mutex_unlock(&ctx->instance_mutex);
@ -116,6 +118,7 @@ int init_ctx_msg_queue(struct vpu_ctx *ctx)
if (!ctx)
return -EINVAL;
vpu_log_func();
mutex_lock(&ctx->instance_mutex);
set_msg_count(ctx, 0);
@ -157,7 +160,7 @@ void put_idle_msg(struct vpu_ctx *ctx, struct vpu_event_msg *msg)
mutex_lock(&ctx->instance_mutex);
if (is_msg_count_full(ctx)) {
free_event_msg(msg);
VPU_SAFE_RELEASE(msg, free_event_msg);
dec_msg_count(ctx);
} else {
list_add_tail(&msg->list, &ctx->idle_q);
@ -209,7 +212,7 @@ int alloc_msg_ext_buffer(struct vpu_event_msg *msg, u32 number)
msg->number = number;
atomic64_add(number, &total_ext_data);
vpu_dbg(LVL_DEBUG, "++++alloc %d msg ext data: %lld\n",
vpu_dbg(LVL_MSG, "++++alloc %d msg ext data: %lld\n",
number, get_total_ext_data_number());
return 0;
@ -223,9 +226,8 @@ void free_msg_ext_buffer(struct vpu_event_msg *msg)
return;
atomic64_sub(msg->number, &total_ext_data);
vfree(msg->ext_data);
msg->ext_data = NULL;
vpu_dbg(LVL_DEBUG, "----free %d msg ext data: %lld\n",
VPU_SAFE_RELEASE(msg->ext_data, vfree);
vpu_dbg(LVL_MSG, "----free %d msg ext data: %lld\n",
msg->number, get_total_ext_data_number());
}