Add Malone decoder and windsor encoder for QXP/QM
Add vpu driver: drivers/mxc/vpu_malone drivers/mxc/vpu_windsor Signed-off-by: Zhou Peng <eagle.zhou@nxp.com>5.4-rM2-2.2.x-imx-squashed
parent
c5b08a52fe
commit
95b1763c0a
|
@ -0,0 +1,20 @@
|
|||
#
|
||||
# Codec configuration
|
||||
#
|
||||
|
||||
menu "MXC VPU(Video Processing Unit) MALONE support"
|
||||
|
||||
config MXC_VPU_MALONE
|
||||
tristate "Support for MXC VPU(Video Processing Unit) DECODER"
|
||||
default y
|
||||
---help---
|
||||
The VPU codec device provides codec function for H.265 H.264 MPEG2 MPEG4 etc.
|
||||
|
||||
config MXC_VPU_MALONE_DEBUG
|
||||
bool "MXC VPU DECODER debugging"
|
||||
depends on MXC_VPU_MALONE != n
|
||||
help
|
||||
This is an option for the developers; most people should
|
||||
say N here. This enables MXC VPU driver debugging.
|
||||
|
||||
endmenu
|
|
@ -0,0 +1,16 @@
|
|||
##
|
||||
## Makefile for the VPU and M0 driver
|
||||
##
|
||||
DEFINES += -D REBOOT=1 \
|
||||
-D BOOT_ARCH=1
|
||||
|
||||
EXTRA_CFLAGS += $(DEFINES)
|
||||
|
||||
obj-y = vpu-malone.o
|
||||
vpu-malone-objs = vpu_b0.o \
|
||||
vpu_rpc.o \
|
||||
insert_startcode.o \
|
||||
vpu_debug_log.o
|
||||
|
||||
clean:
|
||||
rm -rf $(vpu-malone-objs)
|
|
@ -0,0 +1,546 @@
|
|||
/*
|
||||
* Copyright 2018 NXP
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file insert_startcode.c
|
||||
*
|
||||
* copyright here may be changed later
|
||||
*
|
||||
*
|
||||
*/
|
||||
#include "insert_startcode.h"
|
||||
// Global VC1 ID and version
|
||||
u_int32 uVC1CodecID = 0x10; // Simple = 0x10, Main = 0x11
|
||||
u_int32 uVC1VersionID = 1;
|
||||
|
||||
static int insert_RCV_seqhdr(unsigned char *pHeader, u_int32 *pHeaderLen, unsigned char *src,
|
||||
u_int32 nFrameSize, u_int32 nWidth, u_int32 nHeight, int *pNoError)
|
||||
{
|
||||
int nHeaderLen;
|
||||
|
||||
unsigned int nValue;
|
||||
unsigned int HdrExtDataLen;
|
||||
int i = 0;
|
||||
int profile;
|
||||
|
||||
nHeaderLen = RCV_HEADER_LEN;
|
||||
|
||||
//Number of Frames, Header Extension Bit, Codec Version
|
||||
nValue = RCV_NUM_FRAMES | RCV_SET_HDR_EXT | RCV_CODEC_VERSION;
|
||||
pHeader[i++] = (unsigned char)nValue;
|
||||
pHeader[i++] = (unsigned char)(nValue >> 8);
|
||||
pHeader[i++] = (unsigned char)(nValue >> 16);
|
||||
#if 0 //1 ???
|
||||
pHeader[i++] = 0xC5;
|
||||
#else
|
||||
pHeader[i++] = (unsigned char)(nValue >> 24);
|
||||
#endif
|
||||
|
||||
//Header Extension Size
|
||||
//ASF Parser gives 5 bytes whereas the VPU expects only 4 bytes, so limiting it
|
||||
HdrExtDataLen = 4;
|
||||
pHeader[i++] = (unsigned char)HdrExtDataLen;
|
||||
pHeader[i++] = (unsigned char)(HdrExtDataLen >> 8);
|
||||
pHeader[i++] = (unsigned char)(HdrExtDataLen >> 16);
|
||||
pHeader[i++] = (unsigned char)(HdrExtDataLen >> 24);
|
||||
|
||||
profile = (*src)>>4;
|
||||
if ((profile != 0) && (profile != 4) && (profile != 12)) {
|
||||
//it is reasonable to return error immediately since only one sequence header inserted in whole rcv clip
|
||||
*pNoError = 0;
|
||||
}
|
||||
memcpy(pHeader+i, src, HdrExtDataLen);
|
||||
i += HdrExtDataLen;
|
||||
|
||||
//Height
|
||||
pHeader[i++] = (unsigned char)nHeight;
|
||||
pHeader[i++] = (unsigned char)(((nHeight >> 8) & 0xff));
|
||||
pHeader[i++] = (unsigned char)(((nHeight >> 16) & 0xff));
|
||||
pHeader[i++] = (unsigned char)(((nHeight >> 24) & 0xff));
|
||||
//Width
|
||||
pHeader[i++] = (unsigned char)nWidth;
|
||||
pHeader[i++] = (unsigned char)(((nWidth >> 8) & 0xff));
|
||||
pHeader[i++] = (unsigned char)(((nWidth >> 16) & 0xff));
|
||||
pHeader[i++] = (unsigned char)(((nWidth >> 24) & 0xff));
|
||||
|
||||
//Frame Size
|
||||
pHeader[i++] = (unsigned char)nFrameSize;
|
||||
pHeader[i++] = (unsigned char)(nFrameSize >> 8);
|
||||
pHeader[i++] = (unsigned char)(nFrameSize >> 16);
|
||||
#if 0 //1 ???
|
||||
pHeader[i++] = (unsigned char)((nFrameSize >> 24));
|
||||
#else
|
||||
pHeader[i++] = (unsigned char)((nFrameSize >> 24) | 0x80);
|
||||
#endif
|
||||
|
||||
*pHeaderLen = nHeaderLen;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int insert_RCV_pichdr(unsigned char *pHeader, int *pHeaderLen, unsigned int nInSize)
|
||||
{
|
||||
pHeader[0] = (unsigned char)nInSize;
|
||||
pHeader[1] = (unsigned char)(nInSize >> 8);
|
||||
pHeader[2] = (unsigned char)(nInSize >> 16);
|
||||
pHeader[3] = (unsigned char)(nInSize >> 24);
|
||||
*pHeaderLen = 4;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Byte 0-3: Startcode
|
||||
* Byte 4: Payload length bits[23:16]
|
||||
* Byte 5: Payload length bits[15:8]
|
||||
* Byte 6: 0x4e
|
||||
* Byte 7: Payload length bits[7:0]
|
||||
* Byte 8: Codec ID Non-zero
|
||||
* Byte 9: Codec Version ID Non-zero
|
||||
* Byte 10: Picture Width bits[15:8]
|
||||
* Byte 11: Picture Width bits[7:0]
|
||||
* Byte 12: 0x58
|
||||
* Byte 13: Picture Height bits[15:8]
|
||||
* Byte 14: Picture Height bits[7:0]
|
||||
* Byte 15: 0x50
|
||||
*/
|
||||
|
||||
static void insert_payload_header_vc1(u_int8 *dst, u_int32 uScodeType, u_int32 uPayloadSize, u_int32 uWidth, u_int32 uHeight)
|
||||
{
|
||||
// Startcode
|
||||
dst[0] = 0x00;
|
||||
dst[1] = 0x00;
|
||||
dst[2] = 0x01;
|
||||
dst[3] = uScodeType;
|
||||
|
||||
// Length
|
||||
dst[4] = ((uPayloadSize>>16)&0xff);
|
||||
dst[5] = ((uPayloadSize>>8)&0xff);
|
||||
dst[6] = 0x4e;
|
||||
dst[7] = ((uPayloadSize>>0)&0xff);
|
||||
|
||||
// Codec ID and Version
|
||||
dst[8] = uVC1CodecID;
|
||||
dst[9] = uVC1VersionID;
|
||||
|
||||
// Width
|
||||
dst[10] = ((uWidth>>8)&0xff);
|
||||
dst[11] = ((uWidth>>0)&0xff);
|
||||
dst[12] = 0x58;
|
||||
|
||||
// Height
|
||||
dst[13] = ((uHeight>>8)&0xff);
|
||||
dst[14] = ((uHeight>>0)&0xff);
|
||||
dst[15] = 0x50;
|
||||
}
|
||||
|
||||
static int VC1CreateNALSeqHeader(unsigned char *pHeader, int *pHeaderLen,
|
||||
unsigned char *pCodecPri, int nCodecSize, unsigned int *pData, int nMaxHeader)
|
||||
{
|
||||
int nHeaderLen;
|
||||
unsigned char temp[4] = {0x00, 0x00, 0x01, 0x0D};
|
||||
|
||||
nHeaderLen = nCodecSize - 1;
|
||||
if ((4+nHeaderLen) > nMaxHeader) {
|
||||
nHeaderLen = nMaxHeader - 4;
|
||||
vpu_dbg(LVL_ERR, "error: header length %d overrun !!! \r\n", nCodecSize);
|
||||
}
|
||||
memcpy(pHeader, pCodecPri+1, nHeaderLen);
|
||||
|
||||
if (VC1_IS_NOT_NAL(pData[0])) {
|
||||
//insert 0x0000010D at the end of header
|
||||
memcpy(pHeader+nHeaderLen, temp, 4);
|
||||
nHeaderLen += 4;
|
||||
}
|
||||
|
||||
*pHeaderLen = nHeaderLen;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int VC1CreateNalFrameHeader(unsigned char *pHeader, int *pHeaderLen, unsigned int *pInData)
|
||||
{
|
||||
unsigned int VC1Id;
|
||||
|
||||
VC1Id = *pInData;
|
||||
if (VC1_IS_NOT_NAL(VC1Id)) {
|
||||
//need insert header : special ID
|
||||
pHeader[0] = 0x0;
|
||||
pHeader[1] = 0x0;
|
||||
pHeader[2] = 0x01;
|
||||
pHeader[3] = 0x0D;
|
||||
*pHeaderLen = 4;
|
||||
} else {
|
||||
//need not insert header
|
||||
//do nothing
|
||||
*pHeaderLen = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void vp6_scd_sequence_header(unsigned char *buffer, int pic_width, int pic_height)
|
||||
{
|
||||
int Length = 0;
|
||||
|
||||
buffer[0] = 0x00;
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = 0x01;
|
||||
buffer[3] = 0x31;
|
||||
buffer[4] = (Length+12)>>16;
|
||||
buffer[5] = (Length+12)>>8;
|
||||
buffer[6] = 0x4e;
|
||||
buffer[7] = (Length+12);
|
||||
buffer[8] = 0x36;
|
||||
buffer[9] = 0x1;
|
||||
buffer[10] = pic_width>>8;
|
||||
buffer[11] = pic_width;
|
||||
buffer[12] = 0x58;
|
||||
buffer[13] = pic_height>>8;
|
||||
buffer[14] = pic_height;
|
||||
buffer[15] = 0x50;
|
||||
}
|
||||
|
||||
void vp6_scd_frame_header(unsigned char *buffer, int pic_width, int pic_height, int Length)
|
||||
{
|
||||
buffer[0] = 0x00;
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = 0x01;
|
||||
buffer[3] = 0x32;
|
||||
buffer[4] = (Length+12)>>16;
|
||||
buffer[5] = (Length+12)>>8;
|
||||
buffer[6] = 0x4e;
|
||||
buffer[7] = (Length+12);
|
||||
buffer[8] = 0x36;
|
||||
buffer[9] = 0x1;
|
||||
buffer[10] = pic_width>>8;
|
||||
buffer[11] = pic_width;
|
||||
buffer[12] = 0x58;
|
||||
buffer[13] = pic_height>>8;
|
||||
buffer[14] = pic_height;
|
||||
buffer[15] = 0x50;
|
||||
}
|
||||
|
||||
void vp8_ivf_sequence_header(unsigned char *buffer, int pic_width, int pic_height)
|
||||
{
|
||||
int Length = 32;
|
||||
|
||||
buffer[0] = 0x44;
|
||||
buffer[1] = 0x4b;
|
||||
buffer[2] = 0x49;
|
||||
buffer[3] = 0x46; //0-3byte signature "DKIF"
|
||||
buffer[4] = 0x00;
|
||||
buffer[5] = 0x00; //4-5byte version 0
|
||||
buffer[6] = Length;
|
||||
buffer[7] = Length >> 8; //length of Header
|
||||
buffer[8] = 0x56;
|
||||
buffer[9] = 0x50;
|
||||
buffer[10] = 0x38;
|
||||
buffer[11] = 0x30; //VP8 fourcc
|
||||
buffer[12] = pic_width;
|
||||
buffer[13] = pic_width >> 8;
|
||||
buffer[14] = pic_height;
|
||||
buffer[15] = pic_height >> 8;
|
||||
buffer[16] = 0xe8;
|
||||
buffer[17] = 0x03;
|
||||
buffer[18] = 0x00;
|
||||
buffer[19] = 0x00; //16-19 frame rate
|
||||
buffer[20] = 0x01;
|
||||
buffer[21] = 0x00;
|
||||
buffer[22] = 0x00;
|
||||
buffer[23] = 0x00; //20-23 time scale
|
||||
buffer[24] = 0xdf;
|
||||
buffer[25] = 0xf9;
|
||||
buffer[26] = 0x09;
|
||||
buffer[27] = 0x00; //24-27 number frames
|
||||
//28-31 unused
|
||||
}
|
||||
|
||||
void vp8_ivf_frame_header(unsigned char *buffer, u_int32 FrameSize)
|
||||
{
|
||||
buffer[0] = FrameSize;
|
||||
buffer[1] = FrameSize >> 8;
|
||||
buffer[2] = FrameSize >> 16;
|
||||
buffer[3] = FrameSize >> 24;
|
||||
//4-11 timestamp
|
||||
}
|
||||
|
||||
void vp8_scd_sequence_header(unsigned char *buffer, int pic_width, int pic_height)
|
||||
{
|
||||
int Length = 32;
|
||||
|
||||
buffer[0] = 0x00;
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = 0x01;
|
||||
buffer[3] = 0x31;
|
||||
buffer[4] = (Length+12)>>16;
|
||||
buffer[5] = (Length+12)>>8;
|
||||
buffer[6] = 0x4e;
|
||||
buffer[7] = (Length+12);
|
||||
buffer[8] = 0x36;
|
||||
buffer[9] = 0x1;
|
||||
buffer[10] = pic_width>>8;
|
||||
buffer[11] = pic_width;
|
||||
buffer[12] = 0x58;
|
||||
buffer[13] = pic_height>>8;
|
||||
buffer[14] = pic_height;
|
||||
buffer[15] = 0x50;
|
||||
}
|
||||
void vp8_scd_frame_header(unsigned char *buffer, int pic_width, int pic_height, int Length)
|
||||
{
|
||||
buffer[0] = 0x00;
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = 0x01;
|
||||
buffer[3] = 0x32;
|
||||
buffer[4] = (Length+12)>>16;
|
||||
buffer[5] = (Length+12)>>8;
|
||||
buffer[6] = 0x4e;
|
||||
buffer[7] = (Length+12);
|
||||
buffer[8] = 0x36;
|
||||
buffer[9] = 0x1;
|
||||
buffer[10] = pic_width>>8;
|
||||
buffer[11] = pic_width;
|
||||
buffer[12] = 0x58;
|
||||
buffer[13] = pic_height>>8;
|
||||
buffer[14] = pic_height;
|
||||
buffer[15] = 0x50;
|
||||
}
|
||||
|
||||
static void insert_payload_header_divx(u_int8 *dst, u_int32 uPayloadSize, u_int32 uWidth, u_int32 uHeight)
|
||||
{
|
||||
// Startcode
|
||||
dst[0] = 0x00;
|
||||
dst[1] = 0x00;
|
||||
dst[2] = 0x01;
|
||||
dst[3] = 0x32;
|
||||
|
||||
// Length
|
||||
dst[4] = ((uPayloadSize>>16)&0xff);
|
||||
dst[5] = ((uPayloadSize>>8)&0xff);
|
||||
dst[6] = 0x4e;
|
||||
dst[7] = ((uPayloadSize>>0)&0xff);
|
||||
|
||||
// Codec ID and Version
|
||||
dst[8] = 0x38;
|
||||
dst[9] = 0x01;
|
||||
|
||||
// Width
|
||||
dst[10] = ((uWidth>>8)&0xff);
|
||||
dst[11] = ((uWidth>>0)&0xff);
|
||||
dst[12] = 0x58;
|
||||
|
||||
// Height
|
||||
dst[13] = ((uHeight>>8)&0xff);
|
||||
dst[14] = ((uHeight>>0)&0xff);
|
||||
dst[15] = 0x50;
|
||||
}
|
||||
|
||||
static void insert_seq_header_spk(u_int8 *dst, u_int32 uPayloadSize, u_int32 uWidth, u_int32 uHeight)
|
||||
{
|
||||
// Startcode
|
||||
dst[0] = 0x00;
|
||||
dst[1] = 0x00;
|
||||
dst[2] = 0x01;
|
||||
dst[3] = 0x31;
|
||||
|
||||
// Length
|
||||
dst[4] = ((uPayloadSize>>16)&0xff);
|
||||
dst[5] = ((uPayloadSize>>8)&0xff);
|
||||
dst[6] = 0x4e;
|
||||
dst[7] = ((uPayloadSize>>0)&0xff);
|
||||
|
||||
// Codec ID and Version
|
||||
dst[8] = 0x39;
|
||||
dst[9] = 0x01;
|
||||
|
||||
// Width
|
||||
dst[10] = ((uWidth>>8)&0xff);
|
||||
dst[11] = ((uWidth>>0)&0xff);
|
||||
dst[12] = 0x58;
|
||||
|
||||
// Height
|
||||
dst[13] = ((uHeight>>8)&0xff);
|
||||
dst[14] = ((uHeight>>0)&0xff);
|
||||
dst[15] = 0x50;
|
||||
}
|
||||
|
||||
static void insert_frame_header_spk(u_int8 *dst, u_int32 uPayloadSize, u_int32 uWidth, u_int32 uHeight)
|
||||
{
|
||||
uPayloadSize = 0;
|
||||
// Startcode
|
||||
dst[0] = 0x00;
|
||||
dst[1] = 0x00;
|
||||
dst[2] = 0x01;
|
||||
dst[3] = 0x32;
|
||||
|
||||
// Length
|
||||
dst[4] = ((uPayloadSize>>16)&0xff);
|
||||
dst[5] = ((uPayloadSize>>8)&0xff);
|
||||
dst[6] = 0x4e;
|
||||
dst[7] = ((uPayloadSize>>0)&0xff);
|
||||
|
||||
// Codec ID and Version
|
||||
dst[8] = 0x39;
|
||||
dst[9] = 0x01;
|
||||
|
||||
// Width
|
||||
dst[10] = ((uWidth>>8)&0xff);
|
||||
dst[11] = ((uWidth>>0)&0xff);
|
||||
dst[12] = 0x58;
|
||||
|
||||
// Height
|
||||
dst[13] = ((uHeight>>8)&0xff);
|
||||
dst[14] = ((uHeight>>0)&0xff);
|
||||
dst[15] = 0x50;
|
||||
}
|
||||
|
||||
u_int32 insert_scode_4_seq(struct vpu_ctx *ctx, u_int8 *src, u_int8 *dst, u_int32 vdec_std, u_int32 uPayloadSize)
|
||||
{
|
||||
struct queue_data *q_data = &ctx->q_data[V4L2_SRC];
|
||||
u_int32 length = 0;
|
||||
|
||||
switch (vdec_std) {
|
||||
case VPU_VIDEO_VC1: {
|
||||
if (q_data->fourcc == V4L2_PIX_FMT_VC1_ANNEX_G) {
|
||||
u_int8 Header[VC1_MAX_SEQ_HEADER_SIZE];
|
||||
u_int32 uWidth = q_data->width;
|
||||
u_int32 uHeight = q_data->height; //Width & Height in the generic payload header are ignored
|
||||
u_int32 FrameSize = 0x60;
|
||||
u_int32 HeaderLen, NoError = 1;
|
||||
//insert startcode for vc1
|
||||
insert_payload_header_vc1(dst, VC1_SCODE_NEW_SEQUENCE, 20, uWidth, uHeight);
|
||||
length = 16;
|
||||
//insert RCV sequence header for vc1 v1, length=20
|
||||
insert_RCV_seqhdr(Header, &HeaderLen, src, FrameSize, uWidth, uHeight, &NoError);
|
||||
HeaderLen = RCV_HEADER_LEN - 4;
|
||||
memcpy(dst + 16, Header, HeaderLen);
|
||||
length += HeaderLen;
|
||||
} else {
|
||||
u_int8 Header[VC1_MAX_SEQ_HEADER_SIZE];
|
||||
u_int32 HeaderLen;
|
||||
|
||||
VC1CreateNALSeqHeader(Header, &HeaderLen, src, uPayloadSize,
|
||||
(unsigned int *)src, VC1_MAX_SEQ_HEADER_SIZE);
|
||||
if (VC1_IS_NOT_NAL(((unsigned int *)src)[0]))
|
||||
HeaderLen -= 4;
|
||||
memcpy(dst, Header, HeaderLen);
|
||||
length += HeaderLen;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case VPU_VIDEO_VP6: {
|
||||
vp6_scd_sequence_header(dst, q_data->width, q_data->height);
|
||||
length = 16;
|
||||
}
|
||||
break;
|
||||
case VPU_VIDEO_VP8: {
|
||||
u_int8 seq_header[32] = {0};
|
||||
u_int8 frame_header[8] = {0};
|
||||
|
||||
vp8_scd_sequence_header(dst, q_data->width, q_data->height);
|
||||
length = 16;
|
||||
vp8_ivf_sequence_header(seq_header, q_data->width, q_data->height);
|
||||
memcpy(dst+length, seq_header, 32);
|
||||
length += 32;
|
||||
vp8_scd_frame_header(dst + length, q_data->width, q_data->height, uPayloadSize + 8);
|
||||
length += 16;
|
||||
vp8_ivf_frame_header(frame_header, uPayloadSize);
|
||||
memcpy(dst+length, frame_header, 8);
|
||||
length += 8;
|
||||
memcpy(dst+length, src, uPayloadSize);
|
||||
length += uPayloadSize;
|
||||
}
|
||||
break;
|
||||
case VPU_VIDEO_ASP: {
|
||||
if (q_data->fourcc == VPU_PIX_FMT_DIVX) {
|
||||
insert_payload_header_divx(dst, uPayloadSize, q_data->width, q_data->height);
|
||||
length = 16;
|
||||
memcpy(dst+length, src, uPayloadSize);
|
||||
length += uPayloadSize;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VPU_VIDEO_SPK: {
|
||||
insert_seq_header_spk(dst, uPayloadSize, q_data->width, q_data->height);
|
||||
length = 16;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
u_int32 insert_scode_4_pic(struct vpu_ctx *ctx, u_int8 *dst, u_int8 *src, u_int32 vdec_std, u_int32 uPayloadSize)
|
||||
{
|
||||
struct queue_data *q_data = &ctx->q_data[V4L2_SRC];
|
||||
u_int32 length = 0;
|
||||
|
||||
switch (vdec_std) {
|
||||
case VPU_VIDEO_VC1: {
|
||||
if (q_data->fourcc == V4L2_PIX_FMT_VC1_ANNEX_G) {
|
||||
u_int8 Header[VC1_MAX_FRM_HEADER_SIZE];
|
||||
u_int32 HeaderLen;
|
||||
u_int32 uWidth = q_data->width;
|
||||
u_int32 uHeight = q_data->height; //Width & Height in the generic payload header are ignored
|
||||
|
||||
insert_payload_header_vc1(dst, VC1_SCODE_NEW_PICTURE, uPayloadSize + 4, uWidth, uHeight);
|
||||
insert_RCV_pichdr(Header, &HeaderLen, uPayloadSize);
|
||||
memcpy(dst+16, Header, 4);
|
||||
length = 16 + 4;
|
||||
} else {
|
||||
u_int8 Header[VC1_MAX_FRM_HEADER_SIZE];
|
||||
u_int32 HeaderLen;
|
||||
|
||||
VC1CreateNalFrameHeader(Header, (int *)(&HeaderLen), (unsigned int *)(src));
|
||||
memcpy(dst, Header, HeaderLen);
|
||||
length = HeaderLen;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VPU_VIDEO_VP6: {
|
||||
vp6_scd_frame_header(dst, q_data->width, q_data->height, uPayloadSize);
|
||||
length = 16;
|
||||
}
|
||||
break;
|
||||
case VPU_VIDEO_VP8: {
|
||||
u_int8 frame_header[8];
|
||||
|
||||
vp8_scd_frame_header(dst, q_data->width, q_data->height, uPayloadSize + 8);
|
||||
length = 16;
|
||||
vp8_ivf_frame_header(frame_header, uPayloadSize);
|
||||
memcpy(dst+length, frame_header, 8);
|
||||
length += 8;
|
||||
}
|
||||
break;
|
||||
case VPU_VIDEO_ASP: {
|
||||
if (q_data->fourcc == VPU_PIX_FMT_DIVX) {
|
||||
insert_payload_header_divx(dst, uPayloadSize, q_data->width, q_data->height);
|
||||
length = 16;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VPU_VIDEO_SPK: {
|
||||
insert_frame_header_spk(dst, uPayloadSize, q_data->width, q_data->height);
|
||||
length = 16;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2018 NXP
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file insert_startcode.h
|
||||
*
|
||||
*/
|
||||
#ifndef __INSERT_STARTCODE_H__
|
||||
#define __INSERT_STARTCODE_H__
|
||||
|
||||
#include "vpu_b0.h"
|
||||
#include "mediasys_types.h"
|
||||
// Startcode insertion types for VC1
|
||||
#define VC1_SCODE_NEW_SEQUENCE 0x31
|
||||
#define VC1_SCODE_NEW_PICTURE 0x32
|
||||
#define VC1_SCODE_NEW_SLICE 0x33
|
||||
#define RCV_V2_FRAMESIZE_FLAGS (0xFF000000)
|
||||
#define RCV_HEADER_LEN 24
|
||||
#define RCV_CODEC_VERSION (0x5 << 24) //FOURCC_WMV3_WMV
|
||||
#define RCV_NUM_FRAMES 0xFF
|
||||
#define RCV_SET_HDR_EXT 0x80000000
|
||||
#define VC1_IS_NOT_NAL(id) ((id & 0x00FFFFFF) != 0x00010000)
|
||||
#define VC1_MAX_FRM_HEADER_SIZE 32
|
||||
#define VC1_MAX_SEQ_HEADER_SIZE 256
|
||||
|
||||
u_int32 insert_scode_4_pic(struct vpu_ctx *ctx, u_int8 *dst, u_int8 *src, u_int32 vdec_std, u_int32 uPayloadSize);
|
||||
u_int32 insert_scode_4_seq(struct vpu_ctx *ctx, u_int8 *src, u_int8 *dst, u_int32 vdec_std, u_int32 uPayloadSize);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,790 @@
|
|||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _MEDIASYS_TYPES_H_
|
||||
#define _MEDIASYS_TYPES_H_
|
||||
|
||||
typedef unsigned int u_int32;
|
||||
typedef unsigned char u_int8;
|
||||
typedef unsigned long u_int64;
|
||||
typedef unsigned int BOOL;
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#define VPU_MAX_NUM_STREAMS 8
|
||||
#define VID_API_NUM_STREAMS 8
|
||||
#define VID_API_MAX_BUF_PER_STR 3
|
||||
#define VID_API_MAX_NUM_MVC_VIEWS 4
|
||||
#define MEDIAIP_MAX_NUM_MALONES 2
|
||||
#define MEDIAIP_MAX_NUM_MALONE_IRQ_PINS 2
|
||||
#define MEDIAIP_MAX_NUM_WINDSORS 1
|
||||
#define MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS 2
|
||||
#define MEDIAIP_MAX_NUM_CMD_IRQ_PINS 2
|
||||
#define MEDIAIP_MAX_NUM_MSG_IRQ_PINS 1
|
||||
#define MEDIAIP_MAX_NUM_TIMER_IRQ_PINS 4
|
||||
#define MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS 4
|
||||
#define VID_API_COMMAND_LIMIT 64
|
||||
#define VID_API_MESSAGE_LIMIT 256
|
||||
#define MSG_WORD_LENGTH 3
|
||||
|
||||
#define API_CMD_AVAILABLE 0x0
|
||||
#define API_CMD_INCOMPLETE 0x1
|
||||
#define API_CMD_BUFFER_ERROR 0x2
|
||||
#define API_CMD_UNAVAILABLE 0x3
|
||||
#define API_MSG_AVAILABLE 0x0
|
||||
#define API_MSG_INCOMPLETE 0x1
|
||||
#define API_MSG_BUFFER_ERROR 0x2
|
||||
#define API_MSG_UNAVAILABLE 0x3
|
||||
|
||||
typedef enum {
|
||||
FRAME_ALLOC = 0,
|
||||
FRAME_FREE,
|
||||
FRAME_DECODED,
|
||||
FRAME_READY,
|
||||
FRAME_RELEASE,
|
||||
} FRAME_BUFFER_STAT;
|
||||
|
||||
typedef enum {
|
||||
VPU_APP,
|
||||
VPU_DRIVER,
|
||||
VPU_DECODER,
|
||||
} FRAME_BUFFER_OWNER;
|
||||
|
||||
typedef enum {
|
||||
INVALID_MODE = 0,
|
||||
FRAME_LVL,
|
||||
NON_FRAME_LVL,
|
||||
} STREAM_INPUT_MODE;
|
||||
|
||||
typedef enum {
|
||||
MEDIAIP_FRAME_REQ = 0,
|
||||
MEDIAIP_MBI_REQ,
|
||||
MEDIAIP_DCP_REQ,
|
||||
MEDIAIP_REQ_LAST = MEDIAIP_DCP_REQ
|
||||
|
||||
} MEDIAIP_MEM_REQ;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uNum;
|
||||
MEDIAIP_MEM_REQ eType;
|
||||
} MEDIA_PLAYER_FSREQ;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uFSIdx;
|
||||
MEDIAIP_MEM_REQ eType;
|
||||
BOOL bNotDisplayed;
|
||||
} MEDIA_PLAYER_FSREL;
|
||||
|
||||
typedef enum {
|
||||
/* Non-Stream Specific messages */
|
||||
MEDIA_PLAYER_API_MODE_INVALID = 0x00,
|
||||
MEDIA_PLAYER_API_MODE_PARSE_STEP = 0x01,
|
||||
MEDIA_PLAYER_API_MODE_DECODE_STEP = 0x02,
|
||||
MEDIA_PLAYER_API_MODE_CONTINUOUS = 0x03
|
||||
} MEDIA_PLAYER_API_MODE;
|
||||
|
||||
typedef enum {
|
||||
/* Non-Stream Specific messages */
|
||||
MEDIA_PLAYER_FS_CTRL_MODE_INTERNAL = 0x00,
|
||||
MEDIA_PLAYER_FS_CTRL_MODE_EXTERNAL = 0x01
|
||||
} MEDIA_PLAYER_FS_CTRL_MODE;
|
||||
|
||||
typedef enum {
|
||||
/* Non-Stream Specific messages */
|
||||
VID_API_CMD_NULL = 0x00,
|
||||
VID_API_CMD_PARSE_NEXT_SEQ = 0x01,
|
||||
VID_API_CMD_PARSE_NEXT_I = 0x02,
|
||||
VID_API_CMD_PARSE_NEXT_IP = 0x03,
|
||||
VID_API_CMD_PARSE_NEXT_ANY = 0x04,
|
||||
VID_API_CMD_DEC_PIC = 0x05,
|
||||
VID_API_CMD_UPDATE_ES_WR_PTR = 0x06,
|
||||
VID_API_CMD_UPDATE_ES_RD_PTR = 0x07,
|
||||
VID_API_CMD_UPDATE_UDATA = 0x08,
|
||||
VID_API_CMD_GET_FSINFO = 0x09,
|
||||
VID_API_CMD_SKIP_PIC = 0x0a,
|
||||
VID_API_CMD_DEC_CHUNK = 0x0b,
|
||||
VID_API_CMD_START = 0x10,
|
||||
VID_API_CMD_STOP = 0x11,
|
||||
VID_API_CMD_ABORT = 0x12,
|
||||
VID_API_CMD_RST_BUF = 0x13,
|
||||
VID_API_CMD_FS_RELEASE = 0x15,
|
||||
VID_API_CMD_MEM_REGION_ATTACH = 0x16,
|
||||
VID_API_CMD_MEM_REGION_DETACH = 0x17,
|
||||
VID_API_CMD_MVC_VIEW_SELECT = 0x18,
|
||||
VID_API_CMD_FS_ALLOC = 0x19,
|
||||
VID_API_CMD_DBG_GET_STATUS = 0x1C,
|
||||
VID_API_CMD_DBG_START_LOG = 0x1D,
|
||||
VID_API_CMD_DBG_STOP_LOG = 0x1E,
|
||||
VID_API_CMD_DBG_DUMP_LOG = 0x1F,
|
||||
/* Begin Encode CMDs */
|
||||
VID_API_CMD_YUV_READY = 0x20,
|
||||
|
||||
VID_API_CMD_FIRM_RESET = 0x40,
|
||||
|
||||
#if BOOT_ARCH == REBOOT
|
||||
VID_API_CMD_SNAPSHOT = 0xAA,
|
||||
VID_API_CMD_ROLL_SNAPSHOT = 0xAB,
|
||||
VID_API_CMD_LOCK_SCHEDULER = 0xAC,
|
||||
VID_API_CMD_UNLOCK_SCHEDULER = 0xAD,
|
||||
#endif
|
||||
VID_API_CMD_CQ_FIFO_DUMP = 0xAE,
|
||||
VID_API_CMD_DBG_FIFO_DUMP = 0xAF,
|
||||
VID_API_CMD_SVC_ILP = 0xBB,
|
||||
VID_API_CMD_INVALID = 0xFF
|
||||
|
||||
} TB_API_DEC_CMD;
|
||||
|
||||
typedef enum {
|
||||
/* Non-Stream Specific messages */
|
||||
VID_API_EVENT_NULL = 0x00,
|
||||
VID_API_EVENT_RESET_DONE = 0x01,
|
||||
VID_API_EVENT_SEQ_HDR_FOUND = 0x02,
|
||||
VID_API_EVENT_PIC_HDR_FOUND = 0x03,
|
||||
VID_API_EVENT_PIC_DECODED = 0x04,
|
||||
VID_API_EVENT_FIFO_LOW = 0x05,
|
||||
VID_API_EVENT_FIFO_HIGH = 0x06,
|
||||
VID_API_EVENT_FIFO_EMPTY = 0x07,
|
||||
VID_API_EVENT_FIFO_FULL = 0x08,
|
||||
VID_API_EVENT_BS_ERROR = 0x09,
|
||||
VID_API_EVENT_UDATA_FIFO_UPTD = 0x0A,
|
||||
VID_API_EVENT_RES_CHANGE = 0x0B,
|
||||
VID_API_EVENT_FIFO_OVF = 0x0C,
|
||||
VID_API_EVENT_CHUNK_DECODED = 0x0D,
|
||||
VID_API_EVENT_REQ_FRAME_BUFF = 0x10,
|
||||
VID_API_EVENT_FRAME_BUFF_RDY = 0x11,
|
||||
VID_API_EVENT_REL_FRAME_BUFF = 0x12,
|
||||
VID_API_EVENT_STR_BUF_RST = 0x13,
|
||||
VID_API_EVENT_RET_PING = 0x14, /* Temp here - rationalise debug events at bottom */
|
||||
VID_API_EVENT_QMETER = 0x15,
|
||||
VID_API_EVENT_STR_FMT_CHANGE = 0x16,
|
||||
VID_API_EVENT_FIRMWARE_XCPT = 0x17,
|
||||
VID_API_EVENT_START_DONE = 0x18,
|
||||
VID_API_EVENT_STOPPED = 0x19,
|
||||
VID_API_EVENT_ABORT_DONE = 0x1A,
|
||||
VID_API_EVENT_FINISHED = 0x1B,
|
||||
VID_API_EVENT_DBG_STAT_UPDATE = 0x1C,
|
||||
VID_API_EVENT_DBG_LOG_STARTED = 0x1D,
|
||||
VID_API_EVENT_DBG_LOG_STOPPED = 0x1E,
|
||||
VID_API_EVENT_DBG_LOG_UPDATED = 0x1F,
|
||||
VID_API_EVENT_DBG_MSG_DEC = 0x20,
|
||||
VID_API_EVENT_DEC_SC_ERR = 0x21,
|
||||
VID_API_EVENT_CQ_FIFO_DUMP = 0x22,
|
||||
VID_API_EVENT_DBG_FIFO_DUMP = 0x23,
|
||||
VID_API_EVENT_DEC_CHECK_RES = 0x24,
|
||||
VID_API_EVENT_DEC_CFG_INFO = 0x25,
|
||||
VID_API_EVENT_SNAPSHOT_DONE = 0x40,
|
||||
VID_API_EVENT_INVALID = 0xFF
|
||||
|
||||
} TB_API_DEC_EVENT;
|
||||
|
||||
typedef enum {
|
||||
MEDIAIP_PLAYMODE_CONNECTIVITY = 0,
|
||||
MEDIAIP_PLAYMODE_BROADCAST,
|
||||
MEDIAIP_PLAYMODE_BROADCAST_DSS,
|
||||
MEDIAIP_PLAYMODE_LAST = MEDIAIP_PLAYMODE_BROADCAST_DSS
|
||||
|
||||
} MEDIA_IP_PLAYMODE;
|
||||
|
||||
typedef enum {
|
||||
MEDIA_IP_FMT_NULL = 0x0,
|
||||
MEDIA_IP_FMT_AVC = 0x1,
|
||||
MEDIA_IP_FMT_VC1 = 0x2,
|
||||
MEDIA_IP_FMT_MP2 = 0x3,
|
||||
MEDIA_IP_FMT_AVS = 0x4,
|
||||
MEDIA_IP_FMT_ASP = 0x5,
|
||||
MEDIA_IP_FMT_JPG = 0x6,
|
||||
MEDIA_IP_FMT_RV = 0x7,
|
||||
MEDIA_IP_FMT_VP6 = 0x8,
|
||||
MEDIA_IP_FMT_SPK = 0x9,
|
||||
MEDIA_IP_FMT_VP8 = 0xA,
|
||||
MEDIA_IP_FMT_MVC = 0xB,
|
||||
MEDIA_IP_FMT_VP3 = 0xC,
|
||||
MEDIA_IP_FMT_HEVC = 0xD,
|
||||
MEDIA_IP_FMT_AUTO_DETECT = 0xAD00,
|
||||
MEDIA_IP_FMT_ALL = (int)0xAAAAAAAA,
|
||||
MEDIA_IP_FMT_UNSUPPORTED = (int)0xFFFFFFFF,
|
||||
MEDIA_IP_FMT_LAST = MEDIA_IP_FMT_UNSUPPORTED
|
||||
|
||||
} MEDIA_IP_FORMAT;
|
||||
|
||||
typedef enum {
|
||||
VSys_FrmtNull = 0x0,
|
||||
VSys_AvcFrmt = 0x1,
|
||||
VSys_Mp2Frmt = 0x2,
|
||||
VSys_Vc1Frmt = 0x3,
|
||||
VSys_AvsFrmt = 0x4,
|
||||
VSys_AspFrmt = 0x5,
|
||||
VSys_JpgFrmt = 0x6,
|
||||
VSys_RvFrmt = 0x7,
|
||||
VSys_Vp6Frmt = 0x8,
|
||||
VSys_SpkFrmt = 0x9,
|
||||
VSys_Vp8Frmt = 0xA,
|
||||
VSys_HevcFrmt = 0xB,
|
||||
VSys_LastFrmt = VSys_HevcFrmt
|
||||
} TB_API_DEC_FMT;
|
||||
|
||||
typedef struct {
|
||||
u_int32 bTopFldFirst;
|
||||
u_int32 bRptFstField;
|
||||
u_int32 uDispVerRes;
|
||||
u_int32 uDispHorRes;
|
||||
u_int32 uCentreVerOffset;
|
||||
u_int32 uCentreHorOffset;
|
||||
u_int32 uCropLeftRightOffset;
|
||||
u_int32 uCropTopBotOffset;
|
||||
|
||||
} MediaIPFW_Video_PicDispInfo;
|
||||
|
||||
typedef struct MediaIPFW_PicPerfInfo {
|
||||
u_int32 uMemCRC;
|
||||
u_int32 uBSCRC;
|
||||
u_int32 uSlcActiveCnt;
|
||||
u_int32 uIBEmptyCnt;
|
||||
u_int32 uBaseMemCRC;
|
||||
|
||||
u_int32 uBaseCRCSkip;
|
||||
u_int32 uBaseCRCDrop;
|
||||
BOOL bBaseCRCValid;
|
||||
|
||||
u_int32 uCRC0;
|
||||
u_int32 uCRC1;
|
||||
u_int32 uCRC2;
|
||||
u_int32 uCRC3;
|
||||
u_int32 uCRC4;
|
||||
u_int32 uCRC5;
|
||||
|
||||
u_int32 uFrameActCount;
|
||||
u_int32 uRbspBytesCount;
|
||||
u_int32 uDpbReadCount;
|
||||
u_int32 uMprWaitCount;
|
||||
u_int32 uAccQP;
|
||||
u_int32 uCacheStat;
|
||||
u_int32 mbq_full;
|
||||
u_int32 mbq_empty;
|
||||
u_int32 slice_cnt;
|
||||
u_int32 mb_count;
|
||||
|
||||
u_int32 uTotalTime_us;
|
||||
u_int32 uTotalFwTime_us;
|
||||
|
||||
u_int32 uProcIaccTotRdCnt;
|
||||
u_int32 uProcDaccTotRdCnt;
|
||||
u_int32 uProcDaccTotWrCnt;
|
||||
u_int32 uProcDaccRegRdCnt;
|
||||
u_int32 uProcDaccRegWrCnt;
|
||||
u_int32 uProcDaccRngRdCnt;
|
||||
u_int32 uProcDaccRngWrCnt;
|
||||
|
||||
} MediaIPFW_Video_PicPerfInfo;
|
||||
|
||||
typedef struct {
|
||||
u_int32 mb_count;
|
||||
u_int32 slice_cnt;
|
||||
|
||||
/* Front End Metrics */
|
||||
u_int32 uDFEBinsUsed;
|
||||
u_int32 uDFECycleCount;
|
||||
u_int32 uDFESliceCycleCount;
|
||||
u_int32 uDFEIBWaitCount;
|
||||
u_int32 uDFENumBytes;
|
||||
|
||||
u_int32 uProcIaccTotRdCnt;
|
||||
u_int32 uProcDaccTotRdCnt;
|
||||
u_int32 uProcDaccTotWrCnt;
|
||||
u_int32 uProcDaccRegRdCnt;
|
||||
u_int32 uProcDaccRegWrCnt;
|
||||
u_int32 uProcDaccRngRdCnt;
|
||||
u_int32 uProcDaccRngWrCnt;
|
||||
|
||||
/* Back End metrics */
|
||||
u_int32 uNumBEUsed;
|
||||
u_int32 uTotalTime_us;
|
||||
u_int32 uTotalFwTime_us;
|
||||
u_int32 uDBECycleCount[0x2];
|
||||
u_int32 uDBESliceCycleCount[0x2];
|
||||
u_int32 uDBEMprWaitCount[0x2];
|
||||
u_int32 uDBEWaitCount[0x2];
|
||||
u_int32 uDBECRC[0x2];
|
||||
u_int32 uDBETotalTime_us[0x2];
|
||||
|
||||
u_int32 uDBEMPRPRXWaitCount[0x2];
|
||||
u_int32 uDBEPXDPRXWaitCount[0x2];
|
||||
u_int32 uDBEFCHPLQWaitCount[0x2];
|
||||
u_int32 uDBEPXDPLQWaitCount[0x2];
|
||||
|
||||
u_int32 uDBEFchWordsCount[0x2];
|
||||
u_int32 uDBEDpbCRC[0x2];
|
||||
u_int32 uDBEDpbReadCount[0x2];
|
||||
u_int32 uDBECacheStats[0x2];
|
||||
|
||||
} MediaIPFW_Video_PicPerfDcpInfo, *pMediaIPFW_Video_PicPerfDcpInfo;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uPicType;
|
||||
u_int32 uPicStruct;
|
||||
u_int32 bLastPicNPF;
|
||||
u_int32 uPicStAddr;
|
||||
u_int32 uFrameStoreID;
|
||||
MediaIPFW_Video_PicDispInfo DispInfo;
|
||||
MediaIPFW_Video_PicPerfInfo PerfInfo;
|
||||
MediaIPFW_Video_PicPerfDcpInfo PerfDcpInfo;
|
||||
u_int32 bUserDataAvail;
|
||||
u_int32 uPercentInErr;
|
||||
|
||||
u_int32 uBbdHorActive;
|
||||
u_int32 uBbdVerActive;
|
||||
u_int32 uBbdLogoActive;
|
||||
u_int32 uBbdBotPrev;
|
||||
u_int32 uBbdMinColPrj;
|
||||
u_int32 uBbdMinRowPrj;
|
||||
u_int32 uFSBaseAddr;
|
||||
|
||||
/* Only for RealVideo RPR */
|
||||
u_int32 uRprPicWidth;
|
||||
u_int32 uRprPicHeight;
|
||||
|
||||
/*only for divx3*/
|
||||
u_int32 uFrameRate;
|
||||
|
||||
} MediaIPFW_Video_PicInfo;
|
||||
|
||||
|
||||
typedef struct {
|
||||
u_int32 bClosedGop;
|
||||
u_int32 bBrokenLink;
|
||||
} MediaIPFW_Video_GopInfo;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uIQuant;
|
||||
u_int32 uIQuantAvail;
|
||||
u_int32 uGopBitRate;
|
||||
u_int32 uGopBitRateAvail;
|
||||
|
||||
} MediaIPFW_Video_QMeterInfo;
|
||||
|
||||
typedef struct {
|
||||
u_int32 pPicInfoArrayBase;
|
||||
u_int32 uNumSizeDescriptors;
|
||||
} MediaIPFW_Video_PicInfoBuffTabDesc;
|
||||
|
||||
typedef struct {
|
||||
u_int32 pGopInfoArrayBase;
|
||||
u_int32 uNumSizeDescriptors;
|
||||
} MediaIPFW_Video_GopInfoBuffTabDesc;
|
||||
|
||||
typedef struct {
|
||||
u_int32 pQMeterInfoArrayBase;
|
||||
u_int32 uNumSizeDescriptors;
|
||||
} MediaIPFW_Video_QMeterInfoTabDesc;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uMemChunkBase;
|
||||
u_int32 uMemChunkSize;
|
||||
|
||||
} MediaIPFW_Video_FrameBuffer;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uUDataBase;
|
||||
u_int32 uUDataTotalSize;
|
||||
u_int32 uUDataSlotSize;
|
||||
|
||||
} MediaIPFW_Video_UData;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uDecStatusLogBase;
|
||||
u_int32 uDecStatusLogSize;
|
||||
u_int32 uDTVLogBase[VID_API_NUM_STREAMS];
|
||||
u_int32 uDTVLogSize[VID_API_NUM_STREAMS];
|
||||
|
||||
} MediaIPFW_Video_DbgLogDesc;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uDTVLogBase[VID_API_NUM_STREAMS];
|
||||
u_int32 uDTVLogSize[VID_API_NUM_STREAMS];
|
||||
|
||||
} MediaIPFW_Video_EngAccessLogDesc;
|
||||
|
||||
typedef struct MediaIPFW_FrameStore {
|
||||
u_int32 uFrameStoreLumaBase;
|
||||
u_int32 uFrameStoreChromaBase;
|
||||
|
||||
} MediaIPFW_Video_FrameStore;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uAddrFirstDescriptor;
|
||||
u_int32 uNumSizeDescriptors;
|
||||
|
||||
} MediaIPFW_Video_StreamBuffTabDesc;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uAddrFirstDescriptor;
|
||||
u_int32 uNumSizeDescriptors;
|
||||
} MediaIPFW_Video_UserDataBuffTabDesc;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uNumRefFrms;
|
||||
u_int32 uNumDPBFrms;
|
||||
u_int32 uNumDFEAreas;
|
||||
u_int32 uColorDesc;
|
||||
u_int32 uProgressive;
|
||||
u_int32 uVerRes;
|
||||
u_int32 uHorRes;
|
||||
u_int32 uParWidth;
|
||||
u_int32 uParHeight;
|
||||
u_int32 FrameRate;
|
||||
u_int32 UDispAspRatio;
|
||||
u_int32 uLevelIDC;
|
||||
u_int32 uVerDecodeRes;
|
||||
u_int32 uHorDecodeRes;
|
||||
u_int32 uOverScan;
|
||||
u_int32 uChromaFmt;
|
||||
u_int32 uPAFF;
|
||||
u_int32 uMBAFF;
|
||||
u_int32 uBitDepthLuma;
|
||||
u_int32 uBitDepthChroma;
|
||||
u_int32 uMVCNumViews;
|
||||
u_int32 uMVCViewList[VID_API_MAX_NUM_MVC_VIEWS];
|
||||
u_int32 uFBCInUse;
|
||||
u_int32 uFrameCropValid;
|
||||
u_int32 uFrameCropLeftOffset;
|
||||
u_int32 uFrameCropRightOffset;
|
||||
u_int32 uFrameCropTopOffset;
|
||||
u_int32 uFrameCropBottomOffset;
|
||||
|
||||
} MediaIPFW_Video_SeqInfo;
|
||||
|
||||
typedef struct {
|
||||
u_int32 pSeqInfoArrayBase;
|
||||
u_int32 uNumSizeDescriptors;
|
||||
} MediaIPFW_Video_SeqInfoBuffTabDesc;
|
||||
|
||||
typedef struct {
|
||||
u_int32 wptr;
|
||||
u_int32 rptr;
|
||||
u_int32 start;
|
||||
u_int32 end;
|
||||
|
||||
} BUFFER_DESCRIPTOR_TYPE, *pBUFFER_DESCRIPTOR_TYPE;
|
||||
|
||||
typedef struct {
|
||||
u_int32 stream_input_mode;
|
||||
u_int32 stream_pic_input_count;
|
||||
u_int32 stream_pic_parsed_count;
|
||||
} BUFFER_INFO_TYPE, *pBUFFER_INFO_TYPE;
|
||||
|
||||
typedef struct {
|
||||
volatile u_int32 wptr;
|
||||
volatile u_int32 rptr;
|
||||
volatile u_int32 start;
|
||||
volatile u_int32 end;
|
||||
volatile u_int32 LWM;
|
||||
|
||||
} STREAM_BUFFER_DESCRIPTOR_TYPE, *pSTREAM_BUFFER_DESCRIPTOR_TYPE;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uRotationAngle;
|
||||
u_int32 uHorizScaleFactor;
|
||||
u_int32 uVertScaleFactor;
|
||||
u_int32 uRotationMode;
|
||||
u_int32 uRGBMode;
|
||||
u_int32 uChunkMode; /* 0 ~ 1 */
|
||||
u_int32 uLastChunk; /* 0 ~ 1 */
|
||||
u_int32 uChunkRows; /* 0 ~ 255 */
|
||||
u_int32 uNumBytes;
|
||||
u_int32 uJpgCropXStart;
|
||||
u_int32 uJpgCropYStart;
|
||||
u_int32 uJpgCropWidth;
|
||||
u_int32 uJpgCropHeight;
|
||||
u_int32 uJpgMjpegMode;
|
||||
u_int32 uJpgMjpegInterlaced;
|
||||
|
||||
} MediaIPFW_Video_JpegParams;
|
||||
|
||||
typedef struct {
|
||||
u_int32 pJpegParamArrayBase;
|
||||
u_int32 uNumSizeDescriptors;
|
||||
|
||||
} MediaIPFW_Video_JpegParamTabDesc;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uDispImm;
|
||||
u_int32 uFourCC;
|
||||
u_int32 uCodecVersion;
|
||||
u_int32 uFrameRate;
|
||||
u_int32 uEnableDbgLog;
|
||||
u_int32 bbd_lum_thr;
|
||||
u_int32 bbd_coring;
|
||||
u_int32 bbd_s_thr_row;
|
||||
u_int32 bbd_p_thr_row;
|
||||
u_int32 bbd_s_thr_logo_row;
|
||||
u_int32 bbd_p_thr_logo_row;
|
||||
u_int32 bbd_s_thr_col;
|
||||
u_int32 bbd_p_thr_col;
|
||||
u_int32 bbd_chr_thr_row;
|
||||
u_int32 bbd_chr_thr_col;
|
||||
u_int32 bbd_uv_mid_level;
|
||||
u_int32 bbd_excl_win_mb_left;
|
||||
u_int32 bbd_excl_win_mb_right;
|
||||
|
||||
} MediaIPFW_Video_CodecParams;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uFramePitch;
|
||||
|
||||
} MediaIPFW_Video_PitchInfo;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uWrPtr;
|
||||
u_int32 uRdPtr;
|
||||
u_int32 uStart;
|
||||
u_int32 uEnd;
|
||||
u_int32 uLo;
|
||||
u_int32 uHi;
|
||||
|
||||
} MediaIPFW_Video_BufDesc;
|
||||
|
||||
typedef struct {
|
||||
u_int32 pCodecParamArrayBase;
|
||||
u_int32 uNumSizeDescriptors;
|
||||
|
||||
} MediaIPFW_Video_CodecParamTabDesc;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uRC4Key[0x8];
|
||||
u_int32 uMemObfuscVal;
|
||||
|
||||
} MediaIPFW_Video_Encrypt_Info, *pMediaIPFW_Video_Encrypt_Info;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uCfgCookie;
|
||||
|
||||
u_int32 uNumMalones;
|
||||
u_int32 uMaloneBaseAddress[MEDIAIP_MAX_NUM_MALONES];
|
||||
u_int32 uHifOffset[MEDIAIP_MAX_NUM_MALONES];
|
||||
u_int32 uMaloneIrqPin[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
|
||||
u_int32 uMaloneIrqTarget[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
|
||||
|
||||
u_int32 uNumWindsors;
|
||||
u_int32 uWindsorBaseAddress[MEDIAIP_MAX_NUM_WINDSORS];
|
||||
u_int32 uWindsorIrqPin[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
|
||||
u_int32 uWindsorIrqTarget[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
|
||||
|
||||
u_int32 uCmdIrqPin[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
|
||||
u_int32 uCmdIrqTarget[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
|
||||
|
||||
u_int32 uMsgIrqPin[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
|
||||
u_int32 uMsgIrqTarget[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
|
||||
|
||||
u_int32 uSysClkFreq;
|
||||
u_int32 uNumTimers;
|
||||
u_int32 uTimerBaseAddr;
|
||||
u_int32 uTimerIrqPin[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
|
||||
u_int32 uTimerIrqTarget[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
|
||||
u_int32 uTimerSlots[MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS];
|
||||
|
||||
u_int32 uGICBaseAddr;
|
||||
u_int32 uUartBaseAddr;
|
||||
|
||||
u_int32 uDPVBaseAddr;
|
||||
u_int32 uDPVIrqPin;
|
||||
u_int32 uDPVIrqTarget;
|
||||
|
||||
u_int32 uPixIfBaseAddr;
|
||||
|
||||
u_int32 pal_trace_level;
|
||||
u_int32 pal_trace_destination;
|
||||
|
||||
u_int32 pal_trace_level1;
|
||||
u_int32 pal_trace_destination1;
|
||||
|
||||
u_int32 uHeapBase;
|
||||
u_int32 uHeapSize;
|
||||
|
||||
u_int32 uFSLCacheBaseAddr[2];
|
||||
|
||||
} MEDIAIP_FW_SYSTEM_CONFIG, *pMEDIAIP_FW_SYSTEM_CONFIG;
|
||||
|
||||
typedef struct {
|
||||
u_int32 FwExecBaseAddr;
|
||||
u_int32 FwExecAreaSize;
|
||||
MediaIPFW_Video_BufDesc StreamCmdBufferDesc;
|
||||
MediaIPFW_Video_BufDesc StreamMsgBufferDesc;
|
||||
u_int32 StreamCmdIntEnable[VID_API_NUM_STREAMS];
|
||||
MediaIPFW_Video_PitchInfo StreamPitchInfo[VID_API_NUM_STREAMS];
|
||||
u_int32 StreamConfig[VID_API_NUM_STREAMS];
|
||||
MediaIPFW_Video_CodecParamTabDesc CodecParamTabDesc; /* TODO-KMC should we just go ahead and remove the concept of tabdesc? It is basicaly a bad coding style used for pinkys anyway */
|
||||
MediaIPFW_Video_JpegParamTabDesc JpegParamTabDesc;
|
||||
#ifdef COREPLAY_API
|
||||
pBUFFER_DESCRIPTOR_TYPE pStreamBuffDesc[VID_API_NUM_STREAMS][VID_API_MAX_BUF_PER_STR];
|
||||
#else
|
||||
u_int32 pStreamBuffDesc[VID_API_NUM_STREAMS][VID_API_MAX_BUF_PER_STR];
|
||||
#endif
|
||||
MediaIPFW_Video_SeqInfoBuffTabDesc SeqInfoTabDesc;
|
||||
MediaIPFW_Video_PicInfoBuffTabDesc PicInfoTabDesc;
|
||||
MediaIPFW_Video_GopInfoBuffTabDesc GopInfoTabDesc;
|
||||
MediaIPFW_Video_QMeterInfoTabDesc QMeterInfoTabDesc;
|
||||
u_int32 StreamError[VID_API_NUM_STREAMS];
|
||||
u_int32 FWVersion;
|
||||
u_int32 uMVDMipsOffset;
|
||||
u_int32 uMaxDecoderStreams;
|
||||
MediaIPFW_Video_DbgLogDesc DbgLogDesc;
|
||||
MediaIPFW_Video_FrameBuffer StreamFrameBuffer[VID_API_NUM_STREAMS];
|
||||
MediaIPFW_Video_FrameBuffer StreamDCPBuffer[VID_API_NUM_STREAMS];
|
||||
MediaIPFW_Video_UData UDataBuffer[VID_API_NUM_STREAMS];
|
||||
MediaIPFW_Video_BufDesc DebugBufferDesc;
|
||||
MediaIPFW_Video_BufDesc EngAccessBufferDesc[VID_API_NUM_STREAMS];
|
||||
u_int32 ptEncryptInfo[VID_API_NUM_STREAMS];
|
||||
MEDIAIP_FW_SYSTEM_CONFIG sSystemCfg;
|
||||
u_int32 uApiVersion;
|
||||
BUFFER_INFO_TYPE StreamBuffInfo[VID_API_NUM_STREAMS];
|
||||
} DEC_RPC_HOST_IFACE, *pDEC_RPC_HOST_IFACE;
|
||||
|
||||
//x means source data , y means destination data
|
||||
#define VID_STREAM_CONFIG_FORMAT_MASK 0x0000000F
|
||||
#define VID_STREAM_CONFIG_FORMAT_POS 0
|
||||
#define VID_STREAM_CONFIG_FORMAT_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_FORMAT_POS)&VID_STREAM_CONFIG_FORMAT_MASK)))
|
||||
|
||||
#define VID_STREAM_CONFIG_STRBUFIDX_MASK 0x00000300
|
||||
#define VID_STREAM_CONFIG_STRBUFIDX_POS 8
|
||||
#define VID_STREAM_CONFIG_STRBUFIDX_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_STRBUFIDX_POS)&VID_STREAM_CONFIG_STRBUFIDX_MASK)))
|
||||
|
||||
#define VID_STREAM_CONFIG_NOSEQ_MASK 0x00000400
|
||||
#define VID_STREAM_CONFIG_NOSEQ_POS 10
|
||||
#define VID_STREAM_CONFIG_NOSEQ_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_NOSEQ_POS)&VID_STREAM_CONFIG_NOSEQ_MASK)))
|
||||
|
||||
#define VID_STREAM_CONFIG_DEBLOCK_MASK 0x00000800
|
||||
#define VID_STREAM_CONFIG_DEBLOCK_POS 11
|
||||
#define VID_STREAM_CONFIG_DEBLOCK_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_DEBLOCK_POS)&VID_STREAM_CONFIG_DEBLOCK_MASK)))
|
||||
|
||||
#define VID_STREAM_CONFIG_DERING_MASK 0x00001000
|
||||
#define VID_STREAM_CONFIG_DERING_POS 12
|
||||
#define VID_STREAM_CONFIG_DERING_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_DERING_POS)&VID_STREAM_CONFIG_DERING_MASK)))
|
||||
|
||||
#define VID_STREAM_CONFIG_IBWAIT_MASK 0x00002000
|
||||
#define VID_STREAM_CONFIG_IBWAIT_POS 13
|
||||
#define VID_STREAM_CONFIG_IBWAIT_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_IBWAIT_POS)&VID_STREAM_CONFIG_IBWAIT_MASK)))
|
||||
|
||||
#define VID_STREAM_CONFIG_FBC_MASK 0x00004000
|
||||
#define VID_STREAM_CONFIG_FBC_POS 14
|
||||
#define VID_STREAM_CONFIG_FBC_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_FBC_POS)&VID_STREAM_CONFIG_FBC_MASK)))
|
||||
|
||||
#define VID_STREAM_CONFIG_PLAY_MODE_MASK 0x00030000
|
||||
#define VID_STREAM_CONFIG_PLAY_MODE_POS 16
|
||||
#define VID_STREAM_CONFIG_PLAY_MODE_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_PLAY_MODE_POS)&VID_STREAM_CONFIG_PLAY_MODE_MASK)))
|
||||
|
||||
#define VID_STREAM_CONFIG_ENABLE_DCP_MASK 0x00100000
|
||||
#define VID_STREAM_CONFIG_ENABLE_DCP_POS 20
|
||||
#define VID_STREAM_CONFIG_ENABLE_DCP_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_ENABLE_DCP_POS)&VID_STREAM_CONFIG_ENABLE_DCP_MASK)))
|
||||
|
||||
#define VID_STREAM_CONFIG_NUM_STR_BUF_MASK 0x00600000
|
||||
#define VID_STREAM_CONFIG_NUM_STR_BUF_POS 21
|
||||
#define VID_STREAM_CONFIG_NUM_STR_BUF_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_NUM_STR_BUF_POS)&VID_STREAM_CONFIG_NUM_STR_BUF_MASK)))
|
||||
|
||||
#define VID_STREAM_CONFIG_MALONE_USAGE_MASK 0x01800000
|
||||
#define VID_STREAM_CONFIG_MALONE_USAGE_POS 23
|
||||
#define VID_STREAM_CONFIG_MALONE_USAGE_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_MALONE_USAGE_POS)&VID_STREAM_CONFIG_MALONE_USAGE_MASK)))
|
||||
|
||||
#define VID_STREAM_CONFIG_MULTI_VID_MASK 0x02000000
|
||||
#define VID_STREAM_CONFIG_MULTI_VID_POS 25
|
||||
#define VID_STREAM_CONFIG_MULTI_VID_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_MULTI_VID_POS)&VID_STREAM_CONFIG_MULTI_VID_MASK)))
|
||||
|
||||
#define VID_STREAM_CONFIG_OBFUSC_EN_MASK 0x04000000
|
||||
#define VID_STREAM_CONFIG_OBFUSC_EN_POS 26
|
||||
#define VID_STREAM_CONFIG_OBFUSC_EN_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_OBFUSC_EN_POS)&VID_STREAM_CONFIG_OBFUSC_EN_MASK)))
|
||||
|
||||
#define VID_STREAM_CONFIG_RC4_EN_MASK 0x08000000
|
||||
#define VID_STREAM_CONFIG_RC4_EN_POS 27
|
||||
#define VID_STREAM_CONFIG_RC4_EN_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_RC4_EN_POS)&VID_STREAM_CONFIG_RC4_EN_MASK)))
|
||||
|
||||
#define VID_STREAM_CONFIG_MCX_MASK 0x10000000
|
||||
#define VID_STREAM_CONFIG_MCX_POS 28
|
||||
#define VID_STREAM_CONFIG_MCX_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_MCX_POS)&VID_STREAM_CONFIG_MCX_MASK)))
|
||||
|
||||
#define VID_STREAM_CONFIG_PES_MASK 0x20000000
|
||||
#define VID_STREAM_CONFIG_PES_POS 29
|
||||
#define VID_STREAM_CONFIG_PES_SET(x, y) ((*y = (*y | ((x << VID_STREAM_CONFIG_PES_POS)&VID_STREAM_CONFIG_PES_MASK))))
|
||||
|
||||
#define VID_STREAM_CONFIG_NUM_DBE_MASK 0x40000000
|
||||
#define VID_STREAM_CONFIG_NUM_DBE_POS 30
|
||||
#define VID_STREAM_CONFIG_NUM_DBE_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_NUM_DBE_POS)&VID_STREAM_CONFIG_NUM_DBE_MASK)))
|
||||
|
||||
#define VID_STREAM_CONFIG_FS_CTRL_MODE_MASK 0x80000000
|
||||
#define VID_STREAM_CONFIG_FS_CTRL_MODE_POS 31
|
||||
#define VID_STREAM_CONFIG_FS_CTRL_MODE_SET(x, y) (*y = (*y | ((x << VID_STREAM_CONFIG_FS_CTRL_MODE_POS)&VID_STREAM_CONFIG_FS_CTRL_MODE_MASK)))
|
||||
|
||||
#define SCB_XREG_SLV_BASE 0x00000000
|
||||
#define SCB_SCB_BLK_CTRL 0x00070000
|
||||
#define SCB_BLK_CTRL_XMEM_RESET_SET 0x00000090
|
||||
#define SCB_BLK_CTRL_CACHE_RESET_SET 0x000000A0
|
||||
#define SCB_BLK_CTRL_CACHE_RESET_CLR 0x000000A4
|
||||
#define SCB_BLK_CTRL_SCB_CLK_ENABLE_SET 0x00000100
|
||||
|
||||
#define XMEM_CONTROL 0x00041000
|
||||
|
||||
#define DEC_MFD_XREG_SLV_BASE 0x00180000
|
||||
|
||||
#define MFD_HIF 0x0001C000
|
||||
#define MFD_HIF_MSD_REG_INTERRUPT_STATUS 0x00000018
|
||||
#define MFD_SIF 0x0001D000
|
||||
#define MFD_SIF_CTRL_STATUS 0x000000F0
|
||||
#define MFD_SIF_INTR_STATUS 0x000000F4
|
||||
#define MFD_MCX 0x00020800
|
||||
#define MFD_MCX_OFF 0x00000020
|
||||
|
||||
#define MFD_BLK_CTRL 0x00030000
|
||||
#define MFD_BLK_CTRL_MFD_SYS_RESET_SET 0x00000000
|
||||
#define MFD_BLK_CTRL_MFD_SYS_RESET_CLR 0x00000004
|
||||
#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET 0x00000100
|
||||
#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_CLR 0x00000104
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,320 @@
|
|||
/*
|
||||
* Copyright 2018 NXP
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU Lesser General
|
||||
* Public License. You may obtain a copy of the GNU Lesser General
|
||||
* Public License Version 2.1 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/lgpl-license.html
|
||||
* http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file vpu_b0.h
|
||||
*
|
||||
* @brief VPU B0 definition
|
||||
*
|
||||
*/
|
||||
#ifndef __VPU_B0_H
|
||||
#define __VPU_B0_H
|
||||
|
||||
#include <linux/irqreturn.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#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 <linux/mx8_mu.h>
|
||||
#include <media/v4l2-event.h>
|
||||
#include <linux/kfifo.h>
|
||||
#include "vpu_rpc.h"
|
||||
|
||||
extern unsigned int vpu_dbg_level_decoder;
|
||||
|
||||
#define v4l2_fh_to_ctx(__fh) \
|
||||
container_of(__fh, struct vpu_ctx, fh)
|
||||
#define v4l2_ctrl_to_ctx(__ctrl) \
|
||||
container_of((__ctrl)->handler, struct vpu_ctx, ctrl_handler)
|
||||
|
||||
#define MIN_SPACE (SCODE_SIZE + 64)
|
||||
#define SCODE_SIZE (4096)
|
||||
|
||||
#define VPU_MAX_BUFFER 32
|
||||
#define M0FW_FILENAME "vpu/vpu_fw_imx8_dec.bin"
|
||||
#define MMAP_BUF_TYPE_SHIFT 28
|
||||
#define MMAP_BUF_TYPE_MASK 0xF0000000
|
||||
#define DCP_SIZE 0x3000000
|
||||
#define MAX_BUFFER_SIZE 0xc00000
|
||||
#define UDATA_BUFFER_SIZE 0x1000
|
||||
#define MAX_DCP_NUM 2
|
||||
#define MAX_MBI_NUM 18 // same with MEDIA_PLAYER_MAX_MBI_UNIT defined in firmware
|
||||
#define MAX_TIMEOUT_COUNT 10
|
||||
#define VPU_REG_BASE 0x40000000
|
||||
|
||||
#define V4L2_MAX_CTRLS 12
|
||||
#define V4L2_PIX_FMT_NV12_10BIT v4l2_fourcc('N', 'T', '1', '2') /* Y/CbCr 4:2:0 for 10bit */
|
||||
#define INVALID_FRAME_DEPTH -1
|
||||
#define DECODER_NODE_NUMBER 12 // use /dev/video12 as vpu decoder
|
||||
#define DEFAULT_LOG_DEPTH 20
|
||||
#define V4L2_EVENT_SKIP 8
|
||||
|
||||
struct vpu_v4l2_control {
|
||||
uint32_t id;
|
||||
enum v4l2_ctrl_type type;
|
||||
uint32_t minimum;
|
||||
uint32_t maximum;
|
||||
uint32_t step;
|
||||
uint32_t default_value;
|
||||
uint32_t menu_skip_mask;
|
||||
bool is_volatile;
|
||||
};
|
||||
|
||||
typedef enum{
|
||||
INIT_DONE = 1,
|
||||
RPC_BUF_OFFSET,
|
||||
BOOT_ADDRESS,
|
||||
COMMAND,
|
||||
EVENT
|
||||
} MSG_Type;
|
||||
|
||||
enum PLAT_TYPE {
|
||||
IMX8QXP = 0,
|
||||
IMX8QM = 1,
|
||||
};
|
||||
|
||||
enum QUEUE_TYPE {
|
||||
V4L2_SRC = 0,
|
||||
V4L2_DST = 1,
|
||||
};
|
||||
|
||||
enum vpu_video_standard {
|
||||
VPU_VIDEO_UNDEFINED = 0,
|
||||
VPU_VIDEO_AVC = 1,
|
||||
VPU_VIDEO_VC1 = 2,
|
||||
VPU_VIDEO_MPEG2 = 3,
|
||||
VPU_VIDEO_AVS = 4,
|
||||
VPU_VIDEO_ASP = 5,
|
||||
VPU_VIDEO_JPEG = 6,
|
||||
VPU_VIDEO_RV = 7,
|
||||
VPU_VIDEO_VP6 = 8,
|
||||
VPU_VIDEO_SPK = 9,
|
||||
VPU_VIDEO_VP8 = 10,
|
||||
VPU_VIDEO_AVC_MVC = 11,
|
||||
VPU_VIDEO_HEVC = 12,
|
||||
};
|
||||
|
||||
typedef enum{
|
||||
EOS_PADDING_TYPE = 1,
|
||||
BUFFLUSH_PADDING_TYPE = 2,
|
||||
BUFABORT_PADDING_TYPE = 3,
|
||||
} VPU_PADDING_SCODE_TYPE;
|
||||
|
||||
#define VPU_PIX_FMT_AVS v4l2_fourcc('A', 'V', 'S', '0')
|
||||
#define VPU_PIX_FMT_ASP v4l2_fourcc('A', 'S', 'P', '0')
|
||||
#define VPU_PIX_FMT_RV v4l2_fourcc('R', 'V', '0', '0')
|
||||
#define VPU_PIX_FMT_VP6 v4l2_fourcc('V', 'P', '6', '0')
|
||||
#define VPU_PIX_FMT_SPK v4l2_fourcc('S', 'P', 'K', '0')
|
||||
#define VPU_PIX_FMT_DIVX v4l2_fourcc('D', 'I', 'V', 'X')
|
||||
#define VPU_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C')
|
||||
#define VPU_PIX_FMT_LOGO v4l2_fourcc('L', 'O', 'G', 'O')
|
||||
|
||||
#define VPU_PIX_FMT_TILED_8 v4l2_fourcc('Z', 'T', '0', '8')
|
||||
#define VPU_PIX_FMT_TILED_10 v4l2_fourcc('Z', 'T', '1', '0')
|
||||
|
||||
#define V4L2_CID_USER_RAW_BASE (V4L2_CID_USER_BASE + 0x1100)
|
||||
|
||||
enum vpu_pixel_format {
|
||||
VPU_HAS_COLOCATED = 0x00000001,
|
||||
VPU_HAS_SPLIT_FLD = 0x00000002,
|
||||
VPU_PF_MASK = ~(VPU_HAS_COLOCATED | VPU_HAS_SPLIT_FLD),
|
||||
|
||||
VPU_IS_TILED = 0x000000100,
|
||||
VPU_HAS_10BPP = 0x00000200,
|
||||
|
||||
VPU_IS_PLANAR = 0x00001000,
|
||||
VPU_IS_SEMIPLANAR = 0x00002000,
|
||||
VPU_IS_PACKED = 0x00004000,
|
||||
|
||||
// Merged definitions using above flags:
|
||||
VPU_PF_UNDEFINED = 0,
|
||||
VPU_PF_YUV420_SEMIPLANAR = 0x00010000 | VPU_IS_SEMIPLANAR,
|
||||
VPU_PF_YUV420_PLANAR = 0x00020000 | VPU_IS_PLANAR,
|
||||
VPU_PF_UYVY = 0x00040000 | VPU_IS_PACKED,
|
||||
VPU_PF_TILED_8BPP = 0x00080000 | VPU_IS_TILED | VPU_IS_SEMIPLANAR,
|
||||
VPU_PF_TILED_10BPP = 0x00100000 | VPU_IS_TILED | VPU_IS_SEMIPLANAR | VPU_HAS_10BPP,
|
||||
};
|
||||
|
||||
struct vpu_v4l2_fmt {
|
||||
char *name;
|
||||
unsigned int fourcc;
|
||||
unsigned int num_planes;
|
||||
unsigned int vdec_std;
|
||||
unsigned int disable;
|
||||
};
|
||||
|
||||
struct vb2_data_req {
|
||||
struct list_head list;
|
||||
struct vb2_buffer *vb2_buf;
|
||||
int id;
|
||||
u_int32 status;
|
||||
bool bfield;
|
||||
u_int32 phy_addr[2]; //0 for luma, 1 for chroma
|
||||
u_int32 data_offset[2]; //0 for luma, 1 for chroma
|
||||
};
|
||||
|
||||
struct queue_data {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int stride;
|
||||
unsigned int bytesperline;
|
||||
unsigned int num_planes;
|
||||
unsigned int sizeimage[2];
|
||||
unsigned int fourcc;
|
||||
unsigned int vdec_std;
|
||||
struct v4l2_rect rect;
|
||||
int buf_type; // v4l2_buf_type
|
||||
bool vb2_q_inited;
|
||||
struct vb2_queue vb2_q; // vb2 queue
|
||||
struct list_head drv_q; // driver queue
|
||||
struct semaphore drv_q_lock;
|
||||
struct vb2_data_req vb2_reqs[VPU_MAX_BUFFER];
|
||||
enum QUEUE_TYPE type;
|
||||
};
|
||||
struct vpu_ctx;
|
||||
struct vpu_dev {
|
||||
struct device *generic_dev;
|
||||
struct v4l2_device v4l2_dev;
|
||||
struct video_device *pvpu_decoder_dev;
|
||||
struct platform_device *plat_dev;
|
||||
struct firmware *m0_pfw;
|
||||
void *m0_p_fw_space_vir;
|
||||
u_int32 m0_p_fw_space_phy;
|
||||
u_int32 m0_boot_size;
|
||||
void *m0_rpc_virt;
|
||||
u_int32 m0_rpc_phy;
|
||||
u_int32 m0_rpc_size;
|
||||
struct mutex dev_mutex;
|
||||
struct mutex cmd_mutex;
|
||||
bool fw_is_ready;
|
||||
bool firmware_started;
|
||||
struct completion start_cmp;
|
||||
struct completion snap_done_cmp;
|
||||
struct workqueue_struct *workqueue;
|
||||
struct work_struct msg_work;
|
||||
unsigned long instance_mask;
|
||||
unsigned long hang_mask; //this is used to deal with hang issue to reset firmware
|
||||
//sc_ipc_t mu_ipcHandle;
|
||||
struct clk *vpu_clk;
|
||||
void __iomem *mu_base_virtaddr;
|
||||
unsigned int vpu_mu_id;
|
||||
int vpu_mu_init;
|
||||
u_int32 plat_type;
|
||||
|
||||
struct clk *clk_m0;
|
||||
void __iomem *regs_base;
|
||||
void __iomem *csr_base;
|
||||
u_int32 cm_offset;
|
||||
|
||||
struct shared_addr shared_mem;
|
||||
struct vpu_ctx *ctx[VPU_MAX_NUM_STREAMS];
|
||||
struct dentry *debugfs_root;
|
||||
|
||||
struct device *pd_vpu;
|
||||
struct device *pd_dec;
|
||||
struct device *pd_mu;
|
||||
};
|
||||
|
||||
struct vpu_statistic {
|
||||
unsigned long cmd[VID_API_CMD_YUV_READY + 2];
|
||||
unsigned long event[VID_API_EVENT_DEC_CFG_INFO + 2];
|
||||
unsigned long current_cmd;
|
||||
unsigned long current_event;
|
||||
struct timespec ts_cmd;
|
||||
struct timespec ts_event;
|
||||
atomic64_t total_dma_size;
|
||||
atomic64_t total_alloc_size;
|
||||
};
|
||||
|
||||
struct dma_buffer {
|
||||
dma_addr_t dma_phy;
|
||||
void *dma_virt;
|
||||
u_int32 dma_size;
|
||||
};
|
||||
|
||||
struct vpu_ctx {
|
||||
struct vpu_dev *dev;
|
||||
struct v4l2_fh fh;
|
||||
|
||||
struct vpu_statistic statistic;
|
||||
atomic64_t total_alloc_size;
|
||||
struct device_attribute dev_attr_instance_command;
|
||||
char command_name[64];
|
||||
struct device_attribute dev_attr_instance_event;
|
||||
char event_name[64];
|
||||
struct device_attribute dev_attr_instance_buffer;
|
||||
char buffer_name[64];
|
||||
struct device_attribute dev_attr_instance_flow;
|
||||
char flow_name[64];
|
||||
struct dentry *dbglog_dir;
|
||||
char dbglog_name[64];
|
||||
struct v4l2_ctrl *ctrls[V4L2_MAX_CTRLS];
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
bool ctrl_inited;
|
||||
struct list_head log_q;
|
||||
|
||||
int str_index;
|
||||
struct queue_data q_data[2];
|
||||
struct kfifo msg_fifo;
|
||||
struct mutex instance_mutex;
|
||||
struct work_struct instance_work;
|
||||
struct workqueue_struct *instance_wq;
|
||||
struct completion completion;
|
||||
struct completion stop_cmp;
|
||||
struct completion eos_cmp;
|
||||
MediaIPFW_Video_SeqInfo *pSeqinfo;
|
||||
bool b_dis_reorder;
|
||||
bool b_firstseq;
|
||||
bool start_flag;
|
||||
bool wait_abort_done;
|
||||
bool wait_rst_done;
|
||||
bool buffer_null;
|
||||
bool firmware_stopped;
|
||||
bool firmware_finished;
|
||||
bool eos_stop_received;
|
||||
bool eos_stop_added;
|
||||
bool ctx_released;
|
||||
bool start_code_bypass;
|
||||
bool hang_status;
|
||||
wait_queue_head_t buffer_wq;
|
||||
u_int32 mbi_count;
|
||||
u_int32 mbi_num;
|
||||
u_int32 dcp_count;
|
||||
struct dma_buffer dpb_buffer;
|
||||
struct dma_buffer dcp_buffer[MAX_DCP_NUM];
|
||||
struct dma_buffer mbi_buffer[MAX_MBI_NUM];
|
||||
struct dma_buffer stream_buffer;
|
||||
struct dma_buffer udata_buffer;
|
||||
|
||||
int frm_dis_delay;
|
||||
int frm_dec_delay;
|
||||
int frm_total_num;
|
||||
};
|
||||
|
||||
#define LVL_INFO 3
|
||||
#define LVL_EVENT 2
|
||||
#define LVL_WARN 1
|
||||
#define LVL_ERR 0
|
||||
|
||||
#define vpu_dbg(level, fmt, arg...) \
|
||||
do { \
|
||||
if (vpu_dbg_level_decoder >= (level)) \
|
||||
printk("[VPU Decoder]\t " fmt, ## arg); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright 2018 NXP
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file vpu-debug_log.c
|
||||
*
|
||||
* copyright here may be changed later
|
||||
*
|
||||
*
|
||||
*/
|
||||
#include "vpu_debug_log.h"
|
||||
|
||||
int init_log_info_queue(struct vpu_ctx *ctx)
|
||||
{
|
||||
if (!ctx)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
INIT_LIST_HEAD(&ctx->log_q);
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int create_log_info_queue(struct vpu_ctx *ctx, u_int32 vpu_log_depth)
|
||||
{
|
||||
struct vpu_log_info *vpu_info = NULL;
|
||||
u_int32 i;
|
||||
|
||||
if (!ctx)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < vpu_log_depth; i++) {
|
||||
vpu_info = kzalloc(sizeof(*vpu_info), GFP_KERNEL);
|
||||
if (!vpu_info)
|
||||
continue;
|
||||
|
||||
atomic64_add(sizeof(*vpu_info), &ctx->statistic.total_alloc_size);
|
||||
list_add_tail(&vpu_info->list, &ctx->log_q);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int destroy_log_info_queue(struct vpu_ctx *ctx)
|
||||
{
|
||||
struct vpu_log_info *vpu_info, *temp_info;
|
||||
u_int32 ret = 0;
|
||||
|
||||
if (!ctx)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
if (list_empty(&ctx->log_q)) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
list_for_each_entry_safe(vpu_info, temp_info, &ctx->log_q, list)
|
||||
if (vpu_info) {
|
||||
list_del_init(&vpu_info->list);
|
||||
kfree(vpu_info);
|
||||
atomic64_sub(sizeof(*vpu_info), &ctx->statistic.total_alloc_size);
|
||||
}
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int put_log_info(struct vpu_ctx *ctx, struct vpu_log_info *vpu_info)
|
||||
{
|
||||
if (!ctx || !vpu_info)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
list_add_tail(&vpu_info->list, &ctx->log_q);
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct vpu_log_info *pop_log_info(struct vpu_ctx *ctx)
|
||||
{
|
||||
struct vpu_log_info *vpu_info = NULL;
|
||||
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
if (list_empty(&ctx->log_q))
|
||||
vpu_info = NULL;
|
||||
vpu_info = list_first_entry(&ctx->log_q, struct vpu_log_info, list);
|
||||
if (vpu_info)
|
||||
list_del_init(&vpu_info->list);
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
return vpu_info;
|
||||
}
|
||||
|
||||
int set_log_info(struct vpu_log_info *vpu_info, enum ACTION_TYPE type, u_int32 info, u_int32 info_data)
|
||||
{
|
||||
if (!vpu_info)
|
||||
return -EINVAL;
|
||||
if (type >= LOG_RESERVED)
|
||||
return -EINVAL;
|
||||
|
||||
vpu_info->type = type;
|
||||
vpu_info->log_info[type] = info;
|
||||
vpu_info->data = info_data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int record_log_info(struct vpu_ctx *ctx, enum ACTION_TYPE type, u_int32 info, u_int32 info_data)
|
||||
{
|
||||
struct vpu_log_info *vpu_info = NULL;
|
||||
|
||||
if (!ctx)
|
||||
return -EINVAL;
|
||||
|
||||
vpu_info = pop_log_info(ctx);
|
||||
if (!vpu_info)
|
||||
return -EINVAL;
|
||||
set_log_info(vpu_info, type, info, info_data);
|
||||
put_log_info(ctx, vpu_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright 2018 NXP
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU Lesser General
|
||||
* Public License. You may obtain a copy of the GNU Lesser General
|
||||
* Public License Version 2.1 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/lgpl-license.html
|
||||
* http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file vpu_debug_log.h
|
||||
*
|
||||
* @brief VPU debug definition
|
||||
*
|
||||
*/
|
||||
#ifndef _VPU_DEBUG_LOG_H_
|
||||
#define _VPU_DEBUG_LOG_H_
|
||||
#include "vpu_b0.h"
|
||||
enum ACTION_TYPE {
|
||||
LOG_NULL = 0,
|
||||
LOG_EVENT,
|
||||
LOG_COMMAND,
|
||||
LOG_PADDING,
|
||||
LOG_EOS,
|
||||
LOG_UPDATE_STREAM,
|
||||
LOG_RESERVED,
|
||||
};
|
||||
|
||||
struct vpu_log_info {
|
||||
struct list_head list;
|
||||
enum ACTION_TYPE type;
|
||||
u_int32 log_info[LOG_RESERVED];
|
||||
u_int32 data;
|
||||
};
|
||||
int init_log_info_queue(struct vpu_ctx *ctx);
|
||||
int create_log_info_queue(struct vpu_ctx *ctx, u_int32 vpu_log_depth);
|
||||
int destroy_log_info_queue(struct vpu_ctx *ctx);
|
||||
int put_log_info(struct vpu_ctx *ctx, struct vpu_log_info *vpu_info);
|
||||
struct vpu_log_info *pop_log_info(struct vpu_ctx *ctx);
|
||||
int set_log_info(struct vpu_log_info *vpu_info, enum ACTION_TYPE type, u_int32 info, u_int32 info_data);
|
||||
int record_log_info(struct vpu_ctx *ctx, enum ACTION_TYPE type, u_int32 info, u_int32 info_data);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/fs.h>
|
||||
#include "vpu_rpc.h"
|
||||
|
||||
void rpc_init_shared_memory(struct shared_addr *This,
|
||||
unsigned long long base_phy_addr,
|
||||
void *base_virt_addr,
|
||||
u_int32 total_size)
|
||||
{
|
||||
pDEC_RPC_HOST_IFACE pSharedInterface;
|
||||
unsigned int phy_addr;
|
||||
unsigned int i;
|
||||
MediaIPFW_Video_BufDesc *pSharedCmdBufDescPtr;
|
||||
MediaIPFW_Video_BufDesc *pSharedMsgBufDescPtr;
|
||||
MediaIPFW_Video_BufDesc *pDebugBufferDesc;
|
||||
MediaIPFW_Video_BufDesc *pEngAccessBufferDesc;
|
||||
|
||||
This->shared_mem_phy = base_phy_addr;
|
||||
This->shared_mem_vir = base_virt_addr;
|
||||
|
||||
pSharedInterface = (pDEC_RPC_HOST_IFACE)This->shared_mem_vir;
|
||||
This->pSharedInterface = pSharedInterface;
|
||||
|
||||
pSharedInterface->FwExecBaseAddr = base_phy_addr;
|
||||
pSharedInterface->FwExecAreaSize = total_size;
|
||||
|
||||
pSharedCmdBufDescPtr = (MediaIPFW_Video_BufDesc *)&pSharedInterface->StreamCmdBufferDesc;
|
||||
pSharedMsgBufDescPtr = (MediaIPFW_Video_BufDesc *)&pSharedInterface->StreamMsgBufferDesc;
|
||||
|
||||
phy_addr = base_phy_addr + sizeof(DEC_RPC_HOST_IFACE);
|
||||
This->cmd_mem_phy = phy_addr;
|
||||
This->cmd_mem_vir = This->shared_mem_vir + sizeof(DEC_RPC_HOST_IFACE);
|
||||
|
||||
pSharedCmdBufDescPtr->uWrPtr = phy_addr;
|
||||
pSharedCmdBufDescPtr->uRdPtr = pSharedCmdBufDescPtr->uWrPtr;
|
||||
pSharedCmdBufDescPtr->uStart = pSharedCmdBufDescPtr->uWrPtr;
|
||||
pSharedCmdBufDescPtr->uEnd = pSharedCmdBufDescPtr->uStart + CMD_SIZE;
|
||||
|
||||
phy_addr += CMD_SIZE;
|
||||
This->msg_mem_phy = phy_addr;
|
||||
This->msg_mem_vir = This->cmd_mem_vir + CMD_SIZE;
|
||||
|
||||
pSharedMsgBufDescPtr->uWrPtr = phy_addr;
|
||||
pSharedMsgBufDescPtr->uRdPtr = pSharedMsgBufDescPtr->uWrPtr;
|
||||
pSharedMsgBufDescPtr->uStart = pSharedMsgBufDescPtr->uWrPtr;
|
||||
pSharedMsgBufDescPtr->uEnd = pSharedMsgBufDescPtr->uStart + MSG_SIZE;
|
||||
|
||||
phy_addr += MSG_SIZE;
|
||||
This->codec_mem_phy = phy_addr;
|
||||
This->codec_mem_vir = This->msg_mem_vir + MSG_SIZE;
|
||||
pSharedInterface->CodecParamTabDesc.pCodecParamArrayBase = This->codec_mem_phy;
|
||||
|
||||
phy_addr += CODEC_SIZE;
|
||||
This->jpeg_mem_phy = phy_addr;
|
||||
This->jpeg_mem_vir = This->codec_mem_vir + CODEC_SIZE;
|
||||
pSharedInterface->JpegParamTabDesc.pJpegParamArrayBase = This->jpeg_mem_phy;
|
||||
|
||||
phy_addr += JPEG_SIZE;
|
||||
This->seq_mem_phy = phy_addr;
|
||||
This->seq_mem_vir = This->jpeg_mem_vir + JPEG_SIZE;
|
||||
|
||||
pSharedInterface->SeqInfoTabDesc.pSeqInfoArrayBase = This->seq_mem_phy;
|
||||
|
||||
phy_addr += SEQ_SIZE;
|
||||
This->pic_mem_phy = phy_addr;
|
||||
This->pic_mem_vir = This->seq_mem_vir + SEQ_SIZE;
|
||||
|
||||
pSharedInterface->PicInfoTabDesc.pPicInfoArrayBase = This->pic_mem_phy;
|
||||
|
||||
phy_addr += PIC_SIZE;
|
||||
This->gop_mem_phy = phy_addr;
|
||||
This->gop_mem_vir = This->pic_mem_vir + PIC_SIZE;
|
||||
|
||||
pSharedInterface->GopInfoTabDesc.pGopInfoArrayBase = This->gop_mem_phy;
|
||||
|
||||
phy_addr += GOP_SIZE;
|
||||
This->qmeter_mem_phy = phy_addr;
|
||||
This->qmeter_mem_vir = This->gop_mem_vir + GOP_SIZE;
|
||||
|
||||
pSharedInterface->QMeterInfoTabDesc.pQMeterInfoArrayBase = This->qmeter_mem_phy;
|
||||
|
||||
phy_addr += QMETER_SIZE;
|
||||
pDebugBufferDesc = &pSharedInterface->DebugBufferDesc;
|
||||
pDebugBufferDesc->uWrPtr = base_phy_addr + M0_PRINT_OFFSET;
|
||||
pDebugBufferDesc->uRdPtr = pDebugBufferDesc->uWrPtr;
|
||||
pDebugBufferDesc->uStart = pDebugBufferDesc->uWrPtr;
|
||||
pDebugBufferDesc->uEnd = pDebugBufferDesc->uStart + DEBUG_SIZE;
|
||||
|
||||
This->dbglog_mem_phy = phy_addr;
|
||||
This->dbglog_mem_vir = This->qmeter_mem_vir + QMETER_SIZE;
|
||||
|
||||
pSharedInterface->DbgLogDesc.uDecStatusLogBase = This->dbglog_mem_phy;
|
||||
pSharedInterface->DbgLogDesc.uDecStatusLogSize = DBGLOG_SIZE;
|
||||
phy_addr += DBGLOG_SIZE;
|
||||
|
||||
// phy_addr += sizeof(MediaIPFW_Video_BufDesc);
|
||||
for (i = 0; i < VPU_MAX_NUM_STREAMS; i++) {
|
||||
pEngAccessBufferDesc = &pSharedInterface->EngAccessBufferDesc[i];
|
||||
pEngAccessBufferDesc->uWrPtr = phy_addr;
|
||||
pEngAccessBufferDesc->uRdPtr = pEngAccessBufferDesc->uWrPtr;
|
||||
pEngAccessBufferDesc->uStart = pEngAccessBufferDesc->uWrPtr;
|
||||
pEngAccessBufferDesc->uEnd = pEngAccessBufferDesc->uStart + ENG_SIZE;
|
||||
phy_addr += ENG_SIZE;
|
||||
}
|
||||
|
||||
for (i = 0; i < VPU_MAX_NUM_STREAMS; i++) {
|
||||
pSharedInterface->ptEncryptInfo[i] = phy_addr;
|
||||
phy_addr += sizeof(MediaIPFW_Video_Encrypt_Info);
|
||||
}
|
||||
}
|
||||
|
||||
void rpc_set_stream_cfg_value(void *Interface, u_int32 str_idx, u_int32 vpu_dbe_num)
|
||||
{
|
||||
pDEC_RPC_HOST_IFACE pSharedInterface;
|
||||
u_int32 *CurrStrfg;
|
||||
|
||||
pSharedInterface = (pDEC_RPC_HOST_IFACE)Interface;
|
||||
CurrStrfg = &pSharedInterface->StreamConfig[str_idx];
|
||||
*CurrStrfg = 0;
|
||||
//the value should be passed from application
|
||||
VID_STREAM_CONFIG_STRBUFIDX_SET(0, CurrStrfg);
|
||||
VID_STREAM_CONFIG_NOSEQ_SET(FALSE, CurrStrfg);
|
||||
VID_STREAM_CONFIG_DEBLOCK_SET(FALSE, CurrStrfg);
|
||||
VID_STREAM_CONFIG_DERING_SET(FALSE, CurrStrfg);
|
||||
VID_STREAM_CONFIG_PLAY_MODE_SET(MEDIA_PLAYER_API_MODE_CONTINUOUS, CurrStrfg);
|
||||
VID_STREAM_CONFIG_FS_CTRL_MODE_SET(MEDIA_PLAYER_FS_CTRL_MODE_EXTERNAL, CurrStrfg);
|
||||
VID_STREAM_CONFIG_ENABLE_DCP_SET(TRUE, CurrStrfg);
|
||||
VID_STREAM_CONFIG_NUM_STR_BUF_SET(1, CurrStrfg);
|
||||
VID_STREAM_CONFIG_MALONE_USAGE_SET(1, CurrStrfg);
|
||||
VID_STREAM_CONFIG_MULTI_VID_SET(FALSE, CurrStrfg);
|
||||
VID_STREAM_CONFIG_OBFUSC_EN_SET(FALSE, CurrStrfg);
|
||||
VID_STREAM_CONFIG_RC4_EN_SET(FALSE, CurrStrfg);
|
||||
VID_STREAM_CONFIG_MCX_SET(TRUE, CurrStrfg);
|
||||
VID_STREAM_CONFIG_PES_SET(FALSE, CurrStrfg);
|
||||
VID_STREAM_CONFIG_NUM_DBE_SET(vpu_dbe_num, CurrStrfg);
|
||||
}
|
||||
|
||||
void rpc_set_system_cfg_value(void *Interface, u_int32 regs_base)
|
||||
{
|
||||
pDEC_RPC_HOST_IFACE pSharedInterface;
|
||||
MEDIAIP_FW_SYSTEM_CONFIG *pSystemCfg;
|
||||
|
||||
pSharedInterface = (pDEC_RPC_HOST_IFACE)Interface;
|
||||
pSystemCfg = &pSharedInterface->sSystemCfg;
|
||||
pSystemCfg->uNumMalones = 1;
|
||||
pSystemCfg->uMaloneBaseAddress[0] = (unsigned int)(regs_base + 0x180000);
|
||||
|
||||
pSystemCfg->uMaloneBaseAddress[0x1] = 0x0;
|
||||
pSystemCfg->uHifOffset[0x0] = 0x1C000;
|
||||
pSystemCfg->uHifOffset[0x1] = 0x0;
|
||||
|
||||
pSystemCfg->uDPVBaseAddr = 0x0;
|
||||
pSystemCfg->uDPVIrqPin = 0x0;
|
||||
pSystemCfg->uPixIfBaseAddr = (unsigned int)(regs_base + 0x180000 + 0x20000);
|
||||
pSystemCfg->uFSLCacheBaseAddr[0] = (unsigned int)(regs_base + 0x60000);
|
||||
pSystemCfg->uFSLCacheBaseAddr[1] = (unsigned int)(regs_base + 0x68000);
|
||||
}
|
||||
|
||||
u_int32 rpc_MediaIPFW_Video_buffer_space_check(MediaIPFW_Video_BufDesc *pBufDesc,
|
||||
BOOL bFull,
|
||||
u_int32 uSize,
|
||||
u_int32 *puUpdateAddress)
|
||||
{
|
||||
u_int32 uPtr1;
|
||||
u_int32 uPtr2;
|
||||
u_int32 uStart;
|
||||
u_int32 uEnd;
|
||||
u_int32 uTemp;
|
||||
|
||||
/* bFull is FALSE when send message, write data */
|
||||
/* bFull is TRUE when process commands, read data */
|
||||
uPtr1 = (bFull) ? pBufDesc->uRdPtr : pBufDesc->uWrPtr;
|
||||
uPtr2 = (bFull) ? pBufDesc->uWrPtr : pBufDesc->uRdPtr;
|
||||
|
||||
if (uPtr1 == uPtr2) {
|
||||
if (bFull)
|
||||
/* No data at all to read */
|
||||
return 0;
|
||||
else {
|
||||
/* wrt pointer equal to read pointer thus the */
|
||||
/* buffer is completely empty for further writes */
|
||||
uStart = pBufDesc->uStart;
|
||||
uEnd = pBufDesc->uEnd;
|
||||
/* The address to be returned in this case is for */
|
||||
/* the updated write pointer. */
|
||||
uTemp = uPtr1 + uSize;
|
||||
if (uTemp >= uEnd)
|
||||
uTemp += (uStart - uEnd);
|
||||
*puUpdateAddress = uTemp;
|
||||
return (uEnd - uStart);
|
||||
}
|
||||
} else if (uPtr1 < uPtr2) {
|
||||
/* return updated rd pointer address */
|
||||
/* In this case if size was too big - we expect the */
|
||||
/* external ftn to compare the size against the */
|
||||
/* space returned.
|
||||
*/
|
||||
*puUpdateAddress = uPtr1 + uSize;
|
||||
return (uPtr2 - uPtr1);
|
||||
}
|
||||
/* We know the system has looped!! */
|
||||
uStart = pBufDesc->uStart;
|
||||
uEnd = pBufDesc->uEnd;
|
||||
uTemp = uPtr1 + uSize;
|
||||
if (uTemp >= uEnd)
|
||||
uTemp += (uStart - uEnd);
|
||||
*puUpdateAddress = uTemp;
|
||||
return ((uEnd - uPtr1) + (uPtr2 - uStart));
|
||||
}
|
||||
|
||||
static void rpc_update_cmd_buffer_ptr(MediaIPFW_Video_BufDesc *pCmdDesc)
|
||||
{
|
||||
u_int32 uWritePtr;
|
||||
|
||||
mb();
|
||||
uWritePtr = pCmdDesc->uWrPtr + 4;
|
||||
if (uWritePtr >= pCmdDesc->uEnd)
|
||||
uWritePtr = pCmdDesc->uStart;
|
||||
pCmdDesc->uWrPtr = uWritePtr;
|
||||
}
|
||||
|
||||
void rpc_send_cmd_buf(struct shared_addr *This,
|
||||
u_int32 idx,
|
||||
u_int32 cmdid,
|
||||
u_int32 cmdnum,
|
||||
u_int32 *local_cmddata)
|
||||
{
|
||||
pDEC_RPC_HOST_IFACE pSharedInterface = (pDEC_RPC_HOST_IFACE)This->shared_mem_vir;
|
||||
MediaIPFW_Video_BufDesc *pCmdDesc = &pSharedInterface->StreamCmdBufferDesc;
|
||||
u_int32 *cmddata;
|
||||
u_int32 i;
|
||||
u_int32 *cmdword = (u_int32 *)(This->cmd_mem_vir+pCmdDesc->uWrPtr - pCmdDesc->uStart);
|
||||
|
||||
*cmdword = 0;
|
||||
*cmdword |= ((idx & 0x000000ff) << 24);
|
||||
*cmdword |= ((cmdnum & 0x000000ff) << 16);
|
||||
*cmdword |= ((cmdid & 0x00003fff) << 0);
|
||||
rpc_update_cmd_buffer_ptr(pCmdDesc);
|
||||
|
||||
for (i = 0; i < cmdnum; i++) {
|
||||
cmddata = (u_int32 *)(This->cmd_mem_vir+pCmdDesc->uWrPtr - pCmdDesc->uStart);
|
||||
*cmddata = local_cmddata[i];
|
||||
rpc_update_cmd_buffer_ptr(pCmdDesc);
|
||||
}
|
||||
}
|
||||
|
||||
u_int32 rpc_MediaIPFW_Video_message_check(struct shared_addr *This)
|
||||
{
|
||||
u_int32 uSpace;
|
||||
u_int32 uIgnore;
|
||||
pDEC_RPC_HOST_IFACE pSharedInterface = (pDEC_RPC_HOST_IFACE)This->shared_mem_vir;
|
||||
MediaIPFW_Video_BufDesc *pMsgDesc = &pSharedInterface->StreamMsgBufferDesc;
|
||||
u_int32 msgword;
|
||||
u_int32 msgnum;
|
||||
|
||||
uSpace = rpc_MediaIPFW_Video_buffer_space_check(pMsgDesc, TRUE, 0, &uIgnore);
|
||||
uSpace = (uSpace >> 2);
|
||||
if (uSpace) {
|
||||
/* get current msgword word */
|
||||
msgword = *((u_int32 *)(This->msg_mem_vir+pMsgDesc->uRdPtr - pMsgDesc->uStart));
|
||||
/* Find the number of additional words */
|
||||
msgnum = ((msgword & 0x00ff0000) >> 16);
|
||||
|
||||
/*
|
||||
* * Check the number of message words against
|
||||
* * 1) a limit - some sort of maximum or at least
|
||||
* * the size of the SW buffer the message is read into
|
||||
* * 2) The space reported (where space is write ptr - read ptr in 32bit words)
|
||||
* * It must be less than space (as opposed to <=) because
|
||||
* * the message itself is not included in msgword
|
||||
*/
|
||||
if (msgnum < VID_API_MESSAGE_LIMIT) {
|
||||
if (msgnum < uSpace)
|
||||
return API_MSG_AVAILABLE;
|
||||
else
|
||||
return API_MSG_INCOMPLETE;
|
||||
} else
|
||||
return API_MSG_BUFFER_ERROR;
|
||||
}
|
||||
return API_MSG_UNAVAILABLE;
|
||||
}
|
||||
|
||||
static void rpc_update_msg_buffer_ptr(MediaIPFW_Video_BufDesc *pMsgDesc)
|
||||
{
|
||||
u_int32 uReadPtr;
|
||||
|
||||
mb();
|
||||
uReadPtr = pMsgDesc->uRdPtr + 4;
|
||||
if (uReadPtr >= pMsgDesc->uEnd)
|
||||
uReadPtr = pMsgDesc->uStart;
|
||||
pMsgDesc->uRdPtr = uReadPtr;
|
||||
}
|
||||
|
||||
void rpc_receive_msg_buf(struct shared_addr *This, struct event_msg *msg)
|
||||
{
|
||||
unsigned int i;
|
||||
pDEC_RPC_HOST_IFACE pSharedInterface = (pDEC_RPC_HOST_IFACE)This->shared_mem_vir;
|
||||
MediaIPFW_Video_BufDesc *pMsgDesc = &pSharedInterface->StreamMsgBufferDesc;
|
||||
u_int32 msgword = *((u_int32 *)(This->msg_mem_vir+pMsgDesc->uRdPtr - pMsgDesc->uStart));
|
||||
|
||||
msg->idx = ((msgword & 0xff000000) >> 24);
|
||||
msg->msgnum = ((msgword & 0x00ff0000) >> 16);
|
||||
msg->msgid = ((msgword & 0x00003fff) >> 0);
|
||||
rpc_update_msg_buffer_ptr(pMsgDesc);
|
||||
|
||||
for (i = 0; i < msg->msgnum; i++) {
|
||||
msg->msgdata[i] = *((u_int32 *)(This->msg_mem_vir+pMsgDesc->uRdPtr - pMsgDesc->uStart));
|
||||
rpc_update_msg_buffer_ptr(pMsgDesc);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __VPU_IPC_H
|
||||
#define __VPU_IPC_H
|
||||
|
||||
#include "mediasys_types.h"
|
||||
|
||||
#define CMD_SIZE 25600
|
||||
#define MSG_SIZE 25600
|
||||
#define CODEC_SIZE 0x1000
|
||||
#define JPEG_SIZE 0x1000
|
||||
#define SEQ_SIZE 0x1000
|
||||
#define GOP_SIZE 0x1000
|
||||
#define PIC_SIZE 0x1000
|
||||
#define QMETER_SIZE 0x1000
|
||||
#define DBGLOG_SIZE 0x10000
|
||||
#define DEBUG_SIZE 0x80000
|
||||
#define ENG_SIZE 0x1000
|
||||
#define LOCAL_MSG_NUM VID_API_MESSAGE_LIMIT
|
||||
#define M0_PRINT_OFFSET 0x180000
|
||||
|
||||
struct shared_addr {
|
||||
pDEC_RPC_HOST_IFACE pSharedInterface;
|
||||
unsigned long long shared_mem_phy;
|
||||
void *shared_mem_vir;
|
||||
unsigned long long cmd_mem_phy;
|
||||
void *cmd_mem_vir;
|
||||
unsigned long long msg_mem_phy;
|
||||
void *msg_mem_vir;
|
||||
unsigned long long codec_mem_phy;
|
||||
void *codec_mem_vir;
|
||||
unsigned long long jpeg_mem_phy;
|
||||
void *jpeg_mem_vir;
|
||||
unsigned long long seq_mem_phy;
|
||||
void *seq_mem_vir;
|
||||
unsigned long long pic_mem_phy;
|
||||
void *pic_mem_vir;
|
||||
unsigned long long gop_mem_phy;
|
||||
void *gop_mem_vir;
|
||||
unsigned long long qmeter_mem_phy;
|
||||
void *qmeter_mem_vir;
|
||||
unsigned long long dbglog_mem_phy;
|
||||
void *dbglog_mem_vir;
|
||||
};
|
||||
|
||||
struct event_msg {
|
||||
u_int32 idx;
|
||||
u_int32 msgnum;
|
||||
u_int32 msgid;
|
||||
u_int32 msgdata[LOCAL_MSG_NUM];
|
||||
};
|
||||
|
||||
void rpc_init_shared_memory(struct shared_addr *This,
|
||||
unsigned long long base_phy_addr,
|
||||
void *base_virt_addr,
|
||||
u_int32 total_size);
|
||||
void rpc_set_system_cfg_value(void *Interface, u_int32 regs_base);
|
||||
void rpc_set_stream_cfg_value(void *Interface, u_int32 str_idx, u_int32 vpu_dbe_num);
|
||||
void rpc_send_cmd_buf(struct shared_addr *This,
|
||||
u_int32 idx,
|
||||
u_int32 cmdid,
|
||||
u_int32 cmdnum,
|
||||
u_int32 *local_cmddata);
|
||||
void rpc_receive_msg_buf(struct shared_addr *This, struct event_msg *msg);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,25 @@
|
|||
#
|
||||
# Codec configuration
|
||||
#
|
||||
|
||||
menu "MXC VPU(Video Processing Unit) WINDSOR support"
|
||||
|
||||
config MXC_VPU_WINDSOR
|
||||
tristate "Support for MXC VPU(Video Processing Unit) ENCODER"
|
||||
select MEDIA_SUPPORT
|
||||
select VIDEO_DEV
|
||||
select VIDEO_V4L2
|
||||
select VIDEOBUF2_DMA_CONTIG
|
||||
select VIDEOBUF2_VMALLOC
|
||||
default y
|
||||
---help---
|
||||
The VPU codec device provides codec function for H.264 etc.
|
||||
|
||||
config MXC_VPU_WINDSOR_DEBUG
|
||||
bool "MXC VPU 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.
|
||||
|
||||
endmenu
|
|
@ -0,0 +1,15 @@
|
|||
##
|
||||
## Makefile for the VPU and M0 driver
|
||||
##
|
||||
|
||||
EXTRA_CFLAGS += $(DEFINES)
|
||||
|
||||
obj-$(CONFIG_MXC_VPU_WINDSOR) = vpu-windsor.o
|
||||
vpu-windsor-objs = vpu_encoder_b0.o \
|
||||
vpu_encoder_ctrl.o \
|
||||
vpu_event_msg.o \
|
||||
vpu_encoder_mem.o \
|
||||
vpu_encoder_rpc.o
|
||||
|
||||
clean:
|
||||
rm -rf $(vpu-windsor-objs)
|
|
@ -0,0 +1,705 @@
|
|||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _MEDIASYS_TYPES_H_
|
||||
#define _MEDIASYS_TYPES_H_
|
||||
|
||||
typedef unsigned int u_int32;
|
||||
typedef unsigned char u_int8;
|
||||
typedef unsigned long u_int64;
|
||||
typedef unsigned int BOOL;
|
||||
typedef int int32;
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#define VID_API_NUM_STREAMS 8
|
||||
#define VID_API_MAX_BUF_PER_STR 3
|
||||
#define VID_API_MAX_NUM_MVC_VIEWS 4
|
||||
#define MEDIAIP_MAX_NUM_MALONES 2
|
||||
#define MEDIAIP_MAX_NUM_MALONE_IRQ_PINS 2
|
||||
#define MEDIAIP_MAX_NUM_WINDSORS 1
|
||||
#define MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS 2
|
||||
#define MEDIAIP_MAX_NUM_CMD_IRQ_PINS 2
|
||||
#define MEDIAIP_MAX_NUM_MSG_IRQ_PINS 1
|
||||
#define MEDIAIP_MAX_NUM_TIMER_IRQ_PINS 4
|
||||
#define MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS 4
|
||||
#define VID_API_COMMAND_LIMIT 64
|
||||
#define VID_API_MESSAGE_LIMIT 256
|
||||
|
||||
#define API_CMD_AVAILABLE 0x0
|
||||
#define API_CMD_INCOMPLETE 0x1
|
||||
#define API_CMD_BUFFER_ERROR 0x2
|
||||
#define API_CMD_UNAVAILABLE 0x3
|
||||
#define API_MSG_AVAILABLE 0x0
|
||||
#define API_MSG_INCOMPLETE 0x1
|
||||
#define API_MSG_BUFFER_ERROR 0x2
|
||||
#define API_MSG_UNAVAILABLE 0x3
|
||||
#define MEDIAIP_ENC_USER_DATA_WORDS 16
|
||||
#define MEDIAIP_MAX_NUM_WINDSOR_SRC_FRAMES 0x6
|
||||
#define MEDIAIP_MAX_NUM_WINDSOR_REF_FRAMES 0x3
|
||||
|
||||
typedef enum {
|
||||
GTB_ENC_CMD_NOOP = 0x0,
|
||||
GTB_ENC_CMD_STREAM_START,
|
||||
GTB_ENC_CMD_FRAME_ENCODE,
|
||||
GTB_ENC_CMD_FRAME_SKIP,
|
||||
GTB_ENC_CMD_STREAM_STOP,
|
||||
GTB_ENC_CMD_PARAMETER_UPD,
|
||||
GTB_ENC_CMD_TERMINATE,
|
||||
GTB_ENC_CMD_SNAPSHOT,
|
||||
GTB_ENC_CMD_ROLL_SNAPSHOT,
|
||||
GTB_ENC_CMD_LOCK_SCHEDULER,
|
||||
GTB_ENC_CMD_UNLOCK_SCHEDULER,
|
||||
GTB_ENC_CMD_CONFIGURE_CODEC,
|
||||
GTB_ENC_CMD_DEAD_MARK,
|
||||
GTB_ENC_CMD_FIRM_RESET,
|
||||
GTB_ENC_CMD_RESERVED
|
||||
} GTB_ENC_CMD;
|
||||
|
||||
typedef enum {
|
||||
VID_API_EVENT_UNDEFINED = 0x0,
|
||||
VID_API_ENC_EVENT_RESET_DONE = 0x1,
|
||||
VID_API_ENC_EVENT_START_DONE,
|
||||
VID_API_ENC_EVENT_STOP_DONE,
|
||||
VID_API_ENC_EVENT_TERMINATE_DONE,
|
||||
VID_API_ENC_EVENT_FRAME_INPUT_DONE,
|
||||
VID_API_ENC_EVENT_FRAME_DONE,
|
||||
VID_API_ENC_EVENT_FRAME_RELEASE,
|
||||
VID_API_ENC_EVENT_PARA_UPD_DONE,
|
||||
VID_API_ENC_EVENT_MEM_REQUEST,
|
||||
VID_API_ENC_EVENT_FIRMWARE_XCPT,
|
||||
VID_API_ENC_EVENT_RESERVED
|
||||
} ENC_TB_API_ENC_EVENT;
|
||||
|
||||
typedef enum {
|
||||
MEDIAIP_ENC_PIC_TYPE_B_FRAME = 0,
|
||||
MEDIAIP_ENC_PIC_TYPE_P_FRAME,
|
||||
MEDIAIP_ENC_PIC_TYPE_I_FRAME,
|
||||
MEDIAIP_ENC_PIC_TYPE_IDR_FRAME,
|
||||
MEDIAIP_ENC_PIC_TYPE_BI_FRAME
|
||||
|
||||
} MEDIAIP_ENC_PIC_TYPE, *pMEDIAIP_ENC_PIC_TYPE;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uMemPhysAddr;
|
||||
u_int32 uMemVirtAddr;
|
||||
u_int32 uMemSize;
|
||||
} MEDIAIP_ENC_MEM_RESOURCE, *pMEDIAIP_ENC_MEM_RESOURCE;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uEncFrmSize;
|
||||
u_int32 uEncFrmNum;
|
||||
u_int32 uRefFrmSize;
|
||||
u_int32 uRefFrmNum;
|
||||
u_int32 uActBufSize;
|
||||
} MEDIAIP_ENC_MEM_REQ_DATA, *pMEDIAIP_ENC_MEM_REQ_DATA;
|
||||
|
||||
typedef struct {
|
||||
MEDIAIP_ENC_MEM_RESOURCE tEncFrameBuffers[MEDIAIP_MAX_NUM_WINDSOR_SRC_FRAMES];
|
||||
MEDIAIP_ENC_MEM_RESOURCE tRefFrameBuffers[MEDIAIP_MAX_NUM_WINDSOR_REF_FRAMES];
|
||||
MEDIAIP_ENC_MEM_RESOURCE tActFrameBufferArea;
|
||||
} MEDIAIP_ENC_MEM_POOL, *pMEDIAIP_ENC_MEM_POOL;
|
||||
|
||||
///////////////////////////////////////////
|
||||
// MEDIAIP_ENC_PIC_TYPE
|
||||
|
||||
typedef struct {
|
||||
u_int32 uFrameID;
|
||||
u_int32 uPicEncodDone;
|
||||
MEDIAIP_ENC_PIC_TYPE ePicType;
|
||||
u_int32 uSkippedFrame;
|
||||
u_int32 uErrorFlag;
|
||||
u_int32 uPSNR;
|
||||
u_int32 uFlushDone;
|
||||
u_int32 uMBy;
|
||||
u_int32 uMBx;
|
||||
u_int32 uFrameSize;
|
||||
u_int32 uFrameEncTtlCycles;
|
||||
u_int32 uFrameEncTtlFrmCycles;
|
||||
u_int32 uFrameEncTtlSlcCycles;
|
||||
u_int32 uFrameEncTtlEncCycles;
|
||||
u_int32 uFrameEncTtlHmeCycles;
|
||||
u_int32 uFrameEncTtlDsaCycles;
|
||||
u_int32 uFrameEncFwCycles;
|
||||
u_int32 uFrameCrc;
|
||||
u_int32 uNumInterrupts_1;
|
||||
u_int32 uNumInterrupts_2;
|
||||
u_int32 uH264POC;
|
||||
u_int32 uRefInfo;
|
||||
u_int32 uPicNum;
|
||||
u_int32 uPicActivity;
|
||||
u_int32 uSceneChange;
|
||||
u_int32 uMBStats;
|
||||
u_int32 uEncCacheCount0;
|
||||
u_int32 uEncCacheCount1;
|
||||
u_int32 uMtlWrStrbCnt;
|
||||
u_int32 uMtlRdStrbCnt;
|
||||
u_int32 uStrBuffWrPtr;
|
||||
u_int32 uDiagnosticEvents;
|
||||
|
||||
u_int32 uProcIaccTotRdCnt;
|
||||
u_int32 uProcDaccTotRdCnt;
|
||||
u_int32 uProcDaccTotWrCnt;
|
||||
u_int32 uProcDaccRegRdCnt;
|
||||
u_int32 uProcDaccRegWrCnt;
|
||||
u_int32 uProcDaccRngRdCnt;
|
||||
u_int32 uProcDaccRngWrCnt;
|
||||
|
||||
} MEDIAIP_ENC_PIC_INFO, *pMEDIAIP_ENC_PIC_INFO;
|
||||
|
||||
typedef enum {
|
||||
MEDIAIP_PLAYMODE_CONNECTIVITY = 0,
|
||||
MEDIAIP_PLAYMODE_BROADCAST,
|
||||
MEDIAIP_PLAYMODE_BROADCAST_DSS,
|
||||
MEDIAIP_PLAYMODE_LAST = MEDIAIP_PLAYMODE_BROADCAST_DSS
|
||||
|
||||
} MEDIA_IP_PLAYMODE;
|
||||
|
||||
typedef struct {
|
||||
u_int32 wptr;
|
||||
u_int32 rptr;
|
||||
u_int32 start;
|
||||
u_int32 end;
|
||||
|
||||
} BUFFER_DESCRIPTOR_TYPE, *pBUFFER_DESCRIPTOR_TYPE;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uWrPtr;
|
||||
u_int32 uRdPtr;
|
||||
u_int32 uStart;
|
||||
u_int32 uEnd;
|
||||
u_int32 uLo;
|
||||
u_int32 uHi;
|
||||
|
||||
} MediaIPFW_Video_BufDesc;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uCfgCookie;
|
||||
|
||||
u_int32 uNumMalones;
|
||||
u_int32 uMaloneBaseAddress[MEDIAIP_MAX_NUM_MALONES];
|
||||
u_int32 uHifOffset[MEDIAIP_MAX_NUM_MALONES];
|
||||
u_int32 uMaloneIrqPin[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
|
||||
u_int32 uMaloneIrqTarget[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
|
||||
|
||||
u_int32 uNumWindsors;
|
||||
u_int32 uWindsorBaseAddress[MEDIAIP_MAX_NUM_WINDSORS];
|
||||
u_int32 uWindsorIrqPin[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
|
||||
u_int32 uWindsorIrqTarget[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
|
||||
|
||||
u_int32 uCmdIrqPin[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
|
||||
u_int32 uCmdIrqTarget[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
|
||||
|
||||
u_int32 uMsgIrqPin[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
|
||||
u_int32 uMsgIrqTarget[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
|
||||
|
||||
u_int32 uSysClkFreq;
|
||||
u_int32 uNumTimers;
|
||||
u_int32 uTimerBaseAddr;
|
||||
u_int32 uTimerIrqPin[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
|
||||
u_int32 uTimerIrqTarget[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
|
||||
u_int32 uTimerSlots[MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS];
|
||||
|
||||
u_int32 uGICBaseAddr;
|
||||
u_int32 uUartBaseAddr;
|
||||
|
||||
u_int32 uDPVBaseAddr;
|
||||
u_int32 uDPVIrqPin;
|
||||
u_int32 uDPVIrqTarget;
|
||||
|
||||
u_int32 uPixIfBaseAddr;
|
||||
|
||||
u_int32 pal_trace_level;
|
||||
u_int32 pal_trace_destination;
|
||||
|
||||
u_int32 pal_trace_level1;
|
||||
u_int32 pal_trace_destination1;
|
||||
|
||||
u_int32 uHeapBase;
|
||||
u_int32 uHeapSize;
|
||||
|
||||
u_int32 uFSLCacheBaseAddr[2];
|
||||
|
||||
} MEDIAIP_FW_SYSTEM_CONFIG, *pMEDIAIP_FW_SYSTEM_CONFIG;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uFrameID;
|
||||
u_int32 uLumaBase;
|
||||
u_int32 uChromaBase;
|
||||
u_int32 uParamIdx;
|
||||
u_int32 uKeyFrame;
|
||||
} MEDIAIP_ENC_YUV_BUFFER_DESC, *pMEDIAIP_ENC_YUV_BUFFER_DESC;
|
||||
|
||||
typedef struct {
|
||||
u_int32 use_ame;
|
||||
|
||||
u_int32 cme_mvx_max;
|
||||
u_int32 cme_mvy_max;
|
||||
u_int32 ame_prefresh_y0;
|
||||
u_int32 ame_prefresh_y1;
|
||||
u_int32 fme_min_sad;
|
||||
u_int32 cme_min_sad;
|
||||
|
||||
u_int32 fme_pred_int_weight;
|
||||
u_int32 fme_pred_hp_weight;
|
||||
u_int32 fme_pred_qp_weight;
|
||||
u_int32 fme_cost_weight;
|
||||
u_int32 fme_act_thold;
|
||||
u_int32 fme_sad_thold;
|
||||
u_int32 fme_zero_sad_thold;
|
||||
|
||||
u_int32 fme_lrg_mvx_lmt;
|
||||
u_int32 fme_lrg_mvy_lmt;
|
||||
u_int32 fme_force_mode;
|
||||
u_int32 fme_force4mvcost;
|
||||
u_int32 fme_force2mvcost;
|
||||
|
||||
u_int32 h264_inter_thrd;
|
||||
|
||||
u_int32 i16x16_mode_cost;
|
||||
u_int32 i4x4_mode_lambda;
|
||||
u_int32 i8x8_mode_lambda;
|
||||
|
||||
u_int32 inter_mod_mult;
|
||||
u_int32 inter_sel_mult;
|
||||
u_int32 inter_bid_cost;
|
||||
u_int32 inter_bwd_cost;
|
||||
u_int32 inter_4mv_cost;
|
||||
int32 one_mv_i16_cost;
|
||||
int32 one_mv_i4x4_cost;
|
||||
int32 one_mv_i8x8_cost;
|
||||
int32 two_mv_i16_cost;
|
||||
int32 two_mv_i4x4_cost;
|
||||
int32 two_mv_i8x8_cost;
|
||||
int32 four_mv_i16_cost;
|
||||
int32 four_mv_i4x4_cost;
|
||||
int32 four_mv_i8x8_cost;
|
||||
|
||||
u_int32 intra_pred_enab;
|
||||
u_int32 intra_chr_pred;
|
||||
u_int32 intra16_pred;
|
||||
u_int32 intra4x4_pred;
|
||||
u_int32 intra8x8_pred;
|
||||
|
||||
u_int32 cb_base;
|
||||
u_int32 cb_size;
|
||||
u_int32 cb_head_room;
|
||||
|
||||
u_int32 mem_page_width;
|
||||
u_int32 mem_page_height;
|
||||
u_int32 mem_total_size;
|
||||
u_int32 mem_chunk_phys_addr;
|
||||
u_int32 mem_chunk_virt_addr;
|
||||
u_int32 mem_chunk_size;
|
||||
u_int32 mem_y_stride;
|
||||
u_int32 mem_uv_stride;
|
||||
|
||||
u_int32 split_wr_enab;
|
||||
u_int32 split_wr_req_size;
|
||||
u_int32 split_rd_enab;
|
||||
u_int32 split_rd_req_size;
|
||||
|
||||
} MEDIAIP_ENC_CALIB_PARAMS, *pMEDIAIP_ENC_CALIB_PARAMS;
|
||||
|
||||
typedef struct {
|
||||
u_int32 ParamChange;
|
||||
|
||||
u_int32 start_frame; // These variables are for debugging purposes only
|
||||
u_int32 end_frame;
|
||||
|
||||
u_int32 userdata_enable;
|
||||
u_int32 userdata_id[4];
|
||||
u_int32 userdata_message[MEDIAIP_ENC_USER_DATA_WORDS];
|
||||
u_int32 userdata_length;
|
||||
|
||||
u_int32 h264_profile_idc;
|
||||
u_int32 h264_level_idc;
|
||||
u_int32 h264_au_delimiter; // Enable the use of Access Unit Delimiters
|
||||
u_int32 h264_seq_end_code; // Enable the use of Sequence End Codes
|
||||
u_int32 h264_recovery_points; // Enable the use of Recovery Points (must be with a fixed GOP structure)
|
||||
u_int32 h264_vui_parameters; // Enable the use of VUI parameters (for rate control purposes)
|
||||
u_int32 h264_aspect_ratio_present;
|
||||
u_int32 h264_aspect_ratio_sar_width;
|
||||
u_int32 h264_aspect_ratio_sar_height;
|
||||
u_int32 h264_overscan_present;
|
||||
u_int32 h264_video_type_present;
|
||||
u_int32 h264_video_format;
|
||||
u_int32 h264_video_full_range;
|
||||
u_int32 h264_video_colour_descriptor;
|
||||
u_int32 h264_video_colour_primaries;
|
||||
u_int32 h264_video_transfer_char;
|
||||
u_int32 h264_video_matrix_coeff;
|
||||
u_int32 h264_chroma_loc_info_present;
|
||||
u_int32 h264_chroma_loc_type_top;
|
||||
u_int32 h264_chroma_loc_type_bot;
|
||||
u_int32 h264_timing_info_present;
|
||||
u_int32 h264_buffering_period_present;
|
||||
u_int32 h264_low_delay_hrd_flag;
|
||||
|
||||
u_int32 aspect_ratio;
|
||||
u_int32 test_mode; // Automated firmware test mode
|
||||
u_int32 dsa_test_mode; // Automated test mode for the DSA.
|
||||
u_int32 fme_test_mode; // Automated test mode for the fme
|
||||
|
||||
u_int32 cbr_row_mode; //0: FW mode; 1: HW mode
|
||||
u_int32 windsor_mode; //0: normal mode; 1: intra only mode; 2: intra+0MV mode
|
||||
u_int32 encode_mode; // H264, VC1, MPEG2, DIVX
|
||||
u_int32 frame_width; // display width
|
||||
u_int32 frame_height; // display height
|
||||
u_int32 enc_frame_width; // encoding width, should be 16-pix align
|
||||
u_int32 enc_frame_height; // encoding height, should be 16-pix aligned for progressive and 32-pix aligned for interlace
|
||||
u_int32 frame_rate_num;
|
||||
u_int32 frame_rate_den;
|
||||
|
||||
u_int32 vi_field_source; // vi input source is frame or field
|
||||
u_int32 vi_frame_width;
|
||||
u_int32 vi_frame_height;
|
||||
u_int32 crop_frame_width;
|
||||
u_int32 crop_frame_height;
|
||||
u_int32 crop_x_start_posn;
|
||||
u_int32 crop_y_start_posn;
|
||||
u_int32 mode422;
|
||||
u_int32 mode_yuy2;
|
||||
u_int32 dsa_luma_en;
|
||||
u_int32 dsa_chroma_en;
|
||||
u_int32 dsa_ext_hfilt_en;
|
||||
u_int32 dsa_di_en;
|
||||
u_int32 dsa_di_top_ref;
|
||||
u_int32 dsa_vertf_disable; // disable the vertical filter.
|
||||
u_int32 dsa_disable_pwb;
|
||||
u_int32 dsa_hor_phase;
|
||||
u_int32 dsa_ver_phase;
|
||||
|
||||
u_int32 dsa_iac_enable; // IAC / DSA cannot operate independently in FW so this variable controls
|
||||
u_int32 iac_sc_threshold;
|
||||
u_int32 iac_vm_threshold;
|
||||
u_int32 iac_skip_mode;
|
||||
u_int32 iac_grp_width;
|
||||
u_int32 iac_grp_height;
|
||||
|
||||
u_int32 rate_control_mode;
|
||||
u_int32 rate_control_resolution;
|
||||
u_int32 buffer_size;
|
||||
u_int32 buffer_level_init;
|
||||
u_int32 buffer_I_bit_budget;
|
||||
|
||||
u_int32 top_field_first;
|
||||
|
||||
u_int32 intra_lum_qoffset;
|
||||
u_int32 intra_chr_qoffset;
|
||||
u_int32 inter_lum_qoffset;
|
||||
u_int32 inter_chr_qoffset;
|
||||
u_int32 use_def_scaling_mtx;
|
||||
|
||||
u_int32 inter_8x8_enab;
|
||||
u_int32 inter_4x4_enab;
|
||||
|
||||
u_int32 fme_enable_qpel;
|
||||
u_int32 fme_enable_hpel;
|
||||
u_int32 fme_nozeromv; // can force the FME not to do the (0,0) search.
|
||||
u_int32 fme_predmv_en;
|
||||
u_int32 fme_pred_2mv4mv;
|
||||
u_int32 fme_smallsadthresh;
|
||||
|
||||
u_int32 ame_en_lmvc;
|
||||
u_int32 ame_x_mult;
|
||||
u_int32 cme_enable_4mv; // Enable the use of 4MV partitioning
|
||||
u_int32 cme_enable_1mv;
|
||||
u_int32 hme_enable_16x8mv;
|
||||
u_int32 hme_enable_8x16mv;
|
||||
u_int32 cme_mv_weight; // CME motion vector decisions are made by combining these
|
||||
u_int32 cme_mv_cost; // cost and weight variables
|
||||
u_int32 ame_mult_mv;
|
||||
u_int32 ame_shift_mv;
|
||||
|
||||
u_int32 hme_forceto1mv_en;
|
||||
u_int32 hme_2mv_cost; // the cost of choosing a 2MV mode over 1MV.
|
||||
u_int32 hme_pred_mode;
|
||||
u_int32 hme_sc_rnge;
|
||||
u_int32 hme_sw_rnge;
|
||||
|
||||
// for windsor pes , add by fulin
|
||||
u_int32 output_format; // 0: output ES; 1: output PES
|
||||
u_int32 timestamp_enab; // 0: have timestamps in all frame; 1: have timestamps in I and P frame; 2: have timestamps only in I frame
|
||||
u_int32 initial_PTS_enab; // if enabled , use following value,else compute by fw
|
||||
u_int32 initial_PTS; // the initial value of PTS in the first frame (ms)
|
||||
|
||||
} MEDIAIP_ENC_CONFIG_PARAMS, *pMEDIAIP_ENC_CONFIG_PARAMS;
|
||||
|
||||
typedef struct {
|
||||
u_int32 ParamChange;
|
||||
|
||||
u_int32 gop_length;
|
||||
|
||||
u_int32 rate_control_bitrate;
|
||||
u_int32 rate_control_bitrate_min;
|
||||
u_int32 rate_control_bitrate_max;
|
||||
u_int32 rate_control_content_models;
|
||||
u_int32 rate_control_iframe_maxsize; // Maximum size of I frame generated by BPM in comparison to ideal (/4)
|
||||
u_int32 rate_control_qp_init;
|
||||
u_int32 rate_control_islice_qp;
|
||||
u_int32 rate_control_pslice_qp;
|
||||
u_int32 rate_control_bslice_qp;
|
||||
|
||||
u_int32 adaptive_quantization; // Enable the use of activity measures from VIPP in QP assignment
|
||||
u_int32 aq_variance;
|
||||
u_int32 cost_optimization; // Enable picture/frame level adjustments of the cost parameters by FW.
|
||||
u_int32 fdlp_mode; // Frequency-domain low-pass filter control, 0: off, 1-4: specific, 5: adaptive
|
||||
u_int32 enable_isegbframes; // Enable the use of B frames in the first segment of a GOP
|
||||
u_int32 enable_adaptive_keyratio; // Enable the use of an adaptive I to P/B ratio (aims to reduce distortion)
|
||||
u_int32 keyratio_imin; // Clamps applied to picture size ratios
|
||||
u_int32 keyratio_imax;
|
||||
u_int32 keyratio_pmin;
|
||||
u_int32 keyratio_pmax;
|
||||
u_int32 keyratio_bmin;
|
||||
u_int32 keyratio_bmax;
|
||||
int32 keyratio_istep;
|
||||
int32 keyratio_pstep;
|
||||
int32 keyratio_bstep;
|
||||
|
||||
u_int32 enable_paff; // Enable Picture Adaptive Frame/Field
|
||||
u_int32 enable_b_frame_ref; // Enable B frame as references
|
||||
u_int32 enable_adaptive_gop; // Enable an adaptive GOP structure
|
||||
u_int32 enable_closed_gop; // Enable a closed GOP structure
|
||||
// i.e. if enabled, the first consecutive B frames following
|
||||
// an I frame in each GOP will be intra or backwards only coded
|
||||
// and do not rely on previous reference pictures.
|
||||
u_int32 open_gop_refresh_freq; // Controls the insertion of closed GOP's (or IDR GOP's in H.264)
|
||||
u_int32 enable_adaptive_sc; // Enable adaptive scene change GOP structure (0:off, 1:adaptive, 2:IDR)
|
||||
u_int32 enable_fade_detection; // Enable fade detection and associated motion estimation restrictions
|
||||
int32 fade_detection_threshold; // Threshold at which the activity slope indicates a possible fading event
|
||||
u_int32 enable_repeat_b; // Enalbe the repeated B frame mode at CBR
|
||||
u_int32 enable_low_delay_b; // Use low delay-b frames with an IPPPP style GOP
|
||||
|
||||
} MEDIAIP_ENC_STATIC_PARAMS, *pMEDIAIP_ENC_STATIC_PARAMS;
|
||||
|
||||
typedef struct {
|
||||
u_int32 ParamChange;
|
||||
|
||||
u_int32 rows_per_slice;
|
||||
|
||||
u_int32 mbaff_enable; // Macroblock adaptive frame/field enable
|
||||
u_int32 dbf_enable; // Enable the deblocking filter
|
||||
|
||||
u_int32 field_source; // progressive/interlaced control
|
||||
u_int32 gop_b_length; // Number of B frames between anchor frames
|
||||
// (only to be changed at a GOP segment boundary)
|
||||
u_int32 mb_group_size; // Number of macroblocks normally assigned to a group
|
||||
// (implications for performance, interrupts and rate control)
|
||||
|
||||
u_int32 cbr_rows_per_group;
|
||||
|
||||
u_int32 skip_enable; // Enable the use of skipped macroblocks
|
||||
|
||||
u_int32 pts_bits_0_to_31; // TO BE REMOVED...
|
||||
u_int32 pts_bit_32;
|
||||
|
||||
u_int32 rm_expsv_cff;
|
||||
u_int32 const_ipred;
|
||||
int32 chr_qp_offset;
|
||||
u_int32 intra_mb_qp_offset;
|
||||
|
||||
u_int32 h264_cabac_init_method;
|
||||
u_int32 h264_cabac_init_idc;
|
||||
u_int32 h264_cabac_enable; // Main and stream
|
||||
|
||||
int32 alpha_c0_offset_div2;
|
||||
int32 beta_offset_div2;
|
||||
|
||||
u_int32 intra_prefresh_y0; // for setting intra limits for prog refresh.
|
||||
u_int32 intra_prefresh_y1;
|
||||
|
||||
u_int32 dbg_dump_rec_src;
|
||||
|
||||
} MEDIAIP_ENC_DYN_PARAMS, *pMEDIAIP_ENC_DYN_PARAMS;
|
||||
|
||||
typedef struct {
|
||||
MEDIAIP_ENC_CALIB_PARAMS Calib;
|
||||
MEDIAIP_ENC_CONFIG_PARAMS Config;
|
||||
MEDIAIP_ENC_STATIC_PARAMS Static;
|
||||
MEDIAIP_ENC_DYN_PARAMS Dynamic;
|
||||
} MEDIAIP_ENC_EXPERT_MODE_PARAM, *pMEDIAIP_ENC_EXPERT_MODE_PARAM;
|
||||
|
||||
typedef enum {
|
||||
MEDIAIP_ENC_FMT_H264 = 0,
|
||||
MEDIAIP_ENC_FMT_VC1,
|
||||
MEDIAIP_ENC_FMT_MPEG2,
|
||||
MEDIAIP_ENC_FMT_MPEG4SP,
|
||||
MEDIAIP_ENC_FMT_H263,
|
||||
MEDIAIP_ENC_FMT_MPEG1,
|
||||
MEDIAIP_ENC_FMT_SHORT_HEADER,
|
||||
MEDIAIP_ENC_FMT_NULL
|
||||
|
||||
} MEDIAIP_ENC_FMT;
|
||||
|
||||
typedef enum {
|
||||
MEDIAIP_ENC_PROF_MPEG2_SP = 0,
|
||||
MEDIAIP_ENC_PROF_MPEG2_MP,
|
||||
MEDIAIP_ENC_PROF_MPEG2_HP,
|
||||
MEDIAIP_ENC_PROF_H264_BP,
|
||||
MEDIAIP_ENC_PROF_H264_MP,
|
||||
MEDIAIP_ENC_PROF_H264_HP,
|
||||
MEDIAIP_ENC_PROF_MPEG4_SP,
|
||||
MEDIAIP_ENC_PROF_MPEG4_ASP,
|
||||
MEDIAIP_ENC_PROF_VC1_SP,
|
||||
MEDIAIP_ENC_PROF_VC1_MP,
|
||||
MEDIAIP_ENC_PROF_VC1_AP
|
||||
|
||||
} MEDIAIP_ENC_PROFILE;
|
||||
|
||||
typedef enum {
|
||||
MEDIAIP_ENC_BITRATECONTROLMODE_VBR = 0x00000001,
|
||||
MEDIAIP_ENC_BITRATECONTROLMODE_CBR = 0x00000002,
|
||||
MEDIAIP_ENC_BITRATECONTROLMODE_CONSTANT_QP = 0x00000004 /* Only in debug mode */
|
||||
|
||||
} MEDIAIP_ENC_BITRATE_MODE, *pMEDIAIP_ENC_BITRATE_MODE;
|
||||
|
||||
typedef struct {
|
||||
MEDIAIP_ENC_FMT eCodecMode;
|
||||
MEDIAIP_ENC_PROFILE eProfile;
|
||||
u_int32 uLevel;
|
||||
|
||||
MEDIAIP_ENC_MEM_RESOURCE tEncMemDesc;
|
||||
|
||||
u_int32 uFrameRate;
|
||||
u_int32 uSrcStride;
|
||||
u_int32 uSrcWidth;
|
||||
u_int32 uSrcHeight;
|
||||
u_int32 uSrcOffset_x;
|
||||
u_int32 uSrcOffset_y;
|
||||
u_int32 uSrcCropWidth;
|
||||
u_int32 uSrcCropHeight;
|
||||
u_int32 uOutWidth;
|
||||
u_int32 uOutHeight;
|
||||
u_int32 uIFrameInterval;
|
||||
u_int32 uGopBLength;
|
||||
u_int32 uLowLatencyMode;
|
||||
|
||||
MEDIAIP_ENC_BITRATE_MODE eBitRateMode;
|
||||
u_int32 uTargetBitrate;
|
||||
u_int32 uMaxBitRate;
|
||||
u_int32 uMinBitRate;
|
||||
u_int32 uInitSliceQP;
|
||||
|
||||
} MEDIAIP_ENC_PARAM, *pMEDIAIP_ENC_PARAM;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uFrameID;
|
||||
u_int32 uErrorFlag; //Error type
|
||||
u_int32 uMBy;
|
||||
u_int32 uMBx;
|
||||
u_int32 uReserved[12];
|
||||
|
||||
} ENC_ENCODING_STATUS, *pENC_ENCODING_STATUS;
|
||||
|
||||
typedef struct {
|
||||
u_int32 uFrameID;
|
||||
u_int32 uDsaCyle;
|
||||
u_int32 uMBy;
|
||||
u_int32 uMBx;
|
||||
u_int32 uReserved[4];
|
||||
|
||||
} ENC_DSA_STATUS_t, *pENC_DSA_STATUS_t;
|
||||
|
||||
typedef struct {
|
||||
u_int32 pEncYUVBufferDesc;
|
||||
u_int32 pEncStreamBufferDesc;
|
||||
u_int32 pEncExpertModeParam;
|
||||
u_int32 pEncParam;
|
||||
u_int32 pEncMemPool;
|
||||
/* Status information for master to read */
|
||||
u_int32 pEncEncodingStatus;
|
||||
u_int32 pEncDSAStatus;
|
||||
} MEDIA_ENC_API_CONTROL_INTERFACE, *pMEDIA_ENC_API_CONTROL_INTERFACE;
|
||||
|
||||
typedef struct {
|
||||
u_int32 FwExecBaseAddr;
|
||||
u_int32 FwExecAreaSize;
|
||||
BUFFER_DESCRIPTOR_TYPE StreamCmdBufferDesc;
|
||||
BUFFER_DESCRIPTOR_TYPE StreamMsgBufferDesc;
|
||||
u_int32 StreamCmdIntEnable[VID_API_NUM_STREAMS];
|
||||
u_int32 FWVersion;
|
||||
u_int32 uMVDFWOffset;
|
||||
u_int32 uMaxEncoderStreams;
|
||||
u_int32 pEncCtrlInterface[VID_API_NUM_STREAMS];
|
||||
MEDIAIP_FW_SYSTEM_CONFIG sSystemCfg;
|
||||
u_int32 uApiVersion;
|
||||
BUFFER_DESCRIPTOR_TYPE DebugBufferDesc;
|
||||
} ENC_RPC_HOST_IFACE, *pENC_RPC_HOST_IFACE;
|
||||
|
||||
#define SCB_XREG_SLV_BASE 0x00000000
|
||||
#define SCB_SCB_BLK_CTRL 0x00070000
|
||||
#define SCB_BLK_CTRL_XMEM_RESET_SET 0x00000090
|
||||
#define SCB_BLK_CTRL_CACHE_RESET_SET 0x000000A0
|
||||
#define SCB_BLK_CTRL_CACHE_RESET_CLR 0x000000A4
|
||||
#define SCB_BLK_CTRL_SCB_CLK_ENABLE_SET 0x00000100
|
||||
|
||||
#define XMEM_CONTROL 0x00041000
|
||||
|
||||
#define DEC_MFD_XREG_SLV_BASE 0x00180000
|
||||
|
||||
#define MFD_HIF 0x0001C000
|
||||
#define MFD_HIF_MSD_REG_INTERRUPT_STATUS 0x00000018
|
||||
#define MFD_SIF 0x0001D000
|
||||
#define MFD_SIF_CTRL_STATUS 0x000000F0
|
||||
#define MFD_SIF_INTR_STATUS 0x000000F4
|
||||
#define MFD_MCX 0x00020800
|
||||
#define MFD_MCX_OFF 0x00000020
|
||||
|
||||
#define MFD_BLK_CTRL 0x00030000
|
||||
#define MFD_BLK_CTRL_MFD_SYS_RESET_SET 0x00000000
|
||||
#define MFD_BLK_CTRL_MFD_SYS_RESET_CLR 0x00000004
|
||||
#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET 0x00000100
|
||||
#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_CLR 0x00000104
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
* Copyright 2018 NXP
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file vpu_encoder_b0.h
|
||||
*
|
||||
* @brief VPU ENCODER B0 definition
|
||||
*
|
||||
*/
|
||||
#ifndef __VPU_ENCODER_B0_H__
|
||||
#define __VPU_ENCODER_B0_H__
|
||||
|
||||
#include <linux/irqreturn.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#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 <linux/mx8_mu.h>
|
||||
#include <media/v4l2-event.h>
|
||||
#include "vpu_encoder_rpc.h"
|
||||
#include "vpu_encoder_config.h"
|
||||
|
||||
extern unsigned int vpu_dbg_level_encoder;
|
||||
|
||||
#define v4l2_fh_to_ctx(__fh) \
|
||||
container_of(__fh, struct vpu_ctx, fh)
|
||||
#define v4l2_ctrl_to_ctx(__ctrl) \
|
||||
container_of((__ctrl)->handler, struct vpu_ctx, ctrl_handler)
|
||||
|
||||
#define VPU_ENC_MAX_CORE_NUM 2
|
||||
#define VPU_MAX_BUFFER 32
|
||||
#define M0FW_FILENAME "vpu/vpu_fw_imx8_enc.bin"
|
||||
#define MMAP_BUF_TYPE_SHIFT 28
|
||||
#define MMAP_BUF_TYPE_MASK 0xF0000000
|
||||
#define M0_BOOT_SIZE_DEFAULT 0x1000000
|
||||
#define M0_BOOT_SIZE_MIN 0x100000
|
||||
#define RPC_SIZE_DEFAULT 0x80000
|
||||
#define RPC_SIZE_MIN 0x20000
|
||||
#define PRINT_SIZE_DEFAULT 0x80000
|
||||
#define PRINT_SIZE_MIN 0x20000
|
||||
#define STREAM_SIZE 0x300000
|
||||
#define MU_B0_REG_CONTROL (0x10000 + 0x24)
|
||||
|
||||
#define MIN_BUFFER_COUNT 3
|
||||
#define BITRATE_COEF 1024
|
||||
#define BITRATE_LOW_THRESHOLD (16)
|
||||
#define BITRATE_HIGH_THRESHOLD (240 * 1024)
|
||||
#define BITRATE_DEFAULT_TARGET (2 * 1024)
|
||||
#define BITRATE_DEFAULT_PEAK (8 * 1024)
|
||||
#define GOP_H_THRESHOLD 300
|
||||
#define GOP_L_THRESHOLD 1
|
||||
#define GOP_DEFAULT 30
|
||||
#define BFRAMES_H_THRESHOLD 4
|
||||
#define BFRAMES_L_THRESHOLD 0
|
||||
#define BFRAMES_DEFAULT 2
|
||||
#define QP_MAX 51
|
||||
#define QP_MIN 0
|
||||
#define QP_DEFAULT 25
|
||||
|
||||
#define VPU_DISABLE_BITS 0x7
|
||||
#define VPU_ENCODER_MASK 0x1
|
||||
|
||||
#define ENCODER_NODE_NUMBER 13 //use /dev/video13 as encoder node
|
||||
struct vpu_v4l2_control {
|
||||
uint32_t id;
|
||||
enum v4l2_ctrl_type type;
|
||||
uint32_t minimum;
|
||||
uint32_t maximum;
|
||||
uint32_t step;
|
||||
uint32_t default_value;
|
||||
uint32_t menu_skip_mask;
|
||||
bool is_volatile;
|
||||
};
|
||||
|
||||
typedef enum{
|
||||
INIT_DONE = 1,
|
||||
RPC_BUF_OFFSET,
|
||||
BOOT_ADDRESS,
|
||||
COMMAND,
|
||||
EVENT
|
||||
} MSG_Type;
|
||||
|
||||
enum PLAT_TYPE {
|
||||
IMX8QXP = 0,
|
||||
IMX8QM = 1,
|
||||
IMX8DM,
|
||||
IMX8DX,
|
||||
PLAT_TYPE_RESERVED
|
||||
};
|
||||
|
||||
enum QUEUE_TYPE {
|
||||
V4L2_SRC = 0,
|
||||
V4L2_DST = 1,
|
||||
};
|
||||
|
||||
enum vpu_video_standard {
|
||||
VPU_VIDEO_UNDEFINED = 0,
|
||||
VPU_VIDEO_AVC = 1,
|
||||
VPU_VIDEO_VC1 = 2,
|
||||
VPU_VIDEO_MPEG2 = 3,
|
||||
VPU_VIDEO_AVS = 4,
|
||||
VPU_VIDEO_ASP = 5,
|
||||
VPU_VIDEO_JPEG = 6,
|
||||
VPU_VIDEO_RV8 = 7,
|
||||
VPU_VIDEO_RV9 = 8,
|
||||
VPU_VIDEO_VP6 = 9,
|
||||
VPU_VIDEO_SPK = 10,
|
||||
VPU_VIDEO_VP8 = 11,
|
||||
VPU_VIDEO_AVC_MVC = 12,
|
||||
VPU_VIDEO_HEVC = 13,
|
||||
VPU_VIDEO_VP9 = 14,
|
||||
};
|
||||
|
||||
#define VPU_PIX_FMT_AVS v4l2_fourcc('A', 'V', 'S', '0')
|
||||
#define VPU_PIX_FMT_ASP v4l2_fourcc('A', 'S', 'P', '0')
|
||||
#define VPU_PIX_FMT_RV8 v4l2_fourcc('R', 'V', '8', '0')
|
||||
#define VPU_PIX_FMT_RV9 v4l2_fourcc('R', 'V', '9', '0')
|
||||
#define VPU_PIX_FMT_VP6 v4l2_fourcc('V', 'P', '6', '0')
|
||||
#define VPU_PIX_FMT_SPK v4l2_fourcc('S', 'P', 'K', '0')
|
||||
#define VPU_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C')
|
||||
#define VPU_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0')
|
||||
#define VPU_PIX_FMT_LOGO v4l2_fourcc('L', 'O', 'G', 'O')
|
||||
|
||||
#define VPU_PIX_FMT_TILED_8 v4l2_fourcc('Z', 'T', '0', '8')
|
||||
#define VPU_PIX_FMT_TILED_10 v4l2_fourcc('Z', 'T', '1', '0')
|
||||
|
||||
enum vpu_pixel_format {
|
||||
VPU_HAS_COLOCATED = 0x00000001,
|
||||
VPU_HAS_SPLIT_FLD = 0x00000002,
|
||||
VPU_PF_MASK = ~(VPU_HAS_COLOCATED | VPU_HAS_SPLIT_FLD),
|
||||
|
||||
VPU_IS_TILED = 0x000000100,
|
||||
VPU_HAS_10BPP = 0x00000200,
|
||||
|
||||
VPU_IS_PLANAR = 0x00001000,
|
||||
VPU_IS_SEMIPLANAR = 0x00002000,
|
||||
VPU_IS_PACKED = 0x00004000,
|
||||
|
||||
// Merged definitions using above flags:
|
||||
VPU_PF_UNDEFINED = 0,
|
||||
VPU_PF_YUV420_SEMIPLANAR = 0x00010000 | VPU_IS_SEMIPLANAR,
|
||||
VPU_PF_YUV420_PLANAR = 0x00020000 | VPU_IS_PLANAR,
|
||||
VPU_PF_UYVY = 0x00040000 | VPU_IS_PACKED,
|
||||
VPU_PF_TILED_8BPP = 0x00080000 | VPU_IS_TILED | VPU_IS_SEMIPLANAR,
|
||||
VPU_PF_TILED_10BPP = 0x00100000 | VPU_IS_TILED | VPU_IS_SEMIPLANAR | VPU_HAS_10BPP,
|
||||
};
|
||||
|
||||
struct vpu_ctx;
|
||||
struct core_device;
|
||||
struct vpu_dev;
|
||||
struct vpu_v4l2_fmt {
|
||||
char *name;
|
||||
unsigned int fourcc;
|
||||
unsigned int num_planes;
|
||||
unsigned int venc_std;
|
||||
unsigned int is_yuv;
|
||||
};
|
||||
|
||||
struct vb2_data_req {
|
||||
struct list_head list;
|
||||
struct vb2_buffer *vb2_buf;
|
||||
int id;
|
||||
u_int32 buffer_flags;
|
||||
};
|
||||
|
||||
enum ENC_RW_FLAG {
|
||||
VPU_ENC_FLAG_WRITEABLE,
|
||||
VPU_ENC_FLAG_READABLE
|
||||
};
|
||||
|
||||
struct queue_data {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int bytesperline;
|
||||
unsigned int sizeimage[3];
|
||||
unsigned int fourcc;
|
||||
unsigned int vdec_std;
|
||||
struct v4l2_rect rect;
|
||||
int buf_type; // v4l2_buf_type
|
||||
bool vb2_q_inited;
|
||||
struct vb2_queue vb2_q; // vb2 queue
|
||||
struct list_head drv_q; // driver queue
|
||||
struct semaphore drv_q_lock;
|
||||
struct vb2_data_req vb2_reqs[VPU_MAX_BUFFER];
|
||||
enum QUEUE_TYPE type;
|
||||
struct vpu_v4l2_fmt *supported_fmts;
|
||||
unsigned int fmt_count;
|
||||
struct vpu_v4l2_fmt *current_fmt;
|
||||
unsigned long rw_flag;
|
||||
struct list_head frame_q;
|
||||
atomic64_t frame_count;
|
||||
struct list_head frame_idle;
|
||||
struct vpu_ctx *ctx;
|
||||
};
|
||||
|
||||
struct vpu_strip_info {
|
||||
unsigned long count;
|
||||
unsigned long max;
|
||||
unsigned long total;
|
||||
};
|
||||
|
||||
struct vpu_fps_sts {
|
||||
unsigned int thd;
|
||||
unsigned int times;
|
||||
unsigned long frame_number;
|
||||
struct timespec ts;
|
||||
unsigned long fps;
|
||||
};
|
||||
|
||||
struct vpu_statistic {
|
||||
unsigned long cmd[GTB_ENC_CMD_RESERVED + 1];
|
||||
unsigned long event[VID_API_ENC_EVENT_RESERVED + 1];
|
||||
unsigned long current_cmd;
|
||||
unsigned long current_event;
|
||||
struct timespec ts_cmd;
|
||||
struct timespec ts_event;
|
||||
unsigned long yuv_count;
|
||||
unsigned long encoded_count;
|
||||
unsigned long h264_count;
|
||||
struct {
|
||||
struct vpu_strip_info fw;
|
||||
struct vpu_strip_info begin;
|
||||
struct vpu_strip_info eos;
|
||||
} strip_sts;
|
||||
bool fps_sts_enable;
|
||||
struct vpu_fps_sts fps[VPU_FPS_STS_CNT];
|
||||
};
|
||||
|
||||
struct vpu_attr {
|
||||
struct device_attribute dev_attr;
|
||||
char name[64];
|
||||
u32 index;
|
||||
struct core_device *core;
|
||||
|
||||
pid_t pid;
|
||||
pid_t tgid;
|
||||
|
||||
struct vpu_statistic statistic;
|
||||
MEDIAIP_ENC_PARAM param;
|
||||
|
||||
unsigned long ts_start[2];
|
||||
unsigned long msg_count;
|
||||
atomic64_t total_dma_size;
|
||||
|
||||
bool created;
|
||||
};
|
||||
|
||||
struct core_device {
|
||||
void *m0_p_fw_space_vir;
|
||||
u_int32 m0_p_fw_space_phy;
|
||||
u32 fw_buf_size;
|
||||
u32 fw_actual_size;
|
||||
void *m0_rpc_virt;
|
||||
u_int32 m0_rpc_phy;
|
||||
u32 rpc_buf_size;
|
||||
u32 print_buf_size;
|
||||
u32 rpc_actual_size;
|
||||
|
||||
struct mutex cmd_mutex;
|
||||
bool fw_is_ready;
|
||||
bool firmware_started;
|
||||
struct completion start_cmp;
|
||||
struct completion snap_done_cmp;
|
||||
struct workqueue_struct *workqueue;
|
||||
struct work_struct msg_work;
|
||||
void __iomem *mu_base_virtaddr;
|
||||
unsigned int vpu_mu_id;
|
||||
int vpu_mu_init;
|
||||
|
||||
u32 supported_instance_count;
|
||||
struct vpu_ctx *ctx[VID_API_NUM_STREAMS];
|
||||
struct vpu_attr attr[VID_API_NUM_STREAMS];
|
||||
struct shared_addr shared_mem;
|
||||
u32 id;
|
||||
u32 reg_base;
|
||||
u32 reg_size;
|
||||
u32 reg_csr_base;
|
||||
u32 reg_csr_size;
|
||||
int irq;
|
||||
struct device *generic_dev;
|
||||
struct vpu_dev *vdev;
|
||||
bool snapshot;
|
||||
bool suspend;
|
||||
bool hang;
|
||||
struct device_attribute core_attr;
|
||||
char name[64];
|
||||
unsigned long reset_times;
|
||||
};
|
||||
|
||||
struct vpu_dev {
|
||||
struct device *generic_dev;
|
||||
struct v4l2_device v4l2_dev;
|
||||
struct video_device *pvpu_encoder_dev;
|
||||
struct platform_device *plat_dev;
|
||||
struct clk *clk_m0;
|
||||
u32 reg_vpu_base;
|
||||
u32 reg_vpu_size;
|
||||
u32 reg_rpc_system;
|
||||
void __iomem *regs_base;
|
||||
struct mutex dev_mutex;
|
||||
struct core_device core_dev[VPU_ENC_MAX_CORE_NUM];
|
||||
u_int32 plat_type;
|
||||
u_int32 core_num;
|
||||
bool hw_enable;
|
||||
|
||||
struct delayed_work watchdog;
|
||||
u8 heartbeat;
|
||||
|
||||
struct {
|
||||
u32 min_width;
|
||||
u32 max_width;
|
||||
u32 step_width;
|
||||
u32 min_height;
|
||||
u32 max_height;
|
||||
u32 step_height;
|
||||
} supported_size;
|
||||
struct {
|
||||
u32 min;
|
||||
u32 max;
|
||||
u32 step;
|
||||
} supported_fps;
|
||||
struct device *pd_vpu;
|
||||
struct device *pd_enc;
|
||||
struct device *pd_mu;
|
||||
};
|
||||
|
||||
struct buffer_addr {
|
||||
void *virt_addr;
|
||||
dma_addr_t phy_addr;
|
||||
u_int32 size;
|
||||
};
|
||||
|
||||
enum {
|
||||
VPU_ENC_STATUS_INITIALIZED,
|
||||
VPU_ENC_STATUS_SNAPSHOT = 20,
|
||||
VPU_ENC_STATUS_FORCE_RELEASE = 21,
|
||||
VPU_ENC_STATUS_EOS_SEND = 22,
|
||||
VPU_ENC_STATUS_START_SEND = 23,
|
||||
VPU_ENC_STATUS_START_DONE = 24,
|
||||
VPU_ENC_STATUS_STOP_REQ = 25,
|
||||
VPU_ENC_STATUS_STOP_SEND = 26,
|
||||
VPU_ENC_STATUS_STOP_DONE = 27,
|
||||
VPU_ENC_STATUS_CLOSED = 28,
|
||||
VPU_ENC_STATUS_CONFIGURED = 29,
|
||||
VPU_ENC_STATUS_HANG = 30,
|
||||
VPU_ENC_STATUS_KEY_FRAME = 31
|
||||
};
|
||||
|
||||
struct vpu_ctx {
|
||||
struct vpu_dev *dev;
|
||||
struct v4l2_fh fh;
|
||||
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
bool ctrl_inited;
|
||||
|
||||
int str_index;
|
||||
unsigned long status;
|
||||
struct queue_data q_data[2];
|
||||
struct mutex instance_mutex;
|
||||
struct work_struct instance_work;
|
||||
struct workqueue_struct *instance_wq;
|
||||
bool ctx_released;
|
||||
struct buffer_addr encoder_stream;
|
||||
struct buffer_addr encFrame[MEDIAIP_MAX_NUM_WINDSOR_SRC_FRAMES];
|
||||
struct buffer_addr refFrame[MEDIAIP_MAX_NUM_WINDSOR_REF_FRAMES];
|
||||
struct buffer_addr actFrame;
|
||||
struct buffer_addr enc_buffer;
|
||||
MEDIAIP_ENC_MEM_REQ_DATA mem_req;
|
||||
struct core_device *core_dev;
|
||||
|
||||
struct completion stop_cmp;
|
||||
bool power_status;
|
||||
|
||||
struct list_head msg_q;
|
||||
struct list_head idle_q;
|
||||
|
||||
struct vpu_statistic sts;
|
||||
unsigned int frozen_count;
|
||||
};
|
||||
|
||||
#define LVL_DEBUG 4
|
||||
#define LVL_INFO 3
|
||||
#define LVL_IRQ 2
|
||||
#define LVL_ALL 1
|
||||
#define LVL_WARN 1
|
||||
#define LVL_ERR 0
|
||||
|
||||
#ifndef TAG
|
||||
#define TAG "[VPU Encoder]\t "
|
||||
#endif
|
||||
|
||||
#define vpu_dbg(level, fmt, arg...) \
|
||||
do { \
|
||||
if (vpu_dbg_level_encoder >= (level)) \
|
||||
pr_info(TAG""fmt, ## arg); \
|
||||
} while (0)
|
||||
|
||||
#define vpu_err(fmt, arg...) vpu_dbg(LVL_ERR, fmt, ##arg)
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* vpu_encoder_config.h
|
||||
*
|
||||
* Author Ming Qian<ming.qian@nxp.com>
|
||||
*/
|
||||
#ifndef _VPU_ENCODER_CONFIG_H
|
||||
#define _VPU_ENCODER_CONFIG_H
|
||||
|
||||
#define VPU_ENC_WIDTH_MAX 1920
|
||||
#define VPU_ENC_HEIGHT_MAX 1080
|
||||
#define VPU_ENC_WIDTH_MIN 64
|
||||
#define VPU_ENC_HEIGHT_MIN 48
|
||||
#define VPU_ENC_WIDTH_STEP 16
|
||||
#define VPU_ENC_HEIGHT_STEP 2
|
||||
#define VPU_ENC_FRAMERATE_MAX 120
|
||||
#define VPU_ENC_FRAMERATE_MIN 1
|
||||
#define VPU_ENC_FRAMERATE_STEP 1
|
||||
|
||||
#define VPU_ENC_WIDTH_DEFAULT 1920
|
||||
#define VPU_ENC_HEIGHT_DEFAULT 1080
|
||||
#define VPU_ENC_FRAMERATE_DEFAULT 30
|
||||
|
||||
#define VPU_MEM_PATTERN 0x5a5a5a5a
|
||||
|
||||
#define VPU_TAIL_SERACH_SIZE 16
|
||||
#define VPU_STRM_END_PATTERN {0x0, 0x0, 0x1, 0xb}
|
||||
#define VPU_STRM_BEGIN_PATTERN {0x0, 0x0, 0x1}
|
||||
|
||||
#define MSG_DATA_DEFAULT_SIZE 256
|
||||
#define MSG_COUNT_THD 16
|
||||
#define FRAME_COUNT_THD 16
|
||||
|
||||
#define VPU_WATCHDOG_INTERVAL_MS 1000
|
||||
#define VPU_ENC_HANG_THD 15
|
||||
|
||||
#define VPU_FPS_STS_CNT 3
|
||||
#define VPU_FPS_STS_THDS {1, 3, 0}
|
||||
#define VPU_FPS_COEF 100
|
||||
|
||||
#define VPU_DETAIL_INDEX_DFT 0xffff
|
||||
|
||||
#endif
|
|
@ -0,0 +1,589 @@
|
|||
/*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @file vpu_encoder_ctrl.c
|
||||
*
|
||||
* Author Ming Qian<ming.qian@nxp.com>
|
||||
*/
|
||||
|
||||
#include <media/v4l2-ctrls.h>
|
||||
|
||||
#include "vpu_encoder_b0.h"
|
||||
#include "vpu_encoder_ctrl.h"
|
||||
|
||||
// H264 level is maped like level 5.1 to uLevel 51, except level 1b to uLevel 14
|
||||
const u_int32 h264_level[] = {
|
||||
[V4L2_MPEG_VIDEO_H264_LEVEL_1_0] = 10,
|
||||
[V4L2_MPEG_VIDEO_H264_LEVEL_1B] = 14,
|
||||
[V4L2_MPEG_VIDEO_H264_LEVEL_1_1] = 11,
|
||||
[V4L2_MPEG_VIDEO_H264_LEVEL_1_2] = 12,
|
||||
[V4L2_MPEG_VIDEO_H264_LEVEL_1_3] = 13,
|
||||
[V4L2_MPEG_VIDEO_H264_LEVEL_2_0] = 20,
|
||||
[V4L2_MPEG_VIDEO_H264_LEVEL_2_1] = 21,
|
||||
[V4L2_MPEG_VIDEO_H264_LEVEL_2_2] = 22,
|
||||
[V4L2_MPEG_VIDEO_H264_LEVEL_3_0] = 30,
|
||||
[V4L2_MPEG_VIDEO_H264_LEVEL_3_1] = 31,
|
||||
[V4L2_MPEG_VIDEO_H264_LEVEL_3_2] = 32,
|
||||
[V4L2_MPEG_VIDEO_H264_LEVEL_4_0] = 40,
|
||||
[V4L2_MPEG_VIDEO_H264_LEVEL_4_1] = 41,
|
||||
[V4L2_MPEG_VIDEO_H264_LEVEL_4_2] = 42,
|
||||
[V4L2_MPEG_VIDEO_H264_LEVEL_5_0] = 50,
|
||||
[V4L2_MPEG_VIDEO_H264_LEVEL_5_1] = 51
|
||||
};
|
||||
|
||||
static int set_h264_profile(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
|
||||
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
|
||||
pMEDIAIP_ENC_PARAM param = &attr->param;
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
switch (ctrl->val) {
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
|
||||
param->eProfile = MEDIAIP_ENC_PROF_H264_BP;
|
||||
break;
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
|
||||
param->eProfile = MEDIAIP_ENC_PROF_H264_MP;
|
||||
break;
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
|
||||
param->eProfile = MEDIAIP_ENC_PROF_H264_HP;
|
||||
break;
|
||||
default:
|
||||
vpu_dbg(LVL_ERR, "not support H264 profile %d, set to main\n",
|
||||
ctrl->val);
|
||||
param->eProfile = MEDIAIP_ENC_PROF_H264_MP;
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_h264_level(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
|
||||
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
|
||||
pMEDIAIP_ENC_PARAM param = &attr->param;
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
param->uLevel = h264_level[ctrl->val];
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
|
||||
vpu_dbg(LVL_DEBUG, "set h264 level to %d\n", ctrl->val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_bitrate_mode(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
|
||||
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
|
||||
pMEDIAIP_ENC_PARAM param = &attr->param;
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
switch (ctrl->val) {
|
||||
case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
|
||||
param->eBitRateMode =
|
||||
MEDIAIP_ENC_BITRATECONTROLMODE_CONSTANT_QP;
|
||||
break;
|
||||
case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
|
||||
param->eBitRateMode = MEDIAIP_ENC_BITRATECONTROLMODE_CBR;
|
||||
break;
|
||||
default:
|
||||
vpu_dbg(LVL_ERR, "not support bitrate mode %d, set to cbr\n",
|
||||
ctrl->val);
|
||||
param->eBitRateMode = MEDIAIP_ENC_BITRATECONTROLMODE_CBR;
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_bitrate(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
|
||||
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
|
||||
pMEDIAIP_ENC_PARAM param = &attr->param;
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
param->uTargetBitrate = ctrl->val / BITRATE_COEF;
|
||||
if (param->uMaxBitRate < param->uTargetBitrate)
|
||||
param->uMaxBitRate = param->uTargetBitrate;
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_bitrate_peak(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
|
||||
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
|
||||
pMEDIAIP_ENC_PARAM param = &attr->param;
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
param->uMaxBitRate = ctrl->val / BITRATE_COEF;
|
||||
if (param->uTargetBitrate > param->uMaxBitRate)
|
||||
param->uTargetBitrate = param->uMaxBitRate;
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_gop_size(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
|
||||
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
|
||||
pMEDIAIP_ENC_PARAM param = &attr->param;
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
param->uIFrameInterval = ctrl->val;
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_i_period(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
|
||||
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
|
||||
pMEDIAIP_ENC_PARAM param = &attr->param;
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
param->uIFrameInterval = ctrl->val;
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_gop_size(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
|
||||
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
|
||||
pMEDIAIP_ENC_PARAM param = &attr->param;
|
||||
|
||||
ctrl->val = param->uIFrameInterval;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_b_frames(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
|
||||
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
|
||||
pMEDIAIP_ENC_PARAM param = &attr->param;
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
param->uGopBLength = ctrl->val;
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_qp(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
|
||||
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
|
||||
pMEDIAIP_ENC_PARAM param = &attr->param;
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
param->uInitSliceQP = ctrl->val;
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_min_buffers_for_output(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
vpu_dbg(LVL_DEBUG, "get min buffers for output\n");
|
||||
|
||||
ctrl->val = MIN_BUFFER_COUNT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_display_re_ordering(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
|
||||
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
|
||||
pMEDIAIP_ENC_PARAM param = &attr->param;
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
if (ctrl->val)
|
||||
param->uLowLatencyMode = 1;
|
||||
else
|
||||
param->uLowLatencyMode = 0;
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_force_key_frame(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct vpu_ctx *ctx = v4l2_ctrl_to_ctx(ctrl);
|
||||
|
||||
set_bit(VPU_ENC_STATUS_KEY_FRAME, &ctx->status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_ctrl_h264_profile(struct vpu_ctx *ctx)
|
||||
{
|
||||
static const struct v4l2_ctrl_ops ctrl_h264_profile_ops = {
|
||||
.s_ctrl = set_h264_profile,
|
||||
};
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler,
|
||||
&ctrl_h264_profile_ops,
|
||||
V4L2_CID_MPEG_VIDEO_H264_PROFILE,
|
||||
V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
|
||||
0xa,
|
||||
V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE);
|
||||
if (!ctrl) {
|
||||
vpu_dbg(LVL_ERR, "add ctrl h264 profile fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_ctrl_h264_level(struct vpu_ctx *ctx)
|
||||
{
|
||||
static const struct v4l2_ctrl_ops ctrl_h264_level_ops = {
|
||||
.s_ctrl = set_h264_level,
|
||||
};
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler,
|
||||
&ctrl_h264_level_ops,
|
||||
V4L2_CID_MPEG_VIDEO_H264_LEVEL,
|
||||
V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
|
||||
0x0,
|
||||
V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
|
||||
if (!ctrl) {
|
||||
vpu_dbg(LVL_ERR, "add ctrl h264 level fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_ctrl_bitrate_mode(struct vpu_ctx *ctx)
|
||||
{
|
||||
static const struct v4l2_ctrl_ops ctrl_bitrate_mode_ops = {
|
||||
.s_ctrl = set_bitrate_mode,
|
||||
};
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler,
|
||||
&ctrl_bitrate_mode_ops,
|
||||
V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
|
||||
V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
|
||||
0x0,
|
||||
V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
|
||||
if (!ctrl) {
|
||||
vpu_dbg(LVL_ERR, "add ctrl bitrate mode fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_ctrl_bitrate(struct vpu_ctx *ctx)
|
||||
{
|
||||
static const struct v4l2_ctrl_ops ctrl_bitrate_ops = {
|
||||
.s_ctrl = set_bitrate,
|
||||
};
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
|
||||
&ctrl_bitrate_ops,
|
||||
V4L2_CID_MPEG_VIDEO_BITRATE,
|
||||
BITRATE_LOW_THRESHOLD * BITRATE_COEF,
|
||||
BITRATE_HIGH_THRESHOLD * BITRATE_COEF,
|
||||
BITRATE_COEF,
|
||||
BITRATE_DEFAULT_TARGET * BITRATE_COEF);
|
||||
if (!ctrl) {
|
||||
vpu_dbg(LVL_ERR, "add ctrl bitrate fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_ctrl_bitrate_peak(struct vpu_ctx *ctx)
|
||||
{
|
||||
static const struct v4l2_ctrl_ops ctrl_bitrate_ops = {
|
||||
.s_ctrl = set_bitrate_peak,
|
||||
};
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
|
||||
&ctrl_bitrate_ops,
|
||||
V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
|
||||
BITRATE_LOW_THRESHOLD * BITRATE_COEF,
|
||||
BITRATE_HIGH_THRESHOLD * BITRATE_COEF,
|
||||
BITRATE_COEF,
|
||||
BITRATE_DEFAULT_PEAK * BITRATE_COEF);
|
||||
if (!ctrl) {
|
||||
vpu_dbg(LVL_ERR, "add ctrl bitrate peak fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_ctrl_gop_size(struct vpu_ctx *ctx)
|
||||
{
|
||||
static const struct v4l2_ctrl_ops ctrl_gop_ops = {
|
||||
.s_ctrl = set_gop_size,
|
||||
.g_volatile_ctrl = get_gop_size,
|
||||
};
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
|
||||
&ctrl_gop_ops,
|
||||
V4L2_CID_MPEG_VIDEO_GOP_SIZE,
|
||||
GOP_L_THRESHOLD,
|
||||
GOP_H_THRESHOLD,
|
||||
1,
|
||||
GOP_DEFAULT);
|
||||
if (!ctrl) {
|
||||
vpu_dbg(LVL_ERR, "add ctrl gop size fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
|
||||
ctrl->flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_ctrl_i_period(struct vpu_ctx *ctx)
|
||||
{
|
||||
static const struct v4l2_ctrl_ops ctrl_i_period_ops = {
|
||||
.s_ctrl = set_i_period,
|
||||
.g_volatile_ctrl = get_gop_size,
|
||||
};
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
|
||||
&ctrl_i_period_ops,
|
||||
V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
|
||||
GOP_L_THRESHOLD,
|
||||
GOP_H_THRESHOLD,
|
||||
1,
|
||||
GOP_DEFAULT);
|
||||
|
||||
if (!ctrl) {
|
||||
vpu_dbg(LVL_ERR, "add ctrl i period fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
|
||||
ctrl->flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_ctrl_b_frames(struct vpu_ctx *ctx)
|
||||
{
|
||||
static const struct v4l2_ctrl_ops ctrl_b_frames = {
|
||||
.s_ctrl = set_b_frames,
|
||||
};
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
|
||||
&ctrl_b_frames,
|
||||
V4L2_CID_MPEG_VIDEO_B_FRAMES,
|
||||
BFRAMES_L_THRESHOLD,
|
||||
BFRAMES_H_THRESHOLD,
|
||||
1,
|
||||
BFRAMES_DEFAULT);
|
||||
|
||||
if (!ctrl) {
|
||||
vpu_dbg(LVL_ERR, "add ctrl b frames fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_ctrl_i_frame_qp(struct vpu_ctx *ctx)
|
||||
{
|
||||
static const struct v4l2_ctrl_ops ctrl_iframe_qp_ops = {
|
||||
.s_ctrl = set_qp,
|
||||
};
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
|
||||
&ctrl_iframe_qp_ops,
|
||||
V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
|
||||
QP_MIN,
|
||||
QP_MAX,
|
||||
1,
|
||||
QP_DEFAULT);
|
||||
if (!ctrl) {
|
||||
vpu_dbg(LVL_ERR, "add ctrl h264 I frame qp fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_ctrl_p_frame_qp(struct vpu_ctx *ctx)
|
||||
{
|
||||
static const struct v4l2_ctrl_ops ctrl_pframe_qp_ops = {
|
||||
.s_ctrl = set_qp,
|
||||
};
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
|
||||
&ctrl_pframe_qp_ops,
|
||||
V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
|
||||
QP_MIN,
|
||||
QP_MAX,
|
||||
1,
|
||||
QP_DEFAULT);
|
||||
if (!ctrl) {
|
||||
vpu_dbg(LVL_ERR, "add ctrl h264 P frame qp fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_ctrl_b_frame_qp(struct vpu_ctx *ctx)
|
||||
{
|
||||
static const struct v4l2_ctrl_ops ctrl_bframe_qp_ops = {
|
||||
.s_ctrl = set_qp,
|
||||
};
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
|
||||
&ctrl_bframe_qp_ops,
|
||||
V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,
|
||||
QP_MIN,
|
||||
QP_MAX,
|
||||
1,
|
||||
QP_DEFAULT);
|
||||
if (!ctrl) {
|
||||
vpu_dbg(LVL_ERR, "add ctrl h264 B frame qp fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_ctrl_min_buffers_for_output(struct vpu_ctx *ctx)
|
||||
{
|
||||
static const struct v4l2_ctrl_ops ctrl_min_buffers_ops = {
|
||||
.g_volatile_ctrl = get_min_buffers_for_output,
|
||||
};
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
|
||||
&ctrl_min_buffers_ops,
|
||||
V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,
|
||||
1,
|
||||
32,
|
||||
1,
|
||||
MIN_BUFFER_COUNT);
|
||||
if (!ctrl) {
|
||||
vpu_dbg(LVL_ERR, "add ctrl min buffers for output fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_ctrl_display_re_ordering(struct vpu_ctx *ctx)
|
||||
{
|
||||
static const struct v4l2_ctrl_ops re_ordering_ops = {
|
||||
.s_ctrl = set_display_re_ordering,
|
||||
};
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
|
||||
&re_ordering_ops,
|
||||
V4L2_CID_MPEG_VIDEO_H264_ASO,
|
||||
0, 1, 1, 1);
|
||||
if (!ctrl) {
|
||||
vpu_dbg(LVL_ERR, "add ctrl display re ordering fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_ctrl_force_key_frame(struct vpu_ctx *ctx)
|
||||
{
|
||||
static const struct v4l2_ctrl_ops force_key_frame_ops = {
|
||||
.s_ctrl = set_force_key_frame,
|
||||
};
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
ctrl = v4l2_ctrl_new_std(&ctx->ctrl_handler,
|
||||
&force_key_frame_ops,
|
||||
V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME,
|
||||
0, 0, 0, 0);
|
||||
if (!ctrl) {
|
||||
vpu_dbg(LVL_ERR, "add ctrl force key frame fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vpu_enc_register_ctrls(struct vpu_ctx *ctx)
|
||||
{
|
||||
add_ctrl_h264_profile(ctx);
|
||||
add_ctrl_h264_level(ctx);
|
||||
add_ctrl_bitrate_mode(ctx);
|
||||
add_ctrl_bitrate(ctx);
|
||||
add_ctrl_bitrate_peak(ctx);
|
||||
add_ctrl_gop_size(ctx);
|
||||
add_ctrl_i_period(ctx);
|
||||
add_ctrl_b_frames(ctx);
|
||||
add_ctrl_i_frame_qp(ctx);
|
||||
add_ctrl_p_frame_qp(ctx);
|
||||
add_ctrl_b_frame_qp(ctx);
|
||||
add_ctrl_min_buffers_for_output(ctx);
|
||||
add_ctrl_display_re_ordering(ctx);
|
||||
add_ctrl_force_key_frame(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vpu_enc_setup_ctrls(struct vpu_ctx *ctx)
|
||||
{
|
||||
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",
|
||||
ctx->ctrl_handler.error);
|
||||
return -EINVAL;
|
||||
}
|
||||
ctx->ctrl_inited = true;
|
||||
return v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
|
||||
}
|
||||
|
||||
int vpu_enc_free_ctrls(struct vpu_ctx *ctx)
|
||||
{
|
||||
if (ctx->ctrl_inited) {
|
||||
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
|
||||
ctx->ctrl_inited = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* vpu_encoder_ctrl.h
|
||||
*
|
||||
* Author Ming Qian<ming.qian@nxp.com>
|
||||
*/
|
||||
#ifndef _VPU_ENCODER_CTRL_H
|
||||
#define _VPU_ENCODER_CTRL_H
|
||||
|
||||
#include "mediasys_types.h"
|
||||
|
||||
int vpu_enc_setup_ctrls(struct vpu_ctx *ctx);
|
||||
int vpu_enc_free_ctrls(struct vpu_ctx *ctx);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,412 @@
|
|||
/*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* vpu_encoder_mem.c
|
||||
*
|
||||
* Author Ming Qian<ming.qian@nxp.com>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include "vpu_encoder_config.h"
|
||||
#include "vpu_encoder_b0.h"
|
||||
#include "vpu_encoder_mem.h"
|
||||
|
||||
void vpu_enc_add_dma_size(struct vpu_attr *attr, unsigned long size)
|
||||
{
|
||||
if (!attr)
|
||||
return;
|
||||
|
||||
atomic64_add(size, &attr->total_dma_size);
|
||||
}
|
||||
|
||||
void vpu_enc_sub_dma_size(struct vpu_attr *attr, unsigned long size)
|
||||
{
|
||||
if (!attr)
|
||||
return;
|
||||
|
||||
atomic64_sub(size, &attr->total_dma_size);
|
||||
}
|
||||
|
||||
int vpu_enc_alloc_dma_buffer(struct vpu_ctx *ctx, struct buffer_addr *buffer)
|
||||
{
|
||||
if (!ctx || !ctx->dev || !buffer || !buffer->size)
|
||||
return -EINVAL;
|
||||
|
||||
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",
|
||||
buffer->size);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset_io(buffer->virt_addr, 0, buffer->size);
|
||||
vpu_enc_add_dma_size(get_vpu_ctx_attr(ctx), buffer->size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vpu_enc_init_dma_buffer(struct buffer_addr *buffer)
|
||||
{
|
||||
if (!buffer)
|
||||
return;
|
||||
|
||||
buffer->virt_addr = NULL;
|
||||
buffer->phy_addr = 0;
|
||||
buffer->size = 0;
|
||||
}
|
||||
|
||||
int vpu_enc_free_dma_buffer(struct vpu_ctx *ctx, struct buffer_addr *buffer)
|
||||
{
|
||||
if (!ctx || !ctx->dev || !buffer)
|
||||
return -EINVAL;
|
||||
|
||||
if (!buffer->virt_addr)
|
||||
return 0;
|
||||
|
||||
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);
|
||||
|
||||
vpu_enc_init_dma_buffer(buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 get_enc_alloc_size(u32 size)
|
||||
{
|
||||
u32 esize = ALIGN(size, PAGE_SIZE);
|
||||
|
||||
if (esize < size + sizeof(u32))
|
||||
esize += PAGE_SIZE;
|
||||
|
||||
return esize;
|
||||
}
|
||||
|
||||
static int alloc_mem_res(struct vpu_ctx *ctx, struct buffer_addr *buffer,
|
||||
MEDIAIP_ENC_MEM_RESOURCE *resource, u32 size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!ctx || !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_dma_buffer(ctx, 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_mem_res(struct vpu_ctx *ctx, struct buffer_addr *buffer,
|
||||
MEDIAIP_ENC_MEM_RESOURCE *resource)
|
||||
{
|
||||
if (!ctx || !buffer || !resource)
|
||||
return -EINVAL;
|
||||
|
||||
vpu_enc_free_dma_buffer(ctx, 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;
|
||||
|
||||
for (i = 0; i < ctx->mem_req.uEncFrmNum; i++)
|
||||
free_mem_res(ctx, &ctx->encFrame[i],
|
||||
&pool->tEncFrameBuffers[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alloc_enc_frames(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < ctx->mem_req.uEncFrmNum; i++) {
|
||||
ret = alloc_mem_res(ctx,
|
||||
&ctx->encFrame[i],
|
||||
&pool->tEncFrameBuffers[i],
|
||||
ctx->mem_req.uEncFrmSize);
|
||||
if (ret) {
|
||||
vpu_err("alloc enc frame[%d] fail\n", i);
|
||||
goto error;
|
||||
}
|
||||
vpu_dbg(LVL_INFO, "encFrame[%d]: 0x%llx,%d(%d)\n", i,
|
||||
ctx->encFrame[i].phy_addr,
|
||||
ctx->mem_req.uEncFrmSize,
|
||||
ctx->encFrame[i].size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
error:
|
||||
free_enc_frames(ctx, pool);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int free_ref_frames(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ctx->mem_req.uRefFrmNum; i++)
|
||||
free_mem_res(ctx, &ctx->refFrame[i],
|
||||
&pool->tRefFrameBuffers[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alloc_ref_frames(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < ctx->mem_req.uRefFrmNum; i++) {
|
||||
ret = alloc_mem_res(ctx,
|
||||
&ctx->refFrame[i],
|
||||
&pool->tRefFrameBuffers[i],
|
||||
ctx->mem_req.uRefFrmSize);
|
||||
if (ret) {
|
||||
vpu_err("alloc ref frame[%d] fail\n", i);
|
||||
goto error;
|
||||
}
|
||||
vpu_dbg(LVL_INFO, "refFrame[%d]: 0x%llx,%d(%d)\n", i,
|
||||
ctx->refFrame[i].phy_addr,
|
||||
ctx->mem_req.uRefFrmSize,
|
||||
ctx->refFrame[i].size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
error:
|
||||
free_ref_frames(ctx, pool);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alloc_act_frame(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = alloc_mem_res(ctx,
|
||||
&ctx->actFrame,
|
||||
&pool->tActFrameBufferArea,
|
||||
ctx->mem_req.uActBufSize);
|
||||
if (ret) {
|
||||
vpu_err("alloc act frame fail\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
vpu_dbg(LVL_INFO, "actFrame: 0x%llx, %d(%d)\n",
|
||||
ctx->actFrame.phy_addr,
|
||||
ctx->mem_req.uActBufSize,
|
||||
ctx->actFrame.size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_mem_pattern(u32 *ptr)
|
||||
{
|
||||
if (!ptr)
|
||||
return;
|
||||
*ptr = VPU_MEM_PATTERN;
|
||||
}
|
||||
|
||||
static int check_mem_pattern(u32 *ptr)
|
||||
{
|
||||
if (!ptr)
|
||||
return -EINVAL;
|
||||
|
||||
if (*ptr != VPU_MEM_PATTERN)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vpu_enc_set_mem_pattern(struct vpu_ctx *ctx)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
for (i = 0; i < MEDIAIP_MAX_NUM_WINDSOR_SRC_FRAMES; i++) {
|
||||
if (!ctx->encFrame[i].virt_addr)
|
||||
continue;
|
||||
set_mem_pattern(ctx->encFrame[i].virt_addr +
|
||||
ctx->mem_req.uEncFrmSize);
|
||||
}
|
||||
|
||||
for (i = 0; i < MEDIAIP_MAX_NUM_WINDSOR_REF_FRAMES; i++) {
|
||||
if (!ctx->refFrame[i].virt_addr)
|
||||
continue;
|
||||
set_mem_pattern(ctx->refFrame[i].virt_addr +
|
||||
ctx->mem_req.uRefFrmSize);
|
||||
}
|
||||
|
||||
if (ctx->actFrame.virt_addr)
|
||||
set_mem_pattern(ctx->actFrame.virt_addr +
|
||||
ctx->mem_req.uActBufSize);
|
||||
}
|
||||
|
||||
int vpu_enc_check_mem_overstep(struct vpu_ctx *ctx)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
int flag = 0;
|
||||
|
||||
if (!ctx)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < MEDIAIP_MAX_NUM_WINDSOR_SRC_FRAMES; i++) {
|
||||
if (!ctx->encFrame[i].virt_addr)
|
||||
continue;
|
||||
ret = check_mem_pattern(ctx->encFrame[i].virt_addr +
|
||||
ctx->mem_req.uEncFrmSize);
|
||||
if (ret) {
|
||||
vpu_err("***error:[%d][%d]encFrame[%d] out of bounds\n",
|
||||
ctx->core_dev->id, ctx->str_index, i);
|
||||
flag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MEDIAIP_MAX_NUM_WINDSOR_REF_FRAMES; i++) {
|
||||
if (!ctx->refFrame[i].virt_addr)
|
||||
continue;
|
||||
ret = check_mem_pattern(ctx->refFrame[i].virt_addr +
|
||||
ctx->mem_req.uRefFrmSize);
|
||||
if (ret) {
|
||||
vpu_err("***error:[%d][%d]refFrame[%d] out of bounds\n",
|
||||
ctx->core_dev->id, ctx->str_index, i);
|
||||
flag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->actFrame.virt_addr) {
|
||||
ret = check_mem_pattern(ctx->actFrame.virt_addr +
|
||||
ctx->mem_req.uActBufSize);
|
||||
if (ret) {
|
||||
vpu_err("***error:[%d][%d]actFrame out of bounds\n",
|
||||
ctx->core_dev->id, ctx->str_index);
|
||||
flag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
vpu_err("Error:Memory out of bounds in [%d][%d]\n",
|
||||
ctx->core_dev->id, ctx->str_index);
|
||||
vpu_enc_set_mem_pattern(ctx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vpu_enc_alloc_mem(struct vpu_ctx *ctx,
|
||||
MEDIAIP_ENC_MEM_REQ_DATA *req_data,
|
||||
pMEDIAIP_ENC_MEM_POOL pool)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!ctx || !req_data || !pool)
|
||||
return -EINVAL;
|
||||
|
||||
if (ctx->mem_req.uEncFrmSize < req_data->uEncFrmSize ||
|
||||
ctx->mem_req.uEncFrmNum < req_data->uEncFrmNum) {
|
||||
free_enc_frames(ctx, pool);
|
||||
ctx->mem_req.uEncFrmSize = req_data->uEncFrmSize;
|
||||
ctx->mem_req.uEncFrmNum = req_data->uEncFrmNum;
|
||||
ret = alloc_enc_frames(ctx, pool);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ctx->mem_req.uRefFrmSize < req_data->uRefFrmSize ||
|
||||
ctx->mem_req.uRefFrmNum < req_data->uRefFrmNum) {
|
||||
free_ref_frames(ctx, pool);
|
||||
ctx->mem_req.uRefFrmSize = req_data->uRefFrmSize;
|
||||
ctx->mem_req.uRefFrmNum = req_data->uRefFrmNum;
|
||||
ret = alloc_ref_frames(ctx, pool);
|
||||
if (ret)
|
||||
goto error_alloc_refs;
|
||||
}
|
||||
|
||||
if (ctx->mem_req.uActBufSize < req_data->uActBufSize) {
|
||||
free_act_frame(ctx, pool);
|
||||
ctx->mem_req.uActBufSize = req_data->uActBufSize;
|
||||
ret = alloc_act_frame(ctx, pool);
|
||||
if (ret)
|
||||
goto error_alloc_act;
|
||||
}
|
||||
|
||||
vpu_enc_set_mem_pattern(ctx);
|
||||
|
||||
return 0;
|
||||
error_alloc_act:
|
||||
free_ref_frames(ctx, pool);
|
||||
error_alloc_refs:
|
||||
free_enc_frames(ctx, pool);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vpu_enc_free_mem(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool)
|
||||
{
|
||||
if (!ctx || !pool)
|
||||
return -EINVAL;
|
||||
|
||||
free_act_frame(ctx, pool);
|
||||
free_ref_frames(ctx, pool);
|
||||
free_enc_frames(ctx, pool);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vpu_enc_alloc_stream(struct vpu_ctx *ctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ctx->encoder_stream.virt_addr)
|
||||
return 0;
|
||||
|
||||
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");
|
||||
return -ENOMEM;
|
||||
}
|
||||
vpu_dbg(LVL_INFO, "encoder_stream: 0x%llx, %d\n",
|
||||
ctx->encoder_stream.phy_addr, ctx->encoder_stream.size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vpu_enc_free_stream(struct vpu_ctx *ctx)
|
||||
{
|
||||
vpu_enc_free_dma_buffer(ctx, &ctx->encoder_stream);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* vpu_encoder_mem.h
|
||||
*
|
||||
* Author Ming Qian<ming.qian@nxp.com>
|
||||
*/
|
||||
#ifndef _VPU_ENCODER_MEM_H
|
||||
#define _VPU_ENCODER_MEM_H
|
||||
|
||||
#include "vpu_encoder_b0.h"
|
||||
|
||||
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);
|
||||
int vpu_enc_free_dma_buffer(struct vpu_ctx *ctx, struct buffer_addr *buffer);
|
||||
void vpu_enc_init_dma_buffer(struct buffer_addr *buffer);
|
||||
int vpu_enc_check_mem_overstep(struct vpu_ctx *ctx);
|
||||
int vpu_enc_alloc_mem(struct vpu_ctx *ctx,
|
||||
MEDIAIP_ENC_MEM_REQ_DATA *req_data,
|
||||
pMEDIAIP_ENC_MEM_POOL pool);
|
||||
int vpu_enc_free_mem(struct vpu_ctx *ctx, pMEDIAIP_ENC_MEM_POOL pool);
|
||||
int vpu_enc_alloc_stream(struct vpu_ctx *ctx);
|
||||
void vpu_enc_free_stream(struct vpu_ctx *ctx);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,448 @@
|
|||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include "vpu_encoder_rpc.h"
|
||||
|
||||
void rpc_init_shared_memory_encoder(struct shared_addr *This,
|
||||
unsigned long long base_phy_addr,
|
||||
void *base_virt_addr,
|
||||
u_int32 total_size,
|
||||
u32 *actual_size)
|
||||
{
|
||||
pENC_RPC_HOST_IFACE pSharedInterface;
|
||||
unsigned int phy_addr;
|
||||
unsigned int i;
|
||||
unsigned int temp_addr;
|
||||
BUFFER_DESCRIPTOR_TYPE *pSharedCmdBufDescPtr;
|
||||
BUFFER_DESCRIPTOR_TYPE *pSharedMsgBufDescPtr;
|
||||
pMEDIA_ENC_API_CONTROL_INTERFACE pEncCtrlInterface;
|
||||
|
||||
This->shared_mem_phy = base_phy_addr;
|
||||
This->shared_mem_vir = base_virt_addr;
|
||||
This->base_offset = (unsigned long long)(base_virt_addr - base_phy_addr);
|
||||
|
||||
pSharedInterface = (pENC_RPC_HOST_IFACE)This->shared_mem_vir;
|
||||
This->pSharedInterface = pSharedInterface;
|
||||
|
||||
pSharedInterface->FwExecBaseAddr = base_phy_addr;
|
||||
pSharedInterface->FwExecAreaSize = total_size;
|
||||
|
||||
pSharedCmdBufDescPtr = (BUFFER_DESCRIPTOR_TYPE *)&pSharedInterface->StreamCmdBufferDesc;
|
||||
pSharedMsgBufDescPtr = (BUFFER_DESCRIPTOR_TYPE *)&pSharedInterface->StreamMsgBufferDesc;
|
||||
|
||||
phy_addr = base_phy_addr + sizeof(ENC_RPC_HOST_IFACE);
|
||||
This->cmd_mem_phy = phy_addr;
|
||||
This->cmd_mem_vir = This->shared_mem_vir + sizeof(ENC_RPC_HOST_IFACE);
|
||||
|
||||
pSharedCmdBufDescPtr->wptr = phy_addr;
|
||||
pSharedCmdBufDescPtr->rptr = pSharedCmdBufDescPtr->wptr;
|
||||
pSharedCmdBufDescPtr->start = pSharedCmdBufDescPtr->wptr;
|
||||
pSharedCmdBufDescPtr->end = pSharedCmdBufDescPtr->start + CMD_SIZE;
|
||||
|
||||
phy_addr += CMD_SIZE;
|
||||
This->msg_mem_phy = phy_addr;
|
||||
This->msg_mem_vir = This->cmd_mem_vir + CMD_SIZE;
|
||||
|
||||
pSharedMsgBufDescPtr->wptr = phy_addr;
|
||||
pSharedMsgBufDescPtr->rptr = pSharedMsgBufDescPtr->wptr;
|
||||
pSharedMsgBufDescPtr->start = pSharedMsgBufDescPtr->wptr;
|
||||
pSharedMsgBufDescPtr->end = pSharedMsgBufDescPtr->start + MSG_SIZE;
|
||||
|
||||
phy_addr += MSG_SIZE;
|
||||
|
||||
for (i = 0; i < VID_API_NUM_STREAMS; i++) {
|
||||
pSharedInterface->pEncCtrlInterface[i] = phy_addr;
|
||||
phy_addr += sizeof(MEDIA_ENC_API_CONTROL_INTERFACE);
|
||||
}
|
||||
|
||||
for (i = 0; i < VID_API_NUM_STREAMS; i++) {
|
||||
temp_addr = pSharedInterface->pEncCtrlInterface[i];
|
||||
pEncCtrlInterface = (pMEDIA_ENC_API_CONTROL_INTERFACE)(temp_addr + This->base_offset);
|
||||
pEncCtrlInterface->pEncYUVBufferDesc = phy_addr;
|
||||
phy_addr += sizeof(MEDIAIP_ENC_YUV_BUFFER_DESC);
|
||||
pEncCtrlInterface->pEncStreamBufferDesc = phy_addr;
|
||||
phy_addr += sizeof(BUFFER_DESCRIPTOR_TYPE);
|
||||
pEncCtrlInterface->pEncExpertModeParam = phy_addr;
|
||||
phy_addr += sizeof(MEDIAIP_ENC_EXPERT_MODE_PARAM);
|
||||
pEncCtrlInterface->pEncParam = phy_addr;
|
||||
phy_addr += sizeof(MEDIAIP_ENC_PARAM);
|
||||
pEncCtrlInterface->pEncMemPool = phy_addr;
|
||||
phy_addr += sizeof(MEDIAIP_ENC_MEM_POOL);
|
||||
pEncCtrlInterface->pEncEncodingStatus = phy_addr;
|
||||
phy_addr += sizeof(ENC_ENCODING_STATUS);
|
||||
pEncCtrlInterface->pEncDSAStatus = phy_addr;
|
||||
phy_addr += sizeof(ENC_DSA_STATUS_t);
|
||||
}
|
||||
if (actual_size)
|
||||
*actual_size = phy_addr - base_phy_addr;
|
||||
}
|
||||
|
||||
void rpc_set_system_cfg_value_encoder(void *Interface, u_int32 regs_base, u_int32 core_id)
|
||||
{
|
||||
pENC_RPC_HOST_IFACE pSharedInterface;
|
||||
MEDIAIP_FW_SYSTEM_CONFIG *pSystemCfg;
|
||||
|
||||
pSharedInterface = (pENC_RPC_HOST_IFACE)Interface;
|
||||
pSystemCfg = &pSharedInterface->sSystemCfg;
|
||||
pSystemCfg->uNumWindsors = 1;
|
||||
pSystemCfg->uWindsorIrqPin[0x0][0x0] = 0x4; // PAL_IRQ_WINDSOR_LOW
|
||||
pSystemCfg->uWindsorIrqPin[0x0][0x1] = 0x5; // PAL_IRQ_WINDSOR_HI
|
||||
pSystemCfg->uMaloneBaseAddress[0] = (unsigned int)(regs_base + 0x180000);
|
||||
if (core_id == 0)
|
||||
pSystemCfg->uWindsorBaseAddress[0] = (unsigned int)(regs_base + 0x800000);
|
||||
else
|
||||
pSystemCfg->uWindsorBaseAddress[0] = (unsigned int)(regs_base + 0xa00000);
|
||||
pSystemCfg->uMaloneBaseAddress[0x1] = 0x0;
|
||||
pSystemCfg->uHifOffset[0x0] = 0x1C000;
|
||||
pSystemCfg->uHifOffset[0x1] = 0x0;
|
||||
|
||||
pSystemCfg->uDPVBaseAddr = 0x0;
|
||||
pSystemCfg->uDPVIrqPin = 0x0;
|
||||
pSystemCfg->uPixIfBaseAddr = (unsigned int)(regs_base + 0x180000 + 0x20000);
|
||||
pSystemCfg->uFSLCacheBaseAddr[0] = (unsigned int)(regs_base + 0x60000);
|
||||
pSystemCfg->uFSLCacheBaseAddr[1] = (unsigned int)(regs_base + 0x68000);
|
||||
}
|
||||
|
||||
u_int32 rpc_MediaIPFW_Video_buffer_space_check_encoder(BUFFER_DESCRIPTOR_TYPE *pBufDesc,
|
||||
BOOL bFull,
|
||||
u_int32 uSize,
|
||||
u_int32 *puUpdateAddress)
|
||||
{
|
||||
u_int32 uPtr1;
|
||||
u_int32 uPtr2;
|
||||
u_int32 start;
|
||||
u_int32 end;
|
||||
u_int32 uTemp;
|
||||
|
||||
/* bFull is FALSE when send message, write data */
|
||||
/* bFull is TRUE when process commands, read data */
|
||||
uPtr1 = (bFull) ? pBufDesc->rptr : pBufDesc->wptr;
|
||||
uPtr2 = (bFull) ? pBufDesc->wptr : pBufDesc->rptr;
|
||||
|
||||
if (uPtr1 == uPtr2) {
|
||||
if (bFull)
|
||||
/* No data at all to read */
|
||||
return 0;
|
||||
else {
|
||||
/* wrt pointer equal to read pointer thus the */
|
||||
/* buffer is completely empty for further writes */
|
||||
start = pBufDesc->start;
|
||||
end = pBufDesc->end;
|
||||
/* The address to be returned in this case is for */
|
||||
/* the updated write pointer. */
|
||||
uTemp = uPtr1 + uSize;
|
||||
if (uTemp >= end)
|
||||
uTemp += (start - end);
|
||||
*puUpdateAddress = uTemp;
|
||||
return (end - start);
|
||||
}
|
||||
} else if (uPtr1 < uPtr2) {
|
||||
/* return updated rd pointer address */
|
||||
/* In this case if size was too big - we expect the */
|
||||
/* external ftn to compare the size against the */
|
||||
/* space returned.
|
||||
*/
|
||||
*puUpdateAddress = uPtr1 + uSize;
|
||||
return (uPtr2 - uPtr1);
|
||||
}
|
||||
/* We know the system has looped!! */
|
||||
start = pBufDesc->start;
|
||||
end = pBufDesc->end;
|
||||
uTemp = uPtr1 + uSize;
|
||||
if (uTemp >= end)
|
||||
uTemp += (start - end);
|
||||
*puUpdateAddress = uTemp;
|
||||
return ((end - uPtr1) + (uPtr2 - start));
|
||||
}
|
||||
|
||||
static void rpc_update_cmd_buffer_ptr_encoder(BUFFER_DESCRIPTOR_TYPE *pCmdDesc)
|
||||
{
|
||||
u_int32 uWritePtr;
|
||||
|
||||
/*avoid sw reset fail*/
|
||||
mb();
|
||||
uWritePtr = pCmdDesc->wptr + 4;
|
||||
if (uWritePtr >= pCmdDesc->end)
|
||||
uWritePtr = pCmdDesc->start;
|
||||
pCmdDesc->wptr = uWritePtr;
|
||||
}
|
||||
|
||||
void rpc_send_cmd_buf_encoder(struct shared_addr *This,
|
||||
u_int32 idx,
|
||||
u_int32 cmdid,
|
||||
u_int32 cmdnum,
|
||||
u_int32 *local_cmddata)
|
||||
{
|
||||
pENC_RPC_HOST_IFACE pSharedInterface = (pENC_RPC_HOST_IFACE)This->shared_mem_vir;
|
||||
BUFFER_DESCRIPTOR_TYPE *pCmdDesc = &pSharedInterface->StreamCmdBufferDesc;
|
||||
u_int32 *cmddata;
|
||||
u_int32 i;
|
||||
u_int32 *cmdword = (u_int32 *)(This->cmd_mem_vir+pCmdDesc->wptr - pCmdDesc->start);
|
||||
|
||||
*cmdword = 0;
|
||||
*cmdword |= ((idx & 0x000000ff) << 24);
|
||||
*cmdword |= ((cmdnum & 0x000000ff) << 16);
|
||||
*cmdword |= ((cmdid & 0x00003fff) << 0);
|
||||
rpc_update_cmd_buffer_ptr_encoder(pCmdDesc);
|
||||
|
||||
for (i = 0; i < cmdnum; i++) {
|
||||
cmddata = (u_int32 *)(This->cmd_mem_vir+pCmdDesc->wptr - pCmdDesc->start);
|
||||
*cmddata = local_cmddata[i];
|
||||
rpc_update_cmd_buffer_ptr_encoder(pCmdDesc);
|
||||
}
|
||||
}
|
||||
|
||||
u_int32 rpc_MediaIPFW_Video_message_check_encoder(struct shared_addr *This)
|
||||
{
|
||||
u_int32 uSpace;
|
||||
u_int32 uIgnore;
|
||||
pENC_RPC_HOST_IFACE pSharedInterface = (pENC_RPC_HOST_IFACE)This->shared_mem_vir;
|
||||
BUFFER_DESCRIPTOR_TYPE *pMsgDesc = &pSharedInterface->StreamMsgBufferDesc;
|
||||
u_int32 msgword;
|
||||
u_int32 msgnum;
|
||||
|
||||
uSpace = rpc_MediaIPFW_Video_buffer_space_check_encoder(pMsgDesc, TRUE, 0, &uIgnore);
|
||||
uSpace = (uSpace >> 2);
|
||||
if (uSpace) {
|
||||
/* get current msgword word */
|
||||
msgword = *((u_int32 *)(This->msg_mem_vir+pMsgDesc->rptr - pMsgDesc->start));
|
||||
/* Find the number of additional words */
|
||||
msgnum = ((msgword & 0x00ff0000) >> 16);
|
||||
|
||||
/*
|
||||
* * Check the number of message words against
|
||||
* * 1) a limit - some sort of maximum or at least
|
||||
* * the size of the SW buffer the message is read into
|
||||
* * 2) The space reported (where space is write ptr - read ptr in 32bit words)
|
||||
* * It must be less than space (as opposed to <=) because
|
||||
* * the message itself is not included in msgword
|
||||
*/
|
||||
if (msgnum < VID_API_MESSAGE_LIMIT) {
|
||||
if (msgnum < uSpace)
|
||||
return API_MSG_AVAILABLE;
|
||||
else
|
||||
return API_MSG_INCOMPLETE;
|
||||
} else
|
||||
return API_MSG_BUFFER_ERROR;
|
||||
}
|
||||
return API_MSG_UNAVAILABLE;
|
||||
}
|
||||
|
||||
static void rpc_update_msg_buffer_ptr_encoder(BUFFER_DESCRIPTOR_TYPE *pMsgDesc)
|
||||
{
|
||||
u_int32 uReadPtr;
|
||||
|
||||
uReadPtr = pMsgDesc->rptr + 4;
|
||||
if (uReadPtr >= pMsgDesc->end)
|
||||
uReadPtr = pMsgDesc->start;
|
||||
pMsgDesc->rptr = uReadPtr;
|
||||
}
|
||||
|
||||
u32 rpc_read_msg_u32(struct shared_addr *shared_mem)
|
||||
{
|
||||
u32 msgword;
|
||||
u32 *ptr = NULL;
|
||||
pENC_RPC_HOST_IFACE iface = NULL;
|
||||
BUFFER_DESCRIPTOR_TYPE *msg_buf = NULL;
|
||||
|
||||
if (!shared_mem)
|
||||
return 0;
|
||||
|
||||
iface = shared_mem->pSharedInterface;
|
||||
msg_buf = &iface->StreamMsgBufferDesc;
|
||||
ptr = shared_mem->msg_mem_vir + msg_buf->rptr - msg_buf->start;
|
||||
rpc_update_msg_buffer_ptr_encoder(msg_buf);
|
||||
msgword = *ptr;
|
||||
|
||||
return msgword;
|
||||
}
|
||||
|
||||
int rpc_read_msg_array(struct shared_addr *shared_mem, u32 *buf, u32 number)
|
||||
{
|
||||
int i;
|
||||
u32 val;
|
||||
|
||||
if (!shared_mem)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < number; i++) {
|
||||
val = rpc_read_msg_u32(shared_mem);
|
||||
if (buf)
|
||||
buf[i] = val;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpc_get_msg_header(struct shared_addr *shared_mem, struct msg_header *msg)
|
||||
{
|
||||
u32 msgword;
|
||||
|
||||
if (!shared_mem || !msg)
|
||||
return -EINVAL;
|
||||
|
||||
msgword = rpc_read_msg_u32(shared_mem);
|
||||
msg->idx = ((msgword & 0xff000000) >> 24);
|
||||
msg->msgnum = ((msgword & 0x00ff0000) >> 16);
|
||||
msg->msgid = ((msgword & 0x00003fff) >> 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *phy_to_virt(u_int32 src, unsigned long long offset)
|
||||
{
|
||||
void *result;
|
||||
|
||||
result = (void *)(src + offset);
|
||||
return result;
|
||||
}
|
||||
|
||||
#define GET_CTRL_INTERFACE_MEMBER(shared_mem, index, name, member) \
|
||||
do {\
|
||||
pENC_RPC_HOST_IFACE iface = shared_mem->pSharedInterface; \
|
||||
pMEDIA_ENC_API_CONTROL_INTERFACE ctrl_interface =\
|
||||
phy_to_virt(iface->pEncCtrlInterface[index],\
|
||||
shared_mem->base_offset);\
|
||||
name = phy_to_virt(ctrl_interface->member,\
|
||||
shared_mem->base_offset);\
|
||||
} while (0)
|
||||
|
||||
pMEDIAIP_ENC_YUV_BUFFER_DESC rpc_get_yuv_buffer_desc(
|
||||
struct shared_addr *shared_mem, int index)
|
||||
{
|
||||
pMEDIAIP_ENC_YUV_BUFFER_DESC desc = NULL;
|
||||
|
||||
GET_CTRL_INTERFACE_MEMBER(shared_mem, index, desc, pEncYUVBufferDesc);
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
pBUFFER_DESCRIPTOR_TYPE rpc_get_stream_buffer_desc(
|
||||
struct shared_addr *shared_mem, int index)
|
||||
{
|
||||
pBUFFER_DESCRIPTOR_TYPE desc = NULL;
|
||||
|
||||
GET_CTRL_INTERFACE_MEMBER(shared_mem, index,
|
||||
desc, pEncStreamBufferDesc);
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
pMEDIAIP_ENC_EXPERT_MODE_PARAM rpc_get_expert_mode_param(
|
||||
struct shared_addr *shared_mem, int index)
|
||||
{
|
||||
pMEDIAIP_ENC_EXPERT_MODE_PARAM param = NULL;
|
||||
|
||||
GET_CTRL_INTERFACE_MEMBER(shared_mem, index,
|
||||
param, pEncExpertModeParam);
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
pMEDIAIP_ENC_PARAM rpc_get_enc_param(
|
||||
struct shared_addr *shared_mem, int index)
|
||||
{
|
||||
pMEDIAIP_ENC_PARAM param = NULL;
|
||||
|
||||
GET_CTRL_INTERFACE_MEMBER(shared_mem, index, param, pEncParam);
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
pMEDIAIP_ENC_MEM_POOL rpc_get_mem_pool(
|
||||
struct shared_addr *shared_mem, int index)
|
||||
{
|
||||
pMEDIAIP_ENC_MEM_POOL pool = NULL;
|
||||
|
||||
GET_CTRL_INTERFACE_MEMBER(shared_mem, index, pool, pEncMemPool);
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
pENC_ENCODING_STATUS rpc_get_encoding_status(
|
||||
struct shared_addr *shared_mem, int index)
|
||||
{
|
||||
pENC_ENCODING_STATUS encoding_status = NULL;
|
||||
|
||||
GET_CTRL_INTERFACE_MEMBER(shared_mem, index,
|
||||
encoding_status, pEncEncodingStatus);
|
||||
|
||||
return encoding_status;
|
||||
}
|
||||
|
||||
pENC_DSA_STATUS_t rpc_get_dsa_status(struct shared_addr *shared_mem, int index)
|
||||
{
|
||||
pENC_DSA_STATUS_t dsa_status = NULL;
|
||||
|
||||
GET_CTRL_INTERFACE_MEMBER(shared_mem, index, dsa_status, pEncDSAStatus);
|
||||
|
||||
return dsa_status;
|
||||
}
|
||||
|
||||
void rpc_set_print_buffer(struct shared_addr *shared_mem,
|
||||
unsigned long print_phy_addr, u32 size)
|
||||
{
|
||||
pENC_RPC_HOST_IFACE pSharedInterface;
|
||||
pBUFFER_DESCRIPTOR_TYPE debugBufDesc;
|
||||
|
||||
|
||||
pSharedInterface = shared_mem->pSharedInterface;
|
||||
debugBufDesc = &pSharedInterface->DebugBufferDesc;
|
||||
|
||||
debugBufDesc->start = print_phy_addr;
|
||||
debugBufDesc->end = debugBufDesc->start + size;
|
||||
debugBufDesc->wptr = debugBufDesc->rptr = debugBufDesc->start;
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __VPU_ENCODER_RPC_H__
|
||||
#define __VPU_ENCODER_RPC_H__
|
||||
|
||||
#include "mediasys_types.h"
|
||||
|
||||
#define CMD_SIZE 2560
|
||||
#define MSG_SIZE 25600
|
||||
#define CODEC_SIZE 0x1000
|
||||
#define JPEG_SIZE 0x1000
|
||||
#define SEQ_SIZE 0x1000
|
||||
#define GOP_SIZE 0x1000
|
||||
#define PIC_SIZE 0x1000
|
||||
#define QMETER_SIZE 0x1000
|
||||
#define DEBUG_SIZE 0x1000
|
||||
#define ENG_SIZE 0x1000
|
||||
#define LOCAL_MSG_NUM VID_API_MESSAGE_LIMIT
|
||||
|
||||
struct shared_addr {
|
||||
pENC_RPC_HOST_IFACE pSharedInterface;
|
||||
unsigned long long shared_mem_phy;
|
||||
void *shared_mem_vir;
|
||||
unsigned long long cmd_mem_phy;
|
||||
void *cmd_mem_vir;
|
||||
unsigned long long msg_mem_phy;
|
||||
void *msg_mem_vir;
|
||||
unsigned long long codec_mem_phy;
|
||||
void *codec_mem_vir;
|
||||
unsigned long long jpeg_mem_phy;
|
||||
void *jpeg_mem_vir;
|
||||
unsigned long long seq_mem_phy;
|
||||
void *seq_mem_vir;
|
||||
unsigned long long pic_mem_phy;
|
||||
void *pic_mem_vir;
|
||||
unsigned long long gop_mem_phy;
|
||||
void *gop_mem_vir;
|
||||
unsigned long long qmeter_mem_phy;
|
||||
void *qmeter_mem_vir;
|
||||
unsigned long long base_offset;
|
||||
};
|
||||
|
||||
struct msg_header {
|
||||
u32 idx;
|
||||
u32 msgnum;
|
||||
u32 msgid;
|
||||
};
|
||||
|
||||
void rpc_init_shared_memory_encoder(struct shared_addr *This,
|
||||
unsigned long long base_phy_addr,
|
||||
void *base_virt_addr,
|
||||
u_int32 total_size,
|
||||
u32 *actual_size);
|
||||
void rpc_set_system_cfg_value_encoder(void *Interface, u_int32 regs_base, u_int32 core_id);
|
||||
void rpc_send_cmd_buf_encoder(struct shared_addr *This,
|
||||
u_int32 idx,
|
||||
u_int32 cmdid,
|
||||
u_int32 cmdnum,
|
||||
u_int32 *local_cmddata);
|
||||
u32 rpc_read_msg_u32(struct shared_addr *shared_mem);
|
||||
int rpc_read_msg_array(struct shared_addr *shared_mem, u32 *buf, u32 number);
|
||||
int rpc_get_msg_header(struct shared_addr *shared_mem, struct msg_header *msg);
|
||||
|
||||
pMEDIAIP_ENC_YUV_BUFFER_DESC rpc_get_yuv_buffer_desc(
|
||||
struct shared_addr *shared_mem, int index);
|
||||
pBUFFER_DESCRIPTOR_TYPE rpc_get_stream_buffer_desc(
|
||||
struct shared_addr *shared_mem, int index);
|
||||
pMEDIAIP_ENC_EXPERT_MODE_PARAM rpc_get_expert_mode_param(
|
||||
struct shared_addr *shared_mem, int index);
|
||||
pMEDIAIP_ENC_PARAM rpc_get_enc_param(
|
||||
struct shared_addr *shared_mem, int index);
|
||||
pMEDIAIP_ENC_MEM_POOL rpc_get_mem_pool(
|
||||
struct shared_addr *shared_mem, int index);
|
||||
pENC_ENCODING_STATUS rpc_get_encoding_status(
|
||||
struct shared_addr *shared_mem, int index);
|
||||
pENC_DSA_STATUS_t rpc_get_dsa_status(struct shared_addr *shared_mem, int index);
|
||||
void rpc_set_print_buffer(struct shared_addr *shared_mem,
|
||||
unsigned long print_phy_addr, u32 size);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* vpu_event_msg.c
|
||||
*
|
||||
* Author Ming Qian<ming.qian@nxp.com>
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include "vpu_encoder_b0.h"
|
||||
#include "vpu_event_msg.h"
|
||||
|
||||
static atomic64_t total_ext_data = ATOMIC64_INIT(0);
|
||||
|
||||
static struct vpu_event_msg *alloc_event_msg(void)
|
||||
{
|
||||
struct vpu_event_msg *msg = NULL;
|
||||
|
||||
msg = vzalloc(sizeof(*msg));
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
static void free_event_msg(struct vpu_event_msg *msg)
|
||||
{
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
free_msg_ext_buffer(msg);
|
||||
vfree(msg);
|
||||
}
|
||||
|
||||
static void set_msg_count(struct vpu_ctx *ctx, unsigned long count)
|
||||
{
|
||||
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
|
||||
|
||||
if (attr)
|
||||
attr->msg_count = count;
|
||||
}
|
||||
|
||||
static void inc_msg_count(struct vpu_ctx *ctx)
|
||||
{
|
||||
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
|
||||
|
||||
if (attr)
|
||||
attr->msg_count++;
|
||||
}
|
||||
|
||||
static void dec_msg_count(struct vpu_ctx *ctx)
|
||||
{
|
||||
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
|
||||
|
||||
if (attr)
|
||||
attr->msg_count--;
|
||||
}
|
||||
|
||||
static bool is_msg_count_full(struct vpu_ctx *ctx)
|
||||
{
|
||||
struct vpu_attr *attr = get_vpu_ctx_attr(ctx);
|
||||
|
||||
if (!attr)
|
||||
return false;
|
||||
if (attr->msg_count > MSG_COUNT_THD)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void cleanup_ctx_msg_queue(struct vpu_ctx *ctx)
|
||||
{
|
||||
struct vpu_event_msg *msg;
|
||||
struct vpu_event_msg *tmp;
|
||||
|
||||
WARN_ON(!ctx);
|
||||
|
||||
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",
|
||||
ctx->core_dev->id, ctx->str_index, msg->msgid);
|
||||
free_event_msg(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);
|
||||
dec_msg_count(ctx);
|
||||
}
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
}
|
||||
|
||||
static int increase_idle_msg(struct vpu_ctx *ctx, u32 count)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
struct vpu_event_msg *msg = alloc_event_msg();
|
||||
|
||||
if (!msg)
|
||||
continue;
|
||||
list_add_tail(&msg->list, &ctx->idle_q);
|
||||
inc_msg_count(ctx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_ctx_msg_queue(struct vpu_ctx *ctx)
|
||||
{
|
||||
WARN_ON(!ctx);
|
||||
if (!ctx)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
|
||||
set_msg_count(ctx, 0);
|
||||
INIT_LIST_HEAD(&ctx->msg_q);
|
||||
INIT_LIST_HEAD(&ctx->idle_q);
|
||||
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct vpu_event_msg *get_idle_msg(struct vpu_ctx *ctx)
|
||||
{
|
||||
struct vpu_event_msg *msg = NULL;
|
||||
|
||||
WARN_ON(!ctx);
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
if (list_empty(&ctx->idle_q))
|
||||
increase_idle_msg(ctx, 1);
|
||||
|
||||
msg = list_first_entry(&ctx->idle_q, struct vpu_event_msg, list);
|
||||
if (msg)
|
||||
list_del_init(&msg->list);
|
||||
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
void put_idle_msg(struct vpu_ctx *ctx, struct vpu_event_msg *msg)
|
||||
{
|
||||
WARN_ON(!ctx);
|
||||
|
||||
if (!ctx || !msg)
|
||||
return;
|
||||
|
||||
free_msg_ext_buffer(msg);
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
if (is_msg_count_full(ctx)) {
|
||||
free_event_msg(msg);
|
||||
dec_msg_count(ctx);
|
||||
} else {
|
||||
list_add_tail(&msg->list, &ctx->idle_q);
|
||||
}
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
}
|
||||
|
||||
struct vpu_event_msg *pop_event_msg(struct vpu_ctx *ctx)
|
||||
{
|
||||
struct vpu_event_msg *msg = NULL;
|
||||
|
||||
WARN_ON(!ctx);
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
if (list_empty(&ctx->msg_q))
|
||||
goto exit;
|
||||
|
||||
msg = list_first_entry(&ctx->msg_q, struct vpu_event_msg, list);
|
||||
if (msg)
|
||||
list_del_init(&msg->list);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
return msg;
|
||||
}
|
||||
|
||||
void push_back_event_msg(struct vpu_ctx *ctx, struct vpu_event_msg *msg)
|
||||
{
|
||||
WARN_ON(!ctx);
|
||||
|
||||
if (!ctx || !msg)
|
||||
return;
|
||||
|
||||
mutex_lock(&ctx->instance_mutex);
|
||||
list_add_tail(&msg->list, &ctx->msg_q);
|
||||
mutex_unlock(&ctx->instance_mutex);
|
||||
}
|
||||
|
||||
int alloc_msg_ext_buffer(struct vpu_event_msg *msg, u32 number)
|
||||
{
|
||||
WARN_ON(!msg);
|
||||
|
||||
if (!msg || !number)
|
||||
return -EINVAL;
|
||||
|
||||
msg->ext_data = vzalloc(number * sizeof(u32));
|
||||
if (!msg->ext_data)
|
||||
return -ENOMEM;
|
||||
msg->number = number;
|
||||
|
||||
atomic64_add(number, &total_ext_data);
|
||||
vpu_dbg(LVL_DEBUG, "++++alloc %d msg ext data: %lld\n",
|
||||
number, get_total_ext_data_number());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void free_msg_ext_buffer(struct vpu_event_msg *msg)
|
||||
{
|
||||
WARN_ON(!msg);
|
||||
|
||||
if (!msg || !msg->ext_data)
|
||||
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",
|
||||
msg->number, get_total_ext_data_number());
|
||||
}
|
||||
|
||||
long long get_total_ext_data_number(void)
|
||||
{
|
||||
return atomic64_read(&total_ext_data);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright(c) 2018 NXP. All rights reserved.
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* vpu_event_msg.h
|
||||
*
|
||||
* Author Ming Qian<ming.qian@nxp.com>
|
||||
*/
|
||||
#ifndef _VPU_EVENT_MSG_H
|
||||
#define _VPU_EVENT_MSG_H
|
||||
|
||||
#include "vpu_encoder_config.h"
|
||||
|
||||
struct vpu_event_msg {
|
||||
struct list_head list;
|
||||
u32 idx;
|
||||
u32 msgid;
|
||||
u32 number;
|
||||
u32 data[MSG_DATA_DEFAULT_SIZE];
|
||||
u32 *ext_data;
|
||||
};
|
||||
|
||||
int init_ctx_msg_queue(struct vpu_ctx *ctx);
|
||||
void cleanup_ctx_msg_queue(struct vpu_ctx *ctx);
|
||||
struct vpu_event_msg *get_idle_msg(struct vpu_ctx *ctx);
|
||||
void put_idle_msg(struct vpu_ctx *ctx, struct vpu_event_msg *msg);
|
||||
struct vpu_event_msg *pop_event_msg(struct vpu_ctx *ctx);
|
||||
void push_back_event_msg(struct vpu_ctx *ctx, struct vpu_event_msg *msg);
|
||||
int alloc_msg_ext_buffer(struct vpu_event_msg *msg, u32 number);
|
||||
void free_msg_ext_buffer(struct vpu_event_msg *msg);
|
||||
long long get_total_ext_data_number(void);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue