feat[jpeg]: Add VPU720 JPEG support

Change-Id: Ic614a59b292ab9a511f56e46ebbe516e484bd0f2
Signed-off-by: Johnson Ding <johnson.ding@rock-chips.com>
This commit is contained in:
Johnson Ding
2023-07-12 14:00:17 +08:00
parent 0954d08770
commit 6627f4667b
10 changed files with 1320 additions and 19 deletions

View File

@@ -527,6 +527,7 @@ static MPP_RET init_jpeg_component_info(JpegeSyntax *syntax)
syntax->mcu_height = comp_info[0].v_sample_factor * DCT_SIZE;
syntax->mcu_hor_cnt = (syntax->width + syntax->mcu_width - 1) / syntax->mcu_width;
syntax->mcu_ver_cnt = (syntax->height + syntax->mcu_height - 1) / syntax->mcu_height;
syntax->mcu_cnt = syntax->mcu_hor_cnt * syntax->mcu_ver_cnt;
return ret;
}
@@ -567,21 +568,20 @@ static MPP_RET jpege_proc_hal(void *ctx, HalEncTask *task)
init_jpeg_component_info(syntax);
if (split->split_mode) {
RK_U32 mb_h = MPP_ALIGN(prep->height, 16) / 16;
RK_U32 mb_w = syntax->mcu_hor_cnt;
RK_U32 mb_h = syntax->mcu_ver_cnt;
RK_U32 part_rows = 0;
if (split->split_mode == MPP_ENC_SPLIT_BY_CTU) {
RK_U32 part_mbs = split->split_arg;
RK_U32 mb_w = MPP_ALIGN(prep->width, 16) / 16;
RK_U32 mb_all = mb_w * mb_h;
if (part_mbs > 0 && part_mbs <= mb_all) {
if (part_mbs > 0 && part_mbs <= syntax->mcu_cnt) {
part_rows = (part_mbs + mb_w - 1) / mb_w;
if (part_rows >= mb_h)
part_rows = 0;
} else {
mpp_err_f("warning: invalid split arg %d > max %d\n",
part_mbs, mb_all);
part_mbs, syntax->mcu_cnt);
}
} else {
mpp_err_f("warning: only mcu split is supported\n");
@@ -589,7 +589,10 @@ static MPP_RET jpege_proc_hal(void *ctx, HalEncTask *task)
if (part_rows) {
syntax->part_rows = part_rows;
syntax->restart_ri = syntax->mcu_hor_cnt * part_rows;
if (mpp_get_soc_type() == ROCKCHIP_SOC_RK3576 && split->split_arg <= syntax->mcu_cnt)
syntax->restart_ri = split->split_arg;
else
syntax->restart_ri = syntax->mcu_hor_cnt * part_rows;
syntax->low_delay = cfg->base.low_delay && part_rows;
jpege_dbg_func("Split by CTU, part_rows %d, restart_ri %d",
syntax->part_rows, syntax->restart_ri);

View File

@@ -45,6 +45,7 @@ typedef struct JpegeSyntax_t {
RK_U32 ver_stride;
RK_U32 mcu_hor_cnt;
RK_U32 mcu_ver_cnt;
RK_U32 mcu_cnt;
RK_U32 mcu_width;
RK_U32 mcu_height;
MppFrameFormat format;
@@ -80,7 +81,6 @@ typedef struct JpegeSyntax_t {
/* For slice encoding mode */
RK_U32 slice_enable;
RK_U32 slice_size_mb_rows;
RK_U32 restart_interval;
/*
* For unit type and density

View File

@@ -31,6 +31,7 @@
#include "hal_jpege_vepu1_v2.h"
#include "hal_jpege_vepu2_v2.h"
#include "hal_jpege_vepu540c.h"
#include "hal_jpege_vpu720.h"
typedef struct HaljpegeCtx_t {
const MppEncHalApi *api;
@@ -56,6 +57,8 @@ static MPP_RET hal_jpege_init(void *hal, MppEncHalCfg *cfg)
api = &hal_jpege_vepu2;
} else if (vcodec_type & HAVE_VEPU1) {
api = &hal_jpege_vepu1;
} else if (vcodec_type & HAVE_JPEG_ENC) {
api = &hal_jpege_vpu720;
} else {
mpp_err("vcodec type %08x can not find JPEG encoder device\n",
vcodec_type);

View File

@@ -6,11 +6,14 @@ include_directories(../common/)
# hal jpeg header
set(HAL_JPEGE_HDR
hal_jpege_vepu540c_reg.h
hal_jpege_vpu720_reg.h
hal_jpege_vpu720.h
)
# hal jpeg encoder sourse
set(HAL_JPEGE_SRC
hal_jpege_vepu540c.c
hal_jpege_vpu720.c
)
add_library(hal_jpege_rkv STATIC

View File

@@ -0,0 +1,662 @@
/* SPDX-License-Identifier: Apache-2.0 */
/*
* Copyright (c) 2024 Rockchip Electronics Co., Ltd.
*/
#define MODULE_TAG "hal_jpege_vpu720"
#include <string.h>
#include "mpp_mem.h"
#include "mpp_env.h"
#include "mpp_common.h"
#include "mpp_enc_hal.h"
#include "jpege_syntax.h"
#include "hal_jpege_hdr.h"
#include "hal_jpege_debug.h"
#include "hal_jpege_vpu720.h"
#include "hal_jpege_vpu720_reg.h"
typedef enum JpegeVpu720InFmt_e {
JPEGE_VPU720_IN_FMT_TILE_400,
JPEGE_VPU720_IN_FMT_TILE_420,
JPEGE_VPU720_IN_FMT_TILE_422,
JPEGE_VPU720_IN_FMT_TILE_444,
JPEGE_VPU720_IN_FMT_YUV422SP,
JPEGE_VPU720_IN_FMT_YUV422P,
JPEGE_VPU720_IN_FMT_YUV420SP,
JPEGE_VPU720_IN_FMT_YUV420P,
JPEGE_VPU720_IN_FMT_YUYV,
JPEGE_VPU720_IN_FMT_UYVY,
JPEGE_VPU720_IN_FMT_YUV400,
JPEGE_VPU720_IN_FMT_RESERVED,
JPEGE_VPU720_IN_FMT_YUV444SP,
JPEGE_VPU720_IN_FMT_YUV444P,
} JpegeVpu720InFmt;
typedef enum JpegeVpu720OutFmt_e {
JPEGE_VPU720_OUT_FMT_400 = 0,
JPEGE_VPU720_OUT_FMT_420 = 1,
JPEGE_VPU720_OUT_FMT_422 = 2,
JPEGE_VPU720_OUT_FMT_444 = 3,
} JpegeVpu720OutFmt;
typedef enum JpegeVpu720EncCmd_e {
JPEG_VPU720_ENC_MODE_NONE,
JPEG_VPU720_ENC_MODE_ONE_FRAME,
JPEG_VPU720_ENC_MODE_MULTI_FRAME_START,
JPEG_VPU720_ENC_MODE_MULTI_FRAME_UPDATE,
JPEG_VPU720_ENC_MODE_LKT_FORCE_PAUSE,
JPEG_VPU720_ENC_MODE_LKT_CONTINUE,
JPEG_VPU720_ENC_MODE_SAFE_CLR,
JPEG_VPU720_ENC_MODE_FORCE_CLR,
JPEG_VPU720_ENC_MODE_FORCE_BUTT,
} JpegeVpu720EncCmd;
typedef enum JPEGVpu720ColorRangeTrans_t {
JPEG_VPU720_COLOR_RANGE_FULL_TO_LIMIT,
JPEG_VPU720_COLOR_RANGE_LIMIT_TO_FULL,
} JPEGVpu720ColorRangeTrans;
typedef enum JPEGVpu720ChromaDownSampleMode_t {
JPEG_VPU720_CHROMA_DOWN_SAMPLE_MODE_Average,
JPEG_VPU720_CHROMA_DOWN_SAMPLE_MODE_Discard,
} JPEGVpu720ChromaDownSampleMode;
typedef struct JpegeVpu720FmtCfg_t {
JpegeVpu720InFmt input_format;
JpegeVpu720OutFmt out_format;
MppFrameColorRange src_range;
MppFrameColorRange dst_range;
JPEGVpu720ChromaDownSampleMode chroma_ds_mode;
RK_U32 uv_swap;
RK_U32 mirror;
RK_U32 fix_chroma_en;
RK_U32 fix_chroma_u;
RK_U32 fix_chroma_v;
RK_U32 out_nb_comp;
RK_U32 y_stride;
RK_U32 uv_stride;
RK_U32 u_offset;
RK_U32 v_offset;
} JpegeVpu720FmtCfg;
typedef struct JpegeVpu720HalCtx_t {
MppEncHalApi api;
MppDev dev;
void *regs;
/* @frame_cnt starts from ZERO */
RK_U32 frame_cnt;
MppEncCfgSet *cfg;
RK_U32 enc_mode;
RK_U32 frame_size;
RK_S32 max_buf_cnt;
RK_S32 hdr_status;
JpegeVpu720FmtCfg fmt_cfg;
RK_U8 *src_buf;
RK_U8 *dst_buf;
RK_S32 buf_size;
RK_U32 frame_num;
JpegeBits bits;
JpegeSyntax syntax;
RK_S32 hal_start_pos;
MppBufferGroup group;
MppBuffer qtbl_buffer;
RK_U16 *qtbl_sw_buf;
} JpegeVpu720HalCtx;
#define JPEGE_VPU720_QTABLE_SIZE (64 * 3)
static MPP_RET hal_jpege_vpu720_init(void *hal, MppEncHalCfg *cfg)
{
MPP_RET ret = MPP_OK;
JpegeVpu720HalCtx *ctx = (JpegeVpu720HalCtx *)hal;
mpp_env_get_u32("hal_jpege_debug", &hal_jpege_debug, 0);
hal_jpege_enter();
ctx->regs = mpp_calloc(JpegeVpu720Reg, 1);
ctx->cfg = cfg->cfg;
ctx->frame_cnt = 0;
ctx->enc_mode = JPEG_VPU720_ENC_MODE_ONE_FRAME;
cfg->type = VPU_CLIENT_JPEG_ENC;
ret = mpp_dev_init(&cfg->dev, cfg->type);
if (ret) {
mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
return ret;
}
ctx->dev = cfg->dev;
jpege_bits_init(&ctx->bits);
mpp_assert(ctx->bits);
if (ctx->group == NULL) {
ret = mpp_buffer_group_get_internal(&ctx->group, MPP_BUFFER_TYPE_ION);
if (ret) {
mpp_err_f("mpp_buffer_group_get failed ret %d\n", ret);
return ret;
}
}
ret = mpp_buffer_get(ctx->group, &ctx->qtbl_buffer, JPEGE_VPU720_QTABLE_SIZE * sizeof(RK_U16));
ctx->qtbl_sw_buf = (RK_U16 *)mpp_calloc(RK_U16, JPEGE_VPU720_QTABLE_SIZE);
hal_jpege_leave();
return ret;
}
static MPP_RET hal_jpege_vpu720_deinit(void *hal)
{
MPP_RET ret = MPP_OK;
JpegeVpu720HalCtx *ctx = (JpegeVpu720HalCtx *)hal;
hal_jpege_enter();
jpege_bits_deinit(ctx->bits);
MPP_FREE(ctx->regs);
MPP_FREE(ctx->qtbl_sw_buf);
if (ctx->dev) {
mpp_dev_deinit(ctx->dev);
ctx->dev = NULL;
}
if (ctx->qtbl_buffer) {
ret = mpp_buffer_put(ctx->qtbl_buffer);
if (ret) {
mpp_err_f("put qtbl buffer failed\n");
}
}
if (ctx->group) {
ret = mpp_buffer_group_put(ctx->group);
if (ret) {
mpp_err_f("group free buffer failed\n");
}
}
hal_jpege_leave();
return MPP_OK;
}
static MPP_RET jpege_vpu720_setup_format(void *hal, HalEncTask *task)
{
JpegeVpu720HalCtx *ctx = (JpegeVpu720HalCtx *) hal;
MppFrameFormat in_fmt = ctx->cfg->prep.format & MPP_FRAME_FMT_MASK;
JpegeVpu720FmtCfg *fmt_cfg = &ctx->fmt_cfg;
JpegeSyntax *syntax = &ctx->syntax;
MppFrameChromaFormat out_fmt = syntax->format_out;
RK_U32 hor_stride = mpp_frame_get_hor_stride(task->frame);
RK_U32 ver_stride = mpp_frame_get_ver_stride(task->frame);
hal_jpege_enter();
memset(fmt_cfg, 0, sizeof(JpegeVpu720FmtCfg));
if (MPP_FRAME_FMT_IS_TILE(ctx->cfg->prep.format)) {
switch (in_fmt) {
case MPP_FMT_YUV400:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_TILE_400;
fmt_cfg->y_stride = hor_stride * 4;
fmt_cfg->out_format = JPEGE_VPU720_OUT_FMT_400;
break;
case MPP_FMT_YUV420P:
case MPP_FMT_YUV420SP:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_TILE_420;
fmt_cfg->y_stride = hor_stride * 4 * 3 / 2;
break;
case MPP_FMT_YUV422P:
case MPP_FMT_YUV422SP:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_TILE_422;
fmt_cfg->y_stride = hor_stride * 4 * 2;
break;
case MPP_FMT_YUV444P:
case MPP_FMT_YUV444SP:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_TILE_444;
fmt_cfg->y_stride = hor_stride * 4 * 3;
break;
default:
mpp_err("Unsupported input format 0x%08x, with TILE mask.\n", in_fmt);
return MPP_ERR_VALUE;
break;
}
} else {
switch (in_fmt) {
case MPP_FMT_YUV400:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV400;
fmt_cfg->y_stride = hor_stride;
fmt_cfg->out_format = JPEGE_VPU720_OUT_FMT_400;
break;
case MPP_FMT_YUV420P:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV420P;
fmt_cfg->y_stride = hor_stride;
fmt_cfg->uv_stride = hor_stride >> 1;
fmt_cfg->u_offset = hor_stride * ver_stride;
fmt_cfg->v_offset = fmt_cfg->u_offset + fmt_cfg->uv_stride * (ver_stride >> 1);
break;
case MPP_FMT_YUV420SP:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV420SP;
fmt_cfg->y_stride = hor_stride;
fmt_cfg->uv_stride = hor_stride;
fmt_cfg->u_offset = hor_stride * ver_stride;
break;
case MPP_FMT_YUV420SP_VU:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV420SP;
fmt_cfg->y_stride = hor_stride;
fmt_cfg->uv_stride = hor_stride;
fmt_cfg->u_offset = hor_stride * ver_stride;
fmt_cfg->uv_swap = 1;
break;
case MPP_FMT_YUV422P:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV422P;
fmt_cfg->y_stride = hor_stride;
fmt_cfg->uv_stride = hor_stride >> 1;
fmt_cfg->u_offset = hor_stride * ver_stride;
fmt_cfg->v_offset = fmt_cfg->u_offset + fmt_cfg->uv_stride * ver_stride;
break;
case MPP_FMT_YUV422SP:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV422SP;
fmt_cfg->y_stride = hor_stride;
fmt_cfg->uv_stride = hor_stride;
fmt_cfg->u_offset = hor_stride * ver_stride;
break;
case MPP_FMT_YUV422SP_VU:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV422SP;
fmt_cfg->y_stride = hor_stride;
fmt_cfg->uv_stride = hor_stride;
fmt_cfg->u_offset = hor_stride * ver_stride;
fmt_cfg->uv_swap = 1;
break;
case MPP_FMT_YUV422_YUYV:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUYV;
fmt_cfg->y_stride = hor_stride;
break;
case MPP_FMT_YUV422_UYVY:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_UYVY;
fmt_cfg->y_stride = hor_stride;
break;
case MPP_FMT_YUV422_YVYU:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUYV;
fmt_cfg->y_stride = hor_stride;
fmt_cfg->uv_swap = 1;
break;
case MPP_FMT_YUV422_VYUY:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_UYVY;
fmt_cfg->y_stride = hor_stride;
fmt_cfg->uv_swap = 1;
break;
case MPP_FMT_YUV444SP:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV444SP;
fmt_cfg->y_stride = hor_stride;
fmt_cfg->uv_stride = hor_stride << 1;
fmt_cfg->u_offset = hor_stride * ver_stride;
break;
case MPP_FMT_YUV444P:
fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV444P;
fmt_cfg->y_stride = hor_stride;
fmt_cfg->uv_stride = hor_stride;
fmt_cfg->u_offset = hor_stride * ver_stride;
fmt_cfg->v_offset = fmt_cfg->u_offset << 1;
break;
default :
mpp_err("Unsupported input format 0x%08x\n", in_fmt);
return MPP_ERR_VALUE;
break;
}
}
switch (out_fmt) {
case MPP_CHROMA_400:
ctx->fmt_cfg.out_format = JPEGE_VPU720_OUT_FMT_400;
break;
case MPP_CHROMA_420:
ctx->fmt_cfg.out_format = JPEGE_VPU720_OUT_FMT_420;
break;
case MPP_CHROMA_422:
ctx->fmt_cfg.out_format = JPEGE_VPU720_OUT_FMT_422;
break;
case MPP_CHROMA_444:
ctx->fmt_cfg.out_format = JPEGE_VPU720_OUT_FMT_444;
break;
default:
ctx->fmt_cfg.out_format = JPEGE_VPU720_OUT_FMT_420;
break;
}
ctx->fmt_cfg.out_nb_comp = ctx->syntax.nb_components;
switch (ctx->cfg->prep.chroma_ds_mode) {
case MPP_FRAME_CHORMA_DOWN_SAMPLE_MODE_AVERAGE:
ctx->fmt_cfg.chroma_ds_mode = JPEG_VPU720_CHROMA_DOWN_SAMPLE_MODE_Average;
break;
case MPP_FRAME_CHORMA_DOWN_SAMPLE_MODE_DISCARD:
ctx->fmt_cfg.chroma_ds_mode = JPEG_VPU720_CHROMA_DOWN_SAMPLE_MODE_Discard;
break;
default:
ctx->fmt_cfg.chroma_ds_mode = JPEG_VPU720_CHROMA_DOWN_SAMPLE_MODE_Average;
break;
}
hal_jpege_dbg_detail("JPEG format: in 0x%x out 0x%x, hw in_fmt %d, out_fmt %d, ds_mode %d\n",
ctx->cfg->prep.format, ctx->cfg->prep.format_out,
ctx->fmt_cfg.input_format, ctx->fmt_cfg.out_format,
ctx->fmt_cfg.chroma_ds_mode);
if (ctx->cfg->prep.mirroring)
ctx->fmt_cfg.mirror = 1;
if (ctx->cfg->prep.fix_chroma_en) {
ctx->fmt_cfg.fix_chroma_en = 1;
ctx->fmt_cfg.fix_chroma_u = ctx->cfg->prep.fix_chroma_u & 0xff;
ctx->fmt_cfg.fix_chroma_v = ctx->cfg->prep.fix_chroma_v & 0xff;
}
ctx->fmt_cfg.src_range = (ctx->cfg->prep.range == MPP_FRAME_RANGE_UNSPECIFIED) ?
MPP_FRAME_RANGE_JPEG : ctx->cfg->prep.range;
ctx->fmt_cfg.dst_range = (ctx->cfg->prep.range_out == MPP_FRAME_RANGE_UNSPECIFIED) ?
MPP_FRAME_RANGE_JPEG : ctx->cfg->prep.range_out;
hal_jpege_leave();
return MPP_OK;
}
MPP_RET hal_jpege_vpu720_gen_regs(void *hal, HalEncTask *task)
{
MPP_RET ret = MPP_OK;
JpegeVpu720HalCtx *ctx = (JpegeVpu720HalCtx *) hal;
JpegeVpu720Reg *regs = ctx->regs;
JpegeVpu720BaseReg *reg_base = &regs->reg_base;
JpegeBits bits = ctx->bits;
const RK_U8 *qtable[2] = {NULL};
size_t length = mpp_packet_get_length(task->packet);
RK_U8 *buf = mpp_buffer_get_ptr(task->output);
size_t size = mpp_buffer_get_size(task->output);
JpegeSyntax *syntax = &ctx->syntax;
RK_U8 *qtbl_base = (RK_U8 *)mpp_buffer_get_ptr(ctx->qtbl_buffer);
RK_S32 bitpos;
RK_U32 i, j;
hal_jpege_enter();
jpege_vpu720_setup_format(hal, task);
memset(regs, 0, sizeof(JpegeVpu720Reg));
mpp_buffer_sync_begin(task->output);
jpege_bits_setup(bits, buf, (RK_U32)size);
jpege_seek_bits(bits, length << 3);
write_jpeg_header(bits, syntax, qtable);
mpp_buffer_sync_end(task->output);
bitpos = jpege_bits_get_bitpos(bits);
task->length = (bitpos + 7) >> 3;
mpp_packet_set_length(task->packet, task->length);
reg_base->reg001_enc_strt.lkt_num = 0;
reg_base->reg001_enc_strt.vepu_cmd = ctx->enc_mode;
// interupt
reg_base->reg004_int_en.fenc_done_en = 1;
reg_base->reg004_int_en.lkt_node_done_en = 1;
reg_base->reg004_int_en.sclr_done_en = 1;
reg_base->reg004_int_en.vslc_done_en = 1;
reg_base->reg004_int_en.vbsb_oflw_en = 1;
reg_base->reg004_int_en.vbsb_sct_en = 1;
reg_base->reg004_int_en.fenc_err_en = 1;
reg_base->reg004_int_en.wdg_en = 1;
reg_base->reg004_int_en.lkt_oerr_en = 1;
reg_base->reg004_int_en.lkt_estp_en = 1;
reg_base->reg004_int_en.lkt_fstp_en = 1;
reg_base->reg004_int_en.lkt_note_stp_en = 1;
reg_base->reg004_int_en.lkt_data_error_en = 1;
reg_base->reg005_int_msk.fenc_done_msk = 1;
reg_base->reg005_int_msk.lkt_node_done_msk = 1;
reg_base->reg005_int_msk.sclr_done_msk = 1;
reg_base->reg005_int_msk.vslc_done_msk = 1;
reg_base->reg005_int_msk.vbsb_oflw_msk = 1;
reg_base->reg005_int_msk.vbsb_sct_msk = 1;
reg_base->reg005_int_msk.fenc_err_msk = 1;
reg_base->reg005_int_msk.wdg_msk = 1;
reg_base->reg005_int_msk.lkt_oerr_msk = 1;
reg_base->reg005_int_msk.lkt_estp_msk = 1;
reg_base->reg005_int_msk.lkt_fstp_msk = 1;
reg_base->reg005_int_msk.lkt_note_stp_msk = 1;
reg_base->reg005_int_msk.lkt_data_error_msk = 1;
reg_base->reg008_cru_ctrl.resetn_hw_en = 1;
reg_base->reg008_cru_ctrl.sram_ckg_en = 1;
reg_base->reg008_cru_ctrl.cke = 1;
reg_base->reg042_dbus_endn.jbsw_bus_edin = 0xf;
reg_base->reg042_dbus_endn.vsl_bus_edin = 0;
reg_base->reg042_dbus_endn.ecs_len_edin = 0xf;
reg_base->reg042_dbus_endn.sw_qtbl_edin = 0;
reg_base->reg011_wdg_jpeg = syntax->mcu_cnt * 1000;
reg_base->reg026_axi_perf_ctrl0.perf_work_e = 1;
reg_base->reg026_axi_perf_ctrl0.perf_clr_e = 1;
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
ctx->qtbl_sw_buf[i * 8 + j] = 0x8000 / qtable[0][j * 8 + i];
ctx->qtbl_sw_buf[64 + i * 8 + j] = 0x8000 / qtable[1][j * 8 + i];
}
}
memcpy(&ctx->qtbl_sw_buf[64 * 2], &ctx->qtbl_sw_buf[64], sizeof(RK_U16) * 64);
reg_base->reg029_sw_enc_rsl.pic_wd8_m1 = MPP_ALIGN(syntax->width, 8) / 8 - 1;
reg_base->reg029_sw_enc_rsl.pic_hd8_m1 = MPP_ALIGN(syntax->height, 8) / 8 - 1;
reg_base->reg030_sw_src_fill.pic_wfill_jpeg = (syntax->width & 0x7) ? (8 - (syntax->width & 7)) : 0;
reg_base->reg030_sw_src_fill.pic_hfill_jpeg = (syntax->height & 0x7) ? (8 - (syntax->height & 7)) : 0;
reg_base->reg032_sw_src_fmt.src_fmt = ctx->fmt_cfg.input_format;
reg_base->reg032_sw_src_fmt.out_fmt = ctx->fmt_cfg.out_format;
reg_base->reg032_sw_src_fmt.rbuv_swap_jpeg = ctx->fmt_cfg.uv_swap;
reg_base->reg032_sw_src_fmt.chroma_ds_mode = ctx->fmt_cfg.chroma_ds_mode;
reg_base->reg032_sw_src_fmt.src_mirr_jpeg = ctx->fmt_cfg.mirror;
reg_base->reg032_sw_src_fmt.chroma_force_en = ctx->fmt_cfg.fix_chroma_en;
reg_base->reg032_sw_src_fmt.u_force_value = ctx->fmt_cfg.fix_chroma_u;
reg_base->reg032_sw_src_fmt.v_force_value = ctx->fmt_cfg.fix_chroma_v;
if (ctx->fmt_cfg.src_range != ctx->fmt_cfg.dst_range) {
reg_base->reg032_sw_src_fmt.src_range_trns_en = 1;
if (ctx->fmt_cfg.src_range == MPP_FRAME_RANGE_MPEG)
reg_base->reg032_sw_src_fmt.src_range_trns_sel = JPEG_VPU720_COLOR_RANGE_LIMIT_TO_FULL;
else
reg_base->reg032_sw_src_fmt.src_range_trns_sel = JPEG_VPU720_COLOR_RANGE_FULL_TO_LIMIT;
}
reg_base->reg033_sw_pic_ofst.pic_ofst_x = mpp_frame_get_offset_x(task->frame);
reg_base->reg033_sw_pic_ofst.pic_ofst_y = mpp_frame_get_offset_y(task->frame);
reg_base->reg034_sw_src_strd_0.src_strd_0 = ctx->fmt_cfg.y_stride;
reg_base->reg035_sw_src_strd_1.src_strd_1 = ctx->fmt_cfg.uv_stride;
reg_base->reg036_sw_jpeg_enc_cfg.rst_intv = syntax->restart_ri;
reg_base->reg036_sw_jpeg_enc_cfg.rst_m = 0;
reg_base->reg036_sw_jpeg_enc_cfg.pic_last_ecs = 1;
reg_base->reg022_adr_src0 = mpp_buffer_get_fd(task->input);
reg_base->reg023_adr_src1 = reg_base->reg022_adr_src0;
reg_base->reg024_adr_src2 = reg_base->reg022_adr_src0;
reg_base->reg017_adr_bsbt = mpp_buffer_get_fd(task->output);
reg_base->reg018_adr_bsbb = reg_base->reg017_adr_bsbt;
reg_base->reg019_adr_bsbr = reg_base->reg017_adr_bsbt;
reg_base->reg020_adr_bsbs = reg_base->reg017_adr_bsbt;
reg_base->reg016_adr_qtbl = mpp_buffer_get_fd(ctx->qtbl_buffer);
memcpy(qtbl_base, ctx->qtbl_sw_buf, JPEGE_VPU720_QTABLE_SIZE * sizeof(RK_U16));
mpp_buffer_sync_end(ctx->qtbl_buffer);
MppDevRegOffsetCfg trans_cfg_offset;
MppDevRegOffsetCfg trans_cfg_size;
MppDevRegOffsetCfg trans_cfg_chroma;
trans_cfg_offset.reg_idx = 20;
trans_cfg_offset.offset = mpp_packet_get_length(task->packet);
mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_OFFSET, &trans_cfg_offset);
trans_cfg_size.reg_idx = 17;
trans_cfg_size.offset = mpp_buffer_get_size(task->output);
mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_OFFSET, & trans_cfg_size);
trans_cfg_chroma.reg_idx = 23;
trans_cfg_chroma.offset = ctx->fmt_cfg.u_offset;
mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_OFFSET, &trans_cfg_chroma);
trans_cfg_chroma.reg_idx = 24;
trans_cfg_chroma.offset = ctx->fmt_cfg.v_offset;
mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_OFFSET, &trans_cfg_chroma);
ctx->frame_num++;
hal_jpege_leave();
return ret;
}
MPP_RET hal_jpege_vpu720_start(void *hal, HalEncTask *task)
{
MPP_RET ret = MPP_OK;
JpegeVpu720HalCtx *ctx = (JpegeVpu720HalCtx *) hal;
JpegeVpu720Reg *regs = ctx->regs;
MppDevRegWrCfg cfg_base;
MppDevRegRdCfg cfg_st;
hal_jpege_enter();
if (task->flags.err) {
mpp_err_f("task->flags.err 0x%08x, return early\n", task->flags.err);
return MPP_NOK;
}
if (hal_jpege_debug & HAL_JPEGE_DBG_DETAIL) {
RK_U32 i = 0;
RK_U32 *reg = (RK_U32 *)regs;
for (i = 0; i < 43; i++) {
mpp_log_f("set reg[%03d] : %04x : 0x%08x\n", i, i * 4, reg[i]);
}
}
cfg_base.reg = &regs->reg_base;
cfg_base.size = sizeof(JpegeVpu720BaseReg);
cfg_base.offset = 0;
ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &cfg_base);
if (ret) {
mpp_err_f("set register write failed %d\n", ret);
return ret;
}
cfg_st.reg = &regs->int_state;
cfg_st.size = sizeof(RK_U32);
cfg_st.offset = JPEGE_VPU720_REG_BASE_INT_STATE;
ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &cfg_st);
if (ret) {
mpp_err_f("set register to read int state failed %d\n", ret);
}
cfg_st.reg = &regs->reg_st;
cfg_st.size = sizeof(JpegeVpu720StatusReg);
cfg_st.offset = JPEGE_VPU720_REG_STATUS_OFFSET;
ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &cfg_st);
if (ret) {
mpp_err_f("set register to read hw status failed %d\n", ret);
}
ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
if (ret) {
mpp_err_f("send cmd failed %d\n", ret);
}
hal_jpege_leave();
return MPP_OK;
}
MPP_RET hal_jpege_vpu720_wait(void *hal, HalEncTask *task)
{
MPP_RET ret = MPP_OK;
JpegeVpu720HalCtx *ctx = (JpegeVpu720HalCtx *) hal;
JpegeVpu720Reg *regs = (JpegeVpu720Reg *)ctx->regs;
JpegeVpu720StatusReg *reg_st = &regs->reg_st;
RK_U32 int_state = regs->int_state;
hal_jpege_enter();
if (task->flags.err) {
mpp_err_f("task->flags.err 0x%08x, return earyl\n", task->flags.err);
return ret = MPP_NOK;
}
ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
if (ret) {
mpp_err_f("poll cmd failed %d\n", ret);
return ret = MPP_ERR_VPUHW;
} else {
if (int_state & 0x170)
mpp_err_f("JPEG encoder hw error 0x%08x\n", int_state);
else
hal_jpege_dbg_simple("JPEG encoder int state 0x%08x\n", int_state);
hal_jpege_dbg_detail("hw length %d, cycle %d\n",
reg_st->st_bsl_l32_jpeg_head_bits,
reg_st->st_perf_working_cnt);
task->hw_length += reg_st->st_bsl_l32_jpeg_head_bits;
}
hal_jpege_leave();
return MPP_OK;
}
MPP_RET hal_jpege_vpu720_get_task(void *hal, HalEncTask *task)
{
JpegeVpu720HalCtx *ctx = (JpegeVpu720HalCtx *) hal;
JpegeSyntax *syntax = (JpegeSyntax *) task->syntax.data;
hal_jpege_enter();
memcpy(&ctx->syntax, syntax, sizeof(ctx->syntax));
// TODO config rc
hal_jpege_leave();
return MPP_OK;
}
MPP_RET hal_jpege_vpu720_ret_task(void *hal, HalEncTask *task)
{
(void)hal;
EncRcTaskInfo * rc_info = &task->rc_task->info;
hal_jpege_enter();
task->length += task->hw_length;
// setup bit length for rate control
rc_info->bit_real = task->hw_length * 8;
rc_info->quality_real = rc_info->quality_target;
hal_jpege_leave();
return MPP_OK;
}
const MppEncHalApi hal_jpege_vpu720 = {
.name = "hal_jpege_vpu720",
.coding = MPP_VIDEO_CodingMJPEG,
.ctx_size = sizeof(JpegeVpu720HalCtx),
.flag = 0,
.init = hal_jpege_vpu720_init,
.deinit = hal_jpege_vpu720_deinit,
.prepare = NULL,
.get_task = hal_jpege_vpu720_get_task,
.gen_regs = hal_jpege_vpu720_gen_regs,
.start = hal_jpege_vpu720_start,
.wait = hal_jpege_vpu720_wait,
.part_start = NULL,
.part_wait = NULL,
.ret_task = hal_jpege_vpu720_ret_task,
};

View File

@@ -0,0 +1,13 @@
/* SPDX-License-Identifier: Apache-2.0 */
/*
* Copyright (c) 2024 Rockchip Electronics Co., Ltd.
*/
#ifndef __HAL_JPEGE_VPU720_H__
#define __HAL_JPEGE_VPU720_H__
#include "mpp_enc_hal.h"
extern const MppEncHalApi hal_jpege_vpu720;
#endif /* __HAL_JPEGE_VPU720_H__ */

View File

@@ -0,0 +1,555 @@
/* SPDX-License-Identifier: Apache-2.0 */
/*
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
*/
#ifndef __HAL_JPEGE_VPU720_REG_H__
#define __HAL_JPEGE_VPU720_REG_H__
#include "rk_type.h"
typedef struct JpegeVpu720BaseReg_t {
// 0x0000, IP version
RK_U32 reg000_version;
// 0x0004, Start Command
struct {
// Number of new nodes added to link table
RK_U32 lkt_num : 8;
/**
* @brief VEPU command
* 0 -- N/A
* 1 -- One-frame encoding by register configuration
* 2 -- Multi-frame encoding start with link table mode
* 3 -- Multi-frame encoding update (with link table mode)
* 4 -- link table encoding force pause
* 5 -- continue link table encoder when link table stop
* 6 -- safe_clr
* 7 -- force_clr
*/
RK_U32 vepu_cmd : 4;
RK_U32 : 20;
} reg001_enc_strt;
/*reserved 0x8 ~ 0xC*/
RK_U32 reg002_003[2];
// 0x0010, Interrupt Enable
struct {
// One frame encoding finish interrupt enable
RK_U32 fenc_done_en : 1;
// Link table one node finish interrupt enable
RK_U32 lkt_node_done_en : 1;
// Safe clear finish interrupt enable
RK_U32 sclr_done_en : 1;
// One slice of video encoding finish interrupt enable
RK_U32 vslc_done_en : 1;
// Video bit stream buffer overflow interrupt enable
RK_U32 vbsb_oflw_en : 1;
// Video bit stream buffer write section interrupt enable
RK_U32 vbsb_sct_en : 1;
// Frame encoding error interrupt enable
RK_U32 fenc_err_en : 1;
// Watch dog (timeout) interrupt enable
RK_U32 wdg_en : 1;
// Link table operation error interrupt enable
RK_U32 lkt_oerr_en : 1;
// Link table encoding error stop interrupt enable
RK_U32 lkt_estp_en : 1;
// Link cmd force pause interrupt enable
RK_U32 lkt_fstp_en : 1;
// Link table note stop interrupt enable
RK_U32 lkt_note_stp_en : 1;
RK_U32 lkt_data_error_en : 1;
RK_U32 : 19;
} reg004_int_en;
// 0x0014, Interrupt Mask
struct {
RK_U32 fenc_done_msk : 1;
RK_U32 lkt_node_done_msk : 1;
RK_U32 sclr_done_msk : 1;
RK_U32 vslc_done_msk : 1;
RK_U32 vbsb_oflw_msk : 1;
RK_U32 vbsb_sct_msk : 1;
RK_U32 fenc_err_msk : 1;
RK_U32 wdg_msk : 1;
RK_U32 lkt_oerr_msk : 1;
RK_U32 lkt_estp_msk : 1;
RK_U32 lkt_fstp_msk : 1;
RK_U32 lkt_note_stp_msk : 1;
RK_U32 lkt_data_error_msk : 1;
RK_U32 : 19;
} reg005_int_msk;
// 0x0018, Interrupt Clear
struct {
RK_U32 fenc_done_clr : 1;
RK_U32 lkt_node_done_clr : 1;
RK_U32 sclr_done_clr : 1;
RK_U32 vslc_done_clr : 1;
RK_U32 vbsb_oflw_clr : 1;
RK_U32 vbsb_sct_clr : 1;
RK_U32 fenc_err_clr : 1;
RK_U32 wdg_clr : 1;
RK_U32 lkt_oerr_clr : 1;
RK_U32 lkt_estp_clr : 1;
RK_U32 lkt_fstp_clr : 1;
RK_U32 lkt_note_stp_clr : 1;
RK_U32 lkt_data_error_clr : 1;
RK_U32 : 19;
} reg006_int_clr;
// 0x001c, Interrupt State;
struct {
RK_U32 fenc_done_state : 1;
RK_U32 lkt_node_done_state : 1;
RK_U32 sclr_done_state : 1;
RK_U32 vslc_done_state : 1;
RK_U32 vbsb_oflw_state : 1;
RK_U32 vbsb_sct_state : 1;
RK_U32 fenc_err_state : 1;
RK_U32 wdg_state : 1;
RK_U32 lkt_oerr_state : 1;
RK_U32 lkt_estp_state : 1;
RK_U32 lkt_fstp_state : 1;
RK_U32 lkt_note_stp_state : 1;
RK_U32 lkt_data_error_state : 1;
RK_U32 : 19;
} reg007_int_state;
// 0x0020, Clock and RST CTRL
struct {
// Encoder auto reset core clock domain when frame finished
RK_U32 resetn_hw_en : 1;
// Encoder SRAM auto clock gating enable
RK_U32 sram_ckg_en : 1;
// Auto clock gating enable
RK_U32 cke : 1;
RK_U32 : 29;
} reg008_cru_ctrl;
// 0x0024, Fast link table cfg buffer addr, 128 byte aligned
RK_U32 reg009_lkt_base_addr;
// 0x0028, Link table node operation configuration
struct {
// Only the ejpeg with the same core ID can use this node
RK_U32 core_id : 4;
// The enable of lkt error stop next frame
RK_U32 lkt_err_stop_en : 1;
// The enable of lkt frame stop when the frame end
RK_U32 lkt_node_stop_en : 1;
RK_U32 : 10;
/**
* @brief Data swap for link table read channel.
* bit[3] -- swap 64 bits in 128 bits
* bit[2] -- swap 32 bits in 64 bits;
* bit[1] -- swap 16 bits in 32 bits;
* bit[0] -- swap 8 bits in 16 bits;
*/
RK_U32 lktr_bus_edin : 4;
/**
* @brief
* Data swap for link table write channel.
* bit[3] -- swap 64 bits in 128 bits
* bit[2] -- swap 32 bits in 64 bits;
* bit[1] -- swap 16 bits in 32 bits;
* bit[0] -- swap 8 bits in 16 bits;
*/
RK_U32 lktw_bus_edin : 4;
RK_U32 : 8;
} reg010_node_ocfg;
// 0x002c, watch dog configure register
RK_U32 reg011_wdg_jpeg;
// reserved, 0x0030
RK_U32 reg012;
// 0x0034, low delay esc operation configuration. Bit[0-30] : read ecs num.
RK_U32 reg013_low_delay_ecs_ocfg;
// 0x0038, low delay packet operation configuration. Bit[0-30] : read packet num.
RK_U32 reg014_low_delay_packet_ocfg;
// reserved, 0x003c
RK_U32 reg015;
// 0x0040, Address of JPEG Q table buffer, 128 byte aligned
RK_U32 reg016_adr_qtbl;
// 0x0044, Top address of JPEG Bit stream buffer, 16 byte aligned
RK_U32 reg017_adr_bsbt;
// 0x0048, Bottom address of JPEG bit stream buffer, 16 byte aligned
RK_U32 reg018_adr_bsbb;
// 0x004c, Read Address of JPEG bit stream buffer, 1 byte aligned
RK_U32 reg019_adr_bsbr;
// 0x0050, Start address of JPEG bit stream buffer, 1 byte aligned
RK_U32 reg020_adr_bsbs;
// 0x0054, Base address of ECS length buffer, 8 byte align
RK_U32 reg021_adr_ecs_len;
// 0x0058, Base address of the 1st storage area for video source buffer
RK_U32 reg022_adr_src0;
// 0x005c, Base address of the 2nd storage area for video source buffer
RK_U32 reg023_adr_src1;
// 0x0060, Base address of the 3rd storage area for video source buffer
RK_U32 reg024_adr_src2;
// reserved, 0x0064
RK_U32 reg025;
// 0x0068, rk jpeg encoder axi performance ctrl0 description
struct {
RK_U32 perf_work_e : 1;
RK_U32 perf_clr_e : 1;
RK_U32 perf_frm_type : 1;
RK_U32 cnt_type : 1;
RK_U32 rd_latency_id : 4;
RK_U32 rd_latency_thr : 12;
RK_U32 : 12;
} reg026_axi_perf_ctrl0;
// 0x006c, rk jpeg encoder axi performance ctrl1 description
struct {
RK_U32 addr_align_type : 2;
RK_U32 ar_cnt_id_type : 1;
RK_U32 aw_cnt_id_type : 1;
RK_U32 ar_count_id : 4;
RK_U32 aw_count_id : 4;
RK_U32 rd_total_bytes_mode : 1;
RK_U32 : 19;
} reg027_axi_perf_ctrl1;
// 0x0070, reserved
RK_U32 reg028;
// 0x0074, picture size
struct {
// Ceil(encoding picture height / 8) -1
RK_U32 pic_wd8_m1 : 13;
RK_U32 : 3;
// Ceil(encoding picture height / 8) -1
RK_U32 pic_hd8_m1 : 13;
RK_U32 : 3;
} reg029_sw_enc_rsl;
// 0x0078, JPEG source filling pixels for align
struct {
RK_U32 pic_wfill_jpeg : 6;
RK_U32 : 10;
RK_U32 pic_hfill_jpeg : 6;
RK_U32 : 10;
} reg030_sw_src_fill;
/* reserved 0x7c */
RK_U32 reg031;
// 0x0080, JPEG source format
struct {
RK_U32 : 1;
RK_U32 rbuv_swap_jpeg : 1;
/**
* @brief srouce color format
* 4'h0: tile400
* 4'h1: tile420
* 4'h2: tile422
* 4'h3: tile444
* 4'h4: YUV422SP
* 4'h5: YUV422P
* 4'h6: YUV420SP
* 4'h7: YUV420P
* 4'h8: YUYV422
* 4'h9: UYVY422
* 4'ha: YUV400
* 4'hc: YUV444SP
* 4'hd: YUV444P
* Others: Reserved
*/
RK_U32 src_fmt : 4;
/**
* @brief color format of output from preprocess
* 2'h0: YUV400;
* 2'h1: YUV420;
* 2'h2: YUV422;
* 2'h3: YUV444;
*
*/
RK_U32 out_fmt : 2;
RK_U32 : 1;
RK_U32 src_range_trns_en : 1;
RK_U32 src_range_trns_sel : 1;
/**
* @brief Chroma downsample mode
* 0 -- Average
* 1 -- Drop
*/
RK_U32 chroma_ds_mode : 1;
// Chroma value will be force to some value
RK_U32 chroma_force_en : 1;
RK_U32 : 2;
// 1 00 src mirror image
RK_U32 src_mirr_jpeg : 1;
RK_U32 u_force_value : 8;
RK_U32 v_force_value : 8;
} reg032_sw_src_fmt;
// 0x0084, encoding picture offset
struct {
RK_U32 pic_ofst_x : 16;
RK_U32 pic_ofst_y : 16;
} reg033_sw_pic_ofst;
// 0x0088, JPEG source stride0
struct {
RK_U32 src_strd_0 : 20;
RK_U32 : 12;
} reg034_sw_src_strd_0;
// 0x008c, JPEG source stride1
struct {
RK_U32 src_strd_1 : 19;
RK_U32 : 13;
} reg035_sw_src_strd_1;
// 0x0090, JPEG common config
struct {
/* the number of MCU in the restart interval */
RK_U32 rst_intv : 16;
RK_U32 : 9;
/**
* @brief JPEG encoder output mode
* 1'b0: frame by frame, without interrupt at any ECS;
* 1'b1: low latency mode, with interrupt per ECS, flush all the
* bit stream after each ECS finished.
*/
RK_U32 out_mode : 1;
/* the number of the fisrt RSTm */
RK_U32 rst_m : 3;
/**
* @brief Indicate if the current ECS is the last ECS of the whole picture.
* If it is the last ecs, add EOI.
*/
RK_U32 pic_last_ecs : 1;
/**
* @brief reload Q table or not
* 0 -- load Q table for current task
* 1 -- no need to load Q table
*/
RK_U32 jpeg_qtble_noload : 1;
RK_U32 : 1;
} reg036_sw_jpeg_enc_cfg;
// 0x0094, Low dealy packet size config
RK_U32 reg037_bsp_size_jpeg;
// 0x0098, Bit stream output padding config
struct {
RK_U32 uvc_partition0_len : 12;
RK_U32 uvc_partition_len : 12;
RK_U32 uvc_skip_len : 6;
RK_U32 : 2;
} reg038_sw_uvc_cfg;
// 0x009c, Y Quantify rounding
struct {
/* bias for Y at quantization */
RK_U32 bias_y : 15;
RK_U32 : 17;
} reg039_sw_jpeg_y_cfg;
// 0x00a0, U Quantify rounding
struct {
/* bias for U at quantization */
RK_U32 bias_u : 15;
RK_U32 : 17;
} reg040_sw_jpeg_u_cfg;
// 0x00a4, V Quantify rounding
struct {
/* bias for V at quantization */
RK_U32 bias_v : 15;
RK_U32 : 17;
} reg041_sw_jpeg_v_cfg;
// 0x00a8, Data bus endian
struct {
/**
* @brief Data swap for jpeg bit stream write channel
* [3]: Swap 64 bits in 128 bits
* [2]: Swap 32 bits in 64 bits
* [1]: Swap 16 bits in 32 bits
* [0]: Swap 8 bits in 16 bits
*/
RK_U32 jbsw_bus_edin : 4;
// Data swap for video source loading channel.
RK_U32 vsl_bus_edin : 4;
// Data swap for lkt state write channel
RK_U32 ecs_len_edin : 4;
// Data swap for qtbl read channel
RK_U32 sw_qtbl_edin : 4;
} reg042_dbus_endn;
} JpegeVpu720BaseReg;
typedef struct JpegeVpu720StatusReg_t {
// 0x00c0, Low 32 bits of JPEG header bits length.
RK_U32 st_bsl_l32_jpeg_head_bits;
// 0x00c4, High 32 bits of JPEG header bits length
RK_U32 st_bsl_h32_jpeg_head_bits;
// 0x00c8, Y and U source range
struct {
RK_U32 y_max_value : 8;
RK_U32 y_min_value : 8;
RK_U32 u_max_value : 8;
RK_U32 u_min_vlaue : 8;
} st_vsp_value0;
// 0x00cc, V source range and total_ecs_num_minus
struct {
RK_U32 v_max_value : 8;
RK_U32 v_min_vlaue : 8;
RK_U32 total_ecs_num_minus1 : 8;
} st_vsp_value1;
// 0x00d0, bit[0-15]
RK_U32 st_perf_rd_max_latency_num0;
// 0x00d4
RK_U32 st_perf_rd_latency_samp_num;
// 0x00d8
RK_U32 st_perf_rd_latency_acc_sum;
// 0x00dc
RK_U32 st_perf_rd_axi_total_byte;
// 0x00e0
RK_U32 st_perf_wr_axi_total_byte;
// 0x00e4
RK_U32 st_perf_working_cnt;
RK_U32 sw_reserved_00e8_00ec[2];
// 0x00f0
struct {
RK_U32 vsp_work_flag : 1;
RK_U32 jpeg_core_work_flag : 1;
RK_U32 dma_wr_work_flag : 1;
RK_U32 dma_work_flag : 1;
} st_wdg;
// 0x00f4
RK_U32 st_ppl_pos;
// 0x00f8
RK_U32 st_core_pos;
// 0x00fc, Bus status
struct {
RK_U32 ejpeg_arready : 1;
RK_U32 ejpeg_cfg_arvalid : 1;
RK_U32 ejpeg_cfg_arvalid_type : 1;
RK_U32 ejpeg_cfg_arready : 1;
RK_U32 ejpeg_vsp_arvalid : 1;
RK_U32 ejpeg_vsp_arready : 1;
RK_U32 rkejpeg_arvalid : 1;
RK_U32 ejpeg_cfg_ar_cnt : 2;
RK_U32 rkejpeg_arready : 1;
RK_U32 rkejpeg_ravlid : 1;
RK_U32 rkejpeg_rid : 4;
RK_U32 rkejpeg_rresp : 2;
RK_U32 rkejpeg_rready : 1;
RK_U32 axi_wr_state_cs : 1;
RK_U32 ejpeg_strmd_awvalid : 1;
RK_U32 ejpeg_strmd_awtype : 1;
RK_U32 ejpeg_strmd_awready : 1;
RK_U32 ejpeg_strmd_wvalid : 1;
RK_U32 ejpeg_strmd_wready : 1;
RK_U32 ejpeg_cfg_awvalid : 1;
RK_U32 ejpeg_cfg_awready : 1;
RK_U32 rkejpeg_awvalid : 1;
RK_U32 rkejpeg_awid : 1;
RK_U32 rkejpeg_wvalid : 1;
RK_U32 rkejpeg_wready : 1;
RK_U32 ejpeg_freeze_flag : 1;
RK_U32 : 1;
} st_bus;
// 0x0100, vsp_dbg_status
RK_U32 dbg_ppl;
// 0x0104, jpeg core dbg status
RK_U32 dbg_jpeg_core;
// reserved, 0x0108
RK_U32 sw_reserved_0108;
// 0x010c, The bit stream write address status
RK_U32 st_adr_jbsbw;
// 0x0110, ECS length buffer write address status
RK_U32 st_adr_ecs_len;
// 0x0114, the 1st storage aread for video source buffer read address status
RK_U32 st_adr_src0_jpeg;
// 0x0118, the 2nd storage aread for video source buffer read address status
RK_U32 st_adr_src1_jpeg;
// 0x011c, the 3rd storage aread for video source buffer read address status
RK_U32 st_adr_src2_jpeg;
// 0x0120, low delay packet num status
struct {
RK_U32 bs_packet_num : 16;
RK_U32 bs_packet_lst : 1;
} st_low_delay_packet_num;
// 0x0124, low delay ecs_len num status
struct {
RK_U32 ecs_len_num : 16;
RK_U32 ecs_len_lst : 1;
} st_ecs_len_num;
// 0x0128, JPEG common status
struct {
/**
* @brief
* 0: idle
* 1: cru open
* 2: lkt cfg load
* 3: qtbl_cfg_load
* 4:enc
* 5:frame end
* 6:cru_close
* 7:lkt_error_stop
* 8:lkt_force_stop
* 9:lkt_node_stop
*/
RK_U32 jpeg_enc_state : 4;
RK_U32 lkt_mode_en : 1;
} st_enc;
// 0x012c, Link table num
struct {
RK_U32 lkt_cfg_num : 8;
RK_U32 lkt_done_num : 8;
RK_U32 lkt_int_num : 8;
RK_U32 lkt_cfg_load_num : 8;
} st_lkt_num;
// 0x0130, link table cfg info
struct {
RK_U32 lkt_core_id : 4;
RK_U32 : 4;
RK_U32 lkt_stop_flag : 1;
RK_U32 lkt_node_int : 1;
RK_U32 lkt_task_id : 12;
RK_U32 : 10;
} st_lkt_info;
//0x0134, next read addr for lkt_cfg
RK_U32 st_lkt_cfg_next_addr;
//0x0138, lkt state buffer write addr
RK_U32 st_lkt_waddr;
} JpegeVpu720StatusReg;
#define JPEGE_VPU720_REG_BASE_INT_STATE (0x1c)
#define JPEGE_VPU720_REG_STATUS_OFFSET (0xc0)
typedef struct JpegeVpu720RegSet_t {
JpegeVpu720BaseReg reg_base;
JpegeVpu720StatusReg reg_st;
RK_U32 int_state;
} JpegeVpu720Reg;
#endif /* __HAL_JPEGE_VPU720_REG_H__ */

View File

@@ -59,6 +59,7 @@ typedef struct JpegdHalCtx {
RK_U32 have_pp;
PPInfo pp_info;
RK_U32 hw_id;
} JpegdHalCtx;
#endif /* __HAL_JPEGD_COMMON_H__ */

View File

@@ -262,6 +262,8 @@ MPP_RET hal_jpegd_rkv_init(void *hal, MppHalCfg *cfg)
return ret;
}
ctx->hw_id = mpp_get_client_hw_id(VPU_CLIENT_JPEG_DEC);
/* allocate regs buffer */
if (ctx->regs == NULL) {
ctx->regs = mpp_calloc_size(void, sizeof(JpegRegSet));
@@ -363,6 +365,11 @@ static MPP_RET setup_output_fmt(JpegdHalCtx *ctx, JpegdSyntax *syntax, RK_S32 ou
ctx->output_fmt = s->output_fmt;
}
if (MPP_FRAME_FMT_IS_TILE(ctx->output_fmt))
regs->reg2_sys.dec_out_sequence = OUTPUT_TILE;
else
regs->reg2_sys.dec_out_sequence = OUTPUT_RASTER;
jpegd_dbg_hal("convert format %d to format %d\n", s->output_fmt, ctx->output_fmt);
if ((s->yuv_mode == YUV_MODE_420 && regs->reg2_sys.yuv_out_format == YUV_OUT_FMT_NO_TRANS) ||
@@ -392,8 +399,7 @@ static MPP_RET jpegd_gen_regs(JpegdHalCtx *ctx, JpegdSyntax *syntax)
regs->reg3_pic_size.pic_width_m1 = s->width - 1;
regs->reg3_pic_size.pic_height_m1 = s->height - 1;
if (s->sample_precision != DCT_SAMPLE_PRECISION_8 || (s->htbl_entry & 0x0f) != 0x0f
|| s->qtbl_entry > TBL_ENTRY_3)
if (s->sample_precision != DCT_SAMPLE_PRECISION_8 || s->qtbl_entry > TBL_ENTRY_3)
return MPP_NOK;
regs->reg4_pic_fmt.pixel_depth = BIT_DEPTH_8;
@@ -402,8 +408,8 @@ static MPP_RET jpegd_gen_regs(JpegdHalCtx *ctx, JpegdSyntax *syntax)
}
if (s->nb_components > 1) {
regs->reg4_pic_fmt.qtables_sel = (s->qtbl_entry > 1) ? s->qtbl_entry : TBL_ENTRY_2;
regs->reg4_pic_fmt.htables_sel = (s->htbl_entry > 0x0f) ? s->htbl_entry : TBL_ENTRY_2;
regs->reg4_pic_fmt.qtables_sel = (s->qtbl_entry > 1) ? TBL_ENTRY_3 : TBL_ENTRY_2;
regs->reg4_pic_fmt.htables_sel = (s->htbl_entry > 0x0f) ? TBL_ENTRY_3 : TBL_ENTRY_2;
} else {
regs->reg4_pic_fmt.qtables_sel = TBL_ENTRY_1;
regs->reg4_pic_fmt.htables_sel = TBL_ENTRY_1;
@@ -478,8 +484,42 @@ static MPP_RET jpegd_gen_regs(JpegdHalCtx *ctx, JpegdSyntax *syntax)
y_virstride = y_hor_stride * out_height;
if (regs->reg2_sys.dec_out_sequence == OUTPUT_TILE) {
y_hor_stride <<= 3;
uv_hor_virstride <<= 3;
if (mpp_get_soc_type() == ROCKCHIP_SOC_RK3576) {
switch (regs->reg2_sys.yuv_out_format) {
case YUV_OUT_FMT_2_YUYV:
y_hor_stride = y_hor_stride * 4 * 2;
break;
case YUV_OUT_FMT_NO_TRANS:
switch (regs->reg4_pic_fmt.jpeg_mode) {
case YUV_MODE_422:
case YUV_MODE_440:
y_hor_stride = y_hor_stride * 4 * 2;
break;
case YUV_MODE_444:
y_hor_stride = y_hor_stride * 4 * 3;
break;
case YUV_MODE_411:
case YUV_MODE_420:
y_hor_stride = y_hor_stride * 4 * 3 / 2;
break;
case YUV_MODE_400:
y_hor_stride = y_hor_stride * 4;
break;
default:
return MPP_NOK;
break;
}
break;
case YUV_OUT_FMT_2_NV12:
y_hor_stride = y_hor_stride * 4 * 3 / 2;
break;
}
uv_hor_virstride = 0;
} else {
y_hor_stride <<= 3;
uv_hor_virstride <<= 3;
}
}
regs->reg5_hor_virstride.y_hor_virstride = y_hor_stride & 0xffff;
@@ -818,10 +858,15 @@ MPP_RET hal_jpegd_rkv_control(void *hal, MpiCmd cmd_type, void *param)
case MPP_DEC_SET_OUTPUT_FORMAT: {
MppFrameFormat output_fmt = *((MppFrameFormat *)param);
RockchipSocType soc_type = mpp_get_soc_type();
MppFrameFormat frm_fmt = output_fmt & MPP_FRAME_FMT_MASK;
ret = MPP_NOK;
if (MPP_FRAME_FMT_IS_RGB(output_fmt) && (soc_type == ROCKCHIP_SOC_RK3576)) {
mpp_err_f("RGB format is not supported!\n");
return ret = MPP_NOK;
}
switch ((RK_S32)output_fmt) {
switch ((RK_U32)frm_fmt) {
case MPP_FMT_YUV420SP :
case MPP_FMT_YUV420SP_VU :
case MPP_FMT_YUV422_YUYV :
@@ -829,7 +874,7 @@ MPP_RET hal_jpegd_rkv_control(void *hal, MpiCmd cmd_type, void *param)
case MPP_FMT_RGB888 : {
ret = MPP_OK;
} break;
case (MPP_FMT_RGB565) : { // rgb565be
case MPP_FMT_RGB565 : { // rgb565be
if (soc_type >= ROCKCHIP_SOC_RK3588 &&
soc_type < ROCKCHIP_SOC_BUTT)
ret = MPP_OK;

View File

@@ -99,7 +99,14 @@ typedef struct {
RK_U32 soft_rest_rdy : 1;
RK_U32 buf_empty_force_end_flag : 1;
RK_U32 care_strm_error_e : 1;
RK_U32 : 15;
RK_U32 low_delay_out_sta : 1;
RK_U32 lkt_operation_error_sta : 1;
RK_U32 lkt_mode_int_sta : 1;
RK_U32 lkt_force_stop_sta : 1;
RK_U32 lkt_node_int_sta : 1;
RK_U32 lkt_err_stop_sta : 1;
RK_U32 lkt_data_err_sta : 1;
RK_U32 : 8;
} reg1_int;
struct {
@@ -113,7 +120,8 @@ typedef struct {
RK_U32 out_swap32_e : 1;
RK_U32 out_swap64_e : 1;
RK_U32 out_cbcr_swap : 1;
RK_U32 : 2;
RK_U32 out_byte_swap : 1;
RK_U32 : 1;
RK_U32 scaledown_mode : 2;
RK_U32 : 2;
RK_U32 time_out_mode : 1;
@@ -122,7 +130,8 @@ typedef struct {
RK_U32 fbc_e : 1;
RK_U32 allow_16x8_cp_flag : 1;
RK_U32 fbc_force_uncompress : 1;
RK_U32 : 1;
// 0 -- rgb565/rgb888, 1 -- bgr565, bgr888
RK_U32 bgr_sequence : 1;
RK_U32 fill_down_e : 1;
RK_U32 fill_right_e : 1;
RK_U32 dec_out_sequence : 1;
@@ -220,8 +229,15 @@ typedef struct {
RK_U32 val;
} reg16_clk_gate;
RK_U32 reg17_29[13];
// 0x0044, bit[16:0]
RK_U32 reg17_low_delay_output;
// 0x0048, bit[16:0]
RK_U32 reg18_low_delay_output_status;
// 0x004c ~ 0x0074
RK_U32 reg19_29[11];
// 0x0078
struct {
RK_U32 axi_per_work_e : 1;
RK_U32 axi_per_clr_e : 1;