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:
parent
fbfef11442
commit
6c775159dd
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue