From bc84639ba0d9a1800a4e6737448a7deb9182f70a Mon Sep 17 00:00:00 2001 From: Xindong Xu Date: Tue, 14 Apr 2020 09:25:34 +0000 Subject: Merge remote-tracking branch 'remotes/trunk/amlogic-4.9-dev' into HEAD Change-Id: If702f3c1ecbbea265224d6666141c50ece4a100f --- diff --git a/Media.mk b/Media.mk index 7fa3c48..25e8622 100755..100644 --- a/Media.mk +++ b/Media.mk @@ -20,6 +20,7 @@ CONFIGS := CONFIG_AMLOGIC_MEDIA_VDEC_MPEG12=m \ CONFIG_AMLOGIC_MEDIA_VDEC_AVS=m \ CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI=m \ CONFIG_AMLOGIC_MEDIA_VDEC_AVS2=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_AV1=m \ CONFIG_AMLOGIC_MEDIA_VENC_H264=m \ CONFIG_AMLOGIC_MEDIA_VENC_H265=m diff --git a/drivers/amvdec_ports/Makefile b/drivers/amvdec_ports/Makefile index 86bc158..221c0d4 100644 --- a/drivers/amvdec_ports/Makefile +++ b/drivers/amvdec_ports/Makefile @@ -1,7 +1,6 @@ obj-m += amvdec_ports.o amvdec_ports-objs += aml_vcodec_dec_drv.o amvdec_ports-objs += aml_vcodec_dec.o -amvdec_ports-objs += aml_vcodec_dec_pm.o amvdec_ports-objs += aml_vcodec_util.o amvdec_ports-objs += aml_vcodec_adapt.o amvdec_ports-objs += aml_vcodec_vfm.o diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.c b/drivers/amvdec_ports/aml_vcodec_adapt.c index da5637d..b87d0c8 100644 --- a/drivers/amvdec_ports/aml_vcodec_adapt.c +++ b/drivers/amvdec_ports/aml_vcodec_adapt.c @@ -52,8 +52,6 @@ #define PTS_OUTSIDE (1) #define SYNC_OUTSIDE (2) -#define USE_V4L_PORTS (0x80) -#define SCATTER_MEM (0x100) //#define DATA_DEBUG @@ -114,9 +112,8 @@ extern bool aml_set_vfm_enable, aml_set_vdec_type_enable; static void set_default_params(struct aml_vdec_adapt *vdec) { - ulong sync_mode = (PTS_OUTSIDE | SYNC_OUTSIDE | USE_V4L_PORTS); + ulong sync_mode = (PTS_OUTSIDE | SYNC_OUTSIDE); - sync_mode |= vdec->ctx->scatter_mem_enable ? SCATTER_MEM : 0; vdec->dec_prop.param = (void *)sync_mode; vdec->dec_prop.format = vdec->format; vdec->dec_prop.width = 1920; @@ -201,7 +198,7 @@ static void change_vbufsize(struct vdec_s *vdec, struct stream_buf_s *pvbuf) { if (pvbuf->buf_start != 0) { - pr_info("streambuf is alloced before\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "streambuf is alloced before\n"); return; } @@ -261,7 +258,7 @@ static int audio_component_init(struct stream_port_s *port, int r; if ((port->flag & PORT_FLAG_AFORMAT) == 0) { - pr_err("aformat not set\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "aformat not set\n"); return 0; } @@ -335,7 +332,7 @@ static int video_component_init(struct stream_port_s *port, struct vdec_s *vdec = ada_ctx->vdec; if ((vdec->port_flag & PORT_FLAG_VFORMAT) == 0) { - pr_err("vformat not set\n"); + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "vformat not set\n"); return -EPERM; } @@ -351,7 +348,7 @@ static int video_component_init(struct stream_port_s *port, if (port->type & PORT_TYPE_FRAME) { ret = vdec_init(vdec, pbuf->for_4k); if (ret < 0) { - pr_err("video_component_init %d, failed\n", __LINE__); + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "failed\n"); video_component_release(port, pbuf, 2); return ret; } @@ -372,14 +369,14 @@ static int video_component_init(struct stream_port_s *port, ret = stbuf_init(pbuf, vdec, false); if (ret < 0) { - pr_err("video_component_init %d, stbuf_init failed\n", __LINE__); + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "stbuf_init failed\n"); return ret; } /* todo: set path based on port flag */ ret = vdec_init(vdec, pbuf->for_4k); if (ret < 0) { - pr_err("video_component_init %d, vdec_init failed\n", __LINE__); + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "vdec_init failed\n"); video_component_release(port, pbuf, 2); return ret; } @@ -387,8 +384,7 @@ static int video_component_init(struct stream_port_s *port, if (vdec_dual(vdec)) { ret = vdec_init(vdec->slave, pbuf->for_4k); if (ret < 0) { - pr_err("video_component_init %d, vdec_init failed\n", - __LINE__); + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "vdec_init failed\n"); video_component_release(port, pbuf, 2); return ret; } @@ -398,7 +394,7 @@ static int video_component_init(struct stream_port_s *port, ret = esparser_init(pbuf, vdec); if (ret < 0) { video_component_release(port, pbuf, 3); - pr_err("esparser_init() failed\n"); + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "esparser_init() failed\n"); return ret; } } @@ -476,33 +472,25 @@ static void set_vdec_properity(struct vdec_s *vdec, /* set video format, sys info and vfm map.*/ vdec->port->vformat = vdec->format; vdec->port->type |= PORT_TYPE_VIDEO; - vdec->port_flag |= PORT_FLAG_VFORMAT; + vdec->port_flag |= (vdec->port->flag | PORT_FLAG_VFORMAT); if (vdec->slave) { vdec->slave->format = ada_ctx->dec_prop.format; vdec->slave->port_flag |= PORT_FLAG_VFORMAT; } - if (vdec->port->type & PORT_FLAG_DRM) { - vdec->type = VDEC_TYPE_STREAM_PARSER; - vdec->port->type |= PORT_TYPE_ES; - vdec->frame_base_video_path = FRAME_BASE_PATH_V4L_VIDEO; - } else { - vdec->type = VDEC_TYPE_FRAME_BLOCK; - vdec->port->type |= PORT_TYPE_FRAME; - vdec->frame_base_video_path = FRAME_BASE_PATH_V4L_OSD; - } + vdec->type = VDEC_TYPE_FRAME_BLOCK; + vdec->port->type |= PORT_TYPE_FRAME; + vdec->frame_base_video_path = FRAME_BASE_PATH_V4L_OSD; if (aml_set_vdec_type_enable) { if (aml_set_vdec_type == VDEC_TYPE_STREAM_PARSER) { vdec->type = VDEC_TYPE_STREAM_PARSER; vdec->port->type &= ~PORT_TYPE_FRAME; vdec->port->type |= PORT_TYPE_ES; - ada_ctx->ctx->is_stream_mode = true; } else if (aml_set_vdec_type == VDEC_TYPE_FRAME_BLOCK) { vdec->type = VDEC_TYPE_FRAME_BLOCK; vdec->port->type &= ~PORT_TYPE_ES; vdec->port->type |= PORT_TYPE_FRAME; - ada_ctx->ctx->is_stream_mode = false; } } @@ -537,7 +525,7 @@ static int vdec_ports_init(struct aml_vdec_adapt *ada_ctx) /* init hw and gate*/ ret = enable_hardware(vdec->port); if (ret < 0) { - pr_info("enable hw fail.\n"); + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "enable hw fail.\n"); goto error1; } @@ -548,7 +536,7 @@ static int vdec_ports_init(struct aml_vdec_adapt *ada_ctx) && (vdec->port_flag & PORT_FLAG_AFORMAT)) { ret = audio_component_init(vdec->port, pabuf); if (ret < 0) { - pr_err("audio_component_init failed\n"); + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "audio_component_init failed\n"); goto error1; } } @@ -564,7 +552,7 @@ static int vdec_ports_init(struct aml_vdec_adapt *ada_ctx) ret = video_component_init(vdec->port, pvbuf); if (ret < 0) { - pr_err("video_component_init failed\n"); + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "video_component_init failed\n"); goto error2; } @@ -592,7 +580,7 @@ int video_decoder_init(struct aml_vdec_adapt *vdec) /* init the buffer work space and connect vdec.*/ ret = vdec_ports_init(vdec); if (ret < 0) { - pr_info("vdec ports init fail.\n"); + v4l_dbg(vdec->ctx, V4L_DEBUG_CODEC_ERROR, "vdec ports init fail.\n"); goto out; } out: @@ -606,14 +594,14 @@ int video_decoder_release(struct aml_vdec_adapt *vdec) ret = vdec_ports_release(port); if (ret < 0) { - pr_info("vdec ports release fail.\n"); + v4l_dbg(vdec->ctx, V4L_DEBUG_CODEC_ERROR, "vdec ports release fail.\n"); goto out; } /* disable gates */ ret = disable_hardware(port); if (ret < 0) { - pr_info("disable hw fail.\n"); + v4l_dbg(vdec->ctx, V4L_DEBUG_CODEC_ERROR, "disable hw fail.\n"); goto out; } out: @@ -652,14 +640,15 @@ int vdec_vbuf_write(struct aml_vdec_adapt *ada_ctx, } while (ret == -EAGAIN && try_cnt--); if (slow_input) { - pr_info("slow_input: es codec write size %x\n", ret); + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO, + "slow_input: es codec write size %x\n", ret); msleep(10); } #ifdef DATA_DEBUG /* dump to file */ //dump_write(vbuf, size); - //pr_info("vbuf: %p, size: %u, ret: %d\n", vbuf, size, ret); + //v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO, "vbuf: %p, size: %u, ret: %d\n", vbuf, size, ret); #endif return ret; @@ -684,7 +673,8 @@ int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx, ret = vdec_write_vframe(vdec, buf, count); if (slow_input) { - pr_info("slow_input: frame codec write size %d\n", ret); + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO, + "slow_input: frame codec write size %d\n", ret); msleep(30); } @@ -692,8 +682,33 @@ int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx, /* dump to file */ dump_write(buf, count); #endif - aml_v4l2_debug(3, "[%d] write frames, vbuf: %p, size: %u, ret: %d, crc: %x", - ada_ctx->ctx->id, buf, count, ret, crc32_le(0, buf, count)); + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT, + "write frames, vbuf: %p, size: %u, ret: %d, crc: %x\n", + buf, count, ret, crc32_le(0, buf, count)); + + return ret; +} + +int vdec_vframe_write_with_dma(struct aml_vdec_adapt *ada_ctx, + ulong addr, u32 count, u64 timestamp, u32 handle) +{ + int ret = -1; + struct vdec_s *vdec = ada_ctx->vdec; + + /* set timestamp */ + vdec_set_timestamp(vdec, timestamp); + + ret = vdec_write_vframe_with_dma(vdec, addr, count, handle); + + if (slow_input) { + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO, + "slow_input: frame codec write size %d\n", ret); + msleep(30); + } + + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT, + "write frames, vbuf: %lx, size: %u, ret: %d\n", + addr, count, ret); return ret; } @@ -712,13 +727,23 @@ int aml_codec_reset(struct aml_vdec_adapt *ada_ctx, int *mode) int ret = 0; if (vdec) { - vdec_set_eos(vdec, false); - + if (!ada_ctx->ctx->q_data[AML_Q_DATA_SRC].resolution_changed) + vdec_set_eos(vdec, false); if (*mode == V4L_RESET_MODE_NORMAL && - vdec->input.have_frame_num == 0) + vdec->input.have_frame_num == 0) { + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO, + "no input reset mode: %d\n", *mode); *mode = V4L_RESET_MODE_LIGHT; - - aml_v4l2_debug(2, "%s, reset mode: %d\n", __func__, *mode); + } + if (ada_ctx->ctx->param_sets_from_ucode && + *mode == V4L_RESET_MODE_NORMAL && + ada_ctx->ctx->q_data[AML_Q_DATA_SRC].resolution_changed == true) { + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO, + "resolution_changed reset mode: %d\n", *mode); + *mode = V4L_RESET_MODE_LIGHT; + } + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO, + "reset mode: %d\n", *mode); ret = vdec_v4l2_reset(vdec, *mode); *mode = V4L_RESET_MODE_NORMAL; @@ -761,3 +786,8 @@ void v4l2_config_vdec_parm(struct aml_vdec_adapt *ada_ctx, u8 *data, u32 len) memcpy(vdec->config, data, vdec->config_len); } +u32 aml_recycle_buffer(struct aml_vdec_adapt *adaptor) +{ + return vdec_input_get_freed_handle(adaptor->vdec); +} + diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.h b/drivers/amvdec_ports/aml_vcodec_adapt.h index 1f8afdd..b73b9ff 100644 --- a/drivers/amvdec_ports/aml_vcodec_adapt.h +++ b/drivers/amvdec_ports/aml_vcodec_adapt.h @@ -54,6 +54,9 @@ int vdec_vbuf_write(struct aml_vdec_adapt *ada_ctx, int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx, const char *buf, unsigned int count, u64 timestamp); +int vdec_vframe_write_with_dma(struct aml_vdec_adapt *ada_ctx, + ulong addr, u32 count, u64 timestamp, u32 handle); + bool vdec_input_full(struct aml_vdec_adapt *ada_ctx); void aml_decoder_flush(struct aml_vdec_adapt *ada_ctx); @@ -66,5 +69,7 @@ bool is_input_ready(struct aml_vdec_adapt *ada_ctx); int vdec_frame_number(struct aml_vdec_adapt *ada_ctx); +u32 aml_recycle_buffer(struct aml_vdec_adapt *adaptor); + #endif /* VDEC_ADAPT_H */ diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c index ec6d6e3..8856bf8 100644 --- a/drivers/amvdec_ports/aml_vcodec_dec.c +++ b/drivers/amvdec_ports/aml_vcodec_dec.c @@ -26,7 +26,6 @@ //#include "aml_vcodec_intr.h" #include "aml_vcodec_util.h" #include "vdec_drv_if.h" -#include "aml_vcodec_dec_pm.h" #include #include #include @@ -49,7 +48,7 @@ #define DFT_CFG_HEIGHT AML_VDEC_MIN_H #define V4L2_CID_USER_AMLOGIC_BASE (V4L2_CID_USER_BASE + 0x1100) -#define AML_V4L2_SET_DECMODE (V4L2_CID_USER_AMLOGIC_BASE + 0) +#define AML_V4L2_SET_DRMMODE (V4L2_CID_USER_AMLOGIC_BASE + 0) #define WORK_ITEMS_MAX (32) @@ -122,38 +121,58 @@ static struct aml_video_fmt aml_video_formats[] = { static const struct aml_codec_framesizes aml_vdec_framesizes[] = { { .fourcc = V4L2_PIX_FMT_H264, - .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8, - AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 }, + .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2, + AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2}, }, { .fourcc = V4L2_PIX_FMT_HEVC, - .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8, - AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 }, + .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2, + AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2}, }, { .fourcc = V4L2_PIX_FMT_VP9, - .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8, - AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 }, + .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2, + AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2}, }, { .fourcc = V4L2_PIX_FMT_MPEG1, - .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8, - AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 }, + .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2, + AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2}, }, { .fourcc = V4L2_PIX_FMT_MPEG2, - .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8, - AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 }, + .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2, + AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2}, }, { .fourcc = V4L2_PIX_FMT_MPEG4, - .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8, - AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 }, + .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2, + AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2}, }, { .fourcc = V4L2_PIX_FMT_MJPEG, - .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8, - AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 }, + .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2, + AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2}, + }, + { + .fourcc = V4L2_PIX_FMT_NV21, + .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2, + AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2}, + }, + { + .fourcc = V4L2_PIX_FMT_NV21M, + .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2, + AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2}, + }, + { + .fourcc = V4L2_PIX_FMT_NV12, + .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2, + AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2}, + }, + { + .fourcc = V4L2_PIX_FMT_NV12M, + .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2, + AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2}, }, }; @@ -161,6 +180,7 @@ static const struct aml_codec_framesizes aml_vdec_framesizes[] = { #define NUM_FORMATS ARRAY_SIZE(aml_video_formats) extern bool multiplanar; +extern bool dump_capture_frame; extern int dmabuf_fd_install_data(int fd, void* data, u32 size); extern bool is_v4l2_buf_file(struct file *file); @@ -184,10 +204,6 @@ static struct aml_video_fmt *aml_vdec_find_format(struct v4l2_format *f) struct aml_video_fmt *fmt; unsigned int k; - aml_v4l2_debug(4, "%s, type: %u, planes: %u, fmt: %u\n", - __func__, f->type, f->fmt.pix_mp.num_planes, - f->fmt.pix_mp.pixelformat); - for (k = 0; k < NUM_FORMATS; k++) { fmt = &aml_video_formats[k]; if (fmt->fourcc == f->fmt.pix_mp.pixelformat) @@ -210,12 +226,14 @@ void aml_vdec_dispatch_event(struct aml_vcodec_ctx *ctx, u32 changes) { struct v4l2_event event = {0}; - if (ctx->receive_cmd_stop) { + if (ctx->receive_cmd_stop && + changes != V4L2_EVENT_SRC_CH_RESOLUTION && + changes != V4L2_EVENT_SEND_EOS) { ctx->state = AML_STATE_ABORT; ATRACE_COUNTER("v4l2_state", ctx->state); changes = V4L2_EVENT_REQUEST_EXIT; - aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_ABORT)\n"); } switch (changes) { @@ -226,19 +244,22 @@ void aml_vdec_dispatch_event(struct aml_vcodec_ctx *ctx, u32 changes) event.type = V4L2_EVENT_SOURCE_CHANGE; event.u.src_change.changes = changes; break; + case V4L2_EVENT_SEND_EOS: + event.type = V4L2_EVENT_EOS; + break; default: - pr_err("unsupport dispatch event %x\n", changes); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "unsupport dispatch event %x\n", changes); return; } v4l2_event_queue_fh(&ctx->fh, &event); - aml_v4l2_debug(3, "[%d] %s() changes: %x", - ctx->id, __func__, changes); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "changes: %x\n", changes); } static void aml_vdec_flush_decoder(struct aml_vcodec_ctx *ctx) { - aml_v4l2_debug(3, "[%d] %s() [%d]", ctx->id, __func__, __LINE__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s\n", __func__); aml_decoder_flush(ctx->ada_ctx); } @@ -249,7 +270,8 @@ static void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx) int ret; if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->last_decoded_picinfo)) { - aml_v4l2_err("[%d] Error!! Cannot get param : GET_PARAM_PICTURE_INFO ERR", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Cannot get param : GET_PARAM_PICTURE_INFO ERR\n"); return; } @@ -257,7 +279,8 @@ static void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx) ctx->last_decoded_picinfo.visible_height == 0 || ctx->last_decoded_picinfo.coded_width == 0 || ctx->last_decoded_picinfo.coded_height == 0) { - aml_v4l2_err("Cannot get correct pic info"); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Cannot get correct pic info\n"); return; } @@ -265,8 +288,9 @@ static void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx) (ctx->last_decoded_picinfo.visible_height == ctx->picinfo.visible_height)) return;*/ - aml_v4l2_debug(4, "[%d]-> new(%d,%d), old(%d,%d), real(%d,%d)", - ctx->id, ctx->last_decoded_picinfo.visible_width, + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, + "new(%d,%d), old(%d,%d), real(%d,%d)\n", + ctx->last_decoded_picinfo.visible_width, ctx->last_decoded_picinfo.visible_height, ctx->picinfo.visible_width, ctx->picinfo.visible_height, ctx->last_decoded_picinfo.coded_width, @@ -274,36 +298,79 @@ static void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx) ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize); if (dpbsize == 0) - aml_v4l2_err("[%d] Incorrect dpb size, ret=%d", ctx->id, ret); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Incorrect dpb size, ret=%d\n", ret); /* update picture information */ ctx->dpb_size = dpbsize; ctx->picinfo = ctx->last_decoded_picinfo; } +static bool aml_check_inst_quit(struct aml_vcodec_dev *dev, + struct aml_vcodec_ctx * inst, u32 id) +{ + struct aml_vcodec_ctx *ctx = NULL; + bool ret = true; + + if (dev == NULL) + return false; + + mutex_lock(&dev->dev_mutex); + + if (list_empty(&dev->ctx_list)) { + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "v4l inst list is empty.\n"); + ret = true; + goto out; + } + + list_for_each_entry(ctx, &dev->ctx_list, list) { + if ((ctx == inst) && (ctx->id == id)) { + ret = ctx->receive_cmd_stop ? true : false; + goto out; + } + } +out: + mutex_unlock(&dev->dev_mutex); + + return ret; +} + void vdec_frame_buffer_release(void *data) { struct file_private_data *priv_data = (struct file_private_data *) data; - struct vframe_s *vf = &priv_data->vf; + struct aml_vcodec_dev *dev = (struct aml_vcodec_dev *) + priv_data->v4l_dev_handle; + struct aml_vcodec_ctx *inst = (struct aml_vcodec_ctx *) + priv_data->v4l_inst_handle; + u32 id = priv_data->v4l_inst_id; + + if (aml_check_inst_quit(dev, inst, id)) { + struct vframe_s *vf = &priv_data->vf; + + if (decoder_bmmu_box_valide_check(vf->mm_box.bmmu_box)) { + decoder_bmmu_box_free_idx(vf->mm_box.bmmu_box, + vf->mm_box.bmmu_idx); + decoder_bmmu_try_to_release_box(vf->mm_box.bmmu_box); + } - if (decoder_bmmu_box_valide_check(vf->mm_box.bmmu_box)) { - decoder_bmmu_box_free_idx(vf->mm_box.bmmu_box, - vf->mm_box.bmmu_idx); - decoder_bmmu_try_to_release_box(vf->mm_box.bmmu_box); - } + if (decoder_mmu_box_valide_check(vf->mm_box.mmu_box)) { + decoder_mmu_box_free_idx(vf->mm_box.mmu_box, + vf->mm_box.mmu_idx); + decoder_mmu_try_to_release_box(vf->mm_box.mmu_box); + } - if (decoder_mmu_box_valide_check(vf->mm_box.mmu_box)) { - decoder_mmu_box_free_idx(vf->mm_box.mmu_box, - vf->mm_box.mmu_idx); - decoder_mmu_try_to_release_box(vf->mm_box.mmu_box); + v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR, + "[%d]: vf idx: %d, bmmu idx: %d, bmmu_box: %lx\n", + id, vf->index, vf->mm_box.bmmu_idx, + (ulong) vf->mm_box.bmmu_box); + v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR, + "[%d]: vf idx: %d, mmu_idx: %d, mmu_box: %lx\n", + id, vf->index, vf->mm_box.mmu_idx, + (ulong) vf->mm_box.mmu_box); } - aml_v4l2_debug(2, "%s vf idx: %d, bmmu idx: %d, bmmu_box: %p", - __func__, vf->index, vf->mm_box.bmmu_idx, vf->mm_box.bmmu_box); - aml_v4l2_debug(2, "%s vf idx: %d, mmu_idx: %d, mmu_box: %p", - __func__, vf->index, vf->mm_box.mmu_idx, vf->mm_box.mmu_box); - memset(data, 0, sizeof(struct file_private_data)); kfree(data); } @@ -329,18 +396,15 @@ int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_ return -1; } - aml_v4l2_debug(2, "[%d] %s() vbuf idx: %d, state: %d, ready: %d", - ctx->id, __func__, dst_buf->index, dst_buf->state, - v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx)); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "vbuf idx: %d, state: %d, ready: %d\n", + dst_buf->index, dst_buf->state, + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx)); dst_vb2_v4l2 = container_of(dst_buf, struct vb2_v4l2_buffer, vb2_buf); dst_buf_info = container_of(dst_vb2_v4l2, struct aml_video_dec_buf, vb); - if (ctx->scatter_mem_enable) { - pfb = &dst_buf_info->frame_buffer; - pfb->mem_type = VDEC_SCATTER_MEMORY_TYPE; - pfb->status = FB_ST_NORMAL; - } else if (dst_buf->num_planes == 1) { + if (dst_buf->num_planes == 1) { pfb = &dst_buf_info->frame_buffer; pfb->m.mem[0].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); pfb->m.mem[0].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr); @@ -349,8 +413,8 @@ int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_ pfb->num_planes = dst_buf->num_planes; pfb->status = FB_ST_NORMAL; - aml_v4l2_debug(4, "[%d] idx: %u, 1 plane, y:(0x%lx, %d)", - ctx->id, dst_buf->index, + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "idx: %u, 1 plane, y:(0x%lx, %d)\n", dst_buf->index, pfb->m.mem[0].addr, pfb->m.mem[0].size); } else if (dst_buf->num_planes == 2) { pfb = &dst_buf_info->frame_buffer; @@ -366,8 +430,8 @@ int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_ pfb->num_planes = dst_buf->num_planes; pfb->status = FB_ST_NORMAL; - aml_v4l2_debug(4, "[%d] idx: %u, 2 planes, y:(0x%lx, %d), c:(0x%lx, %d)", - ctx->id, dst_buf->index, + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "idx: %u, 2 planes, y:(0x%lx, %d), c:(0x%lx, %d)\n", dst_buf->index, pfb->m.mem[0].addr, pfb->m.mem[0].size, pfb->m.mem[1].addr, pfb->m.mem[1].size); } else { @@ -389,8 +453,9 @@ int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_ pfb->num_planes = dst_buf->num_planes; pfb->status = FB_ST_NORMAL; - aml_v4l2_debug(4, "[%d] idx: %u, 3 planes, y:(0x%lx, %d), u:(0x%lx, %d), v:(0x%lx, %d)", - ctx->id, dst_buf->index, + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "idx: %u, 3 planes, y:(0x%lx, %d), u:(0x%lx, %d), v:(0x%lx, %d)\n", + dst_buf->index, pfb->m.mem[0].addr, pfb->m.mem[0].size, pfb->m.mem[1].addr, pfb->m.mem[1].size, pfb->m.mem[2].addr, pfb->m.mem[2].size); @@ -417,15 +482,13 @@ int put_fb_to_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *in_fb) { struct aml_video_dec_buf *dstbuf; - pr_info("[%d] %s() [%d]\n", ctx->id, __func__, __LINE__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s\n", __func__); if (in_fb == NULL) { - aml_v4l2_debug(4, "[%d] No free frame buffer", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "No free frame buffer\n"); return -1; } - aml_v4l2_debug(4, "[%d] tmp_frame_addr = 0x%p", ctx->id, in_fb); - dstbuf = container_of(in_fb, struct aml_video_dec_buf, frame_buffer); mutex_lock(&ctx->lock); @@ -433,10 +496,9 @@ int put_fb_to_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *in_fb) if (!dstbuf->used) goto out; - aml_v4l2_debug(4, - "[%d] status=%x queue id=%d to rdy_queue", - ctx->id, in_fb->status, - dstbuf->vb.vb2_buf.index); + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, + "status=%x queue id=%d to rdy_queue\n", + in_fb->status, dstbuf->vb.vb2_buf.index); v4l2_m2m_buf_queue(ctx->m2m_ctx, &dstbuf->vb); @@ -454,13 +516,13 @@ void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *f struct aml_video_dec_buf *dstbuf = NULL; struct vframe_s *vf = (struct vframe_s *)fb->vf_handle; - aml_v4l2_debug(3, "[%d] FROM (%s %s) vf: %p, ts: %llx, idx: %d", - ctx->id, vf_get_provider(ctx->ada_ctx->recv_name)->name, + v4l_dbg(ctx, V4L_DEBUG_CODEC_OUTPUT, + "FROM (%s %s) vf: %lx, ts: %llx, idx: %d, " + "Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)\n", + vf_get_provider(ctx->ada_ctx->recv_name)->name, ctx->ada_ctx->vfm_path != FRAME_BASE_PATH_V4L_VIDEO ? "OSD" : "VIDEO", - vf, vf->timestamp, vf->index); - - aml_v4l2_debug(4, "[%d] FROM Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)", - ctx->id, fb->m.mem[0].addr, fb->m.mem[0].size, + (ulong) vf, vf->timestamp, vf->index, + fb->m.mem[0].addr, fb->m.mem[0].size, fb->m.mem[1].addr, fb->m.mem[1].size, fb->m.mem[2].addr, fb->m.mem[2].size); @@ -474,8 +536,21 @@ void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *f dstbuf->vb.vb2_buf.timestamp = vf->timestamp; dstbuf->ready_to_display = true; + if (dump_capture_frame) { + struct file *fp; + fp = filp_open("/data/dec_dump.raw", + O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600); + if (!IS_ERR(fp)) { + struct vb2_buffer *vb = &dstbuf->vb.vb2_buf; + kernel_write(fp,vb2_plane_vaddr(vb, 0),vb->planes[0].bytesused, 0); + if (dstbuf->frame_buffer.num_planes == 2) + kernel_write(fp,vb2_plane_vaddr(vb, 1), + vb->planes[1].bytesused, 0); + filp_close(fp, NULL); + } + } + if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) { - dstbuf->lastframe = true; dstbuf->vb.flags = V4L2_BUF_FLAG_LAST; if (dstbuf->frame_buffer.num_planes == 1) { vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, 0); @@ -484,16 +559,37 @@ void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *f vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, 0); } ctx->has_receive_eos = true; - pr_info("[%d] recevie a empty frame. idx: %d, state: %d\n", - ctx->id, dstbuf->vb.vb2_buf.index, + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "recevie a empty frame. idx: %d, state: %d\n", + dstbuf->vb.vb2_buf.index, dstbuf->vb.vb2_buf.state); ATRACE_COUNTER("v4l2_eos", 0); } - aml_v4l2_debug(4, "[%d] receive vbuf idx: %d, state: %d", - ctx->id, dstbuf->vb.vb2_buf.index, + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, + "receive vbuf idx: %d, state: %d\n", + dstbuf->vb.vb2_buf.index, dstbuf->vb.vb2_buf.state); + if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) { + if (ctx->q_data[AML_Q_DATA_SRC].resolution_changed) { + /* make the run to stanby until new buffs to enque. */ + ctx->v4l_codec_dpb_ready = false; + ctx->reset_flag = V4L_RESET_MODE_LIGHT; + + /* + * After all buffers containing decoded frames from + * before the resolution change point ready to be + * dequeued on the CAPTURE queue, the driver sends a + * V4L2_EVENT_SOURCE_CHANGE event for source change + * type V4L2_EVENT_SRC_CH_RESOLUTION, also the upper + * layer will get new information from cts->picinfo. + */ + aml_vdec_dispatch_event(ctx, V4L2_EVENT_SRC_CH_RESOLUTION); + } else + aml_vdec_dispatch_event(ctx, V4L2_EVENT_SEND_EOS); + } + if (dstbuf->vb.vb2_buf.state == VB2_BUF_STATE_ACTIVE) { /* binding vframe handle. */ vf->flag |= VFRAME_FLAG_VIDEO_LINEAR; @@ -510,29 +606,11 @@ void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *f ctx->has_receive_eos) { ctx->state = AML_STATE_FLUSHED; ATRACE_COUNTER("v4l2_state", ctx->state); - aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_FLUSHED)", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_FLUSHED)\n"); } mutex_unlock(&ctx->state_lock); - if (dstbuf->lastframe && - ctx->q_data[AML_Q_DATA_SRC].resolution_changed) { - - /* make the run to stanby until new buffs to enque. */ - ctx->v4l_codec_dpb_ready = false; - ctx->reset_flag = V4L_RESET_MODE_LIGHT; - - /* - * After all buffers containing decoded frames from - * before the resolution change point ready to be - * dequeued on the CAPTURE queue, the driver sends a - * V4L2_EVENT_SOURCE_CHANGE event for source change - * type V4L2_EVENT_SRC_CH_RESOLUTION, also the upper - * layer will get new information from cts->picinfo. - */ - aml_vdec_dispatch_event(ctx, V4L2_EVENT_SRC_CH_RESOLUTION); - } - ctx->decoded_frame_cnt++; } @@ -540,16 +618,18 @@ static int get_display_buffer(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffe { int ret = -1; - aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s\n", __func__); ret = vdec_if_get_param(ctx, GET_PARAM_DISP_FRAME_BUFFER, out); if (ret) { - aml_v4l2_err("[%d] Cannot get param : GET_PARAM_DISP_FRAME_BUFFER", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Cannot get param : GET_PARAM_DISP_FRAME_BUFFER\n"); return -1; } if (!*out) { - aml_v4l2_debug(4, "[%d] No display frame buffer", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "No display frame buffer\n"); return -1; } @@ -566,10 +646,10 @@ static void aml_check_dpb_ready(struct aml_vcodec_ctx *ctx) if ((ctx->dpb_size) && (ctx->cap_pool.in >= ctx->dpb_size - 4)) ctx->v4l_codec_dpb_ready = true; - aml_v4l2_debug(2, "[%d] %s() dpb: %d, ready: %d, used: %d, dpb is ready: %s", - ctx->id, __func__, ctx->dpb_size, - v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx), - ctx->cap_pool.out, ctx->v4l_codec_dpb_ready ? "yes" : "no"); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "dpb: %d, ready: %d, used: %d, dpb is ready: %s\n", + ctx->dpb_size, v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx), + ctx->cap_pool.out, ctx->v4l_codec_dpb_ready ? "yes" : "no"); } } @@ -578,8 +658,8 @@ static int is_vdec_ready(struct aml_vcodec_ctx *ctx) struct aml_vcodec_dev *dev = ctx->dev; if (!is_input_ready(ctx->ada_ctx)) { - pr_err("[%d] %s() the decoder intput has not ready.\n", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "the decoder input has not ready.\n"); v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); return 0; } @@ -589,10 +669,8 @@ static int is_vdec_ready(struct aml_vcodec_ctx *ctx) if (ctx->state == AML_STATE_PROBE) { ctx->state = AML_STATE_READY; ATRACE_COUNTER("v4l2_state", ctx->state); - ctx->v4l_codec_ready = true; - wake_up_interruptible(&ctx->wq); - aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_READY)", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_READY)\n"); } mutex_unlock(&ctx->state_lock); } @@ -603,8 +681,8 @@ static int is_vdec_ready(struct aml_vcodec_ctx *ctx) ctx->m2m_ctx->cap_q_ctx.q.streaming) { ctx->state = AML_STATE_ACTIVE; ATRACE_COUNTER("v4l2_state", ctx->state); - aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ACTIVE)", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_ACTIVE)\n"); } } mutex_unlock(&ctx->state_lock); @@ -636,7 +714,8 @@ static void aml_wait_dpb_ready(struct aml_vcodec_ctx *ctx) u32 ready_num = 0; if (time_after(jiffies, expires)) { - pr_err("the DPB state has not ready.\n"); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "the DPB state has not ready.\n"); break; } @@ -646,6 +725,30 @@ static void aml_wait_dpb_ready(struct aml_vcodec_ctx *ctx) } } +static void aml_recycle_dma_buffers(struct aml_vcodec_ctx *ctx) +{ + struct vb2_v4l2_buffer *vb; + struct aml_video_dec_buf *buf; + struct vb2_queue *q; + u32 handle; + + q = v4l2_m2m_get_vq(ctx->m2m_ctx, + V4L2_BUF_TYPE_VIDEO_OUTPUT); + + while ((handle = aml_recycle_buffer(ctx->ada_ctx))) { + int index = handle & 0xf; + + vb = to_vb2_v4l2_buffer(q->bufs[index]); + buf = container_of(vb, struct aml_video_dec_buf, vb); + v4l2_m2m_buf_done(vb, buf->error ? VB2_BUF_STATE_ERROR : + VB2_BUF_STATE_DONE); + + v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT, + "recycle buff idx: %d, vbuf: %lx\n", index, + (ulong)vb2_dma_contig_plane_dma_addr(q->bufs[index], 0)); + } +} + static void aml_vdec_worker(struct work_struct *work) { struct aml_vcodec_ctx *ctx = @@ -658,8 +761,6 @@ static void aml_vdec_worker(struct work_struct *work) struct aml_video_dec_buf *src_buf_info; struct vb2_v4l2_buffer *src_vb2_v4l2; - aml_v4l2_debug(4, "[%d] entry [%d] [%s]", ctx->id, __LINE__, __func__); - if (ctx->state < AML_STATE_INIT || ctx->state > AML_STATE_FLUSHED) { v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); @@ -667,14 +768,15 @@ static void aml_vdec_worker(struct work_struct *work) } if (!is_vdec_ready(ctx)) { - pr_err("[%d] %s() the decoder has not ready.\n", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "the decoder has not ready.\n"); goto out; } src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); if (src_buf == NULL) { - pr_err("[%d] src_buf empty!\n", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "src_buf empty.\n"); goto out; } @@ -687,7 +789,8 @@ static void aml_vdec_worker(struct work_struct *work) if (src_buf_info->lastframe) { /*the empty data use to flushed the decoder.*/ - aml_v4l2_debug(2, "[%d] Got empty flush input buffer.", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "Got empty flush input buffer.\n"); /* * when inputs a small amount of src buff, then soon to @@ -702,8 +805,8 @@ static void aml_vdec_worker(struct work_struct *work) if (ctx->state == AML_STATE_ACTIVE) { ctx->state = AML_STATE_FLUSHING;// prepare flushing ATRACE_COUNTER("v4l2_state", ctx->state); - aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_FLUSHING-LASTFRM)", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_FLUSHING-LASTFRM)\n"); } mutex_unlock(&ctx->state_lock); @@ -716,25 +819,28 @@ static void aml_vdec_worker(struct work_struct *work) goto out; } - buf.vaddr = vb2_plane_vaddr(src_buf, 0); - buf.dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0); + buf.index = src_buf->index; + buf.vaddr = vb2_plane_vaddr(src_buf, 0); + buf.addr = vb2_dma_contig_plane_dma_addr(src_buf, 0); + buf.size = src_buf->planes[0].bytesused; + buf.model = src_buf->memory; - buf.size = src_buf->planes[0].bytesused; - if (!buf.vaddr) { + if (!buf.vaddr && !buf.addr) { v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); - aml_v4l2_err("[%d] id=%d src_addr is NULL!!", - ctx->id, src_buf->index); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "id=%d src_addr is NULL.\n", src_buf->index); goto out; } src_buf_info->used = true; - /* pr_err("%s() [%d], size: 0x%zx, crc: 0x%x\n", - __func__, __LINE__, buf.size, crc32(0, buf.va, buf.size));*/ + /* v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, + "size: 0x%zx, crc: 0x%x\n", + buf.size, crc32(0, buf.va, buf.size));*/ /* pts = (time / 10e6) * (90k / fps) */ - aml_v4l2_debug(4, "[%d] %s() timestamp: 0x%llx", ctx->id , __func__, - src_buf->timestamp); + /*v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, + "timestamp: 0x%llx\n", src_buf->timestamp);*/ ret = vdec_if_decode(ctx, &buf, src_buf->timestamp, &res_chg); if (ret > 0) { @@ -742,14 +848,23 @@ static void aml_vdec_worker(struct work_struct *work) * we only return src buffer with VB2_BUF_STATE_DONE * when decode success without resolution change. */ - src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); - v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_DONE); + v4l2_m2m_src_buf_remove(ctx->m2m_ctx); + + if (ctx->is_drm_mode && buf.model == VB2_MEMORY_DMABUF) + aml_recycle_dma_buffers(ctx); + else + v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_DONE); } else if (ret && ret != -EAGAIN) { src_buf_info->error = (ret == -EIO ? true : false); - src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); - v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_ERROR); - aml_v4l2_err("[%d] %s() error processing src data. %d.", - ctx->id, __func__, ret); + v4l2_m2m_src_buf_remove(ctx->m2m_ctx); + + if (ctx->is_drm_mode && buf.model == VB2_MEMORY_DMABUF) + aml_recycle_dma_buffers(ctx); + else + v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_ERROR); + + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "error processing src data. %d.\n", ret); } else if (res_chg) { /* wait the DPB state to be ready. */ aml_wait_dpb_ready(ctx); @@ -766,13 +881,15 @@ static void aml_vdec_worker(struct work_struct *work) if (ctx->state == AML_STATE_ACTIVE) { ctx->state = AML_STATE_FLUSHING;// prepare flushing ATRACE_COUNTER("v4l2_state", ctx->state); - aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_FLUSHING-RESCHG)", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_FLUSHING-RESCHG)\n"); } mutex_unlock(&ctx->state_lock); ctx->q_data[AML_Q_DATA_SRC].resolution_changed = true; - v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx); + while (ctx->m2m_ctx->job_flags & TRANS_RUNNING) { + v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx); + } aml_vdec_flush_decoder(ctx); @@ -787,28 +904,29 @@ out: static void aml_vdec_reset(struct aml_vcodec_ctx *ctx) { if (ctx->state == AML_STATE_ABORT) { - pr_err("[%d] %s() the decoder will be exited.\n", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "the decoder will be exited.\n"); goto out; } if (aml_codec_reset(ctx->ada_ctx, &ctx->reset_flag)) { ctx->state = AML_STATE_ABORT; ATRACE_COUNTER("v4l2_state", ctx->state); - aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_ABORT).\n"); goto out; } if (ctx->state == AML_STATE_RESET) { ctx->state = AML_STATE_PROBE; ATRACE_COUNTER("v4l2_state", ctx->state); - aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_PROBE)", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_PROBE)\n"); - aml_v4l2_debug(0, "[%d] %s() dpb: %d, ready: %d, used: %d", - ctx->id, __func__, ctx->dpb_size, - v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx), ctx->buf_used_count); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "dpb: %d, ready: %d, used: %d\n", ctx->dpb_size, + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx), + ctx->buf_used_count); /* vdec has ready to decode subsequence data of new resolution. */ ctx->q_data[AML_Q_DATA_SRC].resolution_changed = false; @@ -824,18 +942,22 @@ void wait_vcodec_ending(struct aml_vcodec_ctx *ctx) { struct aml_vcodec_dev *dev = ctx->dev; - /* pause inject output data to vdec. */ - v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx); + /* disable queue output item to worker. */ + ctx->output_thread_ready = false; - /* flush worker. */ + /* flush output buffer worker. */ flush_workqueue(dev->decode_workqueue); - ctx->v4l_codec_ready = false; - ctx->v4l_codec_dpb_ready = false; - - /* stop decoder. */ + /* clean output cache and decoder status . */ if (ctx->state > AML_STATE_INIT) aml_vdec_reset(ctx); + + /* pause the job and clean trans status. */ + while (ctx->m2m_ctx->job_flags & TRANS_RUNNING) { + v4l2_m2m_job_pause(ctx->dev->m2m_dev_dec, ctx->m2m_ctx); + } + + ctx->v4l_codec_dpb_ready = false; } void try_to_capture(struct aml_vcodec_ctx *ctx) @@ -845,8 +967,8 @@ void try_to_capture(struct aml_vcodec_ctx *ctx) ret = get_display_buffer(ctx, &fb); if (ret) { - aml_v4l2_debug(4, "[%d] %s() [%d], the que have no disp buf,ret: %d", - ctx->id, __func__, __LINE__, ret); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "the que have no disp buf,ret: %d\n", ret); return; } @@ -866,8 +988,8 @@ static int vdec_thread(void *data) sched_setscheduler(current, SCHED_FIFO, ¶m); for (;;) { - aml_v4l2_debug(3, "[%d] %s() state: %d", ctx->id, - __func__, ctx->state); + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, + "%s, state: %d\n", __func__, ctx->state); if (down_interruptible(&thread->sem)) break; @@ -892,6 +1014,7 @@ void aml_thread_notify(struct aml_vcodec_ctx *ctx, { struct aml_vdec_thread *thread = NULL; + mutex_lock(&ctx->lock); list_for_each_entry(thread, &ctx->vdec_thread_list, node) { if (thread->task == NULL) continue; @@ -899,6 +1022,7 @@ void aml_thread_notify(struct aml_vcodec_ctx *ctx, if (thread->type == type) up(&thread->sem); } + mutex_unlock(&ctx->lock); } EXPORT_SYMBOL_GPL(aml_thread_notify); @@ -944,7 +1068,10 @@ void aml_thread_stop(struct aml_vcodec_ctx *ctx) while (!list_empty(&ctx->vdec_thread_list)) { thread = list_entry(ctx->vdec_thread_list.next, struct aml_vdec_thread, node); + mutex_lock(&ctx->lock); list_del(&thread->node); + mutex_unlock(&ctx->lock); + thread->stop = true; up(&thread->sem); kthread_stop(thread->task); @@ -957,11 +1084,17 @@ EXPORT_SYMBOL_GPL(aml_thread_stop); static int vidioc_try_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd) { + struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); + + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, cmd: %u\n", __func__, cmd->cmd); + switch (cmd->cmd) { case V4L2_DEC_CMD_STOP: case V4L2_DEC_CMD_START: if (cmd->flags != 0) { - aml_v4l2_err("cmd->flags=%u", cmd->flags); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "cmd->flags=%u\n", cmd->flags); return -EINVAL; } break; @@ -979,15 +1112,16 @@ static int vidioc_decoder_cmd(struct file *file, void *priv, struct vb2_queue *src_vq, *dst_vq; int ret; + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, cmd: %u\n", __func__, cmd->cmd); + ret = vidioc_try_decoder_cmd(file, priv, cmd); if (ret) return ret; - aml_v4l2_debug(2, "[%d] %s() [%d], cmd: %u", - ctx->id, __func__, __LINE__, cmd->cmd); dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, - multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : - V4L2_BUF_TYPE_VIDEO_CAPTURE); + multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : + V4L2_BUF_TYPE_VIDEO_CAPTURE); switch (cmd->cmd) { case V4L2_DEC_CMD_STOP: ATRACE_COUNTER("v4l2_stop", 0); @@ -997,8 +1131,8 @@ static int vidioc_decoder_cmd(struct file *file, void *priv, ctx->state = AML_STATE_ABORT; ATRACE_COUNTER("v4l2_state", ctx->state); aml_vdec_dispatch_event(ctx, V4L2_EVENT_REQUEST_EXIT); - aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_ABORT)\n"); return 0; } } @@ -1006,12 +1140,14 @@ static int vidioc_decoder_cmd(struct file *file, void *priv, src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); if (!vb2_is_streaming(src_vq)) { - pr_err("[%d] Output stream is off. No need to flush.\n", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Output stream is off. No need to flush.\n"); return 0; } if (!vb2_is_streaming(dst_vq)) { - pr_err("[%d] Capture stream is off. No need to flush.\n", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Capture stream is off. No need to flush.\n"); return 0; } @@ -1022,7 +1158,7 @@ static int vidioc_decoder_cmd(struct file *file, void *priv, break; case V4L2_DEC_CMD_START: - aml_v4l2_debug(4, "[%d] CMD V4L2_DEC_CMD_START ", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "CMD V4L2_DEC_CMD_START\n"); vb2_clear_last_buffer_dequeued(dst_vq);//pay attention break; @@ -1050,11 +1186,10 @@ static int vidioc_decoder_streamon(struct file *file, void *priv, (ctx->reset_flag == V4L_RESET_MODE_LIGHT)) { ctx->state = AML_STATE_RESET; ATRACE_COUNTER("v4l2_state", ctx->state); - ctx->v4l_codec_ready = false; ctx->v4l_codec_dpb_ready = false; - aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_RESET)", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_RESET)\n"); aml_vdec_reset(ctx); } mutex_unlock(&ctx->state_lock); @@ -1062,6 +1197,10 @@ static int vidioc_decoder_streamon(struct file *file, void *priv, ctx->is_stream_off = false; } } + + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %d\n", __func__, q->type); + return v4l2_m2m_ioctl_streamon(file, priv, i); } @@ -1077,12 +1216,16 @@ static int vidioc_decoder_streamoff(struct file *file, void *priv, ctx->is_stream_off = true; } + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %d\n", __func__, q->type); + return v4l2_m2m_ioctl_streamoff(file, priv, i); } static int vidioc_decoder_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *rb) { + struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); struct v4l2_fh *fh = file->private_data; struct vb2_queue *q; @@ -1091,9 +1234,45 @@ static int vidioc_decoder_reqbufs(struct file *file, void *priv, if (!rb->count) vb2_queue_release(q); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %d, count: %d\n", + __func__, q->type, rb->count); + + if (!V4L2_TYPE_IS_OUTPUT(rb->type)) { + /* driver needs match v4l buffer number with dpb_size */ + if (rb->count > ctx->dpb_size) { + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "reqbufs (st:%d) %d -> %d\n", + ctx->state, rb->count, ctx->dpb_size); + //rb->count = ctx->dpb_size; + } + } + return v4l2_m2m_ioctl_reqbufs(file, priv, rb); } +static int vidioc_vdec_querybuf(struct file *file, void *priv, + struct v4l2_buffer *buf) +{ + struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); + + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %d\n", __func__, buf->type); + + return v4l2_m2m_ioctl_querybuf(file, priv, buf); +} + +static int vidioc_vdec_expbuf(struct file *file, void *priv, + struct v4l2_exportbuffer *eb) +{ + struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); + + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %d\n", __func__, eb->type); + + return v4l2_m2m_ioctl_expbuf(file, priv, eb); +} + void aml_vcodec_dec_release(struct aml_vcodec_ctx *ctx) { ulong flags; @@ -1101,8 +1280,8 @@ void aml_vcodec_dec_release(struct aml_vcodec_ctx *ctx) flags = aml_vcodec_ctx_lock(ctx); ctx->state = AML_STATE_ABORT; ATRACE_COUNTER("v4l2_state", ctx->state); - aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_ABORT)\n"); aml_vcodec_ctx_unlock(ctx, flags); vdec_if_deinit(ctx); @@ -1156,20 +1335,23 @@ void aml_vcodec_dec_set_default_params(struct aml_vcodec_ctx *ctx) ctx->state = AML_STATE_IDLE; ATRACE_COUNTER("v4l2_state", ctx->state); - aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_IDLE)", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_IDLE)\n"); } static int vidioc_vdec_qbuf(struct file *file, void *priv, - struct v4l2_buffer *buf) + struct v4l2_buffer *buf) { struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); int ret; + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %d\n", __func__, buf->type); + if (ctx->state == AML_STATE_ABORT) { - aml_v4l2_err("[%d] Call on QBUF after unrecoverable error, type = %s", - ctx->id, V4L2_TYPE_IS_OUTPUT(buf->type) ? - "OUT" : "IN"); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Call on QBUF after unrecoverable error, type = %s\n", + V4L2_TYPE_IS_OUTPUT(buf->type) ? "OUT" : "IN"); return -EIO; } @@ -1185,15 +1367,18 @@ static int vidioc_vdec_qbuf(struct file *file, void *priv, } static int vidioc_vdec_dqbuf(struct file *file, void *priv, - struct v4l2_buffer *buf) + struct v4l2_buffer *buf) { struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); int ret; + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %d\n", __func__, buf->type); + if (ctx->state == AML_STATE_ABORT) { - aml_v4l2_err("[%d] Call on DQBUF after unrecoverable error, type = %s", - ctx->id, V4L2_TYPE_IS_OUTPUT(buf->type) ? - "OUT" : "IN"); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Call on DQBUF after unrecoverable error, type = %s\n", + V4L2_TYPE_IS_OUTPUT(buf->type) ? "OUT" : "IN"); if (!V4L2_TYPE_IS_OUTPUT(buf->type)) return -EIO; } @@ -1204,7 +1389,7 @@ static int vidioc_vdec_dqbuf(struct file *file, void *priv, ATRACE_COUNTER("v4l2_dqin_eagain", 0); else ATRACE_COUNTER("v4l2_dqin_ok", 0); - } else if (!V4L2_TYPE_IS_OUTPUT(buf->type)) { + } else { if (ret == -EAGAIN) ATRACE_COUNTER("v4l2_dqout_eagain", 0); } @@ -1215,10 +1400,15 @@ static int vidioc_vdec_dqbuf(struct file *file, void *priv, struct aml_video_dec_buf *aml_buf = NULL; struct file *file = NULL; - mutex_lock(&ctx->lock); + if (ctx->is_drm_mode && ctx->output_dma_mode) + aml_recycle_dma_buffers(ctx); + vq = v4l2_m2m_get_vq(ctx->m2m_ctx, buf->type); vb2_v4l2 = to_vb2_v4l2_buffer(vq->bufs[buf->index]); aml_buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb); + aml_buf->privdata.v4l_dev_handle = (ulong) ctx->dev; + aml_buf->privdata.v4l_inst_handle = (ulong) ctx; + aml_buf->privdata.v4l_inst_id = ctx->id; file = fget(vb2_v4l2->private); if (is_v4l2_buf_file(file)) { @@ -1226,30 +1416,38 @@ static int vidioc_vdec_dqbuf(struct file *file, void *priv, (void*)&aml_buf->privdata, sizeof(struct file_private_data)); ATRACE_COUNTER("v4l2_dqout_ok", aml_buf->privdata.vf.index_disp); - aml_v4l2_debug(4, "[%d] %s, disp: %d, vf: %p\n", ctx->id, - __func__, aml_buf->privdata.vf.index_disp, - v4l_get_vf_handle(vb2_v4l2->private)); + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "disp: %d, vf: %lx\n", + aml_buf->privdata.vf.index_disp, + (ulong) v4l_get_vf_handle(vb2_v4l2->private)); } fput(file); - mutex_unlock(&ctx->lock); } return ret; } static int vidioc_vdec_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) + struct v4l2_capability *cap) { + struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); + strlcpy(cap->driver, AML_VCODEC_DEC_NAME, sizeof(cap->driver)); strlcpy(cap->bus_info, AML_PLATFORM_STR, sizeof(cap->bus_info)); strlcpy(cap->card, AML_PLATFORM_STR, sizeof(cap->card)); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, %s\n", __func__, cap->card); + return 0; } static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub) + const struct v4l2_event_subscription *sub) { + struct aml_vcodec_ctx *ctx = fh_to_ctx(fh); + + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %d\n", __func__, sub->type); + switch (sub->type) { case V4L2_EVENT_EOS: return v4l2_event_subscribe(fh, sub, 2, NULL); @@ -1260,6 +1458,17 @@ static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh, } } +static int vidioc_vdec_event_unsubscribe(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + struct aml_vcodec_ctx *ctx = fh_to_ctx(fh); + + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d\n", + __func__, sub->type); + + return v4l2_event_unsubscribe(fh, sub); +} + static int vidioc_try_fmt(struct v4l2_format *f, struct aml_video_fmt *fmt) { struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; @@ -1302,12 +1511,6 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct aml_video_fmt *fmt) (pix_fmt_mp->height + 64) <= AML_VDEC_MAX_H) pix_fmt_mp->height += 64; - aml_v4l2_debug(4, - "before resize width=%d, height=%d, after resize width=%d, height=%d, sizeimage=%d", - tmp_w, tmp_h, pix_fmt_mp->width, - pix_fmt_mp->height, - pix_fmt_mp->width * pix_fmt_mp->height); - pix_fmt_mp->num_planes = fmt->num_planes; pix_fmt_mp->plane_fmt[0].sizeimage = pix_fmt_mp->width * pix_fmt_mp->height; @@ -1334,6 +1537,12 @@ static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv, struct v4l2_format *f) { struct aml_video_fmt *fmt = NULL; + struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); + + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %u, planes: %u, fmt: %u\n", + __func__, f->type, f->fmt.pix_mp.num_planes, + f->fmt.pix_mp.pixelformat); fmt = aml_vdec_find_format(f); if (!fmt) @@ -1347,13 +1556,20 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, { struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; struct aml_video_fmt *fmt = NULL; + struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); + + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %u, planes: %u, fmt: %u\n", + __func__, f->type, f->fmt.pix_mp.num_planes, + f->fmt.pix_mp.pixelformat); fmt = aml_vdec_find_format(f); if (!fmt) return -EINVAL; if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) { - aml_v4l2_err("sizeimage of output format must be given"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "sizeimage of output format must be given\n"); return -EINVAL; } @@ -1361,7 +1577,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, } static int vidioc_vdec_g_selection(struct file *file, void *priv, - struct v4l2_selection *s) + struct v4l2_selection *s) { struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); struct aml_q_data *q_data; @@ -1403,17 +1619,22 @@ static int vidioc_vdec_g_selection(struct file *file, void *priv, s->r.top = 0; s->r.width = q_data->visible_width; s->r.height = q_data->visible_height; - return 0; } + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d\n", + __func__, s->type); + return 0; } static int vidioc_vdec_s_selection(struct file *file, void *priv, - struct v4l2_selection *s) + struct v4l2_selection *s) { struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d\n", + __func__, s->type); + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1432,7 +1653,7 @@ static int vidioc_vdec_s_selection(struct file *file, void *priv, } static int vidioc_vdec_s_fmt(struct file *file, void *priv, - struct v4l2_format *f) + struct v4l2_format *f) { struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); struct v4l2_pix_format_mplane *pix_mp; @@ -1440,7 +1661,10 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, int ret = 0; struct aml_video_fmt *fmt; - aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %u, planes: %u, fmt: %u\n", + __func__, f->type, f->fmt.pix_mp.num_planes, + f->fmt.pix_mp.pixelformat); q_data = aml_vdec_get_q_data(ctx, f->type); if (!q_data) @@ -1449,12 +1673,14 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, pix_mp = &f->fmt.pix_mp; if ((f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) && vb2_is_busy(&ctx->m2m_ctx->out_q_ctx.q)) { - aml_v4l2_err("[%d] out_q_ctx buffers already requested", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "out_q_ctx buffers already requested\n"); } if ((!V4L2_TYPE_IS_OUTPUT(f->type)) && vb2_is_busy(&ctx->m2m_ctx->cap_q_ctx.q)) { - aml_v4l2_err("[%d] cap_q_ctx buffers already requested", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "cap_q_ctx buffers already requested\n"); } fmt = aml_vdec_find_format(f); @@ -1473,12 +1699,15 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, q_data->fmt = fmt; vidioc_try_fmt(f, q_data->fmt); if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + if (ctx->is_drm_mode) + pix_mp->plane_fmt[0].sizeimage = 1; q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; q_data->coded_width = pix_mp->width; q_data->coded_height = pix_mp->height; - aml_v4l2_debug(4, "[%d] %s() [%d], w: %d, h: %d, size: %d", - ctx->id, __func__, __LINE__, pix_mp->width, pix_mp->height, + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, + "w: %d, h: %d, size: %d\n", + pix_mp->width, pix_mp->height, pix_mp->plane_fmt[0].sizeimage); ctx->colorspace = f->fmt.pix_mp.colorspace; @@ -1490,19 +1719,22 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, if (ctx->state == AML_STATE_IDLE) { ret = vdec_if_init(ctx, q_data->fmt->fourcc); if (ret) { - aml_v4l2_err("[%d]: vdec_if_init() fail ret=%d", - ctx->id, ret); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "vdec_if_init() fail ret=%d\n", ret); mutex_unlock(&ctx->state_lock); return -EINVAL; } ctx->state = AML_STATE_INIT; ATRACE_COUNTER("v4l2_state", ctx->state); - aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_INIT)", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_INIT)\n"); } mutex_unlock(&ctx->state_lock); } + if (!V4L2_TYPE_IS_OUTPUT(f->type)) + ctx->cap_pix_fmt = pix_mp->pixelformat; + return 0; } @@ -1512,6 +1744,9 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, int i = 0; struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, idx: %d, pix fmt: %x\n", + __func__, fsize->index, fsize->pixel_format); + if (fsize->index != 0) return -EINVAL; @@ -1523,20 +1758,21 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, fsize->stepwise = aml_vdec_framesizes[i].stepwise; if (!(ctx->dev->dec_capability & VCODEC_CAPABILITY_4K_DISABLED)) { - aml_v4l2_debug(4, "[%d] 4K is enabled", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "4K is enabled\n"); fsize->stepwise.max_width = VCODEC_DEC_4K_CODED_WIDTH; fsize->stepwise.max_height = VCODEC_DEC_4K_CODED_HEIGHT; } - aml_v4l2_debug(4, "[%d] %x, %d %d %d %d %d %d", - ctx->id, ctx->dev->dec_capability, - fsize->stepwise.min_width, - fsize->stepwise.max_width, - fsize->stepwise.step_width, - fsize->stepwise.min_height, - fsize->stepwise.max_height, - fsize->stepwise.step_height); + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, + "%x, %d %d %d %d %d %d\n", + ctx->dev->dec_capability, + fsize->stepwise.min_width, + fsize->stepwise.max_width, + fsize->stepwise.step_width, + fsize->stepwise.min_height, + fsize->stepwise.max_height, + fsize->stepwise.step_height); return 0; } @@ -1565,20 +1801,28 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue) return -EINVAL; } -static int vidioc_vdec_enum_fmt_vid_cap_mplane(struct file *file, void *pirv, - struct v4l2_fmtdesc *f) +static int vidioc_vdec_enum_fmt_vid_cap_mplane(struct file *file, + void *priv, struct v4l2_fmtdesc *f) { + struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); + + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s\n", __func__); + return vidioc_enum_fmt(f, false); } -static int vidioc_vdec_enum_fmt_vid_out_mplane(struct file *file, void *priv, - struct v4l2_fmtdesc *f) +static int vidioc_vdec_enum_fmt_vid_out_mplane(struct file *file, + void *priv, struct v4l2_fmtdesc *f) { + struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); + + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s\n", __func__); + return vidioc_enum_fmt(f, true); } static int vidioc_vdec_g_fmt(struct file *file, void *priv, - struct v4l2_format *f) + struct v4l2_format *f) { struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; @@ -1587,7 +1831,8 @@ static int vidioc_vdec_g_fmt(struct file *file, void *priv, vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); if (!vq) { - aml_v4l2_err("[%d] no vb2 queue for type=%d", ctx->id, f->type); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "no vb2 queue for type=%d\n", f->type); return -EINVAL; } @@ -1660,21 +1905,44 @@ static int vidioc_vdec_g_fmt(struct file *file, void *priv, pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1]; pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1]; - aml_v4l2_debug(4, "[%d] type=%d state=%d Format information could not be read, not ready yet!", - ctx->id, f->type, ctx->state); + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, + "type=%d state=%d Format information could not be read, not ready yet!\n", + f->type, ctx->state); return -EINVAL; } + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %u, planes: %u, fmt: %u\n", + __func__, f->type, f->fmt.pix_mp.num_planes, + f->fmt.pix_mp.pixelformat); + return 0; } +static int vidioc_vdec_create_bufs(struct file *file, void *priv, + struct v4l2_create_buffers *create) +{ + struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); + + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %u, count: %u\n", + __func__, create->format.type, create->count); + + return v4l2_m2m_ioctl_create_bufs(file, priv, create); +} + /*int vidioc_vdec_g_ctrl(struct file *file, void *fh, struct v4l2_control *a) { struct aml_vcodec_ctx *ctx = fh_to_ctx(fh); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, id: %d\n", __func__, a->id); + if (a->id == V4L2_CID_MIN_BUFFERS_FOR_CAPTURE) - a->value = 20; + a->value = 4; + else if (a->id == V4L2_CID_MIN_BUFFERS_FOR_OUTPUT) + a->value = 8; return 0; }*/ @@ -1688,10 +1956,13 @@ static int vb2ops_vdec_queue_setup(struct vb2_queue *vq, struct aml_q_data *q_data; unsigned int i; - q_data = aml_vdec_get_q_data(ctx, vq->type); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d\n", + __func__, vq->type); + q_data = aml_vdec_get_q_data(ctx, vq->type); if (q_data == NULL) { - aml_v4l2_err("[%d] vq->type=%d err", ctx->id, vq->type); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "vq->type=%d err\n", vq->type); return -EINVAL; } @@ -1715,8 +1986,9 @@ static int vb2ops_vdec_queue_setup(struct vb2_queue *vq, } } - pr_info("[%d] type: %d, plane: %d, buf cnt: %d, size: [Y: %u, C: %u]\n", - ctx->id, vq->type, *nplanes, *nbuffers, sizes[0], sizes[1]); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "type: %d, plane: %d, buf cnt: %d, size: [Y: %u, C: %u]\n", + vq->type, *nplanes, *nbuffers, sizes[0], sizes[1]); return 0; } @@ -1727,15 +1999,17 @@ static int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb) struct aml_q_data *q_data; int i; - aml_v4l2_debug(4, "[%d] (%d) id=%d", - ctx->id, vb->vb2_queue->type, vb->index); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %d, idx: %d\n", + __func__, vb->vb2_queue->type, vb->index); q_data = aml_vdec_get_q_data(ctx, vb->vb2_queue->type); for (i = 0; i < q_data->fmt->num_planes; i++) { if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) { - aml_v4l2_err("[%d] data will not fit into plane %d (%lu < %d)", - ctx->id, i, vb2_plane_size(vb, i), + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "data will not fit into plane %d (%lu < %d)\n", + i, vb2_plane_size(vb, i), q_data->sizeimage[i]); } } @@ -1754,26 +2028,31 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) vb2_v4l2 = to_vb2_v4l2_buffer(vb); buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb); - aml_v4l2_debug(3, "[%d] %s(), vb: %p, type: %d, idx: %d, state: %d, used: %d", - ctx->id, __func__, vb, vb->vb2_queue->type, + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, vb: %lx, type: %d, idx: %d, state: %d, used: %d\n", + __func__, (ulong) vb, vb->vb2_queue->type, vb->index, vb->state, buf->used); /* * check if this buffer is ready to be used after decode */ if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { - aml_v4l2_debug(3, "[%d] %s() [%d], y_addr: %lx, vf_h: %lx, state: %d", ctx->id, - __func__, __LINE__, buf->frame_buffer.m.mem[0].addr, - buf->frame_buffer.vf_handle, buf->frame_buffer.status); - if (vb->index >= ctx->dpb_size) { - aml_v4l2_debug(2, "[%d] enque capture buf idx %d is invalid.", - ctx->id, vb->index); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "enque capture buf idx %d/%d is invalid.\n", + vb->index, ctx->dpb_size); return; } + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, + "y_addr: %lx, vf_h: %lx, state: %d", + buf->frame_buffer.m.mem[0].addr, + buf->frame_buffer.vf_handle, + buf->frame_buffer.status); + if (!buf->que_in_m2m) { - aml_v4l2_debug(2, "[%d] enque capture buf idx %d, vf: %p", - ctx->id, vb->index, v4l_get_vf_handle(vb2_v4l2->private)); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "enque capture buf idx %d, vf: %lx\n", + vb->index, (ulong) v4l_get_vf_handle(vb2_v4l2->private)); v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2); buf->que_in_m2m = true; @@ -1800,8 +2079,6 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb)); if (ctx->state != AML_STATE_INIT) { - aml_v4l2_debug(4, "[%d] already init driver %d", - ctx->id, ctx->state); return; } @@ -1809,27 +2086,52 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb); if (buf->lastframe) { /* This shouldn't happen. Just in case. */ - aml_v4l2_err("[%d] Invalid flush buffer.", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Invalid flush buffer.\n"); v4l2_m2m_src_buf_remove(ctx->m2m_ctx); return; } - src_mem.vaddr = vb2_plane_vaddr(vb, 0); - src_mem.dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0); - src_mem.size = vb->planes[0].bytesused; + src_mem.index = vb->index; + src_mem.vaddr = vb2_plane_vaddr(vb, 0); + src_mem.addr = vb2_dma_contig_plane_dma_addr(vb, 0); + src_mem.size = vb->planes[0].bytesused; + src_mem.model = vb->memory; + + if (vb->memory == VB2_MEMORY_DMABUF) { + v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT, + "%s, output_dma_mode set", __func__); + ctx->output_dma_mode = true; + } + if (vdec_if_probe(ctx, &src_mem, NULL)) { v4l2_m2m_src_buf_remove(ctx->m2m_ctx); - v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb), VB2_BUF_STATE_DONE); + + if (ctx->is_drm_mode && src_mem.model == VB2_MEMORY_DMABUF) + aml_recycle_dma_buffers(ctx); + else + v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb), VB2_BUF_STATE_DONE); return; } + /* + * If on model dmabuf must remove the buffer + * because this data has been consumed by hw. + */ + if (ctx->is_drm_mode && src_mem.model == VB2_MEMORY_DMABUF) { + v4l2_m2m_src_buf_remove(ctx->m2m_ctx); + aml_recycle_dma_buffers(ctx); + } + if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo)) { - pr_err("[%d] GET_PARAM_PICTURE_INFO err\n", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "GET_PARAM_PICTURE_INFO err\n"); return; } if (vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpb)) { - pr_err("[%d] GET_PARAM_DPB_SIZE err\n", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "GET_PARAM_DPB_SIZE err\n"); return; } @@ -1844,8 +2146,8 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) if (ctx->state == AML_STATE_INIT) { ctx->state = AML_STATE_PROBE; ATRACE_COUNTER("v4l2_state", ctx->state); - aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_PROBE)", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_PROBE)\n"); } mutex_unlock(&ctx->state_lock); } @@ -1857,6 +2159,10 @@ static void vb2ops_vdec_buf_finish(struct vb2_buffer *vb) struct aml_video_dec_buf *buf = NULL; bool buf_error; + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %d, idx: %d\n", + __func__, vb->vb2_queue->type, vb->index); + vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf); buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb); @@ -1867,11 +2173,12 @@ static void vb2ops_vdec_buf_finish(struct vb2_buffer *vb) buf_error = buf->error; if (buf_error) { - aml_v4l2_err("[%d] Unrecoverable error on buffer.", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Unrecoverable error on buffer.\n"); ctx->state = AML_STATE_ABORT; ATRACE_COUNTER("v4l2_state", ctx->state); - aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)", - ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_ABORT)\n"); } } @@ -1885,8 +2192,8 @@ static int vb2ops_vdec_buf_init(struct vb2_buffer *vb) unsigned int size, phy_addr = 0; char *owner = __getname(); - aml_v4l2_debug(4, "[%d] (%d) id=%d", - ctx->id, vb->vb2_queue->type, vb->index); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d, idx: %d\n", + __func__, vb->vb2_queue->type, vb->index); if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { buf->used = false; @@ -1899,16 +2206,19 @@ static int vb2ops_vdec_buf_init(struct vb2_buffer *vb) /* codec_mm buffers count */ if (V4L2_TYPE_IS_OUTPUT(vb->type)) { - size = vb->planes[0].length; - phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0); - snprintf(owner, PATH_MAX, "%s-%d", "v4l-input", ctx->id); - strncpy(buf->mem_onwer, owner, sizeof(buf->mem_onwer)); - buf->mem_onwer[sizeof(buf->mem_onwer) - 1] = '\0'; + if (vb->memory == VB2_MEMORY_MMAP) { + size = vb->planes[0].length; + phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0); + snprintf(owner, PATH_MAX, "%s-%d", "v4l-input", ctx->id); + strncpy(buf->mem_onwer, owner, sizeof(buf->mem_onwer)); + buf->mem_onwer[sizeof(buf->mem_onwer) - 1] = '\0'; - buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer, + buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer, + phy_addr, size, vb->index); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "IN alloc, addr: %x, size: %u, idx: %u\n", phy_addr, size, vb->index); - aml_v4l2_debug(3, "[%d] IN alloc, addr: %x, size: %u, idx: %u", - ctx->id, phy_addr, size, vb->index); + } } else { snprintf(owner, PATH_MAX, "%s-%d", "v4l-output", ctx->id); strncpy(buf->mem_onwer, owner, sizeof(buf->mem_onwer)); @@ -1919,22 +2229,25 @@ static int vb2ops_vdec_buf_init(struct vb2_buffer *vb) phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0); buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer, phy_addr, size, vb->index); - aml_v4l2_debug(3, "[%d] OUT Y alloc, addr: %x, size: %u, idx: %u", - ctx->id, phy_addr, size, vb->index); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "OUT Y alloc, addr: %x, size: %u, idx: %u\n", + phy_addr, size, vb->index); } else if ((vb->memory == VB2_MEMORY_MMAP) && (vb->num_planes == 2)) { size = vb->planes[0].length; phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0); buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer, phy_addr, size, vb->index); - aml_v4l2_debug(3, "[%d] OUT Y alloc, addr: %x, size: %u, idx: %u", - ctx->id, phy_addr, size, vb->index); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "OUT Y alloc, addr: %x, size: %u, idx: %u\n", + phy_addr, size, vb->index); size = vb->planes[1].length; phy_addr = vb2_dma_contig_plane_dma_addr(vb, 1); buf->mem[1] = v4l_reqbufs_from_codec_mm(buf->mem_onwer, phy_addr, size, vb->index); - aml_v4l2_debug(3, "[%d] OUT C alloc, addr: %x, size: %u, idx: %u", - ctx->id, phy_addr, size, vb->index); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "OUT C alloc, addr: %x, size: %u, idx: %u\n", + phy_addr, size, vb->index); } } @@ -1959,8 +2272,9 @@ static void codec_mm_bufs_cnt_clean(struct vb2_queue *q) if (V4L2_TYPE_IS_OUTPUT(q->bufs[i]->type)) { v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[0]); - aml_v4l2_debug(3, "[%d] IN clean, addr: %lx, size: %u, idx: %u", - ctx->id, buf->mem[0]->phy_addr, buf->mem[0]->buffer_size, i); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "IN clean, addr: %lx, size: %u, idx: %u\n", + buf->mem[0]->phy_addr, buf->mem[0]->buffer_size, i); buf->mem[0] = NULL; continue; } @@ -1969,10 +2283,12 @@ static void codec_mm_bufs_cnt_clean(struct vb2_queue *q) v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[0]); v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[1]); - aml_v4l2_debug(3, "[%d] OUT Y clean, addr: %lx, size: %u, idx: %u", - ctx->id, buf->mem[0]->phy_addr, buf->mem[0]->buffer_size, i); - aml_v4l2_debug(3, "[%d] OUT C clean, addr: %lx, size: %u, idx: %u", - ctx->id, buf->mem[1]->phy_addr, buf->mem[1]->buffer_size, i); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "OUT Y clean, addr: %lx, size: %u, idx: %u\n", + buf->mem[0]->phy_addr, buf->mem[0]->buffer_size, i); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "OUT C clean, addr: %lx, size: %u, idx: %u\n", + buf->mem[1]->phy_addr, buf->mem[1]->buffer_size, i); buf->mem[0] = NULL; buf->mem[1] = NULL; } @@ -1986,6 +2302,9 @@ static int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count) ctx->has_receive_eos = false; v4l2_m2m_set_dst_buffered(ctx->fh.m2m_ctx, true); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %d\n", __func__, q->type); + return 0; } @@ -1996,17 +2315,22 @@ static void vb2ops_vdec_stop_streaming(struct vb2_queue *q) struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(q); int i; - aml_v4l2_debug(3, "[%d] (%d) state=(%x) frame_cnt=%d", - ctx->id, q->type, ctx->state, ctx->decoded_frame_cnt); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %d, state: %x, frame_cnt: %d\n", + __func__, q->type, ctx->state, ctx->decoded_frame_cnt); codec_mm_bufs_cnt_clean(q); if (V4L2_TYPE_IS_OUTPUT(q->type)) { while ((vb2_v4l2 = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR); + + if (ctx->is_drm_mode && q->memory == VB2_MEMORY_DMABUF) + aml_recycle_dma_buffers(ctx); } else { - /* stop decoder. */ - wait_vcodec_ending(ctx); + /* clean output cache and decoder status . */ + if (ctx->state > AML_STATE_INIT) + aml_vdec_reset(ctx); for (i = 0; i < q->num_buffers; ++i) { vb2_v4l2 = to_vb2_v4l2_buffer(q->bufs[i]); @@ -2018,10 +2342,11 @@ static void vb2ops_vdec_stop_streaming(struct vb2_queue *q) if (vb2_v4l2->vb2_buf.state == VB2_BUF_STATE_ACTIVE) v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR); - /*pr_info("idx: %d, state: %d\n", + /*v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "idx: %d, state: %d\n", q->bufs[i]->index, q->bufs[i]->state);*/ } } + ctx->buf_used_count = 0; ctx->cap_pool.in = 0; ctx->cap_pool.out = 0; @@ -2032,15 +2357,12 @@ static void m2mops_vdec_device_run(void *priv) struct aml_vcodec_ctx *ctx = priv; struct aml_vcodec_dev *dev = ctx->dev; - aml_v4l2_debug(4, "[%d] %s() [%d]", ctx->id, __func__, __LINE__); - - queue_work(dev->decode_workqueue, &ctx->decode_work); + if (ctx->output_thread_ready) + queue_work(dev->decode_workqueue, &ctx->decode_work); } void vdec_device_vf_run(struct aml_vcodec_ctx *ctx) { - aml_v4l2_debug(3, "[%d] %s() [%d]", ctx->id, __func__, __LINE__); - if (ctx->state < AML_STATE_INIT || ctx->state > AML_STATE_FLUSHED) return; @@ -2052,9 +2374,6 @@ static int m2mops_vdec_job_ready(void *m2m_priv) { struct aml_vcodec_ctx *ctx = m2m_priv; - aml_v4l2_debug(4, "[%d] %s(), state: %d", ctx->id, - __func__, ctx->state); - if (ctx->state < AML_STATE_PROBE || ctx->state > AML_STATE_FLUSHED) return 0; @@ -2066,7 +2385,7 @@ static void m2mops_vdec_job_abort(void *priv) { struct aml_vcodec_ctx *ctx = priv; - aml_v4l2_debug(3, "[%d] %s() [%d]", ctx->id, __func__, __LINE__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s\n", __func__); } static int aml_vdec_g_v_ctrl(struct v4l2_ctrl *ctrl) @@ -2074,18 +2393,23 @@ static int aml_vdec_g_v_ctrl(struct v4l2_ctrl *ctrl) struct aml_vcodec_ctx *ctx = ctrl_to_ctx(ctrl); int ret = 0; - aml_v4l2_debug(4, "%s() [%d]", __func__, __LINE__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, id: %d\n", __func__, ctrl->id); switch (ctrl->id) { case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: if (ctx->state >= AML_STATE_PROBE) { ctrl->val = ctx->dpb_size; } else { - pr_err("Seqinfo not ready.\n"); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Seqinfo not ready.\n"); ctrl->val = 0; ret = -EINVAL; } break; + case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: + ctrl->val = 4; + break; default: ret = -EINVAL; } @@ -2096,11 +2420,13 @@ static int aml_vdec_try_s_v_ctrl(struct v4l2_ctrl *ctrl) { struct aml_vcodec_ctx *ctx = ctrl_to_ctx(ctrl); - aml_v4l2_debug(4, "%s() [%d]", __func__, __LINE__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s\n", __func__); - if (ctrl->id == AML_V4L2_SET_DECMODE) { + if (ctrl->id == AML_V4L2_SET_DRMMODE) { ctx->is_drm_mode = ctrl->val; - pr_info("set stream mode: %x\n", ctrl->val); + ctx->param_sets_from_ucode = true; + v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, + "set stream mode: %x\n", ctrl->val); } return 0; @@ -2112,8 +2438,8 @@ static const struct v4l2_ctrl_ops aml_vcodec_dec_ctrl_ops = { }; static const struct v4l2_ctrl_config ctrl_st_mode = { - .name = "stream mode", - .id = AML_V4L2_SET_DECMODE, + .name = "drm mode", + .id = AML_V4L2_SET_DRMMODE, .ops = &aml_vcodec_dec_ctrl_ops, .type = V4L2_CTRL_TYPE_BOOLEAN, .flags = V4L2_CTRL_FLAG_WRITE_ONLY, @@ -2128,11 +2454,21 @@ int aml_vcodec_dec_ctrls_setup(struct aml_vcodec_ctx *ctx) int ret; struct v4l2_ctrl *ctrl; - v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 1); + v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 3); ctrl = v4l2_ctrl_new_std(&ctx->ctrl_hdl, &aml_vcodec_dec_ctrl_ops, V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, - 0, 32, 1, 1); + 0, 32, 1, 2); + ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; + if (ctx->ctrl_hdl.error) { + ret = ctx->ctrl_hdl.error; + goto err; + } + + ctrl = v4l2_ctrl_new_std(&ctx->ctrl_hdl, + &aml_vcodec_dec_ctrl_ops, + V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, + 0, 32, 1, 8); ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; if (ctx->ctrl_hdl.error) { ret = ctx->ctrl_hdl.error; @@ -2149,35 +2485,41 @@ int aml_vcodec_dec_ctrls_setup(struct aml_vcodec_ctx *ctx) return 0; err: - aml_v4l2_err("[%d] Adding control failed %d", - ctx->id, ctx->ctrl_hdl.error); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Adding control failed %d\n", + ctx->ctrl_hdl.error); v4l2_ctrl_handler_free(&ctx->ctrl_hdl); return ret; } static int vidioc_vdec_g_parm(struct file *file, void *fh, - struct v4l2_streamparm *a) + struct v4l2_streamparm *a) { struct aml_vcodec_ctx *ctx = fh_to_ctx(fh); if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { if (vdec_if_get_param(ctx, GET_PARAM_CONFIG_INFO, &ctx->config.parm.dec)) { - pr_err("[%d] GET_PARAM_CONFIG_INFO err\n", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "GET_PARAM_CONFIG_INFO err\n"); return -1; } memcpy(a->parm.raw_data, ctx->config.parm.data, sizeof(a->parm.raw_data)); } + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s\n", __func__); + return 0; } static int vidioc_vdec_s_parm(struct file *file, void *fh, - struct v4l2_streamparm *a) + struct v4l2_streamparm *a) { struct aml_vcodec_ctx *ctx = fh_to_ctx(fh); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s\n", __func__); + if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { struct aml_dec_params *in = (struct aml_dec_params *) a->parm.raw_data; @@ -2204,7 +2546,6 @@ static void m2mops_vdec_lock(void *m2m_priv) { struct aml_vcodec_ctx *ctx = m2m_priv; - aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__); mutex_lock(&ctx->dev->dev_mutex); } @@ -2212,7 +2553,6 @@ static void m2mops_vdec_unlock(void *m2m_priv) { struct aml_vcodec_ctx *ctx = m2m_priv; - aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__); mutex_unlock(&ctx->dev->dev_mutex); } @@ -2240,8 +2580,8 @@ const struct v4l2_ioctl_ops aml_vdec_ioctl_ops = { .vidioc_streamon = vidioc_decoder_streamon, .vidioc_streamoff = vidioc_decoder_streamoff, .vidioc_reqbufs = vidioc_decoder_reqbufs, - .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, - .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,//?? + .vidioc_querybuf = vidioc_vdec_querybuf, + .vidioc_expbuf = vidioc_vdec_expbuf, //.vidioc_g_ctrl = vidioc_vdec_g_ctrl, .vidioc_qbuf = vidioc_vdec_qbuf, @@ -2261,7 +2601,7 @@ const struct v4l2_ioctl_ops aml_vdec_ioctl_ops = { .vidioc_g_fmt_vid_out_mplane = vidioc_vdec_g_fmt, .vidioc_g_fmt_vid_out = vidioc_vdec_g_fmt, - .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, + .vidioc_create_bufs = vidioc_vdec_create_bufs, .vidioc_enum_fmt_vid_cap_mplane = vidioc_vdec_enum_fmt_vid_cap_mplane, .vidioc_enum_fmt_vid_cap = vidioc_vdec_enum_fmt_vid_cap_mplane, @@ -2271,7 +2611,7 @@ const struct v4l2_ioctl_ops aml_vdec_ioctl_ops = { .vidioc_querycap = vidioc_vdec_querycap, .vidioc_subscribe_event = vidioc_vdec_subscribe_evt, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + .vidioc_unsubscribe_event = vidioc_vdec_event_unsubscribe, .vidioc_g_selection = vidioc_vdec_g_selection, .vidioc_s_selection = vidioc_vdec_s_selection, @@ -2288,7 +2628,7 @@ int aml_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq, struct aml_vcodec_ctx *ctx = priv; int ret = 0; - aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__); + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s\n", __func__); src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; src_vq->io_modes = VB2_DMABUF | VB2_MMAP; @@ -2300,7 +2640,8 @@ int aml_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq, src_vq->lock = &ctx->dev->dev_mutex; ret = vb2_queue_init(src_vq); if (ret) { - aml_v4l2_err("[%d] Failed to initialize videobuf2 queue(output)", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Failed to initialize videobuf2 queue(output)\n"); return ret; } @@ -2316,7 +2657,8 @@ int aml_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq, ret = vb2_queue_init(dst_vq); if (ret) { vb2_queue_release(src_vq); - aml_v4l2_err("[%d] Failed to initialize videobuf2 queue(capture)", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Failed to initialize videobuf2 queue(capture)\n"); } return ret; diff --git a/drivers/amvdec_ports/aml_vcodec_dec.h b/drivers/amvdec_ports/aml_vcodec_dec.h index 68f878a..3406e9f 100644 --- a/drivers/amvdec_ports/aml_vcodec_dec.h +++ b/drivers/amvdec_ports/aml_vcodec_dec.h @@ -38,8 +38,6 @@ #define VDEC_GATHER_MEMORY_TYPE 0 #define VDEC_SCATTER_MEMORY_TYPE 1 -#define AML_V4L2_SET_DECMODE (V4L2_CID_USER_AMLOGIC_BASE + 0) - /** * struct vdec_fb - decoder frame buffer * @mem_type : gather or scatter memory. diff --git a/drivers/amvdec_ports/aml_vcodec_dec_drv.c b/drivers/amvdec_ports/aml_vcodec_dec_drv.c index 43ff0c5..7758ca8 100644 --- a/drivers/amvdec_ports/aml_vcodec_dec_drv.c +++ b/drivers/amvdec_ports/aml_vcodec_dec_drv.c @@ -32,7 +32,6 @@ #include "aml_vcodec_drv.h" #include "aml_vcodec_dec.h" -#include "aml_vcodec_dec_pm.h" #include "aml_vcodec_util.h" #include "aml_vcodec_vfm.h" #include @@ -49,8 +48,8 @@ #define V4LVIDEO_IOCTL_SET_CONFIG_PARAMS _IOWR(V4LVIDEO_IOC_MAGIC, 0x04, struct v4l2_config_parm) #define V4LVIDEO_IOCTL_GET_CONFIG_PARAMS _IOWR(V4LVIDEO_IOC_MAGIC, 0x05, struct v4l2_config_parm) -bool scatter_mem_enable; -bool param_sets_from_ucode; +bool param_sets_from_ucode = 1; +bool enable_drm_mode; static int fops_vcodec_open(struct file *file) { @@ -83,41 +82,49 @@ static int fops_vcodec_open(struct file *file) mutex_init(&ctx->state_lock); mutex_init(&ctx->lock); spin_lock_init(&ctx->slock); - init_waitqueue_head(&ctx->wq); init_completion(&ctx->comp); - ctx->scatter_mem_enable = scatter_mem_enable ? 1 : 0; ctx->param_sets_from_ucode = param_sets_from_ucode ? 1 : 0; + if (enable_drm_mode) { + ctx->is_drm_mode = true; + ctx->param_sets_from_ucode = true; + } + ctx->type = AML_INST_DECODER; ret = aml_vcodec_dec_ctrls_setup(ctx); if (ret) { - aml_v4l2_err("Failed to setup vcodec controls"); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Failed to setup vcodec controls\n"); goto err_ctrls_setup; } ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev_dec, ctx, &aml_vcodec_dec_queue_init); if (IS_ERR((__force void *)ctx->m2m_ctx)) { ret = PTR_ERR((__force void *)ctx->m2m_ctx); - aml_v4l2_err("Failed to v4l2_m2m_ctx_init() (%d)", ret); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Failed to v4l2_m2m_ctx_init() (%d)\n", ret); goto err_m2m_ctx_init; } src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + ctx->output_thread_ready = true; ctx->empty_flush_buf->vb.vb2_buf.vb2_queue = src_vq; ctx->empty_flush_buf->lastframe = true; aml_vcodec_dec_set_default_params(ctx); ret = aml_thread_start(ctx, try_to_capture, AML_THREAD_CAPTURE, "cap"); if (ret) { - aml_v4l2_err("Failed to creat capture thread."); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Failed to creat capture thread.\n"); goto err_creat_thread; } list_add(&ctx->list, &dev->ctx_list); mutex_unlock(&dev->dev_mutex); - pr_info("[%d] %s decoder\n", ctx->id, dev_name(&dev->plat_dev->dev)); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "%s decoder %lx\n", + dev_name(&dev->plat_dev->dev), (ulong)ctx); return ret; @@ -141,7 +148,7 @@ static int fops_vcodec_release(struct file *file) struct aml_vcodec_dev *dev = video_drvdata(file); struct aml_vcodec_ctx *ctx = fh_to_ctx(file->private_data); - pr_info("[%d] release decoder\n", ctx->id); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "release decoder %lx\n", (ulong) ctx); mutex_lock(&dev->dev_mutex); /* @@ -168,8 +175,8 @@ static int fops_vcodec_release(struct file *file) static int v4l2video_file_release(struct inode *inode, struct file *file) { - aml_v4l2_debug(2,"%s: file: 0x%p, data: %p", - __func__, file, file->private_data); + v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR, "file: %lx, data: %lx\n", + (ulong) file, (ulong) file->private_data); if (file->private_data) vdec_frame_buffer_release(file->private_data); @@ -187,25 +194,29 @@ int v4l2_alloc_fd(int *fd) int file_fd = get_unused_fd_flags(O_CLOEXEC); if (file_fd < 0) { - pr_err("%s: get unused fd fail\n", __func__); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "get unused fd fail\n"); return -ENODEV; } file = anon_inode_getfile("v4l2_meta_file", &v4l2_file_fops, NULL, 0); if (IS_ERR(file)) { put_unused_fd(file_fd); - pr_err("%s: anon_inode_getfile fail\n", __func__); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "anon_inode_getfile fail\n"); return -ENODEV; } file->private_data = kzalloc(sizeof(struct file_private_data), GFP_KERNEL); if (!file->private_data) { - pr_err("%s: alloc priv data faild.\n", __func__); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "alloc priv data faild.\n"); return -ENOMEM; } - aml_v4l2_debug(2, "%s: fd %d, file %p", __func__, file_fd, file); + v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR, "fd %d, file %lx, data: %lx\n", + file_fd, (ulong) file, (ulong) file->private_data); fd_install(file_fd, file); *fd = file_fd; @@ -226,20 +237,23 @@ int v4l2_check_fd(int fd) file = fget(fd); if (!file) { - pr_err("%s: fget fd %d fail!\n", __func__, fd); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "fget fd %d fail!\n", fd); return -EBADF; } if (!is_v4l2_buf_file(file)) { fput(file); - pr_err("%s: is_v4l2_buf_file fail!\n", __func__); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "is_v4l2_buf_file fail!\n"); return -1; } fput(file); - aml_v4l2_debug(5, "%s: ioctl ok, comm %s, pid %d", - __func__, current->comm, current->pid); + v4l_dbg(0, V4L_DEBUG_CODEC_EXINFO, + "ioctl ok, comm %s, pid %d\n", + current->comm, current->pid); return 0; } @@ -251,14 +265,16 @@ int dmabuf_fd_install_data(int fd, void* data, u32 size) file = fget(fd); if (!file) { - pr_err("%s: fget fd %d fail!, comm %s, pid %d\n", - __func__, fd, current->comm, current->pid); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "fget fd %d fail!, comm %s, pid %d\n", + fd, current->comm, current->pid); return -EBADF; } if (!is_v4l2_buf_file(file)) { fput(file); - pr_err("%s the buf file checked fail!\n", __func__); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "the buf file checked fail!\n"); return -EBADF; } @@ -278,20 +294,25 @@ void* v4l_get_vf_handle(int fd) file = fget(fd); if (!file) { - pr_err("%s: fget fd %d fail!, comm %s, pid %d\n", - __func__, fd, current->comm, current->pid); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "fget fd %d fail!, comm %s, pid %d\n", + fd, current->comm, current->pid); return NULL; } if (!is_v4l2_buf_file(file)) { fput(file); - pr_err("%s the buf file checked fail!\n", __func__); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "the buf file checked fail!\n"); return NULL; } data = (struct file_private_data*) file->private_data; - if (data) + if (data) { vf_handle = &data->vf; + v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR, "file: %lx, data: %lx\n", + (ulong) file, (ulong) data); + } fput(file); @@ -315,8 +336,9 @@ static long v4l2_vcodec_ioctl(struct file *file, if (ret != 0) break; put_user(v4lvideo_fd, (u32 __user *)argp); - aml_v4l2_debug(4, "%s: V4LVIDEO_IOCTL_ALLOC_FD fd %d", - __func__, v4lvideo_fd); + v4l_dbg(0, V4L_DEBUG_CODEC_EXINFO, + "V4LVIDEO_IOCTL_ALLOC_FD fd %d\n", + v4lvideo_fd); break; } case V4LVIDEO_IOCTL_CHECK_FD: @@ -327,8 +349,9 @@ static long v4l2_vcodec_ioctl(struct file *file, ret = v4l2_check_fd(v4lvideo_fd); if (ret != 0) break; - aml_v4l2_debug(4, "%s: V4LVIDEO_IOCTL_CHECK_FD fd %d", - __func__, v4lvideo_fd); + v4l_dbg(0, V4L_DEBUG_CODEC_EXINFO, + "V4LVIDEO_IOCTL_CHECK_FD fd %d\n", + v4lvideo_fd); break; } case V4LVIDEO_IOCTL_SET_CONFIG_PARAMS: @@ -341,7 +364,8 @@ static long v4l2_vcodec_ioctl(struct file *file, ctx = fh_to_ctx(file->private_data); if (copy_from_user((void *)&ctx->config, (void *)argp, sizeof(ctx->config))) { - pr_err("[%s],set config parm err\n", __func__); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "set config parm err\n"); return -EFAULT; } break; @@ -356,7 +380,8 @@ static long v4l2_vcodec_ioctl(struct file *file, ctx = fh_to_ctx(file->private_data); if (copy_to_user((void *)argp, (void *)&ctx->config, sizeof(ctx->config))) { - pr_err("[%s],get config parm err\n", __func__); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "get config parm err\n"); return -EFAULT; } break; @@ -412,7 +437,8 @@ static int aml_vcodec_probe(struct platform_device *pdev) ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); if (ret) { - aml_v4l2_err("v4l2_device_register err=%d", ret); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "v4l2_device_register err=%d\n", ret); goto err_res; } @@ -420,7 +446,8 @@ static int aml_vcodec_probe(struct platform_device *pdev) vfd_dec = video_device_alloc(); if (!vfd_dec) { - aml_v4l2_err("Failed to allocate video device"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "Failed to allocate video device\n"); ret = -ENOMEM; goto err_dec_alloc; } @@ -442,7 +469,8 @@ static int aml_vcodec_probe(struct platform_device *pdev) dev->m2m_dev_dec = v4l2_m2m_init(&aml_vdec_m2m_ops); if (IS_ERR((__force void *)dev->m2m_dev_dec)) { - aml_v4l2_err("Failed to init mem2mem dec device"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "Failed to init mem2mem dec device\n"); ret = PTR_ERR((__force void *)dev->m2m_dev_dec); goto err_dec_mem_init; } @@ -451,7 +479,8 @@ static int aml_vcodec_probe(struct platform_device *pdev) alloc_ordered_workqueue(AML_VCODEC_DEC_NAME, WQ_MEM_RECLAIM | WQ_FREEZABLE); if (!dev->decode_workqueue) { - aml_v4l2_err("Failed to create decode workqueue"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "Failed to create decode workqueue\n"); ret = -EINVAL; goto err_event_workq; } @@ -460,11 +489,13 @@ static int aml_vcodec_probe(struct platform_device *pdev) ret = video_register_device(vfd_dec, VFL_TYPE_GRABBER, 26); if (ret) { - pr_err("Failed to register video device\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "Failed to register video device\n"); goto err_dec_reg; } - pr_info("decoder registered as /dev/video%d\n", vfd_dec->num); + v4l_dbg(0, V4L_DEBUG_CODEC_PRINFO, + "decoder registered as /dev/video%d\n", vfd_dec->num); return 0; @@ -553,8 +584,9 @@ module_init(amvdec_ports_init); module_exit(amvdec_ports_exit); */ -module_param(aml_v4l2_dbg_level, int, 0644); -module_param(aml_vcodec_dbg, bool, 0644); +u32 debug_mode; +EXPORT_SYMBOL(debug_mode); +module_param(debug_mode, uint, 0644); bool aml_set_vfm_enable; EXPORT_SYMBOL(aml_set_vfm_enable); @@ -580,12 +612,16 @@ bool multiplanar; EXPORT_SYMBOL(multiplanar); module_param(multiplanar, bool, 0644); -EXPORT_SYMBOL(scatter_mem_enable); -module_param(scatter_mem_enable, bool, 0644); +bool dump_capture_frame; +EXPORT_SYMBOL(dump_capture_frame); +module_param(dump_capture_frame, bool, 0644); EXPORT_SYMBOL(param_sets_from_ucode); module_param(param_sets_from_ucode, bool, 0644); +EXPORT_SYMBOL(enable_drm_mode); +module_param(enable_drm_mode, bool, 0644); + MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("AML video codec V4L2 decoder driver"); diff --git a/drivers/amvdec_ports/aml_vcodec_dec_pm.c b/drivers/amvdec_ports/aml_vcodec_dec_pm.c deleted file mode 100644 index c801e87..0000000 --- a/drivers/amvdec_ports/aml_vcodec_dec_pm.c +++ b/dev/null @@ -1,206 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#include -#include -#include -#include - -#include "aml_vcodec_dec_pm.h" -#include "aml_vcodec_util.h" -//#include "aml_vpu.h" - -int aml_vcodec_init_dec_pm(struct aml_vcodec_dev *amldev) -{ - struct device_node *node; - struct platform_device *pdev; - struct aml_vcodec_pm *pm; - int ret = 0; - - pdev = amldev->plat_dev; - pm = &amldev->pm; - pm->amldev = amldev; - node = of_parse_phandle(pdev->dev.of_node, "larb", 0); - if (!node) { - aml_v4l2_err("of_parse_phandle larb fail!"); - return -1; - } - - pdev = of_find_device_by_node(node); - if (WARN_ON(!pdev)) { - of_node_put(node); - return -1; - } - pm->larbvdec = &pdev->dev; - pdev = amldev->plat_dev; - pm->dev = &pdev->dev; - - pm->vcodecpll = devm_clk_get(&pdev->dev, "vcodecpll"); - if (IS_ERR(pm->vcodecpll)) { - aml_v4l2_err("devm_clk_get vcodecpll fail"); - ret = PTR_ERR(pm->vcodecpll); - } - - pm->univpll_d2 = devm_clk_get(&pdev->dev, "univpll_d2"); - if (IS_ERR(pm->univpll_d2)) { - aml_v4l2_err("devm_clk_get univpll_d2 fail"); - ret = PTR_ERR(pm->univpll_d2); - } - - pm->clk_cci400_sel = devm_clk_get(&pdev->dev, "clk_cci400_sel"); - if (IS_ERR(pm->clk_cci400_sel)) { - aml_v4l2_err("devm_clk_get clk_cci400_sel fail"); - ret = PTR_ERR(pm->clk_cci400_sel); - } - - pm->vdec_sel = devm_clk_get(&pdev->dev, "vdec_sel"); - if (IS_ERR(pm->vdec_sel)) { - aml_v4l2_err("devm_clk_get vdec_sel fail"); - ret = PTR_ERR(pm->vdec_sel); - } - - pm->vdecpll = devm_clk_get(&pdev->dev, "vdecpll"); - if (IS_ERR(pm->vdecpll)) { - aml_v4l2_err("devm_clk_get vdecpll fail"); - ret = PTR_ERR(pm->vdecpll); - } - - pm->vencpll = devm_clk_get(&pdev->dev, "vencpll"); - if (IS_ERR(pm->vencpll)) { - aml_v4l2_err("devm_clk_get vencpll fail"); - ret = PTR_ERR(pm->vencpll); - } - - pm->venc_lt_sel = devm_clk_get(&pdev->dev, "venc_lt_sel"); - if (IS_ERR(pm->venc_lt_sel)) { - aml_v4l2_err("devm_clk_get venc_lt_sel fail"); - ret = PTR_ERR(pm->venc_lt_sel); - } - - pm->vdec_bus_clk_src = devm_clk_get(&pdev->dev, "vdec_bus_clk_src"); - if (IS_ERR(pm->vdec_bus_clk_src)) { - aml_v4l2_err("devm_clk_get vdec_bus_clk_src"); - ret = PTR_ERR(pm->vdec_bus_clk_src); - } - - pm_runtime_enable(&pdev->dev); - - return ret; -} - -void aml_vcodec_release_dec_pm(struct aml_vcodec_dev *dev) -{ - pm_runtime_disable(dev->pm.dev); -} - -void aml_vcodec_dec_pw_on(struct aml_vcodec_pm *pm) -{ - int ret; - - ret = pm_runtime_get_sync(pm->dev); - if (ret) - aml_v4l2_err("pm_runtime_get_sync fail %d", ret); -} - -void aml_vcodec_dec_pw_off(struct aml_vcodec_pm *pm) -{ - int ret; - - ret = pm_runtime_put_sync(pm->dev); - if (ret) - aml_v4l2_err("pm_runtime_put_sync fail %d", ret); -} - -void aml_vcodec_dec_clock_on(struct aml_vcodec_pm *pm) -{ - int ret; - - ret = clk_set_rate(pm->vcodecpll, 1482 * 1000000); - if (ret) - aml_v4l2_err("clk_set_rate vcodecpll fail %d", ret); - - ret = clk_set_rate(pm->vencpll, 800 * 1000000); - if (ret) - aml_v4l2_err("clk_set_rate vencpll fail %d", ret); - - ret = clk_prepare_enable(pm->vcodecpll); - if (ret) - aml_v4l2_err("clk_prepare_enable vcodecpll fail %d", ret); - - ret = clk_prepare_enable(pm->vencpll); - if (ret) - aml_v4l2_err("clk_prepare_enable vencpll fail %d", ret); - - ret = clk_prepare_enable(pm->vdec_bus_clk_src); - if (ret) - aml_v4l2_err("clk_prepare_enable vdec_bus_clk_src fail %d", - ret); - - ret = clk_prepare_enable(pm->venc_lt_sel); - if (ret) - aml_v4l2_err("clk_prepare_enable venc_lt_sel fail %d", ret); - - ret = clk_set_parent(pm->venc_lt_sel, pm->vdec_bus_clk_src); - if (ret) - aml_v4l2_err("clk_set_parent venc_lt_sel vdec_bus_clk_src fail %d", - ret); - - ret = clk_prepare_enable(pm->univpll_d2); - if (ret) - aml_v4l2_err("clk_prepare_enable univpll_d2 fail %d", ret); - - ret = clk_prepare_enable(pm->clk_cci400_sel); - if (ret) - aml_v4l2_err("clk_prepare_enable clk_cci400_sel fail %d", ret); - - ret = clk_set_parent(pm->clk_cci400_sel, pm->univpll_d2); - if (ret) - aml_v4l2_err("clk_set_parent clk_cci400_sel univpll_d2 fail %d", - ret); - - ret = clk_prepare_enable(pm->vdecpll); - if (ret) - aml_v4l2_err("clk_prepare_enable vdecpll fail %d", ret); - - ret = clk_prepare_enable(pm->vdec_sel); - if (ret) - aml_v4l2_err("clk_prepare_enable vdec_sel fail %d", ret); - - ret = clk_set_parent(pm->vdec_sel, pm->vdecpll); - if (ret) - aml_v4l2_err("clk_set_parent vdec_sel vdecpll fail %d", ret); - - //ret = aml_smi_larb_get(pm->larbvdec); - if (ret) - aml_v4l2_err("aml_smi_larb_get larbvdec fail %d", ret); - -} - -void aml_vcodec_dec_clock_off(struct aml_vcodec_pm *pm) -{ - //aml_smi_larb_put(pm->larbvdec); - clk_disable_unprepare(pm->vdec_sel); - clk_disable_unprepare(pm->vdecpll); - clk_disable_unprepare(pm->univpll_d2); - clk_disable_unprepare(pm->clk_cci400_sel); - clk_disable_unprepare(pm->venc_lt_sel); - clk_disable_unprepare(pm->vdec_bus_clk_src); - clk_disable_unprepare(pm->vencpll); - clk_disable_unprepare(pm->vcodecpll); -} diff --git a/drivers/amvdec_ports/aml_vcodec_dec_pm.h b/drivers/amvdec_ports/aml_vcodec_dec_pm.h deleted file mode 100644 index ccdf313..0000000 --- a/drivers/amvdec_ports/aml_vcodec_dec_pm.h +++ b/dev/null @@ -1,34 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ - -#ifndef _AML_VCODEC_DEC_PM_H_ -#define _AML_VCODEC_DEC_PM_H_ - -#include "aml_vcodec_drv.h" - -int aml_vcodec_init_dec_pm(struct aml_vcodec_dev *dev); -void aml_vcodec_release_dec_pm(struct aml_vcodec_dev *dev); - -void aml_vcodec_dec_pw_on(struct aml_vcodec_pm *pm); -void aml_vcodec_dec_pw_off(struct aml_vcodec_pm *pm); -void aml_vcodec_dec_clock_on(struct aml_vcodec_pm *pm); -void aml_vcodec_dec_clock_off(struct aml_vcodec_pm *pm); - -#endif /* _AML_VCODEC_DEC_PM_H_ */ diff --git a/drivers/amvdec_ports/aml_vcodec_drv.h b/drivers/amvdec_ports/aml_vcodec_drv.h index 1baec44..f28dc51 100644 --- a/drivers/amvdec_ports/aml_vcodec_drv.h +++ b/drivers/amvdec_ports/aml_vcodec_drv.h @@ -58,6 +58,9 @@ #define V4L2_EVENT_REQUEST_RESET (1 << 8) #define V4L2_EVENT_REQUEST_EXIT (1 << 9) +/* eos event */ +#define V4L2_EVENT_SEND_EOS (1 << 16) + /* v4l buffer pool */ #define V4L_CAP_BUFF_MAX (32) #define V4L_CAP_BUFF_INVALID (0) @@ -68,6 +71,14 @@ #define V4L_RESET_MODE_NORMAL (1 << 0) /* reset vdec_input and decoder. */ #define V4L_RESET_MODE_LIGHT (1 << 1) /* just only reset decoder. */ +/* m2m job queue's status */ +/* Instance is already queued on the job_queue */ +#define TRANS_QUEUED (1 << 0) +/* Instance is currently running in hardware */ +#define TRANS_RUNNING (1 << 1) +/* Instance is currently aborting */ +#define TRANS_ABORT (1 << 2) + /** * enum aml_hw_reg_idx - AML hw register base index */ @@ -266,6 +277,7 @@ struct vdec_pic_info { unsigned int y_len_sz; unsigned int c_len_sz; int profile_idc; + int ref_frame_count; }; struct aml_vdec_cfg_infos { @@ -369,101 +381,93 @@ struct aml_vdec_thread { /** * struct aml_vcodec_ctx - Context (instance) private data. * - * @type: type of the instance - decoder or encoder - * @dev: pointer to the aml_vcodec_dev of the device - * @list: link to ctx_list of aml_vcodec_dev - * @fh: struct v4l2_fh - * @m2m_ctx: pointer to the v4l2_m2m_ctx of the context - * @q_data: store information of input and output queue - * of the context - * @id: index of the context that this structure describes - * @state: state of the context - * @param_change: indicate encode parameter type - * @enc_params: encoding parameters - * @dec_if: hooked decoder driver interface - * @enc_if: hoooked encoder driver interface - * @drv_handle: driver handle for specific decode/encode instance - * - * @picinfo: store picture info after header parsing + * @id: index of the context that this structure describes. + * @type: type of the instance - decoder or encoder. + * @dev: pointer to the aml_vcodec_dev of the device. + * @m2m_ctx: pointer to the v4l2_m2m_ctx of the context. + * @ada_ctx: pointer to the aml_vdec_adapt of the context. + * @dec_if: hooked decoder driver interface. + * @drv_handle: driver handle for specific decode instance + * @fh: struct v4l2_fh. + * @ctrl_hdl: handler for v4l2 framework. + * @slock: protect v4l2 codec context. + * @empty_flush_buf: a fake size-0 capture buffer that indicates flush. + * @list: link to ctx_list of aml_vcodec_dev. + * @q_data: store information of input and output queue of the context. + * @queue: waitqueue that can be used to wait for this context to finish. + * @lock: protect the vdec thread. + * @state_lock: protect the codec status. + * @state: state of the context. + * @decode_work: decoder work be used to output buffer. + * @output_thread_ready: indicate the output thread ready. + * @cap_pool: capture buffers are remark in the pool. + * @vdec_thread_list: vdec thread be used to capture. * @dpb_size: store dpb count after header parsing - * @int_cond: variable used by the waitqueue - * @int_type: type of the last interrupt - * @queue: waitqueue that can be used to wait for this context to - * finish - * @irq_status: irq status - * - * @ctrl_hdl: handler for v4l2 framework - * @decode_work: worker for the decoding - * @encode_work: worker for the encoding - * @last_decoded_picinfo: pic information get from latest decode - * @empty_flush_buf: a fake size-0 capture buffer that indicates flush - * - * @colorspace: enum v4l2_colorspace; supplemental to pixelformat - * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding - * @quantization: enum v4l2_quantization, colorspace quantization - * @xfer_func: enum v4l2_xfer_func, colorspace transfer function - * @lock: protect variables accessed by V4L2 threads and worker thread such as - * aml_video_dec_buf. + * @param_change: indicate encode parameter type + * @param_sets_from_ucode: if true indicate ps from ucode. + * @v4l_codec_dpb_ready: queue buffer number greater than dpb. + * @comp: comp be used for sync picture information with decoder. + * @config: used to set or get parms for application. + * @picinfo: store picture info after header parsing. + * @last_decoded_picinfo: pic information get from latest decode. + * @colorspace: enum v4l2_colorspace; supplemental to pixelformat. + * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding. + * @quantization: enum v4l2_quantization, colorspace quantization. + * @xfer_func: enum v4l2_xfer_func, colorspace transfer function. + * @cap_pix_fmt: the picture format used to switch nv21 or nv12. + * @has_receive_eos: if receive last frame of capture that be set. + * @is_drm_mode: decoding work on drm mode if that set. + * @is_stream_mode: vdec input used to stream mode, default frame mode. + * @is_stream_off: the value used to handle reset active. + * @receive_cmd_stop: if receive the cmd flush decoder. + * @reset_flag: reset mode includes lightly and normal mode. + * @decoded_frame_cnt: the capture buffer deque number to be count. + * @buf_used_count: means that decode allocate how many buffs from v4l. */ struct aml_vcodec_ctx { - enum aml_instance_type type; - struct aml_vcodec_dev *dev; - struct list_head list; - - struct v4l2_fh fh; - struct v4l2_m2m_ctx *m2m_ctx; - struct aml_vdec_adapt *ada_ctx; - struct aml_q_data q_data[2]; - int id; - struct mutex state_lock; - enum aml_instance_state state; - enum aml_encode_param param_change; - struct aml_enc_params enc_params; - - const struct vdec_common_if *dec_if; - const struct venc_common_if *enc_if; - unsigned long drv_handle; - - struct vdec_pic_info picinfo; - int dpb_size; - - int int_cond; - int int_type; - wait_queue_head_t queue; - unsigned int irq_status; - - struct v4l2_ctrl_handler ctrl_hdl; - struct work_struct decode_work; - struct work_struct encode_work; - struct vdec_pic_info last_decoded_picinfo; - struct aml_video_dec_buf *empty_flush_buf; - - enum v4l2_colorspace colorspace; - enum v4l2_ycbcr_encoding ycbcr_enc; - enum v4l2_quantization quantization; - enum v4l2_xfer_func xfer_func; - - int decoded_frame_cnt; - struct mutex lock; - struct completion comp; - bool has_receive_eos; - struct list_head vdec_thread_list; - bool is_drm_mode; - bool is_stream_mode; - int buf_used_count; - bool receive_cmd_stop; - bool scatter_mem_enable; - bool param_sets_from_ucode; - bool v4l_codec_ready; - bool v4l_codec_dpb_ready; - wait_queue_head_t wq; - spinlock_t slock; - struct v4l2_config_parm config; - bool is_stream_off; - int reset_flag; - int stop_cmd; - u32 display_count; - struct v4l_buff_pool cap_pool; + int id; + enum aml_instance_type type; + struct aml_vcodec_dev *dev; + struct v4l2_m2m_ctx *m2m_ctx; + struct aml_vdec_adapt *ada_ctx; + const struct vdec_common_if *dec_if; + ulong drv_handle; + struct v4l2_fh fh; + struct v4l2_ctrl_handler ctrl_hdl; + spinlock_t slock; + struct aml_video_dec_buf *empty_flush_buf; + struct list_head list; + + struct aml_q_data q_data[2]; + wait_queue_head_t queue; + struct mutex lock, state_lock; + enum aml_instance_state state; + struct work_struct decode_work; + bool output_thread_ready; + struct v4l_buff_pool cap_pool; + struct list_head vdec_thread_list; + + int dpb_size; + bool param_sets_from_ucode; + bool v4l_codec_dpb_ready; + struct completion comp; + struct v4l2_config_parm config; + struct vdec_pic_info picinfo; + struct vdec_pic_info last_decoded_picinfo; + enum v4l2_colorspace colorspace; + enum v4l2_ycbcr_encoding ycbcr_enc; + enum v4l2_quantization quantization; + enum v4l2_xfer_func xfer_func; + u32 cap_pix_fmt; + + bool has_receive_eos; + bool is_drm_mode; + bool output_dma_mode; + bool is_stream_off; + bool receive_cmd_stop; + int reset_flag; + int decoded_frame_cnt; + int buf_used_count; }; /** diff --git a/drivers/amvdec_ports/aml_vcodec_util.c b/drivers/amvdec_ports/aml_vcodec_util.c index 73a4b74..03180ab 100644 --- a/drivers/amvdec_ports/aml_vcodec_util.c +++ b/drivers/amvdec_ports/aml_vcodec_util.c @@ -21,17 +21,6 @@ #include "aml_vcodec_drv.h" #include "aml_vcodec_util.h" -//#include "aml_vpu.h" - -/* For encoder, this will enable logs in venc/*/ -bool aml_vcodec_dbg; -EXPORT_SYMBOL(aml_vcodec_dbg); - -/* The log level of v4l2 encoder or decoder driver. - * That is, files under aml-vcodec/. - */ -int aml_v4l2_dbg_level; -EXPORT_SYMBOL(aml_v4l2_dbg_level); void __iomem *aml_vcodec_get_reg_addr(struct aml_vcodec_ctx *data, unsigned int reg_idx) @@ -39,7 +28,8 @@ void __iomem *aml_vcodec_get_reg_addr(struct aml_vcodec_ctx *data, struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)data; if (!data || reg_idx >= NUM_MAX_VCODEC_REG_BASE) { - aml_v4l2_err("Invalid arguments, reg_idx=%d", reg_idx); + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Invalid arguments, reg_idx=%d\n", reg_idx); return NULL; } return ctx->dev->reg_base[reg_idx]; @@ -57,17 +47,17 @@ int aml_vcodec_mem_alloc(struct aml_vcodec_ctx *data, mem->vaddr = codec_mm_dma_alloc_coherent(dev_name(dev), size, &mem->dma_addr, GFP_KERNEL, 0); if (!mem->vaddr) { - aml_v4l2_err("%s dma_alloc size=%ld failed!", dev_name(dev), + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "%s dma_alloc size=%ld failed!\n", dev_name(dev), size); return -ENOMEM; } memset(mem->vaddr, 0, size); - aml_v4l2_debug(4, "[%d] - va = %p", ctx->id, mem->vaddr); - aml_v4l2_debug(4, "[%d] - dma = 0x%lx", ctx->id, - (unsigned long)mem->dma_addr); - aml_v4l2_debug(4, "[%d] size = 0x%lx", ctx->id, size); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "va: %p\n", mem->vaddr); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "dma: 0x%lx\n", (ulong) mem->dma_addr); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "size: 0x%lx\n", size); return 0; } @@ -81,15 +71,15 @@ void aml_vcodec_mem_free(struct aml_vcodec_ctx *data, struct device *dev = &ctx->dev->plat_dev->dev; if (!mem->vaddr) { - aml_v4l2_err("%s dma_free size=%ld failed!", dev_name(dev), + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "%s dma_free size=%ld failed!\n", dev_name(dev), size); return; } - aml_v4l2_debug(4, "[%d] - va = %p", ctx->id, mem->vaddr); - aml_v4l2_debug(4, "[%d] - dma = 0x%lx", ctx->id, - (unsigned long)mem->dma_addr); - aml_v4l2_debug(4, "[%d] size = 0x%lx", ctx->id, size); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "va: %p\n", mem->vaddr); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "dma: 0x%lx\n", (ulong) mem->dma_addr); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "size: 0x%lx\n", size); dma_free_coherent(dev, size, mem->vaddr, mem->dma_addr); mem->vaddr = NULL; diff --git a/drivers/amvdec_ports/aml_vcodec_util.h b/drivers/amvdec_ports/aml_vcodec_util.h index e93900e..8e479a6 100644 --- a/drivers/amvdec_ports/aml_vcodec_util.h +++ b/drivers/amvdec_ports/aml_vcodec_util.h @@ -24,75 +24,73 @@ #include #include -#define DEBUG - -typedef unsigned long long u64; -typedef signed long long s64; -typedef unsigned int u32; -typedef unsigned short int u16; -typedef short int s16; -typedef unsigned char u8; +typedef unsigned long long u64; +typedef signed long long s64; +typedef unsigned int u32; +typedef unsigned short int u16; +typedef short int s16; +typedef unsigned char u8; #define CODEC_MODE(a, b, c, d)\ (((u8)(a) << 24) | ((u8)(b) << 16) | ((u8)(c) << 8) | (u8)(d)) +#define BUFF_IDX(h, i)\ + (((ulong)(h) << 8) | (u8)(i)) + struct aml_vcodec_mem { + int index; ulong addr; u32 size; void *vaddr; u32 bytes_used; u32 offset; dma_addr_t dma_addr; + u32 model; }; struct aml_vcodec_ctx; struct aml_vcodec_dev; -extern int aml_v4l2_dbg_level; -extern bool aml_vcodec_dbg; +extern u32 debug_mode; +#ifdef v4l_dbg +#undef v4l_dbg +#endif -#if defined(DEBUG) - -#define aml_v4l2_debug(level, fmt, args...) \ +/* v4l debug define. */ +#define V4L_DEBUG_CODEC_ERROR (0) +#define V4L_DEBUG_CODEC_PRINFO (1 << 0) +#define V4L_DEBUG_CODEC_STATE (1 << 1) +#define V4L_DEBUG_CODEC_BUFMGR (1 << 2) +#define V4L_DEBUG_CODEC_INPUT (1 << 3) +#define V4L_DEBUG_CODEC_OUTPUT (1 << 4) +#define V4L_DEBUG_CODEC_COUNT (1 << 5) +#define V4L_DEBUG_CODEC_PARSER (1 << 6) +#define V4L_DEBUG_CODEC_PROT (1 << 7) +#define V4L_DEBUG_CODEC_EXINFO (1 << 8) + +#define __v4l_dbg(h, id, fmt, args...) \ do { \ - if (aml_v4l2_dbg_level >= level) \ - pr_info(fmt "\n", ##args); \ + if (h) \ + pr_info("[%d]: " fmt, id, ##args); \ + else \ + pr_info(fmt, ##args); \ } while (0) -#define aml_v4l2_debug_enter() aml_v4l2_debug(3, "+") -#define aml_v4l2_debug_leave() aml_v4l2_debug(3, "-") - -#define aml_vcodec_debug(h, fmt, args...) \ - do { \ - if (aml_vcodec_dbg) \ - pr_info("[%d]: %s() " fmt "\n", \ - ((struct aml_vcodec_ctx *)h->ctx)->id, \ - __func__, ##args); \ +#define v4l_dbg(h, flags, fmt, args...) \ + do { \ + struct aml_vcodec_ctx *__ctx = (struct aml_vcodec_ctx *) h; \ + if ((flags == V4L_DEBUG_CODEC_ERROR) || \ + (flags == V4L_DEBUG_CODEC_PRINFO) || \ + (debug_mode & flags)) { \ + if (flags == V4L_DEBUG_CODEC_ERROR) { \ + __v4l_dbg(h, __ctx->id, "[ERR]: " fmt, ##args); \ + } else { \ + __v4l_dbg(h, __ctx->id, fmt, ##args); \ + } \ + } \ } while (0) -#define aml_vcodec_debug_enter(h) aml_vcodec_debug(h, "+") -#define aml_vcodec_debug_leave(h) aml_vcodec_debug(h, "-") - -#else - -#define aml_v4l2_debug(level, fmt, args...) -#define aml_v4l2_debug_enter() -#define aml_v4l2_debug_leave() - -#define aml_vcodec_debug(h, fmt, args...) -#define aml_vcodec_debug_enter(h) -#define aml_vcodec_debug_leave(h) - -#endif - -#define aml_v4l2_err(fmt, args...) \ - pr_err("[ERR]" fmt "\n", ##args) - -#define aml_vcodec_err(h, fmt, args...) \ - pr_err("[ERR][%d]" fmt "\n", \ - ((struct aml_vcodec_ctx *)h->ctx)->id, ##args) - void __iomem *aml_vcodec_get_reg_addr(struct aml_vcodec_ctx *data, unsigned int reg_idx); int aml_vcodec_mem_alloc(struct aml_vcodec_ctx *data, diff --git a/drivers/amvdec_ports/aml_vcodec_vfm.c b/drivers/amvdec_ports/aml_vcodec_vfm.c index b64be0c..62896ea 100644 --- a/drivers/amvdec_ports/aml_vcodec_vfm.c +++ b/drivers/amvdec_ports/aml_vcodec_vfm.c @@ -56,7 +56,7 @@ static void vdec_vf_put(struct vframe_s *vf, void *op_arg) //vf_notify_provider(vfm->recv_name, VFRAME_EVENT_RECEIVER_PUT, NULL); if (vfq_level(&vfm->vf_que_recycle) > POOL_SIZE - 1) { - pr_info("%s %d vfq full.\n", __func__, __LINE__); + v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_ERROR, "vfq full.\n"); return; } @@ -95,12 +95,13 @@ void video_vf_put(char *receiver, struct vdec_v4l2_buffer *fb, int id) struct vframe_provider_s *vfp = vf_get_provider(receiver); struct vframe_s *vf = (struct vframe_s *)fb->vf_handle; - aml_v4l2_debug(3, "[%d] TO (%s) vf: %p, idx: %d", - id, vfp->name, vf, vf->index); ATRACE_COUNTER("v4l2_to", vf->index_disp); - aml_v4l2_debug(4, "[%d] TO Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)", - id, fb->m.mem[0].addr, fb->m.mem[0].size, + v4l_dbg(0, V4L_DEBUG_CODEC_OUTPUT, + "[%d]: TO (%s) vf: %p, idx: %d, " + "Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)\n", + id, vfp->name, vf, vf->index, + fb->m.mem[0].addr, fb->m.mem[0].size, fb->m.mem[1].addr, fb->m.mem[1].size, fb->m.mem[2].addr, fb->m.mem[2].size); @@ -122,13 +123,12 @@ static int video_receiver_event_fun(int type, void *data, void *private_data) struct vframe_states states; struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)private_data; - //aml_v4l2_debug(4, "[%d] type: %d, vfm: %p", vfm->ctx->id, type, vfm); - switch (type) { case VFRAME_EVENT_PROVIDER_UNREG: { if (vf_get_receiver(vfm->prov_name)) { - aml_v4l2_debug(4, "[%d] unreg %s provider.", - vfm->ctx->id, vfm->prov_name); + v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_EXINFO, + "unreg %s provider.\n", + vfm->prov_name); vf_unreg_provider(&vfm->vf_prov); } @@ -137,8 +137,9 @@ static int video_receiver_event_fun(int type, void *data, void *private_data) case VFRAME_EVENT_PROVIDER_START: { if (vf_get_receiver(vfm->prov_name)) { - aml_v4l2_debug(4, "[%d] reg %s provider.", - vfm->ctx->id, vfm->prov_name); + v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_EXINFO, + "reg %s provider.\n", + vfm->prov_name); vf_provider_init(&vfm->vf_prov, vfm->prov_name, &vf_provider, vfm); vf_reg_provider(&vfm->vf_prov); @@ -171,7 +172,7 @@ static int video_receiver_event_fun(int type, void *data, void *private_data) ret = -1; if (ret < 0) { - pr_err("[%d] receiver vf err.\n", vfm->ctx->id); + v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_ERROR, "receiver vf err.\n"); break; } @@ -190,7 +191,8 @@ static int video_receiver_event_fun(int type, void *data, void *private_data) } default: - aml_v4l2_debug(4, "[%d] the vf event is %d", vfm->ctx->id, type); + v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_EXINFO, + "the vf event is %d", type); } return ret; diff --git a/drivers/amvdec_ports/decoder/aml_h264_parser.c b/drivers/amvdec_ports/decoder/aml_h264_parser.c index 602633b..d0d0198 100644 --- a/drivers/amvdec_ports/decoder/aml_h264_parser.c +++ b/drivers/amvdec_ports/decoder/aml_h264_parser.c @@ -162,7 +162,8 @@ static int decode_hrd_parameters(struct get_bits_context *gb, cpb_count = get_ue_golomb_31(gb) + 1; if (cpb_count > 32U) { - pr_err("cpb_count %d invalid\n", cpb_count); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "cpb_count %d invalid\n", cpb_count); return -1; } @@ -237,7 +238,7 @@ static int decode_vui_parameters(struct get_bits_context *gb, struct h264_SPS_t } if (show_bits1(gb) && get_bits_left(gb) < 10) { - pr_info("Truncated VUI\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Truncated VUI\n"); return 0; } @@ -246,7 +247,8 @@ static int decode_vui_parameters(struct get_bits_context *gb, struct h264_SPS_t unsigned num_units_in_tick = get_bits_long(gb, 32); unsigned time_scale = get_bits_long(gb, 32); if (!num_units_in_tick || !time_scale) { - pr_info("time_scale/num_units_in_tick invalid or unsupported (%u/%u)\n", + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, + "time_scale/num_units_in_tick invalid or unsupported (%u/%u)\n", time_scale, num_units_in_tick); sps->timing_info_present_flag = 0; } else { @@ -287,7 +289,8 @@ static int decode_vui_parameters(struct get_bits_context *gb, struct h264_SPS_t if (sps->num_reorder_frames > 16U /* max_dec_frame_buffering || max_dec_frame_buffering > 16 */) { - pr_info("Clipping illegal num_reorder_frames %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "Clipping illegal num_reorder_frames %d\n", sps->num_reorder_frames); sps->num_reorder_frames = 16; return -1; @@ -316,7 +319,8 @@ static int aml_h264_parser_sps(struct get_bits_context *gb, struct h264_SPS_t *s sps_id = get_ue_golomb_31(gb); if (sps_id >= MAX_SPS_COUNT) { - pr_info( "sps_id %u out of range\n", sps_id); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "sps_id %u out of range\n", sps_id); goto fail; } @@ -346,12 +350,14 @@ static int aml_h264_parser_sps(struct get_bits_context *gb, struct h264_SPS_t *s sps->chroma_format_idc = get_ue_golomb_31(gb); if (sps->chroma_format_idc > 3U) { - pr_err("chroma_format_idc %u\n", sps->chroma_format_idc); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "chroma_format_idc %u\n", sps->chroma_format_idc); goto fail; } else if (sps->chroma_format_idc == 3) { sps->residual_color_transform_flag = get_bits1(gb); if (sps->residual_color_transform_flag) { - pr_info( "separate color planes are not supported\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "separate color planes are not supported\n"); goto fail; } } @@ -359,14 +365,16 @@ static int aml_h264_parser_sps(struct get_bits_context *gb, struct h264_SPS_t *s sps->bit_depth_luma = get_ue_golomb(gb) + 8; sps->bit_depth_chroma = get_ue_golomb(gb) + 8; if (sps->bit_depth_chroma != sps->bit_depth_luma) { - pr_err("Different chroma and luma bit depth\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "Different chroma and luma bit depth\n"); goto fail; } if (sps->bit_depth_luma < 8 || sps->bit_depth_luma > 14 || sps->bit_depth_chroma < 8 || sps->bit_depth_chroma > 14) { - pr_info("illegal bit depth value (%d, %d)\n", - sps->bit_depth_luma, sps->bit_depth_chroma); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "illegal bit depth value (%d, %d)\n", + sps->bit_depth_luma, sps->bit_depth_chroma); goto fail; } @@ -385,9 +393,9 @@ static int aml_h264_parser_sps(struct get_bits_context *gb, struct h264_SPS_t *s log2_max_frame_num_minus4 = get_ue_golomb(gb); if (log2_max_frame_num_minus4 < MIN_LOG2_MAX_FRAME_NUM - 4 || log2_max_frame_num_minus4 > MAX_LOG2_MAX_FRAME_NUM - 4) { - pr_info( - "log2_max_frame_num_minus4 out of range (0-12): %d\n", - log2_max_frame_num_minus4); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "log2_max_frame_num_minus4 out of range (0-12): %d\n", + log2_max_frame_num_minus4); goto fail; } sps->log2_max_frame_num = log2_max_frame_num_minus4 + 4; @@ -396,7 +404,8 @@ static int aml_h264_parser_sps(struct get_bits_context *gb, struct h264_SPS_t *s if (sps->poc_type == 0) { // FIXME #define u32 t = get_ue_golomb(gb); if (t > 12) { - pr_info( "log2_max_poc_lsb (%d) is out of range\n", t); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "log2_max_poc_lsb (%d) is out of range\n", t); goto fail; } sps->log2_max_poc_lsb = t + 4; @@ -407,20 +416,23 @@ static int aml_h264_parser_sps(struct get_bits_context *gb, struct h264_SPS_t *s sps->poc_cycle_length = get_ue_golomb(gb); if ((u32)sps->poc_cycle_length >= ARRAY_SIZE(sps->offset_for_ref_frame)) { - pr_info("poc_cycle_length overflow %d\n", sps->poc_cycle_length); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "poc_cycle_length overflow %d\n", sps->poc_cycle_length); goto fail; } for (i = 0; i < sps->poc_cycle_length; i++) sps->offset_for_ref_frame[i] = get_se_golomb_long(gb); } else if (sps->poc_type != 2) { - pr_info( "illegal POC type %d\n", sps->poc_type); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "illegal POC type %d\n", sps->poc_type); goto fail; } sps->ref_frame_count = get_ue_golomb_31(gb); if (sps->ref_frame_count > MAX_DELAYED_PIC_COUNT) { - pr_info("too many reference frames %d\n", sps->ref_frame_count); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "too many reference frames %d\n", sps->ref_frame_count); goto fail; } sps->gaps_in_frame_num_allowed_flag = get_bits1(gb); @@ -430,7 +442,7 @@ static int aml_h264_parser_sps(struct get_bits_context *gb, struct h264_SPS_t *s sps->frame_mbs_only_flag = get_bits1(gb); if (sps->mb_height >= INT_MAX / 2U) { - pr_info("height overflow\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "height overflow\n"); goto fail; } sps->mb_height *= 2 - sps->frame_mbs_only_flag; @@ -442,7 +454,8 @@ static int aml_h264_parser_sps(struct get_bits_context *gb, struct h264_SPS_t *s if ((u32)sps->mb_width >= INT_MAX / 16 || (u32)sps->mb_height >= INT_MAX / 16) { - pr_info( "mb_width/height overflow\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "mb_width/height overflow\n"); goto fail; } @@ -467,7 +480,9 @@ static int aml_h264_parser_sps(struct get_bits_context *gb, struct h264_SPS_t *s crop_bottom > (u32)INT_MAX / 4 / step_y || (crop_left + crop_right ) * step_x >= width || (crop_top + crop_bottom) * step_y >= height) { - pr_info( "crop values invalid %u %u %u %u / %d %d\n", crop_left, crop_right, crop_top, crop_bottom, width, height); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "crop values invalid %u %u %u %u / %d %d\n", + crop_left, crop_right, crop_top, crop_bottom, width, height); goto fail; } @@ -491,8 +506,10 @@ static int aml_h264_parser_sps(struct get_bits_context *gb, struct h264_SPS_t *s } if (get_bits_left(gb) < 0) { - pr_info("Overread %s by %d bits\n", sps->vui_parameters_present_flag ? "VUI" : "SPS", -get_bits_left(gb)); - goto out; + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "Overread %s by %d bits\n", + sps->vui_parameters_present_flag ? "VUI" : "SPS", -get_bits_left(gb)); + /*goto out;*/ } #if 0 @@ -527,16 +544,18 @@ static int aml_h264_parser_sps(struct get_bits_context *gb, struct h264_SPS_t *s (sps->max_dec_frame_buffering < sps->num_reorder_frames)) { sps->num_reorder_frames = sps->max_dec_frame_buffering; - pr_info("set reorder_pic_num to %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, + "set reorder_pic_num to %d\n", sps->num_reorder_frames); } if (!sps->sar.den) sps->sar.den = 1; -out: +/*out:*/ if (1) { static const char csp[4][5] = { "Gray", "420", "422", "444" }; - pr_info("sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%u/%u/%u/%u %s %s %d/%d b%d reo:%d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, + "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%u/%u/%u/%u %s %s %d/%d b%d reo:%d\n", sps_id, sps->profile_idc, sps->level_idc, sps->poc_type, sps->ref_frame_count, @@ -625,14 +644,16 @@ static int decode_extradata_ps(u8 *data, int size, struct h264_param_sets *ps) if (get_bits1(&gb) != 0) { ret = -1; - pr_err("invalid h264 data,return!\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "invalid h264 data,return!\n"); goto out; } ref_idc = get_bits(&gb, 2); nal_type = get_bits(&gb, 5); - pr_info("nal_unit_type: %d(%s), nal_ref_idc: %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, + "nal_unit_type: %d(%s), nal_ref_idc: %d\n", nal_type, h264_nal_unit_name(nal_type), ref_idc); switch (nal_type) { @@ -649,7 +670,8 @@ static int decode_extradata_ps(u8 *data, int size, struct h264_param_sets *ps) ps->pps_parsed = true; break;*/ default: - pr_err("Unsupport parser nal type (%s).\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "Unsupport parser nal type (%s).\n", h264_nal_unit_name(nal_type)); break; } @@ -672,7 +694,8 @@ int h264_decode_extradata_ps(u8 *buf, int size, struct h264_param_sets *ps) len = size - (p - buf); ret = decode_extradata_ps(p, len, ps); if (ret) { - pr_err("parse extra data failed. err: %d\n", ret); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "parse extra data failed. err: %d\n", ret); return ret; } diff --git a/drivers/amvdec_ports/decoder/aml_h264_parser.h b/drivers/amvdec_ports/decoder/aml_h264_parser.h index af48d78..aed5378 100644 --- a/drivers/amvdec_ports/decoder/aml_h264_parser.h +++ b/drivers/amvdec_ports/decoder/aml_h264_parser.h @@ -18,6 +18,7 @@ #ifndef AML_H264_PARSER_H #define AML_H264_PARSER_H +#include "../aml_vcodec_drv.h" #include "../utils/pixfmt.h" #define QP_MAX_NUM (51 + 6 * 6) // The maximum supported qp diff --git a/drivers/amvdec_ports/decoder/aml_hevc_parser.c b/drivers/amvdec_ports/decoder/aml_hevc_parser.c index 03b8356..24977a8 100644 --- a/drivers/amvdec_ports/decoder/aml_hevc_parser.c +++ b/drivers/amvdec_ports/decoder/aml_hevc_parser.c @@ -124,15 +124,15 @@ static int decode_profile_tier_level(struct get_bits_context *gb, struct PTLComm ptl->tier_flag = get_bits1(gb); ptl->profile_idc = get_bits(gb, 5); if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN) - pr_info("Main profile bitstream\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Main profile bitstream\n"); else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_10) - pr_info("Main 10 profile bitstream\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Main 10 profile bitstream\n"); else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_STILL_PICTURE) - pr_info("Main Still Picture profile bitstream\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Main Still Picture profile bitstream\n"); else if (ptl->profile_idc == FF_PROFILE_HEVC_REXT) - pr_info("Range Extension profile bitstream\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Range Extension profile bitstream\n"); else - pr_info("Unknown HEVC profile: %d\n", ptl->profile_idc); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Unknown HEVC profile: %d\n", ptl->profile_idc); for (i = 0; i < 32; i++) { ptl->profile_compatibility_flag[i] = get_bits1(gb); @@ -157,7 +157,7 @@ static int parse_ptl(struct get_bits_context *gb, struct PTL *ptl, int max_num_s int i; if (decode_profile_tier_level(gb, &ptl->general_ptl) < 0 || get_bits_left(gb) < 8 + (8*2 * (max_num_sub_layers - 1 > 0))) { - pr_err("PTL information too short\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "PTL information too short\n"); return -1; } @@ -174,12 +174,12 @@ static int parse_ptl(struct get_bits_context *gb, struct PTL *ptl, int max_num_s for (i = 0; i < max_num_sub_layers - 1; i++) { if (ptl->sub_layer_profile_present_flag[i] && decode_profile_tier_level(gb, &ptl->sub_layer_ptl[i]) < 0) { - pr_err("PTL information for sublayer %i too short\n", i); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "PTL information for sublayer %i too short\n", i); return -1; } if (ptl->sub_layer_level_present_flag[i]) { if (get_bits_left(gb) < 8) { - pr_err("Not enough data for sublayer %i level_idc\n", i); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Not enough data for sublayer %i level_idc\n", i); return -1; } else ptl->sub_layer_ptl[i].level_idc = get_bits(gb, 8); @@ -255,7 +255,7 @@ static int decode_hrd(struct get_bits_context *gb, if (!low_delay) { nb_cpb = get_ue_golomb_long(gb) + 1; if (nb_cpb < 1 || nb_cpb > 32) { - pr_err("nb_cpb %d invalid\n", nb_cpb); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "nb_cpb %d invalid\n", nb_cpb); return -1; } } @@ -273,16 +273,16 @@ int ff_hevc_parse_vps(struct get_bits_context *gb, struct h265_VPS_t *vps) int i,j; int vps_id = 0; - pr_info("Decoding VPS\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Decoding VPS\n"); vps_id = get_bits(gb, 4); if (vps_id >= HEVC_MAX_VPS_COUNT) { - pr_err("VPS id out of range: %d\n", vps_id); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "VPS id out of range: %d\n", vps_id); goto err; } if (get_bits(gb, 2) != 3) { // vps_reserved_three_2bits - pr_err("vps_reserved_three_2bits is not three\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "vps_reserved_three_2bits is not three\n"); goto err; } @@ -291,12 +291,12 @@ int ff_hevc_parse_vps(struct get_bits_context *gb, struct h265_VPS_t *vps) vps->vps_temporal_id_nesting_flag = get_bits1(gb); if (get_bits(gb, 16) != 0xffff) { // vps_reserved_ffff_16bits - pr_err("vps_reserved_ffff_16bits is not 0xffff\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "vps_reserved_ffff_16bits is not 0xffff\n"); goto err; } if (vps->vps_max_sub_layers > HEVC_MAX_SUB_LAYERS) { - pr_err("vps_max_sub_layers out of range: %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "vps_max_sub_layers out of range: %d\n", vps->vps_max_sub_layers); goto err; } @@ -313,12 +313,12 @@ int ff_hevc_parse_vps(struct get_bits_context *gb, struct h265_VPS_t *vps) vps->vps_max_latency_increase[i] = get_ue_golomb_long(gb) - 1; if (vps->vps_max_dec_pic_buffering[i] > HEVC_MAX_DPB_SIZE || !vps->vps_max_dec_pic_buffering[i]) { - pr_err("vps_max_dec_pic_buffering_minus1 out of range: %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "vps_max_dec_pic_buffering_minus1 out of range: %d\n", vps->vps_max_dec_pic_buffering[i] - 1); goto err; } if (vps->vps_num_reorder_pics[i] > vps->vps_max_dec_pic_buffering[i] - 1) { - pr_err("vps_max_num_reorder_pics out of range: %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "vps_max_num_reorder_pics out of range: %d\n", vps->vps_num_reorder_pics[i]); goto err; } @@ -328,7 +328,7 @@ int ff_hevc_parse_vps(struct get_bits_context *gb, struct h265_VPS_t *vps) vps->vps_num_layer_sets = get_ue_golomb_long(gb) + 1; if (vps->vps_num_layer_sets < 1 || vps->vps_num_layer_sets > 1024 || (vps->vps_num_layer_sets - 1LL) * (vps->vps_max_layer_id + 1LL) > get_bits_left(gb)) { - pr_err("too many layer_id_included_flags\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "too many layer_id_included_flags\n"); goto err; } @@ -345,7 +345,7 @@ int ff_hevc_parse_vps(struct get_bits_context *gb, struct h265_VPS_t *vps) vps->vps_num_ticks_poc_diff_one = get_ue_golomb_long(gb) + 1; vps->vps_num_hrd_parameters = get_ue_golomb_long(gb); if (vps->vps_num_hrd_parameters > (u32)vps->vps_num_layer_sets) { - pr_err("vps_num_hrd_parameters %d is invalid\n", vps->vps_num_hrd_parameters); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "vps_num_hrd_parameters %d is invalid\n", vps->vps_num_hrd_parameters); goto err; } for (i = 0; i < vps->vps_num_hrd_parameters; i++) { @@ -360,7 +360,7 @@ int ff_hevc_parse_vps(struct get_bits_context *gb, struct h265_VPS_t *vps) get_bits1(gb); /* vps_extension_flag */ if (get_bits_left(gb) < 0) { - pr_err("Overread VPS by %d bits\n", -get_bits_left(gb)); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Overread VPS by %d bits\n", -get_bits_left(gb)); goto err; } @@ -398,7 +398,7 @@ static int map_pixel_format(struct h265_SPS_t *sps) if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P12; break; default: - pr_info("The following bit-depths are currently specified: 8, 9, 10 and 12 bits, " + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "The following bit-depths are currently specified: 8, 9, 10 and 12 bits, " "chroma_format_idc is %d, depth is %d\n", sps->chroma_format_idc, sps->bit_depth); return -1; @@ -466,7 +466,7 @@ static int scaling_list_data(struct get_bits_context *gb, // Copy from previous array. delta *= (size_id == 3) ? 3 : 1; if (matrix_id < delta) { - pr_err("Invalid delta in scaling list data: %d.\n", delta); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid delta in scaling list data: %d.\n", delta); return -1; } @@ -541,7 +541,7 @@ int ff_hevc_decode_short_term_rps(struct get_bits_context *gb, if (is_slice_header) { u32 delta_idx = get_ue_golomb_long(gb) + 1; if (delta_idx > sps->nb_st_rps) { - pr_err("Invalid value of delta_idx in slice header RPS: %d > %d.\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid value of delta_idx in slice header RPS: %d > %d.\n", delta_idx, sps->nb_st_rps); return -1; } @@ -553,7 +553,7 @@ int ff_hevc_decode_short_term_rps(struct get_bits_context *gb, delta_rps_sign = get_bits1(gb); abs_delta_rps = get_ue_golomb_long(gb) + 1; if (abs_delta_rps < 1 || abs_delta_rps > 32768) { - pr_err("Invalid value of abs_delta_rps: %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid value of abs_delta_rps: %d\n", abs_delta_rps); return -1; } @@ -579,7 +579,7 @@ int ff_hevc_decode_short_term_rps(struct get_bits_context *gb, } if (k >= ARRAY_SIZE(rps->used)) { - pr_err( "Invalid num_delta_pocs: %d\n", k); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid num_delta_pocs: %d\n", k); return -1; } @@ -623,7 +623,7 @@ int ff_hevc_decode_short_term_rps(struct get_bits_context *gb, if (rps->num_negative_pics >= HEVC_MAX_REFS || nb_positive_pics >= HEVC_MAX_REFS) { - pr_err("Too many refs in a short term RPS.\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Too many refs in a short term RPS.\n"); return -1; } @@ -633,7 +633,7 @@ int ff_hevc_decode_short_term_rps(struct get_bits_context *gb, for (i = 0; i < rps->num_negative_pics; i++) { delta_poc = get_ue_golomb_long(gb) + 1; if (delta_poc < 1 || delta_poc > 32768) { - pr_err("Invalid value of delta_poc: %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid value of delta_poc: %d\n", delta_poc); return -1; } @@ -645,7 +645,7 @@ int ff_hevc_decode_short_term_rps(struct get_bits_context *gb, for (i = 0; i < nb_positive_pics; i++) { delta_poc = get_ue_golomb_long(gb) + 1; if (delta_poc < 1 || delta_poc > 32768) { - pr_err("Invalid value of delta_poc: %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid value of delta_poc: %d\n", delta_poc); return -1; } @@ -664,7 +664,7 @@ static void decode_vui(struct get_bits_context *gb, struct h265_SPS_t *sps) struct get_bits_context backup; int sar_present, alt = 0; - pr_info("Decoding VUI\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Decoding VUI\n"); sar_present = get_bits1(gb); if (sar_present) { @@ -675,7 +675,8 @@ static void decode_vui(struct get_bits_context *gb, struct h265_SPS_t *sps) vui->sar.num = get_bits(gb, 16); vui->sar.den = get_bits(gb, 16); } else - pr_info("Unknown SAR index: %u.\n", sar_idx); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, + "Unknown SAR index: %u.\n", sar_idx); } vui->overscan_info_present_flag = get_bits1(gb); @@ -732,7 +733,7 @@ static void decode_vui(struct get_bits_context *gb, struct h265_SPS_t *sps) memcpy(&backup_vui, vui, sizeof(backup_vui)); if (get_bits_left(gb) >= 68 && show_bits_long(gb, 21) == 0x100000) { vui->default_display_window_flag = 0; - pr_info("Invalid default display window\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Invalid default display window\n"); } else vui->default_display_window_flag = get_bits1(gb); @@ -752,7 +753,7 @@ timing_info: if (get_bits_left(gb) < 66 && !alt) { // The alternate syntax seem to have timing info located // at where def_disp_win is normally located - pr_info("Strange VUI timing information, retrying...\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Strange VUI timing information, retrying...\n"); memcpy(vui, &backup_vui, sizeof(backup_vui)); memcpy(gb, &backup, sizeof(backup)); alt = 1; @@ -761,7 +762,7 @@ timing_info: vui->vui_num_units_in_tick = get_bits_long(gb, 32); vui->vui_time_scale = get_bits_long(gb, 32); if (alt) { - pr_info("Retry got %u/%u fps\n", + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Retry got %u/%u fps\n", vui->vui_time_scale, vui->vui_num_units_in_tick); } vui->vui_poc_proportional_to_timing_flag = get_bits1(gb); @@ -775,7 +776,7 @@ timing_info: vui->bitstream_restriction_flag = get_bits1(gb); if (vui->bitstream_restriction_flag) { if (get_bits_left(gb) < 8 && !alt) { - pr_info("Strange VUI bitstream restriction information, retrying" + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Strange VUI bitstream restriction information, retrying" " from timing information...\n"); memcpy(vui, &backup_vui, sizeof(backup_vui)); memcpy(gb, &backup, sizeof(backup)); @@ -794,7 +795,7 @@ timing_info: if (get_bits_left(gb) < 1 && !alt) { // XXX: Alternate syntax when sps_range_extension_flag != 0? - pr_info("Overread in VUI, retrying from timing information...\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Overread in VUI, retrying from timing information...\n"); memcpy(vui, &backup_vui, sizeof(backup_vui)); memcpy(gb, &backup, sizeof(backup)); alt = 1; @@ -811,13 +812,13 @@ int ff_hevc_parse_sps(struct get_bits_context *gb, struct h265_SPS_t *sps) sps->vps_id = get_bits(gb, 4); if (sps->vps_id >= HEVC_MAX_VPS_COUNT) { - pr_err("VPS id out of range: %d\n", sps->vps_id); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "VPS id out of range: %d\n", sps->vps_id); return -1; } sps->max_sub_layers = get_bits(gb, 3) + 1; if (sps->max_sub_layers > HEVC_MAX_SUB_LAYERS) { - pr_err("sps_max_sub_layers out of range: %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "sps_max_sub_layers out of range: %d\n", sps->max_sub_layers); return -1; } @@ -829,13 +830,13 @@ int ff_hevc_parse_sps(struct get_bits_context *gb, struct h265_SPS_t *sps) sps->sps_id = get_ue_golomb_long(gb); if (sps->sps_id >= HEVC_MAX_SPS_COUNT) { - pr_err("SPS id out of range: %d\n", sps->sps_id); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "SPS id out of range: %d\n", sps->sps_id); return -1; } sps->chroma_format_idc = get_ue_golomb_long(gb); if (sps->chroma_format_idc > 3U) { - pr_err("chroma_format_idc %d is invalid\n", sps->chroma_format_idc); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "chroma_format_idc %d is invalid\n", sps->chroma_format_idc); return -1; } @@ -848,7 +849,7 @@ int ff_hevc_parse_sps(struct get_bits_context *gb, struct h265_SPS_t *sps) sps->width = get_ue_golomb_long(gb); sps->height = get_ue_golomb_long(gb); if (sps->width > 8192 || sps->height > 8192) { - pr_err("width or height oversize.\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "width or height oversize.\n"); return -1; } @@ -865,7 +866,7 @@ int ff_hevc_parse_sps(struct get_bits_context *gb, struct h265_SPS_t *sps) sps->bit_depth = get_ue_golomb_long(gb) + 8; bit_depth_chroma = get_ue_golomb_long(gb) + 8; if (sps->chroma_format_idc && bit_depth_chroma != sps->bit_depth) { - pr_err("Luma bit depth (%d) is different from chroma bit depth (%d), this is unsupported.\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Luma bit depth (%d) is different from chroma bit depth (%d), this is unsupported.\n", sps->bit_depth, bit_depth_chroma); return -1; } @@ -877,7 +878,7 @@ int ff_hevc_parse_sps(struct get_bits_context *gb, struct h265_SPS_t *sps) sps->log2_max_poc_lsb = get_ue_golomb_long(gb) + 4; if (sps->log2_max_poc_lsb > 16) { - pr_err("log2_max_pic_order_cnt_lsb_minus4 out range: %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "log2_max_pic_order_cnt_lsb_minus4 out range: %d\n", sps->log2_max_poc_lsb - 4); return -1; } @@ -889,12 +890,12 @@ int ff_hevc_parse_sps(struct get_bits_context *gb, struct h265_SPS_t *sps) sps->temporal_layer[i].num_reorder_pics = get_ue_golomb_long(gb); sps->temporal_layer[i].max_latency_increase = get_ue_golomb_long(gb) - 1; if (sps->temporal_layer[i].max_dec_pic_buffering > (u32)HEVC_MAX_DPB_SIZE) { - pr_err("sps_max_dec_pic_buffering_minus1 out of range: %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "sps_max_dec_pic_buffering_minus1 out of range: %d\n", sps->temporal_layer[i].max_dec_pic_buffering - 1U); return -1; } if (sps->temporal_layer[i].num_reorder_pics > sps->temporal_layer[i].max_dec_pic_buffering - 1) { - pr_info("sps_max_num_reorder_pics out of range: %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "sps_max_num_reorder_pics out of range: %d\n", sps->temporal_layer[i].num_reorder_pics); if (sps->temporal_layer[i].num_reorder_pics > HEVC_MAX_DPB_SIZE - 1) { return -1; @@ -918,22 +919,22 @@ int ff_hevc_parse_sps(struct get_bits_context *gb, struct h265_SPS_t *sps) sps->log2_max_trafo_size = log2_diff_max_min_transform_block_size + sps->log2_min_tb_size; if (sps->log2_min_cb_size < 3 || sps->log2_min_cb_size > 30) { - pr_err("Invalid value %d for log2_min_cb_size", sps->log2_min_cb_size); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid value %d for log2_min_cb_size", sps->log2_min_cb_size); return -1; } if (sps->log2_diff_max_min_coding_block_size > 30) { - pr_err("Invalid value %d for log2_diff_max_min_coding_block_size", sps->log2_diff_max_min_coding_block_size); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid value %d for log2_diff_max_min_coding_block_size", sps->log2_diff_max_min_coding_block_size); return -1; } if (sps->log2_min_tb_size >= sps->log2_min_cb_size || sps->log2_min_tb_size < 2) { - pr_err("Invalid value for log2_min_tb_size"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid value for log2_min_tb_size"); return -1; } if (log2_diff_max_min_transform_block_size < 0 || log2_diff_max_min_transform_block_size > 30) { - pr_err("Invalid value %d for log2_diff_max_min_transform_block_size", log2_diff_max_min_transform_block_size); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid value %d for log2_diff_max_min_transform_block_size", log2_diff_max_min_transform_block_size); return -1; } @@ -962,7 +963,7 @@ int ff_hevc_parse_sps(struct get_bits_context *gb, struct h265_SPS_t *sps) sps->pcm.log2_max_pcm_cb_size = sps->pcm.log2_min_pcm_cb_size + get_ue_golomb_long(gb); if (FFMAX(sps->pcm.bit_depth, sps->pcm.bit_depth_chroma) > sps->bit_depth) { - pr_err("PCM bit depth (%d, %d) is greater than normal bit depth (%d)\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "PCM bit depth (%d, %d) is greater than normal bit depth (%d)\n", sps->pcm.bit_depth, sps->pcm.bit_depth_chroma, sps->bit_depth); return -1; } @@ -972,7 +973,7 @@ int ff_hevc_parse_sps(struct get_bits_context *gb, struct h265_SPS_t *sps) sps->nb_st_rps = get_ue_golomb_long(gb); if (sps->nb_st_rps > HEVC_MAX_SHORT_TERM_REF_PIC_SETS) { - pr_err("Too many short term RPS: %d.\n", sps->nb_st_rps); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Too many short term RPS: %d.\n", sps->nb_st_rps); return -1; } for (i = 0; i < sps->nb_st_rps; i++) { @@ -984,7 +985,7 @@ int ff_hevc_parse_sps(struct get_bits_context *gb, struct h265_SPS_t *sps) if (sps->long_term_ref_pics_present_flag) { sps->num_long_term_ref_pics_sps = get_ue_golomb_long(gb); if (sps->num_long_term_ref_pics_sps > HEVC_MAX_LONG_TERM_REF_PICS) { - pr_err("Too many long term ref pics: %d.\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Too many long term ref pics: %d.\n", sps->num_long_term_ref_pics_sps); return -1; } @@ -1011,17 +1012,17 @@ int ff_hevc_parse_sps(struct get_bits_context *gb, struct h265_SPS_t *sps) sps->explicit_rdpcm_enabled_flag = get_bits1(gb); sps->extended_precision_processing_flag = get_bits1(gb); if (sps->extended_precision_processing_flag) - pr_info("extended_precision_processing_flag not yet implemented\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "extended_precision_processing_flag not yet implemented\n"); sps->intra_smoothing_disabled_flag = get_bits1(gb); sps->high_precision_offsets_enabled_flag = get_bits1(gb); if (sps->high_precision_offsets_enabled_flag) - pr_info("high_precision_offsets_enabled_flag not yet implemented\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "high_precision_offsets_enabled_flag not yet implemented\n"); sps->persistent_rice_adaptation_enabled_flag = get_bits1(gb); sps->cabac_bypass_alignment_enabled_flag = get_bits1(gb); if (sps->cabac_bypass_alignment_enabled_flag) - pr_info("cabac_bypass_alignment_enabled_flag not yet implemented\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "cabac_bypass_alignment_enabled_flag not yet implemented\n"); } } @@ -1030,7 +1031,7 @@ int ff_hevc_parse_sps(struct get_bits_context *gb, struct h265_SPS_t *sps) ow->top_offset >= INT_MAX - ow->bottom_offset || ow->left_offset + ow->right_offset >= sps->width || ow->top_offset + ow->bottom_offset >= sps->height) { - pr_err("Invalid cropping offsets: %u/%u/%u/%u\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid cropping offsets: %u/%u/%u/%u\n", ow->left_offset, ow->right_offset, ow->top_offset, ow->bottom_offset); return -1; } @@ -1041,12 +1042,12 @@ int ff_hevc_parse_sps(struct get_bits_context *gb, struct h265_SPS_t *sps) sps->log2_min_pu_size = sps->log2_min_cb_size - 1; if (sps->log2_ctb_size > HEVC_MAX_LOG2_CTB_SIZE) { - pr_err("CTB size out of range: 2^%d\n", sps->log2_ctb_size); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "CTB size out of range: 2^%d\n", sps->log2_ctb_size); return -1; } if (sps->log2_ctb_size < 4) { - pr_err("log2_ctb_size %d differs from the bounds of any known profile\n", sps->log2_ctb_size); - pr_err("log2_ctb_size %d", sps->log2_ctb_size); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "log2_ctb_size %d differs from the bounds of any known profile\n", sps->log2_ctb_size); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "log2_ctb_size %d", sps->log2_ctb_size); return -1; } @@ -1065,32 +1066,32 @@ int ff_hevc_parse_sps(struct get_bits_context *gb, struct h265_SPS_t *sps) if (av_mod_uintp2(sps->width, sps->log2_min_cb_size) || av_mod_uintp2(sps->height, sps->log2_min_cb_size)) { - pr_err("Invalid coded frame dimensions.\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid coded frame dimensions.\n"); return -1; } if (sps->max_transform_hierarchy_depth_inter > sps->log2_ctb_size - sps->log2_min_tb_size) { - pr_err("max_transform_hierarchy_depth_inter out of range: %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "max_transform_hierarchy_depth_inter out of range: %d\n", sps->max_transform_hierarchy_depth_inter); return -1; } if (sps->max_transform_hierarchy_depth_intra > sps->log2_ctb_size - sps->log2_min_tb_size) { - pr_err("max_transform_hierarchy_depth_intra out of range: %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "max_transform_hierarchy_depth_intra out of range: %d\n", sps->max_transform_hierarchy_depth_intra); return -1; } if (sps->log2_max_trafo_size > FFMIN(sps->log2_ctb_size, 5)) { - pr_err("max transform block size out of range: %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "max transform block size out of range: %d\n", sps->log2_max_trafo_size); return -1; } if (get_bits_left(gb) < 0) { - pr_err("Overread SPS by %d bits\n", -get_bits_left(gb)); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Overread SPS by %d bits\n", -get_bits_left(gb)); return -1; } - pr_info("Parsed SPS: id %d; ref: %d, coded wxh: %dx%d, cropped wxh: %dx%d; pix_fmt: %d.\n", + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Parsed SPS: id %d; ref: %d, coded wxh: %dx%d, cropped wxh: %dx%d; pix_fmt: %d.\n", sps->sps_id, sps->temporal_layer[0].num_reorder_pics, sps->width, sps->height, sps->width - (sps->output_window.left_offset + sps->output_window.right_offset), sps->height - (sps->output_window.top_offset + sps->output_window.bottom_offset), @@ -1205,7 +1206,7 @@ static int decode_extradata_ps(u8 *data, int size, struct h265_param_sets *ps) if (get_bits1(&gb) != 0) { ret = -1; - pr_err("invalid data, return!\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "invalid data, return!\n"); goto out; } @@ -1241,7 +1242,7 @@ static int decode_extradata_ps(u8 *data, int size, struct h265_param_sets *ps) ps->pps_parsed = true; break;*/ default: - pr_err("Unsupport parser nal type (%s).\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Unsupport parser nal type (%s).\n", hevc_nal_unit_name(nal_type)); break; } @@ -1264,7 +1265,7 @@ int h265_decode_extradata_ps(u8 *buf, int size, struct h265_param_sets *ps) len = size - (p - buf); ret = decode_extradata_ps(p, len, ps); if (ret) { - pr_err("parse extra data failed. err: %d\n", ret); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "parse extra data failed. err: %d\n", ret); return ret; } diff --git a/drivers/amvdec_ports/decoder/aml_hevc_parser.h b/drivers/amvdec_ports/decoder/aml_hevc_parser.h index 267450f..f55c381 100644 --- a/drivers/amvdec_ports/decoder/aml_hevc_parser.h +++ b/drivers/amvdec_ports/decoder/aml_hevc_parser.h @@ -19,6 +19,7 @@ #ifndef AML_HEVC_PARSER_H #define AML_HEVC_PARSER_H +#include "../aml_vcodec_drv.h" #include "../utils/common.h" #define MAX_DPB_SIZE 16 // A.4.1 diff --git a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c index 1d9d94b..c582ab0 100644 --- a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c +++ b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c @@ -33,7 +33,7 @@ static int find_marker(const u8 **pbuf_ptr, const u8 *buf_end) buf_ptr = buf_end; val = -1; found: - pr_info("find_marker skipped %d bytes\n", skipped); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "find_marker skipped %d bytes\n", skipped); *pbuf_ptr = buf_ptr; return val; @@ -100,7 +100,7 @@ int ff_mjpeg_find_marker(struct MJpegDecodeContext *s, memset(s->buffer + *unescaped_buf_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - pr_info("escaping removed %d bytes\n", + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "escaping removed %d bytes\n", (int)((buf_end - *buf_ptr) - (dst - s->buffer))); } else if (start_code == SOS && s->ls) { const u8 *src = *buf_ptr; @@ -131,7 +131,7 @@ int ff_mjpeg_find_marker(struct MJpegDecodeContext *s, if (x == 0xFF && b < t) { x = src[b++]; if (x & 0x80) { - pr_err("Invalid escape sequence\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid escape sequence\n"); x &= 0x7f; } put_bits(&pb, 7, x); @@ -168,14 +168,14 @@ int ff_mjpeg_decode_sof(struct MJpegDecodeContext *s) bits = get_bits(&s->gb, 8); if (bits > 16 || bits < 1) { - pr_err("bits %d is invalid\n", bits); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "bits %d is invalid\n", bits); return -1; } height = get_bits(&s->gb, 16); width = get_bits(&s->gb, 16); - pr_info("sof0: picture: %dx%d\n", width, height); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "sof0: picture: %dx%d\n", width, height); nb_components = get_bits(&s->gb, 8); if (nb_components <= 0 || @@ -197,16 +197,16 @@ int ff_mjpeg_decode_sof(struct MJpegDecodeContext *s) s->v_max = v_count[i]; s->quant_index[i] = get_bits(&s->gb, 8); if (s->quant_index[i] >= 4) { - pr_err("quant_index is invalid\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "quant_index is invalid\n"); return -1; } if (!h_count[i] || !v_count[i]) { - pr_err("Invalid sampling factor in component %d %d:%d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid sampling factor in component %d %d:%d\n", i, h_count[i], v_count[i]); return -1; } - pr_info("component %d %d:%d id: %d quant:%d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "component %d %d:%d id: %d quant:%d\n", i, h_count[i], v_count[i], s->component_id[i], s->quant_index[i]); } @@ -256,21 +256,21 @@ static int ff_mjpeg_decode_frame(u8 *buf, int buf_size, struct MJpegDecodeContex if (start_code < 0) { break; } else if (unescaped_buf_size > INT_MAX / 8) { - pr_err("MJPEG packet 0x%x too big (%d/%d), corrupt data?\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "MJPEG packet 0x%x too big (%d/%d), corrupt data?\n", start_code, unescaped_buf_size, buf_size); return -1; } - pr_info("marker=%x avail_size_in_buf=%d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "marker=%x avail_size_in_buf=%d\n", start_code, (int)(buf_end - buf_ptr)); ret = init_get_bits8(&s->gb, unescaped_buf_ptr, unescaped_buf_size); if (ret < 0) { - pr_err("invalid buffer\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "invalid buffer\n"); goto fail; } s->start_code = start_code; - pr_info("startcode: %X\n", start_code); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "startcode: %X\n", start_code); switch (start_code) { case SOF0: @@ -348,23 +348,23 @@ static int ff_mjpeg_decode_frame(u8 *buf, int buf_size, struct MJpegDecodeContex case SOF14: case SOF15: case JPG: - pr_err("mjpeg: unsupported coding type (%x)\n", start_code); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "mjpeg: unsupported coding type (%x)\n", start_code); break; } skip: /* eof process start code */ buf_ptr += (get_bits_count(&s->gb) + 7) / 8; - pr_info("marker parser used %d bytes (%d bits)\n", + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "marker parser used %d bytes (%d bits)\n", (get_bits_count(&s->gb) + 7) / 8, get_bits_count(&s->gb)); } - pr_err("No JPEG data found in image\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "No JPEG data found in image\n"); return -1; fail: s->got_picture = 0; return ret; the_end: - pr_info("decode frame unused %d bytes\n", (int)(buf_end - buf_ptr)); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "decode frame unused %d bytes\n", (int)(buf_end - buf_ptr)); return 0; } @@ -382,7 +382,7 @@ int mjpeg_decode_extradata_ps(u8 *buf, int size, struct mjpeg_param_sets *ps) ret = ff_mjpeg_decode_frame(buf, size, &ps->dec_ps); if (ret) { - pr_err("parse extra data failed. err: %d\n", ret); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "parse extra data failed. err: %d\n", ret); vfree(ps->dec_ps.buffer); return ret; } diff --git a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h index 20fdbbc..cc4c453 100644 --- a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h +++ b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h @@ -1,6 +1,7 @@ #ifndef AML_MPEG12_PARSER_H #define AML_MPEG12_PARSER_H +#include "../aml_vcodec_drv.h" #include "../utils/pixfmt.h" #include "../utils/common.h" #include "../utils/get_bits.h" diff --git a/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h b/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h index de1292d..203bb51 100644 --- a/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h +++ b/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h @@ -1,6 +1,7 @@ #ifndef AML_MPEG12_PARSER_H #define AML_MPEG12_PARSER_H +#include "../aml_vcodec_drv.h" #include "../utils/pixfmt.h" #include "../utils/common.h" diff --git a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c index b16c2d1..9c47c08 100644 --- a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c +++ b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c @@ -149,7 +149,7 @@ static int decode_studio_vol_header(struct mpeg4_dec_param *ctx, struct get_bits ctx->rgb = get_bits1(gb); /* rgb_components */ s->chroma_format = get_bits(gb, 2); /* chroma_format */ if (!s->chroma_format) { - pr_err("illegal chroma format\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "illegal chroma format\n"); return -1; } @@ -162,7 +162,7 @@ static int decode_studio_vol_header(struct mpeg4_dec_param *ctx, struct get_bits } } else { - pr_err("MPEG-4 Studio profile bit-depth %u", bits_per_raw_sample); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "MPEG-4 Studio profile bit-depth %u", bits_per_raw_sample); return -1; } ctx->bits_per_raw_sample = bits_per_raw_sample; @@ -253,7 +253,7 @@ static int decode_vol_header(struct mpeg4_dec_param *ctx, struct get_bits_contex if ((ctx->vol_control_parameters = get_bits1(gb))) { /* vol control parameter */ int chroma_format = get_bits(gb, 2); if (chroma_format != CHROMA_420) - pr_err("illegal chroma format\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "illegal chroma format\n"); s->low_delay = get_bits1(gb); if (get_bits1(gb)) { /* vbv parameters */ @@ -286,9 +286,9 @@ static int decode_vol_header(struct mpeg4_dec_param *ctx, struct get_bits_contex ctx->shape = get_bits(gb, 2); /* vol shape */ if (ctx->shape != RECT_SHAPE) - pr_err("only rectangular vol supported\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "only rectangular vol supported\n"); if (ctx->shape == GRAY_SHAPE && vo_ver_id != 1) { - pr_err("Gray shape not supported\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Gray shape not supported\n"); skip_bits(gb, 4); /* video_object_layer_shape_extension */ } @@ -296,7 +296,7 @@ static int decode_vol_header(struct mpeg4_dec_param *ctx, struct get_bits_contex ctx->framerate.num = get_bits(gb, 16); if (!ctx->framerate.num) { - pr_err("framerate==0\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "framerate==0\n"); return -1; } @@ -336,14 +336,14 @@ static int decode_vol_header(struct mpeg4_dec_param *ctx, struct get_bits_contex s->progressive_frame = get_bits1(gb) ^ 1; s->interlaced_dct = 0; if (!get_bits1(gb)) /* OBMC Disable */ - pr_info("MPEG-4 OBMC not supported (very likely buggy encoder)\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "MPEG-4 OBMC not supported (very likely buggy encoder)\n"); if (vo_ver_id == 1) ctx->vol_sprite_usage = get_bits1(gb); /* vol_sprite_usage */ else ctx->vol_sprite_usage = get_bits(gb, 2); /* vol_sprite_usage */ if (ctx->vol_sprite_usage == STATIC_SPRITE) - pr_err("Static Sprites not supported\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Static Sprites not supported\n"); if (ctx->vol_sprite_usage == STATIC_SPRITE || ctx->vol_sprite_usage == GMC_SPRITE) { if (ctx->vol_sprite_usage == STATIC_SPRITE) { @@ -358,7 +358,7 @@ static int decode_vol_header(struct mpeg4_dec_param *ctx, struct get_bits_contex } ctx->num_sprite_warping_points = get_bits(gb, 6); if (ctx->num_sprite_warping_points > 3) { - pr_err("%d sprite_warping_points\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "%d sprite_warping_points\n", ctx->num_sprite_warping_points); ctx->num_sprite_warping_points = 0; return -1; @@ -373,9 +373,9 @@ static int decode_vol_header(struct mpeg4_dec_param *ctx, struct get_bits_contex if (get_bits1(gb) == 1) { /* not_8_bit */ s->quant_precision = get_bits(gb, 4); /* quant_precision */ if (get_bits(gb, 4) != 8) /* bits_per_pixel */ - pr_err("N-bit not supported\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "N-bit not supported\n"); if (s->quant_precision != 5) - pr_err("quant precision %d\n", s->quant_precision); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "quant precision %d\n", s->quant_precision); if (s->quant_precision<3 || s->quant_precision>9) { s->quant_precision = 5; } @@ -396,7 +396,7 @@ static int decode_vol_header(struct mpeg4_dec_param *ctx, struct get_bits_contex for (i = 0; i < 64; i++) { //int j; if (get_bits_left(gb) < 8) { - pr_err("insufficient data for custom matrix\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "insufficient data for custom matrix\n"); return -1; } v = get_bits(gb, 8); @@ -423,7 +423,7 @@ static int decode_vol_header(struct mpeg4_dec_param *ctx, struct get_bits_contex for (i = 0; i < 64; i++) { //int j; if (get_bits_left(gb) < 8) { - pr_err("insufficient data for custom matrix\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "insufficient data for custom matrix\n"); return -1; } v = get_bits(gb, 8); @@ -453,7 +453,7 @@ static int decode_vol_header(struct mpeg4_dec_param *ctx, struct get_bits_contex s->quarter_sample = 0; if (get_bits_left(gb) < 4) { - pr_err("VOL Header truncated\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "VOL Header truncated\n"); return -1; } @@ -502,7 +502,7 @@ static int decode_vol_header(struct mpeg4_dec_param *ctx, struct get_bits_contex ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* qpel */ } } else - pr_err("Invalid Complexity estimation method %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid Complexity estimation method %d\n", estimation_method); } else { @@ -521,12 +521,12 @@ no_cplx_est: if (vo_ver_id != 1) { ctx->new_pred = get_bits1(gb); if (ctx->new_pred) { - pr_err("new pred not supported\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "new pred not supported\n"); skip_bits(gb, 2); /* requested upstream message type */ skip_bits1(gb); /* newpred segment type */ } if (get_bits1(gb)) // reduced_res_vop - pr_err("reduced resolution VOP not supported\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "reduced resolution VOP not supported\n"); } else { ctx->new_pred = 0; } @@ -556,22 +556,21 @@ no_cplx_est: ctx->scalability = 0; *gb = bak; } else - pr_err("scalability not supported\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "scalability not supported\n"); // bin shape stuff FIXME } } if (1) { - pr_info("tb %d/%d, tincrbits:%d, qp_prec:%d, ps:%d, low_delay:%d %s%s%s%s\n", - ctx->framerate.den, ctx->framerate.num, - ctx->time_increment_bits, - s->quant_precision, - s->progressive_sequence, - s->low_delay, - ctx->scalability ? "scalability " :"" , s->quarter_sample ? "qpel " : "", - s->data_partitioning ? "partition " : "", ctx->rvlc ? "rvlc " : "" - ); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "tb %d/%d, tincrbits:%d, qp_prec:%d, ps:%d, low_delay:%d %s%s%s%s\n", + ctx->framerate.den, ctx->framerate.num, + ctx->time_increment_bits, + s->quant_precision, + s->progressive_sequence, + s->low_delay, + ctx->scalability ? "scalability " :"" , s->quarter_sample ? "qpel " : "", + s->data_partitioning ? "partition " : "", ctx->rvlc ? "rvlc " : ""); } return 0; @@ -616,7 +615,7 @@ static int decode_user_data(struct mpeg4_dec_param *ctx, struct get_bits_context e = sscanf(buf, "Lavc%d.%d.%d", &ver, &ver2, &ver3) + 1; if (e > 1) { if (ver > 0xFFU || ver2 > 0xFFU || ver3 > 0xFFU) { - pr_info("Unknown Lavc version string encountered, %d.%d.%d; " + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Unknown Lavc version string encountered, %d.%d.%d; " "clamping sub-version values to 8-bits.\n", ver, ver2, ver3); } @@ -644,7 +643,7 @@ static int mpeg4_decode_gop_header(struct MpegEncContext *s, struct get_bits_con int hours, minutes, seconds; if (!show_bits(gb, 23)) { - pr_err("GOP header invalid\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "GOP header invalid\n"); return -1; } @@ -685,7 +684,7 @@ static int decode_studiovisualobject(struct mpeg4_dec_param *ctx, struct get_bit skip_bits(gb, 4); /* visual_object_verid */ visual_object_type = get_bits(gb, 4); if (visual_object_type != VOT_VIDEO_ID) { - pr_err("VO type %u", visual_object_type); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "VO type %u", visual_object_type); return -1; } @@ -818,7 +817,7 @@ static int decode_vop_header(struct mpeg4_dec_param *ctx, struct get_bits_contex s->pict_type = get_bits(gb, 2) + AV_PICTURE_TYPE_I; /* pict type: I = 0 , P = 1 */ if (s->pict_type == AV_PICTURE_TYPE_B && s->low_delay && ctx->vol_control_parameters == 0) { - pr_err("low_delay flag set incorrectly, clearing it\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "low_delay flag set incorrectly, clearing it\n"); s->low_delay = 0; } @@ -836,7 +835,7 @@ static int decode_vop_header(struct mpeg4_dec_param *ctx, struct get_bits_contex if (ctx->time_increment_bits == 0 || !(show_bits(gb, ctx->time_increment_bits + 1) & 1)) { - pr_info("time_increment_bits %d is invalid in relation to the current bitstream, this is likely caused by a missing VOL header\n", ctx->time_increment_bits); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "time_increment_bits %d is invalid in relation to the current bitstream, this is likely caused by a missing VOL header\n", ctx->time_increment_bits); for (ctx->time_increment_bits = 1; ctx->time_increment_bits < 16; @@ -850,7 +849,7 @@ static int decode_vop_header(struct mpeg4_dec_param *ctx, struct get_bits_contex break; } - pr_info("time_increment_bits set to %d bits, based on bitstream analysis\n", ctx->time_increment_bits); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "time_increment_bits set to %d bits, based on bitstream analysis\n", ctx->time_increment_bits); if (ctx->framerate.num && 4*ctx->framerate.num < 1<time_increment_bits) { ctx->framerate.num = 1<time_increment_bits; //ctx->time_base = av_inv_q(av_mul_q(ctx->framerate, (AVRational){ctx->ticks_per_frame, 1})); @@ -900,14 +899,14 @@ static int decode_vop_header(struct mpeg4_dec_param *ctx, struct get_bits_contex pts = ROUNDED_DIV(s->time, ctx->framerate.den); else pts = AV_NOPTS_VALUE; - pr_info("MPEG4 PTS: %lld\n", pts); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "MPEG4 PTS: %lld\n", pts); check_marker(gb, "before vop_coded"); /* vop coded */ if (get_bits1(gb) != 1) { if (1) - pr_err("vop not coded\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "vop not coded\n"); return FRAME_SKIPPED; } if (ctx->new_pred) @@ -950,7 +949,7 @@ static int decode_vop_header(struct mpeg4_dec_param *ctx, struct get_bits_contex skip_bits_long(gb, ctx->cplx_estimation_trash_b); if (get_bits_left(gb) < 3) { - pr_err("Header truncated\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Header truncated\n"); return -1; } ctx->intra_dc_threshold = ff_mpeg4_dc_threshold[get_bits(gb, 3)]; @@ -969,9 +968,9 @@ static int decode_vop_header(struct mpeg4_dec_param *ctx, struct get_bits_contex //if (mpeg4_decode_sprite_trajectory(ctx, gb) < 0) //return -1; if (ctx->sprite_brightness_change) - pr_err("sprite_brightness_change not supported\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "sprite_brightness_change not supported\n"); if (ctx->vol_sprite_usage == STATIC_SPRITE) - pr_err("static sprite not supported\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "static sprite not supported\n"); } else { memset(s->sprite_offset, 0, sizeof(s->sprite_offset)); memset(s->sprite_delta, 0, sizeof(s->sprite_delta)); @@ -981,14 +980,14 @@ static int decode_vop_header(struct mpeg4_dec_param *ctx, struct get_bits_contex if (ctx->shape != BIN_ONLY_SHAPE) { s->chroma_qscale = s->qscale = get_bits(gb, s->quant_precision); if (s->qscale == 0) { - pr_err("Error, header damaged or not MPEG-4 header (qscale=0)\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Error, header damaged or not MPEG-4 header (qscale=0)\n"); return -1; // makes no sense to continue, as there is nothing left from the image then } if (s->pict_type != AV_PICTURE_TYPE_I) { s->f_code = get_bits(gb, 3); /* fcode_for */ if (s->f_code == 0) { - pr_err("Error, header damaged or not MPEG-4 header (f_code=0)\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Error, header damaged or not MPEG-4 header (f_code=0)\n"); s->f_code = 1; return -1; // makes no sense to continue, as there is nothing left from the image then } @@ -998,7 +997,7 @@ static int decode_vop_header(struct mpeg4_dec_param *ctx, struct get_bits_contex if (s->pict_type == AV_PICTURE_TYPE_B) { s->b_code = get_bits(gb, 3); if (s->b_code == 0) { - pr_err("Error, header damaged or not MPEG4 header (b_code=0)\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Error, header damaged or not MPEG4 header (b_code=0)\n"); s->b_code=1; return -1; // makes no sense to continue, as the MV decoding will break very quickly } @@ -1006,20 +1005,19 @@ static int decode_vop_header(struct mpeg4_dec_param *ctx, struct get_bits_contex s->b_code = 1; if (1) { - pr_info("qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d ce:%d/%d/%d time:%ld tincr:%d\n", - s->qscale, s->f_code, s->b_code, - s->pict_type == AV_PICTURE_TYPE_I ? "I" : (s->pict_type == AV_PICTURE_TYPE_P ? "P" : (s->pict_type == AV_PICTURE_TYPE_B ? "B" : "S")), - gb->size_in_bits,s->progressive_sequence, s->alternate_scan, - s->top_field_first, s->quarter_sample ? "q" : "h", - s->data_partitioning, ctx->resync_marker, - ctx->num_sprite_warping_points, s->sprite_warping_accuracy, - 1 - s->no_rounding, s->vo_type, - ctx->vol_control_parameters ? " VOLC" : " ", ctx->intra_dc_threshold, - ctx->cplx_estimation_trash_i, ctx->cplx_estimation_trash_p, - ctx->cplx_estimation_trash_b, - s->time, - time_increment - ); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d ce:%d/%d/%d time:%ld tincr:%d\n", + s->qscale, s->f_code, s->b_code, + s->pict_type == AV_PICTURE_TYPE_I ? "I" : (s->pict_type == AV_PICTURE_TYPE_P ? "P" : (s->pict_type == AV_PICTURE_TYPE_B ? "B" : "S")), + gb->size_in_bits,s->progressive_sequence, s->alternate_scan, + s->top_field_first, s->quarter_sample ? "q" : "h", + s->data_partitioning, ctx->resync_marker, + ctx->num_sprite_warping_points, s->sprite_warping_accuracy, + 1 - s->no_rounding, s->vo_type, + ctx->vol_control_parameters ? " VOLC" : " ", ctx->intra_dc_threshold, + ctx->cplx_estimation_trash_i, ctx->cplx_estimation_trash_p, + ctx->cplx_estimation_trash_b, + s->time, + time_increment); } if (!ctx->scalability) { @@ -1029,7 +1027,7 @@ static int decode_vop_header(struct mpeg4_dec_param *ctx, struct get_bits_contex if (ctx->enhancement_type) { int load_backward_shape = get_bits1(gb); if (load_backward_shape) - pr_err("load backward shape isn't supported\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "load backward shape isn't supported\n"); } skip_bits(gb, 2); // ref_select_code } @@ -1039,7 +1037,7 @@ static int decode_vop_header(struct mpeg4_dec_param *ctx, struct get_bits_contex * easily (although it's buggy too) */ if (s->vo_type == 0 && ctx->vol_control_parameters == 0 && ctx->divx_version == -1 && s->picture_number == 0) { - pr_info("looks like this file was encoded with (divx4/(old)xvid/opendivx) -> forcing low_delay flag\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "looks like this file was encoded with (divx4/(old)xvid/opendivx) -> forcing low_delay flag\n"); s->low_delay = 1; } @@ -1088,7 +1086,7 @@ int ff_mpeg4_decode_picture_header(struct mpeg4_dec_param *ctx, struct get_bits_ for (;;) { if (get_bits_count(gb) >= gb->size_in_bits) { if (gb->size_in_bits == 8) { - pr_info("frame skip %d\n", gb->size_in_bits); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "frame skip %d\n", gb->size_in_bits); return FRAME_SKIPPED; // divx bug } else return -1; // end of stream @@ -1102,66 +1100,66 @@ int ff_mpeg4_decode_picture_header(struct mpeg4_dec_param *ctx, struct get_bits_ continue; // no startcode if (1) { //debug - pr_info("startcode: %3X \n", startcode); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "startcode: %3X \n", startcode); if (startcode <= 0x11F) - pr_info("Video Object Start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Video Object Start\n"); else if (startcode <= 0x12F) - pr_info("Video Object Layer Start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Video Object Layer Start\n"); else if (startcode <= 0x13F) - pr_info("Reserved\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Reserved\n"); else if (startcode <= 0x15F) - pr_info("FGS bp start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "FGS bp start\n"); else if (startcode <= 0x1AF) - pr_info("Reserved\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Reserved\n"); else if (startcode == 0x1B0) - pr_info("Visual Object Seq Start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Visual Object Seq Start\n"); else if (startcode == 0x1B1) - pr_info("Visual Object Seq End\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Visual Object Seq End\n"); else if (startcode == 0x1B2) - pr_info("User Data\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "User Data\n"); else if (startcode == 0x1B3) - pr_info("Group of VOP start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Group of VOP start\n"); else if (startcode == 0x1B4) - pr_info("Video Session Error\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Video Session Error\n"); else if (startcode == 0x1B5) - pr_info("Visual Object Start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Visual Object Start\n"); else if (startcode == 0x1B6) - pr_info("Video Object Plane start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Video Object Plane start\n"); else if (startcode == 0x1B7) - pr_info("slice start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "slice start\n"); else if (startcode == 0x1B8) - pr_info("extension start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "extension start\n"); else if (startcode == 0x1B9) - pr_info("fgs start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "fgs start\n"); else if (startcode == 0x1BA) - pr_info("FBA Object start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "FBA Object start\n"); else if (startcode == 0x1BB) - pr_info("FBA Object Plane start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "FBA Object Plane start\n"); else if (startcode == 0x1BC) - pr_info("Mesh Object start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Mesh Object start\n"); else if (startcode == 0x1BD) - pr_info("Mesh Object Plane start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Mesh Object Plane start\n"); else if (startcode == 0x1BE) - pr_info("Still Texture Object start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Still Texture Object start\n"); else if (startcode == 0x1BF) - pr_info("Texture Spatial Layer start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Texture Spatial Layer start\n"); else if (startcode == 0x1C0) - pr_info("Texture SNR Layer start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Texture SNR Layer start\n"); else if (startcode == 0x1C1) - pr_info("Texture Tile start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Texture Tile start\n"); else if (startcode == 0x1C2) - pr_info("Texture Shape Layer start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "Texture Shape Layer start\n"); else if (startcode == 0x1C3) - pr_info("stuffing start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "stuffing start\n"); else if (startcode <= 0x1C5) - pr_info("reserved\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "reserved\n"); else if (startcode <= 0x1FF) - pr_info("System start\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "System start\n"); } if (startcode >= 0x120 && startcode <= 0x12F) { if (vol) { - pr_err("Ignoring multiple VOL headers\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Ignoring multiple VOL headers\n"); continue; } vol++; @@ -1180,7 +1178,7 @@ int ff_mpeg4_decode_picture_header(struct mpeg4_dec_param *ctx, struct get_bits_ next_start_code_studio(gb); extension_and_user_data(s, gb, 0); } else if (s->studio_profile) { - pr_err("Mixes studio and non studio profile\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Mixes studio and non studio profile\n"); return -1; } ctx->profile = profile; @@ -1202,7 +1200,7 @@ int ff_mpeg4_decode_picture_header(struct mpeg4_dec_param *ctx, struct get_bits_ end: if (s->studio_profile) { if (!bits_per_raw_sample) { - pr_err("Missing VOL header\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Missing VOL header\n"); return -1; } return decode_studio_vop_header(ctx, gb); @@ -1221,7 +1219,7 @@ int mpeg4_decode_extradata_ps(u8 *buf, int size, struct mpeg4_param_sets *ps) ret = ff_mpeg4_decode_picture_header(&ps->dec_ps, &gb); if (ret < -1) { - pr_err("Failed to parse extradata\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Failed to parse extradata\n"); return ret; } diff --git a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h index 543c631..09f392d 100644 --- a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h +++ b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h @@ -1,6 +1,7 @@ #ifndef AVCODEC_MPEG4VIDEO_H #define AVCODEC_MPEG4VIDEO_H +#include "../aml_vcodec_drv.h" #include "../utils/pixfmt.h" #include "../utils/common.h" diff --git a/drivers/amvdec_ports/decoder/aml_vp9_parser.c b/drivers/amvdec_ports/decoder/aml_vp9_parser.c index 2d82dfb..21d5283 100644 --- a/drivers/amvdec_ports/decoder/aml_vp9_parser.c +++ b/drivers/amvdec_ports/decoder/aml_vp9_parser.c @@ -31,11 +31,11 @@ static int read_colorspace_details(struct VP9Context *s, int profile) if (colorspace == AVCOL_SPC_RGB) { // RGB = profile 1 if (profile & 1) { if (get_bits1(&s->gb)) { - pr_err("Reserved bit set in RGB\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Reserved bit set in RGB\n"); return -1; } } else { - pr_err("RGB not supported in profile %d\n", profile); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "RGB not supported in profile %d\n", profile); return -1; } } else { @@ -52,10 +52,10 @@ static int read_colorspace_details(struct VP9Context *s, int profile) s->ss_v = get_bits1(&s->gb); s->pix_fmt = pix_fmt_for_ss[bits][s->ss_v][s->ss_h]; if (s->pix_fmt == AV_PIX_FMT_YUV420P) { - pr_err("YUV 4:2:0 not supported in profile %d\n", profile); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "YUV 4:2:0 not supported in profile %d\n", profile); return -1; } else if (get_bits1(&s->gb)) { - pr_err("Profile %d color details reserved bit set\n", profile); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Profile %d color details reserved bit set\n", profile); return -1; } } else { @@ -73,12 +73,12 @@ int decode_frame_header(const u8 *data, int size, struct VP9Context *s, int *ref /* general header */ if ((ret = init_get_bits8(&s->gb, data, size)) < 0) { - pr_err("Failed to initialize bitstream reader\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Failed to initialize bitstream reader\n"); return ret; } if (get_bits(&s->gb, 2) != 0x2) { // frame marker - pr_err("Invalid frame marker\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid frame marker\n"); return -1; } @@ -88,7 +88,7 @@ int decode_frame_header(const u8 *data, int size, struct VP9Context *s, int *ref profile += get_bits1(&s->gb); if (profile > 3) { - pr_err("Profile %d is not yet supported\n", profile); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Profile %d is not yet supported\n", profile); return -1; } @@ -108,7 +108,7 @@ int decode_frame_header(const u8 *data, int size, struct VP9Context *s, int *ref if (s->s.h.keyframe) { if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode - pr_err("Invalid sync code\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid sync code\n"); return -1; } if ((ret = read_colorspace_details(s,profile)) < 0) @@ -131,7 +131,7 @@ int decode_frame_header(const u8 *data, int size, struct VP9Context *s, int *ref s->s.h.resetctx = s->s.h.errorres ? 0 : get_bits(&s->gb, 2); if (s->s.h.intraonly) { if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode - pr_err("Invalid sync code\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid sync code\n"); return -1; } if (profile >= 1) { @@ -154,7 +154,7 @@ int decode_frame_header(const u8 *data, int size, struct VP9Context *s, int *ref s->render_width = s->width; s->render_height = s->height; } - pr_info("intra res: (%d x %d), render size: (%d x %d)\n", + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "intra res: (%d x %d), render size: (%d x %d)\n", s->width, s->height, s->render_width, s->render_height); } else { s->s.h.refreshrefmask = get_bits(&s->gb, 8); @@ -215,7 +215,7 @@ int vp9_superframe_split_filter(struct vp9_superframe_split *s) total_size += frame_size; if (frame_size < 0 || total_size > s->data_size - idx_size) { - pr_err( "Invalid frame size in a sframe: %d\n", + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid frame size in a sframe: %d\n", frame_size); ret = -EINVAL; goto fail; @@ -246,7 +246,7 @@ int vp9_superframe_split_filter(struct vp9_superframe_split *s) /* colorspace descriptor */ /* ... */ - pr_info("the frame is a superframe.\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "the frame is a superframe.\n"); } /*pr_err("in: %x, %d, out: %x, sizes %d,%d,%d,%d,%d,%d,%d,%d\n", @@ -277,7 +277,7 @@ int vp9_decode_extradata_ps(u8 *data, int size, struct vp9_param_sets *ps) s.data_size = size; ret = vp9_superframe_split_filter(&s); if (ret) { - pr_err("parse frames failed.\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "parse frames failed.\n"); return ret; } diff --git a/drivers/amvdec_ports/decoder/aml_vp9_parser.h b/drivers/amvdec_ports/decoder/aml_vp9_parser.h index b9f4489..c016eba 100644 --- a/drivers/amvdec_ports/decoder/aml_vp9_parser.h +++ b/drivers/amvdec_ports/decoder/aml_vp9_parser.h @@ -18,6 +18,7 @@ #ifndef AML_VP9_PARSER_H #define AML_VP9_PARSER_H +#include "../aml_vcodec_drv.h" #include "../utils/pixfmt.h" #include "../utils/get_bits.h" diff --git a/drivers/amvdec_ports/decoder/vdec_h264_if.c b/drivers/amvdec_ports/decoder/vdec_h264_if.c index eada4ea..04173d6 100644 --- a/drivers/amvdec_ports/decoder/vdec_h264_if.c +++ b/drivers/amvdec_ports/decoder/vdec_h264_if.c @@ -211,11 +211,13 @@ static void get_pic_info(struct vdec_h264_inst *inst, { *pic = inst->vsi->pic; - aml_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", - pic->visible_width, pic->visible_height, - pic->coded_width, pic->coded_height); - aml_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz, - pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "pic(%d, %d), buf(%d, %d)\n", + pic->visible_width, pic->visible_height, + pic->coded_width, pic->coded_height); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "Y(%d, %d), C(%d, %d)\n", pic->y_bs_sz, + pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz); } static void get_crop_info(struct vdec_h264_inst *inst, struct v4l2_rect *cr) @@ -225,14 +227,15 @@ static void get_crop_info(struct vdec_h264_inst *inst, struct v4l2_rect *cr) cr->width = inst->vsi->crop.width; cr->height = inst->vsi->crop.height; - aml_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d", - cr->left, cr->top, cr->width, cr->height); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "l=%d, t=%d, w=%d, h=%d\n", + cr->left, cr->top, cr->width, cr->height); } static void get_dpb_size(struct vdec_h264_inst *inst, unsigned int *dpb_sz) { *dpb_sz = inst->vsi->dec.dpb_sz; - aml_vcodec_debug(inst, "sz=%d", *dpb_sz); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, "sz=%d\n", *dpb_sz); } static void skip_aud_data(u8 **data, u32 *size) @@ -314,13 +317,15 @@ static int vdec_h264_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) inst->vfm.ada_ctx = &inst->vdec; ret = vcodec_vfm_init(&inst->vfm); if (ret) { - pr_err("%s, init vfm failed.\n", __func__); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "init vfm failed.\n"); goto err; } ret = video_decoder_init(&inst->vdec); if (ret) { - aml_vcodec_err(inst, "vdec_h264 init err=%d", ret); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "vdec_h264 init err=%d\n", ret); goto err; } @@ -333,14 +338,15 @@ static int vdec_h264_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) /* alloc the header buffer to be used cache sps or spp etc.*/ inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL); - if (!inst->vsi) { + if (!inst->vsi->header_buf) { ret = -ENOMEM; goto err; } init_completion(&inst->comp); - aml_vcodec_debug(inst, "H264 Instance >> %p", inst); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "H264 Instance >> %lx", (ulong) inst); ctx->ada_ctx = &inst->vdec; *h_vdec = (unsigned long)inst; @@ -485,7 +491,7 @@ static void fill_vdec_params(struct vdec_h264_inst *inst, struct h264_SPS_t *sps pic->y_len_sz = pic->coded_width * pic->coded_height; pic->c_len_sz = pic->y_len_sz >> 1; pic->profile_idc = sps->profile_idc; - + pic->ref_frame_count= sps->ref_frame_count; /* calc DPB size */ dec->dpb_sz = sps->num_reorder_frames + margin; @@ -503,8 +509,9 @@ static void fill_vdec_params(struct vdec_h264_inst *inst, struct h264_SPS_t *sps vdec_config_dw_mode(pic, dw); - aml_vcodec_debug(inst, "[%d] The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n", - inst->ctx->id, dw, pic->coded_width, pic->coded_height, + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR, + "The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n", + dw, pic->coded_width, pic->coded_height, pic->visible_width, pic->visible_height, dec->dpb_sz - margin, margin); } @@ -552,14 +559,15 @@ static int vdec_search_startcode(u8 *buf, u32 range) return pos; } -static int stream_parse_by_ucode(struct vdec_h264_inst *inst, u8 *buf, u32 size) +static int parse_stream_ucode(struct vdec_h264_inst *inst, u8 *buf, u32 size) { int ret = 0; struct aml_vdec_adapt *vdec = &inst->vdec; ret = vdec_vframe_write(vdec, buf, size, 0); if (ret < 0) { - pr_err("write frame data failed. err: %d\n", ret); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "write frame data failed. err: %d\n", ret); return ret; } @@ -570,7 +578,27 @@ static int stream_parse_by_ucode(struct vdec_h264_inst *inst, u8 *buf, u32 size) return inst->vsi->dec.dpb_sz ? 0 : -1; } -static int stream_parse(struct vdec_h264_inst *inst, u8 *buf, u32 size) +static int parse_stream_ucode_dma(struct vdec_h264_inst *inst, + ulong buf, u32 size, u32 handle) +{ + int ret = 0; + struct aml_vdec_adapt *vdec = &inst->vdec; + + ret = vdec_vframe_write_with_dma(vdec, buf, size, 0, handle); + if (ret < 0) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "write frame data failed. err: %d\n", ret); + return ret; + } + + /* wait ucode parse ending. */ + wait_for_completion_timeout(&inst->comp, + msecs_to_jiffies(1000)); + + return inst->vsi->dec.dpb_sz ? 0 : -1; +} + +static int parse_stream_cpu(struct vdec_h264_inst *inst, u8 *buf, u32 size) { int ret = 0; struct h264_param_sets *ps; @@ -591,7 +619,8 @@ static int stream_parse(struct vdec_h264_inst *inst, u8 *buf, u32 size) ret = h264_decode_extradata_ps(buf, size, ps); if (ret) { - pr_err("parse extra data failed. err: %d\n", ret); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "parse extra data failed. err: %d\n", ret); goto out; } @@ -610,26 +639,38 @@ static int vdec_h264_probe(unsigned long h_vdec, { struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec; - struct stream_info *st; - u8 *buf = (u8 *)bs->vaddr; + u8 *buf = (u8 *) bs->vaddr; u32 size = bs->size; int ret = 0; - st = (struct stream_info *)buf; - if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn)) - return 0; - - if (st->magic == NORe || st->magic == NORn) { - buf = st->data; - size = st->length; - } + if (inst->ctx->is_drm_mode) { + if (bs->model == VB2_MEMORY_MMAP) { + struct aml_video_stream *s = + (struct aml_video_stream *) buf; - skip_aud_data(&buf, &size); + if ((s->magic != AML_VIDEO_MAGIC) && + (s->type != V4L_STREAM_TYPE_MATEDATA)) + return -1; - if (inst->ctx->param_sets_from_ucode) - ret = stream_parse_by_ucode(inst, buf, size); - else - ret = stream_parse(inst, buf, size); + if (inst->ctx->param_sets_from_ucode) { + ret = parse_stream_ucode(inst, s->data, s->len); + } else { + skip_aud_data((u8 **)&s->data, &s->len); + ret = parse_stream_cpu(inst, s->data, s->len); + } + } else if (bs->model == VB2_MEMORY_DMABUF || + bs->model == VB2_MEMORY_USERPTR) { + ret = parse_stream_ucode_dma(inst, bs->addr, size, + BUFF_IDX(bs, bs->index)); + } + } else { + if (inst->ctx->param_sets_from_ucode) { + ret = parse_stream_ucode(inst, buf, size); + } else { + skip_aud_data(&buf, &size); + ret = parse_stream_cpu(inst, buf, size); + } + } inst->vsi->cur_pic = inst->vsi->pic; @@ -642,8 +683,6 @@ static void vdec_h264_deinit(unsigned long h_vdec) struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec; struct aml_vcodec_ctx *ctx = inst->ctx; - aml_vcodec_debug_enter(inst); - video_decoder_release(&inst->vdec); vcodec_vfm_release(&inst->vfm); @@ -675,14 +714,16 @@ static void vdec_h264_get_vf(struct vdec_h264_inst *inst, struct vdec_v4l2_buffe vf = peek_video_frame(&inst->vfm); if (!vf) { - aml_vcodec_debug(inst, "there is no vframe."); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "there is no vframe.\n"); *out = NULL; return; } vf = get_video_frame(&inst->vfm); if (!vf) { - aml_vcodec_debug(inst, "the vframe is avalid."); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the vframe is avalid.\n"); *out = NULL; return; } @@ -690,8 +731,10 @@ static void vdec_h264_get_vf(struct vdec_h264_inst *inst, struct vdec_v4l2_buffe atomic_set(&vf->use_cnt, 1); fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; - fb->vf_handle = (unsigned long)vf; - fb->status = FB_ST_DISPLAY; + if (fb) { + fb->vf_handle = (unsigned long)vf; + fb->status = FB_ST_DISPLAY; + } *out = fb; @@ -719,7 +762,7 @@ static int vdec_write_nalu(struct vdec_h264_inst *inst, goto err; nal_type = AVC_NAL_TYPE(buf[nalu_pos]); - //aml_vcodec_debug(inst, "NALU type: %d, size: %u", nal_type, size); + //v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "NALU type: %d, size: %u\n", nal_type, size); if (nal_type == NAL_H264_SPS && !is_combine) { if (inst->vsi->head_offset + size > HEADER_BUFFER_SIZE) { @@ -775,7 +818,7 @@ static int vdec_write_nalu(struct vdec_h264_inst *inst, return ret; err: - aml_vcodec_err(inst, "%s err(%d)", __func__, ret); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, "err(%d)", ret); return ret; } @@ -796,7 +839,7 @@ static bool monitor_res_change(struct vdec_h264_inst *inst, u8 *buf, u32 size) break; if (type == NAL_H264_SPS) { - ret = stream_parse(inst, p, len); + ret = parse_stream_cpu(inst, p, len); if (ret) break; } @@ -810,8 +853,10 @@ static bool monitor_res_change(struct vdec_h264_inst *inst, u8 *buf, u32 size) inst->vsi->cur_pic.coded_height != inst->vsi->pic.coded_height) || (inst->vsi->pic.profile_idc != - inst->vsi->cur_pic.profile_idc))) { - pr_info("res change\n"); + inst->vsi->cur_pic.profile_idc) || + (inst->vsi->pic.ref_frame_count != + inst->vsi->cur_pic.ref_frame_count))) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "res change\n"); inst->vsi->cur_pic = inst->vsi->pic; return true; } @@ -824,9 +869,8 @@ static int vdec_h264_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs, { struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec; struct aml_vdec_adapt *vdec = &inst->vdec; - struct stream_info *st; - u8 *buf; - u32 size; + u8 *buf = (u8 *) bs->vaddr; + u32 size = bs->size; int ret = -1; if (bs == NULL) @@ -835,23 +879,44 @@ static int vdec_h264_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs, if (vdec_input_full(vdec)) return -EAGAIN; - buf = (u8 *)bs->vaddr; - size = bs->size; - st = (struct stream_info *)buf; - - if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn)) - ret = vdec_vbuf_write(vdec, st->m.buf, sizeof(st->m.drm)); - else if (st->magic == NORe) - ret = vdec_vbuf_write(vdec, st->data, st->length); - else if (st->magic == NORn) - ret = vdec_write_nalu(inst, st->data, st->length, timestamp); - else if (inst->ctx->is_stream_mode) - ret = vdec_vbuf_write(vdec, buf, size); - else { - /*checked whether the resolution changes.*/ - if ((*res_chg = monitor_res_change(inst, buf, size))) - return 0; + if (inst->ctx->is_drm_mode) { + if (bs->model == VB2_MEMORY_MMAP) { + struct aml_video_stream *s = + (struct aml_video_stream *) buf; + if (s->magic != AML_VIDEO_MAGIC) + return -1; + + if (!inst->ctx->param_sets_from_ucode && + (s->type == V4L_STREAM_TYPE_MATEDATA)) { + if ((*res_chg = monitor_res_change(inst, + s->data, s->len))) + return 0; + } + + ret = vdec_vframe_write(vdec, + s->data, + s->len, + timestamp); + } else if (bs->model == VB2_MEMORY_DMABUF || + bs->model == VB2_MEMORY_USERPTR) { + ret = vdec_vframe_write_with_dma(vdec, + bs->addr, size, timestamp, + BUFF_IDX(bs, bs->index)); + } + } else { + if (inst->ctx->param_sets_from_ucode) { + int nal_idx = 0; + /* if the st compose from csd + slice that is the combine data. */ + inst->vsi->is_combine = check_frame_combine(buf, size, &nal_idx); + /*if (nal_idx < 0) + return -1;*/ + } else { + /*checked whether the resolution changes.*/ + if ((*res_chg = monitor_res_change(inst, buf, size))) { + return 0; + } + } ret = vdec_write_nalu(inst, buf, size, timestamp); } @@ -872,7 +937,8 @@ static void get_param_config_info(struct vdec_h264_inst *inst, parms->parms_status |= inst->parms.parms_status; - aml_vcodec_debug(inst, "parms status: %u", parms->parms_status); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "parms status: %u\n", parms->parms_status); } static int vdec_h264_get_param(unsigned long h_vdec, @@ -882,7 +948,8 @@ static int vdec_h264_get_param(unsigned long h_vdec, struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec; if (!inst) { - pr_err("the h264 inst of dec is invalid.\n"); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the h264 inst of dec is invalid.\n"); return -1; } @@ -911,7 +978,8 @@ static int vdec_h264_get_param(unsigned long h_vdec, get_param_config_info(inst, out); break; default: - aml_vcodec_err(inst, "invalid get parameter type=%d", type); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "invalid get parameter type=%d\n", type); ret = -EINVAL; } @@ -929,6 +997,7 @@ static void set_param_ps_info(struct vdec_h264_inst *inst, struct vdec_pic_info *pic = &inst->vsi->pic; struct vdec_h264_dec_info *dec = &inst->vsi->dec; struct v4l2_rect *rect = &inst->vsi->crop; + int dw = inst->parms.cfg.double_write_mode; /* fill visible area size that be used for EGL. */ pic->visible_width = ps->visible_width; @@ -945,17 +1014,21 @@ static void set_param_ps_info(struct vdec_h264_inst *inst, pic->coded_height = ps->coded_height; pic->y_len_sz = pic->coded_width * pic->coded_height; pic->c_len_sz = pic->y_len_sz >> 1; - + pic->profile_idc = ps->profile; + pic->ref_frame_count = ps->ref_frames; dec->dpb_sz = ps->dpb_size; inst->parms.ps = *ps; inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_PSINFO; + vdec_config_dw_mode(pic, dw); + /*wake up*/ complete(&inst->comp); - pr_info("Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n", + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n", ps->visible_width, ps->visible_height, ps->coded_width, ps->coded_height, dec->dpb_sz); @@ -972,14 +1045,16 @@ static void set_param_hdr_info(struct vdec_h264_inst *inst, V4L2_CONFIG_PARM_DECODE_HDRINFO; aml_vdec_dispatch_event(inst->ctx, V4L2_EVENT_SRC_CH_HDRINFO); - pr_info("H264 set HDR infos\n"); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "H264 set HDR infos\n"); } } static void set_param_post_event(struct vdec_h264_inst *inst, u32 *event) { aml_vdec_dispatch_event(inst->ctx, *event); - pr_info("H264 post event: %d\n", *event); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "H264 post event: %d\n", *event); } static int vdec_h264_set_param(unsigned long h_vdec, @@ -989,7 +1064,8 @@ static int vdec_h264_set_param(unsigned long h_vdec, struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec; if (!inst) { - pr_err("the h264 inst of dec is invalid.\n"); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the h264 inst of dec is invalid.\n"); return -1; } @@ -1010,7 +1086,8 @@ static int vdec_h264_set_param(unsigned long h_vdec, set_param_post_event(inst, in); break; default: - aml_vcodec_err(inst, "invalid set parameter type=%d", type); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "invalid set parameter type=%d\n", type); ret = -EINVAL; } diff --git a/drivers/amvdec_ports/decoder/vdec_hevc_if.c b/drivers/amvdec_ports/decoder/vdec_hevc_if.c index cd4d361..10c6b48 100644 --- a/drivers/amvdec_ports/decoder/vdec_hevc_if.c +++ b/drivers/amvdec_ports/decoder/vdec_hevc_if.c @@ -122,11 +122,13 @@ static void get_pic_info(struct vdec_hevc_inst *inst, { *pic = inst->vsi->pic; - aml_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", - pic->visible_width, pic->visible_height, - pic->coded_width, pic->coded_height); - aml_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz, - pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "pic(%d, %d), buf(%d, %d)\n", + pic->visible_width, pic->visible_height, + pic->coded_width, pic->coded_height); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "Y(%d, %d), C(%d, %d)\n", pic->y_bs_sz, + pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz); } static void get_crop_info(struct vdec_hevc_inst *inst, struct v4l2_rect *cr) @@ -136,14 +138,15 @@ static void get_crop_info(struct vdec_hevc_inst *inst, struct v4l2_rect *cr) cr->width = inst->vsi->crop.width; cr->height = inst->vsi->crop.height; - aml_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d", - cr->left, cr->top, cr->width, cr->height); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "l=%d, t=%d, w=%d, h=%d\n", + cr->left, cr->top, cr->width, cr->height); } static void get_dpb_size(struct vdec_hevc_inst *inst, unsigned int *dpb_sz) { *dpb_sz = inst->vsi->dec.dpb_sz; - aml_vcodec_debug(inst, "sz=%d", *dpb_sz); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, "sz=%d\n", *dpb_sz); } static u32 vdec_config_default_parms(u8 *parm) @@ -223,13 +226,15 @@ static int vdec_hevc_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) inst->vfm.ada_ctx = &inst->vdec; ret = vcodec_vfm_init(&inst->vfm); if (ret) { - pr_err("%s, init vfm failed.\n", __func__); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "init vfm failed.\n"); goto err; } ret = video_decoder_init(&inst->vdec); if (ret) { - aml_vcodec_err(inst, "vdec_hevc init err=%d", ret); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "vdec_hevc init err=%d\n", ret); goto err; } @@ -242,14 +247,15 @@ static int vdec_hevc_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) /* alloc the header buffer to be used cache sps or spp etc.*/ inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL); - if (!inst->vsi) { + if (!inst->vsi->header_buf) { ret = -ENOMEM; goto err; } init_completion(&inst->comp); - aml_vcodec_debug(inst, "hevc Instance >> %p", inst); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "hevc Instance >> %lx\n", (ulong) inst); ctx->ada_ctx = &inst->vdec; *h_vdec = (unsigned long)inst; @@ -286,7 +292,7 @@ static int refer_buffer_num(struct h265_SPS_t *sps) used_buf_num = sps->temporal_layer[0].num_reorder_pics; sps_pic_buf_diff = sps->temporal_layer[0].max_dec_pic_buffering - - sps->temporal_layer[0].num_reorder_pics + 1; + sps->temporal_layer[0].num_reorder_pics - 1; if (sps_pic_buf_diff >= 4) used_buf_num += 1; @@ -396,20 +402,42 @@ static void fill_vdec_params(struct vdec_hevc_inst *inst, struct h265_SPS_t *sps inst->parms.ps.dpb_size = dec->dpb_sz; inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_PSINFO; - pr_info("[%d] The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n", - inst->ctx->id, dw, pic->coded_width, pic->coded_height, + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR, + "The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n", + dw, pic->coded_width, pic->coded_height, pic->visible_width, pic->visible_height, dec->dpb_sz - margin, margin); } -static int stream_parse_by_ucode(struct vdec_hevc_inst *inst, u8 *buf, u32 size) +static int parse_stream_ucode(struct vdec_hevc_inst *inst, u8 *buf, u32 size) { int ret = 0; struct aml_vdec_adapt *vdec = &inst->vdec; ret = vdec_vframe_write(vdec, buf, size, 0); if (ret < 0) { - pr_err("write frame data failed. err: %d\n", ret); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "write frame data failed. err: %d\n", ret); + return ret; + } + + /* wait ucode parse ending. */ + wait_for_completion_timeout(&inst->comp, + msecs_to_jiffies(1000)); + + return inst->vsi->dec.dpb_sz ? 0 : -1; +} + +static int parse_stream_ucode_dma(struct vdec_hevc_inst *inst, + ulong buf, u32 size, u32 handle) +{ + int ret = 0; + struct aml_vdec_adapt *vdec = &inst->vdec; + + ret = vdec_vframe_write_with_dma(vdec, buf, size, 0, handle); + if (ret < 0) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "write frame data failed. err: %d\n", ret); return ret; } @@ -420,7 +448,7 @@ static int stream_parse_by_ucode(struct vdec_hevc_inst *inst, u8 *buf, u32 size) return inst->vsi->dec.dpb_sz ? 0 : -1; } -static int stream_parse(struct vdec_hevc_inst *inst, u8 *buf, u32 size) +static int parse_stream_cpu(struct vdec_hevc_inst *inst, u8 *buf, u32 size) { int ret = 0; struct h265_param_sets *ps = NULL; @@ -431,7 +459,8 @@ static int stream_parse(struct vdec_hevc_inst *inst, u8 *buf, u32 size) ret = h265_decode_extradata_ps(buf, size, ps); if (ret) { - pr_err("parse extra data failed. err: %d\n", ret); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "parse extra data failed. err: %d\n", ret); goto out; } @@ -450,22 +479,35 @@ static int vdec_hevc_probe(unsigned long h_vdec, { struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec; - struct stream_info *st; u8 *buf = (u8 *)bs->vaddr; u32 size = bs->size; int ret = 0; - st = (struct stream_info *)buf; - if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn)) - return 0; - - if (st->magic == NORe || st->magic == NORn) - ret = stream_parse(inst, st->data, st->length); - else { - if (inst->ctx->param_sets_from_ucode) - ret = stream_parse_by_ucode(inst, buf, size); - else - ret = stream_parse(inst, buf, size); + if (inst->ctx->is_drm_mode) { + if (bs->model == VB2_MEMORY_MMAP) { + struct aml_video_stream *s = + (struct aml_video_stream *) buf; + + if ((s->magic != AML_VIDEO_MAGIC) && + (s->type != V4L_STREAM_TYPE_MATEDATA)) + return -1; + + if (inst->ctx->param_sets_from_ucode) { + ret = parse_stream_ucode(inst, s->data, s->len); + } else { + ret = parse_stream_cpu(inst, s->data, s->len); + } + } else if (bs->model == VB2_MEMORY_DMABUF || + bs->model == VB2_MEMORY_USERPTR) { + ret = parse_stream_ucode_dma(inst, bs->addr, size, + BUFF_IDX(bs, bs->index)); + } + } else { + if (inst->ctx->param_sets_from_ucode) { + ret = parse_stream_ucode(inst, buf, size); + } else { + ret = parse_stream_cpu(inst, buf, size); + } } inst->vsi->cur_pic = inst->vsi->pic; @@ -479,8 +521,6 @@ static void vdec_hevc_deinit(unsigned long h_vdec) struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec; struct aml_vcodec_ctx *ctx = inst->ctx; - aml_vcodec_debug_enter(inst); - video_decoder_release(&inst->vdec); vcodec_vfm_release(&inst->vfm); @@ -512,14 +552,16 @@ static void vdec_hevc_get_vf(struct vdec_hevc_inst *inst, struct vdec_v4l2_buffe vf = peek_video_frame(&inst->vfm); if (!vf) { - aml_vcodec_debug(inst, "there is no vframe."); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "there is no vframe.\n"); *out = NULL; return; } vf = get_video_frame(&inst->vfm); if (!vf) { - aml_vcodec_debug(inst, "the vframe is avalid."); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the vframe is avalid.\n"); *out = NULL; return; } @@ -568,7 +610,7 @@ static bool monitor_res_change(struct vdec_hevc_inst *inst, u8 *buf, u32 size) break; if (type == HEVC_NAL_SPS) { - ret = stream_parse(inst, p, len); + ret = parse_stream_cpu(inst, p, len); if (ret) break; } @@ -593,9 +635,8 @@ static int vdec_hevc_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs, { struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec; struct aml_vdec_adapt *vdec = &inst->vdec; - struct stream_info *st; - u8 *buf; - u32 size; + u8 *buf = (u8 *) bs->vaddr; + u32 size = bs->size; int ret = -1; if (bs == NULL) @@ -604,23 +645,37 @@ static int vdec_hevc_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs, if (vdec_input_full(vdec)) return -EAGAIN; - buf = (u8 *)bs->vaddr; - size = bs->size; - st = (struct stream_info *)buf; - - if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn)) - ret = vdec_vbuf_write(vdec, st->m.buf, sizeof(st->m.drm)); - else if (st->magic == NORe) - ret = vdec_vbuf_write(vdec, st->data, st->length); - else if (st->magic == NORn) - ret = vdec_write_nalu(inst, st->data, st->length, timestamp); - else if (inst->ctx->is_stream_mode) - ret = vdec_vbuf_write(vdec, buf, size); - else { - /*checked whether the resolution changes.*/ - if ((*res_chg = monitor_res_change(inst, buf, size))) - return 0; + if (inst->ctx->is_drm_mode) { + if (bs->model == VB2_MEMORY_MMAP) { + struct aml_video_stream *s = + (struct aml_video_stream *) buf; + if (s->magic != AML_VIDEO_MAGIC) + return -1; + + if (!inst->ctx->param_sets_from_ucode && + (s->type == V4L_STREAM_TYPE_MATEDATA)) { + if ((*res_chg = monitor_res_change(inst, + s->data, s->len))) + return 0; + } + + ret = vdec_vframe_write(vdec, + s->data, + s->len, + timestamp); + } else if (bs->model == VB2_MEMORY_DMABUF || + bs->model == VB2_MEMORY_USERPTR) { + ret = vdec_vframe_write_with_dma(vdec, + bs->addr, size, timestamp, + BUFF_IDX(bs, bs->index)); + } + } else { + if (!inst->ctx->param_sets_from_ucode) { + /*checked whether the resolution changes.*/ + if ((*res_chg = monitor_res_change(inst, buf, size))) + return 0; + } ret = vdec_write_nalu(inst, buf, size, timestamp); } @@ -641,7 +696,8 @@ static int vdec_hevc_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs, parms->parms_status |= inst->parms.parms_status; - aml_vcodec_debug(inst, "parms status: %u", parms->parms_status); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "parms status: %u\n", parms->parms_status); } static int vdec_hevc_get_param(unsigned long h_vdec, @@ -651,7 +707,8 @@ static int vdec_hevc_get_param(unsigned long h_vdec, struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec; if (!inst) { - pr_err("the hevc inst of dec is invalid.\n"); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the hevc inst of dec is invalid.\n"); return -1; } @@ -680,7 +737,8 @@ static int vdec_hevc_get_param(unsigned long h_vdec, get_param_config_info(inst, out); break; default: - aml_vcodec_err(inst, "invalid get parameter type=%d", type); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "invalid get parameter type=%d\n", type); ret = -EINVAL; } @@ -710,8 +768,9 @@ static void set_param_ps_info(struct vdec_hevc_inst *inst, rect->height = pic->visible_height; /* config canvas size that be used for decoder. */ - pic->coded_width = ALIGN(ps->coded_width, 64); - pic->coded_height = ALIGN(ps->coded_height, 64); + + pic->coded_width = ps->coded_width; + pic->coded_height = ps->coded_height; pic->y_len_sz = pic->coded_width * pic->coded_height; pic->c_len_sz = pic->y_len_sz >> 1; @@ -724,7 +783,8 @@ static void set_param_ps_info(struct vdec_hevc_inst *inst, /*wake up*/ complete(&inst->comp); - pr_info("Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n", + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n", pic->visible_width, pic->visible_height, pic->coded_width, pic->coded_height, dec->dpb_sz); @@ -740,14 +800,16 @@ static void set_param_hdr_info(struct vdec_hevc_inst *inst, V4L2_CONFIG_PARM_DECODE_HDRINFO; aml_vdec_dispatch_event(inst->ctx, V4L2_EVENT_SRC_CH_HDRINFO); - pr_info("H265 set HDR infos\n"); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "H265 set HDR infos\n"); } } static void set_param_post_event(struct vdec_hevc_inst *inst, u32 *event) { aml_vdec_dispatch_event(inst->ctx, *event); - pr_info("H265 post event: %d\n", *event); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "H265 post event: %d\n", *event); } static int vdec_hevc_set_param(unsigned long h_vdec, @@ -757,7 +819,8 @@ static int vdec_hevc_set_param(unsigned long h_vdec, struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec; if (!inst) { - pr_err("the hevc inst of dec is invalid.\n"); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the hevc inst of dec is invalid.\n"); return -1; } @@ -778,7 +841,8 @@ static int vdec_hevc_set_param(unsigned long h_vdec, set_param_post_event(inst, in); break; default: - aml_vcodec_err(inst, "invalid set parameter type=%d", type); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "invalid set parameter type=%d\n", type); ret = -EINVAL; } diff --git a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c index 0db4eca..4e10828 100644 --- a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c +++ b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c @@ -93,6 +93,7 @@ struct vdec_mjpeg_vsi { int head_offset; struct vdec_mjpeg_dec_info dec; struct vdec_pic_info pic; + struct vdec_pic_info cur_pic; struct v4l2_rect crop; bool is_combine; int nalu_pos; @@ -111,6 +112,7 @@ struct vdec_mjpeg_inst { struct aml_vdec_adapt vdec; struct vdec_mjpeg_vsi *vsi; struct vcodec_vfm_s vfm; + struct completion comp; }; static void get_pic_info(struct vdec_mjpeg_inst *inst, @@ -118,11 +120,14 @@ static void get_pic_info(struct vdec_mjpeg_inst *inst, { *pic = inst->vsi->pic; - aml_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", - pic->visible_width, pic->visible_height, - pic->coded_width, pic->coded_height); - aml_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz, - pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "pic(%d, %d), buf(%d, %d)\n", + pic->visible_width, pic->visible_height, + pic->coded_width, pic->coded_height); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "Y(%d, %d), C(%d, %d)\n", + pic->y_bs_sz, pic->y_len_sz, + pic->c_bs_sz, pic->c_len_sz); } static void get_crop_info(struct vdec_mjpeg_inst *inst, struct v4l2_rect *cr) @@ -132,14 +137,16 @@ static void get_crop_info(struct vdec_mjpeg_inst *inst, struct v4l2_rect *cr) cr->width = inst->vsi->crop.width; cr->height = inst->vsi->crop.height; - aml_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d", - cr->left, cr->top, cr->width, cr->height); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "l=%d, t=%d, w=%d, h=%d\n", + cr->left, cr->top, cr->width, cr->height); } static void get_dpb_size(struct vdec_mjpeg_inst *inst, unsigned int *dpb_sz) { *dpb_sz = 20;//inst->vsi->dec.dpb_sz; - aml_vcodec_debug(inst, "sz=%d", *dpb_sz); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "sz=%d\n", *dpb_sz); } static int vdec_mjpeg_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) @@ -168,26 +175,32 @@ static int vdec_mjpeg_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) /* init vfm */ inst->vfm.ctx = ctx; inst->vfm.ada_ctx = &inst->vdec; - vcodec_vfm_init(&inst->vfm); + ret = vcodec_vfm_init(&inst->vfm); + if (ret) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "init vfm failed.\n"); + goto err; + } ret = video_decoder_init(&inst->vdec); if (ret) { - aml_vcodec_err(inst, "vdec_mjpeg init err=%d", ret); - goto error_free_inst; + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "vdec_mjpeg init err=%d\n", ret); + goto err; } /* probe info from the stream */ inst->vsi = kzalloc(sizeof(struct vdec_mjpeg_vsi), GFP_KERNEL); if (!inst->vsi) { ret = -ENOMEM; - goto error_free_inst; + goto err; } /* alloc the header buffer to be used cache sps or spp etc.*/ inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL); - if (!inst->vsi) { + if (!inst->vsi->header_buf) { ret = -ENOMEM; - goto error_free_vsi; + goto err; } inst->vsi->pic.visible_width = 1920; @@ -199,7 +212,8 @@ static int vdec_mjpeg_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) inst->vsi->pic.c_bs_sz = 0; inst->vsi->pic.c_len_sz = (1920 * 1088 / 2); - aml_vcodec_debug(inst, "mjpeg Instance >> %p", inst); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "mjpeg Instance >> %lx\n", (ulong) inst); ctx->ada_ctx = &inst->vdec; *h_vdec = (unsigned long)inst; @@ -208,10 +222,15 @@ static int vdec_mjpeg_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) return 0; -error_free_vsi: - kfree(inst->vsi); -error_free_inst: - kfree(inst); +err: + if (inst) + vcodec_vfm_release(&inst->vfm); + if (inst && inst->vsi && inst->vsi->header_buf) + kfree(inst->vsi->header_buf); + if (inst && inst->vsi) + kfree(inst->vsi); + if (inst) + kfree(inst); *h_vdec = 0; return ret; @@ -252,12 +271,52 @@ static void fill_vdec_params(struct vdec_mjpeg_inst *inst, /* calc DPB size */ dec->dpb_sz = 9;//refer_buffer_num(sps->level_idc, poc_cnt, mb_w, mb_h); - pr_info("[%d] The stream infos, coded:(%d x %d), visible:(%d x %d), DPB: %d\n", - inst->ctx->id, pic->coded_width, pic->coded_height, + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR, + "The stream infos, coded:(%d x %d), visible:(%d x %d), DPB: %d\n", + pic->coded_width, pic->coded_height, pic->visible_width, pic->visible_height, dec->dpb_sz); } -static int stream_parse(struct vdec_mjpeg_inst *inst, u8 *buf, u32 size) +static int parse_stream_ucode(struct vdec_mjpeg_inst *inst, u8 *buf, u32 size) +{ + int ret = 0; + struct aml_vdec_adapt *vdec = &inst->vdec; + + ret = vdec_vframe_write(vdec, buf, size, 0); + if (ret < 0) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "write frame data failed. err: %d\n", ret); + return ret; + } + + /* wait ucode parse ending. */ + wait_for_completion_timeout(&inst->comp, + msecs_to_jiffies(1000)); + + return inst->vsi->dec.dpb_sz ? 0 : -1; +} + +static int parse_stream_ucode_dma(struct vdec_mjpeg_inst *inst, + ulong buf, u32 size, u32 handle) +{ + int ret = 0; + struct aml_vdec_adapt *vdec = &inst->vdec; + + ret = vdec_vframe_write_with_dma(vdec, buf, size, 0, handle); + if (ret < 0) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "write frame data failed. err: %d\n", ret); + return ret; + } + + /* wait ucode parse ending. */ + wait_for_completion_timeout(&inst->comp, + msecs_to_jiffies(1000)); + + return inst->vsi->dec.dpb_sz ? 0 : -1; +} + +static int parse_stream_cpu(struct vdec_mjpeg_inst *inst, u8 *buf, u32 size) { int ret = 0; struct mjpeg_param_sets *ps = NULL; @@ -268,7 +327,8 @@ static int stream_parse(struct vdec_mjpeg_inst *inst, u8 *buf, u32 size) ret = mjpeg_decode_extradata_ps(buf, size, ps); if (ret) { - pr_err("parse extra data failed. err: %d\n", ret); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "parse extra data failed. err: %d\n", ret); goto out; } @@ -287,19 +347,38 @@ static int vdec_mjpeg_probe(unsigned long h_vdec, { struct vdec_mjpeg_inst *inst = (struct vdec_mjpeg_inst *)h_vdec; - struct stream_info *st; u8 *buf = (u8 *)bs->vaddr; u32 size = bs->size; int ret = 0; - st = (struct stream_info *)buf; - if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn)) - return 0; + if (inst->ctx->is_drm_mode) { + if (bs->model == VB2_MEMORY_MMAP) { + struct aml_video_stream *s = + (struct aml_video_stream *) buf; + + if ((s->magic != AML_VIDEO_MAGIC) && + (s->type != V4L_STREAM_TYPE_MATEDATA)) + return -1; + + if (inst->ctx->param_sets_from_ucode) { + ret = parse_stream_ucode(inst, s->data, s->len); + } else { + ret = parse_stream_cpu(inst, s->data, s->len); + } + } else if (bs->model == VB2_MEMORY_DMABUF || + bs->model == VB2_MEMORY_USERPTR) { + ret = parse_stream_ucode_dma(inst, bs->addr, size, + BUFF_IDX(bs, bs->index)); + } + } else { + if (inst->ctx->param_sets_from_ucode) { + ret = parse_stream_ucode(inst, buf, size); + } else { + ret = parse_stream_cpu(inst, buf, size); + } + } - if (st->magic == NORe || st->magic == NORn) - ret = stream_parse(inst, st->data, st->length); - else - ret = stream_parse(inst, buf, size); + inst->vsi->cur_pic = inst->vsi->pic; return ret; } @@ -311,8 +390,6 @@ static void vdec_mjpeg_deinit(unsigned long h_vdec) if (!inst) return; - aml_vcodec_debug_enter(inst); - video_decoder_release(&inst->vdec); vcodec_vfm_release(&inst->vfm); @@ -340,14 +417,16 @@ static void vdec_mjpeg_get_vf(struct vdec_mjpeg_inst *inst, struct vdec_v4l2_buf vf = peek_video_frame(&inst->vfm); if (!vf) { - aml_vcodec_debug(inst, "there is no vframe."); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "there is no vframe.\n"); *out = NULL; return; } vf = get_video_frame(&inst->vfm); if (!vf) { - aml_vcodec_debug(inst, "the vframe is avalid."); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the vframe is avalid.\n"); *out = NULL; return; } @@ -384,29 +463,34 @@ static int vdec_mjpeg_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs, { struct vdec_mjpeg_inst *inst = (struct vdec_mjpeg_inst *)h_vdec; struct aml_vdec_adapt *vdec = &inst->vdec; - struct stream_info *st; - u8 *buf; - u32 size; - int ret = 0; + u8 *buf = (u8 *) bs->vaddr; + u32 size = bs->size; + int ret = -1; - /* bs NULL means flush decoder */ - if (bs == NULL) - return 0; - - buf = (u8 *)bs->vaddr; - size = bs->size; - st = (struct stream_info *)buf; - - if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn)) - ret = vdec_vbuf_write(vdec, st->m.buf, sizeof(st->m.drm)); - else if (st->magic == NORe) - ret = vdec_vbuf_write(vdec, st->data, st->length); - else if (st->magic == NORn) - ret = vdec_write_nalu(inst, st->data, st->length, timestamp); - else if (inst->ctx->is_stream_mode) - ret = vdec_vbuf_write(vdec, buf, size); - else + if (vdec_input_full(vdec)) + return -EAGAIN; + + if (inst->ctx->is_drm_mode) { + if (bs->model == VB2_MEMORY_MMAP) { + struct aml_video_stream *s = + (struct aml_video_stream *) buf; + + if (s->magic != AML_VIDEO_MAGIC) + return -1; + + ret = vdec_vframe_write(vdec, + s->data, + s->len, + timestamp); + } else if (bs->model == VB2_MEMORY_DMABUF || + bs->model == VB2_MEMORY_USERPTR) { + ret = vdec_vframe_write_with_dma(vdec, + bs->addr, size, timestamp, + BUFF_IDX(bs, bs->index)); + } + } else { ret = vdec_write_nalu(inst, buf, size, timestamp); + } return ret; } @@ -418,7 +502,8 @@ static int vdec_mjpeg_get_param(unsigned long h_vdec, struct vdec_mjpeg_inst *inst = (struct vdec_mjpeg_inst *)h_vdec; if (!inst) { - pr_err("the mjpeg inst of dec is invalid.\n"); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the mjpeg inst of dec is invalid.\n"); return -1; } @@ -444,7 +529,8 @@ static int vdec_mjpeg_get_param(unsigned long h_vdec, break; default: - aml_vcodec_err(inst, "invalid get parameter type=%d", type); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "invalid get parameter type=%d\n", type); ret = -EINVAL; } @@ -454,7 +540,7 @@ static int vdec_mjpeg_get_param(unsigned long h_vdec, static void set_param_ps_info(struct vdec_mjpeg_inst *inst, struct aml_vdec_ps_infos *ps) { - pr_info("---%s, %d\n", __func__, __LINE__); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "\n"); } static int vdec_mjpeg_set_param(unsigned long h_vdec, @@ -464,7 +550,8 @@ static int vdec_mjpeg_set_param(unsigned long h_vdec, struct vdec_mjpeg_inst *inst = (struct vdec_mjpeg_inst *)h_vdec; if (!inst) { - pr_err("the mjpeg inst of dec is invalid.\n"); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the mjpeg inst of dec is invalid.\n"); return -1; } @@ -474,7 +561,8 @@ static int vdec_mjpeg_set_param(unsigned long h_vdec, break; default: - aml_vcodec_err(inst, "invalid set parameter type=%d", type); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "invalid set parameter type=%d\n", type); ret = -EINVAL; } diff --git a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c index 5d5ca07..b5b128b 100644 --- a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c +++ b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c @@ -93,6 +93,7 @@ struct vdec_mpeg12_vsi { int head_offset; struct vdec_mpeg12_dec_info dec; struct vdec_pic_info pic; + struct vdec_pic_info cur_pic; struct v4l2_rect crop; bool is_combine; int nalu_pos; @@ -111,6 +112,8 @@ struct vdec_mpeg12_inst { struct aml_vdec_adapt vdec; struct vdec_mpeg12_vsi *vsi; struct vcodec_vfm_s vfm; + struct aml_dec_params parms; + struct completion comp; }; static void get_pic_info(struct vdec_mpeg12_inst *inst, @@ -118,11 +121,14 @@ static void get_pic_info(struct vdec_mpeg12_inst *inst, { *pic = inst->vsi->pic; - aml_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", - pic->visible_width, pic->visible_height, - pic->coded_width, pic->coded_height); - aml_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz, - pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "pic(%d, %d), buf(%d, %d)\n", + pic->visible_width, pic->visible_height, + pic->coded_width, pic->coded_height); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "Y(%d, %d), C(%d, %d)\n", + pic->y_bs_sz, pic->y_len_sz, + pic->c_bs_sz, pic->c_len_sz); } static void get_crop_info(struct vdec_mpeg12_inst *inst, struct v4l2_rect *cr) @@ -132,14 +138,49 @@ static void get_crop_info(struct vdec_mpeg12_inst *inst, struct v4l2_rect *cr) cr->width = inst->vsi->crop.width; cr->height = inst->vsi->crop.height; - aml_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d", - cr->left, cr->top, cr->width, cr->height); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "l=%d, t=%d, w=%d, h=%d\n", + cr->left, cr->top, cr->width, cr->height); } static void get_dpb_size(struct vdec_mpeg12_inst *inst, unsigned int *dpb_sz) { *dpb_sz = inst->vsi->dec.dpb_sz; - aml_vcodec_debug(inst, "sz=%d", *dpb_sz); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, "sz=%d\n", *dpb_sz); +} + +static u32 vdec_config_default_parms(u8 *parm) +{ + u8 *pbuf = parm; + + pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;"); + pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:0;"); + pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:0;"); + + return pbuf - parm; +} + +static void vdec_parser_parms(struct vdec_mpeg12_inst *inst) +{ + struct aml_vcodec_ctx *ctx = inst->ctx; + + if (ctx->config.parm.dec.parms_status & + V4L2_CONFIG_PARM_DECODE_CFGINFO) { + u8 *pbuf = ctx->config.buf; + + pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;"); + pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:%d;", + ctx->config.parm.dec.cfg.canvas_mem_mode); + pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;", + ctx->config.parm.dec.cfg.ref_buf_margin); + ctx->config.length = pbuf - ctx->config.buf; + } else { + ctx->config.length = vdec_config_default_parms(ctx->config.buf); + } + + inst->vdec.config = ctx->config; + inst->parms.cfg = ctx->config.parm.dec.cfg; + inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO; } static int vdec_mpeg12_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) @@ -158,6 +199,8 @@ static int vdec_mpeg12_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) inst->vdec.ctx = ctx; inst->ctx = ctx; + vdec_parser_parms(inst); + /* set play mode.*/ if (ctx->is_drm_mode) inst->vdec.port.flag |= PORT_FLAG_DRM; @@ -168,39 +211,37 @@ static int vdec_mpeg12_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) /* init vfm */ inst->vfm.ctx = ctx; inst->vfm.ada_ctx = &inst->vdec; - vcodec_vfm_init(&inst->vfm); + ret = vcodec_vfm_init(&inst->vfm); + if (ret) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "init vfm failed.\n"); + goto err; + } ret = video_decoder_init(&inst->vdec); if (ret) { - aml_vcodec_err(inst, "vdec_mpeg12 init err=%d", ret); - goto error_free_inst; + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "vdec_mpeg12 init err=%d\n", ret); + goto err; } /* probe info from the stream */ inst->vsi = kzalloc(sizeof(struct vdec_mpeg12_vsi), GFP_KERNEL); if (!inst->vsi) { ret = -ENOMEM; - goto error_free_inst; + goto err; } /* alloc the header buffer to be used cache sps or spp etc.*/ inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL); - if (!inst->vsi) { + if (!inst->vsi->header_buf) { ret = -ENOMEM; - goto error_free_vsi; + goto err; } - inst->vsi->pic.visible_width = 1920; - inst->vsi->pic.visible_height = 1080; - inst->vsi->pic.coded_width = 1920; - inst->vsi->pic.coded_height = 1088; - inst->vsi->pic.y_bs_sz = 0; - inst->vsi->pic.y_len_sz = (1920 * 1088); - inst->vsi->pic.c_bs_sz = 0; - inst->vsi->pic.c_len_sz = (1920 * 1088 / 2); - - aml_vcodec_debug(inst, "mpeg12 Instance >> %p", inst); - + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "mpeg12 Instance >> %lx\n", (ulong) inst); + init_completion(&inst->comp); ctx->ada_ctx = &inst->vdec; *h_vdec = (unsigned long)inst; @@ -208,10 +249,15 @@ static int vdec_mpeg12_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) return 0; -error_free_vsi: - kfree(inst->vsi); -error_free_inst: - kfree(inst); +err: + if (inst) + vcodec_vfm_release(&inst->vfm); + if (inst && inst->vsi && inst->vsi->header_buf) + kfree(inst->vsi->header_buf); + if (inst && inst->vsi) + kfree(inst->vsi); + if (inst) + kfree(inst); *h_vdec = 0; return ret; @@ -236,20 +282,60 @@ static void fill_vdec_params(struct vdec_mpeg12_inst *inst, /* config canvas size that be used for decoder. */ pic->coded_width = ALIGN(dec_ps->coded_width, 64); - pic->coded_height = ALIGN(dec_ps->coded_height, 64);; + pic->coded_height = ALIGN(dec_ps->coded_height, 32); pic->y_len_sz = pic->coded_width * pic->coded_height; pic->c_len_sz = pic->y_len_sz >> 1; - /* calc DPB size */ - dec->dpb_sz = 9;//refer_buffer_num(sps->level_idc, poc_cnt, mb_w, mb_h); + /*7(parm_v4l_buffer_margin) + 8(DECODE_BUFFER_NUM_DEF)*/ + dec->dpb_sz = 15; - pr_info("[%d] The stream infos, coded:(%d x %d), visible:(%d x %d), DPB: %d\n", - inst->ctx->id, pic->coded_width, pic->coded_height, + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR, + "The stream infos, coded:(%d x %d), visible:(%d x %d), DPB: %d\n", + pic->coded_width, pic->coded_height, pic->visible_width, pic->visible_height, dec->dpb_sz); } -static int stream_parse(struct vdec_mpeg12_inst *inst, u8 *buf, u32 size) +static int parse_stream_ucode(struct vdec_mpeg12_inst *inst, u8 *buf, u32 size) +{ + int ret = 0; + struct aml_vdec_adapt *vdec = &inst->vdec; + + ret = vdec_vframe_write(vdec, buf, size, 0); + if (ret < 0) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "write frame data failed. err: %d\n", ret); + return ret; + } + + /* wait ucode parse ending. */ + wait_for_completion_timeout(&inst->comp, + msecs_to_jiffies(1000)); + + return inst->vsi->dec.dpb_sz ? 0 : -1; +} + +static int parse_stream_ucode_dma(struct vdec_mpeg12_inst *inst, + ulong buf, u32 size, u32 handle) +{ + int ret = 0; + struct aml_vdec_adapt *vdec = &inst->vdec; + + ret = vdec_vframe_write_with_dma(vdec, buf, size, 0, handle); + if (ret < 0) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "write frame data failed. err: %d\n", ret); + return ret; + } + + /* wait ucode parse ending. */ + wait_for_completion_timeout(&inst->comp, + msecs_to_jiffies(1000)); + + return inst->vsi->dec.dpb_sz ? 0 : -1; +} + +static int parse_stream_cpu(struct vdec_mpeg12_inst *inst, u8 *buf, u32 size) { int ret = 0; struct mpeg12_param_sets *ps = NULL; @@ -260,7 +346,8 @@ static int stream_parse(struct vdec_mpeg12_inst *inst, u8 *buf, u32 size) ret = mpeg12_decode_extradata_ps(buf, size, ps); if (ret) { - pr_err("parse extra data failed. err: %d\n", ret); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "parse extra data failed. err: %d\n", ret); goto out; } @@ -279,19 +366,38 @@ static int vdec_mpeg12_probe(unsigned long h_vdec, { struct vdec_mpeg12_inst *inst = (struct vdec_mpeg12_inst *)h_vdec; - struct stream_info *st; u8 *buf = (u8 *)bs->vaddr; u32 size = bs->size; int ret = 0; - st = (struct stream_info *)buf; - if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn)) - return 0; + if (inst->ctx->is_drm_mode) { + if (bs->model == VB2_MEMORY_MMAP) { + struct aml_video_stream *s = + (struct aml_video_stream *) buf; + + if ((s->magic != AML_VIDEO_MAGIC) && + (s->type != V4L_STREAM_TYPE_MATEDATA)) + return -1; + + if (inst->ctx->param_sets_from_ucode) { + ret = parse_stream_ucode(inst, s->data, s->len); + } else { + ret = parse_stream_cpu(inst, s->data, s->len); + } + } else if (bs->model == VB2_MEMORY_DMABUF || + bs->model == VB2_MEMORY_USERPTR) { + ret = parse_stream_ucode_dma(inst, bs->addr, size, + BUFF_IDX(bs, bs->index)); + } + } else { + if (inst->ctx->param_sets_from_ucode) { + ret = parse_stream_ucode(inst, buf, size); + } else { + ret = parse_stream_cpu(inst, buf, size); + } + } - if (st->magic == NORe || st->magic == NORn) - ret = stream_parse(inst, st->data, st->length); - else - ret = stream_parse(inst, buf, size); + inst->vsi->cur_pic = inst->vsi->pic; return ret; } @@ -303,8 +409,6 @@ static void vdec_mpeg12_deinit(unsigned long h_vdec) if (!inst) return; - aml_vcodec_debug_enter(inst); - video_decoder_release(&inst->vdec); vcodec_vfm_release(&inst->vfm); @@ -332,14 +436,16 @@ static void vdec_mpeg12_get_vf(struct vdec_mpeg12_inst *inst, struct vdec_v4l2_b vf = peek_video_frame(&inst->vfm); if (!vf) { - aml_vcodec_debug(inst, "there is no vframe."); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "there is no vframe.\n"); *out = NULL; return; } vf = get_video_frame(&inst->vfm); if (!vf) { - aml_vcodec_debug(inst, "the vframe is avalid."); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the vframe is avalid.\n"); *out = NULL; return; } @@ -376,29 +482,34 @@ static int vdec_mpeg12_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs, { struct vdec_mpeg12_inst *inst = (struct vdec_mpeg12_inst *)h_vdec; struct aml_vdec_adapt *vdec = &inst->vdec; - struct stream_info *st; - u8 *buf; - u32 size; - int ret = 0; + u8 *buf = (u8 *) bs->vaddr; + u32 size = bs->size; + int ret = -1; - /* bs NULL means flush decoder */ - if (bs == NULL) - return 0; - - buf = (u8 *)bs->vaddr; - size = bs->size; - st = (struct stream_info *)buf; - - if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn)) - ret = vdec_vbuf_write(vdec, st->m.buf, sizeof(st->m.drm)); - else if (st->magic == NORe) - ret = vdec_vbuf_write(vdec, st->data, st->length); - else if (st->magic == NORn) - ret = vdec_write_nalu(inst, st->data, st->length, timestamp); - else if (inst->ctx->is_stream_mode) - ret = vdec_vbuf_write(vdec, buf, size); - else + if (vdec_input_full(vdec)) + return -EAGAIN; + + if (inst->ctx->is_drm_mode) { + if (bs->model == VB2_MEMORY_MMAP) { + struct aml_video_stream *s = + (struct aml_video_stream *) buf; + + if (s->magic != AML_VIDEO_MAGIC) + return -1; + + ret = vdec_vframe_write(vdec, + s->data, + s->len, + timestamp); + } else if (bs->model == VB2_MEMORY_DMABUF || + bs->model == VB2_MEMORY_USERPTR) { + ret = vdec_vframe_write_with_dma(vdec, + bs->addr, size, timestamp, + BUFF_IDX(bs, bs->index)); + } + } else { ret = vdec_write_nalu(inst, buf, size, timestamp); + } return ret; } @@ -410,7 +521,8 @@ static int vdec_mpeg12_get_param(unsigned long h_vdec, struct vdec_mpeg12_inst *inst = (struct vdec_mpeg12_inst *)h_vdec; if (!inst) { - pr_err("the mpeg12 inst of dec is invalid.\n"); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the mpeg12 inst of dec is invalid.\n"); return -1; } @@ -436,17 +548,56 @@ static int vdec_mpeg12_get_param(unsigned long h_vdec, break; default: - aml_vcodec_err(inst, "invalid get parameter type=%d", type); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "invalid get parameter type=%d\n", type); ret = -EINVAL; } return ret; } +static void set_param_write_sync(struct vdec_mpeg12_inst *inst) +{ + complete(&inst->comp); +} + static void set_param_ps_info(struct vdec_mpeg12_inst *inst, struct aml_vdec_ps_infos *ps) { - pr_info("---%s, %d\n", __func__, __LINE__); + struct vdec_pic_info *pic = &inst->vsi->pic; + struct vdec_mpeg12_dec_info *dec = &inst->vsi->dec; + struct v4l2_rect *rect = &inst->vsi->crop; + + /* fill visible area size that be used for EGL. */ + pic->visible_width = ps->visible_width; + pic->visible_height = ps->visible_height; + + /* calc visible ares. */ + rect->left = 0; + rect->top = 0; + rect->width = pic->visible_width; + rect->height = pic->visible_height; + + /* config canvas size that be used for decoder. */ + pic->coded_width = ps->coded_width; + pic->coded_height = ps->coded_height; + pic->y_len_sz = pic->coded_width * pic->coded_height; + pic->c_len_sz = pic->y_len_sz >> 1; + + dec->dpb_sz = ps->dpb_size; + + inst->parms.ps = *ps; + inst->parms.parms_status |= + V4L2_CONFIG_PARM_DECODE_PSINFO; + + /*wake up*/ + complete(&inst->comp); + + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n", + ps->visible_width, ps->visible_height, + ps->coded_width, ps->coded_height, + dec->dpb_sz); } static int vdec_mpeg12_set_param(unsigned long h_vdec, @@ -456,17 +607,22 @@ static int vdec_mpeg12_set_param(unsigned long h_vdec, struct vdec_mpeg12_inst *inst = (struct vdec_mpeg12_inst *)h_vdec; if (!inst) { - pr_err("the mpeg12 inst of dec is invalid.\n"); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the mpeg12 inst of dec is invalid.\n"); return -1; } switch (type) { + case SET_PARAM_WRITE_FRAME_SYNC: + set_param_write_sync(inst); + break; case SET_PARAM_PS_INFO: set_param_ps_info(inst, in); break; default: - aml_vcodec_err(inst, "invalid set parameter type=%d", type); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "invalid set parameter type=%d\n", type); ret = -EINVAL; } diff --git a/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c index ab428af..c9ec202 100644 --- a/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c +++ b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c @@ -93,6 +93,7 @@ struct vdec_mpeg4_vsi { int head_offset; struct vdec_mpeg4_dec_info dec; struct vdec_pic_info pic; + struct vdec_pic_info cur_pic; struct v4l2_rect crop; bool is_combine; int nalu_pos; @@ -111,6 +112,7 @@ struct vdec_mpeg4_inst { struct aml_vdec_adapt vdec; struct vdec_mpeg4_vsi *vsi; struct vcodec_vfm_s vfm; + struct completion comp; }; static void get_pic_info(struct vdec_mpeg4_inst *inst, @@ -118,11 +120,14 @@ static void get_pic_info(struct vdec_mpeg4_inst *inst, { *pic = inst->vsi->pic; - aml_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", - pic->visible_width, pic->visible_height, - pic->coded_width, pic->coded_height); - aml_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz, - pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "pic(%d, %d), buf(%d, %d)\n", + pic->visible_width, pic->visible_height, + pic->coded_width, pic->coded_height); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "Y(%d, %d), C(%d, %d)\n", + pic->y_bs_sz, pic->y_len_sz, + pic->c_bs_sz, pic->c_len_sz); } static void get_crop_info(struct vdec_mpeg4_inst *inst, struct v4l2_rect *cr) @@ -132,14 +137,15 @@ static void get_crop_info(struct vdec_mpeg4_inst *inst, struct v4l2_rect *cr) cr->width = inst->vsi->crop.width; cr->height = inst->vsi->crop.height; - aml_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d", - cr->left, cr->top, cr->width, cr->height); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "l=%d, t=%d, w=%d, h=%d\n", + cr->left, cr->top, cr->width, cr->height); } static void get_dpb_size(struct vdec_mpeg4_inst *inst, unsigned int *dpb_sz) { *dpb_sz = 9;//inst->vsi->dec.dpb_sz; - aml_vcodec_debug(inst, "sz=%d", *dpb_sz); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, "sz=%d\n", *dpb_sz); } static int vdec_mpeg4_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) @@ -169,26 +175,32 @@ static int vdec_mpeg4_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) /* init vfm */ inst->vfm.ctx = ctx; inst->vfm.ada_ctx = &inst->vdec; - vcodec_vfm_init(&inst->vfm); + ret = vcodec_vfm_init(&inst->vfm); + if (ret) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "init vfm failed.\n"); + goto err; + } ret = video_decoder_init(&inst->vdec); if (ret) { - aml_vcodec_err(inst, "vdec_mpeg4 init err=%d", ret); - goto error_free_inst; + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "vdec_mpeg4 init err=%d\n", ret); + goto err; } /* probe info from the stream */ inst->vsi = kzalloc(sizeof(struct vdec_mpeg4_vsi), GFP_KERNEL); if (!inst->vsi) { ret = -ENOMEM; - goto error_free_inst; + goto err; } /* alloc the header buffer to be used cache sps or spp etc.*/ inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL); - if (!inst->vsi) { + if (!inst->vsi->header_buf) { ret = -ENOMEM; - goto error_free_vsi; + goto err; } inst->vsi->pic.visible_width = 1920; @@ -200,7 +212,8 @@ static int vdec_mpeg4_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) inst->vsi->pic.c_bs_sz = 0; inst->vsi->pic.c_len_sz = (1920 * 1088 / 2); - aml_vcodec_debug(inst, "mpeg4 Instance >> %p", inst); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "mpeg4 Instance >> %lx\n", (ulong) inst); ctx->ada_ctx = &inst->vdec; *h_vdec = (unsigned long)inst; @@ -209,10 +222,15 @@ static int vdec_mpeg4_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) return 0; -error_free_vsi: - kfree(inst->vsi); -error_free_inst: - kfree(inst); +err: + if (inst) + vcodec_vfm_release(&inst->vfm); + if (inst && inst->vsi && inst->vsi->header_buf) + kfree(inst->vsi->header_buf); + if (inst && inst->vsi) + kfree(inst->vsi); + if (inst) + kfree(inst); *h_vdec = 0; return ret; @@ -253,12 +271,52 @@ static void fill_vdec_params(struct vdec_mpeg4_inst *inst, /* calc DPB size */ dec->dpb_sz = 9;//refer_buffer_num(sps->level_idc, poc_cnt, mb_w, mb_h); - pr_info("[%d] The stream infos, coded:(%d x %d), visible:(%d x %d), DPB: %d\n", - inst->ctx->id, pic->coded_width, pic->coded_height, + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR, + "The stream infos, coded:(%d x %d), visible:(%d x %d), DPB: %d\n", + pic->coded_width, pic->coded_height, pic->visible_width, pic->visible_height, dec->dpb_sz); } -static int stream_parse(struct vdec_mpeg4_inst *inst, u8 *buf, u32 size) +static int parse_stream_ucode(struct vdec_mpeg4_inst *inst, u8 *buf, u32 size) +{ + int ret = 0; + struct aml_vdec_adapt *vdec = &inst->vdec; + + ret = vdec_vframe_write(vdec, buf, size, 0); + if (ret < 0) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "write frame data failed. err: %d\n", ret); + return ret; + } + + /* wait ucode parse ending. */ + wait_for_completion_timeout(&inst->comp, + msecs_to_jiffies(1000)); + + return inst->vsi->dec.dpb_sz ? 0 : -1; +} + +static int parse_stream_ucode_dma(struct vdec_mpeg4_inst *inst, + ulong buf, u32 size, u32 handle) +{ + int ret = 0; + struct aml_vdec_adapt *vdec = &inst->vdec; + + ret = vdec_vframe_write_with_dma(vdec, buf, size, 0, handle); + if (ret < 0) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "write frame data failed. err: %d\n", ret); + return ret; + } + + /* wait ucode parse ending. */ + wait_for_completion_timeout(&inst->comp, + msecs_to_jiffies(1000)); + + return inst->vsi->dec.dpb_sz ? 0 : -1; +} + +static int parse_stream_cpu(struct vdec_mpeg4_inst *inst, u8 *buf, u32 size) { int ret = 0; struct mpeg4_param_sets *ps = NULL; @@ -269,7 +327,8 @@ static int stream_parse(struct vdec_mpeg4_inst *inst, u8 *buf, u32 size) ret = mpeg4_decode_extradata_ps(buf, size, ps); if (ret) { - pr_err("parse extra data failed. err: %d\n", ret); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "parse extra data failed. err: %d\n", ret); goto out; } @@ -288,19 +347,38 @@ static int vdec_mpeg4_probe(unsigned long h_vdec, { struct vdec_mpeg4_inst *inst = (struct vdec_mpeg4_inst *)h_vdec; - struct stream_info *st; u8 *buf = (u8 *)bs->vaddr; u32 size = bs->size; int ret = 0; - st = (struct stream_info *)buf; - if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn)) - return 0; + if (inst->ctx->is_drm_mode) { + if (bs->model == VB2_MEMORY_MMAP) { + struct aml_video_stream *s = + (struct aml_video_stream *) buf; + + if ((s->magic != AML_VIDEO_MAGIC) && + (s->type != V4L_STREAM_TYPE_MATEDATA)) + return -1; + + if (inst->ctx->param_sets_from_ucode) { + ret = parse_stream_ucode(inst, s->data, s->len); + } else { + ret = parse_stream_cpu(inst, s->data, s->len); + } + } else if (bs->model == VB2_MEMORY_DMABUF || + bs->model == VB2_MEMORY_USERPTR) { + ret = parse_stream_ucode_dma(inst, bs->addr, size, + BUFF_IDX(bs, bs->index)); + } + } else { + if (inst->ctx->param_sets_from_ucode) { + ret = parse_stream_ucode(inst, buf, size); + } else { + ret = parse_stream_cpu(inst, buf, size); + } + } - if (st->magic == NORe || st->magic == NORn) - ret = stream_parse(inst, st->data, st->length); - else - ret = stream_parse(inst, buf, size); + inst->vsi->cur_pic = inst->vsi->pic; return ret; } @@ -312,8 +390,6 @@ static void vdec_mpeg4_deinit(unsigned long h_vdec) if (!inst) return; - aml_vcodec_debug_enter(inst); - video_decoder_release(&inst->vdec); vcodec_vfm_release(&inst->vfm); @@ -341,14 +417,16 @@ static void vdec_mpeg4_get_vf(struct vdec_mpeg4_inst *inst, struct vdec_v4l2_buf vf = peek_video_frame(&inst->vfm); if (!vf) { - aml_vcodec_debug(inst, "there is no vframe."); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "there is no vframe.\n"); *out = NULL; return; } vf = get_video_frame(&inst->vfm); if (!vf) { - aml_vcodec_debug(inst, "the vframe is avalid."); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the vframe is avalid.\n"); *out = NULL; return; } @@ -385,29 +463,34 @@ static int vdec_mpeg4_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs, { struct vdec_mpeg4_inst *inst = (struct vdec_mpeg4_inst *)h_vdec; struct aml_vdec_adapt *vdec = &inst->vdec; - struct stream_info *st; - u8 *buf; - u32 size; - int ret = 0; + u8 *buf = (u8 *) bs->vaddr; + u32 size = bs->size; + int ret = -1; - /* bs NULL means flush decoder */ - if (bs == NULL) - return 0; - - buf = (u8 *)bs->vaddr; - size = bs->size; - st = (struct stream_info *)buf; - - if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn)) - ret = vdec_vbuf_write(vdec, st->m.buf, sizeof(st->m.drm)); - else if (st->magic == NORe) - ret = vdec_vbuf_write(vdec, st->data, st->length); - else if (st->magic == NORn) - ret = vdec_write_nalu(inst, st->data, st->length, timestamp); - else if (inst->ctx->is_stream_mode) - ret = vdec_vbuf_write(vdec, buf, size); - else + if (vdec_input_full(vdec)) + return -EAGAIN; + + if (inst->ctx->is_drm_mode) { + if (bs->model == VB2_MEMORY_MMAP) { + struct aml_video_stream *s = + (struct aml_video_stream *) buf; + + if (s->magic != AML_VIDEO_MAGIC) + return -1; + + ret = vdec_vframe_write(vdec, + s->data, + s->len, + timestamp); + } else if (bs->model == VB2_MEMORY_DMABUF || + bs->model == VB2_MEMORY_USERPTR) { + ret = vdec_vframe_write_with_dma(vdec, + bs->addr, size, timestamp, + BUFF_IDX(bs, bs->index)); + } + } else { ret = vdec_write_nalu(inst, buf, size, timestamp); + } return ret; } @@ -419,7 +502,8 @@ static int vdec_mpeg4_get_param(unsigned long h_vdec, struct vdec_mpeg4_inst *inst = (struct vdec_mpeg4_inst *)h_vdec; if (!inst) { - pr_err("the mpeg4 inst of dec is invalid.\n"); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the mpeg4 inst of dec is invalid.\n"); return -1; } @@ -445,7 +529,8 @@ static int vdec_mpeg4_get_param(unsigned long h_vdec, break; default: - aml_vcodec_err(inst, "invalid get parameter type=%d", type); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "invalid get parameter type=%d\n", type); ret = -EINVAL; } @@ -455,7 +540,7 @@ static int vdec_mpeg4_get_param(unsigned long h_vdec, static void set_param_ps_info(struct vdec_mpeg4_inst *inst, struct aml_vdec_ps_infos *ps) { - pr_info("---%s, %d\n", __func__, __LINE__); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "\n"); } static int vdec_mpeg4_set_param(unsigned long h_vdec, @@ -465,7 +550,8 @@ static int vdec_mpeg4_set_param(unsigned long h_vdec, struct vdec_mpeg4_inst *inst = (struct vdec_mpeg4_inst *)h_vdec; if (!inst) { - pr_err("the mpeg4 inst of dec is invalid.\n"); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the mpeg4 inst of dec is invalid.\n"); return -1; } @@ -475,7 +561,8 @@ static int vdec_mpeg4_set_param(unsigned long h_vdec, break; default: - aml_vcodec_err(inst, "invalid set parameter type=%d", type); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "invalid set parameter type=%d\n", type); ret = -EINVAL; } diff --git a/drivers/amvdec_ports/decoder/vdec_vp9_if.c b/drivers/amvdec_ports/decoder/vdec_vp9_if.c index 7d395ba..0a5ceda 100644 --- a/drivers/amvdec_ports/decoder/vdec_vp9_if.c +++ b/drivers/amvdec_ports/decoder/vdec_vp9_if.c @@ -136,11 +136,14 @@ static void get_pic_info(struct vdec_vp9_inst *inst, { *pic = inst->vsi->pic; - aml_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", - pic->visible_width, pic->visible_height, - pic->coded_width, pic->coded_height); - aml_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz, - pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "pic(%d, %d), buf(%d, %d)\n", + pic->visible_width, pic->visible_height, + pic->coded_width, pic->coded_height); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "Y(%d, %d), C(%d, %d)\n", + pic->y_bs_sz, pic->y_len_sz, + pic->c_bs_sz, pic->c_len_sz); } static void get_crop_info(struct vdec_vp9_inst *inst, struct v4l2_rect *cr) @@ -150,14 +153,15 @@ static void get_crop_info(struct vdec_vp9_inst *inst, struct v4l2_rect *cr) cr->width = inst->vsi->crop.width; cr->height = inst->vsi->crop.height; - aml_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d", - cr->left, cr->top, cr->width, cr->height); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + "l=%d, t=%d, w=%d, h=%d\n", + cr->left, cr->top, cr->width, cr->height); } static void get_dpb_size(struct vdec_vp9_inst *inst, unsigned int *dpb_sz) { *dpb_sz = inst->vsi->dec.dpb_sz; - aml_vcodec_debug(inst, "sz=%d", *dpb_sz); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, "sz=%d\n", *dpb_sz); } static u32 vdec_config_default_parms(u8 *parm) @@ -277,7 +281,8 @@ static int vdec_vp9_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) inst->vfm.ada_ctx = &inst->vdec; ret = vcodec_vfm_init(&inst->vfm); if (ret) { - pr_err("%s, init vfm failed.\n", __func__); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "init vfm failed.\n"); goto err; } @@ -290,14 +295,15 @@ static int vdec_vp9_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) /* alloc the header buffer to be used cache sps or spp etc.*/ inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL); - if (!inst->vsi) { + if (!inst->vsi->header_buf) { ret = -ENOMEM; goto err; } init_completion(&inst->comp); - aml_vcodec_debug(inst, "vp9 Instance >> %p", inst); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "vp9 Instance >> %lx\n", (ulong) inst); ctx->ada_ctx = &inst->vdec; *h_vdec = (unsigned long)inst; @@ -305,7 +311,8 @@ static int vdec_vp9_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) /* init decoder. */ ret = video_decoder_init(&inst->vdec); if (ret) { - aml_vcodec_err(inst, "vdec_vp9 init err=%d", ret); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "vdec_vp9 init err=%d\n", ret); goto err; } @@ -425,19 +432,21 @@ static void fill_vdec_params(struct vdec_vp9_inst *inst, inst->parms.ps.dpb_size = dec->dpb_sz; inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_PSINFO; - aml_vcodec_debug(inst, "[%d] The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n", - inst->ctx->id, dw, pic->coded_width, pic->coded_height, + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR, + "The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n", + dw, pic->coded_width, pic->coded_height, pic->visible_width, pic->visible_height, dec->dpb_sz - margin, margin); } -static int stream_parse_by_ucode(struct vdec_vp9_inst *inst, u8 *buf, u32 size) +static int parse_stream_ucode(struct vdec_vp9_inst *inst, u8 *buf, u32 size) { int ret = 0; ret = vdec_write_nalu(inst, buf, size, 0); if (ret < 0) { - pr_err("write frame data failed. err: %d\n", ret); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "write frame data failed. err: %d\n", ret); return ret; } @@ -448,7 +457,27 @@ static int stream_parse_by_ucode(struct vdec_vp9_inst *inst, u8 *buf, u32 size) return inst->vsi->dec.dpb_sz ? 0 : -1; } -static int stream_parse(struct vdec_vp9_inst *inst, u8 *buf, u32 size) +static int parse_stream_ucode_dma(struct vdec_vp9_inst *inst, + ulong buf, u32 size, u32 handle) +{ + int ret = 0; + struct aml_vdec_adapt *vdec = &inst->vdec; + + ret = vdec_vframe_write_with_dma(vdec, buf, size, 0, handle); + if (ret < 0) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "write frame data failed. err: %d\n", ret); + return ret; + } + + /* wait ucode parse ending. */ + wait_for_completion_timeout(&inst->comp, + msecs_to_jiffies(1000)); + + return inst->vsi->dec.dpb_sz ? 0 : -1; +} + +static int parse_stream_cpu(struct vdec_vp9_inst *inst, u8 *buf, u32 size) { int ret = 0; struct vp9_param_sets *ps = NULL; @@ -459,7 +488,8 @@ static int stream_parse(struct vdec_vp9_inst *inst, u8 *buf, u32 size) ret = vp9_decode_extradata_ps(buf, size, ps); if (ret) { - pr_err("parse extra data failed. err: %d\n", ret); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "parse extra data failed. err: %d\n", ret); goto out; } @@ -478,22 +508,35 @@ static int vdec_vp9_probe(unsigned long h_vdec, { struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; - struct stream_info *st; u8 *buf = (u8 *)bs->vaddr; u32 size = bs->size; int ret = 0; - st = (struct stream_info *)buf; - if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn)) - return 0; - - if (st->magic == NORe || st->magic == NORn) - ret = stream_parse(inst, st->data, st->length); - else { - if (inst->ctx->param_sets_from_ucode) - ret = stream_parse_by_ucode(inst, buf, size); - else - ret = stream_parse(inst, buf, size); + if (inst->ctx->is_drm_mode) { + if (bs->model == VB2_MEMORY_MMAP) { + struct aml_video_stream *s = + (struct aml_video_stream *) buf; + + if ((s->magic != AML_VIDEO_MAGIC) && + (s->type != V4L_STREAM_TYPE_MATEDATA)) + return -1; + + if (inst->ctx->param_sets_from_ucode) { + ret = parse_stream_ucode(inst, s->data, s->len); + } else { + ret = parse_stream_cpu(inst, s->data, s->len); + } + } else if (bs->model == VB2_MEMORY_DMABUF || + bs->model == VB2_MEMORY_USERPTR) { + ret = parse_stream_ucode_dma(inst, bs->addr, size, + BUFF_IDX(bs, bs->index)); + } + } else { + if (inst->ctx->param_sets_from_ucode) { + ret = parse_stream_ucode(inst, buf, size); + } else { + ret = parse_stream_cpu(inst, buf, size); + } } inst->vsi->cur_pic = inst->vsi->pic; @@ -507,8 +550,6 @@ static void vdec_vp9_deinit(unsigned long h_vdec) struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; struct aml_vcodec_ctx *ctx = inst->ctx; - aml_vcodec_debug_enter(inst); - video_decoder_release(&inst->vdec); vcodec_vfm_release(&inst->vfm); @@ -543,14 +584,16 @@ static void vdec_vp9_get_vf(struct vdec_vp9_inst *inst, struct vdec_v4l2_buffer vf = peek_video_frame(&inst->vfm); if (!vf) { - aml_vcodec_debug(inst, "there is no vframe."); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "there is no vframe.\n"); *out = NULL; return; } vf = get_video_frame(&inst->vfm); if (!vf) { - aml_vcodec_debug(inst, "the vframe is avalid."); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the vframe is avalid.\n"); *out = NULL; return; } @@ -581,7 +624,8 @@ static void add_prefix_data(struct vp9_superframe_split *s, length = s->size + s->nb_frames * PREFIX_SIZE; p = vzalloc(length); if (!p) { - pr_err("alloc size %d failed.\n" ,length); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "alloc size %d failed.\n" ,length); return; } @@ -631,7 +675,8 @@ static void trigger_decoder(struct aml_vdec_adapt *vdec) frame_size = vp9_trigger_framesize[i]; ret = vdec_vframe_write(vdec, p, frame_size, 0); - pr_err("write trigger frame %d\n", ret); + v4l_dbg(vdec->ctx, V4L_DEBUG_CODEC_ERROR, + "write trigger frame %d\n", ret); p += frame_size; } } @@ -660,7 +705,8 @@ static int vdec_write_nalu(struct vdec_vp9_inst *inst, s.data_size = size; ret = vp9_superframe_split_filter(&s); if (ret) { - pr_err("parse frames failed.\n"); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "parse frames failed.\n"); return ret; } @@ -685,7 +731,7 @@ static bool monitor_res_change(struct vdec_vp9_inst *inst, u8 *buf, u32 size) ((p[17] << 16) | (p[18] << 8) | p[19]); if (synccode == SYNC_CODE) { - ret = stream_parse(inst, p, len); + ret = parse_stream_cpu(inst, p, len); if (!ret && (inst->vsi->cur_pic.coded_width != inst->vsi->pic.coded_width || inst->vsi->cur_pic.coded_height != @@ -703,9 +749,8 @@ static int vdec_vp9_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs, { struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; struct aml_vdec_adapt *vdec = &inst->vdec; - struct stream_info *st; - u8 *buf; - u32 size; + u8 *buf = (u8 *) bs->vaddr; + u32 size = bs->size; int ret = -1; if (bs == NULL) @@ -716,21 +761,35 @@ static int vdec_vp9_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs, return -EAGAIN; } - buf = (u8 *)bs->vaddr; - size = bs->size; - st = (struct stream_info *)buf; - - if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn)) - ret = vdec_vbuf_write(vdec, st->m.buf, sizeof(st->m.drm)); - else if (st->magic == NORe) - ret = vdec_vbuf_write(vdec, st->data, st->length); - else if (st->magic == NORn) - ret = vdec_write_nalu(inst, st->data, st->length, timestamp); - else if (inst->ctx->is_stream_mode) - ret = vdec_vbuf_write(vdec, buf, size); - else { + if (inst->ctx->is_drm_mode) { + if (bs->model == VB2_MEMORY_MMAP) { + struct aml_video_stream *s = + (struct aml_video_stream *) buf; + + if (s->magic != AML_VIDEO_MAGIC) + return -1; + + if (!inst->ctx->param_sets_from_ucode && + (s->type == V4L_STREAM_TYPE_MATEDATA)) { + if ((*res_chg = monitor_res_change(inst, + s->data, s->len))) + return 0; + } + + ret = vdec_vframe_write(vdec, + s->data, + s->len, + timestamp); + } else if (bs->model == VB2_MEMORY_DMABUF || + bs->model == VB2_MEMORY_USERPTR) { + ret = vdec_vframe_write_with_dma(vdec, + bs->addr, size, timestamp, + BUFF_IDX(bs, bs->index)); + } + } else { /*checked whether the resolution changes.*/ - if ((*res_chg = monitor_res_change(inst, buf, size))) + if ((!inst->ctx->param_sets_from_ucode) && + (*res_chg = monitor_res_change(inst, buf, size))) return 0; ret = vdec_write_nalu(inst, buf, size, timestamp); @@ -754,7 +813,8 @@ static int vdec_vp9_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs, parms->parms_status |= inst->parms.parms_status; - aml_vcodec_debug(inst, "parms status: %u", parms->parms_status); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "parms status: %u\n", parms->parms_status); } static int vdec_vp9_get_param(unsigned long h_vdec, @@ -764,7 +824,8 @@ static int vdec_vp9_get_param(unsigned long h_vdec, struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; if (!inst) { - pr_err("the vp9 inst of dec is invalid.\n"); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the vp9 inst of dec is invalid.\n"); return -1; } @@ -793,7 +854,8 @@ static int vdec_vp9_get_param(unsigned long h_vdec, get_param_config_info(inst, out); break; default: - aml_vcodec_err(inst, "invalid get parameter type=%d", type); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "invalid get parameter type=%d\n", type); ret = -EINVAL; } @@ -830,7 +892,7 @@ static void set_param_ps_info(struct vdec_vp9_inst *inst, pic->c_len_sz = pic->y_len_sz >> 1; /* calc DPB size */ - dec->dpb_sz = 5; + dec->dpb_sz = ps->dpb_size; inst->parms.ps = *ps; inst->parms.parms_status |= @@ -839,7 +901,8 @@ static void set_param_ps_info(struct vdec_vp9_inst *inst, /*wake up*/ complete(&inst->comp); - pr_info("Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n", + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n", ps->visible_width, ps->visible_height, ps->coded_width, ps->coded_height, ps->dpb_size); @@ -855,14 +918,16 @@ static void set_param_hdr_info(struct vdec_vp9_inst *inst, V4L2_CONFIG_PARM_DECODE_HDRINFO; aml_vdec_dispatch_event(inst->ctx, V4L2_EVENT_SRC_CH_HDRINFO); - pr_info("VP9 set HDR infos\n"); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "VP9 set HDR infos\n"); } } static void set_param_post_event(struct vdec_vp9_inst *inst, u32 *event) { aml_vdec_dispatch_event(inst->ctx, *event); - pr_info("VP9 post event: %d\n", *event); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "VP9 post event: %d\n", *event); } static int vdec_vp9_set_param(unsigned long h_vdec, @@ -872,7 +937,8 @@ static int vdec_vp9_set_param(unsigned long h_vdec, struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; if (!inst) { - pr_err("the vp9 inst of dec is invalid.\n"); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the vp9 inst of dec is invalid.\n"); return -1; } @@ -893,7 +959,8 @@ static int vdec_vp9_set_param(unsigned long h_vdec, set_param_post_event(inst, in); break; default: - aml_vcodec_err(inst, "invalid set parameter type=%d", type); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "invalid set parameter type=%d\n", type); ret = -EINVAL; } diff --git a/drivers/amvdec_ports/vdec_drv_if.c b/drivers/amvdec_ports/vdec_drv_if.c index 4b70ed0..e870da4 100644 --- a/drivers/amvdec_ports/vdec_drv_if.c +++ b/drivers/amvdec_ports/vdec_drv_if.c @@ -24,7 +24,6 @@ #include "vdec_drv_if.h" #include "aml_vcodec_dec.h" #include "vdec_drv_base.h" -#include "aml_vcodec_dec_pm.h" const struct vdec_common_if *get_h264_dec_comm_if(void); const struct vdec_common_if *get_hevc_dec_comm_if(void); @@ -83,8 +82,9 @@ int vdec_if_decode(struct aml_vcodec_ctx *ctx, struct aml_vcodec_mem *bs, int ret = 0; if (bs) { - if ((bs->dma_addr & 63) != 0) { - aml_v4l2_err("bs dma_addr should 64 byte align"); + if ((bs->addr & 63) != 0) { + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "bs dma_addr should 64 byte align\n"); return -EINVAL; } } diff --git a/drivers/amvdec_ports/vdec_drv_if.h b/drivers/amvdec_ports/vdec_drv_if.h index d3ccef2..a5ab735 100644 --- a/drivers/amvdec_ports/vdec_drv_if.h +++ b/drivers/amvdec_ports/vdec_drv_if.h @@ -25,19 +25,26 @@ #include "aml_vcodec_util.h" #include "../stream_input/parser/streambuf.h" -#define NORe CODEC_MODE('N', 'O', 'R', 'e') // normal es -#define NORn CODEC_MODE('N', 'O', 'R', 'n') // normal nalu -#define DRMe CODEC_MODE('D', 'R', 'M', 'e') // drm es -#define DRMn CODEC_MODE('D', 'R', 'M', 'n') // drm nalu +#define AML_VIDEO_MAGIC CODEC_MODE('A', 'M', 'L', 'V') + +#define V4L_STREAM_TYPE_MATEDATA (0) +#define V4L_STREAM_TYPE_FRAME (1) struct stream_info { + u32 stream_width; + u32 stream_height; + u32 stream_field; + u32 stream_dpb; +}; + +struct aml_video_stream { u32 magic; u32 type; union { - struct drm_info drm; - u8 buf[128]; + struct stream_info s; + u8 buf[64]; } m; - u32 length; + u32 len; u8 data[0]; }; diff --git a/drivers/common/chips/chips.c b/drivers/common/chips/chips.c index 63d55ba..a55d640 100644 --- a/drivers/common/chips/chips.c +++ b/drivers/common/chips/chips.c @@ -145,6 +145,7 @@ static const struct type_name vformat_type_name[] = { {VFORMAT_JPEG_ENC, "jpeg_enc"}, {VFORMAT_VP9, "vp9"}, {VFORMAT_AVS2, "avs2"}, + {VFORMAT_AV1, "av1"}, {VFORMAT_YUV, "yuv"}, {0, NULL}, }; diff --git a/drivers/common/chips/decoder_cpu_ver_info.c b/drivers/common/chips/decoder_cpu_ver_info.c index 7818a21..894bd74 100644 --- a/drivers/common/chips/decoder_cpu_ver_info.c +++ b/drivers/common/chips/decoder_cpu_ver_info.c @@ -159,3 +159,11 @@ enum AM_MESON_CPU_MAJOR_ID get_cpu_major_id(void) return cpu_ver_id; } EXPORT_SYMBOL(get_cpu_major_id); + +bool is_cpu_tm2_revb(void) +{ + return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TM2) && + (is_meson_rev_b())); +} +EXPORT_SYMBOL(is_cpu_tm2_revb); + diff --git a/drivers/common/chips/decoder_cpu_ver_info.h b/drivers/common/chips/decoder_cpu_ver_info.h index 494f5f6..83e8274 100644 --- a/drivers/common/chips/decoder_cpu_ver_info.h +++ b/drivers/common/chips/decoder_cpu_ver_info.h @@ -52,4 +52,5 @@ enum AM_MESON_CPU_MAJOR_ID }; enum AM_MESON_CPU_MAJOR_ID get_cpu_major_id(void); +bool is_cpu_tm2_revb(void); #endif diff --git a/drivers/common/firmware/firmware_drv.c b/drivers/common/firmware/firmware_drv.c index fa21f0c..85e904e 100644 --- a/drivers/common/firmware/firmware_drv.c +++ b/drivers/common/firmware/firmware_drv.c @@ -122,12 +122,16 @@ int get_data_from_name(const char *name, char *buf) struct fw_mgr_s *mgr = g_mgr; struct fw_info_s *info; char *fw_name = __getname(); + int len; if (fw_name == NULL) return -ENOMEM; - strcat(fw_name, name); - strcat(fw_name, ".bin"); + len = snprintf(fw_name, PATH_MAX, "%s.bin", name); + if (len >= PATH_MAX) { + __putname(fw_name); + return -ENAMETOOLONG; + } mutex_lock(&mutex); @@ -544,6 +548,7 @@ static int fw_replace_dup_data(char *buf) goto out; } + info->data->head.data_size = len; memcpy(data, pinfo->data, len); memcpy(data, info->data, sizeof(*data)); diff --git a/drivers/common/firmware/firmware_type.c b/drivers/common/firmware/firmware_type.c index e781a51..ac35859 100644 --- a/drivers/common/firmware/firmware_type.c +++ b/drivers/common/firmware/firmware_type.c @@ -55,6 +55,7 @@ static const struct format_name_s format_name[] = { {VIDEO_DEC_VP9_G12A, "vp9_g12a"}, {VIDEO_DEC_AVS2, "avs2"}, {VIDEO_DEC_AVS2_MMU, "avs2_mmu"}, + {VIDEO_DEC_AV1_MMU, "av1_mmu"}, {VIDEO_ENC_H264, "h264_enc"}, {VIDEO_ENC_JPEG, "jpeg_enc"}, {FIRMWARE_MAX, "unknown"}, diff --git a/drivers/common/firmware/firmware_type.h b/drivers/common/firmware/firmware_type.h index c2ef01a..e997057 100644 --- a/drivers/common/firmware/firmware_type.h +++ b/drivers/common/firmware/firmware_type.h @@ -65,6 +65,7 @@ #define VIDEO_DEC_H263_MULTI TAG('2', '6', '3', 'M') #define VIDEO_DEC_HEVC_MMU_SWAP TAG('2', '6', '5', 'S') #define VIDEO_DEC_AVS_MULTI TAG('A', 'V', 'S', 'M') +#define VIDEO_DEC_AV1_MMU TAG('A', 'V', '1', 'M') /* ... */ #define FIRMWARE_MAX (UINT_MAX) diff --git a/drivers/common/media_clock/clk/clk.c b/drivers/common/media_clock/clk/clk.c index b60a08d..144006c 100644 --- a/drivers/common/media_clock/clk/clk.c +++ b/drivers/common/media_clock/clk/clk.c @@ -334,7 +334,8 @@ int vdec_source_changed_for_clk_set(int format, int width, int height, int fps) */ if (format == VFORMAT_HEVC || format == VFORMAT_VP9 - || format == VFORMAT_AVS2) { + || format == VFORMAT_AVS2 + || format == VFORMAT_AV1) { ret_clk = hevc_clock_set(clk); clock_source_wxhxfps_saved[VDEC_HEVC] = width * height * fps; if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { diff --git a/drivers/common/media_clock/clk/clkg12.c b/drivers/common/media_clock/clk/clkg12.c index f045bd3..9694959 100644 --- a/drivers/common/media_clock/clk/clkg12.c +++ b/drivers/common/media_clock/clk/clkg12.c @@ -403,6 +403,11 @@ static struct clk_set_setting clks_for_formats[] = { {1920*1080*60, 166}, {4096*2048*30, 333}, {4096*2048*60, 630}, {INT_MAX, 630},} }, + {/*VFORMAT_AV1*/ + {{1280*720*30, 100}, {1920*1080*30, 100}, + {1920*1080*60, 166}, {4096*2048*30, 333}, + {4096*2048*60, 630}, {INT_MAX, 630},} + }, }; diff --git a/drivers/frame_provider/decoder/Makefile b/drivers/frame_provider/decoder/Makefile index 6511f25..349d381 100644 --- a/drivers/frame_provider/decoder/Makefile +++ b/drivers/frame_provider/decoder/Makefile @@ -11,3 +11,4 @@ obj-y += real/ obj-y += avs/ obj-y += avs2/ obj-y += avs_multi/ +obj-y += vav1/ diff --git a/drivers/frame_provider/decoder/avs/avs.c b/drivers/frame_provider/decoder/avs/avs.c index 642c3bb..b97cb33 100644 --- a/drivers/frame_provider/decoder/avs/avs.c +++ b/drivers/frame_provider/decoder/avs/avs.c @@ -151,7 +151,7 @@ static struct vframe_provider_s vavs_vf_prov; #define RV_AI_BUFF_START_ADDR 0x01a00000 #define LONG_CABAC_RV_AI_BUFF_START_ADDR 0x00000000 -static u32 vf_buf_num = 4; +static u32 vf_buf_num = 8; static u32 vf_buf_num_used; static u32 canvas_base = 128; #ifdef NV21 @@ -479,7 +479,7 @@ static void vavs_isr(void) (((reg >> 8) & 0x3) << 3) - 1) & 0x1f; else buffer_index = - ((reg & 0x7) - 1) & 3; + ((reg & 0x7) - 1) & 7; picture_type = (reg >> 3) & 7; #ifdef DEBUG_PTS @@ -644,7 +644,6 @@ static void vavs_isr(void) decoder_bmmu_box_get_mem_handle( mm_blk_handle, buffer_index); - kfifo_put(&display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); @@ -727,6 +726,7 @@ static void vavs_isr(void) mm_blk_handle, buffer_index); decoder_do_frame_check(NULL, vf); + kfifo_put(&display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); @@ -969,13 +969,14 @@ void vavs_recover(void) WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8)); WRITE_VREG(DOS_SW_RESET0, 0); - + WRITE_VREG(AV_SCRATCH_H, 0); if (firmware_sel == 1) { WRITE_VREG(POWER_CTL_VLD, 0x10); WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2, MEM_FIFO_CNT_BIT, 2); WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8, MEM_LEVEL_CNT_BIT, 6); + WRITE_VREG(AV_SCRATCH_H, 1); // 8 buf flag to ucode } @@ -1078,6 +1079,7 @@ static int vavs_prot_init(void) /*************************************************************/ r = vavs_canvas_init(); + WRITE_VREG(AV_SCRATCH_H, 0); #ifdef NV21 if (firmware_sel == 0) { /* fixed canvas index */ @@ -1095,12 +1097,7 @@ static int vavs_prot_init(void) << 16) ); } - /* - *WRITE_VREG(AV_SCRATCH_0, 0x010100); - *WRITE_VREG(AV_SCRATCH_1, 0x040403); - *WRITE_VREG(AV_SCRATCH_2, 0x070706); - *WRITE_VREG(AV_SCRATCH_3, 0x0a0a09); - */ + WRITE_VREG(AV_SCRATCH_H, 1); // 8 buf flag to ucode } #else /* index v << 16 | u << 8 | y */ @@ -1161,7 +1158,7 @@ static int vavs_prot_init(void) #ifdef AVSP_LONG_CABAC static unsigned char es_write_addr[MAX_CODED_FRAME_SIZE] __aligned(64); #endif -static void vavs_local_init(void) +static void vavs_local_init(bool is_reset) { int i; @@ -1180,19 +1177,23 @@ static void vavs_local_init(void) #ifdef DEBUG_PTS pts_hit = pts_missed = pts_i_hit = pts_i_missed = 0; #endif - INIT_KFIFO(display_q); - INIT_KFIFO(recycle_q); - INIT_KFIFO(newframe_q); - for (i = 0; i < VF_POOL_SIZE; i++) { - const struct vframe_s *vf = &vfpool[i]; + if (!is_reset) { + INIT_KFIFO(display_q); + INIT_KFIFO(recycle_q); + INIT_KFIFO(newframe_q); - vfpool[i].index = vf_buf_num; - vfpool[i].bufWidth = 1920; - kfifo_put(&newframe_q, vf); + for (i = 0; i < VF_POOL_SIZE; i++) { + const struct vframe_s *vf = &vfpool[i]; + + vfpool[i].index = vf_buf_num; + vfpool[i].bufWidth = 1920; + kfifo_put(&newframe_q, vf); + } + + for (i = 0; i < vf_buf_num; i++) + vfbuf_use[i] = 0; } - for (i = 0; i < vf_buf_num; i++) - vfbuf_use[i] = 0; cur_vfpool = vfpool; @@ -1232,7 +1233,7 @@ static void vavs_ppmgr_reset(void) { vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); - vavs_local_init(); + vavs_local_init(true); pr_info("vavs: vf_ppmgr_reset\n"); } @@ -1241,12 +1242,12 @@ static void vavs_ppmgr_reset(void) static void vavs_local_reset(void) { mutex_lock(&vavs_mutex); - recover_flag = 1; + //recover_flag = 1; pr_info("error, local reset\n"); amvdec_stop(); msleep(100); vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); - vavs_local_init(); + vavs_local_init(true); vavs_recover(); @@ -1283,7 +1284,7 @@ static void vavs_fatal_error_handler(struct work_struct *work) vavs_ppmgr_reset(); #else vf_light_unreg_provider(&vavs_vf_prov); - vavs_local_init(); + vavs_local_init(true); vf_reg_provider(&vavs_vf_prov); #endif vavs_recover(); @@ -1341,7 +1342,7 @@ static void vavs_put_timer_func(unsigned long arg) vavs_ppmgr_reset(); #else vf_light_unreg_provider(&vavs_vf_prov); - vavs_local_init(); + vavs_local_init(true); vf_reg_provider(&vavs_vf_prov); #endif vavs_recover(); @@ -1409,7 +1410,6 @@ static void vavs_put_timer_func(unsigned long arg) kfifo_put(&newframe_q, (const struct vframe_s *)vf); } - } if (frame_dur > 0 && saved_resolution != @@ -1548,7 +1548,7 @@ static s32 vavs_init(void) stat |= STAT_TIMER_INIT; amvdec_enable(); - vavs_local_init(); + vavs_local_init(false); if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM) size = get_firmware_data(VIDEO_DEC_AVS, buf); @@ -1660,9 +1660,9 @@ static int amvdec_avs_probe(struct platform_device *pdev) firmware_sel = 1; if (firmware_sel == 1) { - vf_buf_num = 4; + vf_buf_num = 8; canvas_base = 0; - canvas_num = 3; + canvas_num = 2; } else { canvas_base = 128; diff --git a/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c b/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c index 6862180..3da87e4 100644 --- a/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c +++ b/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c @@ -501,9 +501,9 @@ void Get_I_Picture_Header(struct avs2_decoder *avs2_dec) get_param(rpm_param->p.num_to_remove_cur, "num of removed picture"); #ifdef SANITY_CHECK - if (hd->curr_RPS.num_to_remove > 8) { - hd->curr_RPS.num_to_remove = 8; - pr_info("Warning, %s: num_to_remove %d beyond range, force to 8\n", + if (hd->curr_RPS.num_to_remove > MAXREF) { + hd->curr_RPS.num_to_remove = MAXREF; + pr_info("Warning, %s: num_to_remove %d beyond range, force to MAXREF\n", __func__, hd->curr_RPS.num_to_remove); } #endif @@ -691,9 +691,9 @@ void Get_PB_Picture_Header(struct avs2_decoder *avs2_dec) rpm_param->p.num_to_remove_cur, "num of removed picture"); #ifdef SANITY_CHECK - if (hd->curr_RPS.num_to_remove > 8) { - hd->curr_RPS.num_to_remove = 8; - pr_info("Warning, %s: num_to_remove %d beyond range, force to 8\n", + if (hd->curr_RPS.num_to_remove > MAXREF) { + hd->curr_RPS.num_to_remove = MAXREF; + pr_info("Warning, %s: num_to_remove %d beyond range, force to MAXREF\n", __func__, hd->curr_RPS.num_to_remove); } #endif diff --git a/drivers/frame_provider/decoder/avs2/avs2_global.h b/drivers/frame_provider/decoder/avs2/avs2_global.h index e6c28cf..3e7fcb8 100644 --- a/drivers/frame_provider/decoder/avs2/avs2_global.h +++ b/drivers/frame_provider/decoder/avs2/avs2_global.h @@ -811,6 +811,9 @@ struct avs2_frame_s { int max_mv; int min_mv; int avg_mv; + + u32 hw_decode_time; + u32 frame_size; // For frame base mode }; diff --git a/drivers/frame_provider/decoder/avs2/vavs2.c b/drivers/frame_provider/decoder/avs2/vavs2.c index f90fee6..9da22f9 100644 --- a/drivers/frame_provider/decoder/avs2/vavs2.c +++ b/drivers/frame_provider/decoder/avs2/vavs2.c @@ -4136,7 +4136,7 @@ static struct vframe_s *vavs2_vf_get(void *op_arg) if (kfifo_get(&dec->display_q, &vf)) { uint8_t index = vf->index & 0xff; - if (index >= 0 && index < dec->used_buf_num) { + if (index < dec->used_buf_num) { struct avs2_frame_s *pic = get_pic_by_index(dec, index); if (pic == NULL && (debug & AVS2_DBG_PIC_LEAK)) { @@ -4186,8 +4186,7 @@ static void vavs2_vf_put(struct vframe_s *vf, void *op_arg) __func__, vf->index, dec->vf_put_count); - if (index >= 0 - && index < dec->used_buf_num) { + if (index < dec->used_buf_num) { unsigned long flags; struct avs2_frame_s *pic; @@ -4258,7 +4257,10 @@ static void fill_frame_info(struct AVS2Decoder_s *dec, /* #define SHOW_QOS_INFO */ - vframe_qos->size = framesize; + if (input_frame_based(hw_to_vdec(dec))) + vframe_qos->size = pic->frame_size; + else + vframe_qos->size = framesize; vframe_qos->pts = pts; #ifdef SHOW_QOS_INFO avs2_print(dec, 0, "slice:%d\n", pic->slice_type); @@ -4297,8 +4299,6 @@ static void fill_frame_info(struct AVS2Decoder_s *dec, vframe_qos->num++; - if (dec->frameinfo_enable) - vdec_fill_frame_info(vframe_qos, 1); } static void set_vframe(struct AVS2Decoder_s *dec, @@ -4306,7 +4306,7 @@ static void set_vframe(struct AVS2Decoder_s *dec, { unsigned long flags; int stream_offset; - unsigned int frame_size; + unsigned int frame_size = 0; int pts_discontinue; stream_offset = pic->stream_offset; avs2_print(dec, AVS2_DBG_BUFMGR, @@ -4534,6 +4534,22 @@ static void set_vframe(struct AVS2Decoder_s *dec, dec->vf_pre_count++; } +static inline void dec_update_gvs(struct AVS2Decoder_s *dec) +{ + if (dec->gvs->frame_height != dec->frame_height) { + dec->gvs->frame_width = dec->frame_width; + dec->gvs->frame_height = dec->frame_height; + } + if (dec->gvs->frame_dur != dec->frame_dur) { + dec->gvs->frame_dur = dec->frame_dur; + if (dec->frame_dur != 0) + dec->gvs->frame_rate = 96000 / dec->frame_dur; + else + dec->gvs->frame_rate = -1; + } + dec->gvs->status = dec->stat | dec->fatal_error; +} + static int avs2_prepare_display_buf(struct AVS2Decoder_s *dec) { @@ -4541,6 +4557,7 @@ static int avs2_prepare_display_buf(struct AVS2Decoder_s *dec) struct vframe_s *vf = NULL; /*unsigned short slice_type;*/ struct avs2_frame_s *pic; + struct vdec_s *pvdec = hw_to_vdec(dec); while (1) { pic = get_disp_pic(dec); if (pic == NULL) @@ -4575,17 +4592,22 @@ static int avs2_prepare_display_buf(struct AVS2Decoder_s *dec) } if (vf) { + struct vdec_info tmp4x; + int stream_offset = pic->stream_offset; set_vframe(dec, vf, pic, 0); - decoder_do_frame_check(hw_to_vdec(dec), vf); + decoder_do_frame_check(pvdec, vf); kfifo_put(&dec->display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); - #ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC + dec_update_gvs(dec); /*count info*/ - gvs->frame_dur = dec->frame_dur; - vdec_count_info(gvs, 0, stream_offset); - #endif - hw_to_vdec(dec)->vdec_fps_detec(hw_to_vdec(dec)->id); + vdec_count_info(dec->gvs, 0, stream_offset); + memcpy(&tmp4x, dec->gvs, sizeof(struct vdec_info)); + tmp4x.bit_depth_luma = bit_depth_luma; + tmp4x.bit_depth_chroma = bit_depth_chroma; + tmp4x.double_write_mode = get_double_write_mode(dec); + vdec_fill_vdec_frame(pvdec, &dec->vframe_qos, &tmp4x, vf, pic->hw_decode_time); + pvdec->vdec_fps_detec(pvdec->id); if (without_display_mode == 0) { vf_notify_receiver(dec->provider_name, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); @@ -4774,12 +4796,18 @@ we can call this function to get qos info*/ static void get_picture_qos_info(struct AVS2Decoder_s *dec) { struct avs2_frame_s *picture = dec->avs2_dec.hc.cur_pic; + struct vdec_s *vdec = hw_to_vdec(dec); if (!picture) { avs2_print(dec, AVS2_DBG_BUFMGR_MORE, "%s decode picture is none exist\n"); return; } + if (vdec->mvfrm) { + picture->frame_size = vdec->mvfrm->frame_size; + picture->hw_decode_time = + local_clock() - vdec->mvfrm->hw_decode_start; + } /* #define DEBUG_QOS @@ -5133,55 +5161,55 @@ static void get_picture_qos_info(struct AVS2Decoder_s *dec) #endif picture->min_mv = mv_lo; +#ifdef DEBUG_QOS /* {mvy_L0_max, mvy_L0_min} */ rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); mv_hi = (rdata32>>16)&0xffff; if (mv_hi & 0x8000) mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS avs2_print(dec, 0, "[Picture %d Quality] MVY_L0 MAX : %d\n", pic_number, mv_hi); -#endif + mv_lo = (rdata32>>0)&0xffff; if (mv_lo & 0x8000) mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS + avs2_print(dec, 0, "[Picture %d Quality] MVY_L0 MIN : %d\n", pic_number, mv_lo); -#endif + /* {mvx_L1_max, mvx_L1_min} */ rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); mv_hi = (rdata32>>16)&0xffff; if (mv_hi & 0x8000) mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS + avs2_print(dec, 0, "[Picture %d Quality] MVX_L1 MAX : %d\n", pic_number, mv_hi); -#endif + mv_lo = (rdata32>>0)&0xffff; if (mv_lo & 0x8000) mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS + avs2_print(dec, 0, "[Picture %d Quality] MVX_L1 MIN : %d\n", pic_number, mv_lo); -#endif + /* {mvy_L1_max, mvy_L1_min} */ rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); mv_hi = (rdata32>>16)&0xffff; if (mv_hi & 0x8000) mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS + avs2_print(dec, 0, "[Picture %d Quality] MVY_L1 MAX : %d\n", pic_number, mv_hi); -#endif + mv_lo = (rdata32>>0)&0xffff; if (mv_lo & 0x8000) mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS + avs2_print(dec, 0, "[Picture %d Quality] MVY_L1 MIN : %d\n", pic_number, mv_lo); #endif @@ -5440,6 +5468,7 @@ static irqreturn_t vavs2_isr_thread_fn(int irq, void *data) debug_buffer_mgr_more(dec); get_frame_rate(&dec->avs2_dec.param, dec); +#if 0 // The video_signal_type is type of uint16_t and result false, so comment it out. if (dec->avs2_dec.param.p.video_signal_type & (1<<30)) { union param_u *pPara; @@ -5512,6 +5541,7 @@ static irqreturn_t vavs2_isr_thread_fn(int irq, void *data) "max_pic_average:0x%x\n", dec->vf_dp.content_light_level.max_pic_average); } +#endif if (dec->video_ori_signal_type != @@ -6111,19 +6141,17 @@ int vavs2_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) vstatus->error_count = 0; vstatus->status = dec->stat | dec->fatal_error; vstatus->frame_dur = dec->frame_dur; -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC - vstatus->bit_rate = gvs->bit_rate; - vstatus->frame_data = gvs->frame_data; - vstatus->total_data = gvs->total_data; - vstatus->frame_count = gvs->frame_count; - vstatus->error_frame_count = gvs->error_frame_count; - vstatus->drop_frame_count = gvs->drop_frame_count; - vstatus->total_data = gvs->total_data; - vstatus->samp_cnt = gvs->samp_cnt; - vstatus->offset = gvs->offset; + vstatus->bit_rate = dec->gvs->bit_rate; + vstatus->frame_data = dec->gvs->frame_data; + vstatus->total_data = dec->gvs->total_data; + vstatus->frame_count = dec->gvs->frame_count; + vstatus->error_frame_count = dec->gvs->error_frame_count; + vstatus->drop_frame_count = dec->gvs->drop_frame_count; + vstatus->total_data = dec->gvs->total_data; + vstatus->samp_cnt = dec->gvs->samp_cnt; + vstatus->offset = dec->gvs->offset; snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name), "%s", DRIVER_NAME); -#endif return 0; } @@ -6209,7 +6237,7 @@ static int vavs2_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) (struct AVS2Decoder_s *)vdec->private; if (i_only_flag & 0x100) return 0; - if (trickmode == TRICKMODE_I) + if (trickmode == TRICKMODE_I || trickmode == TRICKMODE_I_HEVC) dec->i_only = 0x3; else if (trickmode == TRICKMODE_NONE) dec->i_only = 0x0; @@ -6292,6 +6320,8 @@ static s32 vavs2_init(struct vdec_s *vdec) if (vavs2_local_init(dec) < 0) return -EBUSY; + vdec_set_vframe_comm(vdec, DRIVER_NAME); + fw = vmalloc(sizeof(struct firmware_s) + fw_size); if (IS_ERR_OR_NULL(fw)) return -ENOMEM; @@ -7055,6 +7085,8 @@ static void run(struct vdec_s *vdec, unsigned long mask, WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0); r = dec->chunk->size + (dec->chunk->offset & (VDEC_FIFO_ALIGN - 1)); + if (vdec->mvfrm) + vdec->mvfrm->frame_size = dec->chunk->size; } WRITE_VREG(HEVC_DECODE_SIZE, r); @@ -7072,6 +7104,8 @@ static void run(struct vdec_s *vdec, unsigned long mask, mod_timer(&dec->timer, jiffies); dec->stat |= STAT_TIMER_ARM; dec->stat |= STAT_ISR_REG; + if (vdec->mvfrm) + vdec->mvfrm->hw_decode_start = local_clock(); amhevc_start(); dec->stat |= STAT_VDEC_RUN; } @@ -7311,7 +7345,7 @@ static int ammvdec_avs2_probe(struct platform_device *pdev) dec->stat |= VP9_TRIGGER_FRAME_ENABLE; #if 1 if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 && - pdata->config && pdata->config_len) { + pdata->config_len) { /*use ptr config for doubel_write_mode, etc*/ avs2_print(dec, 0, "pdata->config=%s\n", pdata->config); if (get_config_int(pdata->config, "avs2_double_write_mode", @@ -7402,13 +7436,6 @@ static int ammvdec_avs2_probe(struct platform_device *pdev) dec->first_sc_checked = 0; dec->fatal_error = 0; dec->show_frame_num = 0; - if (pdata == NULL) { - pr_info("\namvdec_avs2 memory resource undefined.\n"); - uninit_mmu_buffers(dec); - /* devm_kfree(&pdev->dev, (void *)dec); */ - vfree((void *)dec); - return -EFAULT; - } if (debug) { pr_info("===AVS2 decoder mem resource 0x%lx size 0x%x\n", diff --git a/drivers/frame_provider/decoder/avs_multi/Makefile b/drivers/frame_provider/decoder/avs_multi/Makefile index b281b40..638cec0 100644 --- a/drivers/frame_provider/decoder/avs_multi/Makefile +++ b/drivers/frame_provider/decoder/avs_multi/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI) += amvdec_mavs.o -amvdec_mavs-objs += avs_multi.o avsp_trans_multi.o +amvdec_mavs-objs += avs_multi.o diff --git a/drivers/frame_provider/decoder/avs_multi/avs_multi.c b/drivers/frame_provider/decoder/avs_multi/avs_multi.c index 11813ad..f041bf7 100644 --- a/drivers/frame_provider/decoder/avs_multi/avs_multi.c +++ b/drivers/frame_provider/decoder/avs_multi/avs_multi.c @@ -14,7 +14,6 @@ * more details. * */ -#define DEBUG #include #include #include @@ -47,9 +46,22 @@ #include #define DEBUG_MULTI_FLAG 0 +/* +#define DEBUG_WITH_SINGLE_MODE +#define DEBUG_MULTI_WITH_AUTOMODE +#define DEBUG_MULTI_FRAME_INS +*/ + + +#define USE_DYNAMIC_BUF_NUM +#ifdef DEBUG_WITH_SINGLE_MODE #define DRIVER_NAME "amvdec_avs" #define MODULE_NAME "amvdec_avs" +#else +#define DRIVER_NAME "ammvdec_avs" +#define MODULE_NAME "ammvdec_avs" +#endif #define MULTI_DRIVER_NAME "ammvdec_avs" @@ -92,23 +104,28 @@ #define AVS_OFFSET_REG AV_SCRATCH_C #define MEM_OFFSET_REG AV_SCRATCH_F #define AVS_ERROR_RECOVERY_MODE AV_SCRATCH_G +#define DECODE_PIC_COUNT AV_SCRATCH_G #define DECODE_MODE AV_SCRATCH_6 #define DECODE_MODE_SINGLE 0x0 #define DECODE_MODE_MULTI_FRAMEBASE 0x1 #define DECODE_MODE_MULTI_STREAMBASE 0x2 +#define DECODE_MODE_MULTI_STREAMBASE_CONT 0x3 #define DECODE_STATUS AV_SCRATCH_H #define DECODE_STATUS_PIC_DONE 0x1 #define DECODE_STATUS_DECODE_BUF_EMPTY 0x2 #define DECODE_STATUS_SEARCH_BUF_EMPTY 0x3 +#define DECODE_STATUS_SKIP_PIC_DONE 0x4 #define DECODE_SEARCH_HEAD 0xff #define DECODE_STOP_POS AV_SCRATCH_J #define DECODE_LMEM_BUF_ADR AV_SCRATCH_I -#define VF_POOL_SIZE 32 +#define DECODE_CFG AV_SCRATCH_K + +#define VF_POOL_SIZE 64 #define PUT_INTERVAL (HZ/100) #if 1 /*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8*/ @@ -118,6 +135,18 @@ #define INT_AMVENCODER INT_MAILBOX_1A #endif +#ifdef USE_DYNAMIC_BUF_NUM +static unsigned int buf_spec_reg[] = { + AV_SCRATCH_0, + AV_SCRATCH_1, + AV_SCRATCH_2, + AV_SCRATCH_3, + AV_SCRATCH_7, /*AVS_SOS_COUNT*/ + AV_SCRATCH_D, /*DEBUG_REG2*/ + AV_SCRATCH_E, /*DEBUG_REG1*/ + AV_SCRATCH_N /*user_data_flags*/ +}; +#endif static void check_timer_func(unsigned long arg); static void vavs_work(struct work_struct *work); @@ -129,17 +158,21 @@ static u32 dec_control = DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE; #define VPP_VD1_POSTBLEND (1 << 10) static int debug; -#define debug_flag debug static unsigned int debug_mask = 0xff; /*for debug*/ /* udebug_flag: bit 0, enable ucode print - bit 1, enable ucode detail print + bit 1, enable ucode more print + bit 3, enable ucdode detail print bit [31:16] not 0, pos to dump lmem bit 2, pop bits to lmem bit [11:8], pre-pop bits for alignment (when bit 2 is 1) + + avs only: + bit [8], disable empty muitl-instance handling + bit [9], enable writting of VC1_CONTROL_REG in ucode */ static u32 udebug_flag; /* @@ -157,16 +190,35 @@ static u32 udebug_pause_val; static u32 udebug_pause_decode_idx; +static u32 udebug_pause_ins_id; + static u32 force_fps; +#ifdef DEBUG_MULTI_FRAME_INS +static u32 delay; +#endif + static u32 step; +static u32 start_decoding_delay; + #define AVS_DEV_NUM 9 static unsigned int max_decode_instance_num = AVS_DEV_NUM; static unsigned int max_process_time[AVS_DEV_NUM]; static unsigned int max_get_frame_interval[AVS_DEV_NUM]; +static unsigned int run_count[AVS_DEV_NUM]; +static unsigned int ins_udebug_flag[AVS_DEV_NUM]; +#ifdef DEBUG_MULTI_FRAME_INS +static unsigned int max_run_count[AVS_DEV_NUM]; +#endif +/* +error_handle_policy: +*/ +static unsigned int error_handle_policy = 3; -static unsigned int decode_timeout_val = 100; +static u32 again_threshold = 0; /*0x40;*/ + +static unsigned int decode_timeout_val = 200; static unsigned int start_decode_buf_level = 0x8000; /******************************** @@ -181,11 +233,6 @@ static int firmware_sel; static int disable_longcabac_trans = 1; -int avs_get_debug_flag(void) -{ - return debug_flag; -} - static struct vframe_s *vavs_vf_peek(void *); static struct vframe_s *vavs_vf_get(void *); static void vavs_vf_put(struct vframe_s *, void *); @@ -211,8 +258,11 @@ static void *mm_blk_handle; static struct vframe_provider_s vavs_vf_prov; #define VF_BUF_NUM_MAX 16 +#ifdef DEBUG_MULTI_FRAME_INS +#define WORKSPACE_SIZE (16 * SZ_1M) +#else #define WORKSPACE_SIZE (4 * SZ_1M) - +#endif #ifdef AVSP_LONG_CABAC #define MAX_BMMU_BUFFER_NUM (VF_BUF_NUM_MAX + 2) #define WORKSPACE_SIZE_A (MAX_CODED_FRAME_SIZE + LOCAL_HEAP_SIZE) @@ -223,7 +273,8 @@ static struct vframe_provider_s vavs_vf_prov; #define RV_AI_BUFF_START_ADDR 0x01a00000 #define LONG_CABAC_RV_AI_BUFF_START_ADDR 0x00000000 -static u32 vf_buf_num = 4; +/* 4 buffers not enough for multi inc*/ +static u32 vf_buf_num = 8; /*static u32 vf_buf_num_used;*/ static u32 canvas_base = 128; #ifdef NV21 @@ -327,6 +378,21 @@ static const u32 frame_rate_tab[16] = { }; #define DECODE_BUFFER_NUM_MAX VF_BUF_NUM_MAX +#define PIC_PTS_NUM 64 +struct buf_pool_s { + unsigned detached; + struct vframe_s vf; +}; + +#define buf_of_vf(vf) container_of(vf, struct buf_pool_s, vf) + +struct pic_pts_s { + u32 pts; + u64 pts64; + u64 timestamp; + unsigned short decode_pic_count; +}; + struct vdec_avs_hw_s { spinlock_t lock; unsigned char m_ins_flag; @@ -334,7 +400,7 @@ struct vdec_avs_hw_s { DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE); DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE); - struct vframe_s vfpool[VF_POOL_SIZE]; + struct buf_pool_s vfpool[VF_POOL_SIZE]; s32 vfbuf_use[VF_BUF_NUM_MAX]; unsigned char again_flag; unsigned char recover_flag; @@ -351,6 +417,9 @@ struct vdec_avs_hw_s { u32 total_frame; u32 next_pts; unsigned char throw_pb_flag; + struct pic_pts_s pic_pts[PIC_PTS_NUM]; + int pic_pts_wr_pos; + #ifdef DEBUG_PTS u32 pts_hit; u32 pts_missed; @@ -380,6 +449,7 @@ struct vdec_avs_hw_s { u8 reset_decode_flag; u32 display_frame_count; u32 buf_status; + u32 pre_parser_wr_ptr; /* buffer_status &= ~buf_recycle_status */ @@ -421,6 +491,9 @@ struct vdec_avs_hw_s { u32 reg_anc2_canvas_addr; u32 reg_anc0_canvas_addr; u32 reg_anc1_canvas_addr; + u32 reg_anc3_canvas_addr; + u32 reg_anc4_canvas_addr; + u32 reg_anc5_canvas_addr; u32 slice_ver_pos_pic_type; u32 vc1_control_reg; u32 avs_co_mb_wr_addr; @@ -458,7 +531,6 @@ struct vdec_avs_hw_s { void (*vdec_cb)(struct vdec_s *, void *); void *vdec_cb_arg; /* for error handling */ - u32 first_i_frame_ready; u32 run_count; u32 not_run_ready; u32 input_empty; @@ -470,6 +542,9 @@ struct vdec_avs_hw_s { u32 buffer_not_ready; int frameinfo_enable; struct firmware_s *fw; + u32 old_udebug_flag; + u32 decode_status_skip_pic_done_flag; + u32 decode_decode_cont_start_code; }; static void reset_process_time(struct vdec_avs_hw_s *hw); @@ -490,11 +565,12 @@ struct vdec_avs_hw_s *ghw; #define DEC_RESULT_GET_DATA_RETRY 7 #define DEC_RESULT_USERDATA 8 -#define DECODE_ID(hw) (hw->m_ins_flag? 0 : hw_to_vdec(hw)->id) +#define DECODE_ID(hw) (hw->m_ins_flag? hw_to_vdec(hw)->id : 0) #define PRINT_FLAG_ERROR 0x0 #define PRINT_FLAG_RUN_FLOW 0X0001 #define PRINT_FLAG_DECODING 0x0002 +#define PRINT_FLAG_PTS 0x0004 #define PRINT_FLAG_VFRAME_DETAIL 0x0010 #define PRINT_FLAG_VLD_DETAIL 0x0020 #define PRINT_FLAG_DEC_DETAIL 0x0040 @@ -504,8 +580,25 @@ struct vdec_avs_hw_s *ghw; #define PRINT_FRAMEBASE_DATA 0x0400 #define PRINT_FLAG_PARA_DATA 0x1000 #define DEBUG_FLAG_PREPARE_MORE_INPUT 0x2000 +#define DEBUG_FLAG_PRINT_REG 0x4000 #define DEBUG_FLAG_DISABLE_TIMEOUT 0x10000 #define DEBUG_WAIT_DECODE_DONE_WHEN_STOP 0x20000 +#define DEBUG_PIC_DONE_WHEN_UCODE_PAUSE 0x40000 + + +#undef DEBUG_REG +#ifdef DEBUG_REG +static void WRITE_VREG_DBG2(unsigned adr, unsigned val) +{ + if (debug & DEBUG_FLAG_PRINT_REG) + pr_info("%s(%x, %x)\n", __func__, adr, val); + if (adr != 0) + WRITE_VREG(adr, val); +} + +#undef WRITE_VREG +#define WRITE_VREG WRITE_VREG_DBG2 +#endif #undef pr_info #define pr_info printk @@ -515,7 +608,9 @@ static int debug_print(struct vdec_avs_hw_s *hw, #define AVS_PRINT_BUF 256 unsigned char buf[AVS_PRINT_BUF]; int len = 0; - int index = hw->m_ins_flag ? DECODE_ID(hw) : 0; + int index = 0; + if (hw) + index = hw->m_ins_flag ? DECODE_ID(hw) : 0; if (hw == NULL || (flag == 0) || ((debug_mask & @@ -527,7 +622,7 @@ static int debug_print(struct vdec_avs_hw_s *hw, if (hw) len = sprintf(buf, "[%d]", index); vsnprintf(buf + len, AVS_PRINT_BUF - len, fmt, args); - pr_debug("%s", buf); + pr_info("%s", buf); va_end(args); } return 0; @@ -538,7 +633,9 @@ static int debug_print_cont(struct vdec_avs_hw_s *hw, { unsigned char buf[AVS_PRINT_BUF]; int len = 0; - int index = hw->m_ins_flag ? DECODE_ID(hw) : 0; + int index = 0; + if (hw) + index = hw->m_ins_flag ? DECODE_ID(hw) : 0; if (hw == NULL || (flag == 0) || ((debug_mask & @@ -554,6 +651,82 @@ static int debug_print_cont(struct vdec_avs_hw_s *hw, return 0; } +static void avs_pts_check_in(struct vdec_avs_hw_s *hw, + unsigned short decode_pic_count, struct vframe_chunk_s *chunk) +{ + if (chunk) + debug_print(hw, PRINT_FLAG_PTS, + "%s %d (wr pos %d), pts %d pts64 %ld timestamp %ld\n", + __func__, decode_pic_count, hw->pic_pts_wr_pos, + chunk->pts, (u64)(chunk->pts64), (u64)(chunk->timestamp)); + else + debug_print(hw, PRINT_FLAG_PTS, + "%s %d, chunk is null\n", + __func__, decode_pic_count); + + if (chunk) { + hw->pic_pts[hw->pic_pts_wr_pos].pts = chunk->pts; + hw->pic_pts[hw->pic_pts_wr_pos].pts64 = chunk->pts64; + hw->pic_pts[hw->pic_pts_wr_pos].timestamp = chunk->timestamp; + } else { + hw->pic_pts[hw->pic_pts_wr_pos].pts = 0; + hw->pic_pts[hw->pic_pts_wr_pos].pts64 = 0; + hw->pic_pts[hw->pic_pts_wr_pos].timestamp = 0; + } + hw->pic_pts[hw->pic_pts_wr_pos].decode_pic_count + = decode_pic_count; + hw->pic_pts_wr_pos++; + if (hw->pic_pts_wr_pos >= PIC_PTS_NUM) + hw->pic_pts_wr_pos = 0; + return; +} + +static void clear_pts_buf(struct vdec_avs_hw_s *hw) +{ + int i; + debug_print(hw, PRINT_FLAG_PTS, + "%s\n", __func__); + hw->pic_pts_wr_pos = 0; + for (i = 0; i < PIC_PTS_NUM; i++) { + hw->pic_pts[hw->pic_pts_wr_pos].pts = 0; + hw->pic_pts[hw->pic_pts_wr_pos].pts64 = 0; + hw->pic_pts[hw->pic_pts_wr_pos].timestamp = 0; + hw->pic_pts[hw->pic_pts_wr_pos].decode_pic_count = 0; + } +} + +static int set_vframe_pts(struct vdec_avs_hw_s *hw, + unsigned short decode_pic_count, struct vframe_s *vf) +{ + int i; + int ret = -1; + for (i = 0; i < PIC_PTS_NUM; i++) { + if (hw->pic_pts[i].decode_pic_count == decode_pic_count) { + vf->pts = hw->pic_pts[i].pts; + vf->pts_us64 = hw->pic_pts[i].pts64; + vf->timestamp = hw->pic_pts[i].timestamp; + ret = 0; + debug_print(hw, PRINT_FLAG_PTS, + "%s %d (rd pos %d), pts %d pts64 %ld timestamp %ld\n", + __func__, decode_pic_count, i, + vf->pts, vf->pts_us64, vf->timestamp); + + break; + } + } + return ret; +} + +static void avs_vf_notify_receiver(struct vdec_avs_hw_s *hw, + const char *provider_name, int event_type, void *data) +{ + if (hw->m_ins_flag) + vf_notify_receiver(hw_to_vdec(hw)->vf_provider_name, + event_type, data); + else + vf_notify_receiver(provider_name, event_type, data); +} + static void set_frame_info(struct vdec_avs_hw_s *hw, struct vframe_s *vf, unsigned int *duration) { @@ -619,6 +792,8 @@ static void set_frame_info(struct vdec_avs_hw_s *hw, struct vframe_s *vf, /*vf->ratio_control |= DISP_RATIO_FORCECONFIG | DISP_RATIO_KEEPRATIO; */ vf->flag = 0; + buf_of_vf(vf)->detached = 0; + } #ifdef ENABLE_USER_DATA @@ -735,6 +910,27 @@ static u8 UserDataHandler(struct vdec_avs_hw_s *hw) } #endif + +static inline void avs_update_gvs(struct vdec_avs_hw_s *hw) +{ + if (hw->gvs->frame_height != hw->frame_height) { + hw->gvs->frame_width = hw->frame_width; + hw->gvs->frame_height = hw->frame_height; + } + if (hw->gvs->frame_dur != hw->frame_dur) { + hw->gvs->frame_dur = hw->frame_dur; + if (hw->frame_dur != 0) + hw->gvs->frame_rate = 96000 / hw->frame_dur; + else + hw->gvs->frame_rate = -1; + } + + hw->gvs->status = hw->stat; + hw->gvs->error_count = READ_VREG(AV_SCRATCH_C); + hw->gvs->drop_frame_count = hw->drop_frame_count; + +} + #ifdef HANDLE_AVS_IRQ static irqreturn_t vavs_isr(int irq, void *dev_id) #else @@ -742,7 +938,7 @@ static void vavs_isr(void) #endif { u32 reg; - struct vframe_s *vf; + struct vframe_s *vf = NULL; u32 dur; u32 repeat_count; u32 picture_type; @@ -755,7 +951,7 @@ static void vavs_isr(void) u32 buffer_status_debug; struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)dev_id; - /*if (debug_flag & AVS_DEBUG_UCODE) { + /*if (debug & AVS_DEBUG_UCODE) { if (READ_VREG(AV_SCRATCH_E) != 0) { pr_info("dbg%x: %x\n", READ_VREG(AV_SCRATCH_E), READ_VREG(AV_SCRATCH_D)); @@ -766,9 +962,9 @@ static void vavs_isr(void) #define DEBUG_REG2 AV_SCRATCH_D debug_tag = READ_VREG(DEBUG_REG1); - buffer_status_debug = debug_tag >> 24; - debug_tag &= 0xffffff; - if (debug_tag & 0x10000) { + buffer_status_debug = debug_tag >> 16; + debug_tag &= 0xffff; + /* if (debug_tag & 0x10000) { int i; dma_sync_single_for_cpu( amports_get_dma_device(), @@ -807,24 +1003,46 @@ static void vavs_isr(void) reset_process_time(hw); else WRITE_VREG(DEBUG_REG1, 0); - } else if (debug_tag != 0) { + } else*/ if (debug_tag != 0) { debug_print(hw, 0, - "dbg%x: %x buffer_status 0x%x l/w/r %x %x %x bitcnt %x\n", + "dbg%x: %x buffer_status 0x%x l/w/r %x %x %x bitcnt %x AVAIL %x\n", debug_tag, READ_VREG(DEBUG_REG2), buffer_status_debug, READ_VREG(VLD_MEM_VIFIFO_LEVEL), READ_VREG(VLD_MEM_VIFIFO_WP), READ_VREG(VLD_MEM_VIFIFO_RP), - READ_VREG(VIFF_BIT_CNT)); + READ_VREG(VIFF_BIT_CNT), + READ_VREG(VLD_MEM_VIFIFO_BYTES_AVAIL)); + if (((udebug_pause_pos & 0xffff) == (debug_tag & 0xffff)) && (udebug_pause_decode_idx == 0 || udebug_pause_decode_idx == hw->decode_pic_count) && (udebug_pause_val == 0 || - udebug_pause_val == READ_VREG(DEBUG_REG2))) { + udebug_pause_val == READ_VREG(DEBUG_REG2)) && + (udebug_pause_ins_id == 0 || + DECODE_ID(hw) == (udebug_pause_ins_id -1))) { udebug_pause_pos &= 0xffff; hw->ucode_pause_pos = udebug_pause_pos; + if (debug & DEBUG_PIC_DONE_WHEN_UCODE_PAUSE) { + hw->decode_pic_count++; + if ((hw->decode_pic_count & 0xffff) == 0) { + /*make ucode do not handle it as first picture*/ + hw->decode_pic_count++; + } + reset_process_time(hw); + hw->dec_result = DEC_RESULT_DONE; + amvdec_stop(); + vavs_save_regs(hw); + debug_print(hw, PRINT_FLAG_DECODING, + "%s ucode pause, force done, decode_pic_count = %d, bit_cnt=0x%x\n", + __func__, + hw->decode_pic_count, + READ_VREG(VIFF_BIT_CNT)); + vdec_schedule_work(&hw->work); + return IRQ_HANDLED; + } } if (hw->ucode_pause_pos) reset_process_time(hw); @@ -856,12 +1074,13 @@ static void vavs_isr(void) #endif reg = READ_VREG(AVS_BUFFEROUT); if (reg) { - if (debug_flag & AVS_DEBUG_PRINT) - pr_info("AVS_BUFFEROUT=%x\n", reg); + unsigned short decode_pic_count + = READ_VREG(DECODE_PIC_COUNT); + debug_print(hw, PRINT_FLAG_DECODING, "AVS_BUFFEROUT=0x%x decode_pic_count %d\n", + reg, decode_pic_count); if (pts_by_offset) { offset = READ_VREG(AVS_OFFSET_REG); - if (debug_flag & AVS_DEBUG_PRINT) - pr_info("AVS OFFSET=%x\n", offset); + debug_print(hw, PRINT_FLAG_DECODING, "AVS OFFSET=%x\n", offset); if (pts_lookup_offset_us64(PTS_TYPE_VIDEO, offset, &pts, &frame_size, 0, &pts_us64) == 0) { @@ -877,6 +1096,11 @@ static void vavs_isr(void) } repeat_count = READ_VREG(AVS_REPEAT_COUNT); +#ifdef USE_DYNAMIC_BUF_NUM + buffer_index = + ((reg & 0x7) + + (((reg >> 8) & 0x3) << 3) - 1) & 0x1f; +#else if (firmware_sel == 0) buffer_index = ((reg & 0x7) + @@ -884,7 +1108,7 @@ static void vavs_isr(void) else buffer_index = ((reg & 0x7) - 1) & 3; - +#endif picture_type = (reg >> 3) & 7; #ifdef DEBUG_PTS if (picture_type == I_PICTURE) { @@ -914,10 +1138,9 @@ static void vavs_isr(void) } else if (reg & INTERLACE_FLAG || force_interlaced_frame) { /* interlace */ hw->throw_pb_flag = 0; - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("interlace, picture type %d\n", + debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, + "interlace, picture type %d\n", picture_type); - } if (kfifo_get(&hw->newframe_q, &vf) == 0) { pr_info @@ -989,10 +1212,9 @@ static void vavs_isr(void) index2canvas(buffer_index); vf->type_original = vf->type; - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("buffer_index %d, canvas addr %x\n", + debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, + "buffer_index %d, canvas addr %x\n", buffer_index, vf->canvas0Addr); - } vf->pts_us64 = (pts_valid) ? pts_us64 : 0; hw->vfbuf_use[buffer_index]++; vf->mem_handle = @@ -1000,9 +1222,12 @@ static void vavs_isr(void) hw->mm_blk_handle, buffer_index); + if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw))) + set_vframe_pts(hw, decode_pic_count, vf); + kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - vf_notify_receiver(PROVIDER_NAME, + avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); @@ -1068,19 +1293,21 @@ static void vavs_isr(void) hw->mm_blk_handle, buffer_index); + if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw))) + set_vframe_pts(hw, decode_pic_count, vf); + kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - vf_notify_receiver(PROVIDER_NAME, + avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); hw->total_frame++; } else { /* progressive */ hw->throw_pb_flag = 0; - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("progressive picture type %d\n", + debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, + "progressive picture type %d\n", picture_type); - } if (kfifo_get(&hw->newframe_q, &vf) == 0) { pr_info ("fatal error, no available buffer slot."); @@ -1145,27 +1372,31 @@ static void vavs_isr(void) vf->type_original = vf->type; vf->pts_us64 = (pts_valid) ? pts_us64 : 0; - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("buffer_index %d, canvas addr %x\n", + debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, + "buffer_index %d, canvas addr %x\n", buffer_index, vf->canvas0Addr); - } hw->vfbuf_use[buffer_index]++; vf->mem_handle = decoder_bmmu_box_get_mem_handle( hw->mm_blk_handle, buffer_index); + + if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw))) + set_vframe_pts(hw, decode_pic_count, vf); + kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - vf_notify_receiver(PROVIDER_NAME, + avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); hw->total_frame++; } /*count info*/ - hw->gvs->frame_dur = hw->frame_dur; vdec_count_info(hw->gvs, 0, offset); + avs_update_gvs(hw); + vdec_fill_vdec_frame(hw_to_vdec(hw), NULL, hw->gvs, vf, 0); /* pr_info("PicType = %d, PTS = 0x%x\n", * picture_type, vf->pts); @@ -1181,14 +1412,24 @@ static void vavs_isr(void) if (hw->dec_result == DEC_RESULT_DONE || hw->dec_result == DEC_RESULT_AGAIN) { debug_print(hw, PRINT_FLAG_DECODING, - "%s !!! decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d\n", - __func__, decode_status, + "%s !!! READ_VREG(DECODE_STATUS) = 0x%x, decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d bit_cnt=0x%x\n", + __func__, status_reg, decode_status, hw->buf_status, - hw->dec_result, hw->decode_pic_count); + hw->dec_result, hw->decode_pic_count, + READ_VREG(VIFF_BIT_CNT)); return IRQ_HANDLED; - } else if (decode_status == DECODE_STATUS_PIC_DONE) { - hw->buf_status = (status_reg >> 8) & 0xffff; + } else if (decode_status == DECODE_STATUS_PIC_DONE || + decode_status == DECODE_STATUS_SKIP_PIC_DONE) { + hw->buf_status = (status_reg >> 16) & 0xffff; + if (decode_status == DECODE_STATUS_SKIP_PIC_DONE) { + hw->decode_status_skip_pic_done_flag = 1; + hw->decode_decode_cont_start_code = (status_reg >> 8) & 0xff; + } hw->decode_pic_count++; + if ((hw->decode_pic_count & 0xffff) == 0) { + /*make ucode do not handle it as first picture*/ + hw->decode_pic_count++; + } reset_process_time(hw); hw->dec_result = DEC_RESULT_DONE; #if DEBUG_MULTI_FLAG == 1 @@ -1198,27 +1439,41 @@ static void vavs_isr(void) #endif vavs_save_regs(hw); debug_print(hw, PRINT_FLAG_DECODING, - "%s DECODE_STATUS_PIC_DONE, decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d\n", - __func__, decode_status, + "%s %s, READ_VREG(DECODE_STATUS) = 0x%x, decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d, bit_cnt=0x%x\n", + __func__, + (decode_status == DECODE_STATUS_PIC_DONE) ? + "DECODE_STATUS_PIC_DONE" : "DECODE_STATUS_SKIP_PIC_DONE", + status_reg, decode_status, hw->buf_status, - hw->dec_result, hw->decode_pic_count); + hw->dec_result, hw->decode_pic_count, + READ_VREG(VIFF_BIT_CNT)); vdec_schedule_work(&hw->work); return IRQ_HANDLED; } else if (decode_status == DECODE_STATUS_DECODE_BUF_EMPTY || decode_status == DECODE_STATUS_SEARCH_BUF_EMPTY) { - hw->buf_status = (status_reg >> 8) & 0xffff; + hw->buf_status = (status_reg >> 16) & 0xffff; reset_process_time(hw); - hw->dec_result = DEC_RESULT_AGAIN; #if DEBUG_MULTI_FLAG == 1 WRITE_VREG(DECODE_STATUS, 0); #else amvdec_stop(); #endif + if (vdec_frame_based(hw_to_vdec(hw))) { + hw->dec_result = DEC_RESULT_DONE; + if (hw->decode_pic_count == 0) { + hw->decode_pic_count++; + } + vavs_save_regs(hw); + } else + hw->dec_result = DEC_RESULT_AGAIN; + debug_print(hw, PRINT_FLAG_DECODING, - "%s BUF_EMPTY, decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d\n", - __func__, decode_status, + "%s BUF_EMPTY, READ_VREG(DECODE_STATUS) = 0x%x, decode_status 0x%x, buf_status 0x%x, scratch_8 (AVS_BUFFERIN) 0x%x, dec_result = 0x%x, decode_pic_count = %d, bit_cnt=0x%x\n", + __func__, status_reg, decode_status, hw->buf_status, - hw->dec_result, hw->decode_pic_count); + hw->reg_scratch_8, + hw->dec_result, hw->decode_pic_count, + READ_VREG(VIFF_BIT_CNT)); vdec_schedule_work(&hw->work); return IRQ_HANDLED; } @@ -1299,12 +1554,13 @@ static struct vframe_s *vavs_vf_get(void *op_arg) } debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, - "%s, index = %d, w %d h %d, type 0x%x\n", + "%s, index = %d, w %d h %d, type 0x%x detached %d\n", __func__, vf->index, vf->width, vf->height, - vf->type); + vf->type, + buf_of_vf(vf)->detached); } return vf; } @@ -1322,18 +1578,19 @@ static void vavs_vf_put(struct vframe_s *vf, void *op_arg) if (vf) { hw->put_num++; debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, - "%s, index = %d, w %d h %d, type 0x%x\n", + "%s, index = %d, w %d h %d, type 0x%x detached 0x%x\n", __func__, vf->index, vf->width, vf->height, - vf->type); + vf->type, + buf_of_vf(vf)->detached); } if (hw->recover_flag) return; for (i = 0; i < VF_POOL_SIZE; i++) { - if (vf == &hw->vfpool[i]) + if (vf == &hw->vfpool[i].vf) break; } if (i < VF_POOL_SIZE) @@ -1391,14 +1648,12 @@ int vavs_set_isreset(struct vdec_s *vdec, int isreset) static int vavs_vdec_info_init(struct vdec_avs_hw_s *hw) { - pr_info("%s %d\n", __func__, __LINE__); hw->gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL); if (NULL == hw->gvs) { pr_info("the struct of vdec status malloc failed.\n"); return -ENOMEM; } - pr_info("%s %d\n", __func__, __LINE__); return 0; } @@ -1415,7 +1670,6 @@ static int vavs_canvas_init(struct vdec_avs_hw_s *hw) if (hw->m_ins_flag) vdec = hw_to_vdec(hw); - hw->vf_buf_num_used = vf_buf_num; if (buf_size <= 0x00400000) { /* SD only */ canvas_width = 768; @@ -1538,10 +1792,9 @@ static int vavs_canvas_init(struct vdec_avs_hw_s *hw) CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); #endif - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("canvas config %d, addr %p\n", i, + debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, + "canvas config %d, addr %p\n", i, (void *)buf_start); - } } } return 0; @@ -1577,7 +1830,7 @@ void vavs_recover(struct vdec_avs_hw_s *hw) WRITE_VREG(AV_SCRATCH_1, hw->vf_buf_num_used); } else { int ii; - +#ifndef USE_DYNAMIC_BUF_NUM for (ii = 0; ii < 4; ii++) { WRITE_VREG(AV_SCRATCH_0 + ii, (canvas_base + canvas_num * ii) | @@ -1587,6 +1840,19 @@ void vavs_recover(struct vdec_avs_hw_s *hw) << 16) ); } +#else + for (ii = 0; ii < hw->vf_buf_num_used; ii += 2) { + WRITE_VREG(buf_spec_reg[ii >> 1], + (canvas_base + canvas_num * ii) | + ((canvas_base + canvas_num * ii + 1) + << 8) | + ((canvas_base + canvas_num * ii + 2) + << 16) | + ((canvas_base + canvas_num * ii + 3) + << 24) + ); + } +#endif } /* notify ucode the buffer offset */ @@ -1595,7 +1861,9 @@ void vavs_recover(struct vdec_avs_hw_s *hw) /* disable PSCALE for hardware sharing */ WRITE_VREG(PSCALE_CTRL, 0); +#ifndef USE_DYNAMIC_BUF_NUM WRITE_VREG(AVS_SOS_COUNT, 0); +#endif WRITE_VREG(AVS_BUFFERIN, 0); WRITE_VREG(AVS_BUFFEROUT, 0); if (error_recovery_mode) @@ -1607,7 +1875,7 @@ void vavs_recover(struct vdec_avs_hw_s *hw) /* enable mailbox interrupt */ WRITE_VREG(ASSIST_MBOX1_MASK, 1); -#if 1 /* def DEBUG_UCODE */ +#ifndef USE_DYNAMIC_BUF_NUM /* def DEBUG_UCODE */ WRITE_VREG(AV_SCRATCH_D, 0); #endif @@ -1665,37 +1933,44 @@ static void vavs_save_regs(struct vdec_avs_hw_s *hw) hw->reg_viff_bit_cnt = READ_VREG(VIFF_BIT_CNT); hw->reg_canvas_addr = READ_VREG(REC_CANVAS_ADDR); - hw->reg_dbkr_canvas_addr = READ_VREG(DBKR_CANVAS_ADDR); - hw->reg_dbkw_canvas_addr = READ_VREG(DBKW_CANVAS_ADDR); - hw->reg_anc2_canvas_addr = READ_VREG(ANC2_CANVAS_ADDR); - hw->reg_anc0_canvas_addr = READ_VREG(ANC0_CANVAS_ADDR); - hw->reg_anc1_canvas_addr = READ_VREG(ANC1_CANVAS_ADDR); - - hw->slice_ver_pos_pic_type = READ_VREG(SLICE_VER_POS_PIC_TYPE); - - hw->vc1_control_reg = READ_VREG(VC1_CONTROL_REG); - hw->avs_co_mb_wr_addr = READ_VREG(AVS_CO_MB_WR_ADDR); - hw->slice_start_byte_01 = READ_VREG(SLICE_START_BYTE_01); - hw->slice_start_byte_23 = READ_VREG(SLICE_START_BYTE_23); - hw->vcop_ctrl_reg = READ_VREG(VCOP_CTRL_REG); - hw->iqidct_control = READ_VREG(IQIDCT_CONTROL); - hw->rv_ai_mb_count = READ_VREG(RV_AI_MB_COUNT); - hw->slice_qp = READ_VREG(SLICE_QP); - - hw->dc_scaler = READ_VREG(DC_SCALER); - hw->avsp_iq_wq_param_01 = READ_VREG(AVSP_IQ_WQ_PARAM_01); - hw->avsp_iq_wq_param_23 = READ_VREG(AVSP_IQ_WQ_PARAM_23); - hw->avsp_iq_wq_param_45 = READ_VREG(AVSP_IQ_WQ_PARAM_45); - hw->avs_co_mb_rd_addr = READ_VREG(AVS_CO_MB_RD_ADDR); - hw->dblk_mb_wid_height = READ_VREG(DBLK_MB_WID_HEIGHT); - hw->mc_pic_w_h = READ_VREG(MC_PIC_W_H); - hw->avs_co_mb_rw_ctl = READ_VREG(AVS_CO_MB_RW_CTL); - - hw->vld_decode_control = READ_VREG(VLD_DECODE_CONTROL); + hw->reg_dbkr_canvas_addr = READ_VREG(DBKR_CANVAS_ADDR); + hw->reg_dbkw_canvas_addr = READ_VREG(DBKW_CANVAS_ADDR); + hw->reg_anc2_canvas_addr = READ_VREG(ANC2_CANVAS_ADDR); + hw->reg_anc0_canvas_addr = READ_VREG(ANC0_CANVAS_ADDR); + hw->reg_anc1_canvas_addr = READ_VREG(ANC1_CANVAS_ADDR); + hw->reg_anc3_canvas_addr = READ_VREG(ANC3_CANVAS_ADDR); + hw->reg_anc4_canvas_addr = READ_VREG(ANC4_CANVAS_ADDR); + hw->reg_anc5_canvas_addr = READ_VREG(ANC5_CANVAS_ADDR); + + hw->slice_ver_pos_pic_type = READ_VREG(SLICE_VER_POS_PIC_TYPE); + + hw->vc1_control_reg = READ_VREG(VC1_CONTROL_REG); + hw->avs_co_mb_wr_addr = READ_VREG(AVS_CO_MB_WR_ADDR); + hw->slice_start_byte_01 = READ_VREG(SLICE_START_BYTE_01); + hw->slice_start_byte_23 = READ_VREG(SLICE_START_BYTE_23); + hw->vcop_ctrl_reg = READ_VREG(VCOP_CTRL_REG); + hw->iqidct_control = READ_VREG(IQIDCT_CONTROL); + hw->rv_ai_mb_count = READ_VREG(RV_AI_MB_COUNT); + hw->slice_qp = READ_VREG(SLICE_QP); + + hw->dc_scaler = READ_VREG(DC_SCALER); + hw->avsp_iq_wq_param_01 = READ_VREG(AVSP_IQ_WQ_PARAM_01); + hw->avsp_iq_wq_param_23 = READ_VREG(AVSP_IQ_WQ_PARAM_23); + hw->avsp_iq_wq_param_45 = READ_VREG(AVSP_IQ_WQ_PARAM_45); + hw->avs_co_mb_rd_addr = READ_VREG(AVS_CO_MB_RD_ADDR); + hw->dblk_mb_wid_height = READ_VREG(DBLK_MB_WID_HEIGHT); + hw->mc_pic_w_h = READ_VREG(MC_PIC_W_H); + hw->avs_co_mb_rw_ctl = READ_VREG(AVS_CO_MB_RW_CTL); + + hw->vld_decode_control = READ_VREG(VLD_DECODE_CONTROL); } static void vavs_restore_regs(struct vdec_avs_hw_s *hw) { + debug_print(hw, PRINT_FLAG_DECODING, + "%s scratch_8 (AVS_BUFFERIN) 0x%x, decode_pic_count = %d\n", + __func__, hw->reg_scratch_8, hw->decode_pic_count); + WRITE_VREG(AV_SCRATCH_0, hw->reg_scratch_0); WRITE_VREG(AV_SCRATCH_1, hw->reg_scratch_1); WRITE_VREG(AV_SCRATCH_2, hw->reg_scratch_2); @@ -1725,6 +2000,9 @@ static void vavs_restore_regs(struct vdec_avs_hw_s *hw) WRITE_VREG(ANC2_CANVAS_ADDR, hw->reg_anc2_canvas_addr); WRITE_VREG(ANC0_CANVAS_ADDR, hw->reg_anc0_canvas_addr); WRITE_VREG(ANC1_CANVAS_ADDR, hw->reg_anc1_canvas_addr); + WRITE_VREG(ANC3_CANVAS_ADDR, hw->reg_anc3_canvas_addr); + WRITE_VREG(ANC4_CANVAS_ADDR, hw->reg_anc4_canvas_addr); + WRITE_VREG(ANC5_CANVAS_ADDR, hw->reg_anc5_canvas_addr); WRITE_VREG(SLICE_VER_POS_PIC_TYPE, hw->slice_ver_pos_pic_type); @@ -1789,15 +2067,28 @@ static int vavs_prot_init(struct vdec_avs_hw_s *hw) int i; if (hw->decode_pic_count == 0) { r = vavs_canvas_init(hw); +#ifndef USE_DYNAMIC_BUF_NUM for (i = 0; i < 4; i++) { WRITE_VREG(AV_SCRATCH_0 + i, hw->canvas_spec[i] ); } +#else + for (i = 0; i < hw->vf_buf_num_used; i += 2) { + WRITE_VREG(buf_spec_reg[i >> 1], + (hw->canvas_spec[i] & 0xffff) | + ((hw->canvas_spec[i + 1] & 0xffff) + << 16) + ); + debug_print(hw, PRINT_FLAG_DECODING, + "%s WRITE_VREG(0x%x, 0x%x)\n", + __func__, buf_spec_reg[i >> 1], READ_VREG(buf_spec_reg[i >> 1])); + } +#endif } else vavs_restore_regs(hw); - for (i = 0; i < 4; i++) { + for (i = 0; i < hw->vf_buf_num_used; i++) { canvas_config_ex(canvas_y(hw->canvas_spec[i]), hw->canvas_config[i][0].phy_addr, hw->canvas_config[i][0].width, @@ -1823,7 +2114,7 @@ static int vavs_prot_init(struct vdec_avs_hw_s *hw) WRITE_VREG(AV_SCRATCH_1, hw->vf_buf_num_used); } else { int ii; - +#ifndef USE_DYNAMIC_BUF_NUM for (ii = 0; ii < 4; ii++) { WRITE_VREG(AV_SCRATCH_0 + ii, (canvas_base + canvas_num * ii) | @@ -1833,6 +2124,19 @@ static int vavs_prot_init(struct vdec_avs_hw_s *hw) << 16) ); } +#else + for (ii = 0; ii < hw->vf_buf_num_used; ii += 2) { + WRITE_VREG(buf_spec_reg[ii >> 1], + (canvas_base + canvas_num * ii) | + ((canvas_base + canvas_num * ii + 1) + << 8) | + ((canvas_base + canvas_num * ii + 2) + << 16) | + ((canvas_base + canvas_num * ii + 3) + << 24) + ); + } +#endif /* *WRITE_VREG(AV_SCRATCH_0, 0x010100); *WRITE_VREG(AV_SCRATCH_1, 0x040403); @@ -1856,7 +2160,9 @@ static int vavs_prot_init(struct vdec_avs_hw_s *hw) WRITE_VREG(PSCALE_CTRL, 0); if (hw->decode_pic_count == 0) { +#ifndef USE_DYNAMIC_BUF_NUM WRITE_VREG(AVS_SOS_COUNT, 0); +#endif WRITE_VREG(AVS_BUFFERIN, 0); WRITE_VREG(AVS_BUFFEROUT, 0); } @@ -1869,7 +2175,7 @@ static int vavs_prot_init(struct vdec_avs_hw_s *hw) /* enable mailbox interrupt */ WRITE_VREG(ASSIST_MBOX1_MASK, 1); -#if 1 /* def DEBUG_UCODE */ +#ifndef USE_DYNAMIC_BUF_NUM /* def DEBUG_UCODE */ if (hw->decode_pic_count == 0) WRITE_VREG(AV_SCRATCH_D, 0); #endif @@ -1881,7 +2187,12 @@ static int vavs_prot_init(struct vdec_avs_hw_s *hw) #ifdef PIC_DC_NEED_CLEAR CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); #endif + if (hw->m_ins_flag && start_decoding_delay > 0) + msleep(start_decoding_delay); + //pr_info("+++++++++++++++++++++++++++++++\n"); + //pr_info("+++++++++++++++++++++++++++++++\n"); + //pr_info("+++++++++++++++++++++++++++++++\n"); #ifdef AVSP_LONG_CABAC if (firmware_sel == 0) { WRITE_VREG(LONG_CABAC_DES_ADDR, es_write_addr_phy); @@ -1900,98 +2211,29 @@ static int vavs_prot_init(struct vdec_avs_hw_s *hw) if (hw->m_ins_flag) { if (vdec_frame_based(hw_to_vdec(hw))) WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_FRAMEBASE); - else - WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE); + else { + if (hw->decode_status_skip_pic_done_flag) { + WRITE_VREG(DECODE_CFG, hw->decode_decode_cont_start_code); + WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE_CONT); + } else + WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE); + } WRITE_VREG(DECODE_LMEM_BUF_ADR, hw->lmem_phy_addr); } else WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); - //WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); - WRITE_VREG(DECODE_STOP_POS, udebug_flag); - - return r; -} -#if DEBUG_MULTI_FLAG > 0 -static int vavs_prot_init_vld_only(struct vdec_avs_hw_s *hw) -{ - int r = 0; - /***************** reset vld **********************************/ - WRITE_VREG(POWER_CTL_VLD, 0x10); - WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2, MEM_FIFO_CNT_BIT, 2); - WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8, MEM_LEVEL_CNT_BIT, 6); - /*************************************************************/ - if (hw->m_ins_flag) { - int i; - if (hw->decode_pic_count == 0) { - r = vavs_canvas_init(hw); - for (i = 0; i < 4; i++) { - WRITE_VREG(AV_SCRATCH_0 + i, - hw->canvas_spec[i] - ); - } - } else - vavs_restore_regs(hw); - - for (i = 0; i < 4; i++) { - canvas_config_ex(canvas_y(hw->canvas_spec[i]), - hw->canvas_config[i][0].phy_addr, - hw->canvas_config[i][0].width, - hw->canvas_config[i][0].height, - CANVAS_ADDR_NOWRAP, - hw->canvas_config[i][0].block_mode, - 0); - - canvas_config_ex(canvas_u(hw->canvas_spec[i]), - hw->canvas_config[i][1].phy_addr, - hw->canvas_config[i][1].width, - hw->canvas_config[i][1].height, - CANVAS_ADDR_NOWRAP, - hw->canvas_config[i][1].block_mode, - 0); - } + if (ins_udebug_flag[DECODE_ID(hw)] && + (ins_udebug_flag[DECODE_ID(hw)] >> 16) == hw->decode_pic_count) { + WRITE_VREG(DECODE_STOP_POS, + ins_udebug_flag[DECODE_ID(hw)] & 0xffff); } - /* notify ucode the buffer offset */ -#if DEBUG_MULTI_FLAG == 0 - /* disable PSCALE for hardware sharing */ - WRITE_VREG(PSCALE_CTRL, 0); - - if (hw->decode_pic_count == 0) { - WRITE_VREG(AVS_SOS_COUNT, 0); - WRITE_VREG(AVS_BUFFERIN, 0); - WRITE_VREG(AVS_BUFFEROUT, 0); - } - if (error_recovery_mode) - WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 0); else - WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 1); - /* clear mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - /* enable mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_MASK, 1); - -#ifdef NV21 - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); -#endif - -#ifdef PIC_DC_NEED_CLEAR - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); -#endif -#endif - if (hw->m_ins_flag) { - if (vdec_frame_based(hw_to_vdec(hw))) - WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_FRAMEBASE); - else - WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE); - WRITE_VREG(DECODE_LMEM_BUF_ADR, hw->lmem_phy_addr); - } else - WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); - //WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); - WRITE_VREG(DECODE_STOP_POS, udebug_flag); + WRITE_VREG(DECODE_STOP_POS, udebug_flag); + hw->old_udebug_flag = udebug_flag; return r; } -#endif + #ifdef AVSP_LONG_CABAC static unsigned char es_write_addr[MAX_CODED_FRAME_SIZE] __aligned(64); @@ -2000,6 +2242,8 @@ static void vavs_local_init(struct vdec_avs_hw_s *hw) { int i; + hw->vf_buf_num_used = vf_buf_num; + hw->vavs_ratio = hw->vavs_amstream_dec_info.ratio; hw->avi_flag = (unsigned long) hw->vavs_amstream_dec_info.param; @@ -2020,13 +2264,14 @@ static void vavs_local_init(struct vdec_avs_hw_s *hw) INIT_KFIFO(hw->newframe_q); for (i = 0; i < VF_POOL_SIZE; i++) { - const struct vframe_s *vf = &hw->vfpool[i]; + const struct vframe_s *vf = &hw->vfpool[i].vf; - hw->vfpool[i].index = vf_buf_num; - hw->vfpool[i].bufWidth = 1920; + hw->vfpool[i].vf.index = hw->vf_buf_num_used; + hw->vfpool[i].vf.bufWidth = 1920; + hw->vfpool[i].detached = 0; kfifo_put(&hw->newframe_q, vf); } - for (i = 0; i < vf_buf_num; i++) + for (i = 0; i < hw->vf_buf_num_used; i++) hw->vfbuf_use[i] = 0; /*cur_vfpool = vfpool;*/ @@ -2088,7 +2333,7 @@ static void vavs_local_reset(struct vdec_avs_hw_s *hw) pr_info("error, local reset\n"); amvdec_stop(); msleep(100); - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); + avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); vavs_local_init(hw); vavs_recover(hw); @@ -2122,7 +2367,7 @@ static void vavs_fatal_error_handler(struct work_struct *work) { struct vdec_avs_hw_s *hw = container_of(work, struct vdec_avs_hw_s, fatal_error_wd_work); - if (debug_flag & AVS_DEBUG_OLD_ERROR_HANDLE) { + if (debug & AVS_DEBUG_OLD_ERROR_HANDLE) { mutex_lock(&vavs_mutex); pr_info("vavs fatal error reset !\n"); amvdec_stop(); @@ -2148,7 +2393,7 @@ static void vavs_notify_work(struct work_struct *work) struct vdec_avs_hw_s *hw = container_of(work, struct vdec_avs_hw_s, notify_work); if (hw->fr_hint_status == VDEC_NEED_HINT) { - vf_notify_receiver(PROVIDER_NAME , + avs_vf_notify_receiver(hw, PROVIDER_NAME , VFRAME_EVENT_PROVIDER_FR_HINT , (void *)((unsigned long)hw->frame_dur)); hw->fr_hint_status = VDEC_HINTED; @@ -2166,7 +2411,7 @@ static void avs_set_clk(struct work_struct *work) hw->saved_resolution = hw->frame_width * hw->frame_height * fps; if (firmware_sel == 0 && - (debug_flag & AVS_DEBUG_USE_FULL_SPEED)) { + (debug & AVS_DEBUG_USE_FULL_SPEED)) { vdec_source_changed(VFORMAT_AVS, 4096, 2048, 60); } else { @@ -2177,6 +2422,9 @@ static void avs_set_clk(struct work_struct *work) } } +#ifdef DEBUG_MULTI_WITH_AUTOMODE +int delay_count = 0; +#endif static void vavs_put_timer_func(unsigned long arg) { struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)arg; @@ -2185,11 +2433,17 @@ static void vavs_put_timer_func(unsigned long arg) #ifndef HANDLE_AVS_IRQ vavs_isr(); #endif - +#ifdef DEBUG_MULTI_WITH_AUTOMODE + if (delay_count > 0) { + if (delay_count == 1) + amvdec_start(); + delay_count--; + } +#endif if (READ_VREG(AVS_SOS_COUNT)) { if (!error_recovery_mode) { #if 0 - if (debug_flag & AVS_DEBUG_OLD_ERROR_HANDLE) { + if (debug & AVS_DEBUG_OLD_ERROR_HANDLE) { mutex_lock(&vavs_mutex); pr_info("vavs fatal error reset !\n"); amvdec_stop(); @@ -2263,14 +2517,14 @@ static void vavs_put_timer_func(unsigned long arg) struct vframe_s *vf; if (kfifo_get(&hw->recycle_q, &vf)) { - if ((vf->index < vf_buf_num) && + if ((vf->index < hw->vf_buf_num_used) && (--hw->vfbuf_use[vf->index] == 0)) { debug_print(hw, PRINT_FLAG_DECODING, "%s WRITE_VREG(AVS_BUFFERIN, 0x%x) for vf index of %d\n", __func__, ~(1 << vf->index), vf->index); WRITE_VREG(AVS_BUFFERIN, ~(1 << vf->index)); - vf->index = vf_buf_num; + vf->index = hw->vf_buf_num_used; } kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); @@ -2440,7 +2694,7 @@ static s32 vavs_init(struct vdec_avs_hw_s *hw) if (size < 0) { amvdec_disable(); pr_err("get firmware fail."); - /*vfree(buf);*/ + vfree(fw); return -1; } @@ -2498,21 +2752,19 @@ static s32 vavs_init(struct vdec_avs_hw_s *hw) #endif hw->stat |= STAT_ISR_REG; - pr_info("%s %d\n", __func__, __LINE__); #ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, hw); vf_reg_provider(&vavs_vf_prov); - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); + avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); #else vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, hw); vf_reg_provider(&vavs_vf_prov); #endif - pr_info("%s %d\n", __func__, __LINE__); if (hw->vavs_amstream_dec_info.rate != 0) { if (!hw->is_reset) - vf_notify_receiver(PROVIDER_NAME, + avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, (void *)((unsigned long) hw->vavs_amstream_dec_info.rate)); @@ -2525,7 +2777,6 @@ static s32 vavs_init(struct vdec_avs_hw_s *hw) hw->recycle_timer.data = (ulong)(hw); hw->recycle_timer.function = vavs_put_timer_func; hw->recycle_timer.expires = jiffies + PUT_INTERVAL; - pr_info("%s %d\n", __func__, __LINE__); add_timer(&hw->recycle_timer); @@ -2537,10 +2788,15 @@ static s32 vavs_init(struct vdec_avs_hw_s *hw) #endif vdec_source_changed(VFORMAT_AVS, 1920, 1080, 30); +#ifdef DEBUG_MULTI_WITH_AUTOMODE + if (start_decoding_delay == 0) + amvdec_start(); + else + delay_count = start_decoding_delay/10; +#else amvdec_start(); - +#endif hw->stat |= STAT_VDEC_RUN; - pr_info("%s %d\n", __func__, __LINE__); return 0; } @@ -2569,7 +2825,9 @@ static int amvdec_avs_probe(struct platform_device *pdev) firmware_sel = 1; if (firmware_sel == 1) { +#ifndef USE_DYNAMIC_BUF_NUM vf_buf_num = 4; +#endif canvas_base = 0; canvas_num = 3; } else { @@ -2615,6 +2873,9 @@ static int amvdec_avs_probe(struct platform_device *pdev) kfree(hw->gvs); hw->gvs = NULL; pdata->dec_status = NULL; + if (hw->fw) + vfree(hw->fw); + hw->fw = NULL; return -ENODEV; } /*vdec = pdata;*/ @@ -2692,7 +2953,7 @@ static int amvdec_avs_remove(struct platform_device *pdev) #endif if (hw->stat & STAT_VF_HOOK) { if (hw->fr_hint_status == VDEC_HINTED && !hw->is_reset) - vf_notify_receiver(PROVIDER_NAME, + avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); hw->fr_hint_status = VDEC_NO_NEED_HINT; vf_unreg_provider(&vavs_vf_prov); @@ -2746,16 +3007,51 @@ static struct platform_driver amvdec_avs_driver = { } }; +static void recycle_frames(struct vdec_avs_hw_s *hw); static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) { struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)vdec->private; int ret = 1; + unsigned buf_busy_mask = (1 << hw->vf_buf_num_used) - 1; +#ifdef DEBUG_MULTI_FRAME_INS + if ((DECODE_ID(hw) == 0) && run_count[0] > run_count[1] && + run_count[1] < max_run_count[1]) + return 0; + + if ((DECODE_ID(hw) == 1) && run_count[1] >= run_count[0] && + run_count[0] < max_run_count[0]) + return 0; - if ((hw->buf_status & 0xf) == 0xf && - kfifo_len(&hw->recycle_q) == 0) - ret = 0; + if (max_run_count[DECODE_ID(hw)] > 0 && + run_count[DECODE_ID(hw)] >= max_run_count[DECODE_ID(hw)]) + return 0; +#endif + + if (hw->reset_decode_flag == 0 && + hw->again_flag == 0 && + (hw->buf_status & buf_busy_mask) == buf_busy_mask) { + recycle_frames(hw); + if (hw->buf_recycle_status == 0) + ret = 0; + } + + if (again_threshold > 0 && + hw->pre_parser_wr_ptr != 0 && + hw->again_flag && + (!vdec_frame_based(vdec))) { + u32 parser_wr_ptr = + READ_PARSER_REG(PARSER_VIDEO_WP); + if (parser_wr_ptr >= hw->pre_parser_wr_ptr && + (parser_wr_ptr - hw->pre_parser_wr_ptr) < + again_threshold) { + int r = vdec_sync_input(vdec); + debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, + "%s buf lelvel:%x\n", __func__, r); + ret = 0; + } + } if (ret) hw->not_run_ready = 0; @@ -2788,6 +3084,9 @@ static void vavs_work(struct work_struct *work) hw->buf_recycle_status = 0; if (!hw->ctx_valid) hw->ctx_valid = 1; +#ifdef DEBUG_MULTI_FRAME_INS + msleep(delay); +#endif vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); } else if (hw->dec_result == DEC_RESULT_AGAIN && (hw_to_vdec(hw)->next_status != @@ -2830,7 +3129,8 @@ static void vavs_work(struct work_struct *work) hw->stat &= ~STAT_ISR_REG; } } else if (hw->dec_result == DEC_RESULT_EOS) { - pr_info("%s: end of stream\n", __func__); + debug_print(hw, PRINT_FLAG_DECODING, + "%s: end of stream\n", __func__); if (hw->stat & STAT_VDEC_RUN) { amvdec_stop(); hw->stat &= ~STAT_VDEC_RUN; @@ -2890,14 +3190,35 @@ static void handle_decoding_error(struct vdec_avs_hw_s *hw) struct vframe_s *vf; spin_lock_irqsave(&lock, flags); for (i = 0; i < VF_POOL_SIZE; i++) { - vf = &hw->vfpool[i]; - if (vf->index < vf_buf_num) - vf->index = -1; + vf = &hw->vfpool[i].vf; + if (vf->index < hw->vf_buf_num_used) { + hw->vfpool[i].detached = 1; + hw->vfbuf_use[vf->index] = 0; + } } - for (i = 0; i < vf_buf_num; i++) - hw->vfbuf_use[i] = 0; + if (error_handle_policy & 0x2) { + while (!kfifo_is_empty(&hw->display_q)) { + if (kfifo_get(&hw->display_q, &vf)) { + if (buf_of_vf(vf)->detached !=0) { + debug_print(hw, PRINT_FLAG_DECODING, + "%s recycle %d => newframe_q\n", + __func__, + vf->index); + vf->index = hw->vf_buf_num_used; + buf_of_vf(vf)->detached = 0; + kfifo_put(&hw->newframe_q, + (const struct vframe_s *)vf); + } + } + + } + } + clear_pts_buf(hw); + hw->decode_pic_count = 0; hw->reset_decode_flag = 1; + hw->pre_parser_wr_ptr = 0; hw->buf_status = 0; + hw->throw_pb_flag = 1; spin_unlock_irqrestore(&lock, flags); } @@ -2905,13 +3226,20 @@ static void timeout_process(struct vdec_avs_hw_s *hw) { struct vdec_s *vdec = hw_to_vdec(hw); amvdec_stop(); - handle_decoding_error(hw); + if (error_handle_policy & 0x1) { + handle_decoding_error(hw); + } else { + vavs_save_regs(hw); + + if (hw->decode_pic_count == 0) + hw->decode_pic_count++; + } + hw->dec_result = DEC_RESULT_DONE; + debug_print(hw, PRINT_FLAG_ERROR, "%s decoder timeout, status=%d, level=%d\n", __func__, vdec->status, READ_VREG(VLD_MEM_VIFIFO_LEVEL)); - hw->dec_result = DEC_RESULT_DONE; reset_process_time(hw); - hw->first_i_frame_ready = 0; vdec_schedule_work(&hw->work); } @@ -2922,8 +3250,15 @@ static void recycle_frame_bufferin(struct vdec_avs_hw_s *hw) struct vframe_s *vf; if (kfifo_get(&hw->recycle_q, &vf)) { - if ((vf->index < vf_buf_num) && - (vf->index >= 0) && + if (buf_of_vf(vf)->detached) { + debug_print(hw, 0, + "%s recycle detached vf, index=%d detched %d used %d\n", + __func__, vf->index, + buf_of_vf(vf)->detached, + hw->vfbuf_use[vf->index]); + } + if ((vf->index < hw->vf_buf_num_used) && + (buf_of_vf(vf)->detached == 0) && (--hw->vfbuf_use[vf->index] == 0)) { hw->buf_recycle_status |= (1 << vf->index); WRITE_VREG(AVS_BUFFERIN, ~(1 << vf->index)); @@ -2933,7 +3268,8 @@ static void recycle_frame_bufferin(struct vdec_avs_hw_s *hw) READ_VREG(AVS_BUFFERIN), vf->index, hw->buf_recycle_status); } - vf->index = vf_buf_num; + vf->index = hw->vf_buf_num_used; + buf_of_vf(vf)->detached = 0; kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); } @@ -2948,8 +3284,17 @@ static void recycle_frames(struct vdec_avs_hw_s *hw) struct vframe_s *vf; if (kfifo_get(&hw->recycle_q, &vf)) { - if ((vf->index < vf_buf_num) && - (vf->index >= 0) && + if (buf_of_vf(vf)->detached) { + debug_print(hw, 0, + "%s recycle detached vf, index=%d detched %d used %d\n", + __func__, vf->index, + buf_of_vf(vf)->detached, + hw->vfbuf_use[vf->index]); + } + + + if ((vf->index < hw->vf_buf_num_used) && + (buf_of_vf(vf)->detached == 0) && (--hw->vfbuf_use[vf->index] == 0)) { hw->buf_recycle_status |= (1 << vf->index); debug_print(hw, PRINT_FLAG_DECODING, @@ -2958,7 +3303,8 @@ static void recycle_frames(struct vdec_avs_hw_s *hw) vf->index, hw->buf_recycle_status); } - vf->index = vf_buf_num; + vf->index = hw->vf_buf_num_used; + buf_of_vf(vf)->detached = 0; kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); } @@ -2976,7 +3322,7 @@ static void check_timer_func(unsigned long arg) unsigned long flags; if (hw->m_ins_flag && - (debug_flag & + (debug & DEBUG_WAIT_DECODE_DONE_WHEN_STOP) == 0 && vdec->next_status == VDEC_STATUS_DISCONNECTED) { @@ -2989,11 +3335,27 @@ static void check_timer_func(unsigned long arg) /*recycle*/ if (!hw->m_ins_flag || - hw->dec_result == DEC_RESULT_NONE) { + hw->dec_result == DEC_RESULT_NONE || + hw->dec_result == DEC_RESULT_USERDATA) { spin_lock_irqsave(&lock, flags); recycle_frame_bufferin(hw); spin_unlock_irqrestore(&lock, flags); } + + if (hw->m_ins_flag) { + if ((READ_VREG(AV_SCRATCH_5) & 0xf) != 0 && + (READ_VREG(AV_SCRATCH_5) & 0xff00) != 0){ + /*ucode buffer empty*/ + if ((kfifo_len(&hw->recycle_q) == 0) && + (kfifo_len(&hw->display_q) == 0)) { + debug_print(hw, + 0, "AV_SCRATCH_5=0x%x, recover ucode buffer_status\n", + READ_VREG(AV_SCRATCH_5)); + WRITE_VREG(AV_SCRATCH_5, 0x10); + /*let ucode to recover buffer_status*/ + } + } + } if (radr != 0) { if (rval != 0) { WRITE_VREG(radr, rval); @@ -3003,6 +3365,11 @@ static void check_timer_func(unsigned long arg) rval = 0; radr = 0; } + + if (udebug_flag != hw->old_udebug_flag) { + WRITE_VREG(DECODE_STOP_POS, udebug_flag); + hw->old_udebug_flag = udebug_flag; + } if (dbg_cmd != 0) { if (dbg_cmd == 1) { int r = vdec_sync_input(vdec); @@ -3018,9 +3385,7 @@ static void check_timer_func(unsigned long arg) } } - if ((debug_flag & DEBUG_FLAG_DISABLE_TIMEOUT) == 0 && - (input_frame_based(vdec) || - (READ_VREG(VLD_MEM_VIFIFO_LEVEL) > 0x100)) && + if ((debug & DEBUG_FLAG_DISABLE_TIMEOUT) == 0 && (timeout_val > 0) && (hw->start_process_time > 0) && ((1000 * (jiffies - hw->start_process_time) / HZ) @@ -3037,14 +3402,21 @@ static void check_timer_func(unsigned long arg) if (READ_VREG(AVS_SOS_COUNT)) { if (!error_recovery_mode) { amvdec_stop(); - handle_decoding_error(hw); + if (error_handle_policy & 0x1) { + handle_decoding_error(hw); + } else { + vavs_save_regs(hw); + + if (hw->decode_pic_count == 0) + hw->decode_pic_count++; + } + hw->dec_result = DEC_RESULT_DONE; + debug_print(hw, PRINT_FLAG_ERROR, "%s decoder error, status=%d, level=%d, AVS_SOS_COUNT=0x%x\n", __func__, vdec->status, READ_VREG(VLD_MEM_VIFIFO_LEVEL), READ_VREG(AVS_SOS_COUNT)); - hw->dec_result = DEC_RESULT_DONE; reset_process_time(hw); - hw->first_i_frame_ready = 0; vdec_schedule_work(&hw->work); } } @@ -3069,12 +3441,8 @@ static void check_timer_func(unsigned long arg) static int avs_hw_ctx_restore(struct vdec_avs_hw_s *hw) { /*int r = 0;*/ -#if DEBUG_MULTI_FLAG > 0 - if (hw->decode_pic_count > 0) - vavs_prot_init_vld_only(hw); - else -#endif vavs_prot_init(hw); + return 0; } @@ -3109,6 +3477,11 @@ void (*callback)(struct vdec_s *, void *), int save_reg = READ_VREG(POWER_CTL_VLD); int size, ret; /* reset everything except DOS_TOP[1] and APB_CBUS[0]*/ + + hw->pre_parser_wr_ptr = + READ_PARSER_REG(PARSER_VIDEO_WP); + +#if 1 #if DEBUG_MULTI_FLAG > 0 if (hw->decode_pic_count == 0) { #endif @@ -3116,10 +3489,14 @@ void (*callback)(struct vdec_s *, void *), WRITE_VREG(DOS_SW_RESET0, 0); WRITE_VREG(POWER_CTL_VLD, save_reg); hw->run_count++; + run_count[DECODE_ID(hw)] = hw->run_count; vdec_reset_core(vdec); #if DEBUG_MULTI_FLAG > 0 } #endif +#else + vdec_reset_core(vdec); +#endif hw->vdec_cb_arg = arg; hw->vdec_cb = callback; @@ -3155,7 +3532,7 @@ void (*callback)(struct vdec_s *, void *), data = ((u8 *)hw->chunk->block->start_virt) + hw->chunk->offset; - if (debug_flag & PRINT_FLAG_RUN_FLOW + if (debug & PRINT_FLAG_RUN_FLOW ) { debug_print(hw, 0, "%s decode_pic_count %d buf_recycle_status 0x%x: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n", @@ -3167,7 +3544,7 @@ void (*callback)(struct vdec_s *, void *), data[size - 3], data[size - 2], data[size - 1]); } - if (debug_flag & PRINT_FRAMEBASE_DATA + if (debug & PRINT_FRAMEBASE_DATA ) { int jj; @@ -3205,7 +3582,10 @@ void (*callback)(struct vdec_s *, void *), hw->input_empty = 0; debug_print(hw, PRINT_FLAG_RUN_FLOW, "%s,%d, size=%d\n", __func__, __LINE__, size); - vdec_enable_input(vdec); + + /*vdec_enable_input(vdec); + need run after VC1_CONTROL_REG is configured + */ hw->init_flag = 1; if (hw->chunk) @@ -3233,7 +3613,6 @@ void (*callback)(struct vdec_s *, void *), vdec->mc_loaded = 1; vdec->mc_type = VFORMAT_AVS; } - if (avs_hw_ctx_restore(hw) < 0) { hw->dec_result = DEC_RESULT_ERROR; debug_print(hw, PRINT_FLAG_ERROR, @@ -3241,6 +3620,20 @@ void (*callback)(struct vdec_s *, void *), vdec_schedule_work(&hw->work); return; } + + /* + This configureation of VC1_CONTROL_REG will + pop bits (even no data in the stream buffer) if input is enabled, + so it can only be configured before vdec_enable_input() is called. + So move this code from ucode to here + */ +#define DISABLE_DBLK_HCMD 0 +#define DISABLE_MC_HCMD 0 + WRITE_VREG(VC1_CONTROL_REG, (DISABLE_DBLK_HCMD<<6) | + (DISABLE_MC_HCMD<<5) | (1 << 7) | (0xc <<8) | (1<<14)); + vdec_enable_input(vdec); + /**/ + /*wmb();*/ hw->stat |= STAT_MC_LOAD; hw->last_vld_level = 0; @@ -3249,18 +3642,24 @@ void (*callback)(struct vdec_s *, void *), "%s READ_VREG(AVS_BUFFERIN)=0x%x, recycle_q num %d\n", __func__, READ_VREG(AVS_BUFFERIN), kfifo_len(&hw->recycle_q)); - recycle_frames(hw); - if (hw->reset_decode_flag) { - hw->buf_recycle_status = 0xff; - WRITE_VREG(AVS_BUFFERIN, 0); - WRITE_VREG(AVS_BUFFEROUT, 0); + + WRITE_VREG(VIFF_BIT_CNT, size * 8); + if (hw->reset_decode_flag) + WRITE_VREG(DECODE_STATUS, 0); + else { + recycle_frames(hw); + avs_pts_check_in(hw, + hw->decode_pic_count & 0xffff, + hw->chunk); + + WRITE_VREG(DECODE_STATUS, + (hw->decode_pic_count & 0xffff) | + ((~hw->buf_recycle_status) << 16)); } - WRITE_VREG(DECODE_STATUS, - hw->decode_pic_count | - ((~hw->buf_recycle_status) << 24)); - hw->buf_recycle_status = 0; + if (hw->again_flag == 0) + hw->buf_recycle_status = 0; hw->reset_decode_flag = 0; - + hw->decode_status_skip_pic_done_flag = 0; start_process_time(hw); #if DEBUG_MULTI_FLAG == 1 if (hw->decode_pic_count > 0) @@ -3297,7 +3696,7 @@ static void vmavs_dump_state(struct vdec_s *vdec) { struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)vdec->private; - + int i; debug_print(hw, 0, "====== %s\n", __func__); @@ -3309,11 +3708,12 @@ static void vmavs_dump_state(struct vdec_s *vdec) ); debug_print(hw, 0, - "is_framebase(%d), decode_status 0x%x, buf_status 0x%x, buf_recycle_status 0x%x, eos %d, state 0x%x, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d\n", + "is_framebase(%d), decode_status 0x%x, buf_status 0x%x, buf_recycle_status 0x%x, throw %d, eos %d, state 0x%x, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d\n", vdec_frame_based(vdec), READ_VREG(DECODE_STATUS) & 0xff, hw->buf_status, hw->buf_recycle_status, + hw->throw_pb_flag, hw->eos, hw->stat, hw->dec_result, @@ -3351,6 +3751,11 @@ static void vmavs_dump_state(struct vdec_s *vdec) hw->put_num ); + debug_print(hw, 0, "vfbuf_use:\n"); + for (i = 0; i < hw->vf_buf_num_used; i++) + debug_print(hw, 0, "%d: vf_buf_use %d\n", + i, hw->vfbuf_use[i]); + debug_print(hw, 0, "DECODE_STATUS=0x%x\n", READ_VREG(DECODE_STATUS)); @@ -3361,6 +3766,9 @@ static void vmavs_dump_state(struct vdec_s *vdec) "DECODE_MODE=0x%x\n", READ_VREG(DECODE_MODE)); debug_print(hw, 0, + "wait_buf_status, AV_SCRATCH_5=0x%x\n", + READ_VREG(AV_SCRATCH_5)); + debug_print(hw, 0, "MBY_MBX=0x%x\n", READ_VREG(MBY_MBX)); debug_print(hw, 0, @@ -3421,7 +3829,534 @@ static void vmavs_dump_state(struct vdec_s *vdec) } -static int ammvdec_avs_probe(struct platform_device *pdev) + int ammvdec_avs_probe(struct platform_device *pdev) +{ + struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; + struct vdec_avs_hw_s *hw = NULL; + + if (vdec_get_debug_flags() & 0x8) + return amvdec_avs_probe(pdev); + + pr_info("ammvdec_avs probe start.\n"); + + if (pdata == NULL) { + pr_info("ammvdec_avs platform data undefined.\n"); + return -EFAULT; + } + + hw = (struct vdec_avs_hw_s *)devm_kzalloc(&pdev->dev, + sizeof(struct vdec_avs_hw_s), GFP_KERNEL); + if (hw == NULL) { + pr_info("\nammvdec_avs decoder driver alloc failed\n"); + return -ENOMEM; + } + /*atomic_set(&hw->error_handler_run, 0);*/ + hw->m_ins_flag = 1; + + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans) + firmware_sel = 1; + + if (firmware_sel == 1) { +#ifndef USE_DYNAMIC_BUF_NUM + vf_buf_num = 4; +#endif + canvas_base = 0; + canvas_num = 3; + } else { + pr_info("Error, do not support longcabac work around!!!"); + return -ENOMEM; + } + + if (pdata->sys_info) + hw->vavs_amstream_dec_info = *pdata->sys_info; + + hw->is_reset = 0; + pdata->user_data_read = NULL; + pdata->reset_userdata_fifo = NULL; + + pdata->private = hw; + pdata->dec_status = vavs_dec_status; + pdata->set_isreset = vavs_set_isreset; + pdata->run_ready = run_ready; + pdata->run = run; + pdata->reset = reset; + pdata->irq_handler = vmavs_isr; + pdata->threaded_irq_handler = vmavs_isr_thread_fn; + pdata->dump_state = vmavs_dump_state; + + vavs_vdec_info_init(hw); + +#ifdef ENABLE_USER_DATA + if (NULL == hw->user_data_buffer) { + hw->user_data_buffer = + dma_alloc_coherent(amports_get_dma_device(), + USER_DATA_SIZE, + &hw->user_data_buffer_phys, GFP_KERNEL); + if (!hw->user_data_buffer) { + pr_info("%s: Can not allocate hw->user_data_buffer\n", + __func__); + return -ENOMEM; + } + pr_debug("hw->user_data_buffer = 0x%p, hw->user_data_buffer_phys = 0x%x\n", + hw->user_data_buffer, (u32)hw->user_data_buffer_phys); + } +#endif + hw->lmem_addr = kmalloc(LMEM_BUF_SIZE, GFP_KERNEL); + if (hw->lmem_addr == NULL) { + pr_err("%s: failed to alloc lmem buffer\n", __func__); + return -1; + } + hw->lmem_phy_addr = dma_map_single(amports_get_dma_device(), + hw->lmem_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE); + if (dma_mapping_error(amports_get_dma_device(), + hw->lmem_phy_addr)) { + pr_err("%s: failed to map lmem buffer\n", __func__); + kfree(hw->lmem_addr); + hw->lmem_addr = NULL; + return -1; + } + + /*INIT_WORK(&hw->set_clk_work, avs_set_clk);*/ + + if (vavs_init(hw) < 0) { + pr_info("amvdec_avs init failed.\n"); + kfree(hw->gvs); + hw->gvs = NULL; + pdata->dec_status = NULL; + return -ENODEV; + } + + /*INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler); + atomic_set(&hw->error_handler_run, 0);*/ +#if 0 +#ifdef ENABLE_USER_DATA + INIT_WORK(&hw->userdata_push_work, userdata_push_do_work); +#endif +#endif + INIT_WORK(&hw->notify_work, vavs_notify_work); + + if (pdata->use_vfm_path) { + snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, + VFM_DEC_PROVIDER_NAME); + hw->frameinfo_enable = 1; + } + else + snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, + MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff); + if (pdata->parallel_dec == 1) { + int i; + for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) + hw->canvas_spec[i] = 0xffffff; + } + vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, + &vavs_vf_provider, hw); + + platform_set_drvdata(pdev, pdata); + + hw->platform_dev = pdev; + + vdec_set_prepare_level(pdata, start_decode_buf_level); + + vdec_set_vframe_comm(pdata, DRIVER_NAME); + + if (pdata->parallel_dec == 1) + vdec_core_request(pdata, CORE_MASK_VDEC_1); + else { + vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC + | CORE_MASK_COMBINE); + } + + /*INIT_WORK(&hw->userdata_push_work, userdata_push_do_work);*/ + + + return 0; +} + + int ammvdec_avs_remove(struct platform_device *pdev) +{ + + if (vdec_get_debug_flags() & 0x8) + return amvdec_avs_remove(pdev); + else { + struct vdec_avs_hw_s *hw = + (struct vdec_avs_hw_s *) + (((struct vdec_s *)(platform_get_drvdata(pdev)))->private); + struct vdec_s *vdec = hw_to_vdec(hw); + int i; + + if (hw->stat & STAT_VDEC_RUN) { + amvdec_stop(); + hw->stat &= ~STAT_VDEC_RUN; + } + + if (hw->stat & STAT_ISR_REG) { + vdec_free_irq(VDEC_IRQ_1, (void *)hw); + hw->stat &= ~STAT_ISR_REG; + } + + if (hw->stat & STAT_TIMER_ARM) { + del_timer_sync(&hw->check_timer); + hw->stat &= ~STAT_TIMER_ARM; + } + + cancel_work_sync(&hw->work); + cancel_work_sync(&hw->notify_work); + + if (hw->mm_blk_handle) { + decoder_bmmu_box_free(hw->mm_blk_handle); + hw->mm_blk_handle = NULL; + } + if (vdec->parallel_dec == 1) + vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1); + else + vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC); + vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED); + + if (vdec->parallel_dec == 1) { + for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { + vdec->free_canvas_ex(canvas_y(hw->canvas_spec[i]), vdec->id); + vdec->free_canvas_ex(canvas_u(hw->canvas_spec[i]), vdec->id); + } + } + #ifdef ENABLE_USER_DATA + if (hw->user_data_buffer != NULL) { + dma_free_coherent( + amports_get_dma_device(), + USER_DATA_SIZE, + hw->user_data_buffer, + hw->user_data_buffer_phys); + hw->user_data_buffer = NULL; + hw->user_data_buffer_phys = 0; + } + #endif + if (hw->lmem_addr) { + dma_unmap_single(amports_get_dma_device(), + hw->lmem_phy_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE); + kfree(hw->lmem_addr); + hw->lmem_addr = NULL; + } + + if (hw->fw) { + vfree(hw->fw); + hw->fw = NULL; + } + + pr_info("ammvdec_avs removed.\n"); + if (hw->gvs) { + kfree(hw->gvs); + hw->gvs = NULL; + } + + return 0; + } +} + + +#ifdef DEBUG_MULTI_WITH_AUTOMODE +struct stream_buf_s *get_vbuf(void); +s32 esparser_init(struct stream_buf_s *buf, struct vdec_s *vdec); + + +static s32 vavs_init2(struct vdec_avs_hw_s *hw) +{ + int size = -1; + struct firmware_s *fw; + u32 fw_size = 0x1000 * 16; + + fw = vmalloc(sizeof(struct firmware_s) + fw_size); + if (IS_ERR_OR_NULL(fw)) + return -ENOMEM; + + pr_info("vavs_init\n"); + + amvdec_enable(); + + + vavs_local_init(hw); + + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM) + size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data); + else { + if (firmware_sel == 1) + size = get_firmware_data(VIDEO_DEC_AVS_NOCABAC, fw->data); +#ifdef AVSP_LONG_CABAC + else { + init_avsp_long_cabac_buf(); + size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data); + } +#endif + } + + if (size < 0) { + amvdec_disable(); + pr_err("get firmware fail."); + /*vfree(buf);*/ + return -1; + } + + fw->len = size; + hw->fw = fw; + if (hw->m_ins_flag) { + init_timer(&hw->check_timer); + hw->check_timer.data = (ulong) hw; + hw->check_timer.function = check_timer_func; + hw->check_timer.expires = jiffies + CHECK_INTERVAL; + + + //add_timer(&hw->check_timer); + hw->stat |= STAT_TIMER_ARM; + + INIT_WORK(&hw->work, vavs_work); + + hw->fw = fw; + } + return 0; +} + +unsigned int debug_flag2; +static int vavs_prot_init2(struct vdec_avs_hw_s *hw, unsigned char post_flag) +{ + int r = 0; + /* + * 2: assist + * 3: vld_reset + * 4: vld_part_reset + * 5: vfifo reset + * 6: iqidct + * 7: mc + * 8: dblk + * 9: pic_dc + * 10: psc + * 11: mcpu + * 12: ccpu + * 13: ddr + * 14: afifo + */ + unsigned char run_flag; +#ifdef OOO + WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) /*| (1 << 4)*/); + WRITE_VREG(DOS_SW_RESET0, 0); + + READ_VREG(DOS_SW_RESET0); + + WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) /*| (1 << 4)*/); + WRITE_VREG(DOS_SW_RESET0, 0); + + WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8)); + WRITE_VREG(DOS_SW_RESET0, 0); +#endif + /***************** reset vld **********************************/ +#ifdef OOO + WRITE_VREG(POWER_CTL_VLD, 0x10); + WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2, MEM_FIFO_CNT_BIT, 2); + WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8, MEM_LEVEL_CNT_BIT, 6); +#endif + if (start_decoding_delay & 0x80000) + msleep(start_decoding_delay&0xffff); + +if (debug_flag2 & 0x1) + run_flag = post_flag; +else + run_flag = !post_flag; +if (run_flag) { + if (hw->m_ins_flag) { + int i; + if (hw->decode_pic_count == 0) { + r = vavs_canvas_init(hw); +#ifndef USE_DYNAMIC_BUF_NUM + for (i = 0; i < 4; i++) { + WRITE_VREG(AV_SCRATCH_0 + i, + hw->canvas_spec[i] + ); + } +#else + for (i = 0; i < hw->vf_buf_num_used; i += 2) { + WRITE_VREG(buf_spec_reg[i >> 1], + (hw->canvas_spec[i] & 0xffff) | + ((hw->canvas_spec[i + 1] & 0xffff) + << 16) + ); + } +#endif + } else + vavs_restore_regs(hw); + + for (i = 0; i < hw->vf_buf_num_used; i++) { + canvas_config_ex(canvas_y(hw->canvas_spec[i]), + hw->canvas_config[i][0].phy_addr, + hw->canvas_config[i][0].width, + hw->canvas_config[i][0].height, + CANVAS_ADDR_NOWRAP, + hw->canvas_config[i][0].block_mode, + 0); + + canvas_config_ex(canvas_u(hw->canvas_spec[i]), + hw->canvas_config[i][1].phy_addr, + hw->canvas_config[i][1].width, + hw->canvas_config[i][1].height, + CANVAS_ADDR_NOWRAP, + hw->canvas_config[i][1].block_mode, + 0); + } + } +} + +if (debug_flag2 & 0x2) + run_flag = post_flag; +else + run_flag = !post_flag; +if (run_flag) { + + /* notify ucode the buffer offset */ + if (hw->decode_pic_count == 0) + WRITE_VREG(AV_SCRATCH_F, hw->buf_offset); +#ifdef OOO + /* disable PSCALE for hardware sharing */ + WRITE_VREG(PSCALE_CTRL, 0); +#endif + } + if (start_decoding_delay & 0x40000) + msleep(start_decoding_delay&0xffff); + + if (debug_flag2 & 0x4) + run_flag = post_flag; + else + run_flag = !post_flag; + if (run_flag) { + if (hw->decode_pic_count == 0) { +#ifndef USE_DYNAMIC_BUF_NUM + WRITE_VREG(AVS_SOS_COUNT, 0); +#endif + WRITE_VREG(AVS_BUFFERIN, 0); + WRITE_VREG(AVS_BUFFEROUT, 0); + } + if (error_recovery_mode) + WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 0); + else + WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 1); + /* clear mailbox interrupt */ + WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); + + /* enable mailbox interrupt */ + WRITE_VREG(ASSIST_MBOX1_MASK, 1); +} + +if (debug_flag2 & 0x8) + run_flag = post_flag; +else + run_flag = !post_flag; +if (run_flag) { + +#ifndef USE_DYNAMIC_BUF_NUM /* def DEBUG_UCODE */ + if (hw->decode_pic_count == 0) + WRITE_VREG(AV_SCRATCH_D, 0); +#endif + if (start_decoding_delay & 0x10000) + msleep(start_decoding_delay&0xffff); +#ifdef NV21 + SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); +#endif + if (start_decoding_delay & 0x20000) + msleep(start_decoding_delay&0xffff); + + +#ifdef PIC_DC_NEED_CLEAR + CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); +#endif +} +if (debug_flag2 & 0x10) + run_flag = post_flag; +else + run_flag = !post_flag; +if (run_flag) { +#ifdef ENABLE_USER_DATA + if (firmware_sel == 0) { + pr_info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! firmware_sel is 0\n"); + WRITE_VREG(AV_SCRATCH_N, (u32)(hw->user_data_buffer_phys - hw->buf_offset)); + pr_debug("AV_SCRATCH_N = 0x%x\n", READ_VREG(AV_SCRATCH_N)); + } +#endif +} + +if (debug_flag2 & 0x20) + run_flag = post_flag; +else + run_flag = !post_flag; +if (run_flag) { + if (hw->m_ins_flag) { + if (vdec_frame_based(hw_to_vdec(hw))) + WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_FRAMEBASE); + else + WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE); + WRITE_VREG(DECODE_LMEM_BUF_ADR, hw->lmem_phy_addr); + } else + WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); + WRITE_VREG(DECODE_STOP_POS, udebug_flag); + hw->old_udebug_flag = udebug_flag; +} + return r; +} + +static void init_hw(struct vdec_s *vdec) +{ + struct vdec_avs_hw_s *hw = + (struct vdec_avs_hw_s *)vdec->private; + int ret; + pr_info("%s, %d\n", __func__, __LINE__); + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM) + ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, hw->fw->data); + else if (firmware_sel == 1) + ret = amvdec_loadmc_ex(VFORMAT_AVS, "avs_no_cabac", hw->fw->data); + else + ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, hw->fw->data); + + if (ret < 0) { + amvdec_disable(); + /*vfree(buf);*/ + pr_err("AVS: the %s fw loading failed, err: %x\n", + tee_enabled() ? "TEE" : "local", ret); + } + pr_info("%s, %d\n", __func__, __LINE__); + + /*vfree(buf);*/ + + hw->stat |= STAT_MC_LOAD; + + /* enable AMRISC side protocol */ + ret = vavs_prot_init2(hw, 0); + if (ret < 0) + return; + pr_info("%s, %d\n", __func__, __LINE__); + +} + + +static unsigned long run_ready2(struct vdec_s *vdec, unsigned long mask) +{ + return 1; +} + +static void run2(struct vdec_s *vdec, unsigned long mask, +void (*callback)(struct vdec_s *, void *), + void *arg) +{ + struct vdec_avs_hw_s *hw = + (struct vdec_avs_hw_s *)vdec->private; + pr_info("%s, %d\n", __func__, __LINE__); + + vavs_prot_init2(hw, 1); + + vdec_source_changed(VFORMAT_AVS, + 1920, 1080, 30); + + amvdec_start(); + + hw->stat |= STAT_VDEC_RUN; + pr_info("%s %d\n", __func__, __LINE__); + +} + +static int ammvdec_avs_probe2(struct platform_device *pdev) { struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; struct vdec_avs_hw_s *hw = NULL; @@ -3450,7 +4385,9 @@ static int ammvdec_avs_probe(struct platform_device *pdev) pr_info("%s %d\n", __func__, __LINE__); if (firmware_sel == 1) { +#ifndef USE_DYNAMIC_BUF_NUM vf_buf_num = 4; +#endif canvas_base = 0; canvas_num = 3; } else { @@ -3472,8 +4409,8 @@ static int ammvdec_avs_probe(struct platform_device *pdev) pdata->private = hw; pdata->dec_status = vavs_dec_status; pdata->set_isreset = vavs_set_isreset; - pdata->run_ready = run_ready; - pdata->run = run; + pdata->run_ready = run_ready2; + pdata->run = run2; pdata->reset = reset; pdata->irq_handler = vmavs_isr; pdata->threaded_irq_handler = vmavs_isr_thread_fn; @@ -3521,23 +4458,19 @@ static int ammvdec_avs_probe(struct platform_device *pdev) pr_info("%s %d\n", __func__, __LINE__); - if (vavs_init(hw) < 0) { + if (vavs_init2(hw) < 0) { pr_info("amvdec_avs init failed.\n"); kfree(hw->gvs); hw->gvs = NULL; pdata->dec_status = NULL; return -ENODEV; } + /*vdec = pdata;*/ + pr_info("%s, %d\n", __func__, __LINE__); - /*INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler); - atomic_set(&hw->error_handler_run, 0);*/ -#if 0 -#ifdef ENABLE_USER_DATA - INIT_WORK(&hw->userdata_push_work, userdata_push_do_work); -#endif -#endif +if (hw->m_ins_flag) { INIT_WORK(&hw->notify_work, vavs_notify_work); - +#if 1 if (pdata->use_vfm_path) { snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, VFM_DEC_PROVIDER_NAME); @@ -3566,53 +4499,91 @@ static int ammvdec_avs_probe(struct platform_device *pdev) vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC | CORE_MASK_COMBINE); } + pr_info("%s, %d\n", __func__, __LINE__); +#endif +}else{ + /*INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler); + atomic_set(&hw->error_handler_run, 0);*/ +#ifdef ENABLE_USER_DATA + INIT_WORK(&hw->userdata_push_work, userdata_push_do_work); +#endif + INIT_WORK(&hw->notify_work, vavs_notify_work); +} - /*INIT_WORK(&hw->userdata_push_work, userdata_push_do_work);*/ + init_hw(pdata); return 0; } -static int ammvdec_avs_remove(struct platform_device *pdev) +static int ammvdec_avs_remove2(struct platform_device *pdev) { - struct vdec_avs_hw_s *hw = - (struct vdec_avs_hw_s *) - (((struct vdec_s *)(platform_get_drvdata(pdev)))->private); - struct vdec_s *vdec = hw_to_vdec(hw); - int i; + struct vdec_avs_hw_s *hw = ghw; + cancel_work_sync(&hw->fatal_error_wd_work); + atomic_set(&hw->error_handler_run, 0); +#ifdef ENABLE_USER_DATA + cancel_work_sync(&hw->userdata_push_work); +#endif + cancel_work_sync(&hw->notify_work); + cancel_work_sync(&hw->set_clk_work); if (hw->stat & STAT_VDEC_RUN) { amvdec_stop(); hw->stat &= ~STAT_VDEC_RUN; } if (hw->stat & STAT_ISR_REG) { - vdec_free_irq(VDEC_IRQ_1, (void *)hw); + vdec_free_irq(VDEC_IRQ_1, (void *)vavs_dec_id); hw->stat &= ~STAT_ISR_REG; } if (hw->stat & STAT_TIMER_ARM) { - del_timer_sync(&hw->check_timer); + del_timer_sync(&hw->recycle_timer); hw->stat &= ~STAT_TIMER_ARM; } +#ifdef AVSP_LONG_CABAC + if (firmware_sel == 0) { + mutex_lock(&vavs_mutex); + cancel_work_sync(&long_cabac_wd_work); + mutex_unlock(&vavs_mutex); - cancel_work_sync(&hw->work); - cancel_work_sync(&hw->notify_work); - - if (hw->mm_blk_handle) { - decoder_bmmu_box_free(hw->mm_blk_handle); - hw->mm_blk_handle = NULL; - } - if (vdec->parallel_dec == 1) - vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1); - else - vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC); - vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED); + if (es_write_addr_virt) { +#if 0 + codec_mm_free_for_dma("vavs", es_write_addr_phy); +#else + dma_unmap_single(amports_get_dma_device(), + es_write_addr_phy, + MAX_CODED_FRAME_SIZE, DMA_FROM_DEVICE); + /*kfree(es_write_addr_virt);*/ + es_write_addr_virt = NULL; +#endif + } - if (vdec->parallel_dec == 1) { - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { - vdec->free_canvas_ex(canvas_y(hw->canvas_spec[i]), vdec->id); - vdec->free_canvas_ex(canvas_u(hw->canvas_spec[i]), vdec->id); +#ifdef BITSTREAM_READ_TMP_NO_CACHE + if (bitstream_read_tmp) { + dma_free_coherent(amports_get_dma_device(), + SVA_STREAM_BUF_SIZE, bitstream_read_tmp, + bitstream_read_tmp_phy); + bitstream_read_tmp = NULL; + } +#else + if (bitstream_read_tmp) { + dma_unmap_single(amports_get_dma_device(), + bitstream_read_tmp_phy, + SVA_STREAM_BUF_SIZE, DMA_FROM_DEVICE); + kfree(bitstream_read_tmp); + bitstream_read_tmp = NULL; } +#endif } +#endif + if (hw->stat & STAT_VF_HOOK) { + if (hw->fr_hint_status == VDEC_HINTED && !hw->is_reset) + avs_vf_notify_receiver(hw, PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); + hw->fr_hint_status = VDEC_NO_NEED_HINT; + vf_unreg_provider(&vavs_vf_prov); + hw->stat &= ~STAT_VF_HOOK; + } + #ifdef ENABLE_USER_DATA if (hw->user_data_buffer != NULL) { dma_free_coherent( @@ -3624,31 +4595,41 @@ static int ammvdec_avs_remove(struct platform_device *pdev) hw->user_data_buffer_phys = 0; } #endif - if (hw->lmem_addr) { - dma_unmap_single(amports_get_dma_device(), - hw->lmem_phy_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE); - kfree(hw->lmem_addr); - hw->lmem_addr = NULL; - } if (hw->fw) { vfree(hw->fw); hw->fw = NULL; } - pr_info("ammvdec_avs removed.\n"); - if (hw->gvs) { - kfree(hw->gvs); - hw->gvs = NULL; + amvdec_disable(); + /*vdec_disable_DMC(NULL);*/ + + hw->pic_type = 0; + if (hw->mm_blk_handle) { + decoder_bmmu_box_free(hw->mm_blk_handle); + hw->mm_blk_handle = NULL; } +#ifdef DEBUG_PTS + pr_debug("pts hit %d, pts missed %d, i hit %d, missed %d\n", hw->pts_hit, + hw->pts_missed, hw->pts_i_hit, hw->pts_i_missed); + pr_debug("total frame %d, hw->avi_flag %d, rate %d\n", hw->total_frame, hw->avi_flag, + hw->vavs_amstream_dec_info.rate); +#endif + kfree(hw->gvs); + hw->gvs = NULL; return 0; } - +#endif static struct platform_driver ammvdec_avs_driver = { +#ifdef DEBUG_MULTI_WITH_AUTOMODE + .probe = ammvdec_avs_probe2, + .remove = ammvdec_avs_remove2, +#else .probe = ammvdec_avs_probe, .remove = ammvdec_avs_remove, +#endif #ifdef CONFIG_PM .suspend = amvdec_suspend, .resume = amvdec_resume, @@ -3684,12 +4665,14 @@ static int __init ammvdec_avs_driver_init_module(void) if (platform_driver_register(&ammvdec_avs_driver)) pr_err("failed to register ammvdec_avs driver\n"); - - /*if (platform_driver_register(&amvdec_avs_driver)) { +#ifdef DEBUG_WITH_SINGLE_MODE + if (platform_driver_register(&amvdec_avs_driver)) { pr_info("failed to register amvdec_avs driver\n"); return -ENODEV; - }*/ + } +#else amvdec_avs_driver = amvdec_avs_driver; +#endif if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB) ammvdec_avs_profile.profile = "avs+"; @@ -3706,8 +4689,9 @@ static void __exit ammvdec_avs_driver_remove_module(void) pr_debug("ammvdec_avs module remove.\n"); platform_driver_unregister(&ammvdec_avs_driver); - - /*platform_driver_unregister(&amvdec_avs_driver);*/ +#ifdef DEBUG_WITH_SINGLE_MODE + platform_driver_unregister(&amvdec_avs_driver); +#endif } /****************************************/ @@ -3726,8 +4710,8 @@ MODULE_PARM_DESC(stat, "\n amvdec_avs stat\n"); module_param(step, uint, 0664); MODULE_PARM_DESC(step, "\n step\n"); -module_param(debug_flag, uint, 0664); -MODULE_PARM_DESC(debug_flag, "\n debug_flag\n"); +module_param(debug, uint, 0664); +MODULE_PARM_DESC(debug, "\n debug\n"); module_param(debug_mask, uint, 0664); MODULE_PARM_DESC(debug_mask, "\n debug_mask\n"); @@ -3785,6 +4769,13 @@ module_param(decode_timeout_val, uint, 0664); MODULE_PARM_DESC(decode_timeout_val, "\n avs decode_timeout_val\n"); +module_param(error_handle_policy, uint, 0664); +MODULE_PARM_DESC(error_handle_policy, + "\n avs error_handle_policy\n"); + +module_param(again_threshold, uint, 0664); +MODULE_PARM_DESC(again_threshold, "\n again_threshold\n"); + module_param(udebug_flag, uint, 0664); MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 udebug_flag\n"); @@ -3797,11 +4788,33 @@ MODULE_PARM_DESC(udebug_pause_val, "\n udebug_pause_val\n"); module_param(udebug_pause_decode_idx, uint, 0664); MODULE_PARM_DESC(udebug_pause_decode_idx, "\n udebug_pause_decode_idx\n"); +module_param(udebug_pause_ins_id, uint, 0664); +MODULE_PARM_DESC(udebug_pause_ins_id, "\n udebug_pause_ins_id\n"); + +module_param(start_decoding_delay, uint, 0664); +MODULE_PARM_DESC(start_decoding_delay, "\n start_decoding_delay\n"); + +#ifdef DEBUG_MULTI_WITH_AUTOMODE +module_param(debug_flag2, uint, 0664); +MODULE_PARM_DESC(debug_flag2, "\n debug_flag2\n"); +#endif module_param(force_fps, uint, 0664); MODULE_PARM_DESC(force_fps, "\n force_fps\n"); +#ifdef DEBUG_MULTI_FRAME_INS +module_param(delay, uint, 0664); +MODULE_PARM_DESC(delay, "\n delay\n"); + +module_param_array(max_run_count, uint, &max_decode_instance_num, 0664); + +#endif + +module_param_array(ins_udebug_flag, uint, &max_decode_instance_num, 0664); + module_param_array(max_process_time, uint, &max_decode_instance_num, 0664); +module_param_array(run_count, uint, &max_decode_instance_num, 0664); + module_param_array(max_get_frame_interval, uint, &max_decode_instance_num, 0664); diff --git a/drivers/frame_provider/decoder/avs_multi/avsp_trans_multi.c b/drivers/frame_provider/decoder/avs_multi/avsp_trans_multi.c deleted file mode 100644 index 89ff844..0000000 --- a/drivers/frame_provider/decoder/avs_multi/avsp_trans_multi.c +++ b/dev/null @@ -1,5065 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/* #include */ -#include -#include -#include "../../../stream_input/parser/streambuf_reg.h" -#include "../utils/amvdec.h" -#include -#include "../../../stream_input/amports/amports_priv.h" - -#include "avs_multi.h" -#ifdef AVSP_LONG_CABAC - -#define DECODING_SANITY_CHECK - -#define TRACE 0 -#define LIWR_FIX 0 -#define pow2(a, b) (1< 0) { - if (num >= 8) - push_num = 8; - else - push_num = num; - - num = num - push_num; - push_value = (value >> num); - - es_res = (es_res << push_num) | push_value; - es_res_ptr = es_res_ptr + push_num; - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & ES_DUMP) - io_printf(" #### es_res : 0x%X, es_res_ptr : %d\n", - es_res, es_res_ptr); -#endif - - while (es_res_ptr >= 8) { - es_res_ptr = es_res_ptr & 7; - wr_es_data = (es_res >> es_res_ptr) & 0xff; - if ((previous_es == 0) & (wr_es_data < 4)) { - io_printf( - " Insert 2'b10 for emu at position : %d\n", - es_ptr); - - es_res_ptr = es_res_ptr + 2; - wr_es_data = 2; - } -#ifdef AVSP_LONG_CABAC -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & ES_DUMP) - pr_info("es_buf[%d] = 0x%02x\r\n", - es_buf_ptr, wr_es_data); -#endif - if (!es_buf_is_overflow) { - es_buf[es_buf_ptr++] = wr_es_data; - if (es_buf_ptr >= MAX_CODED_FRAME_SIZE) - es_buf_is_overflow = 1; - } -#else - putc(wr_es_data, f_es); -#endif - es_ptr++; - previous_es = ((previous_es << 8) | wr_es_data) - & 0xffff; - } - - } -} - -#ifdef BLOCK_SIZE -#undef BLOCK_SIZE -#endif - -#define MIN_QP 0 -#define MAX_QP 63 - -#define BLOCK_SIZE 4 -#define B8_SIZE 8 -#define MB_BLOCK_SIZE 16 - -#define BLOCK_MULTIPLE (MB_BLOCK_SIZE/(BLOCK_SIZE*2)) - -#define DECODE_COPY_MB 0 -#define DECODE_MB 1 - -#define NO_INTRA_PMODE 5 -#define INTRA_PMODE_4x4 10 -#define NO_INTRA_PMODE_4x4 19 -/* 8x8 intra prediction modes */ -#define VERT_PRED 0 -#define HOR_PRED 1 -#define DC_PRED 2 -#define DOWN_LEFT_PRED 3 -#define DOWN_RIGHT_PRED 4 - -#define VERT_PRED_4x4 0 -#define HOR_PRED_4x4 1 -#define DC_PRED_4x4 2 -#define DOWN_LEFT_PRED_4x4 3 -#define DOWN_RIGHT_PRED_4x4 4 - -#define HOR_DOWN_PRED_4x4 5 -#define VERT_LEFT_PRED_4x4 6 -#define HOR_UP_PRED_4x4 7 -#define VERT_RIGHT_PRED_4x4 8 - -#define DC_PRED_8 0 -#define HOR_PRED_8 1 -#define VERT_PRED_8 2 -#define PLANE_8 3 - -#define LUMA_16DC 0 -#define LUMA_16AC 1 -#define LUMA_8x8 2 -#define LUMA_8x4 3 -#define LUMA_4x8 4 -#define LUMA_4x4 5 -#define CHROMA_DC 6 -#define CHROMA_AC 7 -#define NUM_BLOCK_TYPES 8 - -#define I_PICTURE_START_CODE 0xB3 -#define PB_PICTURE_START_CODE 0xB6 -#define SLICE_START_CODE_MIN 0x00 -#define SLICE_START_CODE_MAX 0xAF -#define USER_DATA_START_CODE 0xB2 -#define SEQUENCE_HEADER_CODE 0xB0 -#define EXTENSION_START_CODE 0xB5 -#define SEQUENCE_END_CODE 0xB1 -#define VIDEO_EDIT_CODE 0xB7 - -#define EOS 1 -#define SOP 2 -#define SOS 3 -#define P8x8 8 -#define I8MB 9 -#define I4MB 10 -#define IBLOCK 11 -#define SI4MB 12 -#define MAXMODE 13 - -#define IS_INTRA(MB) ((MB)->mb_type == I8MB || (MB)->mb_type == I4MB) -#define IS_NEWINTRA(MB) ((MB)->mb_type == I4MB) -#define IS_OLDINTRA(MB) ((MB)->mb_type == I8MB) -#define IS_INTER(MB) ((MB)->mb_type != I8MB && (MB)->mb_type != I4MB) -#define IS_INTERMV(MB) ((MB)->mb_type != I8MB && (MB)->mb_type != I4MB\ - && (MB)->mb_type != 0) - -#define IS_DIRECT(MB) ((MB)->mb_type == 0 && (img->type == B_IMG)) -#define IS_COPY(MB) ((MB)->mb_type == 0 && (img->type == P_IMG)) -#define IS_P8x8(MB) ((MB)->mb_type == P8x8) - -#define P_IMG 0 -#define B_IMG 1 -#define I_IMG 2 - -#define FIELD 0 -#define FRAME 1 - -#define SE_CABP 21 -struct decoding_environment_s { - unsigned int dbuffer; - int dbits_to_go; - unsigned char *dcodestrm; - int *dcodestrm_len; -}; - -struct bi_context_type_s { - unsigned char MPS; - unsigned int LG_PMPS; - unsigned char cycno; -}; - - -/********************************************************************** - * C O N T E X T S F O R R M S Y N T A X E L E M E N T S - ********************************************************************** - */ - -#define NUM_MB_TYPE_CTX 11 -#define NUM_B8_TYPE_CTX 9 -#define NUM_MV_RES_CTX 10 -#define NUM_REF_NO_CTX 6 -#define NUM_DELTA_QP_CTX 4 -#define NUM_MB_AFF_CTX 4 - -struct motion_info_contexts_s { - struct bi_context_type_s mb_type_contexts[4][NUM_MB_TYPE_CTX]; - struct bi_context_type_s b8_type_contexts[2][NUM_B8_TYPE_CTX]; - struct bi_context_type_s mv_res_contexts[2][NUM_MV_RES_CTX]; - struct bi_context_type_s ref_no_contexts[2][NUM_REF_NO_CTX]; - struct bi_context_type_s delta_qp_contexts[NUM_DELTA_QP_CTX]; - struct bi_context_type_s mb_aff_contexts[NUM_MB_AFF_CTX]; -#ifdef TEST_WEIGHTING_AEC -struct bi_context_type_s mb_weighting_pred; -#endif -}; - -#define NUM_IPR_CTX 2 -#define NUM_CIPR_CTX 4 -#define NUM_CBP_CTX 4 -#define NUM_BCBP_CTX 4 -#define NUM_MAP_CTX 16 -#define NUM_LAST_CTX 16 - -#define NUM_ONE_CTX 5 -#define NUM_ABS_CTX 5 - -struct texture_info_contexts { - struct bi_context_type_s ipr_contexts[NUM_IPR_CTX]; - struct bi_context_type_s cipr_contexts[NUM_CIPR_CTX]; - struct bi_context_type_s cbp_contexts[3][NUM_CBP_CTX]; - struct bi_context_type_s bcbp_contexts[NUM_BLOCK_TYPES][NUM_BCBP_CTX]; - struct bi_context_type_s one_contexts[NUM_BLOCK_TYPES][NUM_ONE_CTX]; - struct bi_context_type_s abs_contexts[NUM_BLOCK_TYPES][NUM_ABS_CTX]; - struct bi_context_type_s fld_map_contexts[NUM_BLOCK_TYPES][NUM_MAP_CTX]; - struct bi_context_type_s fld_last_contexts - [NUM_BLOCK_TYPES][NUM_LAST_CTX]; - struct bi_context_type_s map_contexts[NUM_BLOCK_TYPES][NUM_MAP_CTX]; - struct bi_context_type_s last_contexts[NUM_BLOCK_TYPES][NUM_LAST_CTX]; -}; -struct img_par; - -struct syntaxelement { - int type; - int value1; - int value2; - int len; - int inf; - unsigned int bitpattern; - int context; - int k; - int golomb_grad; - int golomb_maxlevels; -#if TRACE -#define TRACESTRING_SIZE 100 - char tracestring[TRACESTRING_SIZE]; -#endif - - void (*mapping)(int len, int info, int *value1, int *value2); - - void (*reading)(struct syntaxelement *, struct img_par *, - struct decoding_environment_s *); - -}; - -struct bitstream_s { - - int read_len; - int code_len; - - int frame_bitoffset; - int bitstream_length; - - unsigned char *stream_buffer; -}; - -struct datapartition { - - struct bitstream_s *bitstream; - struct decoding_environment_s de_aec; - - int (*read_syntax_element)(struct syntaxelement *, struct img_par *, - struct datapartition *); -/*!< virtual function; - * actual method depends on chosen data partition and - * entropy coding method - */ -}; - -struct slice_s { - int picture_id; - int qp; - int picture_type; - int start_mb_nr; - int max_part_nr; - int num_mb; - - struct datapartition *part_arr; - struct motion_info_contexts_s *mot_ctx; - struct texture_info_contexts *tex_ctx; - int field_ctx[3][2]; -}; - -struct img_par { - int number; - int current_mb_nr; - int max_mb_nr; - int current_slice_nr; - int tr; - int qp; - int type; - - int typeb; - - int width; - int height; - int width_cr; - int height_cr; - int source_bitdepth; - int mb_y; - int mb_x; - int block_y; - int pix_y; - int pix_x; - int pix_c_y; - int block_x; - int pix_c_x; - - int ***mv; - int mpr[16][16]; - - int m7[16][16]; - int m8[/*2*/4][8][8]; - int cof[4][/*6*/8][4][4]; - int cofu[4]; - int **ipredmode; - int quad[256]; - int cod_counter; - - int ***dfmv; - int ***dbmv; - int **fw_reffrarr; - int **bw_reffrarr; - - int ***mv_frm; - int **fw_reffrarr_frm; - int **bw_reffrarr_frm; - int imgtr_next_p; - int imgtr_last_p; - int tr_frm; - int tr_fld; - int imgtr_last_prev_p; - - int no_forward_reference; - int seq_header_indicate; - int b_discard_flag; - - int ***fw_mv; - int ***bw_mv; - int subblock_x; - int subblock_y; - - int buf_cycle; - - int direct_type; - - int ***mv_top; - int ***mv_bot; - int **fw_reffrarr_top; - int **bw_reffrarr_top; - int **fw_reffrarr_bot; - int **bw_reffrarr_bot; - - int **ipredmode_top; - int **ipredmode_bot; - int ***fw_mv_top; - int ***fw_mv_bot; - int ***bw_mv_top; - int ***bw_mv_bot; - int ***dfmv_top; - int ***dbmv_top; - int ***dfmv_bot; - int ***dbm_bot; - - int toppoc; - int bottompoc; - int framepoc; - unsigned int frame_num; - - unsigned int pic_distance; - int delta_pic_order_cnt_bottom; - - signed int pic_distance_msb; - unsigned int prev_pic_distance_lsb; - signed int curr_pic_distance_msb; - unsigned int this_poc; - - int pic_width_inmbs; - int pic_height_inmbs; - int pic_size_inmbs; - - int block8_x, block8_y; - int structure; - int pn; - int buf_used; - int buf_size; - int picture_structure; - int advanced_pred_mode_disable; - int types; - int current_mb_nr_fld; - - int p_field_enhanced; - int b_field_enhanced; - - int slice_weighting_flag; - int lum_scale[4]; - int lum_shift[4]; - int chroma_scale[4]; - int chroma_shift[4]; - int mb_weighting_flag; - int weighting_prediction; - int mpr_weight[16][16]; - int top_bot; - int bframe_number; - - int auto_crop_right; - int auto_crop_bottom; - - struct slice_s *current_slice; - int is_v_block; - int is_intra_block; - - int new_seq_header_flag; - int new_sequence_flag; - int last_pic_bbv_delay; - - int sequence_end_flag; - int is_top_field; - - int abt_flag; - int qp_shift; - -#ifdef EIGHTH -int eighth_subpixel_flag; -int subpixel_precision; -int unit_length; -int subpixel_mask; - -int max_mvd; -int min_mvd; -#endif - -}; - -struct macroblock { - int qp; - int slice_nr; - int delta_quant; - struct macroblock *mb_available[3][3]; - /*!< pointer to neighboring MBs in a 3x3 window of current MB, - *which is located at [1][1] - * NULL pointer identifies neighboring MBs which are unavailable - */ - - int mb_type; - int mvd[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE][2]; - int cbp, cbp_blk, cbp01; - unsigned long cbp_bits; - - int b8mode[4]; - int b8pdir[4]; - int mb_type_2; - int c_ipred_mode_2; - int dct_mode; - - int c_ipred_mode; - int lf_disable; - int lf_alpha_c0_offset; - int lf_beta_offset; - - int CABT[4]; - int CABP[4]; - int cbp_4x4[4]; - - int skip_flag; - - struct macroblock *mb_available_up; - struct macroblock *mb_available_left; - unsigned int mbaddr_a, mbaddr_b, mbaddr_c, mbaddr_d; - unsigned int mbavail_a, mbavail_b, mbavail_c, mbavail_d; - -}; - -struct macroblock *mb_data; - -struct img_par *img; - -struct bitstream_s *curr_stream; - -struct datapartition *alloc_partition(int n); - -unsigned int vld_mem_start_addr; -unsigned int vld_mem_end_addr; - -int marker_bit; - -int progressive_sequence; -int horizontal_size; -int vertical_size; - -int second_ifield; -int pre_img_type; - -/* slice_header() */ -int slice_vertical_position; -int slice_vertical_position_extension; -int fixed_picture_qp; -int fixed_slice_qp; -int slice_qp; - -/* - ************************************************************************* - * Function:ue_v, reads an u(v) syntax element, the length in bits is stored in - the global UsedBits variable - * Input: - tracestring - the string for the trace file - bitstream - the stream to be read from - * Output: - * Return: the value of the coded syntax element - * Attention: - ************************************************************************* - */ -/*! - * definition of AVS syntaxelements - * order of elements follow dependencies for picture reconstruction - */ -/*! - * \brief Assignment of old TYPE partition elements to new - * elements - * - * old element | new elements - * TYPE_HEADER | SE_HEADER, SE_PTYPE - * TYPE_MBHEADER | SE_MBTYPE, SE_REFFRAME, SE_INTRAPREDMODE - * TYPE_MVD | SE_MVD - * TYPE_CBP | SE_CBP_INTRA, SE_CBP_INTER * SE_DELTA_QUANT_INTER - * SE_DELTA_QUANT_INTRA - * TYPE_COEFF_Y | SE_LUM_DC_INTRA, SE_LUM_AC_INTRA, - SE_LUM_DC_INTER, SE_LUM_AC_INTER - * TYPE_2x2DC | SE_CHR_DC_INTRA, SE_CHR_DC_INTER - * TYPE_COEFF_C | SE_CHR_AC_INTRA, SE_CHR_AC_INTER - * TYPE_EOS | SE_EOS - */ - -#define SE_HEADER 0 -#define SE_PTYPE 1 -#define SE_MBTYPE 2 -#define SE_REFFRAME 3 -#define SE_INTRAPREDMODE 4 -#define SE_MVD 5 -#define SE_CBP_INTRA 6 -#define SE_LUM_DC_INTRA 7 -#define SE_CHR_DC_INTRA 8 -#define SE_LUM_AC_INTRA 9 -#define SE_CHR_AC_INTRA 10 -#define SE_CBP_INTER 11 -#define SE_LUM_DC_INTER 12 -#define SE_CHR_DC_INTER 13 -#define SE_LUM_AC_INTER 14 -#define SE_CHR_AC_INTER 15 -#define SE_DELTA_QUANT_INTER 16 -#define SE_DELTA_QUANT_INTRA 17 -#define SE_BFRAME 18 -#define SE_EOS 19 -#define SE_MAX_ELEMENTS 20 -#define SE_CBP01 21 -int chroma_format; -/* - ************************************************************************* - * Function:Reads bits from the bitstream buffer - * Input: - byte buffer[] - containing VLC-coded data bits - int totbitoffset - bit offset from start of partition - int bytecount - total bytes in bitstream - int numbits - number of bits to read - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -int get_bits(unsigned char buffer[], int totbitoffset, int *info, int bytecount, - int numbits) -{ - register int inf; - long byteoffset; - int bitoffset; - - int bitcounter = numbits; - - byteoffset = totbitoffset / 8; - bitoffset = 7 - (totbitoffset % 8); - - inf = 0; - while (numbits) { - inf <<= 1; - inf |= (buffer[byteoffset] & (0x01 << bitoffset)) >> bitoffset; - numbits--; - bitoffset--; - if (bitoffset < 0) { - byteoffset++; - bitoffset += 8; - if (byteoffset > bytecount) - return -1; - } - } - - *info = inf; - - - return bitcounter; -} - -/* - ************************************************************************* - * Function:read FLC codeword from UVLC-partition - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -int read_syntaxelement_flc(struct syntaxelement *sym) -{ - int frame_bitoffset = curr_stream->frame_bitoffset; - unsigned char *buf = curr_stream->stream_buffer; - int bitstreamlengthinbytes = curr_stream->bitstream_length; - - if ((get_bits(buf, frame_bitoffset, &(sym->inf), bitstreamlengthinbytes, - sym->len)) < 0) - return -1; - - curr_stream->frame_bitoffset += sym->len; - sym->value1 = sym->inf; - -#if TRACE - tracebits2(sym->tracestring, sym->len, sym->inf); -#endif - - return 1; -} - -/* - ************************************************************************* - * Function:ue_v, reads an u(1) syntax element, the length in bits is stored in - the global UsedBits variable - * Input: - tracestring - the string for the trace file - bitstream - the stream to be read from - * Output: - * Return: the value of the coded syntax element - * Attention: - ************************************************************************* - */ -int u_1(char *tracestring) -{ - return u_v(1, tracestring); -} - -/* - ************************************************************************* - * Function:mapping rule for ue(v) syntax elements - * Input:length and info - * Output:number in the code table - * Return: - * Attention: - ************************************************************************* - */ -void linfo_ue(int len, int info, int *value1, int *dummy) -{ - *value1 = (int)pow2(2, (len / 2)) + info - 1; -} - -int u_v(int leninbits, char *tracestring) -{ - struct syntaxelement symbol, *sym = &symbol; - -#ifdef AVSP_LONG_CABAC -#else - assert(curr_stream->stream_buffer != NULL); -#endif - sym->type = SE_HEADER; - sym->mapping = linfo_ue; - sym->len = leninbits; - read_syntaxelement_flc(sym); - - return sym->inf; -} - -/* - ************************************************************************* - * Function:mapping rule for se(v) syntax elements - * Input:length and info - * Output:signed mvd - * Return: - * Attention: - ************************************************************************* - */ - -void linfo_se(int len, int info, int *value1, int *dummy) -{ - int n; - - n = (int)pow2(2, (len / 2)) + info - 1; - *value1 = (n + 1) / 2; - if ((n & 0x01) == 0) - *value1 = -*value1; - -} - -/* - ************************************************************************* - * Function:length and info - * Input: - * Output:cbp (intra) - * Return: - * Attention: - ************************************************************************* - */ - -void linfo_cbp_intra(int len, int info, int *cbp, int *dummy) -{ -} - -const int NCBP[64][2] = {{4, 0}, {16, 19}, {17, 16}, {19, 15}, {14, 18}, - {9, 11}, {22, 31}, {8, 13}, {11, 17}, {21, 30}, {10, 12}, - {7, 9}, {12, 10}, {6, 7}, {5, 8}, {1, 1}, {35, 4}, {47, 42}, { - 48, 38}, {38, 27}, {46, 39}, {36, 33}, {50, 59}, - {26, 26}, {45, 40}, {52, 58}, {41, 35}, {28, 25}, {37, 29}, {23, - 24}, {31, 28}, {2, 3}, {43, 5}, {51, 51}, {56, - 52}, {39, 37}, {55, 50}, {33, 43}, {62, 63}, { - 27, 44}, {54, 53}, {60, 62}, {40, 48}, {32, 47}, - {42, 34}, {24, 45}, {29, 49}, {3, 6}, {49, 14}, {53, 55}, {57, - 56}, {25, 36}, {58, 54}, {30, 41}, {59, 60}, { - 15, 21}, {61, 57}, {63, 61}, {44, 46}, {18, 22}, - {34, 32}, {13, 20}, {20, 23}, {0, 2} }; - -unsigned int s1, t1, value_s, value_t; -unsigned char dec_bypass, dec_final; - -#define get_byte() { \ - dbuffer = dcodestrm[(*dcodestrm_len)++];\ - dbits_to_go = 7; \ -} - -#define dbuffer (dep->dbuffer) -#define dbits_to_go (dep->dbits_to_go) -#define dcodestrm (dep->dcodestrm) -#define dcodestrm_len (dep->dcodestrm_len) - -#define B_BITS 10 - -#define LG_PMPS_SHIFTNO 2 - -#define HALF (1 << (B_BITS-1)) -#define QUARTER (1 << (B_BITS-2)) - -unsigned int biari_decode_symbol(struct decoding_environment_s *dep, - struct bi_context_type_s *bi_ct) -{ - register unsigned char bit; - register unsigned char s_flag; - register unsigned char is_lps = 0; - register unsigned char cwr; - register unsigned char cycno = bi_ct->cycno; - register unsigned int lg_pmps = bi_ct->LG_PMPS; - register unsigned int t_rlps; - register unsigned int s2, t2; - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & AEC_DUMP) - io_printf("LG_PMPS : %03X, MPS : %d, cycno : %d -- %p\n", - bi_ct->LG_PMPS, bi_ct->MPS, bi_ct->cycno, bi_ct); -#endif - - bit = bi_ct->MPS; - - cwr = (cycno <= 1) ? 3 : (cycno == 2) ? 4 : 5; - - if (t1 >= (lg_pmps >> LG_PMPS_SHIFTNO)) { - s2 = s1; - t2 = t1 - (lg_pmps >> LG_PMPS_SHIFTNO); - s_flag = 0; - } else { - s2 = s1 + 1; - t2 = 256 + t1 - (lg_pmps >> LG_PMPS_SHIFTNO); - s_flag = 1; - } - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & AEC_DUMP) - io_printf(" s2 : %d, t2 : %03X\n", s2, t2); -#endif - - if (s2 > value_s || (s2 == value_s && value_t >= t2)) { - is_lps = 1; - bit = !bit; - - t_rlps = (s_flag == 0) ? - (lg_pmps >> LG_PMPS_SHIFTNO) : - (t1 + (lg_pmps >> LG_PMPS_SHIFTNO)); - - if (s2 == value_s) - value_t = (value_t - t2); - else { - if (--dbits_to_go < 0) - get_byte(); - - value_t = (value_t << 1) - | ((dbuffer >> dbits_to_go) & 0x01); - value_t = 256 + value_t - t2; - - } - - while (t_rlps < QUARTER) { - t_rlps = t_rlps << 1; - if (--dbits_to_go < 0) - get_byte(); - - value_t = (value_t << 1) - | ((dbuffer >> dbits_to_go) & 0x01); - } - - s1 = 0; - t1 = t_rlps & 0xff; - - value_s = 0; - while (value_t < QUARTER) { - int j; - - if (--dbits_to_go < 0) - get_byte(); - j = (dbuffer >> dbits_to_go) & 0x01; - - value_t = (value_t << 1) | j; - value_s++; - } - value_t = value_t & 0xff; - } else { - - s1 = s2; - t1 = t2; - } - - if (dec_bypass) - return bit; - - if (is_lps) - cycno = (cycno <= 2) ? (cycno + 1) : 3; - else if (cycno == 0) - cycno = 1; - bi_ct->cycno = cycno; - - if (is_lps) { - switch (cwr) { - case 3: - lg_pmps = lg_pmps + 197; - break; - case 4: - lg_pmps = lg_pmps + 95; - break; - default: - lg_pmps = lg_pmps + 46; - } - - if (lg_pmps >= (256 << LG_PMPS_SHIFTNO)) { - lg_pmps = (512 << LG_PMPS_SHIFTNO) - 1 - lg_pmps; - bi_ct->MPS = !(bi_ct->MPS); - } - } else { -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & AEC_DUMP) - io_printf(" - lg_pmps_MPS : %X (%X - %X - %X)\n", - lg_pmps - (unsigned int)(lg_pmps>>cwr) - - (unsigned int)(lg_pmps>>(cwr+2)), - lg_pmps, - (unsigned int)(lg_pmps>>cwr), - (unsigned int)(lg_pmps>>(cwr+2)) - ); -#endif - lg_pmps = lg_pmps - (unsigned int)(lg_pmps >> cwr) - - (unsigned int)(lg_pmps >> (cwr + 2)); - } - - bi_ct->LG_PMPS = lg_pmps; - - return bit; -} - -unsigned int biari_decode_symbolw(struct decoding_environment_s *dep, - struct bi_context_type_s *bi_ct1, - struct bi_context_type_s *bi_ct2) -{ - register unsigned char bit1, bit2; - register unsigned char pred_mps, bit; - register unsigned int lg_pmps; - register unsigned char cwr1, cycno1 = bi_ct1->cycno; - register unsigned char cwr2, cycno2 = bi_ct2->cycno; - register unsigned int lg_pmps1 = bi_ct1->LG_PMPS; - register unsigned int lg_pmps2 = - bi_ct2->LG_PMPS; - register unsigned int t_rlps; - register unsigned char s_flag, is_lps = 0; - register unsigned int s2, t2; - - - bit1 = bi_ct1->MPS; - bit2 = bi_ct2->MPS; - - cwr1 = (cycno1 <= 1) ? 3 : (cycno1 == 2) ? 4 : 5; - cwr2 = (cycno2 <= 1) ? 3 : (cycno2 == 2) ? 4 : 5; - - if (bit1 == bit2) { - pred_mps = bit1; - lg_pmps = (lg_pmps1 + lg_pmps2) / 2; - } else { - if (lg_pmps1 < lg_pmps2) { - pred_mps = bit1; - lg_pmps = (256 << LG_PMPS_SHIFTNO) - 1 - - ((lg_pmps2 - lg_pmps1) >> 1); - } else { - pred_mps = bit2; - lg_pmps = (256 << LG_PMPS_SHIFTNO) - 1 - - ((lg_pmps1 - lg_pmps2) >> 1); - } - } - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & AEC_DUMP) - io_printf(" - Begin - LG_PMPS : %03X, MPS : %d\n", - lg_pmps, pred_mps); -#endif - if (t1 >= (lg_pmps >> LG_PMPS_SHIFTNO)) { - s2 = s1; - t2 = t1 - (lg_pmps >> LG_PMPS_SHIFTNO); - s_flag = 0; - } else { - s2 = s1 + 1; - t2 = 256 + t1 - (lg_pmps >> LG_PMPS_SHIFTNO); - s_flag = 1; - } - - bit = pred_mps; - if (s2 > value_s || (s2 == value_s && value_t >= t2)) { - is_lps = 1; - bit = !bit; - t_rlps = (s_flag == 0) ? - (lg_pmps >> LG_PMPS_SHIFTNO) : - (t1 + (lg_pmps >> LG_PMPS_SHIFTNO)); - - if (s2 == value_s) - value_t = (value_t - t2); - else { - if (--dbits_to_go < 0) - get_byte(); - - value_t = (value_t << 1) - | ((dbuffer >> dbits_to_go) & 0x01); - value_t = 256 + value_t - t2; - } - - while (t_rlps < QUARTER) { - t_rlps = t_rlps << 1; - if (--dbits_to_go < 0) - get_byte(); - - value_t = (value_t << 1) - | ((dbuffer >> dbits_to_go) & 0x01); - } - s1 = 0; - t1 = t_rlps & 0xff; - - value_s = 0; - while (value_t < QUARTER) { - int j; - - if (--dbits_to_go < 0) - get_byte(); - j = (dbuffer >> dbits_to_go) & 0x01; - - value_t = (value_t << 1) | j; - value_s++; - } - value_t = value_t & 0xff; - } else { - s1 = s2; - t1 = t2; - } - - if (bit != bit1) { - cycno1 = (cycno1 <= 2) ? (cycno1 + 1) : 3; - } else { - if (cycno1 == 0) - cycno1 = 1; - } - - if (bit != bit2) { - cycno2 = (cycno2 <= 2) ? (cycno2 + 1) : 3; - } else { - if (cycno2 == 0) - cycno2 = 1; - } - bi_ct1->cycno = cycno1; - bi_ct2->cycno = cycno2; - - { - - if (bit == bit1) { - lg_pmps1 = - lg_pmps1 - - (unsigned int)(lg_pmps1 - >> cwr1) - - (unsigned int)(lg_pmps1 - >> (cwr1 - + 2)); - } else { - switch (cwr1) { - case 3: - lg_pmps1 = lg_pmps1 + 197; - break; - case 4: - lg_pmps1 = lg_pmps1 + 95; - break; - default: - lg_pmps1 = lg_pmps1 + 46; - } - - if (lg_pmps1 >= (256 << LG_PMPS_SHIFTNO)) { - lg_pmps1 = (512 << LG_PMPS_SHIFTNO) - 1 - - lg_pmps1; - bi_ct1->MPS = !(bi_ct1->MPS); - } - } - bi_ct1->LG_PMPS = lg_pmps1; - - if (bit == bit2) { - lg_pmps2 = - lg_pmps2 - - (unsigned int)(lg_pmps2 - >> cwr2) - - (unsigned int)(lg_pmps2 - >> (cwr2 - + 2)); - } else { - switch (cwr2) { - case 3: - lg_pmps2 = lg_pmps2 + 197; - break; - case 4: - lg_pmps2 = lg_pmps2 + 95; - break; - default: - lg_pmps2 = lg_pmps2 + 46; - } - - if (lg_pmps2 >= (256 << LG_PMPS_SHIFTNO)) { - lg_pmps2 = (512 << LG_PMPS_SHIFTNO) - 1 - - lg_pmps2; - bi_ct2->MPS = !(bi_ct2->MPS); - } - } - bi_ct2->LG_PMPS = lg_pmps2; - } - - - return bit; -} - -/*! - ************************************************************************ - * \brief - * biari_decode_symbol_eq_prob(): - * \return - * the decoded symbol - ************************************************************************ - */ -unsigned int biari_decode_symbol_eq_prob(struct decoding_environment_s *dep) -{ - unsigned char bit; - struct bi_context_type_s octx; - struct bi_context_type_s *ctx = &octx; - - ctx->LG_PMPS = (QUARTER << LG_PMPS_SHIFTNO) - 1; - ctx->MPS = 0; - ctx->cycno = 0xfe; - dec_bypass = 1; - bit = biari_decode_symbol(dep, ctx); - dec_bypass = 0; - return bit; -} - -unsigned int biari_decode_final(struct decoding_environment_s *dep) -{ - unsigned char bit; - struct bi_context_type_s octx; - struct bi_context_type_s *ctx = &octx; - - ctx->LG_PMPS = 1 << LG_PMPS_SHIFTNO; - ctx->MPS = 0; - ctx->cycno = 0xff; - dec_final = 1; - bit = biari_decode_symbol(dep, ctx); - dec_final = 0; - return bit; -} - -int i_8(char *tracestring) -{ - int frame_bitoffset = curr_stream->frame_bitoffset; - unsigned char *buf = curr_stream->stream_buffer; - int bitstreamlengthinbytes = curr_stream->bitstream_length; - struct syntaxelement symbol, *sym = &symbol; -#ifdef AVSP_LONG_CABAC -#else - assert(curr_stream->stream_buffer != NULL); -#endif - - sym->len = 8; - sym->type = SE_HEADER; - sym->mapping = linfo_ue; - - if ((get_bits(buf, frame_bitoffset, &(sym->inf), bitstreamlengthinbytes, - sym->len)) < 0) - return -1; - curr_stream->frame_bitoffset += sym->len; - sym->value1 = sym->inf; - if (sym->inf & 0x80) - sym->inf = -(~((int)0xffffff00 | sym->inf) + 1); -#if TRACE - tracebits2(sym->tracestring, sym->len, sym->inf); -#endif - return sym->inf; -} - -/*! - ************************************************************************ - * \brief - * arideco_bits_read - ************************************************************************ - */ -int arideco_bits_read(struct decoding_environment_s *dep) -{ - - return 8 * ((*dcodestrm_len) - 1) + (8 - dbits_to_go); -} - -/*! - ************************************************************************ - * \brief - * arithmetic decoding - ************************************************************************ - */ -int read_syntaxelement_aec(struct syntaxelement *se, struct img_par *img, - struct datapartition *this_data_part) -{ - int curr_len; - struct decoding_environment_s *dep_dp = &(this_data_part->de_aec); - - curr_len = arideco_bits_read(dep_dp); - - se->reading(se, img, dep_dp); - - se->len = (arideco_bits_read(dep_dp) - curr_len); - return se->len; -} - -/*! - ************************************************************************ - * \brief - * This function is used to arithmetically decode the - * run length info of the skip mb - ************************************************************************ - */ -void readrunlenghtfrombuffer_aec(struct syntaxelement *se, struct img_par *img, - struct decoding_environment_s *dep_dp) -{ - struct bi_context_type_s *pctx; - int ctx, symbol; - - pctx = img->current_slice->tex_ctx->one_contexts[0]; - symbol = 0; - ctx = 0; - while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) { - symbol += 1; - ctx++; - if (ctx >= 3) - ctx = 3; - } - se->value1 = symbol; -#if TRACE - fprintf(p_trace, "@%d%s\t\t\t%d\n", - symbol_count++, se->tracestring, se->value1); - fflush(p_trace); -#endif -} - -/*! - ************************************************************************ - * \brief - * This function is used to arithmetically decode a pair of - * intra prediction modes of a given MB. - ************************************************************************ - */ -int mapd_intrap[5] = {0, 2, 3, 4, 1}; -void read_intrapredmode_aec(struct syntaxelement *se, struct img_par *img, - struct decoding_environment_s *dep_dp) -{ - struct bi_context_type_s *pctx; - int ctx, symbol; - - pctx = img->current_slice->tex_ctx->one_contexts[1]; - symbol = 0; - ctx = 0; -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & AEC_DUMP) - io_printf(" -- read_intrapredmode_aec ctx : %d\n", ctx); -#endif - while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) { - symbol += 1; - ctx++; - if (ctx >= 3) - ctx = 3; -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & AEC_DUMP) - io_printf(" -- read_intrapredmode_aec ctx : %d\n", ctx); -#endif - if (symbol == 4) - break; - } - se->value1 = mapd_intrap[symbol] - 1; - -#if TRACE - fprintf(p_trace, "@%d %s\t\t\t%d\n", - symbol_count++, se->tracestring, se->value1); - fflush(p_trace); -#endif -} - -/*! - ************************************************************************ - * \brief - * decoding of unary binarization using one or 2 distinct - * models for the first and all remaining bins; no terminating - * "0" for max_symbol - *********************************************************************** - */ -unsigned int unary_bin_max_decode(struct decoding_environment_s *dep_dp, - struct bi_context_type_s *ctx, - int ctx_offset, unsigned int max_symbol) -{ - unsigned int l; - unsigned int symbol; - struct bi_context_type_s *ictx; - - symbol = biari_decode_symbol(dep_dp, ctx); - - if (symbol == 0) - return 0; - - if (max_symbol == 1) - return symbol; - symbol = 0; - ictx = ctx + ctx_offset; - do { - l = biari_decode_symbol(dep_dp, ictx); - symbol++; - } while ((l != 0) && (symbol < max_symbol - 1)); - if ((l != 0) && (symbol == max_symbol - 1)) - symbol++; - return symbol; -} - -/*! - ************************************************************************ - * \brief - * decoding of unary binarization using one or 2 distinct - * models for the first and all remaining bins - *********************************************************************** - */ -unsigned int unary_bin_decode(struct decoding_environment_s *dep_dp, - struct bi_context_type_s *ctx, int ctx_offset) -{ - unsigned int l; - unsigned int symbol; - struct bi_context_type_s *ictx; - - symbol = 1 - biari_decode_symbol(dep_dp, ctx); - - if (symbol == 0) - return 0; - symbol = 0; - ictx = ctx + ctx_offset; - do { - l = 1 - biari_decode_symbol(dep_dp, ictx); - symbol++; - } while (l != 0); - return symbol; -} - -/*! - ************************************************************************ - * \brief - * This function is used to arithmetically decode the chroma - * intra prediction mode of a given MB. - ************************************************************************ - */ -void read_cipredmode_aec(struct syntaxelement *se, - struct img_par *img, - struct decoding_environment_s *dep_dp) -{ - struct texture_info_contexts *ctx = img->current_slice->tex_ctx; - struct macroblock *curr_mb = &mb_data[img->current_mb_nr]; - int act_ctx, a, b; - int act_sym = se->value1; - - if (curr_mb->mb_available_up == NULL) - b = 0; - else { - /*if ( (curr_mb->mb_available_up)->mb_type==IPCM) - * b=0; - * else - */ - b = (((curr_mb->mb_available_up)->c_ipred_mode != 0) ? 1 : 0); - } - - if (curr_mb->mb_available_left == NULL) - a = 0; - else { - /* if ( (curr_mb->mb_available_left)->mb_type==IPCM) - * a=0; - * else - */ - a = (((curr_mb->mb_available_left)->c_ipred_mode != 0) ? 1 : 0); - } - - act_ctx = a + b; - - - act_sym = biari_decode_symbol(dep_dp, ctx->cipr_contexts + act_ctx); - - if (act_sym != 0) - act_sym = unary_bin_max_decode(dep_dp, ctx->cipr_contexts + 3, - 0, 2) + 1; - - se->value1 = act_sym; - -#if TRACE - fprintf(p_trace, "@%d %s\t\t%d\n", - symbol_count++, se->tracestring, se->value1); - fflush(p_trace); -#endif - -} - -int slice_header(char *buf, int startcodepos, int length) -{ - int i; - - int weight_para_num = 0; - int mb_row; - int mb_column; - int mb_index; - int mb_width, mb_height; - - mb_column = 0; - - memcpy(curr_stream->stream_buffer, buf, length); - curr_stream->code_len = curr_stream->bitstream_length = length; - - curr_stream->read_len = - curr_stream->frame_bitoffset = (startcodepos) * 8; - slice_vertical_position = u_v(8, "slice vertical position"); - - push_es(slice_vertical_position, 8); - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & SLICE_INFO_DUMP) - io_printf(" * 8-bits slice_vertical_position : %d\n", - slice_vertical_position); -#endif - - if (vertical_size > 2800) { - slice_vertical_position_extension = u_v(3, - "slice vertical position extension"); - push_es(slice_vertical_position_extension, 3); - - } - - if (vertical_size > 2800) - mb_row = (slice_vertical_position_extension << 7) - + slice_vertical_position; - else - mb_row = slice_vertical_position; - - mb_width = (horizontal_size + 15) / 16; - if (!progressive_sequence) - mb_height = 2 * ((vertical_size + 31) / 32); - else - mb_height = (vertical_size + 15) / 16; - - - mb_index = mb_row * mb_width + mb_column; - - if (!img->picture_structure && img->type == I_IMG - && (mb_index >= mb_width * mb_height / 2)) { - second_ifield = 1; - img->type = P_IMG; - pre_img_type = P_IMG; - } - - { - if (!fixed_picture_qp) { - fixed_slice_qp = u_v(1, "fixed_slice_qp"); - push_es(fixed_slice_qp, 1); -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & SLICE_INFO_DUMP) - io_printf(" * 1-bit fixed_slice_qp : %d\n", - fixed_slice_qp); -#endif - slice_qp = u_v(6, "slice_qp"); - push_es(slice_qp, 6); -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & SLICE_INFO_DUMP) - io_printf(" * 6-bits slice_qp : %d\n", - slice_qp); -#endif - - img->qp = slice_qp; - } - - if (img->type != I_IMG) { - img->slice_weighting_flag = u_v(1, - "slice weighting flag"); - - if (img->slice_weighting_flag) { - - if (second_ifield && !img->picture_structure) - weight_para_num = 1; - else if (img->type == P_IMG - && img->picture_structure) - weight_para_num = 2; - else if (img->type == P_IMG - && !img->picture_structure) - weight_para_num = 4; - else if (img->type == B_IMG - && img->picture_structure) - weight_para_num = 2; - else if (img->type == B_IMG - && !img->picture_structure) - weight_para_num = 4; - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & SLICE_INFO_DUMP) - io_printf(" - weight_para_num : %d\n", - weight_para_num); -#endif - for (i = 0; i < weight_para_num; i++) { - img->lum_scale[i] = u_v(8, - "luma scale"); - - img->lum_shift[i] = i_8("luma shift"); - - marker_bit = u_1("insert bit"); - - - { - img->chroma_scale[i] = u_v(8, - "chroma scale"); - - img->chroma_shift[i] = i_8( - "chroma shift"); - - marker_bit = u_1("insert bit"); - - } - } - img->mb_weighting_flag = u_v(1, - "MB weighting flag"); - - } - } - } - - -#if 1 - return mb_index; -#endif -} - -void no_mem_exit(char *where) -{ - io_printf("%s\r\n", where); -} - -unsigned char bit[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; - -struct inputstream_s { - /*FILE *f;*/ - unsigned char buf[SVA_STREAM_BUF_SIZE]; - unsigned int uclear_bits; - unsigned int upre_3bytes; - int ibyte_position; - int ibuf_bytesnum; - int iclear_bitsnum; - int istuff_bitsnum; - int ibits_count; -}; - -struct inputstream_s IRABS; -struct inputstream_s *p_irabs = &IRABS; - -struct stat_bits { - int curr_frame_bits; - int prev_frame_bits; - int emulate_bits; - int prev_emulate_bits; - int last_unit_bits; - int bitrate; - int total_bitrate[1000]; - int coded_pic_num; - int time_s; -}; - -struct stat_bits *stat_bits_ptr; - -unsigned char *temp_slice_buf; -int start_codeposition; -int first_slice_length; -int first_slice_startpos; - -int bitstream_buf_used; -int startcode_offset; - -int bitstream_read_ptr; - -int demulate_enable; - -int last_dquant; - -int total_mb_count; - -int current_mb_skip; - -int skip_mode_flag; - -int current_mb_intra; - -/* - ************************************************************************* - * Function: Check start code's type - * Input: - * Output: - * Return: - * Author: XZHENG, 20080515 - ************************************************************************* - */ -void check_type(int startcode) -{ - startcode = startcode & 0x000000ff; - switch (startcode) { - case 0xb0: - case 0xb2: - case 0xb5: - demulate_enable = 0; - break; - default: - demulate_enable = 1; - break; - } - -} -/* - ************************************************************************* - * Function: - * Input: - * Output: - * Return: 0 : OK - -1 : arrive at stream end - -2 : meet another start code - * Attention: - ************************************************************************* - */ -int clear_nextbyte(struct inputstream_s *p) -{ - int i, k, j; - unsigned char temp[3]; - - i = p->ibyte_position; - k = p->ibuf_bytesnum - i; - if (k < 3) { - for (j = 0; j < k; j++) - temp[j] = p->buf[i + j]; - - p->ibuf_bytesnum = read_bitstream(p->buf + k, - SVA_STREAM_BUF_SIZE - k); - bitstream_buf_used++; - if (p->ibuf_bytesnum == 0) { - if (k > 0) { - while (k > 0) { - p->upre_3bytes = ((p->upre_3bytes << 8) - | p->buf[i]) - & 0x00ffffff; - if (p->upre_3bytes < 4 - && demulate_enable) { - p->uclear_bits = - (p->uclear_bits - << 6) - | (p->buf[i] - >> 2); - p->iclear_bitsnum += 6; - stat_bits_ptr->emulate_bits - += 2; - } else { - p->uclear_bits = (p->uclear_bits - << 8) - | p->buf[i]; - p->iclear_bitsnum += 8; - } - p->ibyte_position++; - k--; - i++; - } - return 0; - } else { - return -1; - } - } else { - for (j = 0; j < k; j++) - p->buf[j] = temp[j]; - p->ibuf_bytesnum += k; - i = p->ibyte_position = 0; - } - } - if (p->buf[i] == 0 && p->buf[i + 1] == 0 && p->buf[i + 2] == 1) - return -2; - p->upre_3bytes = ((p->upre_3bytes << 8) | p->buf[i]) & 0x00ffffff; - if (p->upre_3bytes < 4 && demulate_enable) { - p->uclear_bits = (p->uclear_bits << 6) | (p->buf[i] >> 2); - p->iclear_bitsnum += 6; - stat_bits_ptr->emulate_bits += 2; - } else { - p->uclear_bits = (p->uclear_bits << 8) | p->buf[i]; - p->iclear_bitsnum += 8; - } - p->ibyte_position++; - return 0; -} - -/* - ************************************************************************* - * Function: - * Input: - * Output: - * Return: 0 : OK - -1 : arrive at stream end - -2 : meet another start code - * Attention: - ************************************************************************* - */ -int read_n_bit(struct inputstream_s *p, int n, int *v) -{ - int r; - unsigned int t; - - while (n > p->iclear_bitsnum) { - r = clear_nextbyte(p); - if (r) { - if (r == -1) { - if (p->ibuf_bytesnum - p->ibyte_position > 0) - break; - } - return r; - } - } - t = p->uclear_bits; - r = 32 - p->iclear_bitsnum; - *v = (t << r) >> (32 - n); - p->iclear_bitsnum -= n; - return 0; -} - -#ifdef AVSP_LONG_CABAC -unsigned char TMP_BUF[2 * SVA_STREAM_BUF_SIZE]; -int tmp_buf_wr_ptr; -int tmp_buf_rd_ptr; -int tmp_buf_count; -#endif -void open_irabs(struct inputstream_s *p) -{ - p->uclear_bits = 0xffffffff; - p->ibyte_position = 0; - p->ibuf_bytesnum = 0; - p->iclear_bitsnum = 0; - p->istuff_bitsnum = 0; - p->ibits_count = 0; - p->upre_3bytes = 0; - - bitstream_buf_used = 0; - bitstream_read_ptr = (src_start - 16) & 0xfffffff0; - -#ifdef AVSP_LONG_CABAC - tmp_buf_count = 0; - tmp_buf_wr_ptr = 0; - tmp_buf_rd_ptr = 0; -#endif - -} - -void move_bitstream(unsigned int move_from_addr, unsigned int move_to_addr, - int move_size) -{ - int move_bytes_left = move_size; - unsigned int move_read_addr; - unsigned int move_write_addr = move_to_addr; - - int move_byte; - unsigned int data32; - - while (move_from_addr > vld_mem_end_addr) { - move_from_addr = move_from_addr + vld_mem_start_addr - - vld_mem_end_addr - 8; - } - move_read_addr = move_from_addr; - while (move_bytes_left > 0) { - move_byte = move_bytes_left; - if (move_byte > 512) - move_byte = 512; - if ((move_read_addr + move_byte) > vld_mem_end_addr) - move_byte = (vld_mem_end_addr + 8) - move_read_addr; - - WRITE_VREG(LMEM_DMA_ADR, move_read_addr); - WRITE_VREG(LMEM_DMA_COUNT, move_byte / 2); - WRITE_VREG(LMEM_DMA_CTRL, 0xc200); - - data32 = 0x8000; - while (data32 & 0x8000) - data32 = READ_VREG(LMEM_DMA_CTRL); - - WRITE_VREG(LMEM_DMA_ADR, move_write_addr); - WRITE_VREG(LMEM_DMA_COUNT, move_byte / 2); - WRITE_VREG(LMEM_DMA_CTRL, 0x8200); - - data32 = 0x8000; - while (data32 & 0x8000) - data32 = READ_VREG(LMEM_DMA_CTRL); - - data32 = 0x0fff; - while (data32 & 0x0fff) - data32 = READ_VREG(WRRSP_LMEM); - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & STREAM_INFO_DUMP) - io_printf(" 2 MOVE %d Bytes from 0x%x to 0x%x\n", - move_byte, move_read_addr, move_write_addr); -#endif - - move_read_addr = move_read_addr + move_byte; - if (move_read_addr > vld_mem_end_addr) - move_read_addr = vld_mem_start_addr; - move_write_addr = move_write_addr + move_byte; - move_bytes_left = move_bytes_left - move_byte; - } - -} - -int read_bitstream(unsigned char *buf, int size) -{ - int i; - -#ifdef AVSP_LONG_CABAC - - unsigned int *TMP_BUF_32 = (unsigned int *)bitstream_read_tmp; - - if (tmp_buf_count < size) { - dma_sync_single_for_cpu(amports_get_dma_device(), - bitstream_read_tmp_phy, SVA_STREAM_BUF_SIZE, - DMA_FROM_DEVICE); - - move_bitstream(bitstream_read_ptr, bitstream_read_tmp_phy, - SVA_STREAM_BUF_SIZE); - - for (i = 0; i < SVA_STREAM_BUF_SIZE / 8; i++) { - TMP_BUF[tmp_buf_wr_ptr++] = - (TMP_BUF_32[2 * i + 1] >> 24) & 0xff; - if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_wr_ptr = 0; - TMP_BUF[tmp_buf_wr_ptr++] = - (TMP_BUF_32[2 * i + 1] >> 16) & 0xff; - if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_wr_ptr = 0; - TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 1] >> 8) - & 0xff; - if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_wr_ptr = 0; - TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 1] >> 0) - & 0xff; - if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_wr_ptr = 0; - TMP_BUF[tmp_buf_wr_ptr++] = - (TMP_BUF_32[2 * i + 0] >> 24) & 0xff; - if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_wr_ptr = 0; - TMP_BUF[tmp_buf_wr_ptr++] = - (TMP_BUF_32[2 * i + 0] >> 16) & 0xff; - if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_wr_ptr = 0; - TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 0] >> 8) - & 0xff; - if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_wr_ptr = 0; - TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 0] >> 0) - & 0xff; - if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_wr_ptr = 0; - } - tmp_buf_count = tmp_buf_count + SVA_STREAM_BUF_SIZE; - bitstream_read_ptr = bitstream_read_ptr + SVA_STREAM_BUF_SIZE; - } - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & STREAM_INFO_DUMP) - io_printf(" Read %d bytes from %d, size left : %d\n", - size, tmp_buf_rd_ptr, tmp_buf_count); -#endif - for (i = 0; i < size; i++) { - buf[i] = TMP_BUF[tmp_buf_rd_ptr++]; - if (tmp_buf_rd_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_rd_ptr = 0; - } - tmp_buf_count = tmp_buf_count - size; - -#else - for (i = 0; i < size; i++) - buf[i] = tmp_stream[bitstream_read_ptr + i]; - bitstream_read_ptr = bitstream_read_ptr + size; -#endif - - return size; -} - -int next_startcode(struct inputstream_s *p) -{ - int i, m; - unsigned char a = 0, b = 0; - - m = 0; - - while (1) { - if (p->ibyte_position >= p->ibuf_bytesnum - 2) { - m = p->ibuf_bytesnum - p->ibyte_position; - if (m < 0) - return -2; - if (m == 1) - b = p->buf[p->ibyte_position + 1]; - if (m == 2) { - b = p->buf[p->ibyte_position + 1]; - a = p->buf[p->ibyte_position]; - } - p->ibuf_bytesnum = read_bitstream(p->buf, - SVA_STREAM_BUF_SIZE); - p->ibyte_position = 0; - bitstream_buf_used++; - } - - if (p->ibuf_bytesnum + m < 3) - return -1; - - if (m == 1 && b == 0 && p->buf[0] == 0 && p->buf[1] == 1) { - p->ibyte_position = 2; - p->iclear_bitsnum = 0; - p->istuff_bitsnum = 0; - p->ibits_count += 24; - p->upre_3bytes = 1; - return 0; - } - - if (m == 2 && b == 0 && a == 0 && p->buf[0] == 1) { - p->ibyte_position = 1; - p->iclear_bitsnum = 0; - p->istuff_bitsnum = 0; - p->ibits_count += 24; - p->upre_3bytes = 1; - return 0; - } - - if (m == 2 && b == 0 && p->buf[0] == 0 && p->buf[1] == 1) { - p->ibyte_position = 2; - p->iclear_bitsnum = 0; - p->istuff_bitsnum = 0; - p->ibits_count += 24; - p->upre_3bytes = 1; - return 0; - } - - for (i = p->ibyte_position; i < p->ibuf_bytesnum - 2; i++) { - if (p->buf[i] == 0 && p->buf[i + 1] == 0 - && p->buf[i + 2] == 1) { - p->ibyte_position = i + 3; - p->iclear_bitsnum = 0; - p->istuff_bitsnum = 0; - p->ibits_count += 24; - p->upre_3bytes = 1; - return 0; - } - p->ibits_count += 8; - } - p->ibyte_position = i; - } -} - -int get_oneunit(char *buf, int *startcodepos, int *length) -{ - int i, j, k; - - i = next_startcode(p_irabs); - - if (i != 0) { - if (i == -1) - io_printf( - "\narrive at stream end and start code is not found!"); - if (i == -2) - io_printf("\np->ibyte_position error!"); - - } - startcode_offset = - p_irabs->ibyte_position - - 3 + (bitstream_buf_used-1) - * SVA_STREAM_BUF_SIZE; - buf[0] = 0; - buf[1] = 0; - buf[2] = 1; - *startcodepos = 3; - i = read_n_bit(p_irabs, 8, &j); - buf[3] = (char)j; - - check_type(buf[3]); - if (buf[3] == SEQUENCE_END_CODE) { - *length = 4; - return -1; - } - k = 4; - while (1) { - i = read_n_bit(p_irabs, 8, &j); - if (i < 0) - break; - buf[k++] = (char)j; - if (k >= (MAX_CODED_FRAME_SIZE - 1)) - break; - } - if (p_irabs->iclear_bitsnum > 0) { - int shift; - - shift = 8 - p_irabs->iclear_bitsnum; - i = read_n_bit(p_irabs, p_irabs->iclear_bitsnum, &j); - - if (j != 0) - buf[k++] = (char)(j << shift); - stat_bits_ptr->last_unit_bits += shift; - } - *length = k; - return k; -} - -/*unsigned char tmp_buf[MAX_CODED_FRAME_SIZE] __attribute__ ((aligned(64)));*/ -/*unsigned char tmp_buf[MAX_CODED_FRAME_SIZE] __aligned(64);*/ -int header(void) -{ - unsigned char *buf; - int startcodepos, length; - - unsigned char *tmp_buf; - - tmp_buf = (unsigned char *)avsp_heap_adr; - - buf = &tmp_buf[0]; - while (1) { - start_codeposition = get_oneunit(buf, &startcodepos, &length); - - switch (buf[startcodepos]) { - case SEQUENCE_HEADER_CODE: - io_printf( - "# SEQUENCE_HEADER_CODE (0x%02x) found at offset %d (0x%x)\n", - buf[startcodepos], startcode_offset, - startcode_offset); - break; - case EXTENSION_START_CODE: - io_printf( - "# EXTENSION_START_CODE (0x%02x) found at offset %d (0x%x)\n", - buf[startcodepos], startcode_offset, - startcode_offset); - break; - case USER_DATA_START_CODE: - io_printf( - "# USER_DATA_START_CODE (0x%02x) found at offset %d (0x%x)\n", - buf[startcodepos], startcode_offset, - startcode_offset); - break; - case VIDEO_EDIT_CODE: - io_printf( - "# VIDEO_EDIT_CODE (0x%02x) found at offset %d (0x%x)\n", - buf[startcodepos], startcode_offset, - startcode_offset); - break; - case I_PICTURE_START_CODE: - io_printf( - "# I_PICTURE_START_CODE (0x%02x) found at offset %d (0x%x)\n", - buf[startcodepos], startcode_offset, - startcode_offset); - break; - case PB_PICTURE_START_CODE: - io_printf( - "# PB_PICTURE_START_CODE (0x%02x) found at offset %d (0x%x)\n", - buf[startcodepos], startcode_offset, - startcode_offset); - break; - case SEQUENCE_END_CODE: - io_printf( - "# SEQUENCE_END_CODE (0x%02x) found at offset %d (0x%x)\n", - buf[startcodepos], startcode_offset, - startcode_offset); - break; - default: - io_printf( - "# SLICE_START_CODE (0x%02x) found at offset %d (0x%x)\n", - buf[startcodepos], startcode_offset, - startcode_offset); -#if 0 - io_printf("VLD_MEM_VIFIFO_START_PTR %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_START_PTR)); - io_printf("VLD_MEM_VIFIFO_CURR_PTR %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_CURR_PTR)); - io_printf("VLD_MEM_VIFIFO_END_PTR %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_END_PTR)); - io_printf("VLD_MEM_VIFIFO_WP %x\r\n" - READ_VREG(VLD_MEM_VIFIFO_WP)); - io_printf("VLD_MEM_VIFIFO_RP %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_RP)); - io_printf("VLD_MEM_VBUF_RD_PTR %x\r\n" - READ_VREG(VLD_MEM_VBUF_RD_PTR)); - io_printf("VLD_MEM_VIFIFO_BUF_CNTL %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL)); - io_printf("PARSER_VIDEO_HOLE %x\r\n", - READ_MPEG_REG(PARSER_VIDEO_HOLE)); -#endif - if ((buf[startcodepos] >= SLICE_START_CODE_MIN - && buf[startcodepos] - <= SLICE_START_CODE_MAX) - && ((!img->seq_header_indicate) - || (img->type == B_IMG - && img->b_discard_flag - == 1 - && !img->no_forward_reference))) { - break; - } else if (buf[startcodepos] >= SLICE_START_CODE_MIN) { - - first_slice_length = length; - first_slice_startpos = startcodepos; - - temp_slice_buf = &tmp_buf[0]; - return SOP; - } else { - io_printf("Can't find start code"); - return -EOS; - } - } - } - -} - -/* - ************************************************************************* - * Function:Allocates a Bitstream - * Input: - * Output:allocated Bitstream point - * Return: - * Attention: - ************************************************************************* - */ -struct bitstream_s *alloc_bitstream(void) -{ - struct bitstream_s *bitstream; - - bitstream = (struct bitstream_s *)local_alloc(1, - sizeof(struct bitstream_s)); - if (bitstream == NULL) { - io_printf( - "AllocBitstream: Memory allocation for Bitstream failed"); - return NULL; - } - bitstream->stream_buffer = (unsigned char *)local_alloc( - MAX_CODED_FRAME_SIZE, - sizeof(unsigned char)); - if (bitstream->stream_buffer == NULL) { - io_printf( - "AllocBitstream: Memory allocation for streamBuffer failed"); - return NULL; - } - - return bitstream; -} - -void biari_init_context_logac(struct bi_context_type_s *ctx) -{ - ctx->LG_PMPS = (QUARTER << LG_PMPS_SHIFTNO) - 1; - ctx->MPS = 0; - ctx->cycno = 0; -} - -#define BIARI_CTX_INIT1_LOG(jj, ctx)\ -{\ - for (j = 0; j < jj; j++)\ - biari_init_context_logac(&(ctx[j]));\ -} - -#define BIARI_CTX_INIT2_LOG(ii, jj, ctx)\ -{\ - for (i = 0; i < ii; i++)\ - for (j = 0; j < jj; j++)\ - biari_init_context_logac(&(ctx[i][j]));\ -} - -#define BIARI_CTX_INIT3_LOG(ii, jj, kk, ctx)\ -{\ - for (i = 0; i < ii; i++)\ - for (j = 0; j < jj; j++)\ - for (k = 0; k < kk; k++)\ - biari_init_context_logac(&(ctx[i][j][k]));\ -} - -#define BIARI_CTX_INIT4_LOG(ii, jj, kk, ll, ctx)\ -{\ - for (i = 0; i < ii; i++)\ - for (j = 0; j < jj; j++)\ - for (k = 0; k < kk; k++)\ - for (l = 0; l < ll; l++)\ - biari_init_context_logac\ - (&(ctx[i][j][k][l]));\ -} - -void init_contexts(struct img_par *img) -{ - struct motion_info_contexts_s *mc = img->current_slice->mot_ctx; - struct texture_info_contexts *tc = img->current_slice->tex_ctx; - int i, j; - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & SLICE_INFO_DUMP) - io_printf(" ---- init_contexts ----\n"); -#endif - - BIARI_CTX_INIT2_LOG(3, NUM_MB_TYPE_CTX, mc->mb_type_contexts); - BIARI_CTX_INIT2_LOG(2, NUM_B8_TYPE_CTX, mc->b8_type_contexts); - BIARI_CTX_INIT2_LOG(2, NUM_MV_RES_CTX, mc->mv_res_contexts); - BIARI_CTX_INIT2_LOG(2, NUM_REF_NO_CTX, mc->ref_no_contexts); - BIARI_CTX_INIT1_LOG(NUM_DELTA_QP_CTX, mc->delta_qp_contexts); - BIARI_CTX_INIT1_LOG(NUM_MB_AFF_CTX, mc->mb_aff_contexts); - - BIARI_CTX_INIT1_LOG(NUM_IPR_CTX, tc->ipr_contexts); - BIARI_CTX_INIT1_LOG(NUM_CIPR_CTX, tc->cipr_contexts); - BIARI_CTX_INIT2_LOG(3, NUM_CBP_CTX, tc->cbp_contexts); - BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_BCBP_CTX, tc->bcbp_contexts); - BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_ONE_CTX, tc->one_contexts); - BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_ABS_CTX, tc->abs_contexts); - BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_MAP_CTX, tc->fld_map_contexts); - BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_LAST_CTX, - tc->fld_last_contexts); - BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_MAP_CTX, tc->map_contexts); - BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_LAST_CTX, tc->last_contexts); -#ifdef TEST_WEIGHTING_AEC - biari_init_context_logac(&mc->mb_weighting_pred); -#endif -} - -/*! - ************************************************************************ - * \brief - * Allocation of contexts models for the motion info - * used for arithmetic decoding - * - ************************************************************************ - */ -struct motion_info_contexts_s *create_contexts_motioninfo(void) -{ - struct motion_info_contexts_s *deco_ctx; - - deco_ctx = (struct motion_info_contexts_s *)local_alloc(1, - sizeof(struct motion_info_contexts_s)); - if (deco_ctx == NULL) - no_mem_exit("create_contexts_motioninfo: deco_ctx"); - - return deco_ctx; -} - -/*! - ************************************************************************ - * \brief - * Allocates of contexts models for the texture info - * used for arithmetic decoding - ************************************************************************ - */ -struct texture_info_contexts *create_contexts_textureinfo(void) -{ - struct texture_info_contexts *deco_ctx; - - deco_ctx = (struct texture_info_contexts *)local_alloc(1, - sizeof(struct texture_info_contexts)); - if (deco_ctx == NULL) - no_mem_exit("create_contexts_textureinfo: deco_ctx"); - - return deco_ctx; -} - -struct datapartition *alloc_partition(int n) -{ - struct datapartition *part_arr, *datapart; - int i; - - part_arr = - (struct datapartition *)local_alloc(n, sizeof(struct datapartition)); - if (part_arr == NULL) { - no_mem_exit( - "alloc_partition: Memory allocation for Data Partition failed"); - return NULL; - } - -#if LIWR_FIX - part_arr[0].bitstream = NULL; -#else - for (i = 0; i < n; i++) { - datapart = &(part_arr[i]); - datapart->bitstream = (struct bitstream_s *)local_alloc(1, - sizeof(struct bitstream_s)); - if (datapart->bitstream == NULL) { - no_mem_exit( - "alloc_partition: Memory allocation for Bitstream failed"); - return NULL; - } - } -#endif - return part_arr; -} - -int malloc_slice(struct img_par *img) -{ - struct slice_s *currslice; - - img->current_slice = - (struct slice_s *)local_alloc(1, sizeof(struct slice_s)); - currslice = img->current_slice; - if (currslice == NULL) { - no_mem_exit( - "Memory allocation for struct slice_s datastruct Failed" - ); - return 0; - } - if (1) { - - currslice->mot_ctx = create_contexts_motioninfo(); - if (currslice->mot_ctx == NULL) - return 0; - - currslice->tex_ctx = create_contexts_textureinfo(); - if (currslice->tex_ctx == NULL) - return 0; - } -#if LIWR_FIX - currslice->max_part_nr = 1; -#else - currslice->max_part_nr = 3; -#endif - currslice->part_arr = alloc_partition(currslice->max_part_nr); - if (currslice->part_arr == NULL) - return 0; - return 1; -} - -void init(struct img_par *img) -{ - int i; - - for (i = 0; i < 256; i++) - img->quad[i] = i * i; -} - -/* - ************************************************************************* - * Function:Allocate 2D memory array -> int array2D[rows][columns] - * Input: - * Output: memory size in bytes - * Return: - * Attention: - ************************************************************************* - */ - -int get_mem2Dint(int ***array2D, int rows, int columns) -{ - int i; - - *array2D = (int **)local_alloc(rows, sizeof(int *)); - if (*array2D == NULL) { - no_mem_exit("get_mem2Dint: array2D"); - return -1; - } - (*array2D)[0] = (int *)local_alloc(rows * columns, sizeof(int)); - if ((*array2D)[0] == NULL) { - no_mem_exit("get_mem2Dint: array2D"); - return -1; - } - - for (i = 1; i < rows; i++) - (*array2D)[i] = (*array2D)[i - 1] + columns; - - return rows * columns * sizeof(int); -} - -int initial_decode(void) -{ - int i, j; - int ret; - int img_height = (vertical_size + img->auto_crop_bottom); - int memory_size = 0; - - ret = malloc_slice(img); - if (ret == 0) - return 0; - - mb_data = (struct macroblock *)local_alloc( - (img->width / MB_BLOCK_SIZE) - * (img_height /*vertical_size*/ - / MB_BLOCK_SIZE), sizeof(struct macroblock)); - if (mb_data == NULL) { - no_mem_exit("init_global_buffers: mb_data"); - return 0; - } - - if (progressive_sequence) { - int size; - size = get_mem2Dint(&(img->ipredmode), - img->width / B8_SIZE * 2 + 4, - vertical_size / B8_SIZE * 2 + 4); - if (size == -1) - return 0; - - memory_size += size; - } else { - int size; - size = get_mem2Dint(&(img->ipredmode), - img->width / B8_SIZE * 2 + 4, - (vertical_size + 32) / (2 * B8_SIZE) * 4 + 4); - if (size == -1) - return 0; - - memory_size += size; - } - - for (i = 0; i < img->width / (B8_SIZE) * 2 + 4; i++) { - for (j = 0; j < img->height / (B8_SIZE) * 2 + 4; j++) - img->ipredmode[i][j] = -1; - } - - init(img); - img->number = 0; - img->type = I_IMG; - img->imgtr_last_p = 0; - img->imgtr_next_p = 0; - - img->new_seq_header_flag = 1; - img->new_sequence_flag = 1; - - return 1; -} - -void aec_new_slice(void) -{ - last_dquant = 0; -} - -/*! - ************************************************************************ - * \brief - * Initializes the DecodingEnvironment for the arithmetic coder - ************************************************************************ - */ - -void arideco_start_decoding(struct decoding_environment_s *dep, - unsigned char *cpixcode, - int firstbyte, int *cpixcode_len, int slice_type) -{ - - dcodestrm = cpixcode; - dcodestrm_len = cpixcode_len; - *dcodestrm_len = firstbyte; - - s1 = 0; - t1 = QUARTER - 1; - value_s = 0; - - value_t = 0; - - { - int i; - - dbits_to_go = 0; - for (i = 0; i < B_BITS - 1; i++) { - if (--dbits_to_go < 0) - get_byte(); - - value_t = (value_t << 1) - | ((dbuffer >> dbits_to_go) & 0x01); - } - } - - while (value_t < QUARTER) { - if (--dbits_to_go < 0) - get_byte(); - - value_t = (value_t << 1) | ((dbuffer >> dbits_to_go) & 0x01); - value_s++; - } - value_t = value_t & 0xff; - - dec_final = dec_bypass = 0; - - - -} - -/* - ************************************************************************* - * Function:Checks the availability of neighboring macroblocks of - the current macroblock for prediction and context determination; - marks the unavailable MBs for intra prediction in the - ipredmode-array by -1. Only neighboring MBs in the causal - past of the current MB are checked. - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -void checkavailabilityofneighbors(struct img_par *img) -{ - int i, j; - const int mb_width = img->width / MB_BLOCK_SIZE; - const int mb_nr = img->current_mb_nr; - struct macroblock *curr_mb = &mb_data[mb_nr]; - int check_value; - int remove_prediction; - - curr_mb->mb_available_up = NULL; - curr_mb->mb_available_left = NULL; - - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - mb_data[mb_nr].mb_available[i][j] = NULL; - - mb_data[mb_nr].mb_available[1][1] = curr_mb; - - if (img->pix_x >= MB_BLOCK_SIZE) { - remove_prediction = curr_mb->slice_nr - != mb_data[mb_nr - 1].slice_nr; - - if (remove_prediction) - - { - - img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y - + 1) * 2] = -1; - img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y - + 1) * 2 + 1] = -1; - img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y - + 2) * 2] = -1; - img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y - + 2) * 2 + 1] = -1; - } - if (!remove_prediction) - curr_mb->mb_available[1][0] = &(mb_data[mb_nr - 1]); - - } - - check_value = (img->pix_y >= MB_BLOCK_SIZE); - if (check_value) { - remove_prediction = curr_mb->slice_nr - != mb_data[mb_nr - mb_width].slice_nr; - - if (remove_prediction) { - img->ipredmode - [(img->block_x + 1) * 2][(img->block_y + 1) - * 2 - 1] = -1; - img->ipredmode[(img->block_x + 1) * 2 + 1][(img->block_y - + 1) * 2 - 1] = -1; - img->ipredmode[(img->block_x + 1) * 2 + 2][(img->block_y - + 1) * 2 - 1] = -1; - img->ipredmode[(img->block_x + 1) * 2 + 3][(img->block_y - + 1) * 2 - 1] = -1; - } - - if (!remove_prediction) { - curr_mb->mb_available[0][1] = - &(mb_data[mb_nr - mb_width]); - } - } - - if (img->pix_y >= MB_BLOCK_SIZE && img->pix_x >= MB_BLOCK_SIZE) { - remove_prediction = curr_mb->slice_nr - != mb_data[mb_nr - mb_width - 1].slice_nr; - - if (remove_prediction) { - img->ipredmode[img->block_x * 2 + 1][img->block_y * 2 - + 1] = -1; - } - if (!remove_prediction) { - curr_mb->mb_available[0][0] = &(mb_data[mb_nr - mb_width - - 1]); - } - } - - if (img->pix_y >= MB_BLOCK_SIZE - && img->pix_x < (img->width - MB_BLOCK_SIZE)) { - if (curr_mb->slice_nr == mb_data[mb_nr - mb_width + 1].slice_nr) - curr_mb->mb_available[0][2] = &(mb_data[mb_nr - mb_width - + 1]); - } - - if (1) { - curr_mb->mbaddr_a = mb_nr - 1; - curr_mb->mbaddr_b = mb_nr - img->pic_width_inmbs; - curr_mb->mbaddr_c = mb_nr - img->pic_width_inmbs + 1; - curr_mb->mbaddr_d = mb_nr - img->pic_width_inmbs - 1; - - curr_mb->mbavail_a = - (curr_mb->mb_available[1][0] != NULL) ? 1 : 0; - curr_mb->mbavail_b = - (curr_mb->mb_available[0][1] != NULL) ? 1 : 0; - curr_mb->mbavail_c = - (curr_mb->mb_available[0][2] != NULL) ? 1 : 0; - curr_mb->mbavail_d = - (curr_mb->mb_available[0][0] != NULL) ? 1 : 0; - - } - -} - -void checkavailabilityofneighborsaec(void) -{ - - int i, j; - const int mb_width = img->width / MB_BLOCK_SIZE; - const int mb_nr = img->current_mb_nr; - struct macroblock *curr_mb = &(mb_data[mb_nr]); - int check_value; - - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - mb_data[mb_nr].mb_available[i][j] = NULL; - mb_data[mb_nr].mb_available[1][1] = &(mb_data[mb_nr]); - - if (img->pix_x >= MB_BLOCK_SIZE) { - int remove_prediction = curr_mb->slice_nr - != mb_data[mb_nr - 1].slice_nr; - if (!remove_prediction) - curr_mb->mb_available[1][0] = &(mb_data[mb_nr - 1]); - } - - check_value = (img->pix_y >= MB_BLOCK_SIZE); - if (check_value) { - int remove_prediction = curr_mb->slice_nr - != mb_data[mb_nr - mb_width].slice_nr; - - if (!remove_prediction) { - curr_mb->mb_available[0][1] = - &(mb_data[mb_nr - mb_width]); - } - } - - if (img->pix_y >= MB_BLOCK_SIZE && img->pix_x >= MB_BLOCK_SIZE) { - int remove_prediction = curr_mb->slice_nr - != mb_data[mb_nr - mb_width - 1].slice_nr; - if (!remove_prediction) { - curr_mb->mb_available[0][0] = &(mb_data[mb_nr - mb_width - - 1]); - } - } - - if (img->pix_y >= MB_BLOCK_SIZE - && img->pix_x < (img->width - MB_BLOCK_SIZE)) { - if (curr_mb->slice_nr == mb_data[mb_nr - mb_width + 1].slice_nr) - curr_mb->mb_available[0][2] = &(mb_data[mb_nr - mb_width - + 1]); - } - curr_mb->mb_available_left = curr_mb->mb_available[1][0]; - curr_mb->mb_available_up = curr_mb->mb_available[0][1]; - curr_mb->mbaddr_a = mb_nr - 1; - curr_mb->mbaddr_b = mb_nr - img->pic_width_inmbs; - curr_mb->mbaddr_c = mb_nr - img->pic_width_inmbs + 1; - curr_mb->mbaddr_d = mb_nr - img->pic_width_inmbs - 1; - - curr_mb->mbavail_a = (curr_mb->mb_available[1][0] != NULL) ? 1 : 0; - curr_mb->mbavail_b = (curr_mb->mb_available[0][1] != NULL) ? 1 : 0; - curr_mb->mbavail_c = (curr_mb->mb_available[0][2] != NULL) ? 1 : 0; - curr_mb->mbavail_d = (curr_mb->mb_available[0][0] != NULL) ? 1 : 0; -} - -/* - ************************************************************************* - * Function:initializes the current macroblock - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -void start_macroblock(struct img_par *img) -{ - int i, j, k, l; - struct macroblock *curr_mb; - -#ifdef AVSP_LONG_CABAC -#else - -#endif - - curr_mb = &mb_data[img->current_mb_nr]; - - /* Update coordinates of the current macroblock */ - img->mb_x = (img->current_mb_nr) % (img->width / MB_BLOCK_SIZE); - img->mb_y = (img->current_mb_nr) / (img->width / MB_BLOCK_SIZE); - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & MB_NUM_DUMP) - io_printf(" #Begin MB : %d, (%x, %x) es_ptr %d\n", - img->current_mb_nr, img->mb_x, img->mb_y, es_ptr); -#endif - - - total_mb_count = total_mb_count + 1; - - /* Define vertical positions */ - img->block_y = img->mb_y * BLOCK_SIZE / 2; /* luma block position */ - img->block8_y = img->mb_y * BLOCK_SIZE / 2; - img->pix_y = img->mb_y * MB_BLOCK_SIZE; /* luma macroblock position */ - if (chroma_format == 2) - img->pix_c_y = img->mb_y * - MB_BLOCK_SIZE; /* chroma macroblock position */ - else - img->pix_c_y = img->mb_y * - MB_BLOCK_SIZE / 2; /* chroma macroblock position */ - - /* Define horizontal positions */ - img->block_x = img->mb_x * BLOCK_SIZE / 2; /* luma block position */ - img->block8_x = img->mb_x * BLOCK_SIZE / 2; - img->pix_x = img->mb_x * MB_BLOCK_SIZE; /* luma pixel position */ - img->pix_c_x = img->mb_x * - MB_BLOCK_SIZE / 2; /* chroma pixel position */ - - checkavailabilityofneighbors(img); - - /*qp = img->qp; - curr_mb->mb_type = 0; - curr_mb->delta_quant = 0; - curr_mb->cbp = 0; - curr_mb->cbp_blk = 0; - curr_mb->c_ipred_mode = DC_PRED_8; - curr_mb->c_ipred_mode_2 = DC_PRED_8; - - for (l = 0; l < 2; l++) - for (j = 0; j < BLOCK_MULTIPLE; j++) - for (i = 0; i < BLOCK_MULTIPLE; i++) - for (k = 0; k < 2; k++) - curr_mb->mvd[l][j][i][k] = 0; - - curr_mb->cbp_bits = 0; - - for (j = 0; j < MB_BLOCK_SIZE; j++) - for (i = 0; i < MB_BLOCK_SIZE; i++) - img->m7[i][j] = 0; - - for (j = 0; j < 2 * BLOCK_SIZE; j++) - for (i = 0; i < 2 * BLOCK_SIZE; i++) { - img->m8[0][i][j] = 0; - img->m8[1][i][j] = 0; - img->m8[2][i][j] = 0; - img->m8[3][i][j] = 0; - } - - curr_mb->lf_disable = 1; - - img->weighting_prediction = 0; -} - -/* - ************************************************************************* - * Function:init macroblock I and P frames - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -void init_macroblock(struct img_par *img) -{ - int i, j; - - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - img->ipredmode[img->block_x * 2 + i + 2][img->block_y - * 2 + j + 2] = -1; - } - } - -} - -/* - ************************************************************************* - * Function:Interpret the mb mode for I-Frames - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -void interpret_mb_mode_i(struct img_par *img) -{ - int i; - - struct macroblock *curr_mb = &mb_data[img->current_mb_nr]; - int num = 4; - - curr_mb->mb_type = I8MB; - - - current_mb_intra = 1; - - for (i = 0; i < 4; i++) { - curr_mb->b8mode[i] = IBLOCK; - curr_mb->b8pdir[i] = -1; - } - - for (i = num; i < 4; i++) { - curr_mb->b8mode[i] = - curr_mb->mb_type_2 == P8x8 ? - 4 : curr_mb->mb_type_2; - curr_mb->b8pdir[i] = 0; - } -} - -const int pred_4x4[9][9] = {{0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 1, 1, 1, 1, 1, - 1, 1}, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {0, 0, 0, 3, 3, 3, 3, 3, 3}, - {0, 1, 4, 4, 4, 4, 4, 4, 4}, {0, 1, 5, 5, 5, 5, 5, 5, 5}, {0, 0, - 0, 0, 0, 0, 6, 0, 0}, - {0, 1, 7, 7, 7, 7, 7, 7, 7}, {0, 0, 0, 0, 4, 5, 6, 7, 8} - -}; - -const int pred_4x4to8x8[9] = {0, 1, 2, 3, 4, 1, 0, 1, 0 - -}; - -const int pred_8x8to4x4[5] = {0, 1, 2, 3, 4}; - -void read_ipred_block_modes(struct img_par *img, int b8) -{ - int bi, bj, dec; - struct syntaxelement curr_se; - struct macroblock *curr_mb; - int j2; - int mostprobableintrapredmode; - int upintrapredmode; - int uprightintrapredmode; - int leftintrapredmode; - int leftdownintrapredmode; - int intrachromapredmodeflag; - - struct slice_s *currslice = img->current_slice; - struct datapartition *dp; - - curr_mb = mb_data + img->current_mb_nr; - intrachromapredmodeflag = IS_INTRA(curr_mb); - - curr_se.type = SE_INTRAPREDMODE; -#if TRACE - strncpy(curr_se.tracestring, "Ipred Mode", TRACESTRING_SIZE); -#endif - - if (b8 < 4) { - if (curr_mb->b8mode[b8] == IBLOCK) { - intrachromapredmodeflag = 1; - - if (1) { - dp = &(currslice->part_arr[0]); - curr_se.reading = read_intrapredmode_aec; - dp->read_syntax_element(&curr_se, img, dp); - - if (curr_se.value1 == -1) - push_es(1, 1); - else - push_es(curr_se.value1, 3); - - - } - bi = img->block_x + (b8 & 1); - bj = img->block_y + (b8 / 2); - - upintrapredmode = img->ipredmode[(bi + 1) * 2][(bj) * 2 - + 1]; - uprightintrapredmode = - img->ipredmode[(bi + 1) * 2 + 1][(bj) - * 2 + 1]; - leftintrapredmode = - img->ipredmode[(bi) * 2 + 1][(bj + 1) - * 2]; - leftdownintrapredmode = img->ipredmode[(bi) * 2 + 1][(bj - + 1) * 2 + 1]; - - if ((upintrapredmode < 0) || (leftintrapredmode < 0)) { - mostprobableintrapredmode = DC_PRED; - } else if ((upintrapredmode < NO_INTRA_PMODE) - && (leftintrapredmode < - NO_INTRA_PMODE)) { - mostprobableintrapredmode = - upintrapredmode - < leftintrapredmode ? - upintrapredmode : - leftintrapredmode; - } else if (upintrapredmode < NO_INTRA_PMODE) { - mostprobableintrapredmode = upintrapredmode; - } else if (leftintrapredmode < NO_INTRA_PMODE) { - mostprobableintrapredmode = leftintrapredmode; - } else { - mostprobableintrapredmode = - pred_4x4[leftintrapredmode - - INTRA_PMODE_4x4][upintrapredmode - - INTRA_PMODE_4x4]; - mostprobableintrapredmode = - pred_4x4to8x8[mostprobableintrapredmode]; - } - - - - dec = - (curr_se.value1 == -1) ? - mostprobableintrapredmode : - curr_se.value1 - + (curr_se.value1 - >= mostprobableintrapredmode); - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & MB_INFO_DUMP) - io_printf(" - ipredmode[%d] : %d\n", b8, dec); -#endif - - img->ipredmode[(1 + bi) * 2][(1 + bj) * 2] = dec; - img->ipredmode[(1 + bi) * 2 + 1][(1 + bj) * 2] = dec; - img->ipredmode[(1 + bi) * 2][(1 + bj) * 2 + 1] = dec; - img->ipredmode[(1 + bi) * 2 + 1][(1 + bj) * 2 + 1] = - dec; - - j2 = bj; - } - } else if (b8 == 4 && curr_mb->b8mode[b8 - 3] == IBLOCK) { - - curr_se.type = SE_INTRAPREDMODE; -#if TRACE - strncpy(curr_se.tracestring, - "Chroma intra pred mode", TRACESTRING_SIZE); -#endif - - if (1) { - dp = &(currslice->part_arr[0]); - curr_se.reading = read_cipredmode_aec; - dp->read_syntax_element(&curr_se, img, dp); - } else - - { - } - curr_mb->c_ipred_mode = curr_se.value1; - - push_es(UE[curr_se.value1][0], UE[curr_se.value1][1]); - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & MB_INFO_DUMP) - io_printf(" * UE c_ipred_mode read : %d\n", - curr_mb->c_ipred_mode); -#endif - - if (curr_se.value1 < DC_PRED_8 || curr_se.value1 > PLANE_8) { -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & MB_INFO_DUMP) - io_printf("%d\n", img->current_mb_nr); -#endif - pr_info("illegal chroma intra pred mode!\n"); - } - } -} - -/*! - ************************************************************************ - * \brief - * This function is used to arithmetically decode the coded - * block pattern of a given MB. - ************************************************************************ - */ -void readcp_aec(struct syntaxelement *se, struct img_par *img, - struct decoding_environment_s *dep_dp) -{ - struct texture_info_contexts *ctx = img->current_slice->tex_ctx; - struct macroblock *curr_mb = &mb_data[img->current_mb_nr]; - - int mb_x, mb_y; - int a, b; - int curr_cbp_ctx, curr_cbp_idx; - int cbp = 0; - int cbp_bit; - int mask; - - for (mb_y = 0; mb_y < 4; mb_y += 2) { - for (mb_x = 0; mb_x < 4; mb_x += 2) { - if (curr_mb->b8mode[mb_y + (mb_x / 2)] == IBLOCK) - curr_cbp_idx = 0; - else - curr_cbp_idx = 1; - - if (mb_y == 0) { - if (curr_mb->mb_available_up == NULL) - b = 0; - else { - b = ((((curr_mb->mb_available_up)->cbp - & (1 << (2 + mb_x / 2))) - == 0) ? 1 : 0); - } - - } else - b = (((cbp & (1 << (mb_x / 2))) == 0) ? 1 : 0); - - if (mb_x == 0) { - if (curr_mb->mb_available_left == NULL) - a = 0; - else { - a = - ((((curr_mb->mb_available_left)->cbp - & (1 - << (2 - * (mb_y - / 2) - + 1))) - == 0) ? - 1 : 0); - } - } else - a = (((cbp & (1 << mb_y)) == 0) ? 1 : 0); - curr_cbp_ctx = a + 2 * b; - mask = (1 << (mb_y + mb_x / 2)); - cbp_bit = biari_decode_symbol(dep_dp, - ctx->cbp_contexts[0] + curr_cbp_ctx); - - if (cbp_bit) - cbp += mask; - } - } - curr_cbp_ctx = 0; - cbp_bit = biari_decode_symbol(dep_dp, - ctx->cbp_contexts[1] + curr_cbp_ctx); - - if (cbp_bit) { - curr_cbp_ctx = 1; - cbp_bit = biari_decode_symbol(dep_dp, - ctx->cbp_contexts[1] + curr_cbp_ctx); - if (cbp_bit) { - cbp += 48; - - } else { - curr_cbp_ctx = 1; - cbp_bit = biari_decode_symbol(dep_dp, - ctx->cbp_contexts[1] + curr_cbp_ctx); - cbp += (cbp_bit == 1) ? 32 : 16; - - } - } - - se->value1 = cbp; - if (!cbp) - last_dquant = 0; - - - -} - -/*! - ************************************************************************ - * \brief - * This function is used to arithmetically decode the delta qp - * of a given MB. - ************************************************************************ - */ -void readdquant_aec(struct syntaxelement *se, struct img_par *img, - struct decoding_environment_s *dep_dp) -{ - struct motion_info_contexts_s *ctx = img->current_slice->mot_ctx; - - int act_ctx; - int act_sym; - int dquant; - - - act_ctx = ((last_dquant != 0) ? 1 : 0); - - act_sym = 1 - - biari_decode_symbol(dep_dp, - ctx->delta_qp_contexts + act_ctx); - if (act_sym != 0) { - act_ctx = 2; - act_sym = unary_bin_decode(dep_dp, - ctx->delta_qp_contexts + act_ctx, 1); - act_sym++; - } - act_sym &= 0x3f; - push_es(UE[act_sym][0], UE[act_sym][1]); - - dquant = (act_sym + 1) / 2; - if ((act_sym & 0x01) == 0) - dquant = -dquant; - se->value1 = dquant; - - last_dquant = dquant; - -} - -int csyntax; - -#define CHECKDELTAQP {\ - if (img->qp+curr_mb->delta_quant > 63\ - || img->qp+curr_mb->delta_quant < 0) {\ - csyntax = 0;\ - transcoding_error_flag = 1;\ - io_printf("error(0) (%3d|%3d) @ MB%d\n",\ - curr_mb->delta_quant,\ - img->qp+curr_mb->delta_quant,\ - img->picture_structure == 0 \ - ? img->current_mb_nr_fld : img->current_mb_nr);\ - } } - -int dct_level[65]; -int dct_run[65]; -int pair_pos; -int dct_pairs = -1; -const int t_chr[5] = {0, 1, 2, 4, 3000}; - -void readrunlevel_aec_ref(struct syntaxelement *se, struct img_par *img, - struct decoding_environment_s *dep_dp) -{ - int pairs, rank, pos; - int run, level, abslevel, symbol; - int sign; - - if (dct_pairs < 0) { - struct bi_context_type_s (*primary)[NUM_MAP_CTX]; - struct bi_context_type_s *pctx; - struct bi_context_type_s *pCTX2; - int ctx, ctx2, offset; - - if (se->context == LUMA_8x8) { - if (img->picture_structure == 0) { - primary = - img->current_slice->tex_ctx->fld_map_contexts; - } else { - primary = - img->current_slice->tex_ctx->map_contexts; - } - } else { - if (img->picture_structure == 0) { - primary = - img->current_slice->tex_ctx->fld_last_contexts; - } else { - primary = - img->current_slice->tex_ctx->last_contexts; - } - } - - rank = 0; - pos = 0; - for (pairs = 0; pairs < 65; pairs++) { -#ifdef DECODING_SANITY_CHECK - /*max index is NUM_BLOCK_TYPES - 1*/ - pctx = primary[rank & 0x7]; -#else - pctx = primary[rank]; -#endif - if (rank > 0) { -#ifdef DECODING_SANITY_CHECK - /*max index is NUM_BLOCK_TYPES - 1*/ - pCTX2 = primary[(5 + (pos >> 5)) & 0x7]; -#else - pCTX2 = primary[5 + (pos >> 5)]; -#endif - ctx2 = (pos >> 1) & 0x0f; - ctx = 0; - - - if (biari_decode_symbolw(dep_dp, pctx + ctx, - pCTX2 + ctx2)) { - break; - } - } - - ctx = 1; - symbol = 0; - while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) { - symbol += 1; - ctx++; - if (ctx >= 2) - ctx = 2; - } - abslevel = symbol + 1; - - if (biari_decode_symbol_eq_prob(dep_dp)) { - level = -abslevel; - sign = 1; - } else { - level = abslevel; - sign = 0; - } -#if TRACE - tracebits2("level", 1, level); -#endif - - if (abslevel == 1) - offset = 4; - else - offset = 6; - symbol = 0; - ctx = 0; - while (biari_decode_symbol(dep_dp, pctx + ctx + offset) - == 0) { - symbol += 1; - ctx++; - if (ctx >= 1) - ctx = 1; - } - run = symbol; - -#if TRACE - tracebits2("run", 1, run); -#endif - dct_level[pairs] = level; - dct_run[pairs] = run; - if (abslevel > t_chr[rank]) { - if (abslevel <= 2) - rank = abslevel; - else if (abslevel <= 4) - rank = 3; - else - rank = 4; - } - pos += (run + 1); - if (pos >= 64) - pos = 63; - } - dct_pairs = pairs; - pair_pos = dct_pairs; - } - - if (dct_pairs > 0) { - se->value1 = dct_level[pair_pos - 1]; - se->value2 = dct_run[pair_pos - 1]; - pair_pos--; - } else { - - se->value1 = se->value2 = 0; - } - - if ((dct_pairs--) == 0) - pair_pos = 0; -} - -int b8_ctr; -#if 0 -int curr_residual_chroma[4][16][16]; -int curr_residual_luma[16][16]; -#endif - -const int SCAN[2][64][2] = {{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {0, 3}, {0, 4}, {1, - 1}, {1, 2}, {0, 5}, {0, 6}, {1, 3}, {2, 0}, {2, 1}, {0, 7}, {1, - 4}, {2, 2}, {3, 0}, {1, 5}, {1, 6}, {2, 3}, {3, 1}, {3, 2}, {4, - 0}, {1, 7}, {2, 4}, {4, 1}, {2, 5}, {3, 3}, {4, 2}, {2, 6}, {3, - 4}, {4, 3}, {5, 0}, {5, 1}, {2, 7}, {3, 5}, {4, 4}, {5, 2}, {6, - 0}, {5, 3}, {3, 6}, {4, 5}, {6, 1}, {6, 2}, {5, 4}, {3, 7}, {4, - 6}, {6, 3}, {5, 5}, {4, 7}, {6, 4}, {5, 6}, {6, 5}, {5, 7}, {6, - 6}, {7, 0}, {6, 7}, {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 5}, {7, - 6}, {7, 7} }, {{0, 0}, {1, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0}, { - 3, 0}, {2, 1}, {1, 2}, {0, 3}, {0, 4}, {1, 3}, {2, 2}, {3, 1}, { - 4, 0}, {5, 0}, {4, 1}, {3, 2}, {2, 3}, {1, 4}, {0, 5}, {0, 6}, { - 1, 5}, {2, 4}, {3, 3}, {4, 2}, {5, 1}, {6, 0}, {7, 0}, {6, 1}, { - 5, 2}, {4, 3}, {3, 4}, {2, 5}, {1, 6}, {0, 7}, {1, 7}, {2, 6}, { - 3, 5}, {4, 4}, {5, 3}, {6, 2}, {7, 1}, {7, 2}, {6, 3}, {5, 4}, { - 4, 5}, {3, 6}, {2, 7}, {3, 7}, {4, 6}, {5, 5}, {6, 4}, {7, 3}, { - 7, 4}, {6, 5}, {5, 6}, {4, 7}, {5, 7}, {6, 6}, {7, 5}, {7, 6}, { - 6, 7}, {7, 7} } }; - -const int SCAN_4x4[16][2] = {{0, 0}, {1, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0}, {3, - 0}, {2, 1}, {1, 2}, {0, 3}, {1, 3}, {2, 2}, {3, 1}, {3, 2}, {2, - 3}, {3, 3} }; - -/* - ************************************************************************* - * Function: - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -void encode_golomb_word(unsigned int symbol, unsigned int grad0, - unsigned int max_levels, unsigned int *res_bits, - unsigned int *res_len) -{ - unsigned int level, res, numbits; - - res = 1UL << grad0; - level = 1UL; - numbits = 1UL + grad0; - - while (symbol >= res && level < max_levels) { - symbol -= res; - res = res << 1; - level++; - numbits += 2UL; - } - - if (level >= max_levels) { - if (symbol >= res) - symbol = res - 1UL; - } - - *res_bits = res | symbol; - *res_len = numbits; -} - -/* - ************************************************************************* - * Function: - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -void encode_multilayer_golomb_word(unsigned int symbol, - const unsigned int *grad, const unsigned int *max_levels, - unsigned int *res_bits, unsigned int *res_len) -{ - unsigned int accbits, acclen, bits, len, tmp; - - accbits = acclen = 0UL; - - while (1) { - encode_golomb_word(symbol, *grad, *max_levels, &bits, &len); - accbits = (accbits << len) | bits; - acclen += len; -#ifdef AVSP_LONG_CABAC -#else - assert(acclen <= 32UL); -#endif - tmp = *max_levels - 1UL; - - if (!((len == (tmp << 1) + (*grad)) - && (bits == (1UL << (tmp + *grad)) - 1UL))) - break; - - tmp = *max_levels; - symbol -= (((1UL << tmp) - 1UL) << (*grad)) - 1UL; - grad++; - max_levels++; - } - *res_bits = accbits; - *res_len = acclen; -} - -/* - ************************************************************************* - * Function: - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -int writesyntaxelement_golomb(struct syntaxelement *se, int write_to_stream) -{ - unsigned int bits, len, i; - unsigned int grad[4], max_lev[4]; - - if (!(se->golomb_maxlevels & ~0xFF)) - encode_golomb_word(se->value1, se->golomb_grad, - se->golomb_maxlevels, &bits, &len); - else { - for (i = 0UL; i < 4UL; i++) { - grad[i] = (se->golomb_grad >> (i << 3)) & 0xFFUL; - max_lev[i] = (se->golomb_maxlevels >> (i << 3)) - & 0xFFUL; - } - encode_multilayer_golomb_word(se->value1, grad, max_lev, &bits, - &len); - } - - se->len = len; - se->bitpattern = bits; - - if (write_to_stream) - push_es(bits, len); - return se->len; -} - -/* - ************************************************************************* - * Function:Get coded block pattern and coefficients (run/level) - from the bitstream - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -void read_cbpandcoeffsfrom_nal(struct img_par *img) -{ - - int tablenum; - int inumblk; - int inumcoeff; - int symbol2D; - int escape_level_diff; - const int (*AVS_2DVLC_table_intra)[26][27]; - const int (*AVS_2DVLC_table_chroma)[26][27]; - int write_to_stream; - struct syntaxelement currse_enc; - struct syntaxelement *e_currse = &currse_enc; - - int coeff_save[65][2]; - int coeff_ptr; - - int ii, jj; - int mb_nr = img->current_mb_nr; - - int m2, jg2; - struct macroblock *curr_mb = &mb_data[mb_nr]; - - int block8x8; - - int block_x, block_y; - - struct slice_s *currslice = img->current_slice; - int level, run, coef_ctr, len, k, i0, j0, uv, qp; - - int boff_x, boff_y, start_scan; - struct syntaxelement curr_se; - struct datapartition *dp; - - AVS_2DVLC_table_intra = AVS_2DVLC_INTRA; - AVS_2DVLC_table_chroma = AVS_2DVLC_CHROMA; - write_to_stream = 1; - - dct_pairs = -1; - - curr_mb->qp = img->qp; - qp = curr_mb->qp; - - - for (block_y = 0; block_y < 4; block_y += 2) {/* all modes */ - for (block_x = 0; block_x < 4; block_x += 2) { - block8x8 = 2 * (block_y / 2) + block_x / 2; - if (curr_mb->cbp & (1 << block8x8)) { - tablenum = 0; - inumblk = 1; - inumcoeff = 65; - coeff_save[0][0] = 0; - coeff_save[0][1] = 0; - coeff_ptr = 1; - - b8_ctr = block8x8; - - boff_x = (block8x8 % 2) << 3; - boff_y = (block8x8 / 2) << 3; - - img->subblock_x = boff_x >> 2; - img->subblock_y = boff_y >> 2; - - start_scan = 0; - coef_ctr = start_scan - 1; - level = 1; - img->is_v_block = 0; - img->is_intra_block = IS_INTRA(curr_mb); - for (k = start_scan; - (k < 65) && (level != 0); - k++) { - - curr_se.context = LUMA_8x8; - curr_se.type = - (IS_INTRA(curr_mb)) ? - SE_LUM_AC_INTRA : - SE_LUM_AC_INTER; - - dp = &(currslice->part_arr[0]); - curr_se.reading = - readrunlevel_aec_ref; - dp-> - read_syntax_element(&curr_se, - img, dp); - level = curr_se.value1; - run = curr_se.value2; - len = curr_se.len; - - if (level != 0) { - coeff_save[coeff_ptr][0] = - run; - coeff_save[coeff_ptr][1] = - level; - coeff_ptr++; - } - - - - if (level != 0) {/* leave if len = 1 */ - coef_ctr += run + 1; - if ((img->picture_structure - == FRAME)) { - ii = - SCAN[img->picture_structure] - [coef_ctr][0]; - jj = - SCAN[img->picture_structure] - [coef_ctr][1]; - } else { - ii = - SCAN[img->picture_structure] - [coef_ctr][0]; - jj = - SCAN[img->picture_structure] - [coef_ctr][1]; - } - - } - } - - while (coeff_ptr > 0) { - run = - coeff_save[coeff_ptr - - 1][0]; - level = - coeff_save[coeff_ptr - - 1][1]; - - coeff_ptr--; - - symbol2D = CODE2D_ESCAPE_SYMBOL; - if (level > -27 && level < 27 - && run < 26) { - if (tablenum == 0) - - symbol2D = - AVS_2DVLC_table_intra - [tablenum] - [run][abs( - level) - - 1]; - else - - symbol2D = - AVS_2DVLC_table_intra - [tablenum] - [run][abs( - level)]; - if (symbol2D >= 0 - && level - < 0) - symbol2D++; - if (symbol2D < 0) - - symbol2D = - (CODE2D_ESCAPE_SYMBOL - + (run - << 1) - + ((level - > 0) ? - 1 : - 0)); - } - - else { - - symbol2D = - (CODE2D_ESCAPE_SYMBOL - + (run - << 1) - + ((level - > 0) ? - 1 : - 0)); - } - - - - e_currse->type = SE_LUM_AC_INTER; - e_currse->value1 = symbol2D; - e_currse->value2 = 0; - - e_currse->golomb_grad = - vlc_golomb_order - [0][tablenum][0]; - e_currse->golomb_maxlevels = - vlc_golomb_order - [0][tablenum][1]; - - writesyntaxelement_golomb( - e_currse, - write_to_stream); - - if (symbol2D - >= CODE2D_ESCAPE_SYMBOL) { - - e_currse->type = - SE_LUM_AC_INTER; - e_currse->golomb_grad = - 1; - e_currse->golomb_maxlevels = - 11; - escape_level_diff = - abs( - level) - - ((run - > MaxRun[0][tablenum]) ? - 1 : - refabslevel[tablenum][run]); - e_currse->value1 = - escape_level_diff; - - writesyntaxelement_golomb( - e_currse, - write_to_stream); - - } - - if (abs(level) - > incvlc_intra[tablenum]) { - if (abs(level) <= 2) - tablenum = - abs( - level); - else if (abs(level) <= 4) - tablenum = 3; - else if (abs(level) <= 7) - tablenum = 4; - else if (abs(level) - <= 10) - tablenum = 5; - else - tablenum = 6; - } - } - - - } - } - } - - - - m2 = img->mb_x * 2; - jg2 = img->mb_y * 2; - - - uv = -1; - block_y = 4; -#if 0 - qp = QP_SCALE_CR[curr_mb->qp]; -#endif - for (block_x = 0; block_x < 4; block_x += 2) { - - uv++; - - - b8_ctr = (uv + 4); - if ((curr_mb->cbp >> (uv + 4)) & 0x1) { - - tablenum = 0; - inumblk = 1; - inumcoeff = 65; - coeff_save[0][0] = 0; - coeff_save[0][1] = 0; - coeff_ptr = 1; - - coef_ctr = -1; - level = 1; - img->subblock_x = 0; - img->subblock_y = 0; - curr_se.context = CHROMA_AC; - curr_se.type = (IS_INTRA(curr_mb) ? - SE_CHR_AC_INTRA : - SE_CHR_AC_INTER); - dp = &(currslice->part_arr[0]); - curr_se.reading = readrunlevel_aec_ref; - img->is_v_block = uv; - img->is_intra_block = IS_INTRA(curr_mb); - for (k = 0; (k < 65) && (level != 0); k++) { - - dp->read_syntax_element - (&curr_se, img, dp); - level = curr_se.value1; - run = curr_se.value2; - len = curr_se.len; - - if (level != 0) { - coeff_save[coeff_ptr][0] = run; - coeff_save[coeff_ptr][1] = - level; - coeff_ptr++; - } - - - if (level != 0) { - coef_ctr = coef_ctr + run + 1; - if ((img->picture_structure - == FRAME) - /*&& (!curr_mb->mb_field)*/) { - i0 = - SCAN[img->picture_structure] - [coef_ctr][0]; - j0 = - SCAN[img->picture_structure] - [coef_ctr][1]; - } else { - i0 = - SCAN[img->picture_structure] - [coef_ctr][0]; - j0 = - SCAN[img->picture_structure] - [coef_ctr][1]; - } - - } - } - - while (coeff_ptr > 0) { - - run = coeff_save[coeff_ptr - 1][0]; - level = coeff_save[coeff_ptr - 1][1]; - - coeff_ptr--; - - symbol2D = CODE2D_ESCAPE_SYMBOL; - if (level > -27 && level < 27 - && run < 26) { - if (tablenum == 0) - - symbol2D = - AVS_2DVLC_table_chroma - [tablenum][run][abs( - level) - - 1]; - else - symbol2D = - AVS_2DVLC_table_chroma - [tablenum][run][abs( - level)]; - if (symbol2D >= 0 - && level < 0) - symbol2D++; - if (symbol2D < 0) - symbol2D = - (CODE2D_ESCAPE_SYMBOL - + (run - << 1) - + ((level - > 0) ? - 1 : - 0)); - } - - else { - symbol2D = - (CODE2D_ESCAPE_SYMBOL - + (run - << 1) - + ((level - > 0) ? - 1 : - 0)); - } - - e_currse->type = SE_LUM_AC_INTER; - e_currse->value1 = symbol2D; - e_currse->value2 = 0; - e_currse->golomb_grad = - vlc_golomb_order[2] - [tablenum][0]; - e_currse->golomb_maxlevels = - vlc_golomb_order[2] - [tablenum][1]; - - writesyntaxelement_golomb(e_currse, - write_to_stream); - - /* - * if (write_to_stream) - * { - * bitCount[BITS_COEFF_UV_MB]+=e_currse->len; - * e_currse++; - * curr_mb->currSEnr++; - * } - * no_bits+=e_currse->len; - - - * if (icoef == 0) break; - */ - - if (symbol2D >= CODE2D_ESCAPE_SYMBOL) { - - e_currse->type = SE_LUM_AC_INTER; - e_currse->golomb_grad = 0; - e_currse->golomb_maxlevels = 11; - escape_level_diff = - abs(level) - - ((run - > MaxRun[2][tablenum]) ? - 1 : - refabslevel[tablenum - + 14][run]); - e_currse->value1 = - escape_level_diff; - - writesyntaxelement_golomb( - e_currse, - write_to_stream); - - } - - if (abs(level) - > incvlc_chroma[tablenum]) { - if (abs(level) <= 2) - tablenum = abs(level); - else if (abs(level) <= 4) - tablenum = 3; - else - tablenum = 4; - } - } - - } - } -} - -/* - ************************************************************************* - * Function:Get the syntax elements from the NAL - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -int read_one_macroblock(struct img_par *img) -{ - int i, j; - - struct syntaxelement curr_se; - struct macroblock *curr_mb = &mb_data[img->current_mb_nr]; - - int cabp_flag; - - int tempcbp; - int fixqp; - - struct slice_s *currslice = img->current_slice; - struct datapartition *dp; - - fixqp = (fixed_picture_qp || fixed_slice_qp); - - for (i = 0; i < 8; i++) - for (j = 0; j < 8; j++) { - img->m8[0][i][j] = 0; - img->m8[1][i][j] = 0; - img->m8[2][i][j] = 0; - img->m8[3][i][j] = 0; - } - - current_mb_skip = 0; - - curr_mb->qp = img->qp; - curr_se.type = SE_MBTYPE; - curr_se.mapping = linfo_ue; - - curr_mb->mb_type_2 = 0; - - if (img->type == I_IMG) - curr_mb->mb_type = 0; - - interpret_mb_mode_i(img); - - init_macroblock(img); - - if ((IS_INTRA(curr_mb)) && (img->abt_flag)) { - -#if TRACE - strncpy(curr_se.tracestring, "cabp_flag", TRACESTRING_SIZE); -#endif - - curr_se.len = 1; - curr_se.type = SE_CABP; - read_syntaxelement_flc(&curr_se); - cabp_flag = curr_se.value1; - if (cabp_flag == 0) { - curr_mb->CABP[0] = 0; - curr_mb->CABP[1] = 0; - curr_mb->CABP[2] = 0; - curr_mb->CABP[3] = 0; - } else { - for (i = 0; i < 4; i++) { - curr_se.len = 1; - curr_se.type = SE_CABP; - read_syntaxelement_flc(&curr_se); - curr_mb->CABP[i] = curr_se.value1; - } - } - - } else { - curr_mb->CABP[0] = 0; - curr_mb->CABP[1] = 0; - curr_mb->CABP[2] = 0; - curr_mb->CABP[3] = 0; - - } - - if (IS_INTRA(curr_mb)) { - for (i = 0; i < /*5*/(chroma_format + 4); i++) - - read_ipred_block_modes(img, i); - } - - curr_se.type = SE_CBP_INTRA; - curr_se.mapping = linfo_cbp_intra; - -#if TRACE - snprintf(curr_se.tracestring, TRACESTRING_SIZE, "CBP"); -#endif - - if (img->type == I_IMG || IS_INTER(curr_mb)) { - curr_se.golomb_maxlevels = 0; - - if (1) { - dp = &(currslice->part_arr[0]); - curr_se.reading = readcp_aec; - dp->read_syntax_element(&curr_se, img, dp); - } - - - curr_mb->cbp = curr_se.value1; - push_es(UE[NCBP[curr_se.value1][0]][0], - UE[NCBP[curr_se.value1][0]][1]); - - } - -# if 1 - if (curr_mb->cbp != 0) - tempcbp = 1; - else - tempcbp = 0; -#else - - if (chroma_format == 2) { -#if TRACE - snprintf(curr_se.tracestring, TRACESTRING_SIZE, "CBP422"); -#endif - curr_se.mapping = /*linfo_se*/linfo_ue; - curr_se.type = SE_CBP_INTRA; - readsyntaxelement_uvlc(&curr_se, inp); - curr_mb->cbp01 = curr_se.value1; - io_printf(" * UE cbp01 read : 0x%02X\n", curr_mb->cbp01); - } - - if (chroma_format == 2) { - if (curr_mb->cbp != 0 || curr_mb->cbp01 != 0) - tempcbp = 1; - else - tempcbp = 0; - - } else { - if (curr_mb->cbp != 0) - tempcbp = 1; - else - tempcbp = 0; - } - -#endif - - if (IS_INTRA(curr_mb) && (img->abt_flag) && (curr_mb->cbp & (0xF))) { - curr_mb->CABT[0] = curr_mb->CABP[0]; - curr_mb->CABT[1] = curr_mb->CABP[1]; - curr_mb->CABT[2] = curr_mb->CABP[2]; - curr_mb->CABT[3] = curr_mb->CABP[3]; - } else { - - curr_mb->CABT[0] = 0; - curr_mb->CABT[1] = 0; - curr_mb->CABT[2] = 0; - curr_mb->CABT[3] = 0; - - if (!fixqp && (tempcbp)) { - if (IS_INTER(curr_mb)) - curr_se.type = SE_DELTA_QUANT_INTER; - else - curr_se.type = SE_DELTA_QUANT_INTRA; - -#if TRACE - snprintf(curr_se.tracestring, - TRACESTRING_SIZE, "Delta quant "); -#endif - - if (1) { - dp = &(currslice->part_arr[0]); - curr_se.reading = readdquant_aec; - dp->read_syntax_element(&curr_se, img, dp); - } - - curr_mb->delta_quant = curr_se.value1; -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & MB_INFO_DUMP) { - io_printf(" * SE delta_quant read : %d\n", - curr_mb->delta_quant); - } -#endif - CHECKDELTAQP - - if (transcoding_error_flag) - return -1; - - img->qp = (img->qp - MIN_QP + curr_mb->delta_quant - + (MAX_QP - MIN_QP + 1)) - % (MAX_QP - MIN_QP + 1) + MIN_QP; - } - - if (fixqp) { - curr_mb->delta_quant = 0; - img->qp = (img->qp - MIN_QP + curr_mb->delta_quant - + (MAX_QP - MIN_QP + 1)) - % (MAX_QP - MIN_QP + 1) + MIN_QP; - - } -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & MB_INFO_DUMP) - io_printf(" - img->qp : %d\n", img->qp); -#endif - } - - read_cbpandcoeffsfrom_nal(img); - return DECODE_MB; -} - -/*! - ************************************************************************ - * \brief - * finding end of a slice in case this is not the end of a frame - * - * Unsure whether the "correction" below actually solves an off-by-one - * problem or whether it introduces one in some cases :-( Anyway, - * with this change the bit stream format works with AEC again. - * StW, 8.7.02 - ************************************************************************ - */ -int aec_startcode_follows(struct img_par *img, int eos_bit) -{ - struct slice_s *currslice = img->current_slice; - struct datapartition *dp; - unsigned int bit; - struct decoding_environment_s *dep_dp; - - dp = &(currslice->part_arr[0]); - dep_dp = &(dp->de_aec); - - if (eos_bit) - bit = biari_decode_final(dep_dp); - else - bit = 0; - - return bit == 1 ? 1 : 0; -} - -#ifdef AVSP_LONG_CABAC -int process_long_cabac(void) -#else -void main(void) -#endif -{ - int data32; - int current_header; - int i; - int tmp; - int ret; - - int byte_startposition; - int aec_mb_stuffing_bit; - struct slice_s *currslice; -#ifdef PERFORMANCE_DEBUG - pr_info("enter %s\r\n", __func__); -#endif - transcoding_error_flag = 0; - ret = 0; - es_buf = es_write_addr_virt; - - if (local_heap_init(MAX_CODED_FRAME_SIZE * 4) < 0) { - ret = -1; - goto End; - } - - img = (struct img_par *)local_alloc(1, sizeof(struct img_par)); - if (img == NULL) { - no_mem_exit("main: img"); - ret = -1; - goto End; - } - stat_bits_ptr = (struct stat_bits *)local_alloc(1, - sizeof(struct stat_bits)); - if (stat_bits_ptr == NULL) { - no_mem_exit("main: stat_bits"); - ret = -1; - goto End; - } - - curr_stream = alloc_bitstream(); - if (curr_stream == NULL) { - io_printf("alloc bitstream failed\n"); - ret = -1; - goto End; - } - - chroma_format = 1; - demulate_enable = 0; - img->seq_header_indicate = 1; - -#ifdef AVSP_LONG_CABAC - data32 = READ_VREG(LONG_CABAC_REQ); - progressive_sequence = (data32 >> 1) & 1; - fixed_picture_qp = (data32 >> 2) & 1; - img->picture_structure = (data32 >> 3) & 1; - img->type = (data32 >> 4) & 3; - skip_mode_flag = (data32 >> 6) & 1; - - src_start = READ_VREG(LONG_CABAC_SRC_ADDR); - des_start = READ_VREG(LONG_CABAC_DES_ADDR); - - data32 = READ_VREG(LONG_CABAC_PIC_SIZE); - horizontal_size = (data32 >> 0) & 0xffff; - vertical_size = (data32 >> 16) & 0xffff; - if (horizontal_size * vertical_size > 1920 * 1080) { - io_printf("pic size check failed: width = %d, height = %d\n", - horizontal_size, vertical_size); - ret = -1; - goto End; - } - - vld_mem_start_addr = READ_VREG(VLD_MEM_VIFIFO_START_PTR); - vld_mem_end_addr = READ_VREG(VLD_MEM_VIFIFO_END_PTR); - -#else - progressive_sequence = 0; - fixed_picture_qp = 0; - img->picture_structure = 0; - img->type = I_IMG; - skip_mode_flag = 1; - horizontal_size = 1920; - vertical_size = 1080; - - src_start = 0; -#endif - - if (horizontal_size % 16 != 0) - img->auto_crop_right = 16 - (horizontal_size % 16); - else - img->auto_crop_right = 0; - - if (!progressive_sequence) { - if (vertical_size % 32 != 0) - img->auto_crop_bottom = 32 - (vertical_size % 32); - else - img->auto_crop_bottom = 0; - } else { - if (vertical_size % 16 != 0) - img->auto_crop_bottom = 16 - (vertical_size % 16); - else - img->auto_crop_bottom = 0; - } - - img->width = (horizontal_size + img->auto_crop_right); - if (img->picture_structure) - img->height = (vertical_size + img->auto_crop_bottom); - else - img->height = (vertical_size + img->auto_crop_bottom) / 2; - img->width_cr = (img->width >> 1); - - img->pic_width_inmbs = img->width / MB_BLOCK_SIZE; - img->pic_height_inmbs = img->height / MB_BLOCK_SIZE; - img->pic_size_inmbs = img->pic_width_inmbs * img->pic_height_inmbs; - - io_printf( - "[LONG CABAC] Start Transcoding from 0x%x to 0x%x Size : %d x %d\r\n", - src_start, des_start, horizontal_size, vertical_size); -#if 0 - io_printf("VLD_MEM_VIFIFO_START_PTR %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_START_PTR)); - io_printf("VLD_MEM_VIFIFO_CURR_PTR %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_CURR_PTR)); - io_printf("VLD_MEM_VIFIFO_END_PTR %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_END_PTR)); - io_printf("VLD_MEM_VIFIFO_WP %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_WP)); - io_printf("VLD_MEM_VIFIFO_RP %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_RP)); - io_printf("VLD_MEM_VBUF_RD_PTR %x\r\n", - READ_VREG(VLD_MEM_VBUF_RD_PTR)); - io_printf("VLD_MEM_VIFIFO_BUF_CNTL %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL)); -#endif - io_printf( - "[LONG CABAC] progressive_sequence : %d, fixed_picture_qp : %d, skip_mode_flag : %d\r\n", - progressive_sequence, fixed_picture_qp, skip_mode_flag); - io_printf("[LONG CABAC] picture_structure : %d, picture_type : %d\r\n", - img->picture_structure, img->type); - - open_irabs(p_irabs); - - - if (initial_decode() == 0) { - io_printf("initial_decode failed\n"); - ret = -1; - goto End; - } - - init_es(); - - current_header = header(); - io_printf("[LONG CABAC] header Return : %d\n", current_header); - - tmp = slice_header(temp_slice_buf, first_slice_startpos, - first_slice_length); - - init_contexts(img); - aec_new_slice(); - byte_startposition = (curr_stream->frame_bitoffset) / 8; - - currslice = img->current_slice; - - if (1) { - for (i = 0; i < 1; i++) { - img->current_slice->part_arr[i].read_syntax_element = - read_syntaxelement_aec; - img->current_slice->part_arr[i].bitstream = curr_stream; - } - curr_stream = currslice->part_arr[0].bitstream; - } - if ((curr_stream->frame_bitoffset) % 8 != 0) - byte_startposition++; - - arideco_start_decoding(&img->current_slice->part_arr[0].de_aec, - curr_stream->stream_buffer, (byte_startposition), - &(curr_stream->read_len), img->type); - - img->current_mb_nr = 0; - total_mb_count = 0; - while (img->current_mb_nr < img->pic_size_inmbs) - - { - start_macroblock(img); - if (-1 == read_one_macroblock(img)) { - ret = -1; - pr_info("macroblock trans failed, exit\n"); - goto End; - } - if (img->cod_counter <= 0) - aec_mb_stuffing_bit = aec_startcode_follows(img, 1); - img->current_mb_nr++; - } - - push_es(0xff, 8); - io_printf(" Total ES_LENGTH : %d\n", es_ptr); - -#ifdef AVSP_LONG_CABAC - push_es(0xff, 64); - if (es_buf_is_overflow) { - io_printf("fatal error: es_buf_is_overflow\n"); - ret = -1; - goto End; - } - - if (transcoding_error_flag == 0) { -#if 1 - dma_sync_single_for_device(amports_get_dma_device(), - es_write_addr_phy, - es_ptr, DMA_TO_DEVICE); - - wmb(); /**/ -#endif - } -#else - fclose(f_es); -#endif - -End: -#ifdef AVSP_LONG_CABAC - WRITE_VREG(LONG_CABAC_REQ, 0); -#endif - local_heap_uninit(); -#ifdef PERFORMANCE_DEBUG - pr_info("exit %s\r\n", __func__); -#endif - return ret; -} -#endif diff --git a/drivers/frame_provider/decoder/h264/vh264.c b/drivers/frame_provider/decoder/h264/vh264.c index a6acc03..3470147 100644 --- a/drivers/frame_provider/decoder/h264/vh264.c +++ b/drivers/frame_provider/decoder/h264/vh264.c @@ -1680,55 +1680,55 @@ static void load_qos_data(int pic_number, uint32_t b_offset) node->min_mv = mv_lo; #endif +#ifdef DEBUG_QOS /* {mvy_L0_max, mvy_L0_min} */ rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); mv_hi = (rdata32>>16)&0xffff; if (mv_hi & 0x8000) mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS pr_info(" [Picture %d Quality] MVY_L0 MAX : %d\n", pic_number, mv_hi); -#endif + mv_lo = (rdata32>>0)&0xffff; if (mv_lo & 0x8000) mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS + pr_info(" [Picture %d Quality] MVY_L0 MIN : %d\n", pic_number, mv_lo); -#endif + /* {mvx_L1_max, mvx_L1_min} */ rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); mv_hi = (rdata32>>16)&0xffff; if (mv_hi & 0x8000) mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS + pr_info(" [Picture %d Quality] MVX_L1 MAX : %d\n", pic_number, mv_hi); -#endif + mv_lo = (rdata32>>0)&0xffff; if (mv_lo & 0x8000) mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS + pr_info(" [Picture %d Quality] MVX_L1 MIN : %d\n", pic_number, mv_lo); -#endif + /* {mvy_L1_max, mvy_L1_min} */ rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); mv_hi = (rdata32>>16)&0xffff; if (mv_hi & 0x8000) mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS + pr_info(" [Picture %d Quality] MVY_L1 MAX : %d\n", pic_number, mv_hi); -#endif + mv_lo = (rdata32>>0)&0xffff; if (mv_lo & 0x8000) mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS + pr_info(" [Picture %d Quality] MVY_L1 MIN : %d\n", pic_number, mv_lo); #endif @@ -2570,6 +2570,36 @@ static inline bool vh264_isr_parser(struct vframe_s *vf, } return true; } + +static inline void h264_update_gvs(void) +{ + u32 ratio_control; + u32 ar; + + if (gvs->frame_height != frame_height) { + gvs->frame_width = frame_width; + gvs->frame_height = frame_height; + } + if (gvs->frame_dur != frame_dur) { + gvs->frame_dur = frame_dur; + if (frame_dur != 0) + gvs->frame_rate = 96000 / frame_dur; + else + gvs->frame_rate = -1; + } + gvs->error_count = READ_VREG(AV_SCRATCH_D); + gvs->status = stat; + if (fatal_error_reset) + gvs->status |= fatal_error_flag; + ar = min_t(u32, + h264_ar, + DISP_RATIO_ASPECT_RATIO_MAX); + ratio_control = + ar << DISP_RATIO_ASPECT_RATIO_BIT; + gvs->ratio_control = ratio_control; +} + + #ifdef HANDLE_H264_IRQ static irqreturn_t vh264_isr(int irq, void *dev_id) #else @@ -2875,7 +2905,7 @@ static void vh264_isr(void) frame_count++; s_vframe_qos.num = frame_count; - vdec_fill_frame_info(&s_vframe_qos, 1); + //vdec_fill_frame_info(&s_vframe_qos, 1); /* on second IDR frame,check the diff between pts * compute from duration and pts from lookup , @@ -3011,8 +3041,9 @@ static void vh264_isr(void) */ /*count info*/ - gvs->frame_dur = frame_dur; + h264_update_gvs(); vdec_count_info(gvs, error, b_offset); + vdec_fill_vdec_frame(vdec_h264, &s_vframe_qos, gvs, vf, 0); if ((pts_valid) && (check_pts_discontinue) && (!error)) { @@ -4325,6 +4356,7 @@ static int amvdec_h264_probe(struct platform_device *pdev) atomic_set(&vh264_active, 1); mutex_unlock(&vh264_mutex); + vdec_set_vframe_comm(pdata, DRIVER_NAME); return 0; } diff --git a/drivers/frame_provider/decoder/h264_multi/h264_dpb.c b/drivers/frame_provider/decoder/h264_multi/h264_dpb.c index 2258f75..56ee637 100644 --- a/drivers/frame_provider/decoder/h264_multi/h264_dpb.c +++ b/drivers/frame_provider/decoder/h264_multi/h264_dpb.c @@ -94,6 +94,8 @@ static struct StorablePicture *get_new_pic( struct h264_dpb_stru *p_H264_Dpb, enum PictureStructure structure, unsigned char is_output); +static void update_ref_list(struct DecodedPictureBuffer *p_Dpb); + static void init_dummy_fs(void) { dummy_fs.frame = &dummy_pic; @@ -868,6 +870,7 @@ void fill_frame_num_gap(struct VideoParameters *p_Vid, struct Slice *currSlice) CurrFrameNum = currSlice->frame_num; /*p_Vid->frame_num;*/ while (CurrFrameNum != UnusedShortTermFrameNum) { + /*pr_err("CurrFrameNum = %d, UnusedShortTermFrameNum = %d\n", CurrFrameNum, UnusedShortTermFrameNum);*/ /*picture = alloc_storable_picture *(p_Vid, FRAME, p_Vid->width, *p_Vid->height, @@ -1057,14 +1060,14 @@ static void init_picture(struct h264_dpb_stru *p_H264_Dpb, currSlice->picture_structure_mmco); } - if (currSlice->pic_struct >= 3) - dec_picture->pic_struct = currSlice->pic_struct + 2; - else if (currSlice->pic_struct == 1) - dec_picture->pic_struct = PIC_TOP_BOT; - else if (currSlice->pic_struct >= 2) - dec_picture->pic_struct = PIC_BOT_TOP; - else + if (currSlice->pic_struct < PIC_INVALID) { + dec_picture->pic_struct = currSlice->pic_struct; + } else { dec_picture->pic_struct = PIC_INVALID; + } + + dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, + "%s pic_struct = %d\n", __func__, dec_picture->pic_struct); } void dump_pic(struct h264_dpb_stru *p_H264_Dpb) @@ -1565,7 +1568,7 @@ static void dpb_combine_field(struct h264_dpb_stru *p_H264_Dpb, fs->frame->view_id = fs->view_id; #endif fs->frame->iCodingType = fs->top_field->iCodingType; - if (fs->top_field->poc < fs->bottom_field->poc) { + if (fs->bottom_field && fs->top_field->poc < fs->bottom_field->poc) { fs->pts = fs->top_field->pts; fs->pts64 = fs->top_field->pts64; /*SWPL-7105 fix */ @@ -1575,7 +1578,7 @@ static void dpb_combine_field(struct h264_dpb_stru *p_H264_Dpb, fs->pts64 = 0; } fs->offset_delimiter = fs->top_field->offset_delimiter; - } else { + } else if (fs->bottom_field) { fs->pts = fs->bottom_field->pts; fs->pts64 = fs->bottom_field->pts64; fs->offset_delimiter = fs->bottom_field->offset_delimiter; @@ -1609,6 +1612,7 @@ static void insert_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb, struct StorablePicture *p, unsigned char data_flag) { + struct vdec_frames_s *mvfrm = p_H264_Dpb->vdec->mvfrm; struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo; /* InputParameters *p_Inp = p_Vid->p_Inp; * dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, @@ -1621,6 +1625,8 @@ static void insert_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb, */ dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, "%s %p %p\n", __func__, fs, p); + p_H264_Dpb->dpb_frame_count++; + fs->dpb_frame_count = p_H264_Dpb->dpb_frame_count; #if 1 /* rain */ /* p->buf_spec_num = fs->index; */ @@ -1756,6 +1762,10 @@ static void insert_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb, //fs->pts64 = p->pts64; } fs->timestamp = p->timestamp; + if (mvfrm) { + fs->frame_size2 = mvfrm->frame_size; + fs->hw_decode_time = mvfrm->hw_decode_time; + } } void reset_frame_store(struct h264_dpb_stru *p_H264_Dpb, @@ -1795,7 +1805,7 @@ void reset_frame_store(struct h264_dpb_stru *p_H264_Dpb, } } -static void unmark_for_reference(struct DecodedPictureBuffer *p_Dpb, +void unmark_for_reference(struct DecodedPictureBuffer *p_Dpb, struct FrameStore *fs) { struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb, @@ -2117,6 +2127,7 @@ static int unmark_one_error_out_frame(struct h264_dpb_stru *p_H264_Dpb) unmark_for_reference(p_Dpb, p_Dpb->fs[i]); ret = 1; + break; } } return ret; @@ -2162,6 +2173,7 @@ void bufmgr_h264_remove_unused_frame(struct h264_dpb_stru *p_H264_Dpb, dpb_print(p_H264_Dpb->decoder_index, 0, "%s, Warnning, force unmark one frame\r\n", __func__); + update_ref_list(p_Dpb); remove_unused_frame_from_dpb(p_H264_Dpb); dump_dpb(p_Dpb, 0); } @@ -2170,6 +2182,7 @@ void bufmgr_h264_remove_unused_frame(struct h264_dpb_stru *p_H264_Dpb, dpb_print(p_H264_Dpb->decoder_index, 0, "%s, unmark error frame\r\n", __func__); + update_ref_list(p_Dpb); remove_unused_frame_from_dpb(p_H264_Dpb); dump_dpb(p_Dpb, 0); } @@ -2238,16 +2251,19 @@ int output_frames(struct h264_dpb_stru *p_H264_Dpb, unsigned char flush_flag) (!p_Dpb->fs[i]->pre_output) &&((p_Dpb->fs[i]->is_used == 3 ||p_Dpb->fs[i]->data_flag & ERROR_FLAG ))) { none_displayed_num++; - if ((p_H264_Dpb->first_insert_frame == FirstInsertFrm_IDLE) + if ((p_H264_Dpb->first_insert_frame == FirstInsertFrm_IDLE || + p_H264_Dpb->first_insert_frame == FirstInsertFrm_RESET) && (p_Dpb->fs[i]->is_used == 3) && (p_Dpb->last_output_poc == INT_MIN)) { + if (p_H264_Dpb->first_insert_frame == FirstInsertFrm_IDLE) + fast_output_flag = 1; p_H264_Dpb->first_insert_frame = FirstInsertFrm_OUT; p_H264_Dpb->first_output_poc = p_Dpb->fs[i]->poc; - fast_output_flag = 1; dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, "%s first insert frame i %d poc %d frame_num %x\n", __func__, i, p_Dpb->fs[i]->poc, p_Dpb->fs[i]->frame_num); } + /*check poc even/odd*/ if (p_H264_Dpb->poc_even_odd_flag == 0 && p_H264_Dpb->decode_pic_count >= 3) @@ -2695,6 +2711,11 @@ void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force) 0, "non_existing "); } + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + "dpb_frame_count %d ", + p_Dpb->fs[i]->dpb_frame_count); + #if (MVC_EXTENSION_ENABLE) if (p_Dpb->fs[i]->is_reference) dpb_print_cont(p_H264_Dpb->decoder_index, @@ -3504,6 +3525,8 @@ int store_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb, p_Vid->last_pic_bottom_field = (p->structure == BOTTOM_FIELD); if (p->idr_flag) { idr_memory_management(p_H264_Dpb, p); + if (p_H264_Dpb->first_insert_frame == FirstInsertFrm_OUT) + p_H264_Dpb->first_insert_frame = FirstInsertFrm_SKIPDONE; #if 0 /* ??? */ /* picture error concealment */ @@ -5682,7 +5705,7 @@ static void check_frame_store_same_pic_num(struct DecodedPictureBuffer *p_Dpb, } } -int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb) +int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb, int *frame_num_gap) { int new_pic_flag = 0; @@ -5750,6 +5773,7 @@ int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb) *if (p_Vid->conceal_mode == 0) */ fill_frame_num_gap(p_Vid, currSlice); + *frame_num_gap = 1; } if (currSlice->nal_reference_idc) { diff --git a/drivers/frame_provider/decoder/h264_multi/h264_dpb.h b/drivers/frame_provider/decoder/h264_multi/h264_dpb.h index 471ffa5..99d1a6d 100644 --- a/drivers/frame_provider/decoder/h264_multi/h264_dpb.h +++ b/drivers/frame_provider/decoder/h264_multi/h264_dpb.h @@ -53,16 +53,6 @@ */ #define IGNORE_PARAM_FROM_CONFIG 0x8000000 - -#define PIC_SINGLE_FRAME 0 -#define PIC_TOP_BOT_TOP 1 -#define PIC_BOT_TOP_BOT 2 -#define PIC_DOUBLE_FRAME 3 -#define PIC_TRIPLE_FRAME 4 -#define PIC_TOP_BOT 5 -#define PIC_BOT_TOP 6 -#define PIC_INVALID 7 - #define MVC_EXTENSION_ENABLE 0 #define PRINTREFLIST 0 @@ -430,6 +420,19 @@ enum PictureStructure { BOTTOM_FIELD }; +typedef enum { + PIC_SINGLE_FRAME = 0, + PIC_TOP, + PIC_BOT, + PIC_TOP_BOT, + PIC_BOT_TOP, + PIC_TOP_BOT_TOP = 5, + PIC_BOT_TOP_BOT, + PIC_DOUBLE_FRAME, + PIC_TRIPLE_FRAME, + PIC_INVALID, +} PicStruct_E; + #define I_Slice 2 #define P_Slice 5 #define B_Slice 6 @@ -463,6 +466,7 @@ enum FirstInsertFrm_State { FirstInsertFrm_IDLE = 0, FirstInsertFrm_OUT = 1, FirstInsertFrm_SKIPDONE = 2, + FirstInsertFrm_RESET = 3, }; @@ -804,6 +808,9 @@ struct FrameStore { int max_mv; int min_mv; int avg_mv; + int dpb_frame_count; + u32 hw_decode_time; + u32 frame_size2; // For recording the chunk->size in frame mode }; @@ -896,6 +903,7 @@ struct h264_dpb_stru { unsigned int origin_max_reference; unsigned int first_insert_frame; int first_output_poc; + int dpb_frame_count; }; @@ -916,7 +924,7 @@ void set_frame_output_flag(struct h264_dpb_stru *p_H264_Dpb, int index); int is_there_unused_frame_from_dpb(struct DecodedPictureBuffer *p_Dpb); -int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb); +int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb, int *frame_num_gap); void dpb_init_global(struct h264_dpb_stru *p_H264_Dpb, int id, int actual_dpb_size, int max_reference_size); @@ -959,4 +967,8 @@ enum PictureStructure get_cur_slice_picture_struct( int dpb_check_ref_list_error( struct h264_dpb_stru *p_H264_Dpb); + +void unmark_for_reference(struct DecodedPictureBuffer *p_Dpb, + struct FrameStore *fs); + #endif diff --git a/drivers/frame_provider/decoder/h264_multi/vmh264.c b/drivers/frame_provider/decoder/h264_multi/vmh264.c index c2e0e91..91d8c1f 100644 --- a/drivers/frame_provider/decoder/h264_multi/vmh264.c +++ b/drivers/frame_provider/decoder/h264_multi/vmh264.c @@ -63,6 +63,9 @@ #include #include +#define DETECT_WRONG_MULTI_SLICE + + #undef pr_info #define pr_info printk #define VDEC_DW @@ -131,6 +134,8 @@ unsigned int h264_debug_mask = 0xff; */ unsigned int h264_debug_cmd; +static int ref_b_frame_error_max_count = 50; + static unsigned int dec_control = DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE | DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE; @@ -267,8 +272,13 @@ static unsigned int i_only_flag; bit[12] i_only when error happen bit[13] 0: mark error according to last pic, 1: ignore mark error bit[14] 0: result done when timeout from ucode. 1: reset bufmgr when timeout. + bit[15] 1: dpb_frame_count If the dpb_frame_count difference is large, it moves out of the DPB buffer. + bit[16] 1: check slice header number. + bit[17] 1: If the decoded Mb count is insufficient but greater than the threshold, it is considered the correct frame. + bit[18] 1: time out status, store pic to dpb buffer. + bit[19] 1: If a lot b frames are wrong consecutively, the DPB queue reset. */ -static unsigned int error_proc_policy = 0x4fb6; /*0x1f14*/ +static unsigned int error_proc_policy = 0xfCfb6; /*0x1f14*/ /* @@ -306,6 +316,9 @@ static unsigned int frmbase_cont_bitlevel = 0x40; static unsigned int frmbase_cont_bitlevel2 = 0x1; +static unsigned int check_slice_num = 30; + +static unsigned int mb_count_threshold = 5; /*percentage*/ #define MH264_USERDATA_ENABLE @@ -633,8 +646,8 @@ struct vdec_h264_hw_s { #endif struct StorablePicture *last_dec_picture; - ulong lmem_addr; - dma_addr_t lmem_addr_remap; + ulong lmem_phy_addr; + dma_addr_t lmem_addr; void *bmmu_box; #ifdef H264_MMU @@ -846,10 +859,26 @@ struct vdec_h264_hw_s { bool first_head_check_flag; unsigned int height_aspect_ratio; unsigned int width_aspect_ratio; - bool new_iframe_flag; - bool ref_err_flush_dpb_flag; unsigned int first_i_policy; u32 reorder_dpb_size_margin; + bool wait_reset_done_flag; +#ifdef DETECT_WRONG_MULTI_SLICE + unsigned int multi_slice_pic_check_count; + /* multi_slice_pic_flag: + 0, unknown; + 1, single slice; + 2, multi slice + */ + unsigned int multi_slice_pic_flag; + unsigned int picture_slice_count; + unsigned int cur_picture_slice_count; + unsigned char force_slice_as_picture_flag; + unsigned int last_picture_slice_count; + unsigned int first_pre_frame_num; +#endif + unsigned int res_ch_flag; + u32 b_frame_error_count; + struct vdec_info gvs; }; static u32 again_threshold; @@ -902,13 +931,11 @@ static void h264_clear_dpb(struct vdec_h264_hw_s *hw); /* 0:linear 1:32x32 2:64x32 ; m8baby test1902 */ static u32 mem_map_mode = H265_MEM_MAP_MODE; -#define MAX_SIZE_8K (8192 * 4608) #define MAX_SIZE_4K (4096 * 2304) static int is_oversize(int w, int h) { - int max = (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)? - MAX_SIZE_8K : MAX_SIZE_4K; + int max = MAX_SIZE_4K; if (w < 0 || h < 0) return true; @@ -1669,6 +1696,7 @@ static unsigned char is_buf_spec_in_disp_q(struct vdec_h264_hw_s *hw, static int alloc_one_buf_spec(struct vdec_h264_hw_s *hw, int i) { + struct vdec_s *vdec = hw_to_vdec(hw); if (hw->mmu_enable) { if (hw->buffer_spec[i].alloc_header_addr) return 0; @@ -1706,7 +1734,25 @@ static int alloc_one_buf_spec(struct vdec_h264_hw_s *hw, int i) hw->no_mem_count = 0; hw->stat &= ~DECODER_FATAL_ERROR_NO_MEM; } - + if (!vdec_secure(vdec)) { + /*init internal buf*/ + char *tmpbuf = (char *)codec_mm_phys_to_virt(hw->buffer_spec[i].cma_alloc_addr); + if (tmpbuf) { + memset(tmpbuf, 0, PAGE_ALIGN(buf_size)); + codec_mm_dma_flush(tmpbuf, + PAGE_ALIGN(buf_size), + DMA_TO_DEVICE); + } else { + tmpbuf = codec_mm_vmap(hw->buffer_spec[i].cma_alloc_addr, PAGE_ALIGN(buf_size)); + if (tmpbuf) { + memset(tmpbuf, 0, PAGE_ALIGN(buf_size)); + codec_mm_dma_flush(tmpbuf, + PAGE_ALIGN(buf_size), + DMA_TO_DEVICE); + codec_mm_unmap_phyaddr(tmpbuf); + } + } + } hw->buffer_spec[i].buf_adr = hw->buffer_spec[i].cma_alloc_addr; addr = hw->buffer_spec[i].buf_adr; @@ -2513,6 +2559,7 @@ static int check_force_interlace(struct vdec_h264_hw_s *hw, static void fill_frame_info(struct vdec_h264_hw_s *hw, struct FrameStore *frame) { struct vframe_qos_s *vframe_qos = &hw->vframe_qos; + if (frame->slice_type == I_SLICE) vframe_qos->type = 1; else if (frame->slice_type == P_SLICE) @@ -2520,7 +2567,10 @@ static void fill_frame_info(struct vdec_h264_hw_s *hw, struct FrameStore *frame) else if (frame->slice_type == B_SLICE) vframe_qos->type = 3; - vframe_qos->size = frame->frame_size; + if (input_frame_based(hw_to_vdec(hw))) + vframe_qos->size = frame->frame_size2; + else + vframe_qos->size = frame->frame_size; vframe_qos->pts = frame->pts64; vframe_qos->max_mv = frame->max_mv; @@ -2553,8 +2603,6 @@ static void fill_frame_info(struct vdec_h264_hw_s *hw, struct FrameStore *frame) vframe_qos->min_skip); */ vframe_qos->num++; - if (hw->frameinfo_enable) - vdec_fill_frame_info(vframe_qos, 1); } static int is_iframe(struct FrameStore *frame) { @@ -2572,6 +2620,8 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame) struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; struct vframe_s *vf = NULL; int buffer_index = frame->buf_spec_num; + struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; + ulong nv_order = VIDTYPE_VIU_NV21; int vf_count = 1; int i; int bForceInterlace = 0; @@ -2582,6 +2632,14 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame) __func__, buffer_index); return -1; } + + /* swap uv */ + if (hw->is_used_v4l) { + if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) || + (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M)) + nv_order = VIDTYPE_VIU_NV12; + } + if (force_disp_bufspec_num & 0x100) { /*recycle directly*/ if (hw->buffer_spec[frame->buf_spec_num].used != 3 && @@ -2631,6 +2689,40 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame) hw->last_pts64 = frame->pts64; hw->last_pts = frame->pts; } + + /* SWPL-18973 96000/15=6400, less than 15fps check */ + if ((!hw->duration_from_pts_done) && (hw->frame_dur > 6400ULL)) { + if ((check_force_interlace(hw, frame)) && + (frame->slice_type == I_SLICE) && + (hw->pts_outside)) { + if ((!hw->h264_pts_count) || (!hw->h264pts1)) { + hw->h264pts1 = frame->pts; + hw->h264_pts_count = 0; + } else if (frame->pts > hw->h264pts1) { + u32 calc_dur = + PTS2DUR(frame->pts - hw->h264pts1); + calc_dur = ((calc_dur/hw->h264_pts_count) << 1); + if (hw->frame_dur < (calc_dur + 200) && + hw->frame_dur > (calc_dur - 200)) { + hw->frame_dur >>= 1; + vdec_schedule_work(&hw->notify_work); + dpb_print(DECODE_ID(hw), 0, + "correct frame_dur %d, calc_dur %d, count %d\n", + hw->frame_dur, (calc_dur >> 1), hw->h264_pts_count); + hw->duration_from_pts_done = 1; + hw->h264_pts_count = 0; + } + } + } + hw->h264_pts_count++; + } + + if (frame->data_flag & ERROR_FLAG) { + vdec_count_info(&hw->gvs, 1, 0); + if (!hw->send_error_frame_flag) + hw->gvs.drop_frame_count++; + } + if ((frame->data_flag & NODISP_FLAG) || (frame->data_flag & NULL_FLAG) || ((!hw->send_error_frame_flag) && @@ -2666,6 +2758,8 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame) bForceInterlace = check_force_interlace(hw, frame); if (bForceInterlace) vf_count = 2; + if (hw->is_used_v4l) + vf_count = 1; hw->buffer_spec[buffer_index].vf_ref = 0; fill_frame_info(hw, frame); for (i = 0; i < vf_count; i++) { @@ -2713,7 +2807,7 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame) if (hw->double_write_mode) { vf->type |= VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; - vf->type |= VIDTYPE_VIU_NV21; + vf->type |= nv_order; if (hw->double_write_mode == 3) vf->type |= VIDTYPE_COMPRESS; @@ -2746,7 +2840,7 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame) vf->compHeight = hw->frame_height; } else { vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | - VIDTYPE_VIU_NV21; + nv_order; vf->canvas0Addr = vf->canvas1Addr = spec2canvas(&hw->buffer_spec[buffer_index]); @@ -2778,12 +2872,23 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame) if (bForceInterlace || is_interlace(frame)) { vf->type = VIDTYPE_INTERLACE_FIRST | - VIDTYPE_VIU_NV21; + nv_order; if (bForceInterlace) { + if (frame->frame != NULL && frame->frame->pic_struct == PIC_TOP_BOT) { vf->type |= (i == 0 ? VIDTYPE_INTERLACE_TOP : VIDTYPE_INTERLACE_BOTTOM); + } else if (frame->frame != NULL && frame->frame->pic_struct == PIC_BOT_TOP) { + vf->type |= (i == 0 ? + VIDTYPE_INTERLACE_BOTTOM : + VIDTYPE_INTERLACE_TOP); + } else { + vf->type |= (i == 0 ? + VIDTYPE_INTERLACE_TOP : + VIDTYPE_INTERLACE_BOTTOM); + } + if (i == 1) { vf->pts = 0; vf->pts_us64 = 0; @@ -2800,8 +2905,16 @@ int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame) vf->duration = vf->duration/2; } - if (i == 0) - decoder_do_frame_check(hw_to_vdec(hw), vf); + if (i == 0) { + struct vdec_s *pvdec; + struct vdec_info vs; + + pvdec = hw_to_vdec(hw); + memset(&vs, 0, sizeof(struct vdec_info)); + pvdec->dec_status(pvdec, &vs); + decoder_do_frame_check(pvdec, vf); + vdec_fill_vdec_frame(pvdec, &hw->vframe_qos, &vs, vf, frame->hw_decode_time); + } /*vf->ratio_control |= (0x3FF << DISP_RATIO_ASPECT_RATIO_BIT);*/ vf->sar_width = hw->width_aspect_ratio; @@ -3211,7 +3324,7 @@ int config_decode_buf(struct vdec_h264_hw_s *hw, struct StorablePicture *pic) * bit 1:0 -- h264_co_mb_info_wr_ptr */ #define H264_CO_MB_RW_CTL VLD_C3D /* 0xc3d */ - +#define DCAC_DDR_BYTE64_CTL 0x0e1d unsigned long canvas_adr; unsigned int ref_reg_val; unsigned int one_ref_cfg = 0; @@ -3313,9 +3426,14 @@ int config_decode_buf(struct vdec_h264_hw_s *hw, struct StorablePicture *pic) h264_buffer_info_data_write_count = 0; //disable this read cache when frame width <= 64 (4MBs) - //IQIDCT_CONTROL, bit[16] – dcac_dma_read_cache_disable - if (hw->frame_width <= 64) + //IQIDCT_CONTROL, bit[16] dcac_dma_read_cache_disable + if (hw->frame_width <= 64) { SET_VREG_MASK(IQIDCT_CONTROL,(1 << 16)); + if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)) + // Disable DDR_BYTE64_CACHE + WRITE_VREG(DCAC_DDR_BYTE64_CTL, + (READ_VREG(DCAC_DDR_BYTE64_CTL) & (~0xf)) | 0xa); + } else CLEAR_VREG_MASK(IQIDCT_CONTROL,(1 << 16)); @@ -3352,6 +3470,24 @@ int config_decode_buf(struct vdec_h264_hw_s *hw, struct StorablePicture *pic) pic->data_flag |= ERROR_FLAG; dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " ref error mark1 \n"); } + + if (error_proc_policy & 0x80000) { + if (ref_b_frame_error_max_count && + ref->slice_type == B_SLICE) { + if (ref->data_flag & ERROR_FLAG) + hw->b_frame_error_count++; + else + hw->b_frame_error_count = 0; + if (hw->b_frame_error_count > ref_b_frame_error_max_count) { + hw->b_frame_error_count = 0; + dpb_print(DECODE_ID(hw), 0, + "error %d B frame, reset dpb buffer\n", + ref_b_frame_error_max_count); + return -1; + } + } + } + if (ref->data_flag & NULL_FLAG) hw->data_flag |= NULL_FLAG; #endif @@ -3736,10 +3872,19 @@ static struct vframe_s *vh264_vf_get(void *op_arg) struct vframe_s *vf; struct vdec_s *vdec = op_arg; struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; + struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; + ulong nv_order = VIDTYPE_VIU_NV21; if (!hw) return NULL; + /* swap uv */ + if (hw->is_used_v4l) { + if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) || + (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M)) + nv_order = VIDTYPE_VIU_NV12; + } + if (force_disp_bufspec_num & 0x100) { int buffer_index = force_disp_bufspec_num & 0xff; if (force_disp_bufspec_num & 0x200) @@ -3770,7 +3915,7 @@ static struct vframe_s *vh264_vf_get(void *op_arg) if (hw->double_write_mode) { vf->type |= VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; - vf->type |= VIDTYPE_VIU_NV21; + vf->type |= nv_order; if (hw->double_write_mode == 3) vf->type |= VIDTYPE_COMPRESS; @@ -3808,7 +3953,7 @@ static struct vframe_s *vh264_vf_get(void *op_arg) } } else { vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | - VIDTYPE_VIU_NV21; + nv_order; vf->canvas0Addr = vf->canvas1Addr = spec2canvas(&hw->buffer_spec[buffer_index]); } @@ -3862,6 +4007,24 @@ static struct vframe_s *vh264_vf_get(void *op_arg) return NULL; } +static bool vf_valid_check(struct vframe_s *vf, struct vdec_h264_hw_s *hw) { + int i,j; + if (hw->is_used_v4l) + return true; + for (i = 0; i < VF_POOL_SIZE; i++) { + for (j = 0; j < VF_POOL_NUM; j ++) { + if (vf == &(hw->vfpool[j][i])) + return true; + } + } + dpb_print(DECODE_ID(hw), 0, " invalid vf been put, vf = %p\n", vf); + for (i = 0; i < VF_POOL_SIZE; i++) { + dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, + "dump vf [%d]= %p\n", i, &(hw->vfpool[hw->cur_pool][i])); + } + return false; +} + static void vh264_vf_put(struct vframe_s *vf, void *op_arg) { struct vdec_s *vdec = op_arg; @@ -3925,7 +4088,8 @@ static void vh264_vf_put(struct vframe_s *vf, void *op_arg) spin_unlock_irqrestore(&hw->bufspec_lock, flags); hw->vf_put_count++; - kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); + if (vf && (vf_valid_check(vf, hw) == true)) + kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); #define ASSIST_MBOX1_IRQ_REG VDEC_ASSIST_MBOX1_IRQ_REG if (hw->buffer_empty_flag) @@ -4378,55 +4542,55 @@ static void get_picture_qos_info(struct StorablePicture *picture) #endif picture->min_mv = mv_lo; +#ifdef DEBUG_QOS /* {mvy_L0_max, mvy_L0_min} */ rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); mv_hi = (rdata32>>16)&0xffff; if (mv_hi & 0x8000) mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS pr_info(" [Picture %d Quality] MVY_L0 MAX : %d\n", pic_number, mv_hi); -#endif + mv_lo = (rdata32>>0)&0xffff; if (mv_lo & 0x8000) mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS + pr_info(" [Picture %d Quality] MVY_L0 MIN : %d\n", pic_number, mv_lo); -#endif + /* {mvx_L1_max, mvx_L1_min} */ rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); mv_hi = (rdata32>>16)&0xffff; if (mv_hi & 0x8000) mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS + pr_info(" [Picture %d Quality] MVX_L1 MAX : %d\n", pic_number, mv_hi); -#endif + mv_lo = (rdata32>>0)&0xffff; if (mv_lo & 0x8000) mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS + pr_info(" [Picture %d Quality] MVX_L1 MIN : %d\n", pic_number, mv_lo); -#endif + /* {mvy_L1_max, mvy_L1_min} */ rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); mv_hi = (rdata32>>16)&0xffff; if (mv_hi & 0x8000) mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS + pr_info(" [Picture %d Quality] MVY_L1 MAX : %d\n", pic_number, mv_hi); -#endif + mv_lo = (rdata32>>0)&0xffff; if (mv_lo & 0x8000) mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS + pr_info(" [Picture %d Quality] MVY_L1 MIN : %d\n", pic_number, mv_lo); #endif @@ -5339,6 +5503,8 @@ static int parse_one_sei_record(struct vdec_h264_hw_s *hw, /* user data length should be align with 8 bytes, if not, then padding with zero*/ for (i = 0; i < payload_size; i += 8) { + if (hw->sei_itu_data_len + i >= SEI_ITU_DATA_SIZE) + break; // Avoid out-of-bound writing for (j = 0; j < 8; j++) { int index; @@ -5356,6 +5522,8 @@ static int parse_one_sei_record(struct vdec_h264_hw_s *hw, data_len = ((payload_size + 8) >> 3) << 3; hw->sei_itu_data_len += data_len; + if (hw->sei_itu_data_len >= SEI_ITU_DATA_SIZE) + hw->sei_itu_data_len = SEI_ITU_DATA_SIZE; /* dpb_print(DECODE_ID(hw), 0, "%s: user data, and len = %d:\n", @@ -5408,16 +5576,22 @@ static void check_decoded_pic_error(struct vdec_h264_hw_s *hw) return; if (get_cur_slice_picture_struct(p_H264_Dpb) != FRAME) mb_total /= 2; - if (error_proc_policy & 0x100) { - if (decode_mb_count < mb_total) - p->data_flag |= ERROR_FLAG; - } if ((error_proc_policy & 0x200) && READ_VREG(ERROR_STATUS_REG) != 0) { p->data_flag |= ERROR_FLAG; } + if (error_proc_policy & 0x100) { + if (decode_mb_count < mb_total) { + p->data_flag |= ERROR_FLAG; + if ((error_proc_policy & 0x20000) && + decode_mb_count >= mb_total * (100 - mb_count_threshold) / 100) { + p->data_flag &= ~ERROR_FLAG; + } + } + } + if (p->data_flag & ERROR_FLAG) { dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, "%s: decode error, seq_info2 0x%x, mby_mbx 0x%x, mb_total %d decoded mb_count %d ERROR_STATUS_REG 0x%x\n", @@ -5432,6 +5606,157 @@ static void check_decoded_pic_error(struct vdec_h264_hw_s *hw) } } +static int vh264_pic_done_proc(struct vdec_s *vdec) +{ + struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)(vdec->private); + struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; + int ret; + + if (vdec->mvfrm) + vdec->mvfrm->hw_decode_time = + local_clock() - vdec->mvfrm->hw_decode_start; + + if (input_frame_based(vdec) && + (!(hw->i_only & 0x2)) && + frmbase_cont_bitlevel != 0 && + READ_VREG(VIFF_BIT_CNT) > + frmbase_cont_bitlevel) { + /*handle the case: multi pictures in one packet*/ + dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, + "%s H264_PIC_DATA_DONE decode slice count %d, continue (bitcnt 0x%x)\n", + __func__, + hw->decode_pic_count, + READ_VREG(VIFF_BIT_CNT)); + hw->frmbase_cont_flag = 1; + } else + hw->frmbase_cont_flag = 0; + + if (p_H264_Dpb->mVideo.dec_picture) { + get_picture_qos_info(p_H264_Dpb->mVideo.dec_picture); +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + DEL_EXIST(hw, + p_H264_Dpb->mVideo.dec_picture) = 0; + if (vdec->master) { + struct vdec_h264_hw_s *hw_ba = + (struct vdec_h264_hw_s *) + vdec->master->private; + if (hw_ba->last_dec_picture) + DEL_EXIST(hw_ba, + hw_ba->last_dec_picture) + = 1; + } +#endif + mutex_lock(&hw->chunks_mutex); + if (hw->chunk) { + p_H264_Dpb->mVideo.dec_picture->pts = + hw->chunk->pts; + p_H264_Dpb->mVideo.dec_picture->pts64 = + hw->chunk->pts64; + p_H264_Dpb->mVideo.dec_picture->timestamp = + hw->chunk->timestamp; +#ifdef MH264_USERDATA_ENABLE + vmh264_udc_fill_vpts(hw, + p_H264_Dpb->mSlice.slice_type, + hw->chunk->pts, 1); +#endif + +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + } else if (vdec->master) { + /*dv enhance layer, + do not checkout pts*/ + struct StorablePicture *pic = + p_H264_Dpb->mVideo.dec_picture; + pic->pts = 0; + pic->pts64 = 0; +#endif + } else { + struct StorablePicture *pic = + p_H264_Dpb->mVideo.dec_picture; + u32 offset = pic->offset_delimiter; + if (pts_pickout_offset_us64(PTS_TYPE_VIDEO, + offset, &pic->pts, 0, &pic->pts64)) { + pic->pts = 0; + pic->pts64 = 0; +#ifdef MH264_USERDATA_ENABLE + vmh264_udc_fill_vpts(hw, + p_H264_Dpb->mSlice.slice_type, + pic->pts, 0); +#endif + } else { +#ifdef MH264_USERDATA_ENABLE + vmh264_udc_fill_vpts(hw, + p_H264_Dpb->mSlice.slice_type, + pic->pts, 1); +#endif + } + + } + mutex_unlock(&hw->chunks_mutex); + + check_decoded_pic_error(hw); +#ifdef ERROR_HANDLE_TEST + if ((hw->data_flag & ERROR_FLAG) + && (error_proc_policy & 0x80)) { + release_cur_decoding_buf(hw); + h264_clear_dpb(hw); + hw->dec_flag = 0; + hw->data_flag = 0; + hw->skip_frame_count = 0; + hw->has_i_frame = 0; + hw->no_error_count = 0xfff; + hw->no_error_i_count = 0xf; + } else +#endif + ret = store_picture_in_dpb(p_H264_Dpb, + p_H264_Dpb->mVideo.dec_picture, + hw->data_flag | hw->dec_flag | + p_H264_Dpb->mVideo.dec_picture->data_flag); + + + + if (ret == -1) { + release_cur_decoding_buf(hw); + bufmgr_force_recover(p_H264_Dpb); + } else { + if (hw->data_flag & ERROR_FLAG) { + hw->no_error_count = 0; + hw->no_error_i_count = 0; + } else { + hw->no_error_count++; + if (hw->data_flag & I_FLAG) + hw->no_error_i_count++; + } + if (hw->mmu_enable) + hevc_set_unused_4k_buff_idx(hw, + p_H264_Dpb->mVideo. + dec_picture->buf_spec_num); + bufmgr_post(p_H264_Dpb); + hw->last_dec_picture = + p_H264_Dpb->mVideo.dec_picture; + p_H264_Dpb->mVideo.dec_picture = NULL; + /* dump_dpb(&p_H264_Dpb->mDPB); */ + hw->has_i_frame = 1; + if (hw->mmu_enable) + hevc_set_frame_done(hw); + hw->decode_pic_count++; + p_H264_Dpb->decode_pic_count = hw->decode_pic_count; + if (hw->skip_frame_count > 0) { + /*skip n frame after first I */ + hw->skip_frame_count--; + if (hw->skip_frame_count == 0) + hw->dec_flag &= (~NODISP_FLAG); + } else if (hw->skip_frame_count < -1) { + /*skip n frame after first I until second I */ + hw->skip_frame_count++; + if (hw->skip_frame_count == -1) + hw->dec_flag &= (~NODISP_FLAG); + } + } + } + return 0; +} + + static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq) { int i; @@ -5439,16 +5764,10 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq) struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; unsigned int dec_dpb_status = p_H264_Dpb->dec_dpb_status; u32 debug_tag; - int ret; if (dec_dpb_status == H264_CONFIG_REQUEST) { #if 1 unsigned short *p = (unsigned short *)hw->lmem_addr; - dma_sync_single_for_cpu( - amports_get_dma_device(), - hw->lmem_addr_remap, - PAGE_SIZE, - DMA_FROM_DEVICE); for (i = 0; i < (RPM_END-RPM_BEGIN); i += 4) { int ii; for (ii = 0; ii < 4; ii++) { @@ -5495,6 +5814,20 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq) reset_process_time(hw); hw->reg_iqidct_control = READ_VREG(IQIDCT_CONTROL); hw->dec_result = DEC_RESULT_CONFIG_PARAM; +#ifdef DETECT_WRONG_MULTI_SLICE + /*restart check count and set 'unknown'*/ + dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT, + "%s MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d), H264_CONFIG_REQUEST => restart check\n", + __func__, + hw->multi_slice_pic_check_count, + hw->picture_slice_count, + hw->cur_picture_slice_count, + hw->multi_slice_pic_flag); + + hw->multi_slice_pic_check_count = 0; + hw->multi_slice_pic_flag = 0; + hw->picture_slice_count = 0; +#endif vdec_schedule_work(&hw->work); } else if (dec_dpb_status == H264_SLICE_HEAD_DONE) { u16 data_hight; @@ -5503,21 +5836,42 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq) int slice_header_process_status = 0; int I_flag; + int frame_num_gap = 0; /*unsigned char is_idr;*/ unsigned short *p = (unsigned short *)hw->lmem_addr; reset_process_time(hw); - if (hw->is_used_v4l) { - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - - if (ctx->param_sets_from_ucode && !ctx->v4l_codec_ready) { - //amvdec_stop(); - hw->dec_result = DEC_RESULT_DONE; - vdec_schedule_work(&hw->work); - return IRQ_HANDLED; +#ifdef DETECT_WRONG_MULTI_SLICE + hw->cur_picture_slice_count++; + if (hw->multi_slice_pic_flag == 1 && + hw->cur_picture_slice_count == 1 && + (error_proc_policy & 0x10000)) { + hw->first_pre_frame_num = p_H264_Dpb->mVideo.pre_frame_num; + } + if (hw->multi_slice_pic_flag == 1 && + hw->cur_picture_slice_count > 1 && + (error_proc_policy & 0x10000)) { + dpb_print(DECODE_ID(hw), 0, + "%s MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d), WRONG_MULTI_SLICE detected, insert picture\n", + __func__, + hw->multi_slice_pic_check_count, + hw->picture_slice_count, + hw->cur_picture_slice_count, + hw->multi_slice_pic_flag); + if (hw->cur_picture_slice_count > hw->last_picture_slice_count) + vh264_pic_done_proc(vdec); + else { + if (p_H264_Dpb->mVideo.dec_picture) { + if (p_H264_Dpb->mVideo.dec_picture->colocated_buf_index >= 0) { + release_colocate_buf(p_H264_Dpb, + p_H264_Dpb->mVideo.dec_picture->colocated_buf_index); + p_H264_Dpb->mVideo.dec_picture->colocated_buf_index = -1; + } + } + release_cur_decoding_buf(hw); } } +#endif hw->reg_iqidct_control = READ_VREG(IQIDCT_CONTROL); hw->reg_vcop_ctrl_reg = READ_VREG(VCOP_CTRL_REG); @@ -5536,11 +5890,6 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq) goto empty_proc; } - dma_sync_single_for_cpu( - amports_get_dma_device(), - hw->lmem_addr_remap, - PAGE_SIZE, - DMA_FROM_DEVICE); #if 0 if (p_H264_Dpb->mVideo.dec_picture == NULL) { if (!is_buffer_available(vdec)) { @@ -5687,7 +6036,7 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq) } slice_header_process_status = - h264_slice_header_process(p_H264_Dpb); + h264_slice_header_process(p_H264_Dpb, &frame_num_gap); if (hw->mmu_enable) hevc_sao_set_slice_type(hw, slice_header_process_status, @@ -5744,23 +6093,16 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq) READ_VREG(MBY_MBX), decode_mb_count); p->data_flag |= ERROR_FLAG; - } else if (!p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE] && decode_mb_count) { + }/* else if (!p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE] && decode_mb_count) { p->data_flag |= ERROR_FLAG; goto pic_done_proc; - } + }*/ } - if (p_H264_Dpb->mVideo.dec_picture->slice_type == I_SLICE) { - hw->new_iframe_flag = 1; - } - if (hw->new_iframe_flag) { - if (p_H264_Dpb->mVideo.dec_picture->slice_type == P_SLICE) { - hw->new_iframe_flag = 0; - hw->ref_err_flush_dpb_flag = 1; - }else if (p_H264_Dpb->mVideo.dec_picture->slice_type == B_SLICE) { - hw->new_iframe_flag = 0; - hw->ref_err_flush_dpb_flag = 0; - } + if (!I_flag && frame_num_gap) { + hw->data_flag |= ERROR_FLAG; + p_H264_Dpb->mVideo.dec_picture->data_flag |= ERROR_FLAG; + dpb_print(DECODE_ID(hw), 0, "frame number gap error\n"); } if (error_proc_policy & 0x400) { @@ -5774,15 +6116,6 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq) hw->skip_frame_count, hw->reflist_error_count); - if (hw->ref_err_flush_dpb_flag) { - flush_dpb(p_H264_Dpb); - p_H264_Dpb->colocated_buf_map = 0; - if (p_H264_Dpb->mVideo.dec_picture->colocated_buf_index >= 0) { - p_H264_Dpb->colocated_buf_map |= 1 << - p_H264_Dpb->mVideo.dec_picture->colocated_buf_index; - } - } - p_H264_Dpb->mVideo.dec_picture->data_flag = NODISP_FLAG; if (((error_proc_policy & 0x80) && ((hw->dec_flag & @@ -5844,146 +6177,37 @@ static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq) start_process_time(hw); } else if (dec_dpb_status == H264_PIC_DATA_DONE ||((dec_dpb_status == H264_DATA_REQUEST) && input_frame_based(vdec))) { -pic_done_proc: - reset_process_time(hw); - - if (input_frame_based(vdec) && - (!(hw->i_only & 0x2)) && - frmbase_cont_bitlevel != 0 && - READ_VREG(VIFF_BIT_CNT) > - frmbase_cont_bitlevel) { - /*handle the case: multi pictures in one packet*/ - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s H264_PIC_DATA_DONE decode slice count %d, continue (bitcnt 0x%x)\n", - __func__, - hw->decode_pic_count, - READ_VREG(VIFF_BIT_CNT)); - hw->frmbase_cont_flag = 1; - } else - hw->frmbase_cont_flag = 0; - - if (p_H264_Dpb->mVideo.dec_picture) { - get_picture_qos_info(p_H264_Dpb->mVideo.dec_picture); -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - DEL_EXIST(hw, - p_H264_Dpb->mVideo.dec_picture) = 0; - if (vdec->master) { - struct vdec_h264_hw_s *hw_ba = - (struct vdec_h264_hw_s *) - vdec->master->private; - if (hw_ba->last_dec_picture) - DEL_EXIST(hw_ba, - hw_ba->last_dec_picture) - = 1; - } -#endif - mutex_lock(&hw->chunks_mutex); - if (hw->chunk) { - p_H264_Dpb->mVideo.dec_picture->pts = - hw->chunk->pts; - p_H264_Dpb->mVideo.dec_picture->pts64 = - hw->chunk->pts64; - p_H264_Dpb->mVideo.dec_picture->timestamp = - hw->chunk->timestamp; -#ifdef MH264_USERDATA_ENABLE - vmh264_udc_fill_vpts(hw, - p_H264_Dpb->mSlice.slice_type, - hw->chunk->pts, 1); -#endif - -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - } else if (vdec->master) { - /*dv enhance layer, - do not checkout pts*/ - struct StorablePicture *pic = - p_H264_Dpb->mVideo.dec_picture; - pic->pts = 0; - pic->pts64 = 0; -#endif - } else { - struct StorablePicture *pic = - p_H264_Dpb->mVideo.dec_picture; - u32 offset = pic->offset_delimiter; - if (pts_pickout_offset_us64(PTS_TYPE_VIDEO, - offset, &pic->pts, 0, &pic->pts64)) { - pic->pts = 0; - pic->pts64 = 0; -#ifdef MH264_USERDATA_ENABLE - vmh264_udc_fill_vpts(hw, - p_H264_Dpb->mSlice.slice_type, - pic->pts, 0); -#endif - } else { -#ifdef MH264_USERDATA_ENABLE - vmh264_udc_fill_vpts(hw, - p_H264_Dpb->mSlice.slice_type, - pic->pts, 1); -#endif +#ifdef DETECT_WRONG_MULTI_SLICE + dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT, + "%s MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d), H264_PIC_DATA_DONE\n", + __func__, + hw->multi_slice_pic_check_count, + hw->picture_slice_count, + hw->cur_picture_slice_count, + hw->multi_slice_pic_flag); + + if (hw->multi_slice_pic_check_count < check_slice_num) { + hw->multi_slice_pic_check_count++; + if (hw->cur_picture_slice_count != + hw->picture_slice_count) { + /*restart check count and set 'unknown'*/ + hw->multi_slice_pic_check_count = 0; + hw->multi_slice_pic_flag = 0; + } + hw->picture_slice_count = + hw->cur_picture_slice_count; + } else if (hw->multi_slice_pic_check_count >= check_slice_num) { + if (hw->picture_slice_count > 1) + hw->multi_slice_pic_flag = 2; + else + hw->multi_slice_pic_flag = 1; } - - } - mutex_unlock(&hw->chunks_mutex); - - check_decoded_pic_error(hw); -#ifdef ERROR_HANDLE_TEST - if ((hw->data_flag & ERROR_FLAG) - && (error_proc_policy & 0x80)) { - release_cur_decoding_buf(hw); - h264_clear_dpb(hw); - hw->dec_flag = 0; - hw->data_flag = 0; - hw->skip_frame_count = 0; - hw->has_i_frame = 0; - hw->no_error_count = 0xfff; - hw->no_error_i_count = 0xf; - } else #endif - ret = store_picture_in_dpb(p_H264_Dpb, - p_H264_Dpb->mVideo.dec_picture, - hw->data_flag | hw->dec_flag | - p_H264_Dpb->mVideo.dec_picture->data_flag); - +pic_done_proc: + reset_process_time(hw); + vh264_pic_done_proc(vdec); - if (ret == -1) { - release_cur_decoding_buf(hw); - bufmgr_force_recover(p_H264_Dpb); - } else { - if (hw->data_flag & ERROR_FLAG) { - hw->no_error_count = 0; - hw->no_error_i_count = 0; - } else { - hw->no_error_count++; - if (hw->data_flag & I_FLAG) - hw->no_error_i_count++; - } - if (hw->mmu_enable) - hevc_set_unused_4k_buff_idx(hw, - p_H264_Dpb->mVideo. - dec_picture->buf_spec_num); - bufmgr_post(p_H264_Dpb); - hw->last_dec_picture = - p_H264_Dpb->mVideo.dec_picture; - p_H264_Dpb->mVideo.dec_picture = NULL; - /* dump_dpb(&p_H264_Dpb->mDPB); */ - hw->has_i_frame = 1; - if (hw->mmu_enable) - hevc_set_frame_done(hw); - hw->decode_pic_count++; - p_H264_Dpb->decode_pic_count = hw->decode_pic_count; - if (hw->skip_frame_count > 0) { - /*skip n frame after first I */ - hw->skip_frame_count--; - if (hw->skip_frame_count == 0) - hw->dec_flag &= (~NODISP_FLAG); - } else if (hw->skip_frame_count < -1) { - /*skip n frame after first I until second I */ - hw->skip_frame_count++; - if (hw->skip_frame_count == -1) - hw->dec_flag &= (~NODISP_FLAG); - } - } - } if (hw->frmbase_cont_flag) { /*do not DEC_RESULT_GET_DATA*/ hw->get_data_count = 0x7fffffff; @@ -6034,11 +6258,6 @@ pic_done_proc: } else if (dec_dpb_status == H264_AUX_DATA_READY) { reset_process_time(hw); if (READ_VREG(H264_AUX_DATA_SIZE) != 0) { - dma_sync_single_for_cpu( - amports_get_dma_device(), - hw->aux_phy_addr, - hw->prefix_aux_size + hw->suffix_aux_size, - DMA_FROM_DEVICE); if (dpb_is_debug(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL)) dump_aux_buf(hw); @@ -6082,6 +6301,9 @@ pic_done_proc: (dec_dpb_status == H264_DECODE_TIMEOUT)) { empty_proc: reset_process_time(hw); + if ((error_proc_policy & 0x40000) && + dec_dpb_status == H264_DECODE_TIMEOUT) + goto pic_done_proc; if (!hw->frmbase_cont_flag) release_cur_decoding_buf(hw); @@ -6133,6 +6355,14 @@ empty_proc: vdec_schedule_work(&hw->work); } else { /* WRITE_VREG(DPB_STATUS_REG, H264_ACTION_INIT); */ +#ifdef DETECT_WRONG_MULTI_SLICE + if (hw->multi_slice_pic_flag == 1 && + hw->cur_picture_slice_count > 1 && + (error_proc_policy & 0x10000)) { + p_H264_Dpb->mVideo.pre_frame_num = hw->first_pre_frame_num; + } + hw->last_picture_slice_count = hw->cur_picture_slice_count; +#endif dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, "%s DEC_RESULT_AGAIN\n", __func__); send_again: @@ -6182,11 +6412,6 @@ send_again: u8 *sei_data_buf; u8 swap_byte; - dma_sync_single_for_cpu( - amports_get_dma_device(), - hw->aux_phy_addr, - hw->prefix_aux_size + hw->suffix_aux_size, - DMA_FROM_DEVICE); #if 0 dump_aux_buf(hw); #endif @@ -6240,12 +6465,6 @@ send_again: if (debug_tag & 0x10000) { unsigned short *p = (unsigned short *)hw->lmem_addr; - dma_sync_single_for_cpu( - amports_get_dma_device(), - hw->lmem_addr_remap, - PAGE_SIZE, - DMA_FROM_DEVICE); - dpb_print(DECODE_ID(hw), 0, "LMEM:\n", debug_tag); for (i = 0; i < 0x400; i += 4) { @@ -6317,9 +6536,11 @@ static irqreturn_t vh264_isr(struct vdec_s *vdec, int irq) p_H264_Dpb->dec_dpb_status = READ_VREG(DPB_STATUS_REG); dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT, - "%s DPB_STATUS_REG: 0x%x, ERROR_STATUS_REG 0x%x, sb (0x%x 0x%x 0x%x) bitcnt 0x%x mby_mbx 0x%x\n", + "%s DPB_STATUS_REG: 0x%x, run(%d) last_state (%x) ERROR_STATUS_REG 0x%x, sb (0x%x 0x%x 0x%x) bitcnt 0x%x mby_mbx 0x%x\n", __func__, p_H264_Dpb->dec_dpb_status, + run_count[DECODE_ID(hw)], + hw->dec_result, READ_VREG(ERROR_STATUS_REG), READ_VREG(VLD_MEM_VIFIFO_LEVEL), READ_VREG(VLD_MEM_VIFIFO_WP), @@ -6415,7 +6636,7 @@ static void vmh264_dump_state(struct vdec_s *vdec) ); dpb_print(DECODE_ID(hw), 0, - "is_framebase(%d), eos %d, state 0x%x, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d bufmgr_reset_cnt %d\n", + "is_framebase(%d), eos %d, state 0x%x, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d bufmgr_reset_cnt %d error_frame_count = %d, drop_frame_count = %d\n", input_frame_based(vdec), hw->eos, hw->stat, @@ -6425,9 +6646,21 @@ static void vmh264_dump_state(struct vdec_s *vdec) run_count[DECODE_ID(hw)], not_run_ready[DECODE_ID(hw)], input_empty[DECODE_ID(hw)], - hw->reset_bufmgr_count + hw->reset_bufmgr_count, + hw->gvs.error_frame_count, + hw->gvs.drop_frame_count ); +#ifdef DETECT_WRONG_MULTI_SLICE + dpb_print(DECODE_ID(hw), 0, + "MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d)\n", + hw->multi_slice_pic_check_count, + hw->picture_slice_count, + hw->cur_picture_slice_count, + hw->multi_slice_pic_flag); +#endif + + if (vf_get_receiver(vdec->vf_provider_name)) { enum receviver_start_e state = vf_notify_receiver(vdec->vf_provider_name, @@ -6561,7 +6794,8 @@ static void check_timer_func(unsigned long arg) return; } - if (vdec->next_status == VDEC_STATUS_DISCONNECTED) { + if (vdec->next_status == VDEC_STATUS_DISCONNECTED && + !hw->is_used_v4l) { hw->dec_result = DEC_RESULT_FORCE_EXIT; vdec_schedule_work(&hw->work); pr_debug("vdec requested to be disconnected\n"); @@ -6578,9 +6812,7 @@ static void check_timer_func(unsigned long arg) radr = 0; } - if ((input_frame_based(vdec) || - (READ_VREG(VLD_MEM_VIFIFO_LEVEL) > 0xb0)) && - ((h264_debug_flag & DISABLE_ERROR_HANDLE) == 0) && + if (((h264_debug_flag & DISABLE_ERROR_HANDLE) == 0) && (timeout_val > 0) && (hw->start_process_time > 0) && ((1000 * (jiffies - hw->start_process_time) / HZ) @@ -6629,7 +6861,7 @@ static void check_timer_func(unsigned long arg) static int dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) { - u32 ar; + u32 ar, ar_tmp; struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; if (!hw) @@ -6637,22 +6869,29 @@ static int dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) vstatus->frame_width = hw->frame_width; vstatus->frame_height = hw->frame_height; - if (hw->frame_dur != 0) + if (hw->frame_dur != 0) { + vstatus->frame_dur = hw->frame_dur; vstatus->frame_rate = 96000 / hw->frame_dur; + } else vstatus->frame_rate = -1; - vstatus->error_count = 0; + vstatus->error_count = hw->gvs.error_frame_count; vstatus->status = hw->stat; if (hw->h264_ar == 0x3ff) - hw->h264_ar = (0x100 * + ar_tmp = (0x100 * hw->frame_height * hw->height_aspect_ratio) / (hw->frame_width * hw->width_aspect_ratio); + else + ar_tmp = hw->h264_ar; ar = min_t(u32, - hw->h264_ar, + ar_tmp, DISP_RATIO_ASPECT_RATIO_MAX); vstatus->ratio_control = ar << DISP_RATIO_ASPECT_RATIO_BIT; + vstatus->error_frame_count = hw->gvs.error_frame_count; + vstatus->drop_frame_count = hw->gvs.drop_frame_count; + vstatus->frame_count = decode_frame_count[DECODE_ID(hw)]; snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name), "%s-%02d", DRIVER_NAME, hw->id); @@ -6731,6 +6970,8 @@ static int vh264_hw_ctx_restore(struct vdec_h264_hw_s *hw) && (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21 || v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M)) SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16); + else + CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16); SET_VREG_MASK(MDEC_PIC_DC_CTRL, 0xbf << 24); CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 0xbf << 24); @@ -6805,7 +7046,7 @@ static int vh264_hw_ctx_restore(struct vdec_h264_hw_s *hw) else*/ CLEAR_VREG_MASK(AV_SCRATCH_F, 1 << 6); - WRITE_VREG(LMEM_DUMP_ADR, (u32)hw->lmem_addr_remap); + WRITE_VREG(LMEM_DUMP_ADR, (u32)hw->lmem_phy_addr); #if 1 /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa); #endif @@ -7057,28 +7298,15 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw) } #if 1 /* #ifdef BUFFER_MGR_IN_C */ - hw->lmem_addr = __get_free_page(GFP_KERNEL); - if (!hw->lmem_addr) { - pr_info("%s: failed to alloc lmem_addr\n", __func__); - return -ENOMEM; - } else { - hw->lmem_addr_remap = dma_map_single( - amports_get_dma_device(), - (void *)hw->lmem_addr, - PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(amports_get_dma_device(), - hw->lmem_addr_remap)) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR, - "%s: failed to map lmem_addr\n", __func__); - free_page(hw->lmem_addr); - hw->lmem_addr = 0; - hw->lmem_addr_remap = 0; - return -ENOMEM; - } + hw->lmem_addr = (dma_addr_t)dma_alloc_coherent(amports_get_dma_device(), + PAGE_SIZE, (dma_addr_t *)&hw->lmem_phy_addr, GFP_KERNEL); - pr_debug("%s, vaddr=%lx phy_addr=%p\n", - __func__, hw->lmem_addr, (void *)hw->lmem_addr_remap); + if (hw->lmem_addr == 0) { + pr_err("%s: failed to alloc lmem buffer\n", __func__); + return -1; } + pr_debug("%s, phy_addr=%lx vaddr=%p\n", + __func__, hw->lmem_phy_addr, (void *)hw->lmem_addr); if (prefix_aux_buf_size > 0 || suffix_aux_buf_size > 0) { @@ -7086,21 +7314,14 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw) hw->prefix_aux_size = AUX_BUF_ALIGN(prefix_aux_buf_size); hw->suffix_aux_size = AUX_BUF_ALIGN(suffix_aux_buf_size); aux_buf_size = hw->prefix_aux_size + hw->suffix_aux_size; - hw->aux_addr = kmalloc(aux_buf_size, GFP_KERNEL); + hw->aux_addr = dma_alloc_coherent(amports_get_dma_device(), + aux_buf_size, &hw->aux_phy_addr, + GFP_KERNEL); if (hw->aux_addr == NULL) { pr_err("%s: failed to alloc rpm buffer\n", __func__); return -1; } - hw->aux_phy_addr = dma_map_single(amports_get_dma_device(), - hw->aux_addr, aux_buf_size, DMA_FROM_DEVICE); - if (dma_mapping_error(amports_get_dma_device(), - hw->aux_phy_addr)) { - pr_err("%s: failed to map rpm buffer\n", __func__); - kfree(hw->aux_addr); - hw->aux_addr = NULL; - return -1; - } hw->sei_data_buf = kmalloc(SEI_DATA_SIZE, GFP_KERNEL); if (hw->sei_data_buf == NULL) { pr_err("%s: failed to alloc sei itu data buffer\n", @@ -7111,7 +7332,9 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw) if (hw->sei_itu_data_buf == NULL) { pr_err("%s: failed to alloc sei itu data buffer\n", __func__); - kfree(hw->aux_addr); + dma_free_coherent(amports_get_dma_device(), + hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr, + hw->aux_phy_addr); hw->aux_addr = NULL; kfree(hw->sei_data_buf); hw->sei_data_buf = NULL; @@ -7125,7 +7348,9 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw) if (!hw->sei_user_data_buffer) { pr_info("%s: Can not allocate sei_data_buffer\n", __func__); - kfree(hw->aux_addr); + dma_free_coherent(amports_get_dma_device(), + hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr, + hw->aux_phy_addr); hw->aux_addr = NULL; kfree(hw->sei_data_buf); hw->sei_data_buf = NULL; @@ -7183,22 +7408,17 @@ static int vh264_stop(struct vdec_h264_hw_s *hw) vdec_free_irq(VDEC_IRQ_1, (void *)hw); hw->stat &= ~STAT_ISR_REG; } - if (hw->lmem_addr_remap) { - dma_unmap_single(amports_get_dma_device(), - hw->lmem_addr_remap, - PAGE_SIZE, DMA_FROM_DEVICE); - hw->lmem_addr_remap = 0; - } if (hw->lmem_addr) { - free_page(hw->lmem_addr); + dma_free_coherent(amports_get_dma_device(), + PAGE_SIZE, (void *)hw->lmem_addr, + hw->lmem_phy_addr); hw->lmem_addr = 0; } + if (hw->aux_addr) { - dma_unmap_single(amports_get_dma_device(), - hw->aux_phy_addr, - hw->prefix_aux_size + hw->suffix_aux_size, - DMA_FROM_DEVICE); - kfree(hw->aux_addr); + dma_free_coherent(amports_get_dma_device(), + hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr, + hw->aux_phy_addr); hw->aux_addr = NULL; } if (hw->sei_data_buf != NULL) { @@ -7884,6 +8104,117 @@ static void vmh264_wakeup_userdata_poll(struct vdec_s *vdec) #endif +static int vmh264_get_ps_info(struct vdec_h264_hw_s *hw, u32 param1, u32 param4, struct aml_vdec_ps_infos *ps) +{ + struct vdec_s *vdec = hw_to_vdec(hw); + int mb_width, mb_total; + int mb_height = 0; + int active_buffer_spec_num; + int max_reference_size ,level_idc; + unsigned int used_reorder_dpb_size_margin + = hw->reorder_dpb_size_margin; + int reorder_pic_num; + + level_idc = param4 & 0xff; + max_reference_size = (param4 >> 8) & 0xff; + +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + if (vdec->master || vdec->slave) + used_reorder_dpb_size_margin = + reorder_dpb_size_margin_dv; +#endif + mb_width = param1 & 0xff; + mb_total = (param1 >> 8) & 0xffff; + if (!mb_width && mb_total) /*for 4k2k*/ + mb_width = 256; + if (mb_width) + mb_height = mb_total/mb_width; + if (mb_width <= 0 || mb_height <= 0 || + is_oversize(mb_width << 4, mb_height << 4)) { + dpb_print(DECODE_ID(hw), 0, + "!!!wrong param1 0x%x mb_width/mb_height (0x%x/0x%x) %x\r\n", + param1, + mb_width, + mb_height); + return -1; + } + + reorder_pic_num = + get_max_dec_frame_buf_size(level_idc, + max_reference_size, mb_width, mb_height); + + if ((hw->bitstream_restriction_flag) && + (hw->max_dec_frame_buffering < + reorder_pic_num)) { + reorder_pic_num = hw->max_dec_frame_buffering; + dpb_print(DECODE_ID(hw), 0, + "set reorder_pic_num to %d\n", + reorder_pic_num); + } + + active_buffer_spec_num = + reorder_pic_num + + used_reorder_dpb_size_margin; + + if (active_buffer_spec_num > MAX_VF_BUF_NUM) { + active_buffer_spec_num = MAX_VF_BUF_NUM; + reorder_pic_num = active_buffer_spec_num + - used_reorder_dpb_size_margin; + } + + if (hw->no_poc_reorder_flag) + reorder_pic_num = 1; + + ps->profile = level_idc; + ps->ref_frames = max_reference_size; + ps->mb_width = mb_width; + ps->mb_height = mb_height; + ps->visible_width = mb_width << 4; + ps->visible_height = mb_height << 4; + ps->coded_width = ALIGN(mb_width << 4, 64); + ps->coded_height = ALIGN(mb_height << 4, 64); + ps->reorder_frames = reorder_pic_num; + ps->dpb_size = active_buffer_spec_num; + + return 0; +} + +static int v4l_res_change(struct vdec_h264_hw_s *hw, u32 param1, u32 param4) +{ + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hw->v4l2_ctx); + struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; + int ret = 0; + + if (ctx->param_sets_from_ucode && + hw->res_ch_flag == 0) { + if (param1 != 0 && + hw->seq_info2 != (param1 & (~0x80000000)) && + hw->seq_info2 != 0) /*picture size changed*/ { + struct aml_vdec_ps_infos ps; + dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, "h264 res_change\n"); + if (vmh264_get_ps_info(hw, param1, param4, &ps) < 0) { + dpb_print(DECODE_ID(hw), 0, "set parameters error\n"); + } + hw->v4l_params_parsed = false; + vdec_v4l_set_ps_infos(ctx, &ps); + vdec_v4l_res_ch_event(ctx); + hw->res_ch_flag = 1; + amvdec_stop(); + if (hw->mmu_enable) + amhevc_stop(); + hw->eos = 1; + flush_dpb(p_H264_Dpb); + //del_timer_sync(&hw->check_timer); + if (hw->is_used_v4l) + notify_v4l_eos(hw_to_vdec(hw)); + ret = 1; + } + } + + return ret; + +} static void vh264_work_implement(struct vdec_h264_hw_s *hw, struct vdec_s *vdec, int from) @@ -7909,34 +8240,48 @@ static void vh264_work_implement(struct vdec_h264_hw_s *hw, u32 param2 = READ_VREG(AV_SCRATCH_2); u32 param3 = READ_VREG(AV_SCRATCH_6); u32 param4 = READ_VREG(AV_SCRATCH_B); - - if (vh264_set_params(hw, param1, - param2, param3, param4) < 0) - dpb_print(DECODE_ID(hw), 0, "set parameters error\n"); - - WRITE_VREG(AV_SCRATCH_0, (hw->max_reference_size<<24) | - (hw->dpb.mDPB.size<<16) | - (hw->dpb.mDPB.size<<8)); - - if (hw->is_used_v4l) { - struct aml_vcodec_ctx *ctx = + struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) { - struct aml_vdec_ps_infos ps; - - ps.visible_width = hw->frame_width; - ps.visible_height = hw->frame_height; - ps.coded_width = ALIGN(hw->frame_width, 64); - ps.coded_height = ALIGN(hw->frame_height, 64); - ps.dpb_size = hw->dpb.mDPB.size; - hw->v4l_params_parsed = true; - vdec_v4l_set_ps_infos(ctx, &ps); + if (hw->is_used_v4l && + ctx->param_sets_from_ucode) { + if (!v4l_res_change(hw, param1, param4)) { + if (!hw->v4l_params_parsed) { + struct aml_vdec_ps_infos ps; + dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, "h264 parsered csd data\n"); + if (vmh264_get_ps_info(hw, param1, param4, &ps) < 0) { + dpb_print(DECODE_ID(hw), 0, "set parameters error\n"); + } + hw->v4l_params_parsed = true; + vdec_v4l_set_ps_infos(ctx, &ps); + amvdec_stop(); + if (hw->mmu_enable) + amhevc_stop(); + } + else { + if (vh264_set_params(hw, param1, + param2, param3, param4) < 0) + dpb_print(DECODE_ID(hw), 0, "set parameters error\n"); + + WRITE_VREG(AV_SCRATCH_0, (hw->max_reference_size<<24) | + (hw->dpb.mDPB.size<<16) | + (hw->dpb.mDPB.size<<8)); + hw->res_ch_flag = 0; + start_process_time(hw); + return; + } } - } + } else { + if (vh264_set_params(hw, param1, + param2, param3, param4) < 0) + dpb_print(DECODE_ID(hw), 0, "set parameters error\n"); - start_process_time(hw); - return; + WRITE_VREG(AV_SCRATCH_0, (hw->max_reference_size<<24) | + (hw->dpb.mDPB.size<<16) | + (hw->dpb.mDPB.size<<8)); + start_process_time(hw); + return; + } } else if (((hw->dec_result == DEC_RESULT_GET_DATA) || (hw->dec_result == DEC_RESULT_GET_DATA_RETRY)) @@ -8043,6 +8388,22 @@ static void vh264_work_implement(struct vdec_h264_hw_s *hw, /* if (!hw->ctx_valid) hw->ctx_valid = 1; */ result_done: + { + if (error_proc_policy & 0x8000) { + struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; + int i; + struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; + + for (i = 0; i < p_Dpb->used_size; i++) { + if (p_Dpb->fs[i]->dpb_frame_count + 500 < p_H264_Dpb->dpb_frame_count) { + dpb_print(DECODE_ID(hw), + 0, + "unmark reference dpb_frame_count diffrence large in dpb\n"); + unmark_for_reference(p_Dpb, p_Dpb->fs[i]); + } + } + } + } if (hw->mmu_enable && hw->frame_busy && hw->frame_done) { long used_4k_num; @@ -8127,7 +8488,10 @@ result_done: WRITE_VREG(ASSIST_MBOX1_MASK, 0); del_timer_sync(&hw->check_timer); hw->stat &= ~STAT_TIMER_ARM; - +#ifdef DETECT_WRONG_MULTI_SLICE + if (hw->dec_result != DEC_RESULT_AGAIN) + hw->last_picture_slice_count = 0; +#endif wait_vmh264_search_done(hw); /* mark itself has all HW resource released and input released */ @@ -8297,15 +8661,24 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - if (ctx->param_sets_from_ucode && - !ctx->v4l_codec_ready && - hw->v4l_params_parsed) { - ret = 0; /*the params has parsed.*/ + if (ctx->param_sets_from_ucode) { + if (hw->v4l_params_parsed) { + if (!ctx->v4l_codec_dpb_ready && + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < + run_ready_min_buf_num) + ret = 0; + } else { + if ((hw->res_ch_flag == 1) && + ((ctx->state <= AML_STATE_INIT) || + (ctx->state >= AML_STATE_FLUSHING))) + ret = 0; + } } else if (!ctx->v4l_codec_dpb_ready) { if (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < run_ready_min_buf_num) ret = 0; } + } if (ret) @@ -8358,6 +8731,10 @@ static void run(struct vdec_s *vdec, unsigned long mask, hw->vdec_cb_arg = arg; hw->vdec_cb = callback; +#ifdef DETECT_WRONG_MULTI_SLICE + hw->cur_picture_slice_count = 0; +#endif + if (kfifo_len(&hw->display_q) > VF_POOL_SIZE) { hw->reset_bufmgr_flag = 1; dpb_print(DECODE_ID(hw), 0, @@ -8504,7 +8881,7 @@ static void run(struct vdec_s *vdec, unsigned long mask, } vdec->mc_type = ((1 << 16) | VFORMAT_H264); } - vdec->mc_loaded = 1; + vdec->mc_loaded = 0; } vmh264_reset_udr_mgr(hw); @@ -8520,6 +8897,8 @@ static void run(struct vdec_s *vdec, unsigned long mask, WRITE_VREG(H264_DECODE_INFO, (1<<13)); WRITE_VREG(H264_DECODE_SIZE, decode_size); WRITE_VREG(VIFF_BIT_CNT, decode_size * 8); + if (vdec->mvfrm) + vdec->mvfrm->frame_size = hw->chunk->size; } else { if (size <= 0) size = 0x7fffffff; /*error happen*/ @@ -8553,6 +8932,8 @@ static void run(struct vdec_s *vdec, unsigned long mask, else CLEAR_VREG_MASK(VDEC_ASSIST_MMC_CTRL1, 1 << 3); } + if (vdec->mvfrm) + vdec->mvfrm->hw_decode_start = local_clock(); amvdec_start(); if (hw->mmu_enable /*&& !hw->frame_busy && !hw->frame_done*/) { WRITE_VREG(HEVC_ASSIST_SCRATCH_0, 0x0); @@ -8600,7 +8981,9 @@ static void reset(struct vdec_s *vdec) cancel_work_sync(&hw->work); cancel_work_sync(&hw->notify_work); if (hw->stat & STAT_VDEC_RUN) { - amhevc_stop(); + amvdec_stop(); + if (hw->mmu_enable) + amhevc_stop(); hw->stat &= ~STAT_VDEC_RUN; } @@ -8715,6 +9098,7 @@ static void h264_reset_bufmgr(struct vdec_s *vdec) { ulong timeout; struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; + struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; #if 0 struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; int actual_dpb_size, max_reference_size; @@ -8771,6 +9155,8 @@ static void h264_reset_bufmgr(struct vdec_s *vdec) __func__, hw->decode_pic_count+1, hw->skip_frame_count); + flush_dpb(&hw->dpb); + timeout = jiffies + HZ; while (kfifo_len(&hw->display_q) > 0) { if (time_after(jiffies, timeout)) @@ -8778,8 +9164,6 @@ static void h264_reset_bufmgr(struct vdec_s *vdec) schedule(); } - vf_notify_receiver(vdec->vf_provider_name, VFRAME_EVENT_PROVIDER_RESET, NULL); - buf_spec_init(hw); vh264_local_init(hw, true); @@ -8797,7 +9181,10 @@ static void h264_reset_bufmgr(struct vdec_s *vdec) if (first_i_policy & 0x01) hw->first_i_policy = (3 << 8) | first_i_policy; + p_H264_Dpb->first_insert_frame = FirstInsertFrm_RESET; + hw->init_flag = 1; + hw->reset_bufmgr_count++; #endif } @@ -8880,8 +9267,6 @@ static int ammvdec_h264_probe(struct platform_device *pdev) hw->mmu_enable = 0; hw->first_head_check_flag = 0; - hw->new_iframe_flag = 0; - hw->ref_err_flush_dpb_flag = 0; if (pdata->sys_info) hw->vh264_amstream_dec_info = *pdata->sys_info; @@ -9128,6 +9513,9 @@ static int ammvdec_h264_probe(struct platform_device *pdev) | CORE_MASK_COMBINE); atomic_set(&hw->vh264_active, 1); + vdec_set_vframe_comm(pdata, DRIVER_NAME); + display_frame_count[DECODE_ID(hw)] = 0; + decode_frame_count[DECODE_ID(hw)] = 0; return 0; } @@ -9483,6 +9871,11 @@ MODULE_PARM_DESC(mem_map_mode, "\n mem_map_mode\n"); module_param(without_display_mode, uint, 0664); MODULE_PARM_DESC(without_display_mode, "\n without_display_mode\n"); +module_param(check_slice_num, uint, 0664); +MODULE_PARM_DESC(check_slice_num, "\n check_slice_num\n"); + +module_param(mb_count_threshold, uint, 0664); +MODULE_PARM_DESC(mb_count_threshold, "\n mb_count_threshold\n"); module_init(ammvdec_h264_driver_init_module); module_exit(ammvdec_h264_driver_remove_module); diff --git a/drivers/frame_provider/decoder/h265/vh265.c b/drivers/frame_provider/decoder/h265/vh265.c index 8d4e0f3..53aeb10 100644 --- a/drivers/frame_provider/decoder/h265/vh265.c +++ b/drivers/frame_provider/decoder/h265/vh265.c @@ -49,6 +49,8 @@ #include "../utils/vdec_v4l2_buffer_ops.h" #include +#define HEVC_8K_LFTOFFSET_FIX + #define CONSTRAIN_MAX_BUF_NUM #define SWAP_HEVC_UCODE @@ -185,7 +187,7 @@ static int start_decode_buf_level = 0x8000; static unsigned int decode_timeout_val = 200; static u32 run_ready_min_buf_num = 2; - +static u32 disable_ip_mode; /*data_resend_policy: bit 0, stream base resend data when decoding buf empty */ @@ -473,8 +475,11 @@ static unsigned int force_disp_pic_index; static unsigned int disp_vframe_valve_level; static int pre_decode_buf_level = 0x1000; static unsigned int pic_list_debug; - - +#ifdef HEVC_8K_LFTOFFSET_FIX + /* performance_profile: bit 0, multi slice in ucode + */ +static unsigned int performance_profile = 1; +#endif #ifdef MULTI_INSTANCE_SUPPORT static unsigned int max_decode_instance_num = MAX_DECODE_INSTANCE_NUM; @@ -532,12 +537,13 @@ void WRITE_VREG_DBG(unsigned adr, unsigned val) #undef WRITE_VREG #define WRITE_VREG WRITE_VREG_DBG #endif +extern u32 trickmode_i; static DEFINE_MUTEX(vh265_mutex); static DEFINE_MUTEX(vh265_log_mutex); -static struct vdec_info *gvs; +//static struct vdec_info *gvs; static u32 without_display_mode; @@ -822,7 +828,7 @@ union param_u { unsigned short tiles_enabled_flag; unsigned short num_tile_columns_minus1; unsigned short num_tile_rows_minus1; - unsigned short tile_width[8]; + unsigned short tile_width[12]; unsigned short tile_height[8]; unsigned short misc_flag0; unsigned short pps_beta_offset_div2; @@ -1312,6 +1318,8 @@ struct BUF_s { u32 header_size; int used_flag; ulong v4l_ref_buf_addr; + ulong chroma_addr; + u32 chroma_size; } /*BUF_t */; /* level 6, 6.1 maximum slice number is 800; other is 200 */ @@ -1403,7 +1411,10 @@ struct PIC_s { int min_mv; int avg_mv; + u32 hw_decode_time; + u32 frame_size; // For frame base mode bool vframe_bound; + bool ip_mode; } /*PIC_t */; #define MAX_TILE_COL_NUM 10 @@ -1736,6 +1747,10 @@ struct hevc_state_s { void *v4l2_ctx; bool v4l_params_parsed; u32 mem_map_mode; + u32 performance_profile; + struct vdec_info *gvs; + unsigned int res_ch_flag; + bool ip_mode; } /*hevc_stru_t */; #ifdef AGAIN_HAS_THRESHOLD @@ -1947,6 +1962,31 @@ static int get_double_write_mode(struct hevc_state_s *hevc) return dw; } +static int v4l_parser_get_double_write_mode(struct hevc_state_s *hevc, int w, int h) +{ + u32 valid_dw_mode = get_valid_double_write_mode(hevc); + u32 dw = 0x1; /*1:1*/ + switch (valid_dw_mode) { + case 0x100: + if (w > 1920 && h > 1088) + dw = 0x4; /*1:2*/ + break; + case 0x200: + if (w > 1920 && h > 1088) + dw = 0x2; /*1:4*/ + break; + case 0x300: + if (w > 1280 && h > 720) + dw = 0x4; /*1:2*/ + break; + default: + dw = valid_dw_mode; + break; + } + return dw; +} + + static int get_double_write_ratio(struct hevc_state_s *hevc, int dw_mode) { @@ -3096,15 +3136,21 @@ static int v4l_alloc_buf(struct hevc_state_s *hevc, struct PIC_s *pic) pic->cma_alloc_addr = hevc->m_BUF[i].v4l_ref_buf_addr; if (fb->num_planes == 1) { hevc->m_BUF[i].start_adr = fb->m.mem[0].addr; - hevc->m_BUF[i].size = fb->m.mem[0].size; hevc->m_BUF[i].luma_size = fb->m.mem[0].offset; + hevc->m_BUF[i].size = fb->m.mem[0].size; fb->m.mem[0].bytes_used = fb->m.mem[0].size; + pic->dw_y_adr = hevc->m_BUF[i].start_adr; + pic->dw_u_v_adr = pic->dw_y_adr + hevc->m_BUF[i].luma_size; } else if (fb->num_planes == 2) { hevc->m_BUF[i].start_adr = fb->m.mem[0].addr; - hevc->m_BUF[i].size = fb->m.mem[0].size + fb->m.mem[1].size; hevc->m_BUF[i].luma_size = fb->m.mem[0].size; + hevc->m_BUF[i].chroma_addr = fb->m.mem[1].addr; + hevc->m_BUF[i].chroma_size = fb->m.mem[1].size; + hevc->m_BUF[i].size = fb->m.mem[0].size + fb->m.mem[1].size; fb->m.mem[0].bytes_used = fb->m.mem[0].size; fb->m.mem[1].bytes_used = fb->m.mem[1].size; + pic->dw_y_adr = hevc->m_BUF[i].start_adr; + pic->dw_u_v_adr = hevc->m_BUF[i].chroma_addr; } return ret; @@ -3297,11 +3343,68 @@ static int get_work_pic_num(struct hevc_state_s *hevc) used_buf_num += 1; } + if (hevc->is_used_v4l) { + /* for eos add more buffer to flush.*/ + used_buf_num++; + } + if (used_buf_num > MAX_BUF_NUM) used_buf_num = MAX_BUF_NUM; return used_buf_num; } +static int v4l_parser_work_pic_num(struct hevc_state_s *hevc) +{ + int used_buf_num = 0; + int sps_pic_buf_diff = 0; + pr_debug("margin = %d, sps_max_dec_pic_buffering_minus1_0 = %d, sps_num_reorder_pics_0 = %d\n", + get_dynamic_buf_num_margin(hevc), + hevc->param.p.sps_max_dec_pic_buffering_minus1_0, + hevc->param.p.sps_num_reorder_pics_0); + if (get_dynamic_buf_num_margin(hevc) > 0) { + if ((!hevc->param.p.sps_num_reorder_pics_0) && + (hevc->param.p.sps_max_dec_pic_buffering_minus1_0)) { + /* the range of sps_num_reorder_pics_0 is in + [0, sps_max_dec_pic_buffering_minus1_0] */ + used_buf_num = get_dynamic_buf_num_margin(hevc) + + hevc->param.p.sps_max_dec_pic_buffering_minus1_0; + } else + used_buf_num = hevc->param.p.sps_num_reorder_pics_0 + + get_dynamic_buf_num_margin(hevc); + + sps_pic_buf_diff = hevc->param.p.sps_max_dec_pic_buffering_minus1_0 + - hevc->param.p.sps_num_reorder_pics_0; +#ifdef MULTI_INSTANCE_SUPPORT + /* + need one more for multi instance, as + apply_ref_pic_set() has no chanch to run to + to clear referenced flag in some case + */ + if (hevc->m_ins_flag) + used_buf_num++; +#endif + } else + used_buf_num = max_buf_num; + + if (hevc->save_buffer_mode) + hevc_print(hevc, 0, + "save buf _mode : dynamic_buf_num_margin %d ----> %d \n", + dynamic_buf_num_margin, hevc->dynamic_buf_num_margin); + + if (sps_pic_buf_diff >= 4) + { + used_buf_num += 1; + } + + /* for eos add more buffer to flush.*/ + used_buf_num++; + + if (used_buf_num > MAX_BUF_NUM) + used_buf_num = MAX_BUF_NUM; + return used_buf_num; +} + + static int get_alloc_pic_count(struct hevc_state_s *hevc) { int alloc_pic_count = 0; @@ -3329,16 +3432,10 @@ static int v4l_config_pic(struct hevc_state_s *hevc, struct PIC_s *pic) pic->mc_canvas_u_v = pic->index; if (dw_mode & 0x10) { - pic->mc_y_adr = hevc->m_BUF[i].start_adr; - pic->mc_u_v_adr = pic->mc_y_adr + hevc->m_BUF[i].luma_size; pic->mc_canvas_y = (pic->index << 1); pic->mc_canvas_u_v = (pic->index << 1) + 1; - - pic->dw_y_adr = pic->mc_y_adr; - pic->dw_u_v_adr = pic->mc_u_v_adr; - } else if (dw_mode) { - pic->dw_y_adr = hevc->m_BUF[i].start_adr; - pic->dw_u_v_adr = pic->dw_y_adr + hevc->m_BUF[i].luma_size; + pic->mc_y_adr = pic->dw_y_adr; + pic->mc_u_v_adr = pic->dw_u_v_adr; } return 0; @@ -3493,30 +3590,6 @@ static void init_pic_list(struct hevc_state_s *hevc) set_canvas(hevc, pic); } } - - for (; i < MAX_REF_PIC_NUM; i++) { - struct PIC_s *pic = hevc->m_PIC[i]; - - if (!pic) { - pic = vmalloc(sizeof(struct PIC_s)); - if (pic == NULL) { - hevc_print(hevc, 0, - "%s: alloc pic %d fail!!!\n", - __func__, i); - break; - } - hevc->m_PIC[i] = pic; - } - memset(pic, 0, sizeof(struct PIC_s)); - - pic->index = -1; - pic->BUF_index = -1; - if (vdec->parallel_dec == 1) { - pic->y_canvas_index = -1; - pic->uv_canvas_index = -1; - } - } - } static void uninit_pic_list(struct hevc_state_s *hevc) @@ -3644,31 +3717,6 @@ static void init_pic_list_hw(struct hevc_state_s *hevc) } if (cur_pic_num == 0) return; - for (; i < MAX_REF_PIC_NUM; i++) { - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) { - if (hevc->mmu_enable && ((dw_mode & 0x10) == 0)) - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, - hevc->m_PIC[cur_pic_num-1]->header_adr>>5); - else - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, - hevc->m_PIC[cur_pic_num-1]->mc_y_adr >> 5); -#ifndef LOSLESS_COMPRESS_MODE - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, - hevc->m_PIC[cur_pic_num-1]->mc_u_v_adr >> 5); -#endif - } else { - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, - hevc->m_PIC[cur_pic_num-1]->mc_y_adr| - (hevc->m_PIC[cur_pic_num-1]->mc_canvas_y<<8) - | 0x1); -#ifndef LOSLESS_COMPRESS_MODE - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, - hevc->m_PIC[cur_pic_num-1]->mc_u_v_adr| - (hevc->m_PIC[cur_pic_num-1]->mc_canvas_u_v<<8) - | 0x1); -#endif - } - } WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1); @@ -3748,7 +3796,7 @@ static struct PIC_s *output_pic(struct hevc_state_s *hevc, unsigned char flush_flag) { int num_pic_not_yet_display = 0; - int i; + int i, fisrt_pic_flag = 0; struct PIC_s *pic; struct PIC_s *pic_display = NULL; struct vdec_s *vdec = hw_to_vdec(hevc); @@ -3796,6 +3844,7 @@ static struct PIC_s *output_pic(struct hevc_state_s *hevc, pic->num_reorder_pic = 0; if (vdec->master || vdec->slave) pic_display = pic; + fisrt_pic_flag = 1; hevc_print(hevc, 0, "VH265: output first frame\n"); } } @@ -3817,10 +3866,21 @@ static struct PIC_s *output_pic(struct hevc_state_s *hevc, decode_idx)) pic_display = pic; + } else pic_display = pic; + } } + /* dv wait cur_pic all data get, + some data may get after picture output */ + if ((vdec->master || vdec->slave) + && (pic_display == hevc->cur_pic) && + (!flush_flag) && + (hevc->bypass_dvenl && !dolby_meta_with_el) + && (!fisrt_pic_flag)) + pic_display = NULL; + if (pic_display) { if ((num_pic_not_yet_display > pic_display->num_reorder_pic) @@ -3841,7 +3901,8 @@ static struct PIC_s *output_pic(struct hevc_state_s *hevc, } } - if (pic_display && (hevc->vf_pre_count == 1) && (hevc->first_pic_flag == 1)) { + if (pic_display && hevc->sps_num_reorder_pics_0 && + (hevc->vf_pre_count == 1) && (hevc->first_pic_flag == 1)) { pic_display = NULL; hevc->first_pic_flag = 0; } @@ -4473,6 +4534,13 @@ static void hevc_config_work_space_hw(struct hevc_state_s *hevc) buf_spec->swap_buf.buf_start); WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, buf_spec->swap_buf2.buf_start);*/ WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start); +#ifdef HEVC_8K_LFTOFFSET_FIX + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { + WRITE_VREG(HEVC_DBLK_CFG3, 0x808020); /*offset should x2 if 8k*/ + hevc_print(hevc, H265_DEBUG_BUFMGR_MORE, + "write HEVC_DBLK_CFG3\n"); + } +#endif /* cfg_p_addr */ WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start); /* cfg_d_addr */ @@ -5312,8 +5380,8 @@ static void config_sao_hw(struct hevc_state_s *hevc, union param_u *params) /* swap uv */ if (hevc->is_used_v4l) { - if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) || - (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M)) + if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21) || + (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21M)) data32 &= ~(1 << 8); /* NV21 */ else data32 |= (1 << 8); /* NV12 */ @@ -5355,8 +5423,8 @@ static void config_sao_hw(struct hevc_state_s *hevc, union param_u *params) /* swap uv */ if (hevc->is_used_v4l) { - if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) || - (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M)) + if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21) || + (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21M)) data32 |= (1 << 12); /* NV21 */ else data32 &= ~(1 << 12); /* NV12 */ @@ -5625,6 +5693,7 @@ static struct PIC_s *get_new_pic(struct hevc_state_s *hevc, new_pic->dis_mark = 0; /* new_pic->output_ready = 0; */ new_pic->num_reorder_pic = rpm_param->p.sps_num_reorder_pics_0; + new_pic->ip_mode = (!new_pic->num_reorder_pic && !disable_ip_mode) ? true : false; new_pic->losless_comp_body_size = hevc->losless_comp_body_size; new_pic->POC = hevc->curr_POC; new_pic->pic_struct = hevc->curr_pic_struct; @@ -5748,6 +5817,7 @@ static struct PIC_s *v4l_get_new_pic(struct hevc_state_s *hevc, new_pic->dis_mark = 0; /* new_pic->output_ready = 0; */ new_pic->num_reorder_pic = rpm_param->p.sps_num_reorder_pics_0; + new_pic->ip_mode = (!new_pic->num_reorder_pic && !disable_ip_mode) ? true : false; new_pic->losless_comp_body_size = hevc->losless_comp_body_size; new_pic->POC = hevc->curr_POC; new_pic->pic_struct = hevc->curr_pic_struct; @@ -5821,11 +5891,8 @@ static void flush_output(struct hevc_state_s *hevc, struct PIC_s *pic) hevc->ignore_bufmgr_error |= 0x2; } } - /**/ - if (pic->POC != INVALID_POC) { + if (pic->POC != INVALID_POC && !pic->ip_mode) pic->output_mark = 1; - pic->recon_mark = 1; - } pic->recon_mark = 1; } do { @@ -5851,6 +5918,14 @@ static void flush_output(struct hevc_state_s *hevc, struct PIC_s *pic) hevc_print_cont(hevc, 0, "Debug mode or error, recycle it\n"); } + /* + * Here the pic/frame error_mark is 1, + * and it won't be displayed, so increase + * the drop count + */ + hevc->gvs->drop_frame_count++; + /* error frame count also need increase */ + hevc->gvs->error_frame_count++; } else { if (hevc->i_only & 0x1 && pic_display->slice_type != 2) { @@ -5936,7 +6011,7 @@ static void set_aux_data(struct hevc_state_s *hevc, } } new_size = pic->aux_data_size + aux_count + heads_size; - new_buf = vmalloc(new_size); + new_buf = vzalloc(new_size); if (new_buf) { unsigned char valid_tag = 0; unsigned char *h = @@ -5945,10 +6020,13 @@ static void set_aux_data(struct hevc_state_s *hevc, unsigned char *p = h + 8; int len = 0; int padding_len = 0; - memcpy(new_buf, pic->aux_data_buf, pic->aux_data_size); - if (pic->aux_data_buf) + + if (pic->aux_data_buf) { + memcpy(new_buf, pic->aux_data_buf, pic->aux_data_size); vfree(pic->aux_data_buf); + } pic->aux_data_buf = new_buf; + for (i = 0; i < aux_count; i += 4) { int ii; unsigned char tag = aux_adr[i + 3] >> 8; @@ -6066,6 +6144,8 @@ static inline void hevc_pre_pic(struct hevc_state_s *hevc, pic = get_pic_by_POC(hevc, decoded_poc); if (pic && (pic->POC != INVALID_POC)) { + struct vdec_s *vdec = hw_to_vdec(hevc); + /*PB skip control */ if (pic->error_mark == 0 && hevc->PB_skip_mode == 1) { @@ -6110,10 +6190,14 @@ static inline void hevc_pre_pic(struct hevc_state_s *hevc, hevc->used_4k_num = -1; } } - - pic->output_mark = 1; + if (!pic->ip_mode) + pic->output_mark = 1; pic->recon_mark = 1; pic->dis_mark = 1; + if (vdec->mvfrm) { + pic->frame_size = vdec->mvfrm->frame_size; + pic->hw_decode_time = (u32)vdec->mvfrm->hw_decode_time; + } } do { pic_display = output_pic(hevc, 0); @@ -6139,6 +6223,14 @@ static inline void hevc_pre_pic(struct hevc_state_s *hevc, hevc_print_cont(hevc, 0, "Debug or err,recycle it\n"); } + /* + * Here the pic/frame error_mark is 1, + * and it won't be displayed, so increase + * the drop count + */ + hevc->gvs->drop_frame_count++; + /* error frame count also need increase */ + hevc->gvs->error_frame_count++; } else { if (hevc->i_only & 0x1 && pic_display-> @@ -6652,55 +6744,55 @@ static void get_picture_qos_info(struct hevc_state_s *hevc) #endif picture->min_mv = mv_lo; +#ifdef DEBUG_QOS /* {mvy_L0_max, mvy_L0_min} */ rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); mv_hi = (rdata32>>16)&0xffff; if (mv_hi & 0x8000) mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS hevc_print(hevc, 0, "[Picture %d Quality] MVY_L0 MAX : %d\n", pic_number, mv_hi); -#endif + mv_lo = (rdata32>>0)&0xffff; if (mv_lo & 0x8000) mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS + hevc_print(hevc, 0, "[Picture %d Quality] MVY_L0 MIN : %d\n", pic_number, mv_lo); -#endif + /* {mvx_L1_max, mvx_L1_min} */ rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); mv_hi = (rdata32>>16)&0xffff; if (mv_hi & 0x8000) mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS + hevc_print(hevc, 0, "[Picture %d Quality] MVX_L1 MAX : %d\n", pic_number, mv_hi); -#endif + mv_lo = (rdata32>>0)&0xffff; if (mv_lo & 0x8000) mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS + hevc_print(hevc, 0, "[Picture %d Quality] MVX_L1 MIN : %d\n", pic_number, mv_lo); -#endif + /* {mvy_L1_max, mvy_L1_min} */ rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); mv_hi = (rdata32>>16)&0xffff; if (mv_hi & 0x8000) mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS + hevc_print(hevc, 0, "[Picture %d Quality] MVY_L1 MAX : %d\n", pic_number, mv_hi); -#endif + mv_lo = (rdata32>>0)&0xffff; if (mv_lo & 0x8000) mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS + hevc_print(hevc, 0, "[Picture %d Quality] MVY_L1 MIN : %d\n", pic_number, mv_lo); #endif @@ -6728,10 +6820,16 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc, int lcu_y_num_div; int Col_ref; int dbg_skip_flag = 0; + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hevc->v4l2_ctx); + + if (hevc->is_used_v4l && ctx->param_sets_from_ucode) + hevc->res_ch_flag = 0; if (hevc->wait_buf == 0) { hevc->sps_num_reorder_pics_0 = rpm_param->p.sps_num_reorder_pics_0; + hevc->ip_mode = (!hevc->sps_num_reorder_pics_0 && !disable_ip_mode) ? true : false; hevc->m_temporalId = rpm_param->p.m_temporalId; hevc->m_nalUnitType = rpm_param->p.m_nalUnitType; hevc->interlace_flag = @@ -6743,7 +6841,8 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc, (rpm_param->p.sei_frame_field_info >> 8) & 0x1; } - if (interlace_enable == 0 || hevc->m_ins_flag) + /* if (interlace_enable == 0 || hevc->m_ins_flag) */ + if (interlace_enable == 0) hevc->interlace_flag = 0; if (interlace_enable & 0x100) hevc->interlace_flag = interlace_enable & 0x1; @@ -7299,11 +7398,11 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc, if (hevc->cur_pic->error_mark && ((hevc->ignore_bufmgr_error & 0x1) == 0)) { -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC /*count info*/ - vdec_count_info(gvs, hevc->cur_pic->error_mark, + vdec_count_info(hevc->gvs, hevc->cur_pic->error_mark, hevc->cur_pic->stream_offset); -#endif + if (hevc->PB_skip_mode == 2) + hevc->gvs->drop_frame_count++; } if (is_skip_decoding(hevc, @@ -7331,11 +7430,11 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc, hevc_print(hevc, 0, "Discard this picture index %d\n", hevc->cur_pic->index); -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC /*count info*/ - vdec_count_info(gvs, hevc->cur_pic->error_mark, + vdec_count_info(hevc->gvs, hevc->cur_pic->error_mark, hevc->cur_pic->stream_offset); -#endif + if (hevc->PB_skip_mode == 2) + hevc->gvs->drop_frame_count++; return 2; } #ifdef MCRCC_ENABLE @@ -7363,7 +7462,7 @@ static int H265_alloc_mmu(struct hevc_state_s *hevc, struct PIC_s *new_pic, picture_size = compute_losless_comp_body_size(hevc, new_pic->width, new_pic->height, !bit_depth_10); cur_mmu_4k_number = ((picture_size+(1<<12)-1) >> 12); - if (hevc->double_write_mode & 0x10) + if (get_double_write_mode(hevc) == 0x10) return 0; /*hevc_print(hevc, 0, "alloc_mmu cur_idx : %d picture_size : %d mmu_4k_number : %d\r\n", @@ -7471,8 +7570,7 @@ static void hevc_local_uninit(struct hevc_state_s *hevc) hevc->frame_mmu_map_addr = NULL; } - kfree(gvs); - gvs = NULL; + //pr_err("[%s line %d] hevc->gvs=0x%p operation\n",__func__, __LINE__, hevc->gvs); } static int hevc_local_init(struct hevc_state_s *hevc) @@ -7928,6 +8026,7 @@ static void set_frame_info(struct hevc_state_s *hevc, struct vframe_s *vf, pic->height), DISP_RATIO_ASPECT_RATIO_MAX); vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT); + vf->ratio_control <<= hevc->interlace_flag; } hevc->ratio_control = vf->ratio_control; if (pic->aux_data_buf @@ -8221,6 +8320,8 @@ static void vh265_vf_put(struct vframe_s *vf, void *op_arg) return; if (vf == (&hevc->vframe_dummy)) return; + if (!vf) + return; index_top = vf->index & 0xff; index_bot = (vf->index >> 8) & 0xff; if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) @@ -8517,7 +8618,10 @@ static void fill_frame_info(struct hevc_state_s *hevc, /* #define SHOW_QOS_INFO */ - vframe_qos->size = framesize; + if (input_frame_based(hw_to_vdec(hevc))) + vframe_qos->size = pic->frame_size; + else + vframe_qos->size = framesize; vframe_qos->pts = pts; #ifdef SHOW_QOS_INFO hevc_print(hevc, 0, "slice:%d, poc:%d\n", pic->slice_type, pic->POC); @@ -8556,19 +8660,44 @@ static void fill_frame_info(struct hevc_state_s *hevc, vframe_qos->num++; - if (hevc->frameinfo_enable) - vdec_fill_frame_info(vframe_qos, 1); +} + +static inline void hevc_update_gvs(struct hevc_state_s *hevc) +{ + if (hevc->gvs->frame_height != hevc->frame_height) { + hevc->gvs->frame_width = hevc->frame_width; + hevc->gvs->frame_height = hevc->frame_height; + } + if (hevc->gvs->frame_dur != hevc->frame_dur) { + hevc->gvs->frame_dur = hevc->frame_dur; + if (hevc->frame_dur != 0) + hevc->gvs->frame_rate = 96000 / hevc->frame_dur; + else + hevc->gvs->frame_rate = -1; + } + hevc->gvs->error_count = hevc->gvs->error_frame_count; + hevc->gvs->status = hevc->stat | hevc->fatal_error; + if (hevc->gvs->ratio_control != hevc->ratio_control) + hevc->gvs->ratio_control = hevc->ratio_control; } static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) { -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION struct vdec_s *vdec = hw_to_vdec(hevc); -#endif struct vframe_s *vf = NULL; int stream_offset = pic->stream_offset; unsigned short slice_type = pic->slice_type; - u32 frame_size; + ulong nv_order = VIDTYPE_VIU_NV21; + u32 frame_size = 0; + struct vdec_info tmp4x; + struct aml_vcodec_ctx * v4l2_ctx = hevc->v4l2_ctx; + + /* swap uv */ + if (hevc->is_used_v4l) { + if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) || + (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M)) + nv_order = VIDTYPE_VIU_NV12; + } if (force_disp_pic_index & 0x100) { /*recycle directly*/ @@ -8598,7 +8727,7 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) } #ifdef MULTI_INSTANCE_SUPPORT - if (vdec_frame_based(hw_to_vdec(hevc))) { + if (vdec_frame_based(vdec)) { vf->pts = pic->pts; vf->pts_us64 = pic->pts64; vf->timestamp = pic->timestamp; @@ -8728,7 +8857,7 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) } if (pic->double_write_mode) { vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; - vf->type |= VIDTYPE_VIU_NV21; + vf->type |= nv_order; if ((pic->double_write_mode == 3) && (!(IS_8K_SIZE(pic->width, pic->height)))) { @@ -8794,7 +8923,7 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) vf->bitdepth |= BITDEPTH_SAVING_MODE; #else vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; - vf->type |= VIDTYPE_VIU_NV21; + vf->type |= nv_order; vf->canvas0Addr = vf->canvas1Addr = spec2canvas(pic); #endif set_frame_info(hevc, vf, pic); @@ -8895,17 +9024,17 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) if (pic->pic_struct == 3) { vf->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21; + | nv_order; vf2->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21; + | nv_order; } else { vf->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21; + | nv_order; vf2->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21; + | nv_order; } hevc->vf_pre_count++; - decoder_do_frame_check(hw_to_vdec(hevc), vf); + decoder_do_frame_check(vdec, vf); kfifo_put(&hevc->display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); @@ -8940,21 +9069,21 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) if (pic->pic_struct == 5) { vf->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21; + | nv_order; vf2->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21; + | nv_order; vf3->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21; + | nv_order; } else { vf->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21; + | nv_order; vf2->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21; + | nv_order; vf3->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21; + | nv_order; } hevc->vf_pre_count++; - decoder_do_frame_check(hw_to_vdec(hevc), vf); + decoder_do_frame_check(vdec, vf); kfifo_put(&hevc->display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); @@ -8980,19 +9109,19 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) process_pending_vframe(hevc, pic, (pic->pic_struct == 9)); - decoder_do_frame_check(hw_to_vdec(hevc), vf); + decoder_do_frame_check(vdec, vf); /* process current vf */ kfifo_put(&hevc->pending_q, (const struct vframe_s *)vf); vf->height <<= 1; if (pic->pic_struct == 9) { vf->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21 | VIDTYPE_VIU_FIELD; + | nv_order | VIDTYPE_VIU_FIELD; process_pending_vframe(hevc, hevc->pre_bot_pic, 0); } else { vf->type = VIDTYPE_INTERLACE_BOTTOM | - VIDTYPE_VIU_NV21 | VIDTYPE_VIU_FIELD; + nv_order | VIDTYPE_VIU_FIELD; vf->index = (pic->index << 8) | 0xff; process_pending_vframe(hevc, hevc->pre_top_pic, 1); @@ -9023,13 +9152,13 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) vf->height <<= 1; if (pic->pic_struct == 11) vf->type = VIDTYPE_INTERLACE_TOP | - VIDTYPE_VIU_NV21 | VIDTYPE_VIU_FIELD; + nv_order | VIDTYPE_VIU_FIELD; else { vf->type = VIDTYPE_INTERLACE_BOTTOM | - VIDTYPE_VIU_NV21 | VIDTYPE_VIU_FIELD; + nv_order | VIDTYPE_VIU_FIELD; vf->index = (pic->index << 8) | 0xff; } - decoder_do_frame_check(hw_to_vdec(hevc), vf); + decoder_do_frame_check(vdec, vf); kfifo_put(&hevc->pending_q, (const struct vframe_s *)vf); if (hevc->vf_pre_count == 0) @@ -9060,21 +9189,21 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) case 1: vf->height <<= 1; vf->type = VIDTYPE_INTERLACE_TOP | - VIDTYPE_VIU_NV21 | VIDTYPE_VIU_FIELD; + nv_order | VIDTYPE_VIU_FIELD; process_pending_vframe(hevc, pic, 1); hevc->pre_top_pic = pic; break; case 2: vf->height <<= 1; vf->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21 + | nv_order | VIDTYPE_VIU_FIELD; process_pending_vframe(hevc, pic, 0); hevc->pre_bot_pic = pic; break; } hevc->vf_pre_count++; - decoder_do_frame_check(hw_to_vdec(hevc), vf); + decoder_do_frame_check(vdec, vf); kfifo_put(&hevc->display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); @@ -9083,23 +9212,26 @@ static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) vf->type_original = vf->type; pic->vf_ref = 1; hevc->vf_pre_count++; - decoder_do_frame_check(hw_to_vdec(hevc), vf); + decoder_do_frame_check(vdec, vf); kfifo_put(&hevc->display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); - - if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) - hevc_print(hevc, 0, - "%s(type %d index 0x%x poc %d/%d) pts(%d,%d) dur %d\n", - __func__, vf->type, vf->index, - get_pic_poc(hevc, vf->index & 0xff), - get_pic_poc(hevc, (vf->index >> 8) & 0xff), - vf->pts, vf->pts_us64, - vf->duration); #endif -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC /*count info*/ - vdec_count_info(gvs, 0, stream_offset); -#endif + vdec_count_info(hevc->gvs, 0, stream_offset); + hevc_update_gvs(hevc); + memcpy(&tmp4x, hevc->gvs, sizeof(struct vdec_info)); + tmp4x.bit_depth_luma = hevc->bit_depth_luma; + tmp4x.bit_depth_chroma = hevc->bit_depth_chroma; + tmp4x.double_write_mode = get_double_write_mode(hevc); + vdec_fill_vdec_frame(vdec, &hevc->vframe_qos, &tmp4x, vf, pic->hw_decode_time); + vdec->vdec_fps_detec(vdec->id); + hevc_print(hevc, H265_DEBUG_BUFMGR, + "%s(type %d index 0x%x poc %d/%d) pts(%d,%d) dur %d\n", + __func__, vf->type, vf->index, + get_pic_poc(hevc, vf->index & 0xff), + get_pic_poc(hevc, (vf->index >> 8) & 0xff), + vf->pts, vf->pts_us64, + vf->duration); hw_to_vdec(hevc)->vdec_fps_detec(hw_to_vdec(hevc)->id); if (without_display_mode == 0) { vf_notify_receiver(hevc->provider_name, @@ -9485,6 +9617,59 @@ static void read_decode_info(struct hevc_state_s *hevc) hevc->rps_set_id = (decode_info >> 8) & 0xff; } +static int vh265_get_ps_info(struct hevc_state_s *hevc, int width, int height, struct aml_vdec_ps_infos *ps) +{ + int dw_mode = v4l_parser_get_double_write_mode(hevc, width, height); + + ps->visible_width = width / get_double_write_ratio(hevc, dw_mode); + ps->visible_height = height / get_double_write_ratio(hevc, dw_mode); + ps->coded_width = ALIGN(width, 32) / get_double_write_ratio(hevc, dw_mode); + ps->coded_height = ALIGN(height, 32) / get_double_write_ratio(hevc, dw_mode); + ps->dpb_size = v4l_parser_work_pic_num(hevc); + + return 0; +} + +static int v4l_res_change(struct hevc_state_s *hevc, union param_u *rpm_param) +{ + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hevc->v4l2_ctx); + int ret = 0; + + if (ctx->param_sets_from_ucode && + hevc->res_ch_flag == 0) { + struct aml_vdec_ps_infos ps; + int width = rpm_param->p.pic_width_in_luma_samples; + int height = rpm_param->p.pic_height_in_luma_samples; + if ((hevc->pic_w != 0 && + hevc->pic_h != 0) && + (hevc->pic_w != width || + hevc->pic_h != height)) { + hevc_print(hevc, 0, + "v4l_res_change Pic Width/Height Change (%d,%d)=>(%d,%d), interlace %d\n", + hevc->pic_w, hevc->pic_h, + width, + height, + hevc->interlace_flag); + + vh265_get_ps_info(hevc, width, height, &ps); + vdec_v4l_set_ps_infos(ctx, &ps); + vdec_v4l_res_ch_event(ctx); + hevc->v4l_params_parsed = false; + hevc->res_ch_flag = 1; + hevc->eos = 1; + flush_output(hevc, NULL); + //del_timer_sync(&hevc->timer); + notify_v4l_eos(hw_to_vdec(hevc)); + + ret = 1; + } + } + + return ret; +} + + static irqreturn_t vh265_isr_thread_fn(int irq, void *data) { struct hevc_state_s *hevc = (struct hevc_state_s *) data; @@ -9662,6 +9847,10 @@ static irqreturn_t vh265_isr_thread_fn(int irq, void *data) struct PIC_s *pic; struct PIC_s *pic_display; int decoded_poc; + + if (vdec->mvfrm) + vdec->mvfrm->hw_decode_time = + local_clock() - vdec->mvfrm->hw_decode_start; #ifdef DETREFILL_ENABLE if (hevc->is_swap && get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM) { @@ -9707,7 +9896,7 @@ pic_done: reset_process_time(hevc); - if (hevc->vf_pre_count == 0) { + if (hevc->vf_pre_count == 0 || hevc->ip_mode) { decoded_poc = hevc->curr_POC; pic = get_pic_by_POC(hevc, decoded_poc); if (pic && (pic->POC != INVALID_POC)) { @@ -9757,6 +9946,12 @@ pic_done: pic->output_mark = 1; pic->recon_mark = 1; + if (vdec->mvfrm) { + pic->frame_size = + vdec->mvfrm->frame_size; + pic->hw_decode_time = + (u32)vdec->mvfrm->hw_decode_time; + } } check_pic_decoded_error(hevc, READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff); @@ -9788,8 +9983,8 @@ force_output: "Debug or err,recycle it\n"); } } else { - if (pic_display-> - slice_type != 2) { + if ((pic_display-> + slice_type != 2) && !pic_display->ip_mode) { pic_display->output_ready = 0; } else { prepare_display_buf @@ -10156,20 +10351,33 @@ force_output: if (hevc->is_used_v4l) { struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hevc->v4l2_ctx); + if (!v4l_res_change(hevc, &hevc->param)) { + if (ctx->param_sets_from_ucode && !hevc->v4l_params_parsed) { + struct aml_vdec_ps_infos ps; + int width = hevc->param.p.pic_width_in_luma_samples; + int height = hevc->param.p.pic_height_in_luma_samples; + + pr_debug("set ucode parse\n"); + vh265_get_ps_info(hevc, width, height, &ps); + /*notice the v4l2 codec.*/ + vdec_v4l_set_ps_infos(ctx, &ps); + hevc->v4l_params_parsed = true; + hevc->dec_result = DEC_RESULT_AGAIN; + amhevc_stop(); + restore_decode_state(hevc); + reset_process_time(hevc); + vdec_schedule_work(&hevc->work); + return IRQ_HANDLED; + } + }else { + pr_debug("resolution change\n"); + hevc->dec_result = DEC_RESULT_AGAIN; + amhevc_stop(); + restore_decode_state(hevc); + reset_process_time(hevc); + vdec_schedule_work(&hevc->work); + return IRQ_HANDLED; - if (ctx->param_sets_from_ucode && !hevc->v4l_params_parsed) { - struct aml_vdec_ps_infos ps; - - hevc->frame_width = hevc->param.p.pic_width_in_luma_samples; - hevc->frame_height = hevc->param.p.pic_height_in_luma_samples; - ps.visible_width = hevc->frame_width; - ps.visible_height = hevc->frame_height; - ps.coded_width = ALIGN(hevc->frame_width, 32); - ps.coded_height = ALIGN(hevc->frame_height, 32); - ps.dpb_size = get_work_pic_num(hevc); - hevc->v4l_params_parsed = true; - /*notice the v4l2 codec.*/ - vdec_v4l_set_ps_infos(ctx, &ps); } } @@ -10236,9 +10444,7 @@ force_output: &hevc->notify_work); hevc->get_frame_dur = true; -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC - gvs->frame_dur = hevc->frame_dur; -#endif + //hevc->gvs->frame_dur = hevc->frame_dur; } if (hevc->video_signal_type != @@ -10285,6 +10491,11 @@ force_output: hevc->pic_h = hevc->param.p.pic_height_in_luma_samples; hevc->lcu_size = 1 << (log + 3 + log_s); hevc->lcu_size_log2 = log2i(hevc->lcu_size); + if (performance_profile &&( (!is_oversize(hevc->pic_w, hevc->pic_h)) && IS_8K_SIZE(hevc->pic_w,hevc->pic_h))) + hevc->performance_profile = 1; + else + hevc->performance_profile = 0; + hevc_print(hevc, 0, "hevc->performance_profile %d\n", hevc->performance_profile); if (hevc->pic_w == 0 || hevc->pic_h == 0 || hevc->lcu_size == 0 || is_oversize(hevc->pic_w, hevc->pic_h) @@ -10307,7 +10518,19 @@ force_output: } else { hevc->sps_num_reorder_pics_0 = hevc->param.p.sps_num_reorder_pics_0; + hevc->ip_mode = (!hevc->sps_num_reorder_pics_0 && !disable_ip_mode) ? true : false; hevc->pic_list_init_flag = 1; + if ((!IS_4K_SIZE(hevc->pic_w, hevc->pic_h)) && + ((hevc->param.p.profile_etc & 0xc) == 0x4) + && (interlace_enable != 0)) { + hevc->double_write_mode = 1; + hevc->interlace_flag = 1; + hevc->frame_ar = (hevc->pic_h * 0x100 / hevc->pic_w) * 2; + hevc_print(hevc, 0, + "interlace (%d, %d), profile_etc %x, ar 0x%x, dw %d\n", + hevc->pic_w, hevc->pic_h, hevc->param.p.profile_etc, hevc->frame_ar, + get_double_write_mode(hevc)); + } #ifdef MULTI_INSTANCE_SUPPORT if (hevc->m_ins_flag) { vdec_schedule_work(&hevc->work); @@ -10379,9 +10602,7 @@ force_output: #endif } else { /* skip, search next start code */ -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC - gvs->drop_frame_count++; -#endif + hevc->gvs->drop_frame_count++; WRITE_VREG(HEVC_WAIT_FLAG, READ_VREG(HEVC_WAIT_FLAG) & (~0x2)); hevc->skip_flag = 1; WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); @@ -10550,7 +10771,8 @@ static void vh265_check_timer_func(unsigned long arg) (get_dbg_flag(hevc) & H265_DEBUG_WAIT_DECODE_DONE_WHEN_STOP) == 0 && hw_to_vdec(hevc)->next_status == - VDEC_STATUS_DISCONNECTED) { + VDEC_STATUS_DISCONNECTED && + !hevc->is_used_v4l) { hevc->dec_result = DEC_RESULT_FORCE_EXIT; vdec_schedule_work(&hevc->work); hevc_print(hevc, @@ -10559,9 +10781,7 @@ static void vh265_check_timer_func(unsigned long arg) } if (hevc->m_ins_flag) { - if ((input_frame_based(hw_to_vdec(hevc)) || - (READ_VREG(HEVC_STREAM_LEVEL) > 0xb0)) && - ((get_dbg_flag(hevc) & + if (((get_dbg_flag(hevc) & H265_DEBUG_DIS_LOC_ERROR_PROC) == 0) && (decode_timeout_val > 0) && (hevc->start_process_time > 0) && @@ -10825,30 +11045,30 @@ int vh265_dec_status(struct vdec_info *vstatus) return -1; vstatus->frame_width = hevc->frame_width; - vstatus->frame_height = hevc->frame_height; + /* for hevc interlace for disp height x2 */ + vstatus->frame_height = + (hevc->frame_height << hevc->interlace_flag); if (hevc->frame_dur != 0) vstatus->frame_rate = 96000 / hevc->frame_dur; else vstatus->frame_rate = -1; - vstatus->error_count = 0; + vstatus->error_count = hevc->gvs->error_frame_count; vstatus->status = hevc->stat | hevc->fatal_error; -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC - vstatus->bit_rate = gvs->bit_rate; + vstatus->bit_rate = hevc->gvs->bit_rate; vstatus->frame_dur = hevc->frame_dur; - if (gvs) { - vstatus->bit_rate = gvs->bit_rate; - vstatus->frame_data = gvs->frame_data; - vstatus->total_data = gvs->total_data; - vstatus->frame_count = gvs->frame_count; - vstatus->error_frame_count = gvs->error_frame_count; - vstatus->drop_frame_count = gvs->drop_frame_count; - vstatus->total_data = gvs->total_data; - vstatus->samp_cnt = gvs->samp_cnt; - vstatus->offset = gvs->offset; + if (hevc->gvs) { + vstatus->bit_rate = hevc->gvs->bit_rate; + vstatus->frame_data = hevc->gvs->frame_data; + vstatus->total_data = hevc->gvs->total_data; + vstatus->frame_count = hevc->gvs->frame_count; + vstatus->error_frame_count = hevc->gvs->error_frame_count; + vstatus->drop_frame_count = hevc->gvs->drop_frame_count; + vstatus->samp_cnt = hevc->gvs->samp_cnt; + vstatus->offset = hevc->gvs->offset; } + snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name), "%s", DRIVER_NAME); -#endif vstatus->ratio_control = hevc->ratio_control; return 0; } @@ -10859,13 +11079,15 @@ int vh265_set_isreset(struct vdec_s *vdec, int isreset) return 0; } -static int vh265_vdec_info_init(void) +static int vh265_vdec_info_init(struct hevc_state_s *hevc) { - gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL); - if (NULL == gvs) { + hevc->gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL); + //pr_err("[%s line %d] hevc->gvs=0x%p operation\n",__func__, __LINE__, hevc->gvs); + if (NULL == hevc->gvs) { pr_info("the struct of vdec status malloc failed.\n"); return -ENOMEM; } + vdec_set_vframe_comm(hw_to_vdec(hevc), DRIVER_NAME); return 0; } @@ -10890,12 +11112,43 @@ static void H265_DECODE_INIT(void) } #endif +int vh265_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) +{ + struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private; + hevc_print(hevc, 0, "[%s %d] trickmode:%lu\n", __func__, __LINE__, trickmode); + + if (trickmode == TRICKMODE_I) { + trickmode_i = 1; + i_only_flag = 0x1; + } else if (trickmode == TRICKMODE_NONE) { + trickmode_i = 0; + i_only_flag = 0x0; + } else if (trickmode == 0x02) { + trickmode_i = 0; + i_only_flag = 0x02; + } else if (trickmode == 0x03) { + trickmode_i = 1; + i_only_flag = 0x03; + } else if (trickmode == 0x07) { + trickmode_i = 1; + i_only_flag = 0x07; + } + //hevc_print(hevc, 0, "i_only_flag: %d trickmode_i:%d\n", i_only_flag, trickmode_i); + + return 0; +} + static void config_decode_mode(struct hevc_state_s *hevc) { #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION struct vdec_s *vdec = hw_to_vdec(hevc); #endif unsigned decode_mode; +#ifdef HEVC_8K_LFTOFFSET_FIX + if (hevc->performance_profile) + WRITE_VREG(NAL_SEARCH_CTL, + READ_VREG(NAL_SEARCH_CTL) | (1 << 21)); +#endif if (!hevc->m_ins_flag) decode_mode = DECODE_MODE_SINGLE; else if (vdec_frame_based(hw_to_vdec(hevc))) @@ -11050,9 +11303,7 @@ static int vh265_local_init(struct hevc_state_s *hevc) hevc->frame_dur = (hevc->vh265_amstream_dec_info.rate == 0) ? 3600 : hevc->vh265_amstream_dec_info.rate; -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC - gvs->frame_dur = hevc->frame_dur; -#endif + //hevc->gvs->frame_dur = hevc->frame_dur; if (hevc->frame_width && hevc->frame_height) hevc->frame_ar = hevc->frame_height * 0x100 / hevc->frame_width; @@ -11193,6 +11444,7 @@ static s32 vh265_init(struct hevc_state_s *hevc) hevc->timer.expires = jiffies + PUT_INTERVAL; hevc->fw = fw; + hevc->init_flag = 1; return 0; } @@ -11427,8 +11679,10 @@ static int vh265_stop(struct hevc_state_s *hevc) uninit_mmu_buffers(hevc); amhevc_disable(); - kfree(gvs); - gvs = NULL; + //pr_err("[%s line %d] hevc->gvs=0x%p operation\n",__func__, __LINE__, hevc->gvs); + if (hevc->gvs) + kfree(hevc->gvs); + hevc->gvs = NULL; return 0; } @@ -11626,13 +11880,9 @@ static int vmh265_stop(struct hevc_state_s *hevc) hevc_local_uninit(hevc); - hevc->init_flag = 0; - hevc->first_sc_checked = 0; - cancel_work_sync(&hevc->notify_work); - cancel_work_sync(&hevc->set_clk_work); - cancel_work_sync(&hevc->timeout_work); - - uninit_mmu_buffers(hevc); + if (hevc->gvs) + kfree(hevc->gvs); + hevc->gvs = NULL; if (use_cma) { hevc->uninit_list = 1; @@ -11649,7 +11899,13 @@ static int vmh265_stop(struct hevc_state_s *hevc) msleep(20); #endif } + hevc->init_flag = 0; + hevc->first_sc_checked = 0; + cancel_work_sync(&hevc->notify_work); + cancel_work_sync(&hevc->set_clk_work); + cancel_work_sync(&hevc->timeout_work); cancel_work_sync(&hevc->work); + uninit_mmu_buffers(hevc); vfree(hevc->fw); hevc->fw = NULL; @@ -11720,7 +11976,6 @@ static void vh265_work_implement(struct hevc_state_s *hevc, if (hevc->dec_result == DEC_RESULT_FREE_CANVAS) { /*USE_BUF_BLOCK*/ uninit_pic_list(hevc); - hevc_print(hevc, 0, "uninit list\n"); hevc->uninit_list = 0; #ifdef USE_UNINIT_SEMA up(&hevc->h265_uninit_done_sema); @@ -12263,10 +12518,18 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hevc->v4l2_ctx); - if (ctx->param_sets_from_ucode && - !ctx->v4l_codec_ready && - hevc->v4l_params_parsed) { - ret = 0; /*the params has parsed.*/ + if (ctx->param_sets_from_ucode) { + if (hevc->v4l_params_parsed) { + if (!ctx->v4l_codec_dpb_ready && + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < + run_ready_min_buf_num) + ret = 0; + } else { + if ((hevc->res_ch_flag == 1) && + ((ctx->state <= AML_STATE_INIT) || + (ctx->state >= AML_STATE_FLUSHING))) + ret = 0; + } } else if (!ctx->v4l_codec_dpb_ready) { if (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < run_ready_min_buf_num) @@ -12435,6 +12698,8 @@ static void run(struct vdec_s *vdec, unsigned long mask, r = hevc->chunk->size + (hevc->chunk->offset & (VDEC_FIFO_ALIGN - 1)); hevc->decode_size = r; + if (vdec->mvfrm) + vdec->mvfrm->frame_size = hevc->chunk->size; } #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION else { @@ -12456,6 +12721,8 @@ static void run(struct vdec_s *vdec, unsigned long mask, mod_timer(&hevc->timer, jiffies); hevc->stat |= STAT_TIMER_ARM; hevc->stat |= STAT_ISR_REG; + if (vdec->mvfrm) + vdec->mvfrm->hw_decode_start = local_clock(); amhevc_start(); hevc->stat |= STAT_VDEC_RUN; } @@ -12497,7 +12764,6 @@ static void reset(struct vdec_s *vdec) } hevc->dec_result = DEC_RESULT_NONE; reset_process_time(hevc); - hevc->init_flag = 0; hevc->pic_list_init_flag = 0; dealloc_mv_bufs(hevc); aml_free_canvas(vdec); @@ -12646,11 +12912,12 @@ static int amvdec_h265_probe(struct platform_device *pdev) workaround_enable &= ~3; #endif hevc->cma_dev = pdata->cma_dev; - vh265_vdec_info_init(); + vh265_vdec_info_init(hevc); #ifdef MULTI_INSTANCE_SUPPORT pdata->private = hevc; pdata->dec_status = vh265_dec_status; + pdata->set_trickmode = vh265_set_trickmode; pdata->set_isreset = vh265_set_isreset; is_reset = 0; if (vh265_init(pdata) < 0) { @@ -12660,6 +12927,9 @@ static int amvdec_h265_probe(struct platform_device *pdev) hevc_print(hevc, 0, "\namvdec_h265 init failed.\n"); hevc_local_uninit(hevc); + if (hevc->gvs) + kfree(hevc->gvs); + hevc->gvs = NULL; uninit_mmu_buffers(hevc); vfree(hevc); pdata->dec_status = NULL; @@ -12742,10 +13012,11 @@ static void vh265_dump_state(struct vdec_s *vdec) "====== %s\n", __func__); hevc_print(hevc, 0, - "width/height (%d/%d), reorder_pic_num %d buf count(bufspec size) %d, video_signal_type 0x%x, is_swap %d\n", + "width/height (%d/%d), reorder_pic_num %d ip_mode %d buf count(bufspec size) %d, video_signal_type 0x%x, is_swap %d\n", hevc->frame_width, hevc->frame_height, hevc->sps_num_reorder_pics_0, + hevc->ip_mode, get_work_pic_num(hevc), hevc->video_signal_type_debug, hevc->is_swap @@ -12901,6 +13172,7 @@ static int ammvdec_h265_probe(struct platform_device *pdev) #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC int config_val; #endif + //pr_err("[%s pid=%d tgid=%d] \n",__func__, current->pid, current->tgid); if (pdata == NULL) { pr_info("\nammvdec_h265 memory resource undefined.\n"); return -EFAULT; @@ -12920,7 +13192,7 @@ static int ammvdec_h265_probe(struct platform_device *pdev) pdata->private = hevc; pdata->dec_status = vh265_dec_status; - /* pdata->set_trickmode = set_trickmode; */ + pdata->set_trickmode = vh265_set_trickmode; pdata->run_ready = run_ready; pdata->run = run; pdata->reset = reset; @@ -13028,6 +13300,9 @@ static int ammvdec_h265_probe(struct platform_device *pdev) } hevc->double_write_mode = double_write_mode; } + /* get valid double write from configure or node */ + hevc->double_write_mode = get_double_write_mode(hevc); + if (!hevc->is_used_v4l) { if (hevc->save_buffer_mode && dynamic_buf_num_margin > 2) hevc->dynamic_buf_num_margin = dynamic_buf_num_margin -2; @@ -13101,11 +13376,15 @@ static int ammvdec_h265_probe(struct platform_device *pdev) hevc->double_write_mode); hevc->cma_dev = pdata->cma_dev; + vh265_vdec_info_init(hevc); if (vh265_init(pdata) < 0) { hevc_print(hevc, 0, "\namvdec_h265 init failed.\n"); hevc_local_uninit(hevc); + if (hevc->gvs) + kfree(hevc->gvs); + hevc->gvs = NULL; uninit_mmu_buffers(hevc); /* devm_kfree(&pdev->dev, (void *)hevc); */ if (hevc) @@ -13133,11 +13412,13 @@ static int ammvdec_h265_remove(struct platform_device *pdev) struct hevc_state_s *hevc = (struct hevc_state_s *) (((struct vdec_s *)(platform_get_drvdata(pdev)))->private); - struct vdec_s *vdec = hw_to_vdec(hevc); + struct vdec_s *vdec; if (hevc == NULL) return 0; + vdec = hw_to_vdec(hevc); + //pr_err("%s [pid=%d,tgid=%d]\n", __func__, current->pid, current->tgid); if (get_dbg_flag(hevc)) hevc_print(hevc, 0, "%s\r\n", __func__); @@ -13152,6 +13433,7 @@ static int ammvdec_h265_remove(struct platform_device *pdev) vdec_set_status(hw_to_vdec(hevc), VDEC_STATUS_DISCONNECTED); vfree((void *)hevc); + return 0; } @@ -13578,6 +13860,13 @@ MODULE_PARM_DESC(pic_list_debug, "\n pic_list_debug\n"); module_param(without_display_mode, uint, 0664); MODULE_PARM_DESC(without_display_mode, "\n amvdec_h265 without_display_mode\n"); +#ifdef HEVC_8K_LFTOFFSET_FIX +module_param(performance_profile, uint, 0664); +MODULE_PARM_DESC(performance_profile, "\n amvdec_h265 performance_profile\n"); +#endif +module_param(disable_ip_mode, uint, 0664); +MODULE_PARM_DESC(disable_ip_mode, "\n amvdec_h265 disable ip_mode\n"); + module_init(amvdec_h265_driver_init_module); module_exit(amvdec_h265_driver_remove_module); diff --git a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c index 493231b..eab36e5 100644 --- a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c +++ b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c @@ -257,6 +257,22 @@ static void set_frame_info(struct vdec_mjpeg_hw_s *hw, struct vframe_s *vf) static irqreturn_t vmjpeg_isr(struct vdec_s *vdec, int irq) { + struct vdec_mjpeg_hw_s *hw = + (struct vdec_mjpeg_hw_s *)(vdec->private); + + if (!hw) + return IRQ_HANDLED; + + if (hw->eos) + return IRQ_HANDLED; + + WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); + + return IRQ_WAKE_THREAD; +} + +static irqreturn_t vmjpeg_isr_thread_fn(struct vdec_s *vdec, int irq) +{ struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)(vdec->private); u32 reg; struct vframe_s *vf = NULL; @@ -264,13 +280,7 @@ static irqreturn_t vmjpeg_isr(struct vdec_s *vdec, int irq) u64 pts_us64; u32 frame_size; - if (!hw) - return IRQ_HANDLED; - - if (hw->eos) - return IRQ_HANDLED; reset_process_time(hw); - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); if (READ_VREG(AV_SCRATCH_D) != 0 && (debug_enable & PRINT_FLAG_UCODE_DETAIL)) { pr_info("dbg%x: %x\n", READ_VREG(AV_SCRATCH_D), @@ -308,9 +318,6 @@ static irqreturn_t vmjpeg_isr(struct vdec_s *vdec, int irq) hw->v4l_params_parsed = true; vdec_v4l_set_ps_infos(ctx, &ps); } - - if (!ctx->v4l_codec_ready) - return IRQ_HANDLED; } if (hw->is_used_v4l) { @@ -351,6 +358,7 @@ static irqreturn_t vmjpeg_isr(struct vdec_s *vdec, int irq) vf->mem_handle = decoder_bmmu_box_get_mem_handle( hw->mm_blk_handle, index); + decoder_do_frame_check(vdec, vf); kfifo_put(&hw->display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); hw->frame_num++; @@ -463,8 +471,11 @@ static void vmjpeg_canvas_init(struct vdec_mjpeg_hw_s *hw) u32 canvas_width, canvas_height; u32 decbuf_size, decbuf_y_size, decbuf_uv_size; unsigned long buf_start, addr; + u32 endian; struct vdec_s *vdec = hw_to_vdec(hw); + endian = (vdec->canvas_mode == + CANVAS_BLKMODE_LINEAR) ? 7 : 0; canvas_width = 1920; canvas_height = 1088; decbuf_y_size = 0x200000; @@ -509,12 +520,12 @@ static void vmjpeg_canvas_init(struct vdec_mjpeg_hw_s *hw) hw->buffer_spec[i].v_canvas_index = canvas_v(canvas); } - canvas_config(hw->buffer_spec[i].y_canvas_index, + canvas_config_ex(hw->buffer_spec[i].y_canvas_index, hw->buffer_spec[i].y_addr, canvas_width, canvas_height, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); + CANVAS_BLKMODE_LINEAR, endian); hw->buffer_spec[i].canvas_config[0].phy_addr = hw->buffer_spec[i].y_addr; hw->buffer_spec[i].canvas_config[0].width = @@ -523,13 +534,15 @@ static void vmjpeg_canvas_init(struct vdec_mjpeg_hw_s *hw) canvas_height; hw->buffer_spec[i].canvas_config[0].block_mode = CANVAS_BLKMODE_LINEAR; + hw->buffer_spec[i].canvas_config[0].endian = + endian; - canvas_config(hw->buffer_spec[i].u_canvas_index, + canvas_config_ex(hw->buffer_spec[i].u_canvas_index, hw->buffer_spec[i].u_addr, canvas_width / 2, canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); + CANVAS_BLKMODE_LINEAR, endian); hw->buffer_spec[i].canvas_config[1].phy_addr = hw->buffer_spec[i].u_addr; hw->buffer_spec[i].canvas_config[1].width = @@ -538,13 +551,15 @@ static void vmjpeg_canvas_init(struct vdec_mjpeg_hw_s *hw) canvas_height / 2; hw->buffer_spec[i].canvas_config[1].block_mode = CANVAS_BLKMODE_LINEAR; + hw->buffer_spec[i].canvas_config[1].endian = + endian; - canvas_config(hw->buffer_spec[i].v_canvas_index, + canvas_config_ex(hw->buffer_spec[i].v_canvas_index, hw->buffer_spec[i].v_addr, canvas_width / 2, canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); + CANVAS_BLKMODE_LINEAR, endian); hw->buffer_spec[i].canvas_config[2].phy_addr = hw->buffer_spec[i].v_addr; hw->buffer_spec[i].canvas_config[2].width = @@ -553,6 +568,8 @@ static void vmjpeg_canvas_init(struct vdec_mjpeg_hw_s *hw) canvas_height / 2; hw->buffer_spec[i].canvas_config[2].block_mode = CANVAS_BLKMODE_LINEAR; + hw->buffer_spec[i].canvas_config[2].endian = + endian; } } @@ -1432,6 +1449,7 @@ static int ammvdec_mjpeg_probe(struct platform_device *pdev) pdata->run = run; pdata->run_ready = run_ready; pdata->irq_handler = vmjpeg_isr; + pdata->threaded_irq_handler = vmjpeg_isr_thread_fn; pdata->dump_state = vmjpeg_dump_state; if (pdata->parallel_dec == 1) { @@ -1504,9 +1522,13 @@ static int ammvdec_mjpeg_remove(struct platform_device *pdev) struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *) (((struct vdec_s *)(platform_get_drvdata(pdev)))->private); - struct vdec_s *vdec = hw_to_vdec(hw); + struct vdec_s *vdec; int i; + if (!hw) + return -1; + vdec = hw_to_vdec(hw); + vmjpeg_stop(hw); if (vdec->parallel_dec == 1) @@ -1521,10 +1543,8 @@ static int ammvdec_mjpeg_remove(struct platform_device *pdev) vdec->free_canvas_ex(hw->buffer_spec[i].v_canvas_index, vdec->id); } } - if (hw) { - vfree(hw); - hw = NULL; - } + vfree(hw); + pr_info("%s\n", __func__); return 0; } diff --git a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c index 64e81c7..eaf2e4e 100644 --- a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c +++ b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c @@ -46,9 +46,12 @@ #include "../utils/decoder_bmmu_box.h" #include #include +#include "../utils/config_parser.h" #include "../utils/firmware.h" #include "../utils/vdec_v4l2_buffer_ops.h" #include "../utils/config_parser.h" +#include + #define MEM_NAME "codec_mmpeg12" @@ -172,6 +175,9 @@ static struct vframe_s *vmpeg_vf_get(void *); static void vmpeg_vf_put(struct vframe_s *, void *); static int vmpeg_vf_states(struct vframe_states *states, void *); static int vmpeg_event_cb(int type, void *data, void *private_data); +static int notify_v4l_eos(struct vdec_s *vdec); + + struct mmpeg2_userdata_record_t { struct userdata_meta_info_t meta_info; @@ -203,6 +209,8 @@ struct pic_info_t { u64 pts64; bool pts_valid; ulong v4l_ref_buf_addr; + u32 hw_decode_time; + u32 frame_size; // For frame base mode }; struct vdec_mpeg12_hw_s { @@ -212,6 +220,7 @@ struct vdec_mpeg12_hw_s { DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); struct vframe_s vfpool[VF_POOL_SIZE]; s32 vfbuf_use[DECODE_BUFFER_NUM_MAX]; + s32 ref_use[DECODE_BUFFER_NUM_MAX]; u32 frame_width; u32 frame_height; u32 frame_dur; @@ -307,11 +316,17 @@ struct vdec_mpeg12_hw_s { bool v4l_params_parsed; u32 buf_num; u32 dynamic_buf_num_margin; + struct vdec_info gvs; + struct vframe_qos_s vframe_qos; + unsigned int res_ch_flag; + u32 i_only; }; static void vmpeg12_local_init(struct vdec_mpeg12_hw_s *hw); static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw); static void reset_process_time(struct vdec_mpeg12_hw_s *hw); -static struct vdec_info gvs; +static void vmpeg12_canvas_init(struct vdec_mpeg12_hw_s *hw); +static void flush_output(struct vdec_mpeg12_hw_s *hw); + static int debug_enable; /*static struct work_struct userdata_push_work;*/ #undef pr_info @@ -319,6 +334,9 @@ static int debug_enable; unsigned int mpeg12_debug_mask = 0xff; /*static int counter_max = 5;*/ +static u32 run_ready_min_buf_num = 2; + + #define PRINT_FLAG_ERROR 0x0 #define PRINT_FLAG_RUN_FLOW 0X0001 #define PRINT_FLAG_TIMEINFO 0x0002 @@ -340,6 +358,7 @@ unsigned int mpeg12_debug_mask = 0xff; + int debug_print(int index, int debug_flag, const char *fmt, ...) { if (((debug_enable & debug_flag) && @@ -382,11 +401,13 @@ static int vmpeg12_v4l_alloc_buff_config_canvas(struct vdec_mpeg12_hw_s *hw, int { int ret; u32 canvas; - ulong decbuf_start = 0; - int decbuf_y_size = 0; + ulong decbuf_start = 0, decbuf_uv_start = 0; + int decbuf_y_size = 0, decbuf_uv_size = 0; u32 canvas_width = 0, canvas_height = 0; struct vdec_s *vdec = hw_to_vdec(hw); struct vdec_v4l2_buffer *fb = NULL; + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hw->v4l2_ctx); if (hw->pics[i].v4l_ref_buf_addr) return 0; @@ -394,44 +415,57 @@ static int vmpeg12_v4l_alloc_buff_config_canvas(struct vdec_mpeg12_hw_s *hw, int ret = vdec_v4l_get_buffer(hw->v4l2_ctx, &fb); if (ret < 0) { debug_print(DECODE_ID(hw), 0, - "[%d] get fb fail.\n", - ((struct aml_vcodec_ctx *) - (hw->v4l2_ctx))->id); + "[%d] get fb fail %d/%d.\n", + ctx->id, i, hw->buf_num); return ret; } + if (!hw->frame_width || !hw->frame_height) { + struct vdec_pic_info pic; + vdec_v4l_get_pic_info(ctx, &pic); + hw->frame_width = pic.visible_width; + hw->frame_height = pic.visible_height; + debug_print(DECODE_ID(hw), 0, + "[%d] set %d x %d from IF layer\n", ctx->id, + hw->frame_width, hw->frame_height); + } + hw->pics[i].v4l_ref_buf_addr = (ulong)fb; if (fb->num_planes == 1) { decbuf_start = fb->m.mem[0].addr; decbuf_y_size = fb->m.mem[0].offset; + decbuf_uv_start = decbuf_start + decbuf_y_size; + decbuf_uv_size = decbuf_y_size / 2; canvas_width = ALIGN(hw->frame_width, 64); canvas_height = ALIGN(hw->frame_height, 32); fb->m.mem[0].bytes_used = fb->m.mem[0].size; } else if (fb->num_planes == 2) { decbuf_start = fb->m.mem[0].addr; decbuf_y_size = fb->m.mem[0].size; + decbuf_uv_start = fb->m.mem[1].addr; + decbuf_uv_size = fb->m.mem[1].size; canvas_width = ALIGN(hw->frame_width, 64); canvas_height = ALIGN(hw->frame_height, 32); fb->m.mem[0].bytes_used = decbuf_y_size; - fb->m.mem[1].bytes_used = decbuf_y_size << 1; + fb->m.mem[1].bytes_used = decbuf_uv_size; } debug_print(DECODE_ID(hw), 0, "[%d] %s(), v4l ref buf addr: 0x%x\n", - ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id, __func__, fb); + ctx->id, __func__, fb); if (vdec->parallel_dec == 1) { u32 tmp; - if (canvas_y(hw->canvas_spec[i]) == 0xff) { - tmp = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id); - hw->canvas_spec[i] &= ~0xff; - hw->canvas_spec[i] |= tmp; - } if (canvas_u(hw->canvas_spec[i]) == 0xff) { tmp = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id); hw->canvas_spec[i] &= ~(0xffff << 8); hw->canvas_spec[i] |= tmp << 8; hw->canvas_spec[i] |= tmp << 16; } + if (canvas_y(hw->canvas_spec[i]) == 0xff) { + tmp = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id); + hw->canvas_spec[i] &= ~0xff; + hw->canvas_spec[i] |= tmp; + } canvas = hw->canvas_spec[i]; } else { canvas = vdec->get_canvas(i, 2); @@ -446,7 +480,7 @@ static int vmpeg12_v4l_alloc_buff_config_canvas(struct vdec_mpeg12_hw_s *hw, int (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0; canvas_config_config(canvas_y(canvas), &hw->canvas_config[i][0]); - hw->canvas_config[i][1].phy_addr = decbuf_start + decbuf_y_size; + hw->canvas_config[i][1].phy_addr = decbuf_uv_start; hw->canvas_config[i][1].width = canvas_width; hw->canvas_config[i][1].height = canvas_height / 2; hw->canvas_config[i][1].block_mode = hw->canvas_mode; @@ -454,6 +488,12 @@ static int vmpeg12_v4l_alloc_buff_config_canvas(struct vdec_mpeg12_hw_s *hw, int (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0; canvas_config_config(canvas_u(canvas), &hw->canvas_config[i][1]); + debug_print(DECODE_ID(hw), PRINT_FLAG_BUFFER_DETAIL, + "[%d] %s(), canvas: 0x%x mode: %d y: %x uv: %x w: %d h: %d\n", + ctx->id, __func__, canvas, hw->canvas_mode, + decbuf_start, decbuf_uv_start, + canvas_width, canvas_height); + return 0; } @@ -475,7 +515,7 @@ static bool is_enough_free_buffer(struct vdec_mpeg12_hw_s *hw) int i; for (i = 0; i < hw->buf_num; i++) { - if (hw->vfbuf_use[i] == 0) + if ((hw->vfbuf_use[i] == 0) && (hw->ref_use[i] == 0)) break; } @@ -487,16 +527,25 @@ static int find_free_buffer(struct vdec_mpeg12_hw_s *hw) int i; for (i = 0; i < hw->buf_num; i++) { - if (hw->vfbuf_use[i] == 0) + if ((hw->vfbuf_use[i] == 0) && + (hw->ref_use[i] == 0)) break; } if (i == hw->buf_num) return -1; - if (hw->is_used_v4l) - if (vmpeg12_v4l_alloc_buff_config_canvas(hw, i)) - return -1; + if (hw->is_used_v4l) { + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hw->v4l2_ctx); + if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) { + /*run to parser csd data*/ + i = 0; + } else { + if (vmpeg12_v4l_alloc_buff_config_canvas(hw, i)) + return -1; + } + } return i; } @@ -512,6 +561,99 @@ static u32 spec_to_index(struct vdec_mpeg12_hw_s *hw, u32 spec) return hw->buf_num; } +/* +[SE][BUG-145343][huanghang] fixed:mpeg2 frame qos info notify */ +static void fill_frame_info(struct vdec_mpeg12_hw_s *hw, u32 slice_type, + int frame_size, u32 pts) +{ + unsigned char a[3]; + unsigned char i, j, t; + unsigned long data; + struct vframe_qos_s *vframe_qos = &hw->vframe_qos; + + vframe_qos->type = ((slice_type & PICINFO_TYPE_MASK) == + PICINFO_TYPE_I) ? 1 : + ((slice_type & + PICINFO_TYPE_MASK) == + PICINFO_TYPE_P) ? 2 : 3; + vframe_qos->size = frame_size; + vframe_qos->pts = pts; + + get_random_bytes(&data, sizeof(unsigned long)); + if (vframe_qos->type == 1) + data = 0; + a[0] = data & 0xff; + a[1] = (data >> 8) & 0xff; + a[2] = (data >> 16) & 0xff; + + for (i = 0; i < 3; i++) { + for (j = i+1; j < 3; j++) { + if (a[j] < a[i]) { + t = a[j]; + a[j] = a[i]; + a[i] = t; + } else if (a[j] == a[i]) { + a[i]++; + t = a[j]; + a[j] = a[i]; + a[i] = t; + } + } + } + vframe_qos->max_mv = a[2]; + vframe_qos->avg_mv = a[1]; + vframe_qos->min_mv = a[0]; + + get_random_bytes(&data, sizeof(unsigned long)); + a[0] = data & 0x1f; + a[1] = (data >> 8) & 0x3f; + a[2] = (data >> 16) & 0x7f; + + for (i = 0; i < 3; i++) { + for (j = i+1; j < 3; j++) { + if (a[j] < a[i]) { + t = a[j]; + a[j] = a[i]; + a[i] = t; + } else if (a[j] == a[i]) { + a[i]++; + t = a[j]; + a[j] = a[i]; + a[i] = t; + } + } + } + vframe_qos->max_qp = a[2]; + vframe_qos->avg_qp = a[1]; + vframe_qos->min_qp = a[0]; + + get_random_bytes(&data, sizeof(unsigned long)); + a[0] = data & 0x1f; + a[1] = (data >> 8) & 0x3f; + a[2] = (data >> 16) & 0x7f; + + for (i = 0; i < 3; i++) { + for (j = i + 1; j < 3; j++) { + if (a[j] < a[i]) { + t = a[j]; + a[j] = a[i]; + a[i] = t; + } else if (a[j] == a[i]) { + a[i]++; + t = a[j]; + a[j] = a[i]; + a[i] = t; + } + } + } + vframe_qos->max_skip = a[2]; + vframe_qos->avg_skip = a[1]; + vframe_qos->min_skip = a[0]; + + vframe_qos->num++; + + return; +} + static void set_frame_info(struct vdec_mpeg12_hw_s *hw, struct vframe_s *vf) { u32 ar_bits; @@ -1306,7 +1448,7 @@ static void userdata_push_do_work(struct work_struct *work) psrc_data = (u8 *)hw->ccbuf_phyAddress_virt + hw->ucode_cc_last_wp; pdata = hw->userdata_info.data_buf + hw->userdata_info.last_wp; - for (i = 0; i < data_length; i++) { + for (i = 0; i < data_length && psrc_data; i++) { *pdata++ = *psrc_data++; if (pdata >= hw->userdata_info.data_buf_end) pdata = hw->userdata_info.data_buf; @@ -1351,6 +1493,28 @@ void userdata_pushed_drop(struct vdec_mpeg12_hw_s *hw) } +static inline void hw_update_gvs(struct vdec_mpeg12_hw_s *hw) +{ + if (hw->gvs.frame_height != hw->frame_height) { + hw->gvs.frame_width = hw->frame_width; + hw->gvs.frame_height = hw->frame_height; + } + if (hw->gvs.frame_dur != hw->frame_dur) { + hw->gvs.frame_dur = hw->frame_dur; + if (hw->frame_dur != 0) + hw->gvs.frame_rate = 96000 / hw->frame_dur; + else + hw->gvs.frame_rate = -1; + } + if (hw->gvs.ratio_control != hw->ratio_control) + hw->gvs.ratio_control = hw->ratio_control; + + hw->gvs.status = hw->stat; + hw->gvs.error_count = hw->gvs.error_frame_count; + hw->gvs.drop_frame_count = hw->drop_frame_count; + +} + static int prepare_display_buf(struct vdec_mpeg12_hw_s *hw, struct pic_info_t *pic) { @@ -1360,18 +1524,31 @@ static int prepare_display_buf(struct vdec_mpeg12_hw_s *hw, u32 index = pic->index; u32 info = pic->buffer_info; struct vdec_s *vdec = hw_to_vdec(hw); + struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; + ulong nv_order = VIDTYPE_VIU_NV21; + bool pb_skip = false; - if (hw == NULL || pic == NULL) - return -1; - - user_data_ready_notify(hw, pic->pts, pic->pts_valid); #ifdef NV21 - type = VIDTYPE_VIU_NV21; + type = nv_order; #endif + /* swap uv */ + if (hw->is_used_v4l) { + if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) || + (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M)) + nv_order = VIDTYPE_VIU_NV12; + } + + pb_skip = (hw->pics[hw->refs[0]].offset == + hw->pics[hw->refs[1]].offset); + if (hw->i_only) { + pb_skip = 1; + } + + user_data_ready_notify(hw, pic->pts, pic->pts_valid); if (hw->frame_prog & PICINFO_PROG) { field_num = 1; - type |= VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; + type |= VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | nv_order; } else { #ifdef INTERLACE_SEQ_ALWAYS /* once an interlace seq, force interlace, to make di easy. */ @@ -1410,7 +1587,7 @@ static int prepare_display_buf(struct vdec_mpeg12_hw_s *hw, vf->duration_pulldown = (field_num == 3) ? (vf->duration >> 1):0; if (i > 0) - type = VIDTYPE_VIU_NV21; + type = nv_order; if (i == 1) /* second field*/ type |= (first_field_type == VIDTYPE_INTERLACE_TOP) ? VIDTYPE_INTERLACE_BOTTOM : VIDTYPE_INTERLACE_TOP; @@ -1447,21 +1624,33 @@ static int prepare_display_buf(struct vdec_mpeg12_hw_s *hw, vf->type_original = vf->type; if ((error_skip(hw, pic->buffer_info, vf)) || - ((hw->first_i_frame_ready == 0) && + (((hw->first_i_frame_ready == 0) || pb_skip) && ((PICINFO_TYPE_MASK & pic->buffer_info) != PICINFO_TYPE_I))) { hw->drop_frame_count++; + /* Though we drop it, it is still an error frame, count it. + * Becase we've counted the error frame in vdec_count_info + * function, avoid count it twice. + */ + if (!(info & PICINFO_ERROR)) + hw->gvs.error_frame_count++; hw->vfbuf_use[index]--; kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); } else { debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO, - "%s, num: %d(%c), i: %d, pts: %d(%lld), dur: %d, type: %x\n", - __func__, hw->disp_num, GET_SLICE_TYPE(info), i, - vf->pts, vf->pts_us64, vf->duration, vf->type); + "%s, vf: %lx, num[%d]: %d(%c), dur: %d, type: %x, pts: %d(%lld)\n", + __func__, (ulong)vf, i, hw->disp_num, GET_SLICE_TYPE(info), + vf->duration, vf->type, vf->pts, vf->pts_us64); hw->disp_num++; - if (i == 0) - decoder_do_frame_check(hw_to_vdec(hw), vf); + if (i == 0) { + struct vdec_s *vdec = hw_to_vdec(hw); + + decoder_do_frame_check(vdec, vf); + hw_update_gvs(hw); + vdec_fill_vdec_frame(vdec, &hw->vframe_qos, + &hw->gvs, vf, pic->hw_decode_time); + } vdec->vdec_fps_detec(vdec->id); vf->mem_handle = decoder_bmmu_box_get_mem_handle( @@ -1523,7 +1712,7 @@ static void force_interlace_check(struct vdec_mpeg12_hw_s *hw) static int update_reference(struct vdec_mpeg12_hw_s *hw, int index) { - hw->vfbuf_use[index]++; + hw->ref_use[index]++; if (hw->refs[1] == -1) { hw->refs[1] = index; /* @@ -1536,7 +1725,7 @@ static int update_reference(struct vdec_mpeg12_hw_s *hw, /* second pic do not output */ index = hw->buf_num; } else { - hw->vfbuf_use[hw->refs[0]]--; + hw->ref_use[hw->refs[0]]--; //old ref0 ununsed hw->refs[0] = hw->refs[1]; hw->refs[1] = index; index = hw->refs[0]; @@ -1552,10 +1741,56 @@ static bool is_ref_error(struct vdec_mpeg12_hw_s *hw) return 0; } +static int vmpeg2_get_ps_info(struct vdec_mpeg12_hw_s *hw, int width, int height, struct aml_vdec_ps_infos *ps) +{ + ps->visible_width = width; + ps->visible_height = height; + ps->coded_width = ALIGN(width, 64); + ps->coded_height = ALIGN(height, 32); + ps->dpb_size = hw->buf_num; + + return 0; +} + +static int v4l_res_change(struct vdec_mpeg12_hw_s *hw, int width, int height) +{ + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hw->v4l2_ctx); + int ret = 0; + + if (ctx->param_sets_from_ucode && + hw->res_ch_flag == 0) { + struct aml_vdec_ps_infos ps; + + if ((hw->frame_width != 0 && + hw->frame_height != 0) && + (hw->frame_width != width || + hw->frame_height != height)) { + debug_print(DECODE_ID(hw), 0, + "v4l_res_change Pic Width/Height Change (%d,%d)=>(%d,%d)\n", + hw->frame_width, hw->frame_height, + width, + height); + vmpeg2_get_ps_info(hw, width, height, &ps); + vdec_v4l_set_ps_infos(ctx, &ps); + vdec_v4l_res_ch_event(ctx); + hw->v4l_params_parsed = false; + hw->res_ch_flag = 1; + hw->eos = 1; + flush_output(hw); + notify_v4l_eos(hw_to_vdec(hw)); + + ret = 1; + } + } + + return ret; +} + static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq) { - u32 reg, index, info, seqinfo, offset, pts, frame_size, tmp; + u32 reg, index, info, seqinfo, offset, pts, frame_size=0, tmp; u64 pts_us64 = 0; struct pic_info_t *new_pic, *disp_pic; struct vdec_mpeg12_hw_s *hw = @@ -1575,6 +1810,38 @@ static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq) return IRQ_HANDLED; } + reg = READ_VREG(AV_SCRATCH_G); + if (reg == 1) { + if (hw->is_used_v4l) { + int frame_width = READ_VREG(MREG_PIC_WIDTH); + int frame_height = READ_VREG(MREG_PIC_HEIGHT); + if (!v4l_res_change(hw, frame_width, frame_height)) { + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hw->v4l2_ctx); + if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) { + struct aml_vdec_ps_infos ps; + + vmpeg2_get_ps_info(hw, frame_width, frame_height, &ps); + hw->v4l_params_parsed = true; + vdec_v4l_set_ps_infos(ctx, &ps); + userdata_pushed_drop(hw); + reset_process_time(hw); + hw->dec_result = DEC_RESULT_AGAIN; + vdec_schedule_work(&hw->work); + } else { + WRITE_VREG(AV_SCRATCH_G, 0); + } + } else { + userdata_pushed_drop(hw); + reset_process_time(hw); + hw->dec_result = DEC_RESULT_AGAIN; + vdec_schedule_work(&hw->work); + } + } else + WRITE_VREG(AV_SCRATCH_G, 0); + return IRQ_HANDLED; + } + reg = READ_VREG(AV_SCRATCH_J); if (reg & (1<<16)) { vdec_schedule_work(&hw->userdata_push_work); @@ -1624,6 +1891,11 @@ static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq) hw->dec_num++; hw->dec_result = DEC_RESULT_DONE; new_pic = &hw->pics[index]; + if (vdec->mvfrm) { + new_pic->frame_size = vdec->mvfrm->frame_size; + new_pic->hw_decode_time = + local_clock() - vdec->mvfrm->hw_decode_start; + } tmp = READ_VREG(MREG_PIC_WIDTH); if ((tmp > 1920) || (tmp == 0)) { new_pic->width = 1920; @@ -1642,26 +1914,6 @@ static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq) hw->frame_height = tmp; } - if (hw->is_used_v4l) { - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - - if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) { - struct aml_vdec_ps_infos ps; - - ps.visible_width = hw->frame_width; - ps.visible_height = hw->frame_height; - ps.coded_width = ALIGN(hw->frame_width, 64); - ps.coded_height = ALIGN(hw->frame_height, 64); - ps.dpb_size = hw->buf_num; - hw->v4l_params_parsed = true; - vdec_v4l_set_ps_infos(ctx, &ps); - } - - if (!ctx->v4l_codec_ready) - return IRQ_HANDLED; - } - new_pic->buffer_info = info; new_pic->offset = offset; new_pic->index = index; @@ -1734,6 +1986,11 @@ static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq) if (disp_pic->pts_valid) hw->lastpts64 = disp_pic->pts64; + if (input_frame_based(hw_to_vdec(hw))) + frame_size = new_pic->frame_size; + + fill_frame_info(hw, info, frame_size, new_pic->pts); + if ((hw->first_i_frame_ready == 0) && ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) && ((info & PICINFO_ERROR) == 0)) @@ -1760,7 +2017,7 @@ static irqreturn_t vmpeg12_isr(struct vdec_s *vdec, int irq) info = READ_VREG(MREG_PIC_INFO); offset = READ_VREG(MREG_FRAME_OFFSET); - vdec_count_info(&gvs, info & PICINFO_ERROR, offset); + vdec_count_info(&hw->gvs, info & PICINFO_ERROR, offset); WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); @@ -1809,8 +2066,14 @@ static void flush_output(struct vdec_mpeg12_hw_s *hw) if (hw->dec_num < 2) return; - if (index >= 0 && index < hw->buf_num) + if ((hw->refs[0] >= 0) && + (hw->refs[0] < hw->buf_num)) + hw->ref_use[hw->refs[0]] = 0; + + if (index >= 0 && index < hw->buf_num) { + hw->ref_use[index] = 0; prepare_display_buf(hw, &hw->pics[index]); + } } static int notify_v4l_eos(struct vdec_s *vdec) @@ -1819,6 +2082,7 @@ static int notify_v4l_eos(struct vdec_s *vdec) struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); struct vframe_s *vf = NULL; struct vdec_v4l2_buffer *fb = NULL; + int index; if (hw->is_used_v4l && hw->eos) { if (kfifo_get(&hw->newframe_q, &vf) == 0 || vf == NULL) { @@ -1827,14 +2091,17 @@ static int notify_v4l_eos(struct vdec_s *vdec) __func__); return -1; } - - if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb)) { + index = find_free_buffer(hw); + if ((index == -1) && + vdec_v4l_get_buffer(hw->v4l2_ctx, &fb)) { pr_err("[%d] get fb fail.\n", ctx->id); return -1; } + vf->type |= VIDTYPE_V4L_EOS; vf->timestamp = ULONG_MAX; - vf->v4l_mem_handle = (unsigned long)fb; + vf->v4l_mem_handle = (index == -1) ? (ulong)fb : + hw->pics[index].v4l_ref_buf_addr; vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L; kfifo_put(&hw->display_q, (const struct vframe_s *)vf); @@ -1941,6 +2208,15 @@ static void vmpeg12_work_implement(struct vdec_mpeg12_hw_s *hw, del_timer_sync(&hw->check_timer); hw->stat &= ~STAT_TIMER_ARM; + if (hw->is_used_v4l) { + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hw->v4l2_ctx); + + if (ctx->param_sets_from_ucode && + !hw->v4l_params_parsed) + vdec_v4l_write_frame_sync(ctx); + } + if (hw->vdec_cb) hw->vdec_cb(vdec, hw->vdec_cb_arg); } @@ -1994,19 +2270,42 @@ static struct vframe_s *vmpeg_vf_get(void *op_arg) return NULL; } +static int mpeg12_valid_vf_check(struct vframe_s *vf, struct vdec_mpeg12_hw_s *hw) +{ + int i; + + if (vf == NULL) + return 0; + + for (i = 0; i < VF_POOL_SIZE; i++) { + if (vf == &hw->vfpool[i]) + return 1; + } + return 0; +} + static void vmpeg_vf_put(struct vframe_s *vf, void *op_arg) { struct vdec_s *vdec = op_arg; struct vdec_mpeg12_hw_s *hw = (struct vdec_mpeg12_hw_s *)vdec->private; + if (!mpeg12_valid_vf_check(vf, hw)) { + debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR, + "invalid vf: %lx\n", (ulong)vf); + return ; + } hw->vfbuf_use[vf->index]--; + if (hw->vfbuf_use[vf->index] < 0) { + debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR, + "warn: vf %lx, index %d putback repetitive\n", (ulong)vf, vf->index); + } hw->put_num++; - kfifo_put(&hw->newframe_q, - (const struct vframe_s *)vf); debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW, - "%s: index %d, use %d\n", __func__, + "%s: vf: %lx, index: %d, use: %d\n", __func__, (ulong)vf, vf->index, hw->vfbuf_use[vf->index]); + kfifo_put(&hw->newframe_q, + (const struct vframe_s *)vf); } static int vmpeg_event_cb(int type, void *data, void *private_data) @@ -2047,16 +2346,16 @@ static int vmmpeg12_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) vstatus->frame_rate = -1; vstatus->error_count = READ_VREG(AV_SCRATCH_C); vstatus->status = hw->stat; - vstatus->bit_rate = gvs.bit_rate; + vstatus->bit_rate = hw->gvs.bit_rate; vstatus->frame_dur = hw->frame_dur; - vstatus->frame_data = gvs.frame_data; - vstatus->total_data = gvs.total_data; - vstatus->frame_count = gvs.frame_count; - vstatus->error_frame_count = gvs.error_frame_count; + vstatus->frame_data = hw->gvs.frame_data; + vstatus->total_data = hw->gvs.total_data; + vstatus->frame_count = hw->gvs.frame_count; + vstatus->error_frame_count = hw->gvs.error_frame_count; vstatus->drop_frame_count = hw->drop_frame_count; - vstatus->total_data = gvs.total_data; - vstatus->samp_cnt = gvs.samp_cnt; - vstatus->offset = gvs.offset; + vstatus->total_data = hw->gvs.total_data; + vstatus->samp_cnt = hw->gvs.samp_cnt; + vstatus->offset = hw->gvs.offset; vstatus->ratio_control = hw->ratio_control; snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name), "%s", DRIVER_NAME); @@ -2211,7 +2510,8 @@ static void vmpeg2_dump_state(struct vdec_s *vdec) for (i = 0; i < hw->buf_num; i++) { debug_print(DECODE_ID(hw), 0, - "index %d, used %d\n", i, hw->vfbuf_use[i]); + "index %d, used %d, ref %d\n", i, + hw->vfbuf_use[i], hw->ref_use[i]); } if (vf_get_receiver(vdec->vf_provider_name)) { @@ -2225,13 +2525,13 @@ static void vmpeg2_dump_state(struct vdec_s *vdec) state); } debug_print(DECODE_ID(hw), 0, - "%s, newq(%d/%d), dispq(%d/%d) vf peek/get/put (%d/%d/%d),drop=%d, buffer_not_ready %d\n", + "%s, newq(%d/%d), dispq(%d/%d) vf pre/get/put (%d/%d/%d),drop=%d, buffer_not_ready %d\n", __func__, kfifo_len(&hw->newframe_q), VF_POOL_SIZE, kfifo_len(&hw->display_q), VF_POOL_SIZE, - hw->peek_num, + hw->disp_num, hw->get_num, hw->put_num, hw->drop_frame_count, @@ -2376,15 +2676,17 @@ static void check_timer_func(unsigned long arg) static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw) { - int index, i; + u32 index, i; + struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; + index = find_free_buffer(hw); if (index < 0 || index >= hw->buf_num) return -1; if (!hw->init_flag) vmpeg12_canvas_init(hw); else { + WRITE_VREG(MREG_CO_MV_START, hw->buf_start); if (!hw->is_used_v4l) { - WRITE_VREG(MREG_CO_MV_START, hw->buf_start); for (i = 0; i < hw->buf_num; i++) { canvas_config_config(canvas_y(hw->canvas_spec[i]), &hw->canvas_config[i][0]); @@ -2414,7 +2716,6 @@ static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw) READ_VREG(MREG_REF1), READ_VREG(REC_CANVAS_ADDR), hw->ctx_valid, index); - /* set to mpeg1 default */ WRITE_VREG(MPEG1_2_REG, (hw->ctx_valid) ? hw->reg_mpeg1_2_reg : 0); @@ -2454,14 +2755,36 @@ static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw) WRITE_VREG(VCOP_CTRL_REG, hw->reg_vcop_ctrl_reg); WRITE_VREG(AV_SCRATCH_H, hw->reg_signal_type); + if (READ_VREG(MREG_ERROR_COUNT) != 0 || + READ_VREG(MREG_FATAL_ERROR) == 1) + debug_print(DECODE_ID(hw), PRINT_FLAG_RESTORE, + "err_cnt:%d fa_err:%d\n", + READ_VREG(MREG_ERROR_COUNT), + READ_VREG(MREG_FATAL_ERROR)); + /* clear error count */ WRITE_VREG(MREG_ERROR_COUNT, 0); - WRITE_VREG(MREG_FATAL_ERROR, 0); + /*Use MREG_FATAL_ERROR bit1, the ucode determine + whether to report the interruption of width and + height information,in order to be compatible + with the old version of ucode. + 1: Report the width and height information + 0: Not Report*/ + WRITE_VREG(MREG_FATAL_ERROR, 1 << 1); /* clear wait buffer status */ WRITE_VREG(MREG_WAIT_BUFFER, 0); #ifdef NV21 SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1<<17); #endif + + /* cbcr_merge_swap_en */ + if (hw->is_used_v4l + && (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21 + || v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M)) + SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16); + else + CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16); + if (!hw->ctx_valid) WRITE_VREG(AV_SCRATCH_J, hw->userdata_wp_ctx); @@ -2489,8 +2812,10 @@ static void vmpeg12_local_init(struct vdec_mpeg12_hw_s *hw) kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); } - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) + for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { hw->vfbuf_use[i] = 0; + hw->ref_use[i] = 0; + } if (hw->mm_blk_handle) { @@ -2630,6 +2955,30 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) } #endif + if (hw->is_used_v4l) { + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hw->v4l2_ctx); + + if (ctx->param_sets_from_ucode) { + if (hw->v4l_params_parsed) { + if (!ctx->v4l_codec_dpb_ready && + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < + run_ready_min_buf_num) + if (!ctx->v4l_codec_dpb_ready) + return 0; + } else { + if ((hw->res_ch_flag == 1) && + ((ctx->state <= AML_STATE_INIT) || + (ctx->state >= AML_STATE_FLUSHING))) + return 0; + } + } else if (!ctx->v4l_codec_dpb_ready) { + if (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < + run_ready_min_buf_num) + return 0; + } + } + if (!is_enough_free_buffer(hw)) { hw->buffer_not_ready++; return 0; @@ -2691,13 +3040,27 @@ void (*callback)(struct vdec_s *, void *), if (size < 0) { hw->input_empty++; hw->dec_result = DEC_RESULT_AGAIN; + + debug_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, + "vdec_prepare_input: Insufficient data\n"); vdec_schedule_work(&hw->work); return; } - if (vdec_frame_based(vdec) && debug_enable) { - u8 *data = NULL; + if (vdec_frame_based(vdec) && !vdec_secure(vdec)) { + /* HW needs padding (NAL start) for frame ending */ + char* tail = (char *)hw->chunk->block->start_virt; + tail += hw->chunk->offset + hw->chunk->size; + tail[0] = 0; + tail[1] = 0; + tail[2] = 1; + tail[3] = 0; + codec_mm_dma_flush(tail, 4, DMA_TO_DEVICE); + } + + if (vdec_frame_based(vdec) && debug_enable) { + u8 *data = NULL; if (hw->chunk) debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW, "run: chunk offset 0x%x, size %d\n", @@ -2752,6 +3115,8 @@ void (*callback)(struct vdec_s *, void *), READ_PARSER_REG(PARSER_VIDEO_WP), size); + if (vdec->mvfrm && hw->chunk) + vdec->mvfrm->frame_size = hw->chunk->size; hw->input_empty = 0; vdec_enable_input(vdec); @@ -2786,6 +3151,8 @@ void (*callback)(struct vdec_s *, void *), hw->stat |= STAT_MC_LOAD; hw->last_vld_level = 0; start_process_time(hw); + if (vdec->mvfrm) + vdec->mvfrm->hw_decode_start = local_clock(); amvdec_start(); hw->stat |= STAT_VDEC_RUN; hw->init_flag = 1; @@ -2797,6 +3164,23 @@ static void reset(struct vdec_s *vdec) pr_info("ammvdec_mpeg12: reset.\n"); } +static int vmpeg12_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) +{ + struct vdec_mpeg12_hw_s *hw = + (struct vdec_mpeg12_hw_s *)vdec->private; + if (!hw) + return 0; + + if (trickmode == TRICKMODE_I) { + hw->i_only = 0x3; + //trickmode_i = 1; + } else if (trickmode == TRICKMODE_NONE) { + hw->i_only = 0x0; + //trickmode_i = 0; + } + return 0; +} + static int ammvdec_mpeg12_probe(struct platform_device *pdev) { struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; @@ -2821,6 +3205,7 @@ static int ammvdec_mpeg12_probe(struct platform_device *pdev) pdata->private = hw; pdata->dec_status = vmmpeg12_dec_status; + pdata->set_trickmode = vmpeg12_set_trickmode; pdata->run_ready = run_ready; pdata->run = run; pdata->reset = reset; @@ -2848,25 +3233,34 @@ static int ammvdec_mpeg12_probe(struct platform_device *pdev) vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, &vf_provider_ops, pdata); - if (((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0) && pdata->config_len) { - debug_print(DECODE_ID(hw), 0, "pdata->config: %s\n", pdata->config); - if (get_config_int(pdata->config, "parm_v4l_buffer_margin", - &config_val) == 0) - hw->dynamic_buf_num_margin = config_val; - else - hw->dynamic_buf_num_margin = dynamic_buf_num_margin; - } else { - hw->dynamic_buf_num_margin = dynamic_buf_num_margin; - } - hw->buf_num = vmpeg12_get_buf_num(hw); - if (pdata->parallel_dec == 1) { int i; for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) hw->canvas_spec[i] = 0xffffff; } platform_set_drvdata(pdev, pdata); + + hw->dynamic_buf_num_margin = dynamic_buf_num_margin; hw->canvas_mode = pdata->canvas_mode; + if (pdata->config_len) { + if (get_config_int(pdata->config, + "parm_v4l_codec_enable", + &config_val) == 0) + hw->is_used_v4l = config_val; + + if (get_config_int(pdata->config, + "parm_v4l_canvas_mem_mode", + &config_val) == 0) + hw->canvas_mode = config_val; + + if ((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0 && + get_config_int(pdata->config, + "parm_v4l_buffer_margin", + &config_val) == 0) + hw->dynamic_buf_num_margin= config_val; + } + + hw->buf_num = vmpeg12_get_buf_num(hw); hw->platform_dev = pdev; hw->tvp_flag = vdec_secure(pdata) ? CODEC_MM_FLAGS_TVP : 0; @@ -2891,6 +3285,8 @@ static int ammvdec_mpeg12_probe(struct platform_device *pdev) } vdec_set_prepare_level(pdata, start_decode_buf_level); + vdec_set_vframe_comm(pdata, DRIVER_NAME); + if (pdata->parallel_dec == 1) vdec_core_request(pdata, CORE_MASK_VDEC_1); else { @@ -2902,9 +3298,6 @@ static int ammvdec_mpeg12_probe(struct platform_device *pdev) reset_user_data_buf(hw); #endif - hw->is_used_v4l = (((unsigned long) - hw->vmpeg12_amstream_dec_info.param & 0x80) >> 7); - /*INIT_WORK(&userdata_push_work, userdata_push_do_work);*/ return 0; } @@ -2974,12 +3367,10 @@ static int ammvdec_mpeg12_remove(struct platform_device *pdev) vfree(hw->fw); hw->fw = NULL; } - if (hw) { - vfree(hw); - hw = NULL; - } + + vfree(hw); + pr_info("ammvdec_mpeg12 removed.\n"); - memset(&gvs, 0x0, sizeof(gvs)); return 0; } diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4.c index 7092ddb..b0a715a 100644 --- a/drivers/frame_provider/decoder/mpeg4/vmpeg4.c +++ b/drivers/frame_provider/decoder/mpeg4/vmpeg4.c @@ -41,7 +41,7 @@ #include #include #include - +#include "../../../common/chips/decoder_cpu_ver_info.h" /* #define CONFIG_AM_VDEC_MPEG4_LOG */ @@ -1198,7 +1198,8 @@ static int amvdec_mpeg4_remove(struct platform_device *pdev) cancel_work_sync(&set_clk_work); amvdec_disable(); - + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_TM2) + vdec_reset_core(NULL); if (mm_blk_handle) { decoder_bmmu_box_free(mm_blk_handle); mm_blk_handle = NULL; diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c index c098a5e..aa73613 100644 --- a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c +++ b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c @@ -200,6 +200,8 @@ struct pic_info_t { u32 duration; u32 repeat_cnt; ulong v4l_ref_buf_addr; + u32 hw_decode_time; + u32 frame_size; // For frame base mode; }; struct vdec_mpeg4_hw_s { @@ -305,6 +307,7 @@ struct vdec_mpeg4_hw_s { bool v4l_params_parsed; u32 buf_num; u32 dynamic_buf_num_margin; + u32 i_only; }; static void vmpeg4_local_init(struct vdec_mpeg4_hw_s *hw); static int vmpeg4_hw_ctx_restore(struct vdec_mpeg4_hw_s *hw); @@ -611,7 +614,20 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, { struct vframe_s *vf = NULL; struct vdec_s *vdec = hw_to_vdec(hw); + struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; + ulong nv_order = VIDTYPE_VIU_NV21; int index = pic->index; + bool pb_skip = false; + + /* swap uv */ + if (hw->is_used_v4l) { + if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) || + (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M)) + nv_order = VIDTYPE_VIU_NV12; + } + + if (hw->i_only) + pb_skip = 1; if (pic->pic_info & INTERLACE_FLAG) { if (kfifo_get(&hw->newframe_q, &vf) == 0) { @@ -642,7 +658,7 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, vf->type = (pic->pic_info & TOP_FIELD_FIRST_FLAG) ? VIDTYPE_INTERLACE_TOP : VIDTYPE_INTERLACE_BOTTOM; #ifdef NV21 - vf->type |= VIDTYPE_VIU_NV21; + vf->type |= nv_order; #endif set_frame_info(hw, vf, pic->index); @@ -651,7 +667,7 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, "field0: pts %d, pts64 %lld, w %d, h %d, dur %d\n", vf->pts, vf->pts_us64, vf->width, vf->height, vf->duration); - if ((hw->first_i_frame_ready == 0) + if (((hw->first_i_frame_ready == 0) || pb_skip) && (pic->pic_type != I_PICTURE)) { hw->drop_frame_count++; hw->vfbuf_use[index]--; @@ -694,7 +710,7 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, vf->type = (pic->pic_info & TOP_FIELD_FIRST_FLAG) ? VIDTYPE_INTERLACE_BOTTOM : VIDTYPE_INTERLACE_TOP; #ifdef NV21 - vf->type |= VIDTYPE_VIU_NV21; + vf->type |= nv_order; #endif set_frame_info(hw, vf, pic->index); @@ -702,8 +718,8 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO, "filed1: pts %d, pts64 %lld, w %d, h %d, dur: %d\n", vf->pts, vf->pts_us64, vf->width, vf->height, vf->duration); - if ((hw->first_i_frame_ready == 0) && - (pic->pic_type != I_PICTURE)) { + if (((hw->first_i_frame_ready == 0) || pb_skip) + && (pic->pic_type != I_PICTURE)) { hw->drop_frame_count++; hw->vfbuf_use[index]--; kfifo_put(&hw->newframe_q, @@ -755,7 +771,7 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, pic->duration; #ifdef NV21 vf->type = VIDTYPE_PROGRESSIVE | - VIDTYPE_VIU_FIELD | VIDTYPE_VIU_NV21; + VIDTYPE_VIU_FIELD | nv_order; #else vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; @@ -767,13 +783,15 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, "prog: pts %d, pts64 %lld, w %d, h %d, dur %d\n", vf->pts, vf->pts_us64, vf->width, vf->height, vf->duration); - if ((hw->first_i_frame_ready == 0) && - (pic->pic_type != I_PICTURE)) { + if (((hw->first_i_frame_ready == 0) || pb_skip) + && (pic->pic_type != I_PICTURE)) { hw->drop_frame_count++; hw->vfbuf_use[index]--; kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); } else { + struct vdec_info vinfo; + vf->mem_handle = decoder_bmmu_box_get_mem_handle( hw->mm_blk_handle, index); @@ -784,6 +802,9 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, decoder_do_frame_check(vdec, vf); hw->frame_num++; + vdec->dec_status(vdec, &vinfo); + vdec_fill_vdec_frame(vdec, NULL, + &vinfo, vf, pic->hw_decode_time); if (without_display_mode == 0) { vf_notify_receiver(vdec->vf_provider_name, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); @@ -949,6 +970,11 @@ static irqreturn_t vmpeg4_isr_thread_fn(struct vdec_s *vdec, int irq) } hw->dec_result = DEC_RESULT_DONE; dec_pic = &hw->pic[index]; + if (vdec->mvfrm) { + dec_pic->frame_size = vdec->mvfrm->frame_size; + dec_pic->hw_decode_time = + local_clock() - vdec->mvfrm->hw_decode_start; + } dec_pic->pts_valid = false; dec_pic->pts = 0; dec_pic->pts64 = 0; @@ -978,9 +1004,6 @@ static irqreturn_t vmpeg4_isr_thread_fn(struct vdec_s *vdec, int irq) hw->v4l_params_parsed = true; vdec_v4l_set_ps_infos(ctx, &ps); } - - if (!ctx->v4l_codec_ready) - return IRQ_HANDLED; } if (hw->vmpeg4_amstream_dec_info.rate == 0) { @@ -1518,13 +1541,8 @@ static int vmpeg4_canvas_init(struct vdec_mpeg4_hw_s *hw) decbuf_size = ALIGN(align_w * align_h * 3/2, SZ_64K); } else { /*1080p*/ - if (h > w) { - canvas_width = 1088; - canvas_height = 1920; - } else { - canvas_width = 1920; - canvas_height = 1088; - } + canvas_width = 1920; + canvas_height = 1088; decbuf_y_size = 0x200000; decbuf_size = 0x300000; } @@ -1770,8 +1788,6 @@ static void check_timer_func(unsigned long arg) } if (((debug_enable & PRINT_FLAG_TIMEOUT_STATUS) == 0) && - (vdec_frame_based(vdec) || - ((u32)READ_VREG(VLD_MEM_VIFIFO_LEVEL) > 0x100)) && (timeout_val > 0) && (hw->start_process_time > 0) && ((1000 * (jiffies - hw->start_process_time) / HZ) @@ -2205,6 +2221,8 @@ static void run(struct vdec_s *vdec, unsigned long mask, size = hw->chunk_size + (hw->chunk_offset & (VDEC_FIFO_ALIGN - 1)); WRITE_VREG(VIFF_BIT_CNT, size * 8); + if (vdec->mvfrm) + vdec->mvfrm->frame_size = hw->chunk->size; } hw->input_empty = 0; hw->last_vld_level = 0; @@ -2213,6 +2231,8 @@ static void run(struct vdec_s *vdec, unsigned long mask, /* wmb before ISR is handled */ wmb(); + if (vdec->mvfrm) + vdec->mvfrm->hw_decode_start = local_clock(); amvdec_start(); hw->stat |= STAT_VDEC_RUN; hw->init_flag = 1; @@ -2250,6 +2270,23 @@ static void reset(struct vdec_s *vdec) hw->ctx_valid = 0; } +static int vmpeg4_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) +{ + struct vdec_mpeg4_hw_s *hw = + (struct vdec_mpeg4_hw_s *)vdec->private; + if (!hw) + return 0; + + if (trickmode == TRICKMODE_I) { + hw->i_only = 0x3; + trickmode_i = 1; + } else if (trickmode == TRICKMODE_NONE) { + hw->i_only = 0x0; + trickmode_i = 0; + } + return 0; +} + static int ammvdec_mpeg4_probe(struct platform_device *pdev) { struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; @@ -2274,6 +2311,7 @@ static int ammvdec_mpeg4_probe(struct platform_device *pdev) pdata->private = hw; pdata->dec_status = dec_status; /* pdata->set_trickmode = set_trickmode; */ + pdata->set_trickmode = vmpeg4_set_trickmode; pdata->run_ready = run_ready; pdata->run = run; pdata->reset = reset; @@ -2348,6 +2386,8 @@ static int ammvdec_mpeg4_probe(struct platform_device *pdev) } vdec_set_prepare_level(pdata, start_decode_buf_level); + vdec_set_vframe_comm(pdata, DRIVER_NAME); + if (pdata->parallel_dec == 1) vdec_core_request(pdata, CORE_MASK_VDEC_1); else { diff --git a/drivers/frame_provider/decoder/utils/amvdec.c b/drivers/frame_provider/decoder/utils/amvdec.c index bf8955e..c37b473 100644 --- a/drivers/frame_provider/decoder/utils/amvdec.c +++ b/drivers/frame_provider/decoder/utils/amvdec.c @@ -425,6 +425,11 @@ s32 optee_load_fw(enum vformat_e type, const char *fw_name) vdec = OPTEE_VDEC_HEVC; break; + case VFORMAT_AV1: + format = VIDEO_DEC_AV1_MMU; + vdec = OPTEE_VDEC_HEVC; + break; + case VFORMAT_HEVC: if (!strcmp(name, "h265_mmu")) format = VIDEO_DEC_HEVC_MMU; diff --git a/drivers/frame_provider/decoder/utils/frame_check.c b/drivers/frame_provider/decoder/utils/frame_check.c index 95d2609..accb430 100644 --- a/drivers/frame_provider/decoder/utils/frame_check.c +++ b/drivers/frame_provider/decoder/utils/frame_check.c @@ -122,10 +122,10 @@ static int get_frame_size(struct pic_check_mgr_t *pic, } pic->size_y = vf->width * vf->height; - pic->size_uv = pic->size_y >> 1; - pic->size_pic = pic->size_y + pic->size_uv; + pic->size_uv = pic->size_y >> (1 + pic->mjpeg_flag); + pic->size_pic = pic->size_y + (pic->size_y >> 1); - if (!(vf->type & VIDTYPE_VIU_NV21)) + if ((!(vf->type & VIDTYPE_VIU_NV21)) && (!pic->mjpeg_flag)) return 0; if ((vf->canvas0Addr == vf->canvas1Addr) && @@ -165,7 +165,7 @@ static int canvas_get_virt_addr(struct pic_check_mgr_t *pic, (vf->canvas0Addr != 0) && (vf->canvas0Addr != -1)) { phy_y_addr = canvas_get_addr(canvasY(vf->canvas0Addr)); - phy_uv_addr = canvas_get_addr(canvasUV(vf->canvas0Addr)); + phy_uv_addr = canvas_get_addr(canvasU(vf->canvas0Addr)); } else { phy_y_addr = vf->canvas0_config[0].phy_addr; phy_uv_addr = vf->canvas0_config[1].phy_addr; @@ -183,6 +183,20 @@ static int canvas_get_virt_addr(struct pic_check_mgr_t *pic, pic->y_phyaddr = phy_y_addr; pic->uv_phyaddr = phy_uv_addr; + if (pic->mjpeg_flag) { + if ((vf->canvas0Addr == vf->canvas1Addr) && + (vf->canvas0Addr != 0) && + (vf->canvas0Addr != -1)) { + pic->extra_v_phyaddr = canvas_get_addr(canvasV(vf->canvas0Addr)); + } else { + pic->extra_v_phyaddr = vf->canvas0_config[2].phy_addr; + } + pic->extra_v_vaddr = codec_mm_phys_to_virt(phy_uv_addr); + + if (!pic->extra_v_vaddr && !pic->extra_v_phyaddr) + return -1; + } + return 0; } @@ -252,6 +266,7 @@ static struct file* file_open(int mode, const char *str, ...) if (IS_ERR(fp)) { fp = NULL; dbg_print(FC_ERROR, "open %s failed\n", file); + va_end(args); return fp; } dbg_print(FC_ERROR, "open %s success\n", file); @@ -365,10 +380,13 @@ static int memcpy_phy_to_virt(char *to_virt, if (single_mode_vdec != NULL) { unsigned int offset = phy_from & (~PAGE_MASK); while (size > 0) { + /* flush dcache in isr. */ + flush_dcache_page(phys_to_page(phy_from)); + if (offset + size >= PAGE_SIZE) { vaddr = kmap_atomic(phys_to_page(phy_from)); tmp_size = (PAGE_SIZE - offset); - phy_from += tmp_size; + phy_from += tmp_size; //for next loop; size -= tmp_size; vaddr += offset; } else { @@ -382,14 +400,9 @@ static int memcpy_phy_to_virt(char *to_virt, __func__, (unsigned int)phy_from); return -1; } - /*Fixed frame error in random position of avs code stream. - Called in an interrupt.*/ - flush_dcache_page(phys_to_page(phy_from)); - /* - codec_mm_dma_flush(vaddr, - tmp_size, DMA_FROM_DEVICE); - */ + memcpy(to_virt, vaddr, tmp_size); + to_virt += tmp_size; kunmap_atomic(vaddr - offset); offset = 0; @@ -422,16 +435,37 @@ static int memcpy_phy_to_virt(char *to_virt, return 0; } + +static int do_yuv_unit_cp(void **addr, ulong phy, void *virt, + int h, int w, int stride) +{ + int ret = 0, i; + void *tmp = *addr; + + if ((phy != 0) && (virt == NULL)) { + for (i = 0; i < h; i++) { + ret |= memcpy_phy_to_virt(tmp, phy, w); + phy += stride; + tmp += w; + } + } else { + for (i = 0; i < h; i++) { + memcpy(tmp, virt, w); + virt += stride; + tmp += w; + } + } + *addr = tmp; + + return ret; +} + static int do_yuv_dump(struct pic_check_mgr_t *mgr, struct vframe_s *vf) { - int i, ret = 0; - void *tmp_addr, *tmp_yaddr, *tmp_uvaddr; - ulong y_phyaddr, uv_phyaddr; + int ret = 0; + void *tmp_addr; struct pic_dump_t *dump = &mgr->pic_dump; - /* - if ((vf->type & VIDTYPE_VIU_NV21) == 0) - return 0; - */ + if (dump->start > 0) { dump->start--; return 0; @@ -445,7 +479,7 @@ static int do_yuv_dump(struct pic_check_mgr_t *mgr, struct vframe_s *vf) (dump->buf_size - dump->dump_cnt * mgr->size_pic)) { if (dump->buf_size) { dbg_print(FC_ERROR, - "not enough buf, force dump less\n"); + "not enough buf for single mode, force dump less\n"); dump->num = dump->dump_cnt; check_schedule(mgr); } else @@ -464,49 +498,37 @@ static int do_yuv_dump(struct pic_check_mgr_t *mgr, struct vframe_s *vf) tmp_addr = dump->buf_addr; } - if ((mgr->uv_vaddr == NULL) || (mgr->y_vaddr == NULL)) { - y_phyaddr = mgr->y_phyaddr; - uv_phyaddr = mgr->uv_phyaddr; - if (vf->width == mgr->canvas_w) { - ret |= memcpy_phy_to_virt(tmp_addr, y_phyaddr, mgr->size_y); + if (vf->width == mgr->canvas_w) { + if ((mgr->uv_vaddr == NULL) || (mgr->y_vaddr == NULL)) { + ret |= memcpy_phy_to_virt(tmp_addr, mgr->y_phyaddr, mgr->size_y); ret |= memcpy_phy_to_virt(tmp_addr + mgr->size_y, - uv_phyaddr, mgr->size_uv); + mgr->uv_phyaddr, mgr->size_uv); + if (mgr->mjpeg_flag) /*mjpeg yuv420 u v is separate */ + ret |= memcpy_phy_to_virt(tmp_addr + mgr->size_y + mgr->size_uv, + mgr->extra_v_phyaddr, mgr->size_uv); } else { - for (i = 0; i < vf->height; i++) { - ret |= memcpy_phy_to_virt(tmp_addr, y_phyaddr, vf->width); - y_phyaddr += mgr->canvas_w; - tmp_addr += vf->width; - } - for (i = 0; i < vf->height/2; i++) { - ret |= memcpy_phy_to_virt(tmp_addr, uv_phyaddr, vf->width); - uv_phyaddr += mgr->canvas_w; - tmp_addr += vf->width; - } - } - if (ret < 0) { - dbg_print(0, "dump yuv failed, may codec_mm_vmap failed\n"); - return ret; + memcpy(tmp_addr, mgr->y_vaddr, mgr->size_y); + memcpy(tmp_addr + mgr->size_y, mgr->uv_vaddr, mgr->size_uv); + if (mgr->mjpeg_flag) /*mjpeg u v is separate */ + memcpy(tmp_addr + mgr->size_y + mgr->size_uv, + mgr->extra_v_vaddr, mgr->size_uv); } } else { - if (vf->width == mgr->canvas_w) { - memcpy(tmp_addr, mgr->y_vaddr, mgr->size_y); - memcpy(tmp_addr + mgr->size_y, - mgr->uv_vaddr, mgr->size_uv); - } else { - tmp_yaddr = mgr->y_vaddr; - tmp_uvaddr = mgr->uv_vaddr; - for (i = 0; i < vf->height; i++) { - memcpy(tmp_addr, tmp_yaddr, vf->width); - tmp_yaddr += mgr->canvas_w; - tmp_addr += vf->width; - } - for (i = 0; i < vf->height/2; i++) { - memcpy(tmp_addr, tmp_uvaddr, vf->width); - tmp_uvaddr += mgr->canvas_w; - tmp_addr += vf->width; + u32 uv_stride, uv_cpsize; + ret |= do_yuv_unit_cp(&tmp_addr, mgr->y_phyaddr, mgr->y_vaddr, + vf->height, vf->width, mgr->canvas_w); + + uv_stride = (mgr->mjpeg_flag) ? (mgr->canvas_w >> 1) : mgr->canvas_w; + uv_cpsize = (mgr->mjpeg_flag) ? (vf->width >> 1) : vf->width; + ret |= do_yuv_unit_cp(&tmp_addr, mgr->uv_phyaddr, mgr->uv_vaddr, + vf->height >> 1, uv_cpsize, uv_stride); + + if (mgr->mjpeg_flag) { + ret |= do_yuv_unit_cp(&tmp_addr, mgr->extra_v_phyaddr, mgr->extra_v_vaddr, + vf->height >> 1, uv_cpsize, uv_stride); } - } } + dump->dump_cnt++; dbg_print(0, "----->dump %dst, size %x (%d x %d), dec total %d\n", dump->dump_cnt, mgr->size_pic, vf->width, vf->height, mgr->frame_cnt); @@ -610,6 +632,9 @@ static int crc32_vmap_le(unsigned int *crc32, if (single_mode_vdec != NULL) { unsigned int offset = phyaddr & (~PAGE_MASK); while (size > 0) { + /*flush dcache in isr.*/ + flush_dcache_page(phys_to_page(phyaddr)); + if (offset + size >= PAGE_SIZE) { vaddr = kmap_atomic(phys_to_page(phyaddr)); tmp_size = (PAGE_SIZE - offset); @@ -627,13 +652,7 @@ static int crc32_vmap_le(unsigned int *crc32, __func__, (unsigned int)phyaddr); return -1; } - /*Fixed frame error in random position of avs code stream. - Called in an interrupt.*/ - flush_dcache_page(phys_to_page(phyaddr)); - /* - codec_mm_dma_flush(vaddr, - tmp_size, DMA_FROM_DEVICE); - */ + crc = crc32_le(crc, vaddr, tmp_size); kunmap_atomic(vaddr - offset); @@ -878,11 +897,13 @@ int decoder_do_frame_check(struct vdec_s *vdec, struct vframe_s *vf) single_mode_vdec = NULL; } - if ((mgr == NULL) || - (vf == NULL) || + if ((mgr == NULL) || (vf == NULL) || (mgr->enable == 0)) return 0; + mgr->mjpeg_flag = ((vdec) && + (vdec->format == VFORMAT_MJPEG)) ? 1 : 0; + if (get_frame_size(mgr, vf) < 0) return -1; @@ -898,17 +919,29 @@ int decoder_do_frame_check(struct vdec_s *vdec, struct vframe_s *vf) resize = 0; mgr->last_size_pic = mgr->size_pic; - if (vf->type & VIDTYPE_VIU_NV21) { + if ((vf->type & VIDTYPE_VIU_NV21) || (mgr->mjpeg_flag)) { + int flush_size; + if (canvas_get_virt_addr(mgr, vf) < 0) return -2; - if ((mgr->y_vaddr) && (mgr->uv_vaddr)) { + + /* flush */ + flush_size = mgr->mjpeg_flag ? + ((mgr->canvas_w * mgr->canvas_h) >> 2) : + ((mgr->canvas_w * mgr->canvas_h) >> 1); + if (mgr->y_vaddr) codec_mm_dma_flush(mgr->y_vaddr, mgr->canvas_w * mgr->canvas_h, DMA_FROM_DEVICE); + if (mgr->uv_vaddr) codec_mm_dma_flush(mgr->uv_vaddr, - ((mgr->canvas_w * mgr->canvas_h) >> 1), DMA_FROM_DEVICE); - } + flush_size, DMA_FROM_DEVICE); + if ((mgr->mjpeg_flag) && (mgr->extra_v_vaddr)) + codec_mm_dma_flush(mgr->extra_v_vaddr, + flush_size, DMA_FROM_DEVICE); + if (mgr->enable & CRC_MASK) ret = do_check_nv21(mgr, vf); + if (mgr->enable & YUV_MASK) do_yuv_dump(mgr, vf); @@ -1128,12 +1161,11 @@ int vdec_frame_check_init(struct vdec_s *vdec) return 0; vdec->vfc.err_crc_block = 0; + single_mode_vdec = (vdec_single(vdec))? vdec : NULL; + if (!check_enable && !yuv_enable) return 0; - if (vdec_single(vdec)) - single_mode_vdec = vdec; - vdec->canvas_mode = CANVAS_BLKMODE_LINEAR; id = vdec->id; diff --git a/drivers/frame_provider/decoder/utils/frame_check.h b/drivers/frame_provider/decoder/utils/frame_check.h index 430015f..251e141 100644 --- a/drivers/frame_provider/decoder/utils/frame_check.h +++ b/drivers/frame_provider/decoder/utils/frame_check.h @@ -85,6 +85,10 @@ struct pic_check_mgr_t{ struct usr_crc_info_t *cmp_pool; int usr_cmp_num; int usr_cmp_result; + /* for mjpeg u different addr with v */ + bool mjpeg_flag; + void *extra_v_vaddr; + ulong extra_v_phyaddr; }; int dump_yuv_trig(struct pic_check_mgr_t *mgr, diff --git a/drivers/frame_provider/decoder/utils/vdec.c b/drivers/frame_provider/decoder/utils/vdec.c index 41e84ba..15b841e 100644 --- a/drivers/frame_provider/decoder/utils/vdec.c +++ b/drivers/frame_provider/decoder/utils/vdec.c @@ -121,10 +121,8 @@ static int max_di_instance = 2; //static int path_debug = 0; -static struct vframe_qos_s *frame_info_buf_in = NULL; -static struct vframe_qos_s *frame_info_buf_out = NULL; -static int frame_qos_wr = 0; -static int frame_qos_rd = 0; +static int enable_mvdec_info = 1; + int decode_underflow = 0; #define CANVAS_MAX_SIZE (AMVDEC_CANVAS_MAX1 - AMVDEC_CANVAS_START_INDEX + 1 + AMVDEC_CANVAS_MAX2 + 1) @@ -195,9 +193,63 @@ static const char * const vdec_status_string[] = { "VDEC_STATUS_CONNECTED", "VDEC_STATUS_ACTIVE" }; +/* +bit [28] enable print +bit [23:16] etc +bit [15:12] + none 0 and not 0x1: force single + none 0 and 0x1: force multi +bit [8] + 1: force dual +bit [3] + 1: use mavs for single mode +bit [2] + 1: force vfm path for frame mode +bit [1] + 1: force esparser auto mode +bit [0] + 1: disable audo manual mode ?? +*/ static int debugflags; +static char vfm_path[VDEC_MAP_NAME_SIZE] = {"disable"}; +static const char vfm_path_node[][VDEC_MAP_NAME_SIZE] = +{ + "video_render.0", + "video_render.1", + "amvideo", + "videopip", + "deinterlace", + "dimulti.1", + "amlvideo", + "aml_video.1", + "amlvideo2.0", + "amlvideo2.1", + "ppmgr", + "ionvideo", + "ionvideo.1", + "ionvideo.2", + "ionvideo.3", + "ionvideo.4", + "ionvideo.5", + "ionvideo.6", + "ionvideo.7", + "ionvideo.8", + "videosync.0", + "v4lvideo.0", + "v4lvideo.1", + "v4lvideo.2", + "v4lvideo.3", + "v4lvideo.4", + "v4lvideo.5", + "v4lvideo.6", + "v4lvideo.7", + "v4lvideo.8", + "disable", + "reserved", +}; + static struct canvas_status_s canvas_stat[AMVDEC_CANVAS_MAX1 - AMVDEC_CANVAS_START_INDEX + 1 + AMVDEC_CANVAS_MAX2 + 1]; @@ -207,6 +259,13 @@ int vdec_get_debug_flags(void) } EXPORT_SYMBOL(vdec_get_debug_flags); +void VDEC_PRINT_FUN_LINENO(const char *fun, int line) +{ + if (debugflags & 0x10000000) + pr_info("%s, %d\n", fun, line); +} +EXPORT_SYMBOL(VDEC_PRINT_FUN_LINENO); + unsigned char is_mult_inc(unsigned int type) { unsigned char ret = 0; @@ -585,9 +644,15 @@ static void vdec_disable_DMC(struct vdec_s *vdec) codec_dmcbus_read(DMC_REQ_CTRL) & ~mask); spin_unlock_irqrestore(&vdec_spin_lock, flags); - while (!(codec_dmcbus_read(DMC_CHAN_STS) + if (is_cpu_tm2_revb()) { + while (!(codec_dmcbus_read(TM2_REVB_DMC_CHAN_STS) & mask)) ; + } else { + while (!(codec_dmcbus_read(DMC_CHAN_STS) + & mask)) + ; + } pr_debug("%s input->target= 0x%x\n", __func__, input->target); } @@ -628,6 +693,7 @@ static int vdec_get_hw_type(int value) case VFORMAT_HEVC: case VFORMAT_VP9: case VFORMAT_AVS2: + case VFORMAT_AV1: type = CORE_MASK_HEVC; break; @@ -741,7 +807,6 @@ EXPORT_SYMBOL(vdec_status); int vdec_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) { int r; - if (vdec->set_trickmode) { r = vdec->set_trickmode(vdec, trickmode); @@ -750,7 +815,6 @@ int vdec_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) trickmode); return r; } - return -1; } EXPORT_SYMBOL(vdec_set_trickmode); @@ -863,7 +927,8 @@ static const char * const vdec_device_name[] = { "amvenc_avc", "amvenc_avc", "jpegenc", "jpegenc", "amvdec_vp9", "ammvdec_vp9", - "amvdec_avs2", "ammvdec_avs2" + "amvdec_avs2", "ammvdec_avs2", + "amvdec_av1", "ammvdec_av1", }; @@ -885,7 +950,8 @@ static const char * const vdec_device_name[] = { "amvenc_avc", "jpegenc", "amvdec_vp9", - "amvdec_avs2" + "amvdec_avs2", + "amvdec_av1" }; #endif @@ -897,7 +963,7 @@ static const char * const vdec_device_name[] = { static const char *get_dev_name(bool use_legacy_vdec, int format) { #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC - if (use_legacy_vdec) + if (use_legacy_vdec && (debugflags & 0x8) == 0) return vdec_device_name[format * 2]; else return vdec_device_name[format * 2 + 1]; @@ -987,7 +1053,8 @@ int vdec_set_decinfo(struct vdec_s *vdec, struct dec_sysinfo *p) sprintf(fmt, "m%s", ++str); if (is_support_profile(fmt) && - vdec->sys_info->format != VIDEO_DEC_FORMAT_H263) + vdec->sys_info->format != VIDEO_DEC_FORMAT_H263 && + vdec->format != VFORMAT_AV1) vdec->type = VDEC_TYPE_STREAM_PARSER; } @@ -1027,6 +1094,9 @@ struct vdec_s *vdec_create(struct stream_port_s *port, INIT_LIST_HEAD(&vdec->list); atomic_inc(&vdec_core->vdec_nr); +#ifdef CONFIG_AMLOGIC_V4L_VIDEO3 + v4lvideo_dec_count_increase(); +#endif vdec->id = id; vdec_input_init(&vdec->input, vdec); vdec->input.vdec_is_input_frame_empty = vdec_is_input_frame_empty; @@ -1036,6 +1106,12 @@ struct vdec_s *vdec_create(struct stream_port_s *port, master->slave = vdec; master->sched = 1; } + if (enable_mvdec_info) { + vdec->mvfrm = (struct vdec_frames_s *) + vzalloc(sizeof(struct vdec_frames_s)); + if (!vdec->mvfrm) + pr_err("vzalloc: vdec_frames_s failed\n"); + } } pr_debug("vdec_create instance %p, total %d\n", vdec, @@ -1137,6 +1213,13 @@ int vdec_write_vframe(struct vdec_s *vdec, const char *buf, size_t count) } EXPORT_SYMBOL(vdec_write_vframe); +int vdec_write_vframe_with_dma(struct vdec_s *vdec, + ulong addr, size_t count, u32 handle) +{ + return vdec_input_add_frame_with_dma(&vdec->input, addr, count, handle); +} +EXPORT_SYMBOL(vdec_write_vframe_with_dma); + /* add a work queue thread for vdec*/ void vdec_schedule_work(struct work_struct *work) { @@ -1693,9 +1776,15 @@ void hevc_wait_ddr(void) codec_dmcbus_read(DMC_REQ_CTRL) & ~mask); spin_unlock_irqrestore(&vdec_spin_lock, flags); - while (!(codec_dmcbus_read(DMC_CHAN_STS) - & mask)) - ; + if (is_cpu_tm2_revb()) { + while (!(codec_dmcbus_read(TM2_REVB_DMC_CHAN_STS) + & mask)) + ; + } else { + while (!(codec_dmcbus_read(DMC_CHAN_STS) + & mask)) + ; + } } void vdec_save_input_context(struct vdec_s *vdec) @@ -1744,6 +1833,7 @@ void vdec_save_input_context(struct vdec_s *vdec) vdec->input.streaming_rp &= 0xffffffffULL << 32; vdec->input.streaming_rp |= vdec->input.stream_cookie; vdec->input.total_rd_count = vdec->input.streaming_rp; + hevc_wait_ddr(); } input->swap_valid = true; @@ -1759,8 +1849,6 @@ void vdec_save_input_context(struct vdec_s *vdec) /* pr_info("master->input.last_swap_slave = %d\n", master->input.last_swap_slave); */ } - - hevc_wait_ddr(); } } EXPORT_SYMBOL(vdec_save_input_context); @@ -1877,6 +1965,8 @@ EXPORT_SYMBOL(vdec_sync_input); const char *vdec_status_str(struct vdec_s *vdec) { + if (vdec->status < 0) + return "INVALID"; return vdec->status < ARRAY_SIZE(vdec_status_string) ? vdec_status_string[vdec->status] : "INVALID"; } @@ -2025,8 +2115,13 @@ int vdec_destroy(struct vdec_s *vdec) vdec_profile_flush(vdec); #endif ida_simple_remove(&vdec_core->ida, vdec->id); + if (vdec->mvfrm) + vfree(vdec->mvfrm); vfree(vdec); +#ifdef CONFIG_AMLOGIC_V4L_VIDEO3 + v4lvideo_dec_count_decrease(); +#endif atomic_dec(&vdec_core->vdec_nr); return 0; @@ -2044,6 +2139,7 @@ s32 vdec_init(struct vdec_s *vdec, int is_4k) const char *dev_name; int id = PLATFORM_DEVID_AUTO;/*if have used my self*/ + //pr_err("%s [pid=%d,tgid=%d]\n", __func__, current->pid, current->tgid); dev_name = get_dev_name(vdec_single(vdec), vdec->format); if (dev_name == NULL) @@ -2073,21 +2169,26 @@ s32 vdec_init(struct vdec_s *vdec, int is_4k) vdec_input_set_type(&vdec->input, vdec->type, (vdec->format == VFORMAT_HEVC || vdec->format == VFORMAT_AVS2 || - vdec->format == VFORMAT_VP9) ? + vdec->format == VFORMAT_VP9 || + vdec->format == VFORMAT_AV1 + ) ? VDEC_INPUT_TARGET_HEVC : VDEC_INPUT_TARGET_VLD); - if (vdec_single(vdec)) + if (vdec_single(vdec) || (vdec_get_debug_flags() & 0x2)) vdec_enable_DMC(vdec); p->cma_dev = vdec_core->cma_dev; p->get_canvas = get_canvas; p->get_canvas_ex = get_canvas_ex; p->free_canvas_ex = free_canvas_ex; p->vdec_fps_detec = vdec_fps_detec; + atomic_set(&p->inrelease, 0); atomic_set(&p->inirq_flag, 0); atomic_set(&p->inirq_thread_flag, 0); /* todo */ if (!vdec_dual(vdec)) p->use_vfm_path = vdec_stream_based(vdec); + if (debugflags & 0x4) + p->use_vfm_path = 1; /* vdec_dev_reg.flag = 0; */ if (vdec->id >= 0) id = vdec->id; @@ -2149,7 +2250,13 @@ s32 vdec_init(struct vdec_s *vdec, int is_4k) goto error; } - if (p->frame_base_video_path == FRAME_BASE_PATH_IONVIDEO) { + + if (strncmp("disable", vfm_path, strlen("disable"))) { + snprintf(vdec->vfm_map_chain, VDEC_MAP_NAME_SIZE, + "%s %s", vdec->vf_provider_name, vfm_path); + snprintf(vdec->vfm_map_id, VDEC_MAP_NAME_SIZE, + "vdec-map-%d", vdec->id); + } else if (p->frame_base_video_path == FRAME_BASE_PATH_IONVIDEO) { #if 1 r = ionvideo_assign_map(&vdec->vf_receiver_name, &vdec->vf_receiver_inst); @@ -2212,6 +2319,12 @@ s32 vdec_init(struct vdec_s *vdec, int is_4k) "amvideo"); snprintf(vdec->vfm_map_id, VDEC_MAP_NAME_SIZE, "vdec-map-%d", vdec->id); + } else if (p->frame_base_video_path == FRAME_BASE_PATH_PIP_TUNNEL_MODE) { + snprintf(vdec->vfm_map_chain, VDEC_MAP_NAME_SIZE, + "%s %s", vdec->vf_provider_name, + "videosync.0 videopip"); + snprintf(vdec->vfm_map_id, VDEC_MAP_NAME_SIZE, + "vdec-map-%d", vdec->id); } else if (p->frame_base_video_path == FRAME_BASE_PATH_V4L_VIDEO) { snprintf(vdec->vfm_map_chain, VDEC_MAP_NAME_SIZE, "%s %s %s", vdec->vf_provider_name, @@ -2233,7 +2346,7 @@ s32 vdec_init(struct vdec_s *vdec, int is_4k) mutex_unlock(&vdec_mutex); goto error; } - if (!v4lvideo_add_di || vdec_secure(vdec)) + if (!v4lvideo_add_di) snprintf(vdec->vfm_map_chain, VDEC_MAP_NAME_SIZE, "%s %s", vdec->vf_provider_name, vdec->vf_receiver_name); @@ -2330,32 +2443,14 @@ s32 vdec_init(struct vdec_s *vdec, int is_4k) } p->dolby_meta_with_el = 0; - pr_debug("vdec_init, vf_provider_name = %s\n", p->vf_provider_name); + pr_debug("vdec_init, vf_provider_name = %s, b %d\n", + p->vf_provider_name, is_cpu_tm2_revb()); vdec_input_prepare_bufs(/*prepared buffer for fast playing.*/ &vdec->input, vdec->sys_info->width, vdec->sys_info->height); /* vdec is now ready to be active */ vdec_set_status(vdec, VDEC_STATUS_DISCONNECTED); - if (p->use_vfm_path) { - frame_info_buf_in = (struct vframe_qos_s *) - kmalloc(QOS_FRAME_NUM*sizeof(struct vframe_qos_s), GFP_KERNEL); - if (!frame_info_buf_in) - pr_err("kmalloc: frame_info_buf_in failed\n"); - else - memset(frame_info_buf_in, 0, - QOS_FRAME_NUM*sizeof(struct vframe_qos_s)); - - frame_info_buf_out = (struct vframe_qos_s *) - kmalloc(QOS_FRAME_NUM*sizeof(struct vframe_qos_s), GFP_KERNEL); - if (!frame_info_buf_out) - pr_err("kmalloc: frame_info_buf_out failed\n"); - else - memset(frame_info_buf_out, 0, - QOS_FRAME_NUM*sizeof(struct vframe_qos_s)); - frame_qos_wr = 0; - frame_qos_rd = 0; - } return 0; error: @@ -2363,6 +2458,34 @@ error: } EXPORT_SYMBOL(vdec_init); +/* + *Remove the vdec after timeout happens both in vdec_disconnect + *and platform_device_unregister. Then after, we can release the vdec. + */ +static void vdec_connect_list_force_clear(struct vdec_core_s *core, struct vdec_s *v_ref) +{ + struct vdec_s *vdec, *tmp; + unsigned long flags; + + flags = vdec_core_lock(core); + + list_for_each_entry_safe(vdec, tmp, + &core->connected_vdec_list, list) { + if ((vdec->status == VDEC_STATUS_DISCONNECTED) && + (vdec == v_ref)) { + pr_err("%s, vdec = %p, active vdec = %p\n", + __func__, vdec, core->active_vdec); + if (core->active_vdec == v_ref) + core->active_vdec = NULL; + if (core->last_vdec == v_ref) + core->last_vdec = NULL; + list_del(&vdec->list); + } + } + + vdec_core_unlock(core, flags); +} + /* vdec_create/init/release/destroy are applied to both dual running decoders */ void vdec_release(struct vdec_s *vdec) @@ -2404,6 +2527,7 @@ void vdec_release(struct vdec_s *vdec) } } + atomic_set(&vdec->inrelease, 1); while ((atomic_read(&vdec->inirq_flag) > 0) || (atomic_read(&vdec->inirq_thread_flag) > 0)) schedule(); @@ -2415,16 +2539,10 @@ void vdec_release(struct vdec_s *vdec) if (atomic_read(&vdec_core->vdec_nr) == 1) vdec_disable_DMC(vdec); platform_device_unregister(vdec->dev); + /*Check if the vdec still in connected list, if yes, delete it*/ + vdec_connect_list_force_clear(vdec_core, vdec); pr_debug("vdec_release instance %p, total %d\n", vdec, atomic_read(&vdec_core->vdec_nr)); - if (vdec->use_vfm_path) { - kfree(frame_info_buf_in); - frame_info_buf_in = NULL; - kfree(frame_info_buf_out); - frame_info_buf_out = NULL; - frame_qos_wr = 0; - frame_qos_rd = 0; - } vdec_destroy(vdec); mutex_lock(&vdec_mutex); @@ -2657,6 +2775,8 @@ static irqreturn_t vdec_isr(int irq, void *dev_id) } if (vdec) { + if (atomic_read(&vdec->inrelease) > 0) + return ret; atomic_set(&vdec->inirq_flag, 1); vdec->isr_ns = local_clock(); } @@ -2714,11 +2834,13 @@ static irqreturn_t vdec_thread_isr(int irq, void *dev_id) if (vdec) { u32 isr2tfn = 0; + if (atomic_read(&vdec->inrelease) > 0) + return ret; atomic_set(&vdec->inirq_thread_flag, 1); vdec->tfn_ns = local_clock(); isr2tfn = vdec->tfn_ns - vdec->isr_ns; if (isr2tfn > 10000000) - pr_err("!!!!!!! %s vdec_isr to %s took %uns !!!\n", + pr_err("!!!!!!! %s vdec_isr to %s took %u ns !!!\n", vdec->vf_provider_name, __func__, isr2tfn); } if (c->dev_threaded_isr) { @@ -2863,12 +2985,7 @@ void vdec_prepare_run(struct vdec_s *vdec, unsigned long mask) if (secure && vdec_stream_based(vdec) && force_nosecure_even_drm) { - /* Verimatrix ultra webclient (HLS) was played in drmmode and used hw demux. In drmmode VDEC only can access secure. - Now HW demux parsed es data to no-secure buffer. So the VDEC input was no-secure, VDEC playback failed. Forcing - use nosecure for verimatrix webclient HLS. If in the future HW demux can parse es data to secure buffer, make - VDEC r/w secure.*/ secure = 0; - //pr_debug("allow VDEC can access nosecure even in drmmode\n"); } if (input->target == VDEC_INPUT_TARGET_VLD) tee_config_device_secure(DMC_DEV_ID_VDEC, secure); @@ -3837,9 +3954,15 @@ void vdec_reset_core(struct vdec_s *vdec) codec_dmcbus_read(DMC_REQ_CTRL) & ~mask); spin_unlock_irqrestore(&vdec_spin_lock, flags); - while (!(codec_dmcbus_read(DMC_CHAN_STS) - & mask)) - ; + if (is_cpu_tm2_revb()) { + while (!(codec_dmcbus_read(TM2_REVB_DMC_CHAN_STS) + & mask)) + ; + } else { + while (!(codec_dmcbus_read(DMC_CHAN_STS) + & mask)) + ; + } /* * 2: assist * 3: vld_reset @@ -3920,9 +4043,15 @@ void hevc_reset_core(struct vdec_s *vdec) codec_dmcbus_read(DMC_REQ_CTRL) & ~mask); spin_unlock_irqrestore(&vdec_spin_lock, flags); - while (!(codec_dmcbus_read(DMC_CHAN_STS) - & mask)) - ; + if (is_cpu_tm2_revb()) { + while (!(codec_dmcbus_read(TM2_REVB_DMC_CHAN_STS) + & mask)) + ; + } else { + while (!(codec_dmcbus_read(DMC_CHAN_STS) + & mask)) + ; + } if (vdec == NULL || input_frame_based(vdec)) WRITE_VREG(HEVC_STREAM_CONTROL, 0); @@ -4193,6 +4322,28 @@ static ssize_t clock_level_show(struct class *class, return ret; } +static ssize_t enable_mvdec_info_show(struct class *cla, + struct class_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", enable_mvdec_info); +} + +static ssize_t enable_mvdec_info_store(struct class *cla, + struct class_attribute *attr, + const char *buf, size_t count) +{ + int r; + int val; + + r = kstrtoint(buf, 0, &val); + if (r < 0) + return -EINVAL; + enable_mvdec_info = val; + + return count; +} + + static ssize_t store_poweron_clock_level(struct class *class, struct class_attribute *attr, const char *buf, size_t size) @@ -4241,6 +4392,7 @@ static ssize_t show_keep_vdec_mem(struct class *class, return sprintf(buf, "%d\n", keep_vdec_mem); } + #ifdef VDEC_DEBUG_SUPPORT static ssize_t store_debug(struct class *class, struct class_attribute *attr, @@ -4363,6 +4515,79 @@ static ssize_t show_debug(struct class *class, } #endif +static ssize_t store_vdec_vfm_path(struct class *class, + struct class_attribute *attr, + const char *buf, size_t count) +{ + char *buf_dup, *ps, *token; + char str[VDEC_MAP_NAME_SIZE] = "\0"; + bool found = false; + int i; + + if (strlen(buf) >= VDEC_MAP_NAME_SIZE) { + pr_info("parameter is overflow\n"); + return -1; + } + + buf_dup = kstrdup(buf, GFP_KERNEL); + ps = buf_dup; + while (1) { + token = strsep(&ps, "\n "); + if (token == NULL) + break; + if (*token == '\0') + continue; + + for (i = 0; strcmp("reserved", vfm_path_node[i]) != 0; i++) { + if (!strncmp (vfm_path_node[i], token, strlen(vfm_path_node[i]))) { + break; + } + } + + if (strcmp("reserved", vfm_path_node[i]) == 0 || + strncmp("help", buf, strlen("help")) == 0) { + if (strncmp("help", buf, strlen("help")) != 0) { + pr_info("warnning! Input parameter is invalid. set failed!\n"); + } + pr_info("\nusage for example: \n"); + pr_info("echo help > /sys/class/vdec/vfm_path \n"); + pr_info("echo disable > /sys/class/vdec/vfm_path \n"); + pr_info("echo amlvideo ppmgr amvideo > /sys/class/vdec/vfm_path \n"); + found = false; + + break; + } else { + strcat(str, vfm_path_node[i]); + strcat(str, " "); + found = true; + } + } + + if (found == true) { + memset(vfm_path, 0, sizeof(vfm_path)); + strncpy(vfm_path, str, strlen(str)); + vfm_path[VDEC_MAP_NAME_SIZE - 1] = '\0'; + pr_info("cfg path success: decoder %s\n", vfm_path); + } + kfree(buf_dup); + + return count; +} + +static ssize_t show_vdec_vfm_path(struct class *class, + struct class_attribute *attr, char *buf) +{ + int len = 0; + int i; + len += sprintf(buf + len, "cfg vfm path: decoder %s\n", vfm_path); + len += sprintf(buf + len, "\nvfm path node list: \n"); + for (i = 0; strcmp("reserved", vfm_path_node[i]) != 0; i++) { + len += sprintf(buf + len, "\t%s \n", vfm_path_node[i]); + } + + return len; +} + /*irq num as same as .dts*/ /* * interrupts = <0 3 1 @@ -4846,6 +5071,8 @@ static struct class_attribute vdec_class_attrs[] = { __ATTR_RO(amrisc_regs), __ATTR_RO(dump_trace), __ATTR_RO(clock_level), + __ATTR(enable_mvdec_info, S_IRUGO | S_IWUSR | S_IWGRP, + enable_mvdec_info_show, enable_mvdec_info_store), __ATTR(poweron_clock_level, S_IRUGO | S_IWUSR | S_IWGRP, show_poweron_clock_level, store_poweron_clock_level), __ATTR(dump_risc_mem, S_IRUGO | S_IWUSR | S_IWGRP, @@ -4868,6 +5095,8 @@ static struct class_attribute vdec_class_attrs[] = { frame_check_show, frame_check_store), #endif __ATTR_RO(dump_fps), + __ATTR(vfm_path, S_IRUGO | S_IWUSR | S_IWGRP, + show_vdec_vfm_path, store_vdec_vfm_path), __ATTR_NULL }; @@ -5073,104 +5302,109 @@ static int __init vdec_mem_setup(struct reserved_mem *rmem) return 0; } -void vdec_fill_frame_info(struct vframe_qos_s *vframe_qos, int debug) + +void vdec_set_vframe_comm(struct vdec_s *vdec, char *n) { - if (frame_info_buf_in == NULL) { - pr_info("error,frame_info_buf_in is null\n"); - return; - } - if (frame_info_buf_out == NULL) { - pr_info("error,frame_info_buf_out is null\n"); - return; - } - if (frame_qos_wr >= QOS_FRAME_NUM) - frame_qos_wr = 0; + struct vdec_frames_s *mvfrm = vdec->mvfrm; - if (frame_qos_wr >= QOS_FRAME_NUM || - frame_qos_wr < 0) { - pr_info("error,index :%d is error\n", frame_qos_wr); + if (!mvfrm) return; - } - if (frameinfo_flag == DISABLE_FRAME_INFO) + + mvfrm->comm.vdec_id = vdec->id; + + snprintf(mvfrm->comm.vdec_name, sizeof(mvfrm->comm.vdec_name)-1, + "%s", n); + mvfrm->comm.vdec_type = vdec->type; +} +EXPORT_SYMBOL(vdec_set_vframe_comm); + +void vdec_fill_vdec_frame(struct vdec_s *vdec, struct vframe_qos_s *vframe_qos, + struct vdec_info *vinfo,struct vframe_s *vf, + u32 hw_dec_time) +{ + u32 i; + struct vframe_counter_s *fifo_buf; + struct vdec_frames_s *mvfrm = vdec->mvfrm; + + if (!mvfrm) return; + fifo_buf = mvfrm->fifo_buf; + + /* assume fps==60,mv->wr max value can support system running 828 days, + this is enough for us */ + i = mvfrm->wr & (NUM_FRAME_VDEC-1); //find the slot num in fifo_buf + mvfrm->fifo_buf[i].decode_time_cost = hw_dec_time; + if (vframe_qos) + memcpy(&fifo_buf[i].qos, vframe_qos, sizeof(struct vframe_qos_s)); + if (vinfo) { + memcpy(&fifo_buf[i].frame_width, &vinfo->frame_width, + ((char*)&vinfo->reserved[0] - (char*)&vinfo->frame_width)); + } + if (vf) { + fifo_buf[i].vf_type = vf->type; + fifo_buf[i].signal_type = vf->signal_type; + fifo_buf[i].pts = vf->pts; + fifo_buf[i].pts_us64 = vf->pts_us64; + } + mvfrm->wr++; +} +EXPORT_SYMBOL(vdec_fill_vdec_frame); + +/* In this function,if we use copy_to_user, we may encounter sleep, +which may block the vdec_fill_vdec_frame,this is not acceptable. +So, we should use a tmp buffer(passed by caller) to get the content */ +u32 vdec_get_frame_vdec(struct vdec_s *vdec, struct vframe_counter_s *tmpbuf) +{ + u32 toread = 0; + u32 slot_rd; + struct vframe_counter_s *fifo_buf = NULL; + struct vdec_frames_s *mvfrm = NULL; - if (frameinfo_flag == PRINT_FRAME_INFO) { - pr_info("num %d size %d pts %d\n", - vframe_qos->num, - vframe_qos->size, - vframe_qos->pts); - pr_info("mv min_mv %d avg_mv %d max_mv %d\n", - vframe_qos->min_mv, - vframe_qos->avg_mv, - vframe_qos->max_mv); - pr_info("qp min_qp %d avg_qp %d max_qp %d\n", - vframe_qos->min_qp, - vframe_qos->avg_qp, - vframe_qos->max_qp); - pr_info("skip min_skip %d avg_skip %d max_skip %d\n", - vframe_qos->min_skip, - vframe_qos->avg_skip, - vframe_qos->max_skip); - } - memcpy(&frame_info_buf_in[frame_qos_wr++], - vframe_qos, sizeof(struct vframe_qos_s)); - if (frame_qos_wr >= QOS_FRAME_NUM) - frame_qos_wr = 0; - - /*pr_info("frame_qos_wr:%d\n", frame_qos_wr);*/ - -} -EXPORT_SYMBOL(vdec_fill_frame_info); - -struct vframe_qos_s *vdec_get_qos_info(void) -{ - int write_count = 0; - int qos_wr = frame_qos_wr; - - if (frame_info_buf_in == NULL) { - pr_info("error,frame_info_buf_in is null\n"); - return NULL; - } - if (frame_info_buf_out == NULL) { - pr_info("error,frame_info_buf_out is null\n"); - return NULL; + /* + switch (version) { + case version_1: + f1(); + case version_2: + f2(); + default: + break; } + */ + if (!vdec) + return 0; + mvfrm = vdec->mvfrm; + if (!mvfrm) + return 0; - memset(frame_info_buf_out, 0, - QOS_FRAME_NUM*sizeof(struct vframe_qos_s)); - if (frame_qos_rd > qos_wr) { - write_count = QOS_FRAME_NUM - frame_qos_rd; - if (write_count > 0 && write_count <= QOS_FRAME_NUM) { - memcpy(frame_info_buf_out, &frame_info_buf_in[0], - write_count*sizeof(struct vframe_qos_s)); - if ((write_count + qos_wr) <= QOS_FRAME_NUM) - memcpy(&frame_info_buf_out[write_count], frame_info_buf_in, - qos_wr*sizeof(struct vframe_qos_s)); - else - pr_info("get_qos_info:%d,out of range\n", __LINE__); - } else - pr_info("get_qos_info:%d,out of range\n", __LINE__); - } else if (frame_qos_rd < qos_wr) { - write_count = qos_wr - frame_qos_rd; - if (write_count > 0 && write_count < QOS_FRAME_NUM) - memcpy(frame_info_buf_out, &frame_info_buf_in[frame_qos_rd], - (write_count)*sizeof(struct vframe_qos_s)); - else - pr_info("get_qos_info:%d, out of range\n", __LINE__); + fifo_buf = &mvfrm->fifo_buf[0]; + + toread = mvfrm->wr - mvfrm->rd; + if (toread) { + if (toread >= NUM_FRAME_VDEC - QOS_FRAME_NUM) { + /* round the fifo_buf length happens, give QOS_FRAME_NUM for buffer */ + mvfrm->rd = mvfrm->wr - (NUM_FRAME_VDEC - QOS_FRAME_NUM); + } + + if (toread >= QOS_FRAME_NUM) { + toread = QOS_FRAME_NUM; //by default, we use this num + } + + slot_rd = mvfrm->rd &( NUM_FRAME_VDEC-1); //In this case it equals to x%y + if (slot_rd + toread <= NUM_FRAME_VDEC) { + memcpy(tmpbuf, &fifo_buf[slot_rd], toread*sizeof(struct vframe_counter_s)); + } else { + u32 exeed; + exeed = slot_rd + toread - NUM_FRAME_VDEC; + memcpy(tmpbuf, &fifo_buf[slot_rd], (NUM_FRAME_VDEC - slot_rd)*sizeof(struct vframe_counter_s)); + memcpy(&tmpbuf[NUM_FRAME_VDEC-slot_rd], &fifo_buf[0], exeed*sizeof(struct vframe_counter_s)); + } + + mvfrm->rd += toread; } - /* - pr_info("cnt:%d,size:%d,num:%d,rd:%d,wr:%d\n", - wirte_count, - frame_info_buf_out[0].size, - frame_info_buf_out[0].num, - frame_qos_rd,qos_wr); - */ - frame_qos_rd = qos_wr; - return frame_info_buf_out; + return toread; } -EXPORT_SYMBOL(vdec_get_qos_info); - +EXPORT_SYMBOL(vdec_get_frame_vdec); RESERVEDMEM_OF_DECLARE(vdec, "amlogic, vdec-memory", vdec_mem_setup); /* diff --git a/drivers/frame_provider/decoder/utils/vdec.h b/drivers/frame_provider/decoder/utils/vdec.h index 59ee2db..bc4ef21 100644 --- a/drivers/frame_provider/decoder/utils/vdec.h +++ b/drivers/frame_provider/decoder/utils/vdec.h @@ -121,7 +121,13 @@ extern void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size); unsigned int get_vdec_clk_config_settings(void); void update_vdec_clk_config_settings(unsigned int config); //unsigned int get_mmu_mode(void);//DEBUG_TMP -extern void vdec_fill_frame_info(struct vframe_qos_s *vframe_qos, int debug); +//extern void vdec_fill_frame_info(struct vframe_qos_s *vframe_qos, int debug); +extern void vdec_fill_vdec_frame(struct vdec_s *vdec, + struct vframe_qos_s *vframe_qos, + struct vdec_info *vinfo, + struct vframe_s *vf, u32 hw_dec_time); +extern void vdec_set_vframe_comm(struct vdec_s *vdec, char *n); + struct vdec_s; enum vformat_t; @@ -261,9 +267,11 @@ struct vdec_s { #endif atomic_t inirq_thread_flag; atomic_t inirq_flag; + atomic_t inrelease; int parallel_dec; volatile u64 isr_ns; volatile u64 tfn_ns; + struct vdec_frames_s *mvfrm; }; /* common decoder vframe provider name to use default vfm path */ @@ -316,6 +324,9 @@ extern int vdec_set_receive_id(struct vdec_s *vdec, int receive_id); extern int vdec_write_vframe(struct vdec_s *vdec, const char *buf, size_t count); +extern int vdec_write_vframe_with_dma(struct vdec_s *vdec, + ulong addr, size_t count, u32 handle); + /* mark the vframe_chunk as consumed */ extern void vdec_vframe_dirty(struct vdec_s *vdec, struct vframe_chunk_s *chunk); @@ -438,13 +449,16 @@ extern void vdec_set_step_mode(void); #endif int vdec_get_debug_flags(void); +void VDEC_PRINT_FUN_LINENO(const char *fun, int line); + + unsigned char is_mult_inc(unsigned int); int vdec_get_status(struct vdec_s *vdec); void vdec_set_timestamp(struct vdec_s *vdec, u64 timestamp); -extern struct vframe_qos_s *vdec_get_qos_info(void); +extern u32 vdec_get_frame_vdec(struct vdec_s *vdec, struct vframe_counter_s *tmpbuf); int vdec_get_frame_num(struct vdec_s *vdec); diff --git a/drivers/frame_provider/decoder/utils/vdec_input.c b/drivers/frame_provider/decoder/utils/vdec_input.c index 74bbaa7..ce30dbd 100644 --- a/drivers/frame_provider/decoder/utils/vdec_input.c +++ b/drivers/frame_provider/decoder/utils/vdec_input.c @@ -948,7 +948,7 @@ int vdec_input_add_frame(struct vdec_input_s *input, const char *buf, while (count > 0) { if (count < sizeof(struct drm_info)) return -EIO; - if (copy_from_user(&drm, buf + ret, sizeof(struct drm_info))) + if (copy_from_user((void*)&drm, buf + ret, sizeof(struct drm_info))) return -EAGAIN; if (!(drm.drm_flag & TYPE_DRMINFO_V2)) return -EIO; /*must drm info v2 version*/ @@ -971,6 +971,16 @@ int vdec_input_add_frame(struct vdec_input_s *input, const char *buf, } EXPORT_SYMBOL(vdec_input_add_frame); +int vdec_input_add_frame_with_dma(struct vdec_input_s *input, ulong addr, + size_t count, u32 handle) +{ + struct vdec_s *vdec = input->vdec; + + return vdec_secure(vdec) ? + vdec_input_add_chunk(input, (char *)addr, count, handle) : -1; +} +EXPORT_SYMBOL(vdec_input_add_frame_with_dma); + struct vframe_chunk_s *vdec_input_next_chunk(struct vdec_input_s *input) { struct vframe_chunk_s *chunk = NULL; diff --git a/drivers/frame_provider/decoder/utils/vdec_input.h b/drivers/frame_provider/decoder/utils/vdec_input.h index 26ccb49..4e871e7 100644 --- a/drivers/frame_provider/decoder/utils/vdec_input.h +++ b/drivers/frame_provider/decoder/utils/vdec_input.h @@ -143,6 +143,9 @@ extern int vdec_input_set_buffer(struct vdec_input_s *input, u32 start, extern int vdec_input_add_frame(struct vdec_input_s *input, const char *buf, size_t count); +extern int vdec_input_add_frame_with_dma(struct vdec_input_s *input, ulong addr, + size_t count, u32 handle); + /* Peek next frame data from decoder's input */ extern struct vframe_chunk_s *vdec_input_next_chunk( struct vdec_input_s *input); diff --git a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c index 107efec..e133b93 100644 --- a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c +++ b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c @@ -1,4 +1,6 @@ #include "vdec_v4l2_buffer_ops.h" +#include +#include int vdec_v4l_get_buffer(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out) @@ -15,6 +17,21 @@ int vdec_v4l_get_buffer(struct aml_vcodec_ctx *ctx, } EXPORT_SYMBOL(vdec_v4l_get_buffer); +int vdec_v4l_get_pic_info(struct aml_vcodec_ctx *ctx, + struct vdec_pic_info *pic) +{ + int ret = 0; + + if (ctx->drv_handle == 0) + return -EIO; + + ret = ctx->dec_if->get_param(ctx->drv_handle, + GET_PARAM_PIC_INFO, pic); + + return ret; +} +EXPORT_SYMBOL(vdec_v4l_get_pic_info); + int vdec_v4l_set_ps_infos(struct aml_vcodec_ctx *ctx, struct aml_vdec_ps_infos *ps) { @@ -45,6 +62,52 @@ int vdec_v4l_set_hdr_infos(struct aml_vcodec_ctx *ctx, } EXPORT_SYMBOL(vdec_v4l_set_hdr_infos); +static void aml_wait_dpb_ready(struct aml_vcodec_ctx *ctx) +{ + ulong expires; + + expires = jiffies + msecs_to_jiffies(1000); + while (!ctx->v4l_codec_dpb_ready) { + u32 ready_num = 0; + + if (time_after(jiffies, expires)) { + pr_err("the DPB state has not ready.\n"); + break; + } + + ready_num = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx); + if ((ready_num + ctx->buf_used_count) >= ctx->dpb_size) + ctx->v4l_codec_dpb_ready = true; + } +} + +void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx) +{ + unsigned int dpbsize = 0; + int ret; + + if (ctx->dec_if->get_param(ctx->drv_handle, GET_PARAM_PIC_INFO, &ctx->last_decoded_picinfo)) { + pr_err("Cannot get param : GET_PARAM_PICTURE_INFO ERR\n"); + return; + } + + if (ctx->last_decoded_picinfo.visible_width == 0 || + ctx->last_decoded_picinfo.visible_height == 0 || + ctx->last_decoded_picinfo.coded_width == 0 || + ctx->last_decoded_picinfo.coded_height == 0) { + pr_err("Cannot get correct pic info\n"); + return; + } + + ret = ctx->dec_if->get_param(ctx->drv_handle, GET_PARAM_DPB_SIZE, &dpbsize); + if (dpbsize == 0) + pr_err("Incorrect dpb size, ret=%d\n", ret); + + /* update picture information */ + ctx->dpb_size = dpbsize; + ctx->picinfo = ctx->last_decoded_picinfo; +} + int vdec_v4l_post_evet(struct aml_vcodec_ctx *ctx, u32 event) { int ret = 0; @@ -60,6 +123,35 @@ int vdec_v4l_post_evet(struct aml_vcodec_ctx *ctx, u32 event) } EXPORT_SYMBOL(vdec_v4l_post_evet); +int vdec_v4l_res_ch_event(struct aml_vcodec_ctx *ctx) +{ + int ret = 0; + struct aml_vcodec_dev *dev = ctx->dev; + + if (ctx->drv_handle == 0) + return -EIO; + + /* wait the DPB state to be ready. */ + aml_wait_dpb_ready(ctx); + + aml_vdec_pic_info_update(ctx); + + mutex_lock(&ctx->state_lock); + + ctx->state = AML_STATE_FLUSHING;/*prepare flushing*/ + + pr_info("[%d]: vcodec state (AML_STATE_FLUSHING-RESCHG)\n", ctx->id); + + mutex_unlock(&ctx->state_lock); + + ctx->q_data[AML_Q_DATA_SRC].resolution_changed = true; + v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx); + + return ret; +} +EXPORT_SYMBOL(vdec_v4l_res_ch_event); + + int vdec_v4l_write_frame_sync(struct aml_vcodec_ctx *ctx) { int ret = 0; diff --git a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h index 13f3543..8bedb88 100644 --- a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h +++ b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h @@ -8,6 +8,10 @@ int vdec_v4l_get_buffer( struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out); +int vdec_v4l_get_pic_info( + struct aml_vcodec_ctx *ctx, + struct vdec_pic_info *pic); + int vdec_v4l_set_ps_infos( struct aml_vcodec_ctx *ctx, struct aml_vdec_ps_infos *ps); @@ -23,4 +27,7 @@ int vdec_v4l_post_evet( struct aml_vcodec_ctx *ctx, u32 event); +int vdec_v4l_res_ch_event( + struct aml_vcodec_ctx *ctx); + #endif diff --git a/drivers/frame_provider/decoder/vav1/Makefile b/drivers/frame_provider/decoder/vav1/Makefile new file mode 100644 index 0000000..64a4973 --- a/dev/null +++ b/drivers/frame_provider/decoder/vav1/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AV1) += amvdec_av1.o +amvdec_av1-objs += vav1.o av1_bufmgr.o diff --git a/drivers/frame_provider/decoder/vav1/aom_av1_define.h b/drivers/frame_provider/decoder/vav1/aom_av1_define.h new file mode 100644 index 0000000..8a67885 --- a/dev/null +++ b/drivers/frame_provider/decoder/vav1/aom_av1_define.h @@ -0,0 +1,171 @@ +enum NalUnitType +{ + NAL_UNIT_CODED_SLICE_TRAIL_N = 0, // 0 + NAL_UNIT_CODED_SLICE_TRAIL_R, // 1 + + NAL_UNIT_CODED_SLICE_TSA_N, // 2 + NAL_UNIT_CODED_SLICE_TLA, // 3 // Current name in the spec: TSA_R + + NAL_UNIT_CODED_SLICE_STSA_N, // 4 + NAL_UNIT_CODED_SLICE_STSA_R, // 5 + + NAL_UNIT_CODED_SLICE_RADL_N, // 6 + NAL_UNIT_CODED_SLICE_DLP, // 7 // Current name in the spec: RADL_R + + NAL_UNIT_CODED_SLICE_RASL_N, // 8 + NAL_UNIT_CODED_SLICE_TFD, // 9 // Current name in the spec: RASL_R + + NAL_UNIT_RESERVED_10, + NAL_UNIT_RESERVED_11, + NAL_UNIT_RESERVED_12, + NAL_UNIT_RESERVED_13, + NAL_UNIT_RESERVED_14, + NAL_UNIT_RESERVED_15, + + NAL_UNIT_CODED_SLICE_BLA, // 16 // Current name in the spec: BLA_W_LP + NAL_UNIT_CODED_SLICE_BLANT, // 17 // Current name in the spec: BLA_W_DLP + NAL_UNIT_CODED_SLICE_BLA_N_LP, // 18 + NAL_UNIT_CODED_SLICE_IDR, // 19 // Current name in the spec: IDR_W_DLP + NAL_UNIT_CODED_SLICE_IDR_N_LP, // 20 + NAL_UNIT_CODED_SLICE_CRA, // 21 + NAL_UNIT_RESERVED_22, + NAL_UNIT_RESERVED_23, + + NAL_UNIT_RESERVED_24, + NAL_UNIT_RESERVED_25, + NAL_UNIT_RESERVED_26, + NAL_UNIT_RESERVED_27, + NAL_UNIT_RESERVED_28, + NAL_UNIT_RESERVED_29, + NAL_UNIT_RESERVED_30, + NAL_UNIT_RESERVED_31, + + NAL_UNIT_VPS, // 32 + NAL_UNIT_SPS, // 33 + NAL_UNIT_PPS, // 34 + NAL_UNIT_ACCESS_UNIT_DELIMITER, // 35 + NAL_UNIT_EOS, // 36 + NAL_UNIT_EOB, // 37 + NAL_UNIT_FILLER_DATA, // 38 + NAL_UNIT_SEI, // 39 Prefix SEI + NAL_UNIT_SEI_SUFFIX, // 40 Suffix SEI + NAL_UNIT_RESERVED_41, + NAL_UNIT_RESERVED_42, + NAL_UNIT_RESERVED_43, + NAL_UNIT_RESERVED_44, + NAL_UNIT_RESERVED_45, + NAL_UNIT_RESERVED_46, + NAL_UNIT_RESERVED_47, + NAL_UNIT_UNSPECIFIED_48, + NAL_UNIT_UNSPECIFIED_49, + NAL_UNIT_UNSPECIFIED_50, + NAL_UNIT_UNSPECIFIED_51, + NAL_UNIT_UNSPECIFIED_52, + NAL_UNIT_UNSPECIFIED_53, + NAL_UNIT_UNSPECIFIED_54, + NAL_UNIT_UNSPECIFIED_55, + NAL_UNIT_UNSPECIFIED_56, + NAL_UNIT_UNSPECIFIED_57, + NAL_UNIT_UNSPECIFIED_58, + NAL_UNIT_UNSPECIFIED_59, + NAL_UNIT_UNSPECIFIED_60, + NAL_UNIT_UNSPECIFIED_61, + NAL_UNIT_UNSPECIFIED_62, + NAL_UNIT_UNSPECIFIED_63, + NAL_UNIT_INVALID, +}; + +int forbidden_zero_bit; +int m_nalUnitType; +int m_reservedZero6Bits; +int m_temporalId; + +//--------------------------------------------------- +// Amrisc Software Interrupt +//--------------------------------------------------- +#define AMRISC_STREAM_EMPTY_REQ 0x01 +#define AMRISC_PARSER_REQ 0x02 +#define AMRISC_MAIN_REQ 0x04 + +//--------------------------------------------------- +// AOM_AV1_DEC_STATUS (HEVC_DEC_STATUS) define +//--------------------------------------------------- + /*command*/ +#define AOM_AV1_DEC_IDLE 0 +#define AOM_AV1_DEC_FRAME_HEADER 1 +#define AOM_AV1_DEC_TILE_END 2 +#define AOM_AV1_DEC_TG_END 3 +#define AOM_AV1_DEC_LCU_END 4 +#define AOM_AV1_DECODE_SLICE 5 +#define AOM_AV1_SEARCH_HEAD 6 +#define AOM_AV1_DUMP_LMEM 7 +#define AOM_AV1_FGS_PARAM_CONT 8 +#define AOM_AV1_FGS_PARAM_CONT 8 +#define AOM_AV1_PIC_END_CONT 9 + /*status*/ +#define AOM_AV1_DEC_PIC_END 0xe0 + /*AOM_AV1_FGS_PARA: + Bit[11] - 0 Read, 1 - Write + Bit[10:8] - film_grain_params_ref_idx, For Write request + */ +#define AOM_AV1_FGS_PARAM 0xe1 +#define AOM_AV1_DEC_PIC_END_PRE 0xe2 +#define AOM_AV1_HEAD_PARSER_DONE 0xf0 +#define AOM_AV1_HEAD_SEARCH_DONE 0xf1 +#define AOM_AV1_SEQ_HEAD_PARSER_DONE 0xf2 +#define AOM_AV1_FRAME_HEAD_PARSER_DONE 0xf3 +#define AOM_AV1_FRAME_PARSER_DONE 0xf4 +#define AOM_AV1_REDUNDANT_FRAME_HEAD_PARSER_DONE 0xf5 +#define HEVC_ACTION_DONE 0xff + + +//--------------------------------------------------- +// Include "parser_cmd.h" +//--------------------------------------------------- +#define PARSER_CMD_SKIP_CFG_0 0x0000090b + +#define PARSER_CMD_SKIP_CFG_1 0x1b14140f + +#define PARSER_CMD_SKIP_CFG_2 0x001b1910 + +#define PARSER_CMD_NUMBER 37 + +unsigned short parser_cmd[PARSER_CMD_NUMBER] = { +0x0401, +0x8401, +0x0800, +0x0402, +0x9002, +0x1423, +0x8CC3, +0x1423, +0x8804, +0x9825, +0x0800, +0x04FE, +0x8406, +0x8411, +0x1800, +0x8408, +0x8409, +0x8C2A, +0x9C2B, +0x1C00, +0x840F, +0x8407, +0x8000, +0x8408, +0x2000, +0xA800, +0x8410, +0x04DE, +0x840C, +0x840D, +0xAC00, +0xA000, +0x08C0, +0x08E0, +0xA40E, +0xFC00, +0x7C00 +}; diff --git a/drivers/frame_provider/decoder/vav1/av1_bufmgr.c b/drivers/frame_provider/decoder/vav1/av1_bufmgr.c new file mode 100644 index 0000000..0e983c9 --- a/dev/null +++ b/drivers/frame_provider/decoder/vav1/av1_bufmgr.c @@ -0,0 +1,3392 @@ +#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC +#include +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include + +#undef pr_info +#define pr_info printk + +#define __COMPARE(context, p1, p2) comp(p1, p2) +#define __SHORTSORT(lo, hi, width, comp, context) \ + shortsort(lo, hi, width, comp) +#define CUTOFF 8 /* testing shows that this is good value */ +#define STKSIZ (8*sizeof(void *) - 2) + +#undef swap +static void swap(char *a, char *b, size_t width) +{ + char tmp; + + if (a != b) + /* Do the swap one character at a time to avoid potential + * alignment problems. + */ + while (width--) { + tmp = *a; + *a++ = *b; + *b++ = tmp; + } +} + +static void shortsort(char *lo, char *hi, size_t width, + int (*comp)(const void *, const void *)) +{ + char *p, *max; + + /* Note: in assertions below, i and j are alway inside original + * bound of array to sort. + */ + while (hi > lo) { + /* A[i] <= A[j] for i <= j, j > hi */ + max = lo; + for (p = lo + width; p <= hi; p += width) { + /* A[i] <= A[max] for lo <= i < p */ + if (__COMPARE(context, p, max) > 0) + max = p; + /* A[i] <= A[max] for lo <= i <= p */ + } + /* A[i] <= A[max] for lo <= i <= hi */ + swap(max, hi, width); + + /* A[i] <= A[hi] for i <= hi, so A[i] <= A[j] for i <= j, + * j >= hi + */ + hi -= width; + + /* A[i] <= A[j] for i <= j, j > hi, loop top condition + * established + */ + } +} + +static void qsort(void *base, size_t num, size_t width, + int (*comp)(const void *, const void *)) +{ + char *lo, *hi; /* ends of sub-array currently sorting */ + char *mid; /* points to middle of subarray */ + char *loguy, *higuy; /* traveling pointers for partition step */ + size_t size; /* size of the sub-array */ + char *lostk[STKSIZ], *histk[STKSIZ]; + int stkptr; + +/* stack for saving sub-array to be + * processed + */ +#if 0 + /* validation section */ + _VALIDATE_RETURN_VOID(base != NULL || num == 0, EINVAL); + _VALIDATE_RETURN_VOID(width > 0, EINVAL); + _VALIDATE_RETURN_VOID(comp != NULL, EINVAL); +#endif + if (num < 2) + return; /* nothing to do */ + + stkptr = 0; /* initialize stack */ + lo = (char *)base; + hi = (char *)base + width * (num - 1); /* initialize limits */ + + /* this entry point is for pseudo-recursion calling: setting + * lo and hi and jumping to here is like recursion, but stkptr is + * preserved, locals aren't, so we preserve stuff on the stack + */ +recurse: + + size = (hi - lo) / width + 1; /* number of el's to sort */ + + /* below a certain size, it is faster to use a O(n^2) sorting method */ + if (size <= CUTOFF) { + __SHORTSORT(lo, hi, width, comp, context); + } else { + /* First we pick a partitioning element. The efficiency of + * the algorithm demands that we find one that is approximately + * the median of the values, but also that we select one fast. + * We choose the median of the first, middle, and last + * elements, to avoid bad performance in the face of already + * sorted data, or data that is made up of multiple sorted + * runs appended together. Testing shows that a + * median-of-three algorithm provides better performance than + * simply picking the middle element for the latter case. + */ + + mid = lo + (size / 2) * width; /* find middle element */ + + /* Sort the first, middle, last elements into order */ + if (__COMPARE(context, lo, mid) > 0) + swap(lo, mid, width); + if (__COMPARE(context, lo, hi) > 0) + swap(lo, hi, width); + if (__COMPARE(context, mid, hi) > 0) + swap(mid, hi, width); + + /* We now wish to partition the array into three pieces, one + * consisting of elements <= partition element, one of elements + * equal to the partition element, and one of elements > than + * it. This is done below; comments indicate conditions + * established at every step. + */ + + loguy = lo; + higuy = hi; + + /* Note that higuy decreases and loguy increases on every + * iteration, so loop must terminate. + */ + for (;;) { + /* lo <= loguy < hi, lo < higuy <= hi, + * A[i] <= A[mid] for lo <= i <= loguy, + * A[i] > A[mid] for higuy <= i < hi, + * A[hi] >= A[mid] + */ + + /* The doubled loop is to avoid calling comp(mid,mid), + * since some existing comparison funcs don't work + * when passed the same value for both pointers. + */ + + if (mid > loguy) { + do { + loguy += width; + } while (loguy < mid && + __COMPARE(context, loguy, mid) <= 0); + } + if (mid <= loguy) { + do { + loguy += width; + } while (loguy <= hi && + __COMPARE(context, loguy, mid) <= 0); + } + + /* lo < loguy <= hi+1, A[i] <= A[mid] for + * lo <= i < loguy, + * either loguy > hi or A[loguy] > A[mid] + */ + + do { + higuy -= width; + } while (higuy > mid && + __COMPARE(context, higuy, mid) > 0); + + /* lo <= higuy < hi, A[i] > A[mid] for higuy < i < hi, + * either higuy == lo or A[higuy] <= A[mid] + */ + + if (higuy < loguy) + break; + + /* if loguy > hi or higuy == lo, then we would have + * exited, so A[loguy] > A[mid], A[higuy] <= A[mid], + * loguy <= hi, higuy > lo + */ + + swap(loguy, higuy, width); + + /* If the partition element was moved, follow it. + * Only need to check for mid == higuy, since before + * the swap, A[loguy] > A[mid] implies loguy != mid. + */ + + if (mid == higuy) + mid = loguy; + + /* A[loguy] <= A[mid], A[higuy] > A[mid]; so condition + * at top of loop is re-established + */ + } + + /* A[i] <= A[mid] for lo <= i < loguy, + * A[i] > A[mid] for higuy < i < hi, + * A[hi] >= A[mid] + * higuy < loguy + * implying: + * higuy == loguy-1 + * or higuy == hi - 1, loguy == hi + 1, A[hi] == A[mid] + */ + + /* Find adjacent elements equal to the partition element. The + * doubled loop is to avoid calling comp(mid,mid), since some + * existing comparison funcs don't work when passed the same + * value for both pointers. + */ + + higuy += width; + if (mid < higuy) { + do { + higuy -= width; + } while (higuy > mid && + __COMPARE(context, higuy, mid) == 0); + } + if (mid >= higuy) { + do { + higuy -= width; + } while (higuy > lo && + __COMPARE(context, higuy, mid) == 0); + } + + /* OK, now we have the following: + * higuy < loguy + * lo <= higuy <= hi + * A[i] <= A[mid] for lo <= i <= higuy + * A[i] == A[mid] for higuy < i < loguy + * A[i] > A[mid] for loguy <= i < hi + * A[hi] >= A[mid] + */ + + /* We've finished the partition, now we want to sort the + * subarrays [lo, higuy] and [loguy, hi]. + * We do the smaller one first to minimize stack usage. + * We only sort arrays of length 2 or more. + */ + + if (higuy - lo >= hi - loguy) { + if (lo < higuy) { + lostk[stkptr] = lo; + histk[stkptr] = higuy; + ++stkptr; + } /* save big recursion for later */ + + if (loguy < hi) { + lo = loguy; + goto recurse; /* do small recursion */ + } + } else { + if (loguy < hi) { + lostk[stkptr] = loguy; + histk[stkptr] = hi; + ++stkptr; /* save big recursion for later */ + } + + if (lo < higuy) { + hi = higuy; + goto recurse; /* do small recursion */ + } + } + } + + /* We have sorted the array, except for any pending sorts on the stack. + * Check if there are any, and do them. + */ + + --stkptr; + if (stkptr >= 0) { + lo = lostk[stkptr]; + hi = histk[stkptr]; + goto recurse; /* pop subarray from stack */ + } else + return; /* all subarrays done */ +} + +#endif + +#include "av1_global.h" +int aom_realloc_frame_buffer(AV1_COMMON *cm, PIC_BUFFER_CONFIG *pic, + int width, int height, unsigned int order_hint); +void dump_params(AV1Decoder *pbi, union param_u *params); + +#define assert(a) +#define IMPLIES(a) + +int new_compressed_data_count = 0; + +static int valid_ref_frame_size(int ref_width, int ref_height, + int this_width, int this_height) { + return 2 * this_width >= ref_width && 2 * this_height >= ref_height && + this_width <= 16 * ref_width && this_height <= 16 * ref_height; +} + +#ifdef SUPPORT_SCALE_FACTOR +// Note: Expect val to be in q4 precision +static inline int scaled_x(int val, const struct scale_factors *sf) { + const int off = + (sf->x_scale_fp - (1 << REF_SCALE_SHIFT)) * (1 << (SUBPEL_BITS - 1)); + const int64_t tval = (int64_t)val * sf->x_scale_fp + off; + return (int)ROUND_POWER_OF_TWO_SIGNED_64(tval, + REF_SCALE_SHIFT - SCALE_EXTRA_BITS); +} + +// Note: Expect val to be in q4 precision +static inline int scaled_y(int val, const struct scale_factors *sf) { + const int off = + (sf->y_scale_fp - (1 << REF_SCALE_SHIFT)) * (1 << (SUBPEL_BITS - 1)); + const int64_t tval = (int64_t)val * sf->y_scale_fp + off; + return (int)ROUND_POWER_OF_TWO_SIGNED_64(tval, + REF_SCALE_SHIFT - SCALE_EXTRA_BITS); +} + +// Note: Expect val to be in q4 precision +static int unscaled_value(int val, const struct scale_factors *sf) { + (void)sf; + return val << SCALE_EXTRA_BITS; +} + +static int get_fixed_point_scale_factor(int other_size, int this_size) { + // Calculate scaling factor once for each reference frame + // and use fixed point scaling factors in decoding and encoding routines. + // Hardware implementations can calculate scale factor in device driver + // and use multiplication and shifting on hardware instead of division. + return ((other_size << REF_SCALE_SHIFT) + this_size / 2) / this_size; +} + +// Given the fixed point scale, calculate coarse point scale. +static int fixed_point_scale_to_coarse_point_scale(int scale_fp) { + return ROUND_POWER_OF_TWO(scale_fp, REF_SCALE_SHIFT - SCALE_SUBPEL_BITS); +} + + +void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w, + int other_h, int this_w, int this_h) { + if (!valid_ref_frame_size(other_w, other_h, this_w, this_h)) { + sf->x_scale_fp = REF_INVALID_SCALE; + sf->y_scale_fp = REF_INVALID_SCALE; + return; + } + + sf->x_scale_fp = get_fixed_point_scale_factor(other_w, this_w); + sf->y_scale_fp = get_fixed_point_scale_factor(other_h, this_h); + + sf->x_step_q4 = fixed_point_scale_to_coarse_point_scale(sf->x_scale_fp); + sf->y_step_q4 = fixed_point_scale_to_coarse_point_scale(sf->y_scale_fp); + + if (av1_is_scaled(sf)) { + sf->scale_value_x = scaled_x; + sf->scale_value_y = scaled_y; + } else { + sf->scale_value_x = unscaled_value; + sf->scale_value_y = unscaled_value; + } +#ifdef ORI_CODE + // AV1 convolve functions + // Special case convolve functions should produce the same result as + // av1_convolve_2d. + // subpel_x_qn == 0 && subpel_y_qn == 0 + sf->convolve[0][0][0] = av1_convolve_2d_copy_sr; + // subpel_x_qn == 0 + sf->convolve[0][1][0] = av1_convolve_y_sr; + // subpel_y_qn == 0 + sf->convolve[1][0][0] = av1_convolve_x_sr; + // subpel_x_qn != 0 && subpel_y_qn != 0 + sf->convolve[1][1][0] = av1_convolve_2d_sr; + // subpel_x_qn == 0 && subpel_y_qn == 0 + sf->convolve[0][0][1] = av1_dist_wtd_convolve_2d_copy; + // subpel_x_qn == 0 + sf->convolve[0][1][1] = av1_dist_wtd_convolve_y; + // subpel_y_qn == 0 + sf->convolve[1][0][1] = av1_dist_wtd_convolve_x; + // subpel_x_qn != 0 && subpel_y_qn != 0 + sf->convolve[1][1][1] = av1_dist_wtd_convolve_2d; + // AV1 High BD convolve functions + // Special case convolve functions should produce the same result as + // av1_highbd_convolve_2d. + // subpel_x_qn == 0 && subpel_y_qn == 0 + sf->highbd_convolve[0][0][0] = av1_highbd_convolve_2d_copy_sr; + // subpel_x_qn == 0 + sf->highbd_convolve[0][1][0] = av1_highbd_convolve_y_sr; + // subpel_y_qn == 0 + sf->highbd_convolve[1][0][0] = av1_highbd_convolve_x_sr; + // subpel_x_qn != 0 && subpel_y_qn != 0 + sf->highbd_convolve[1][1][0] = av1_highbd_convolve_2d_sr; + // subpel_x_qn == 0 && subpel_y_qn == 0 + sf->highbd_convolve[0][0][1] = av1_highbd_dist_wtd_convolve_2d_copy; + // subpel_x_qn == 0 + sf->highbd_convolve[0][1][1] = av1_highbd_dist_wtd_convolve_y; + // subpel_y_qn == 0 + sf->highbd_convolve[1][0][1] = av1_highbd_dist_wtd_convolve_x; + // subpel_x_qn != 0 && subpel_y_qn != 0 + sf->highbd_convolve[1][1][1] = av1_highbd_dist_wtd_convolve_2d; +#endif +} +#endif + + +static int get_free_fb(AV1_COMMON *cm) { + RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; + int i; + unsigned long flags; + lock_buffer_pool(cm->buffer_pool, flags); + for (i = 0; i < FRAME_BUFFERS; ++i) + if (frame_bufs[i].ref_count == 0 +#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC + && frame_bufs[i].buf.vf_ref == 0 +#endif + ) + break; + + if (i != FRAME_BUFFERS) { + if (frame_bufs[i].buf.use_external_reference_buffers) { + // If this frame buffer's y_buffer, u_buffer, and v_buffer point to the + // external reference buffers. Restore the buffer pointers to point to the + // internally allocated memory. + PIC_BUFFER_CONFIG *ybf = &frame_bufs[i].buf; + ybf->y_buffer = ybf->store_buf_adr[0]; + ybf->u_buffer = ybf->store_buf_adr[1]; + ybf->v_buffer = ybf->store_buf_adr[2]; + ybf->use_external_reference_buffers = 0; + } + + frame_bufs[i].ref_count = 1; + } else { + // We should never run out of free buffers. If this assertion fails, there + // is a reference leak. + assert(0 && "Ran out of free frame buffers. Likely a reference leak."); + // Reset i to be INVALID_IDX to indicate no free buffer found. + i = INVALID_IDX; + } + + unlock_buffer_pool(cm->buffer_pool, flags); + return i; +} + +static RefCntBuffer *assign_cur_frame_new_fb(AV1_COMMON *const cm) { + // Release the previously-used frame-buffer + int new_fb_idx; + if (cm->cur_frame != NULL) { + --cm->cur_frame->ref_count; + cm->cur_frame = NULL; + } + + // Assign a new framebuffer + new_fb_idx = get_free_fb(cm); + if (new_fb_idx == INVALID_IDX) return NULL; + + cm->cur_frame = &cm->buffer_pool->frame_bufs[new_fb_idx]; + cm->cur_frame->buf.buf_8bit_valid = 0; +#ifdef AML + cm->cur_frame->buf.index = new_fb_idx; +#endif +#ifdef ORI_CODE + av1_zero(cm->cur_frame->interp_filter_selected); +#endif + return cm->cur_frame; +} + +// Modify 'lhs_ptr' to reference the buffer at 'rhs_ptr', and update the ref +// counts accordingly. +static void assign_frame_buffer_p(RefCntBuffer **lhs_ptr, + RefCntBuffer *rhs_ptr) { + RefCntBuffer *const old_ptr = *lhs_ptr; + if (old_ptr != NULL) { + assert(old_ptr->ref_count > 0); + // One less reference to the buffer at 'old_ptr', so decrease ref count. + --old_ptr->ref_count; + } + + *lhs_ptr = rhs_ptr; + // One more reference to the buffer at 'rhs_ptr', so increase ref count. + ++rhs_ptr->ref_count; +} + +AV1Decoder *av1_decoder_create(BufferPool *const pool) { + int i; + AV1_COMMON *cm; + +#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC + AV1Decoder *pbi = (AV1Decoder *)malloc(sizeof(*pbi)); +#else + AV1Decoder *pbi = (AV1Decoder *)vmalloc(sizeof(AV1Decoder)); +#endif + if (!pbi) return NULL; + memset(pbi, 0, sizeof(*pbi)); + + cm = &pbi->common; + + // The jmp_buf is valid only for the duration of the function that calls + // setjmp(). Therefore, this function must reset the 'setjmp' field to 0 + // before it returns. + + cm->error.setjmp = 1; + +#ifdef ORI_CODE + memset(cm->fc, 0, sizeof(*cm->fc)); + memset(cm->default_frame_context, 0, sizeof(*cm->default_frame_context)); +#endif + pbi->need_resync = 1; + + // Initialize the references to not point to any frame buffers. + for (i = 0; i < REF_FRAMES; i++) { + cm->ref_frame_map[i] = NULL; + cm->next_ref_frame_map[i] = NULL; +#ifdef AML + cm->next_used_ref_frame_map[i] = NULL; +#endif + } + + cm->current_frame.frame_number = 0; + pbi->decoding_first_frame = 1; + pbi->common.buffer_pool = pool; + + cm->seq_params.bit_depth = AOM_BITS_8; + +#ifdef ORI_CODE + cm->alloc_mi = dec_alloc_mi; + cm->free_mi = dec_free_mi; + cm->setup_mi = dec_setup_mi; + + av1_loop_filter_init(cm); + + av1_qm_init(cm); + av1_loop_restoration_precal(); +#if CONFIG_ACCOUNTING + pbi->acct_enabled = 1; + aom_accounting_init(&pbi->accounting); +#endif +#endif + cm->error.setjmp = 0; + +#ifdef ORI_CODE + aom_get_worker_interface()->init(&pbi->lf_worker); + pbi->lf_worker.thread_name = "aom lf worker"; +#endif + + return pbi; +} + +int release_fb_cb(void *cb_priv, aom_codec_frame_buffer_t *fb) { +#if 0 + InternalFrameBuffer *const int_fb = (InternalFrameBuffer *)fb->priv; + (void)cb_priv; + if (int_fb) int_fb->in_use = 0; +#endif + return 0; +} + +static void decrease_ref_count(AV1Decoder *pbi, RefCntBuffer *const buf, + BufferPool *const pool) { + if (buf != NULL) { + --buf->ref_count; + // Reference counts should never become negative. If this assertion fails, + // there is a bug in our reference count management. + assert(buf->ref_count >= 0); + // A worker may only get a free framebuffer index when calling get_free_fb. + // But the raw frame buffer is not set up until we finish decoding header. + // So if any error happens during decoding header, frame_bufs[idx] will not + // have a valid raw frame buffer. + if (buf->ref_count == 0 +#ifdef ORI_CODE + && buf->raw_frame_buffer.data +#endif + ) { +#ifdef AML + av1_release_buf(pbi, buf); +#endif + release_fb_cb(pool->cb_priv, &buf->raw_frame_buffer); + buf->raw_frame_buffer.data = NULL; + buf->raw_frame_buffer.size = 0; + buf->raw_frame_buffer.priv = NULL; + } + } +} + +static void swap_frame_buffers(AV1Decoder *pbi, int frame_decoded) { + int ref_index = 0, mask; + AV1_COMMON *const cm = &pbi->common; + BufferPool *const pool = cm->buffer_pool; + unsigned long flags; + + if (frame_decoded) { + int check_on_show_existing_frame; + lock_buffer_pool(pool, flags); + + // In ext-tile decoding, the camera frame header is only decoded once. So, + // we don't release the references here. + if (!pbi->camera_frame_header_ready) { + // If we are not holding reference buffers in cm->next_ref_frame_map, + // assert that the following two for loops are no-ops. + assert(IMPLIES(!pbi->hold_ref_buf, + cm->current_frame.refresh_frame_flags == 0)); + assert(IMPLIES(!pbi->hold_ref_buf, + cm->show_existing_frame && !pbi->reset_decoder_state)); + + // The following two for loops need to release the reference stored in + // cm->ref_frame_map[ref_index] before transferring the reference stored + // in cm->next_ref_frame_map[ref_index] to cm->ref_frame_map[ref_index]. + for (mask = cm->current_frame.refresh_frame_flags; mask; mask >>= 1) { + decrease_ref_count(pbi, cm->ref_frame_map[ref_index], pool); + cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index]; + cm->next_ref_frame_map[ref_index] = NULL; + ++ref_index; + } + + check_on_show_existing_frame = + !cm->show_existing_frame || pbi->reset_decoder_state; + for (; ref_index < REF_FRAMES && check_on_show_existing_frame; + ++ref_index) { + decrease_ref_count(pbi, cm->ref_frame_map[ref_index], pool); + cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index]; + cm->next_ref_frame_map[ref_index] = NULL; + } + } + + if (cm->show_existing_frame || cm->show_frame) { + if (pbi->output_all_layers) { + // Append this frame to the output queue + if (pbi->num_output_frames >= MAX_NUM_SPATIAL_LAYERS) { + // We can't store the new frame anywhere, so drop it and return an + // error + cm->cur_frame->buf.corrupted = 1; + decrease_ref_count(pbi, cm->cur_frame, pool); + cm->error.error_code = AOM_CODEC_UNSUP_BITSTREAM; + } else { + pbi->output_frames[pbi->num_output_frames] = cm->cur_frame; + pbi->num_output_frames++; + } + } else { + // Replace any existing output frame + assert(pbi->num_output_frames == 0 || pbi->num_output_frames == 1); + if (pbi->num_output_frames > 0) { + decrease_ref_count(pbi, pbi->output_frames[0], pool); + } + pbi->output_frames[0] = cm->cur_frame; + pbi->num_output_frames = 1; + } + } else { + decrease_ref_count(pbi, cm->cur_frame, pool); + } + + unlock_buffer_pool(pool, flags); + } else { + // The code here assumes we are not holding reference buffers in + // cm->next_ref_frame_map. If this assertion fails, we are leaking the + // frame buffer references in cm->next_ref_frame_map. + assert(IMPLIES(!pbi->camera_frame_header_ready, !pbi->hold_ref_buf)); + // Nothing was decoded, so just drop this frame buffer + lock_buffer_pool(pool, flags); + decrease_ref_count(pbi, cm->cur_frame, pool); + unlock_buffer_pool(pool, flags); + } + cm->cur_frame = NULL; + + if (!pbi->camera_frame_header_ready) { + pbi->hold_ref_buf = 0; + + // Invalidate these references until the next frame starts. + for (ref_index = 0; ref_index < INTER_REFS_PER_FRAME; ref_index++) { + cm->remapped_ref_idx[ref_index] = INVALID_IDX; + } + } +} + +void aom_internal_error(struct aom_internal_error_info *info, + aom_codec_err_t error, const char *fmt, ...) { + va_list ap; + + info->error_code = error; + info->has_detail = 0; + + if (fmt) { + size_t sz = sizeof(info->detail); + + info->has_detail = 1; + va_start(ap, fmt); + vsnprintf(info->detail, sz - 1, fmt, ap); + va_end(ap); + info->detail[sz - 1] = '\0'; + } +#ifdef ORI_CODE + if (info->setjmp) longjmp(info->jmp, info->error_code); +#endif +} + +#ifdef ORI_CODE +void av1_zero_unused_internal_frame_buffers(InternalFrameBufferList *list) { + int i; + + assert(list != NULL); + + for (i = 0; i < list->num_internal_frame_buffers; ++i) { + if (list->int_fb[i].data && !list->int_fb[i].in_use) + memset(list->int_fb[i].data, 0, list->int_fb[i].size); + } +} +#endif + +// Release the references to the frame buffers in cm->ref_frame_map and reset +// all elements of cm->ref_frame_map to NULL. +static void reset_ref_frame_map(AV1Decoder *const pbi) { + AV1_COMMON *const cm = &pbi->common; + BufferPool *const pool = cm->buffer_pool; + int i; + + for (i = 0; i < REF_FRAMES; i++) { + decrease_ref_count(pbi, cm->ref_frame_map[i], pool); + cm->ref_frame_map[i] = NULL; +#ifdef AML + cm->next_used_ref_frame_map[i] = NULL; +#endif + } +} + +// Generate next_ref_frame_map. +static void generate_next_ref_frame_map(AV1Decoder *const pbi) { + AV1_COMMON *const cm = &pbi->common; + BufferPool *const pool = cm->buffer_pool; + unsigned long flags; + int ref_index = 0; + int mask; + + lock_buffer_pool(pool, flags); + // cm->next_ref_frame_map holds references to frame buffers. After storing a + // frame buffer index in cm->next_ref_frame_map, we need to increase the + // frame buffer's ref_count. + for (mask = cm->current_frame.refresh_frame_flags; mask; mask >>= 1) { + if (mask & 1) { + cm->next_ref_frame_map[ref_index] = cm->cur_frame; + } else { + cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index]; + } + if (cm->next_ref_frame_map[ref_index] != NULL) + ++cm->next_ref_frame_map[ref_index]->ref_count; + ++ref_index; + } + + for (; ref_index < REF_FRAMES; ++ref_index) { + cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index]; + if (cm->next_ref_frame_map[ref_index] != NULL) + ++cm->next_ref_frame_map[ref_index]->ref_count; + } + unlock_buffer_pool(pool, flags); + pbi->hold_ref_buf = 1; +} + +// If the refresh_frame_flags bitmask is set, update reference frame id values +// and mark frames as valid for reference. +static void update_ref_frame_id(AV1_COMMON *const cm, int frame_id) { + int i; + int refresh_frame_flags = cm->current_frame.refresh_frame_flags; + assert(cm->seq_params.frame_id_numbers_present_flag); + for (i = 0; i < REF_FRAMES; i++) { + if ((refresh_frame_flags >> i) & 1) { + cm->ref_frame_id[i] = frame_id; + cm->valid_for_referencing[i] = 1; + } + } +} + +static void show_existing_frame_reset(AV1Decoder *const pbi, + int existing_frame_idx) { + AV1_COMMON *const cm = &pbi->common; + int i; + assert(cm->show_existing_frame); + + cm->current_frame.frame_type = KEY_FRAME; + + cm->current_frame.refresh_frame_flags = (1 << REF_FRAMES) - 1; + + for (i = 0; i < INTER_REFS_PER_FRAME; ++i) { + cm->remapped_ref_idx[i] = INVALID_IDX; + } + + if (pbi->need_resync) { + reset_ref_frame_map(pbi); + pbi->need_resync = 0; + } + + // Note that the displayed frame must be valid for referencing in order to + // have been selected. + if (cm->seq_params.frame_id_numbers_present_flag) { + cm->current_frame_id = cm->ref_frame_id[existing_frame_idx]; + update_ref_frame_id(cm, cm->current_frame_id); + } + + cm->refresh_frame_context = REFRESH_FRAME_CONTEXT_DISABLED; + + generate_next_ref_frame_map(pbi); + +#ifdef ORI_CODE + // Reload the adapted CDFs from when we originally coded this keyframe + *cm->fc = cm->next_ref_frame_map[existing_frame_idx]->frame_context; +#endif +} + +static void reset_frame_buffers(AV1Decoder *const pbi) { + AV1_COMMON *const cm = &pbi->common; + RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; + int i; + unsigned long flags; + + // We have not stored any references to frame buffers in + // cm->next_ref_frame_map, so we can directly reset it to all NULL. + for (i = 0; i < REF_FRAMES; ++i) { + cm->next_ref_frame_map[i] = NULL; + } + + lock_buffer_pool(cm->buffer_pool, flags); + reset_ref_frame_map(pbi); + assert(cm->cur_frame->ref_count == 1); + for (i = 0; i < FRAME_BUFFERS; ++i) { + // Reset all unreferenced frame buffers. We can also reset cm->cur_frame + // because we are the sole owner of cm->cur_frame. + if (frame_bufs[i].ref_count > 0 && &frame_bufs[i] != cm->cur_frame) { + continue; + } + frame_bufs[i].order_hint = 0; + av1_zero(frame_bufs[i].ref_order_hints); + } +#ifdef ORI_CODE + av1_zero_unused_internal_frame_buffers(&cm->buffer_pool->int_frame_buffers); +#endif + unlock_buffer_pool(cm->buffer_pool, flags); +} + +static int frame_is_intra_only(const AV1_COMMON *const cm) { + return cm->current_frame.frame_type == KEY_FRAME || + cm->current_frame.frame_type == INTRA_ONLY_FRAME; +} + +static int frame_is_sframe(const AV1_COMMON *cm) { + return cm->current_frame.frame_type == S_FRAME; +} + +// These functions take a reference frame label between LAST_FRAME and +// EXTREF_FRAME inclusive. Note that this is different to the indexing +// previously used by the frame_refs[] array. +static int get_ref_frame_map_idx(const AV1_COMMON *const cm, + const MV_REFERENCE_FRAME ref_frame) { + return (ref_frame >= LAST_FRAME && ref_frame <= EXTREF_FRAME) + ? cm->remapped_ref_idx[ref_frame - LAST_FRAME] + : INVALID_IDX; +} + +static RefCntBuffer *get_ref_frame_buf( + const AV1_COMMON *const cm, const MV_REFERENCE_FRAME ref_frame) { + const int map_idx = get_ref_frame_map_idx(cm, ref_frame); + return (map_idx != INVALID_IDX) ? cm->ref_frame_map[map_idx] : NULL; +} +#ifdef SUPPORT_SCALE_FACTOR +static struct scale_factors *get_ref_scale_factors( + AV1_COMMON *const cm, const MV_REFERENCE_FRAME ref_frame) { + const int map_idx = get_ref_frame_map_idx(cm, ref_frame); + return (map_idx != INVALID_IDX) ? &cm->ref_scale_factors[map_idx] : NULL; +} +#endif +static RefCntBuffer *get_primary_ref_frame_buf( + const AV1_COMMON *const cm) { + int map_idx; + if (cm->primary_ref_frame == PRIMARY_REF_NONE) return NULL; + map_idx = get_ref_frame_map_idx(cm, cm->primary_ref_frame + 1); + return (map_idx != INVALID_IDX) ? cm->ref_frame_map[map_idx] : NULL; +} + +static int get_relative_dist(const OrderHintInfo *oh, int a, int b) { + int bits; + int m; + int diff; + if (!oh->enable_order_hint) return 0; + + bits = oh->order_hint_bits_minus_1 + 1; + + assert(bits >= 1); + assert(a >= 0 && a < (1 << bits)); + assert(b >= 0 && b < (1 << bits)); + + diff = a - b; + m = 1 << (bits - 1); + diff = (diff & (m - 1)) - (diff & m); + return diff; +} + + +void av1_read_frame_size(union param_u *params, int num_bits_width, + int num_bits_height, int *width, int *height, int* dec_width) { + *width = params->p.frame_width; + *height = params->p.frame_height;//aom_rb_read_literal(rb, num_bits_height) + 1; +#ifdef AML + *dec_width = params->p.dec_frame_width; +#endif +} + +static REFERENCE_MODE read_frame_reference_mode( + const AV1_COMMON *cm, union param_u *params) { + if (frame_is_intra_only(cm)) { + return SINGLE_REFERENCE; + } else { + return params->p.reference_mode ? REFERENCE_MODE_SELECT : SINGLE_REFERENCE; + } +} + +static inline int calc_mi_size(int len) { + // len is in mi units. Align to a multiple of SBs. + return ALIGN_POWER_OF_TWO(len, MAX_MIB_SIZE_LOG2); +} + +void av1_set_mb_mi(AV1_COMMON *cm, int width, int height) { + // Ensure that the decoded width and height are both multiples of + // 8 luma pixels (note: this may only be a multiple of 4 chroma pixels if + // subsampling is used). + // This simplifies the implementation of various experiments, + // eg. cdef, which operates on units of 8x8 luma pixels. + const int aligned_width = ALIGN_POWER_OF_TWO(width, 3); + const int aligned_height = ALIGN_POWER_OF_TWO(height, 3); + av1_print2(AV1_DEBUG_BUFMGR_DETAIL, " [PICTURE] av1_set_mb_mi (%d X %d)\n", width, height); + + cm->mi_cols = aligned_width >> MI_SIZE_LOG2; + cm->mi_rows = aligned_height >> MI_SIZE_LOG2; + cm->mi_stride = calc_mi_size(cm->mi_cols); + + cm->mb_cols = (cm->mi_cols + 2) >> 2; + cm->mb_rows = (cm->mi_rows + 2) >> 2; + cm->MBs = cm->mb_rows * cm->mb_cols; + +#if CONFIG_LPF_MASK + alloc_loop_filter_mask(cm); +#endif +} + +int av1_alloc_context_buffers(AV1_COMMON *cm, int width, int height) { +#ifdef ORI_CODE + int new_mi_size; +#endif + av1_set_mb_mi(cm, width, height); +#ifdef ORI_CODE + new_mi_size = cm->mi_stride * calc_mi_size(cm->mi_rows); + if (cm->mi_alloc_size < new_mi_size) { + cm->free_mi(cm); + if (cm->alloc_mi(cm, new_mi_size)) goto fail; + } +#endif + return 0; + +#ifdef ORI_CODE +fail: +#endif + // clear the mi_* values to force a realloc on resync + av1_set_mb_mi(cm, 0, 0); +#ifdef ORI_CODE + av1_free_context_buffers(cm); +#endif + return 1; +} + +#ifndef USE_SCALED_WIDTH_FROM_UCODE +static void calculate_scaled_size_helper(int *dim, int denom) { + if (denom != SCALE_NUMERATOR) { + // We need to ensure the constraint in "Appendix A" of the spec: + // * FrameWidth is greater than or equal to 16 + // * FrameHeight is greater than or equal to 16 + // For this, we clamp the downscaled dimension to at least 16. One + // exception: if original dimension itself was < 16, then we keep the + // downscaled dimension to be same as the original, to ensure that resizing + // is valid. + const int min_dim = AOMMIN(16, *dim); + // Use this version if we need *dim to be even + // *width = (*width * SCALE_NUMERATOR + denom) / (2 * denom); + // *width <<= 1; + *dim = (*dim * SCALE_NUMERATOR + denom / 2) / (denom); + *dim = AOMMAX(*dim, min_dim); + } +} +#ifdef ORI_CODE +void av1_calculate_scaled_size(int *width, int *height, int resize_denom) { + calculate_scaled_size_helper(width, resize_denom); + calculate_scaled_size_helper(height, resize_denom); +} +#endif +void av1_calculate_scaled_superres_size(int *width, int *height, + int superres_denom) { + (void)height; + calculate_scaled_size_helper(width, superres_denom); +} +#endif + +static void setup_superres(AV1_COMMON *const cm, union param_u *params, + int *width, int *height) { +#ifdef USE_SCALED_WIDTH_FROM_UCODE + cm->superres_upscaled_width = params->p.frame_width_scaled; + cm->superres_upscaled_height = params->p.frame_height; + + + *width = params->p.dec_frame_width; + *height = params->p.frame_height; + av1_print2(AV1_DEBUG_BUFMGR_DETAIL, " [PICTURE] set decoding size to (%d X %d) scaled size to (%d X %d)\n", + *width, *height, + cm->superres_upscaled_width, + cm->superres_upscaled_height); +#else + cm->superres_upscaled_width = *width; + cm->superres_upscaled_height = *height; + + const SequenceHeader *const seq_params = &cm->seq_params; + if (!seq_params->enable_superres) return; + + //if (aom_rb_read_bit(-1, defmark, rb)) { + if (params->p.superres_scale_denominator != SCALE_NUMERATOR) { +#ifdef ORI_CODE + cm->superres_scale_denominator = + (uint8_t)aom_rb_read_literal(-1, defmark, rb, SUPERRES_SCALE_BITS); + cm->superres_scale_denominator += SUPERRES_SCALE_DENOMINATOR_MIN; +#else + cm->superres_scale_denominator = params->p.superres_scale_denominator; +#endif + // Don't edit cm->width or cm->height directly, or the buffers won't get + // resized correctly + av1_calculate_scaled_superres_size(width, height, + cm->superres_scale_denominator); + } else { + // 1:1 scaling - ie. no scaling, scale not provided + cm->superres_scale_denominator = SCALE_NUMERATOR; + } +/*!USE_SCALED_WIDTH_FROM_UCODE*/ +#endif +} + +static void resize_context_buffers(AV1_COMMON *cm, int width, int height) { +#if CONFIG_SIZE_LIMIT + if (width > DECODE_WIDTH_LIMIT || height > DECODE_HEIGHT_LIMIT) + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Dimensions of %dx%d beyond allowed size of %dx%d.", + width, height, DECODE_WIDTH_LIMIT, DECODE_HEIGHT_LIMIT); +#endif + if (cm->width != width || cm->height != height) { + const int new_mi_rows = + ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2) >> MI_SIZE_LOG2; + const int new_mi_cols = + ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2) >> MI_SIZE_LOG2; + + // Allocations in av1_alloc_context_buffers() depend on individual + // dimensions as well as the overall size. + if (new_mi_cols > cm->mi_cols || new_mi_rows > cm->mi_rows) { + if (av1_alloc_context_buffers(cm, width, height)) { + // The cm->mi_* values have been cleared and any existing context + // buffers have been freed. Clear cm->width and cm->height to be + // consistent and to force a realloc next time. + cm->width = 0; + cm->height = 0; + aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR, + "Failed to allocate context buffers"); + } + } else { + av1_set_mb_mi(cm, width, height); + } +#ifdef ORI_CODE + av1_init_context_buffers(cm); +#endif + cm->width = width; + cm->height = height; + } + +#ifdef ORI_CODE + ensure_mv_buffer(cm->cur_frame, cm); +#endif + cm->cur_frame->width = cm->width; + cm->cur_frame->height = cm->height; +} + +static void setup_buffer_pool(AV1_COMMON *cm) { + BufferPool *const pool = cm->buffer_pool; + const SequenceHeader *const seq_params = &cm->seq_params; + unsigned long flags; + + lock_buffer_pool(pool, flags); + if (aom_realloc_frame_buffer(cm, &cm->cur_frame->buf, + cm->width, cm->height, cm->cur_frame->order_hint)) { + unlock_buffer_pool(pool, flags); + aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR, + "Failed to allocate frame buffer"); + } + unlock_buffer_pool(pool, flags); + + cm->cur_frame->buf.bit_depth = (unsigned int)seq_params->bit_depth; + cm->cur_frame->buf.color_primaries = seq_params->color_primaries; + cm->cur_frame->buf.transfer_characteristics = + seq_params->transfer_characteristics; + cm->cur_frame->buf.matrix_coefficients = seq_params->matrix_coefficients; + cm->cur_frame->buf.monochrome = seq_params->monochrome; + cm->cur_frame->buf.chroma_sample_position = + seq_params->chroma_sample_position; + cm->cur_frame->buf.color_range = seq_params->color_range; + cm->cur_frame->buf.render_width = cm->render_width; + cm->cur_frame->buf.render_height = cm->render_height; +} + +static void setup_frame_size(AV1_COMMON *cm, int frame_size_override_flag, union param_u *params) { + const SequenceHeader *const seq_params = &cm->seq_params; + int width, height, dec_width; + + if (frame_size_override_flag) { + int num_bits_width = seq_params->num_bits_width; + int num_bits_height = seq_params->num_bits_height; + av1_read_frame_size(params, num_bits_width, num_bits_height, &width, &height, &dec_width); +#ifdef AML + cm->dec_width = dec_width; +#endif + if (width > seq_params->max_frame_width || + height > seq_params->max_frame_height) { + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Frame dimensions are larger than the maximum values"); + } + } else { + width = seq_params->max_frame_width; + height = seq_params->max_frame_height; +#ifdef AML + cm->dec_width = dec_width = params->p.dec_frame_width; +#endif + } + setup_superres(cm, params, &width, &height); + resize_context_buffers(cm, width, height); +#ifdef ORI_CODE + setup_render_size(cm, params); +#endif + setup_buffer_pool(cm); +} + +static int valid_ref_frame_img_fmt(aom_bit_depth_t ref_bit_depth, + int ref_xss, int ref_yss, + aom_bit_depth_t this_bit_depth, + int this_xss, int this_yss) { + return ref_bit_depth == this_bit_depth && ref_xss == this_xss && + ref_yss == this_yss; +} + +static void setup_frame_size_with_refs(AV1_COMMON *cm, union param_u *params) { + int width, height, dec_width; + int found = 0; + int has_valid_ref_frame = 0; + int i; + SequenceHeader *seq_params; + for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) { + /*if (aom_rb_read_bit(rb)) {*/ + if (params->p.valid_ref_frame_bits & (1<error, AOM_CODEC_CORRUPT_FRAME, + "Invalid condition: invalid reference buffer"); + } else { + const PIC_BUFFER_CONFIG *const buf = &ref_buf->buf; + width = buf->y_crop_width; + height = buf->y_crop_height; + cm->render_width = buf->render_width; + cm->render_height = buf->render_height; + setup_superres(cm, params, &width, &height); + resize_context_buffers(cm, width, height); + found = 1; + break; + } + } + } + + seq_params = &cm->seq_params; + if (!found) { + int num_bits_width = seq_params->num_bits_width; + int num_bits_height = seq_params->num_bits_height; + + av1_read_frame_size(params, num_bits_width, num_bits_height, &width, &height, &dec_width); +#ifdef AML + cm->dec_width = dec_width; +#endif + setup_superres(cm, params, &width, &height); + resize_context_buffers(cm, width, height); +#ifdef ORI_CODE + setup_render_size(cm, rb); +#endif + } + + if (width <= 0 || height <= 0) + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Invalid frame size"); + + // Check to make sure at least one of frames that this frame references + // has valid dimensions. + for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) { + const RefCntBuffer *const ref_frame = get_ref_frame_buf(cm, i); + if (ref_frame != NULL) { + has_valid_ref_frame |= + valid_ref_frame_size(ref_frame->buf.y_crop_width, + ref_frame->buf.y_crop_height, width, height); + } + } + if (!has_valid_ref_frame) + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Referenced frame has invalid size"); + for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) { + const RefCntBuffer *const ref_frame = get_ref_frame_buf(cm, i); + if (ref_frame != NULL) { + if (!valid_ref_frame_img_fmt( + ref_frame->buf.bit_depth, ref_frame->buf.subsampling_x, + ref_frame->buf.subsampling_y, seq_params->bit_depth, + seq_params->subsampling_x, seq_params->subsampling_y)) + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Referenced frame has incompatible color format"); + } + } + setup_buffer_pool(cm); +} + +typedef struct { + int map_idx; // frame map index + RefCntBuffer *buf; // frame buffer + int sort_idx; // index based on the offset to be used for sorting +} REF_FRAME_INFO; + +// Compares the sort_idx fields. If they are equal, then compares the map_idx +// fields to break the tie. This ensures a stable sort. +static int compare_ref_frame_info(const void *arg_a, const void *arg_b) { + const REF_FRAME_INFO *info_a = (REF_FRAME_INFO *)arg_a; + const REF_FRAME_INFO *info_b = (REF_FRAME_INFO *)arg_b; + + const int sort_idx_diff = info_a->sort_idx - info_b->sort_idx; + if (sort_idx_diff != 0) return sort_idx_diff; + return info_a->map_idx - info_b->map_idx; +} + + +/* +for av1_setup_motion_field() +*/ +static int motion_field_projection(AV1_COMMON *cm, + MV_REFERENCE_FRAME start_frame, int dir) { +#ifdef ORI_CODE + TPL_MV_REF *tpl_mvs_base = cm->tpl_mvs; + int ref_offset[REF_FRAMES] = { 0 }; +#endif + MV_REFERENCE_FRAME rf; + const RefCntBuffer *const start_frame_buf = + get_ref_frame_buf(cm, start_frame); + int start_frame_order_hint; + unsigned int const *ref_order_hints; + int cur_order_hint; + int start_to_current_frame_offset; + +#ifdef AML + int i; + //av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "$$$$$$$$$$$%s:cm->mv_ref_id_index = %d, start_frame=%d\n", __func__, cm->mv_ref_id_index, start_frame); + cm->mv_ref_id[cm->mv_ref_id_index] = start_frame; + for (i = 0; i < REF_FRAMES; i++) { + cm->mv_ref_offset[cm->mv_ref_id_index][i]=0; + } + cm->mv_cal_tpl_mvs[cm->mv_ref_id_index]=0; + cm->mv_ref_id_index++; +#endif + if (start_frame_buf == NULL) return 0; + + if (start_frame_buf->frame_type == KEY_FRAME || + start_frame_buf->frame_type == INTRA_ONLY_FRAME) + return 0; + + if (start_frame_buf->mi_rows != cm->mi_rows || + start_frame_buf->mi_cols != cm->mi_cols) + return 0; + + start_frame_order_hint = start_frame_buf->order_hint; + ref_order_hints = + &start_frame_buf->ref_order_hints[0]; + cur_order_hint = cm->cur_frame->order_hint; + start_to_current_frame_offset = get_relative_dist( + &cm->seq_params.order_hint_info, start_frame_order_hint, cur_order_hint); + + for (rf = LAST_FRAME; rf <= INTER_REFS_PER_FRAME; ++rf) { + cm->mv_ref_offset[cm->mv_ref_id_index-1][rf] = get_relative_dist(&cm->seq_params.order_hint_info, + start_frame_order_hint, + ref_order_hints[rf - LAST_FRAME]); + } +#ifdef AML + cm->mv_cal_tpl_mvs[cm->mv_ref_id_index-1]=1; +#endif + if (dir == 2) start_to_current_frame_offset = -start_to_current_frame_offset; +#ifdef ORI_CODE + MV_REF *mv_ref_base = start_frame_buf->mvs; + const int mvs_rows = (cm->mi_rows + 1) >> 1; + const int mvs_cols = (cm->mi_cols + 1) >> 1; + + for (int blk_row = 0; blk_row < mvs_rows; ++blk_row) { + for (int blk_col = 0; blk_col < mvs_cols; ++blk_col) { + MV_REF *mv_ref = &mv_ref_base[blk_row * mvs_cols + blk_col]; + MV fwd_mv = mv_ref->mv.as_mv; + + if (mv_ref->ref_frame > INTRA_FRAME) { + int_mv this_mv; + int mi_r, mi_c; + const int ref_frame_offset = ref_offset[mv_ref->ref_frame]; + + int pos_valid = + abs(ref_frame_offset) <= MAX_FRAME_DISTANCE && + ref_frame_offset > 0 && + abs(start_to_current_frame_offset) <= MAX_FRAME_DISTANCE; + + if (pos_valid) { + get_mv_projection(&this_mv.as_mv, fwd_mv, + start_to_current_frame_offset, ref_frame_offset); + pos_valid = get_block_position(cm, &mi_r, &mi_c, blk_row, blk_col, + this_mv.as_mv, dir >> 1); + } + + if (pos_valid) { + const int mi_offset = mi_r * (cm->mi_stride >> 1) + mi_c; + + tpl_mvs_base[mi_offset].mfmv0.as_mv.row = fwd_mv.row; + tpl_mvs_base[mi_offset].mfmv0.as_mv.col = fwd_mv.col; + tpl_mvs_base[mi_offset].ref_frame_offset = ref_frame_offset; + } + } + } + } +#endif + return 1; +} + +#ifdef AML +static int setup_motion_field_debug_count = 0; +#endif +void av1_setup_motion_field(AV1_COMMON *cm) { + const OrderHintInfo *const order_hint_info = &cm->seq_params.order_hint_info; + int ref_frame; + int size; + int cur_order_hint; + const RefCntBuffer *ref_buf[INTER_REFS_PER_FRAME]; + int ref_order_hint[INTER_REFS_PER_FRAME]; + int ref_stamp; + memset(cm->ref_frame_side, 0, sizeof(cm->ref_frame_side)); + if (!order_hint_info->enable_order_hint) return; +#ifdef ORI_CODE + TPL_MV_REF *tpl_mvs_base = cm->tpl_mvs; +#endif + size = ((cm->mi_rows + MAX_MIB_SIZE) >> 1) * (cm->mi_stride >> 1); +#ifdef ORI_CODE + for (int idx = 0; idx < size; ++idx) { + tpl_mvs_base[idx].mfmv0.as_int = INVALID_MV; + tpl_mvs_base[idx].ref_frame_offset = 0; + } +#endif + cur_order_hint = cm->cur_frame->order_hint; + + for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) { + const int ref_idx = ref_frame - LAST_FRAME; + const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame); + int order_hint = 0; + + if (buf != NULL) order_hint = buf->order_hint; + + ref_buf[ref_idx] = buf; + ref_order_hint[ref_idx] = order_hint; + + if (get_relative_dist(order_hint_info, order_hint, cur_order_hint) > 0) + cm->ref_frame_side[ref_frame] = 1; + else if (order_hint == cur_order_hint) + cm->ref_frame_side[ref_frame] = -1; + } + ref_stamp = MFMV_STACK_SIZE - 1; +#ifdef AML + cm->mv_ref_id_index = 0; + av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "%s(%d) mi_cols %d mi_rows %d\n", + __func__, setup_motion_field_debug_count++, + cm->mi_cols, + cm->mi_rows + ); +#endif + if (ref_buf[LAST_FRAME - LAST_FRAME] != NULL) { + const int alt_of_lst_order_hint = + ref_buf[LAST_FRAME - LAST_FRAME] + ->ref_order_hints[ALTREF_FRAME - LAST_FRAME]; + + const int is_lst_overlay = + (alt_of_lst_order_hint == ref_order_hint[GOLDEN_FRAME - LAST_FRAME]); + if (!is_lst_overlay) motion_field_projection(cm, LAST_FRAME, 2); + --ref_stamp; + } + + if (get_relative_dist(order_hint_info, + ref_order_hint[BWDREF_FRAME - LAST_FRAME], + cur_order_hint) > 0) { + if (motion_field_projection(cm, BWDREF_FRAME, 0)) --ref_stamp; + } + + if (get_relative_dist(order_hint_info, + ref_order_hint[ALTREF2_FRAME - LAST_FRAME], + cur_order_hint) > 0) { + if (motion_field_projection(cm, ALTREF2_FRAME, 0)) --ref_stamp; + } + + if (get_relative_dist(order_hint_info, + ref_order_hint[ALTREF_FRAME - LAST_FRAME], + cur_order_hint) > 0 && + ref_stamp >= 0) + if (motion_field_projection(cm, ALTREF_FRAME, 0)) --ref_stamp; + + if (ref_stamp >= 0) motion_field_projection(cm, LAST2_FRAME, 2); +} + + +static void set_ref_frame_info(int *remapped_ref_idx, int frame_idx, + REF_FRAME_INFO *ref_info) { + assert(frame_idx >= 0 && frame_idx < INTER_REFS_PER_FRAME); + + remapped_ref_idx[frame_idx] = ref_info->map_idx; + av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "+++++++++++++%s:remapped_ref_idx[%d]=0x%x\n", __func__, frame_idx, ref_info->map_idx); +} + + +void av1_set_frame_refs(AV1_COMMON *const cm, int *remapped_ref_idx, + int lst_map_idx, int gld_map_idx) { + int lst_frame_sort_idx = -1; + int gld_frame_sort_idx = -1; + int i; + //assert(cm->seq_params.order_hint_info.enable_order_hint); + //assert(cm->seq_params.order_hint_info.order_hint_bits_minus_1 >= 0); + const int cur_order_hint = (int)cm->current_frame.order_hint; + const int cur_frame_sort_idx = + 1 << cm->seq_params.order_hint_info.order_hint_bits_minus_1; + + REF_FRAME_INFO ref_frame_info[REF_FRAMES]; + int ref_flag_list[INTER_REFS_PER_FRAME] = { 0, 0, 0, 0, 0, 0, 0 }; + int bwd_start_idx; + int bwd_end_idx; + int fwd_start_idx, fwd_end_idx; + int ref_idx; + static const MV_REFERENCE_FRAME ref_frame_list[INTER_REFS_PER_FRAME - 2] = { + LAST2_FRAME, LAST3_FRAME, BWDREF_FRAME, ALTREF2_FRAME, ALTREF_FRAME + }; + + for (i = 0; i < REF_FRAMES; ++i) { + const int map_idx = i; + RefCntBuffer *buf; + int offset; + + ref_frame_info[i].map_idx = map_idx; + ref_frame_info[i].sort_idx = -1; + + buf = cm->ref_frame_map[map_idx]; + ref_frame_info[i].buf = buf; + + if (buf == NULL) continue; + // If this assertion fails, there is a reference leak. + assert(buf->ref_count > 0); + + offset = (int)buf->order_hint; + ref_frame_info[i].sort_idx = + (offset == -1) ? -1 + : cur_frame_sort_idx + + get_relative_dist(&cm->seq_params.order_hint_info, + offset, cur_order_hint); + assert(ref_frame_info[i].sort_idx >= -1); + + if (map_idx == lst_map_idx) lst_frame_sort_idx = ref_frame_info[i].sort_idx; + if (map_idx == gld_map_idx) gld_frame_sort_idx = ref_frame_info[i].sort_idx; + } + + // Confirm both LAST_FRAME and GOLDEN_FRAME are valid forward reference + // frames. + if (lst_frame_sort_idx == -1 || lst_frame_sort_idx >= cur_frame_sort_idx) { + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Inter frame requests a look-ahead frame as LAST"); + } + if (gld_frame_sort_idx == -1 || gld_frame_sort_idx >= cur_frame_sort_idx) { + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Inter frame requests a look-ahead frame as GOLDEN"); + } + + // Sort ref frames based on their frame_offset values. + qsort(ref_frame_info, REF_FRAMES, sizeof(REF_FRAME_INFO), + compare_ref_frame_info); + + // Identify forward and backward reference frames. + // Forward reference: offset < order_hint + // Backward reference: offset >= order_hint + fwd_start_idx = 0; + fwd_end_idx = REF_FRAMES - 1; + + for (i = 0; i < REF_FRAMES; i++) { + if (ref_frame_info[i].sort_idx == -1) { + fwd_start_idx++; + continue; + } + + if (ref_frame_info[i].sort_idx >= cur_frame_sort_idx) { + fwd_end_idx = i - 1; + break; + } + } + + bwd_start_idx = fwd_end_idx + 1; + bwd_end_idx = REF_FRAMES - 1; + + // === Backward Reference Frames === + + // == ALTREF_FRAME == + if (bwd_start_idx <= bwd_end_idx) { + set_ref_frame_info(remapped_ref_idx, ALTREF_FRAME - LAST_FRAME, + &ref_frame_info[bwd_end_idx]); + ref_flag_list[ALTREF_FRAME - LAST_FRAME] = 1; + bwd_end_idx--; + } + + // == BWDREF_FRAME == + if (bwd_start_idx <= bwd_end_idx) { + set_ref_frame_info(remapped_ref_idx, BWDREF_FRAME - LAST_FRAME, + &ref_frame_info[bwd_start_idx]); + ref_flag_list[BWDREF_FRAME - LAST_FRAME] = 1; + bwd_start_idx++; + } + + // == ALTREF2_FRAME == + if (bwd_start_idx <= bwd_end_idx) { + set_ref_frame_info(remapped_ref_idx, ALTREF2_FRAME - LAST_FRAME, + &ref_frame_info[bwd_start_idx]); + ref_flag_list[ALTREF2_FRAME - LAST_FRAME] = 1; + } + + // === Forward Reference Frames === + + for (i = fwd_start_idx; i <= fwd_end_idx; ++i) { + // == LAST_FRAME == + if (ref_frame_info[i].map_idx == lst_map_idx) { + set_ref_frame_info(remapped_ref_idx, LAST_FRAME - LAST_FRAME, + &ref_frame_info[i]); + ref_flag_list[LAST_FRAME - LAST_FRAME] = 1; + } + + // == GOLDEN_FRAME == + if (ref_frame_info[i].map_idx == gld_map_idx) { + set_ref_frame_info(remapped_ref_idx, GOLDEN_FRAME - LAST_FRAME, + &ref_frame_info[i]); + ref_flag_list[GOLDEN_FRAME - LAST_FRAME] = 1; + } + } + + assert(ref_flag_list[LAST_FRAME - LAST_FRAME] == 1 && + ref_flag_list[GOLDEN_FRAME - LAST_FRAME] == 1); + + // == LAST2_FRAME == + // == LAST3_FRAME == + // == BWDREF_FRAME == + // == ALTREF2_FRAME == + // == ALTREF_FRAME == + + // Set up the reference frames in the anti-chronological order. + for (ref_idx = 0; ref_idx < (INTER_REFS_PER_FRAME - 2); ref_idx++) { + const MV_REFERENCE_FRAME ref_frame = ref_frame_list[ref_idx]; + + if (ref_flag_list[ref_frame - LAST_FRAME] == 1) continue; + + while (fwd_start_idx <= fwd_end_idx && + (ref_frame_info[fwd_end_idx].map_idx == lst_map_idx || + ref_frame_info[fwd_end_idx].map_idx == gld_map_idx)) { + fwd_end_idx--; + } + if (fwd_start_idx > fwd_end_idx) break; + + set_ref_frame_info(remapped_ref_idx, ref_frame - LAST_FRAME, + &ref_frame_info[fwd_end_idx]); + ref_flag_list[ref_frame - LAST_FRAME] = 1; + + fwd_end_idx--; + } + + // Assign all the remaining frame(s), if any, to the earliest reference frame. + for (; ref_idx < (INTER_REFS_PER_FRAME - 2); ref_idx++) { + const MV_REFERENCE_FRAME ref_frame = ref_frame_list[ref_idx]; + if (ref_flag_list[ref_frame - LAST_FRAME] == 1) continue; + set_ref_frame_info(remapped_ref_idx, ref_frame - LAST_FRAME, + &ref_frame_info[fwd_start_idx]); + ref_flag_list[ref_frame - LAST_FRAME] = 1; + } + + for (i = 0; i < INTER_REFS_PER_FRAME; i++) { + assert(ref_flag_list[i] == 1); + } +} + +void av1_setup_frame_buf_refs(AV1_COMMON *cm) { + MV_REFERENCE_FRAME ref_frame; + cm->cur_frame->order_hint = cm->current_frame.order_hint; + + for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { + const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame); + if (buf != NULL) + cm->cur_frame->ref_order_hints[ref_frame - LAST_FRAME] = buf->order_hint; + } +} + +void av1_setup_frame_sign_bias(AV1_COMMON *cm) { + MV_REFERENCE_FRAME ref_frame; + for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { + const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame); + if (cm->seq_params.order_hint_info.enable_order_hint && buf != NULL) { + const int ref_order_hint = buf->order_hint; + cm->ref_frame_sign_bias[ref_frame] = + (get_relative_dist(&cm->seq_params.order_hint_info, ref_order_hint, + (int)cm->current_frame.order_hint) <= 0) + ? 0 + : 1; + } else { + cm->ref_frame_sign_bias[ref_frame] = 0; + } + } +} + + +void av1_setup_skip_mode_allowed(AV1_COMMON *cm) +{ + const OrderHintInfo *const order_hint_info = &cm->seq_params.order_hint_info; + SkipModeInfo *const skip_mode_info = &cm->current_frame.skip_mode_info; + int i; + int cur_order_hint; + int ref_order_hints[2] = { -1, INT_MAX }; + int ref_idx[2] = { INVALID_IDX, INVALID_IDX }; + + skip_mode_info->skip_mode_allowed = 0; + skip_mode_info->ref_frame_idx_0 = INVALID_IDX; + skip_mode_info->ref_frame_idx_1 = INVALID_IDX; + av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "av1_setup_skip_mode_allowed %d %d %d\n", order_hint_info->enable_order_hint, + frame_is_intra_only(cm), + cm->current_frame.reference_mode); + if (!order_hint_info->enable_order_hint || frame_is_intra_only(cm) || + cm->current_frame.reference_mode == SINGLE_REFERENCE) + return; + + cur_order_hint = cm->current_frame.order_hint; + + // Identify the nearest forward and backward references. + for (i = 0; i < INTER_REFS_PER_FRAME; ++i) { + const RefCntBuffer *const buf = get_ref_frame_buf(cm, LAST_FRAME + i); + int ref_order_hint; + if (buf == NULL) continue; + + ref_order_hint = buf->order_hint; + if (get_relative_dist(order_hint_info, ref_order_hint, cur_order_hint) < 0) { + // Forward reference + if (ref_order_hints[0] == -1 || + get_relative_dist(order_hint_info, ref_order_hint, + ref_order_hints[0]) > 0) { + ref_order_hints[0] = ref_order_hint; + ref_idx[0] = i; + } + } else if (get_relative_dist(order_hint_info, ref_order_hint, + cur_order_hint) > 0) { + // Backward reference + if (ref_order_hints[1] == INT_MAX || + get_relative_dist(order_hint_info, ref_order_hint, + ref_order_hints[1]) < 0) { + ref_order_hints[1] = ref_order_hint; + ref_idx[1] = i; + } + } + } + + if (ref_idx[0] != INVALID_IDX && ref_idx[1] != INVALID_IDX) { + // == Bi-directional prediction == + skip_mode_info->skip_mode_allowed = 1; + skip_mode_info->ref_frame_idx_0 = AOMMIN(ref_idx[0], ref_idx[1]); + skip_mode_info->ref_frame_idx_1 = AOMMAX(ref_idx[0], ref_idx[1]); + } else if (ref_idx[0] != INVALID_IDX && ref_idx[1] == INVALID_IDX) { + // == Forward prediction only == + // Identify the second nearest forward reference. + ref_order_hints[1] = -1; + for (i = 0; i < INTER_REFS_PER_FRAME; ++i) { + const RefCntBuffer *const buf = get_ref_frame_buf(cm, LAST_FRAME + i); + int ref_order_hint; + if (buf == NULL) continue; + + ref_order_hint = buf->order_hint; + if ((ref_order_hints[0] != -1 && + get_relative_dist(order_hint_info, ref_order_hint, ref_order_hints[0]) < 0) && + (ref_order_hints[1] == -1 || + get_relative_dist(order_hint_info, ref_order_hint, ref_order_hints[1]) > 0)) { + // Second closest forward reference + ref_order_hints[1] = ref_order_hint; + ref_idx[1] = i; + } + } + if (ref_order_hints[1] != -1) { + skip_mode_info->skip_mode_allowed = 1; + skip_mode_info->ref_frame_idx_0 = AOMMIN(ref_idx[0], ref_idx[1]); + skip_mode_info->ref_frame_idx_1 = AOMMAX(ref_idx[0], ref_idx[1]); + } + } + av1_print2(AV1_DEBUG_BUFMGR_DETAIL, + "skip_mode_info: skip_mode_allowed 0x%x 0x%x 0x%x\n", + cm->current_frame.skip_mode_info.skip_mode_allowed, + cm->current_frame.skip_mode_info.ref_frame_idx_0, + cm->current_frame.skip_mode_info.ref_frame_idx_1); +} + +static inline int frame_might_allow_ref_frame_mvs(const AV1_COMMON *cm) { + return !cm->error_resilient_mode && + cm->seq_params.order_hint_info.enable_ref_frame_mvs && + cm->seq_params.order_hint_info.enable_order_hint && + !frame_is_intra_only(cm); +} + +#ifdef ORI_CODE +/* +* segmentation +*/ +static const int seg_feature_data_signed[SEG_LVL_MAX] = { + 1, 1, 1, 1, 1, 0, 0, 0 +}; + +static const int seg_feature_data_max[SEG_LVL_MAX] = { MAXQ, + MAX_LOOP_FILTER, + MAX_LOOP_FILTER, + MAX_LOOP_FILTER, + MAX_LOOP_FILTER, + 7, + 0, + 0 }; + + +static inline void segfeatures_copy(struct segmentation *dst, + const struct segmentation *src) { + int i, j; + for (i = 0; i < MAX_SEGMENTS; i++) { + dst->feature_mask[i] = src->feature_mask[i]; + for (j = 0; j < SEG_LVL_MAX; j++) { + dst->feature_data[i][j] = src->feature_data[i][j]; + } + } + dst->segid_preskip = src->segid_preskip; + dst->last_active_segid = src->last_active_segid; +} + +static void av1_clearall_segfeatures(struct segmentation *seg) { + av1_zero(seg->feature_data); + av1_zero(seg->feature_mask); +} + +static void av1_enable_segfeature(struct segmentation *seg, int segment_id, + int feature_id) { + seg->feature_mask[segment_id] |= 1 << feature_id; +} + +void av1_calculate_segdata(struct segmentation *seg) { + seg->segid_preskip = 0; + seg->last_active_segid = 0; + for (int i = 0; i < MAX_SEGMENTS; i++) { + for (int j = 0; j < SEG_LVL_MAX; j++) { + if (seg->feature_mask[i] & (1 << j)) { + seg->segid_preskip |= (j >= SEG_LVL_REF_FRAME); + seg->last_active_segid = i; + } + } + } +} + +static int av1_seg_feature_data_max(int feature_id) { + return seg_feature_data_max[feature_id]; +} + +static int av1_is_segfeature_signed(int feature_id) { + return seg_feature_data_signed[feature_id]; +} + +static void av1_set_segdata(struct segmentation *seg, int segment_id, + int feature_id, int seg_data) { + if (seg_data < 0) { + assert(seg_feature_data_signed[feature_id]); + assert(-seg_data <= seg_feature_data_max[feature_id]); + } else { + assert(seg_data <= seg_feature_data_max[feature_id]); + } + + seg->feature_data[segment_id][feature_id] = seg_data; +} + +static inline int clamp(int value, int low, int high) { + return value < low ? low : (value > high ? high : value); +} + +static void setup_segmentation(AV1_COMMON *const cm, + union param_u *params) { + struct segmentation *const seg = &cm->seg; + + seg->update_map = 0; + seg->update_data = 0; + seg->temporal_update = 0; + + seg->enabled = params->p.seg_enabled; //aom_rb_read_bit(-1, defmark, rb); + if (!seg->enabled) { + if (cm->cur_frame->seg_map) + memset(cm->cur_frame->seg_map, 0, (cm->mi_rows * cm->mi_cols)); + + memset(seg, 0, sizeof(*seg)); + segfeatures_copy(&cm->cur_frame->seg, seg); + return; + } + if (cm->seg.enabled && cm->prev_frame && + (cm->mi_rows == cm->prev_frame->mi_rows) && + (cm->mi_cols == cm->prev_frame->mi_cols)) { + cm->last_frame_seg_map = cm->prev_frame->seg_map; + } else { + cm->last_frame_seg_map = NULL; + } + // Read update flags + if (cm->primary_ref_frame == PRIMARY_REF_NONE) { + // These frames can't use previous frames, so must signal map + features + seg->update_map = 1; + seg->temporal_update = 0; + seg->update_data = 1; + } else { + seg->update_map = params->p.seg_update_map; // aom_rb_read_bit(-1, defmark, rb); + if (seg->update_map) { + seg->temporal_update = params->p.seg_temporal_update; //aom_rb_read_bit(-1, defmark, rb); + } else { + seg->temporal_update = 0; + } + seg->update_data = params->p.seg_update_data; //aom_rb_read_bit(-1, defmark, rb); + } + + // Segmentation data update + if (seg->update_data) { + av1_clearall_segfeatures(seg); + + for (int i = 0; i < MAX_SEGMENTS; i++) { + for (int j = 0; j < SEG_LVL_MAX; j++) { + int data = 0; + const int feature_enabled = params->p.seg_feature_enabled ;//aom_rb_read_bit(-1, defmark, rb); + if (feature_enabled) { + av1_enable_segfeature(seg, i, j); + + const int data_max = av1_seg_feature_data_max(j); + const int data_min = -data_max; + /* + const int ubits = get_unsigned_bits(data_max); + + if (av1_is_segfeature_signed(j)) { + data = aom_rb_read_inv_signed_literal(-1, defmark, rb, ubits); + } else { + data = aom_rb_read_literal(-1, defmark, rb, ubits); + }*/ + data = params->p.seg_data; + data = clamp(data, data_min, data_max); + } + av1_set_segdata(seg, i, j, data); + } + } + av1_calculate_segdata(seg); + } else if (cm->prev_frame) { + segfeatures_copy(seg, &cm->prev_frame->seg); + } + segfeatures_copy(&cm->cur_frame->seg, seg); +} +#endif + +/**/ + + +int av1_decode_frame_headers_and_setup(AV1Decoder *pbi, int trailing_bits_present, union param_u *params) +{ + AV1_COMMON *const cm = &pbi->common; + /* + read_uncompressed_header() + */ + const SequenceHeader *const seq_params = &cm->seq_params; + CurrentFrame *const current_frame = &cm->current_frame; + //MACROBLOCKD *const xd = &pbi->mb; + BufferPool *const pool = cm->buffer_pool; + RefCntBuffer *const frame_bufs = pool->frame_bufs; + int i; + int frame_size_override_flag; + unsigned long flags; + + if (!pbi->sequence_header_ready) { + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "No sequence header"); + } + cm->last_frame_type = current_frame->frame_type; + + if (seq_params->reduced_still_picture_hdr) { + cm->show_existing_frame = 0; + cm->show_frame = 1; + current_frame->frame_type = KEY_FRAME; + if (pbi->sequence_header_changed) { + // This is the start of a new coded video sequence. + pbi->sequence_header_changed = 0; + pbi->decoding_first_frame = 1; + reset_frame_buffers(pbi); + } + cm->error_resilient_mode = 1; + } else { + cm->show_existing_frame = params->p.show_existing_frame; + pbi->reset_decoder_state = 0; + if (cm->show_existing_frame) { + int existing_frame_idx; + RefCntBuffer *frame_to_show; + if (pbi->sequence_header_changed) { + aom_internal_error( + &cm->error, AOM_CODEC_CORRUPT_FRAME, + "New sequence header starts with a show_existing_frame."); + } + // Show an existing frame directly. + existing_frame_idx = params->p.existing_frame_idx; //aom_rb_read_literal(rb, 3); + frame_to_show = cm->ref_frame_map[existing_frame_idx]; + if (frame_to_show == NULL) { + aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM, + "Buffer does not contain a decoded frame"); + } + if (seq_params->decoder_model_info_present_flag && + cm->timing_info.equal_picture_interval == 0) { + cm->frame_presentation_time = params->p.frame_presentation_time; + //read_temporal_point_info(cm); + } + if (seq_params->frame_id_numbers_present_flag) { + //int frame_id_length = seq_params->frame_id_length; + int display_frame_id = params->p.display_frame_id; //aom_rb_read_literal(rb, frame_id_length); + /* Compare display_frame_id with ref_frame_id and check valid for + * referencing */ + if (display_frame_id != cm->ref_frame_id[existing_frame_idx] || + cm->valid_for_referencing[existing_frame_idx] == 0) + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Reference buffer frame ID mismatch"); + } + lock_buffer_pool(pool, flags); + assert(frame_to_show->ref_count > 0); + // cm->cur_frame should be the buffer referenced by the return value + // of the get_free_fb() call in av1_receive_compressed_data(), and + // generate_next_ref_frame_map() has not been called, so ref_count + // should still be 1. + assert(cm->cur_frame->ref_count == 1); + // assign_frame_buffer_p() decrements ref_count directly rather than + // call decrease_ref_count(). If cm->cur_frame->raw_frame_buffer has + // already been allocated, it will not be released by + // assign_frame_buffer_p()! + assert(!cm->cur_frame->raw_frame_buffer.data); + assign_frame_buffer_p(&cm->cur_frame, frame_to_show); + pbi->reset_decoder_state = frame_to_show->frame_type == KEY_FRAME; + unlock_buffer_pool(pool, flags); + +#ifdef ORI_CODE + cm->lf.filter_level[0] = 0; + cm->lf.filter_level[1] = 0; +#endif + cm->show_frame = 1; + + // Section 6.8.2: It is a requirement of bitstream conformance that when + // show_existing_frame is used to show a previous frame, that the value + // of showable_frame for the previous frame was equal to 1. + if (!frame_to_show->showable_frame) { + aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM, + "Buffer does not contain a showable frame"); + } + // Section 6.8.2: It is a requirement of bitstream conformance that when + // show_existing_frame is used to show a previous frame with + // RefFrameType[ frame_to_show_map_idx ] equal to KEY_FRAME, that the + // frame is output via the show_existing_frame mechanism at most once. + if (pbi->reset_decoder_state) frame_to_show->showable_frame = 0; + +#ifdef ORI_CODE + cm->film_grain_params = frame_to_show->film_grain_params; +#endif + if (pbi->reset_decoder_state) { + show_existing_frame_reset(pbi, existing_frame_idx); + } else { + current_frame->refresh_frame_flags = 0; + } + + return 0; + } + + current_frame->frame_type = (FRAME_TYPE)params->p.frame_type; //aom_rb_read_literal(rb, 2); + if (pbi->sequence_header_changed) { + if (current_frame->frame_type == KEY_FRAME) { + // This is the start of a new coded video sequence. + pbi->sequence_header_changed = 0; + pbi->decoding_first_frame = 1; + reset_frame_buffers(pbi); + } else { + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Sequence header has changed without a keyframe."); + } + } + cm->show_frame = params->p.show_frame; //aom_rb_read_bit(rb); + if (seq_params->still_picture && + (current_frame->frame_type != KEY_FRAME || !cm->show_frame)) { + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Still pictures must be coded as shown keyframes"); + } + cm->showable_frame = current_frame->frame_type != KEY_FRAME; + if (cm->show_frame) { + if (seq_params->decoder_model_info_present_flag && + cm->timing_info.equal_picture_interval == 0) + cm->frame_presentation_time = params->p.frame_presentation_time; + //read_temporal_point_info(cm); + } else { + // See if this frame can be used as show_existing_frame in future + cm->showable_frame = params->p.showable_frame;//aom_rb_read_bit(rb); + } + cm->cur_frame->showable_frame = cm->showable_frame; + cm->error_resilient_mode = + frame_is_sframe(cm) || + (current_frame->frame_type == KEY_FRAME && cm->show_frame) + ? 1 + : params->p.error_resilient_mode; //aom_rb_read_bit(rb); + } + +#ifdef ORI_CODE + cm->disable_cdf_update = aom_rb_read_bit(rb); + if (seq_params->force_screen_content_tools == 2) { + cm->allow_screen_content_tools = aom_rb_read_bit(rb); + } else { + cm->allow_screen_content_tools = seq_params->force_screen_content_tools; + } + + if (cm->allow_screen_content_tools) { + if (seq_params->force_integer_mv == 2) { + cm->cur_frame_force_integer_mv = aom_rb_read_bit(rb); + } else { + cm->cur_frame_force_integer_mv = seq_params->force_integer_mv; + } + } else { + cm->cur_frame_force_integer_mv = 0; + } +#endif + + frame_size_override_flag = 0; + cm->allow_intrabc = 0; + cm->primary_ref_frame = PRIMARY_REF_NONE; + + if (!seq_params->reduced_still_picture_hdr) { + if (seq_params->frame_id_numbers_present_flag) { + int frame_id_length = seq_params->frame_id_length; + int diff_len = seq_params->delta_frame_id_length; + int prev_frame_id = 0; + int have_prev_frame_id = + !pbi->decoding_first_frame && + !(current_frame->frame_type == KEY_FRAME && cm->show_frame); + if (have_prev_frame_id) { + prev_frame_id = cm->current_frame_id; + } + cm->current_frame_id = params->p.current_frame_id; //aom_rb_read_literal(rb, frame_id_length); + + if (have_prev_frame_id) { + int diff_frame_id; + if (cm->current_frame_id > prev_frame_id) { + diff_frame_id = cm->current_frame_id - prev_frame_id; + } else { + diff_frame_id = + (1 << frame_id_length) + cm->current_frame_id - prev_frame_id; + } + /* Check current_frame_id for conformance */ + if (prev_frame_id == cm->current_frame_id || + diff_frame_id >= (1 << (frame_id_length - 1))) { + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Invalid value of current_frame_id"); + } + } + /* Check if some frames need to be marked as not valid for referencing */ + for (i = 0; i < REF_FRAMES; i++) { + if (current_frame->frame_type == KEY_FRAME && cm->show_frame) { + cm->valid_for_referencing[i] = 0; + } else if (cm->current_frame_id - (1 << diff_len) > 0) { + if (cm->ref_frame_id[i] > cm->current_frame_id || + cm->ref_frame_id[i] < cm->current_frame_id - (1 << diff_len)) + cm->valid_for_referencing[i] = 0; + } else { + if (cm->ref_frame_id[i] > cm->current_frame_id && + cm->ref_frame_id[i] < (1 << frame_id_length) + + cm->current_frame_id - (1 << diff_len)) + cm->valid_for_referencing[i] = 0; + } + } + } + + frame_size_override_flag = frame_is_sframe(cm) ? 1 : params->p.frame_size_override_flag; //aom_rb_read_bit(rb); + + current_frame->order_hint = params->p.order_hint; /*aom_rb_read_literal( + rb, seq_params->order_hint_info.order_hint_bits_minus_1 + 1);*/ + current_frame->frame_number = current_frame->order_hint; + + if (!cm->error_resilient_mode && !frame_is_intra_only(cm)) { + cm->primary_ref_frame = params->p.primary_ref_frame;//aom_rb_read_literal(rb, PRIMARY_REF_BITS); + } + } + + if (seq_params->decoder_model_info_present_flag) { + cm->buffer_removal_time_present = params->p.buffer_removal_time_present; //aom_rb_read_bit(rb); + if (cm->buffer_removal_time_present) { + int op_num; + for (op_num = 0; + op_num < seq_params->operating_points_cnt_minus_1 + 1; op_num++) { + if (cm->op_params[op_num].decoder_model_param_present_flag) { + if ((((seq_params->operating_point_idc[op_num] >> + cm->temporal_layer_id) & + 0x1) && + ((seq_params->operating_point_idc[op_num] >> + (cm->spatial_layer_id + 8)) & + 0x1)) || + seq_params->operating_point_idc[op_num] == 0) { + cm->op_frame_timing[op_num].buffer_removal_time = + params->p.op_frame_timing[op_num]; + /*aom_rb_read_unsigned_literal( + rb, cm->buffer_model.buffer_removal_time_length);*/ + } else { + cm->op_frame_timing[op_num].buffer_removal_time = 0; + } + } else { + cm->op_frame_timing[op_num].buffer_removal_time = 0; + } + } + } + } + if (current_frame->frame_type == KEY_FRAME) { + if (!cm->show_frame) { // unshown keyframe (forward keyframe) + current_frame->refresh_frame_flags = params->p.refresh_frame_flags; //aom_rb_read_literal(rb, REF_FRAMES); + } else { // shown keyframe + current_frame->refresh_frame_flags = (1 << REF_FRAMES) - 1; + } + + for (i = 0; i < INTER_REFS_PER_FRAME; ++i) { + cm->remapped_ref_idx[i] = INVALID_IDX; + } + if (pbi->need_resync) { + reset_ref_frame_map(pbi); + pbi->need_resync = 0; + } + } else { + if (current_frame->frame_type == INTRA_ONLY_FRAME) { + current_frame->refresh_frame_flags = params->p.refresh_frame_flags; //aom_rb_read_literal(rb, REF_FRAMES); + if (current_frame->refresh_frame_flags == 0xFF) { + aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM, + "Intra only frames cannot have refresh flags 0xFF"); + } + if (pbi->need_resync) { + reset_ref_frame_map(pbi); + pbi->need_resync = 0; + } + } else if (pbi->need_resync != 1) { /* Skip if need resync */ + current_frame->refresh_frame_flags = + frame_is_sframe(cm) ? 0xFF : params->p.refresh_frame_flags; //aom_rb_read_literal(rb, REF_FRAMES); + } + } + + if (!frame_is_intra_only(cm) || current_frame->refresh_frame_flags != 0xFF) { + // Read all ref frame order hints if error_resilient_mode == 1 + if (cm->error_resilient_mode && + seq_params->order_hint_info.enable_order_hint) { + int ref_idx; + for (ref_idx = 0; ref_idx < REF_FRAMES; ref_idx++) { + // Read order hint from bit stream + unsigned int order_hint = params->p.ref_order_hint[ref_idx];/*aom_rb_read_literal( + rb, seq_params->order_hint_info.order_hint_bits_minus_1 + 1);*/ + // Get buffer + RefCntBuffer *buf = cm->ref_frame_map[ref_idx]; + int buf_idx; + if (buf == NULL || order_hint != buf->order_hint) { + if (buf != NULL) { + lock_buffer_pool(pool, flags); + decrease_ref_count(pbi, buf, pool); + unlock_buffer_pool(pool, flags); + } + // If no corresponding buffer exists, allocate a new buffer with all + // pixels set to neutral grey. + buf_idx = get_free_fb(cm); + if (buf_idx == INVALID_IDX) { + aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR, + "Unable to find free frame buffer"); + } + buf = &frame_bufs[buf_idx]; + lock_buffer_pool(pool, flags); + if (aom_realloc_frame_buffer(cm, &buf->buf, seq_params->max_frame_width, + seq_params->max_frame_height, buf->order_hint)) { + decrease_ref_count(pbi, buf, pool); + unlock_buffer_pool(pool, flags); + aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR, + "Failed to allocate frame buffer"); + } + unlock_buffer_pool(pool, flags); +#ifdef ORI_CODE + set_planes_to_neutral_grey(seq_params, &buf->buf, 0); +#endif + cm->ref_frame_map[ref_idx] = buf; + buf->order_hint = order_hint; + } + } + } + } + + if (current_frame->frame_type == KEY_FRAME) { + setup_frame_size(cm, frame_size_override_flag, params); +#ifdef ORI_CODE + if (cm->allow_screen_content_tools && !av1_superres_scaled(cm)) + cm->allow_intrabc = aom_rb_read_bit(rb); +#endif + cm->allow_ref_frame_mvs = 0; + cm->prev_frame = NULL; + } else { + cm->allow_ref_frame_mvs = 0; + + if (current_frame->frame_type == INTRA_ONLY_FRAME) { +#ifdef ORI_CODE + cm->cur_frame->film_grain_params_present = + seq_params->film_grain_params_present; +#endif + setup_frame_size(cm, frame_size_override_flag, params); +#ifdef ORI_CODE + if (cm->allow_screen_content_tools && !av1_superres_scaled(cm)) + cm->allow_intrabc = aom_rb_read_bit(rb); +#endif + } else if (pbi->need_resync != 1) { /* Skip if need resync */ + int frame_refs_short_signaling = 0; + // Frame refs short signaling is off when error resilient mode is on. + if (seq_params->order_hint_info.enable_order_hint) + frame_refs_short_signaling = params->p.frame_refs_short_signaling;//aom_rb_read_bit(rb); + + if (frame_refs_short_signaling) { + // == LAST_FRAME == + const int lst_ref = params->p.lst_ref; //aom_rb_read_literal(rb, REF_FRAMES_LOG2); + const RefCntBuffer *const lst_buf = cm->ref_frame_map[lst_ref]; + + // == GOLDEN_FRAME == + const int gld_ref = params->p.gld_ref; //aom_rb_read_literal(rb, REF_FRAMES_LOG2); + const RefCntBuffer *const gld_buf = cm->ref_frame_map[gld_ref]; + + // Most of the time, streams start with a keyframe. In that case, + // ref_frame_map will have been filled in at that point and will not + // contain any NULLs. However, streams are explicitly allowed to start + // with an intra-only frame, so long as they don't then signal a + // reference to a slot that hasn't been set yet. That's what we are + // checking here. + if (lst_buf == NULL) + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Inter frame requests nonexistent reference"); + if (gld_buf == NULL) + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Inter frame requests nonexistent reference"); + + av1_set_frame_refs(cm, cm->remapped_ref_idx, lst_ref, gld_ref); + } + + for (i = 0; i < INTER_REFS_PER_FRAME; ++i) { + int ref = 0; + if (!frame_refs_short_signaling) { + ref = params->p.remapped_ref_idx[i];//aom_rb_read_literal(rb, REF_FRAMES_LOG2); + + // Most of the time, streams start with a keyframe. In that case, + // ref_frame_map will have been filled in at that point and will not + // contain any NULLs. However, streams are explicitly allowed to start + // with an intra-only frame, so long as they don't then signal a + // reference to a slot that hasn't been set yet. That's what we are + // checking here. + if (cm->ref_frame_map[ref] == NULL) + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Inter frame requests nonexistent reference"); + cm->remapped_ref_idx[i] = ref; + } else { + ref = cm->remapped_ref_idx[i]; + } + + cm->ref_frame_sign_bias[LAST_FRAME + i] = 0; + + if (seq_params->frame_id_numbers_present_flag) { + int frame_id_length = seq_params->frame_id_length; + //int diff_len = seq_params->delta_frame_id_length; + int delta_frame_id_minus_1 = params->p.delta_frame_id_minus_1[i];//aom_rb_read_literal(rb, diff_len); + int ref_frame_id = + ((cm->current_frame_id - (delta_frame_id_minus_1 + 1) + + (1 << frame_id_length)) % + (1 << frame_id_length)); + // Compare values derived from delta_frame_id_minus_1 and + // refresh_frame_flags. Also, check valid for referencing + if (ref_frame_id != cm->ref_frame_id[ref] || + cm->valid_for_referencing[ref] == 0) + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Reference buffer frame ID mismatch"); + } + } + + if (!cm->error_resilient_mode && frame_size_override_flag) { + setup_frame_size_with_refs(cm, params); + } else { + setup_frame_size(cm, frame_size_override_flag, params); + } +#ifdef ORI_CODE + if (cm->cur_frame_force_integer_mv) { + cm->allow_high_precision_mv = 0; + } else { + cm->allow_high_precision_mv = aom_rb_read_bit(rb); + } + cm->interp_filter = read_frame_interp_filter(rb); + cm->switchable_motion_mode = aom_rb_read_bit(rb); +#endif + } + + cm->prev_frame = get_primary_ref_frame_buf(cm); + if (cm->primary_ref_frame != PRIMARY_REF_NONE && + get_primary_ref_frame_buf(cm) == NULL) { + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Reference frame containing this frame's initial " + "frame context is unavailable."); + } +#if 0 + av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "%d,%d,%d,%d\n",cm->error_resilient_mode, + cm->seq_params.order_hint_info.enable_ref_frame_mvs, + cm->seq_params.order_hint_info.enable_order_hint,frame_is_intra_only(cm)); + + printf("frame_might_allow_ref_frame_mvs()=>%d, current_frame->frame_type=%d, pbi->need_resync=%d, params->p.allow_ref_frame_mvs=%d\n", + frame_might_allow_ref_frame_mvs(cm), current_frame->frame_type, pbi->need_resync, + params->p.allow_ref_frame_mvs); +#endif + if (!(current_frame->frame_type == INTRA_ONLY_FRAME) && + pbi->need_resync != 1) { + if (frame_might_allow_ref_frame_mvs(cm)) + cm->allow_ref_frame_mvs = params->p.allow_ref_frame_mvs; //aom_rb_read_bit(-1, "", rb); + else + cm->allow_ref_frame_mvs = 0; + +#ifdef SUPPORT_SCALE_FACTOR + for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) { + const RefCntBuffer *const ref_buf = get_ref_frame_buf(cm, i); + struct scale_factors *const ref_scale_factors = + get_ref_scale_factors(cm, i); + if (ref_buf != NULL) { +#ifdef AML + av1_setup_scale_factors_for_frame( + ref_scale_factors, ref_buf->buf.y_crop_width, + ref_buf->buf.y_crop_height, cm->dec_width, cm->height); +#else + av1_setup_scale_factors_for_frame( + ref_scale_factors, ref_buf->buf.y_crop_width, + ref_buf->buf.y_crop_height, cm->width, cm->height); +#endif + } + if (ref_scale_factors) { + if ((!av1_is_valid_scale(ref_scale_factors))) + aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM, + "Reference frame has invalid dimensions"); + } + } +#endif + } + } + + av1_setup_frame_buf_refs(cm); + + av1_setup_frame_sign_bias(cm); + + cm->cur_frame->frame_type = current_frame->frame_type; + + if (seq_params->frame_id_numbers_present_flag) { + update_ref_frame_id(cm, cm->current_frame_id); + } +#ifdef ORI_CODE + const int might_bwd_adapt = + !(seq_params->reduced_still_picture_hdr) && !(cm->disable_cdf_update); + if (might_bwd_adapt) { + cm->refresh_frame_context = aom_rb_read_bit(rb) + ? REFRESH_FRAME_CONTEXT_DISABLED + : REFRESH_FRAME_CONTEXT_BACKWARD; + } else { + cm->refresh_frame_context = REFRESH_FRAME_CONTEXT_DISABLED; + } +#endif + + cm->cur_frame->buf.bit_depth = seq_params->bit_depth; + cm->cur_frame->buf.color_primaries = seq_params->color_primaries; + cm->cur_frame->buf.transfer_characteristics = + seq_params->transfer_characteristics; + cm->cur_frame->buf.matrix_coefficients = seq_params->matrix_coefficients; + cm->cur_frame->buf.monochrome = seq_params->monochrome; + cm->cur_frame->buf.chroma_sample_position = + seq_params->chroma_sample_position; + cm->cur_frame->buf.color_range = seq_params->color_range; + cm->cur_frame->buf.render_width = cm->render_width; + cm->cur_frame->buf.render_height = cm->render_height; + + if (pbi->need_resync) { + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Keyframe / intra-only frame required to reset decoder" + " state"); + } + + generate_next_ref_frame_map(pbi); + +#ifdef ORI_CODE + if (cm->allow_intrabc) { + // Set parameters corresponding to no filtering. + struct loopfilter *lf = &cm->lf; + lf->filter_level[0] = 0; + lf->filter_level[1] = 0; + cm->cdef_info.cdef_bits = 0; + cm->cdef_info.cdef_strengths[0] = 0; + cm->cdef_info.nb_cdef_strengths = 1; + cm->cdef_info.cdef_uv_strengths[0] = 0; + cm->rst_info[0].frame_restoration_type = RESTORE_NONE; + cm->rst_info[1].frame_restoration_type = RESTORE_NONE; + cm->rst_info[2].frame_restoration_type = RESTORE_NONE; + } + + read_tile_info(pbi, rb); + if (!av1_is_min_tile_width_satisfied(cm)) { + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Minimum tile width requirement not satisfied"); + } + + setup_quantization(cm, rb); + xd->bd = (int)seq_params->bit_depth; + + if (cm->num_allocated_above_context_planes < av1_num_planes(cm) || + cm->num_allocated_above_context_mi_col < cm->mi_cols || + cm->num_allocated_above_contexts < cm->tile_rows) { + av1_free_above_context_buffers(cm, cm->num_allocated_above_contexts); + if (av1_alloc_above_context_buffers(cm, cm->tile_rows)) + aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR, + "Failed to allocate context buffers"); + } + + if (cm->primary_ref_frame == PRIMARY_REF_NONE) { + av1_setup_past_independence(cm); + } + + setup_segmentation(cm, params); + + cm->delta_q_info.delta_q_res = 1; + cm->delta_q_info.delta_lf_res = 1; + cm->delta_q_info.delta_lf_present_flag = 0; + cm->delta_q_info.delta_lf_multi = 0; + cm->delta_q_info.delta_q_present_flag = + cm->base_qindex > 0 ? aom_rb_read_bit(-1, defmark, rb) : 0; + if (cm->delta_q_info.delta_q_present_flag) { + xd->current_qindex = cm->base_qindex; + cm->delta_q_info.delta_q_res = 1 << aom_rb_read_literal(-1, defmark, rb, 2); + if (!cm->allow_intrabc) + cm->delta_q_info.delta_lf_present_flag = aom_rb_read_bit(-1, defmark, rb); + if (cm->delta_q_info.delta_lf_present_flag) { + cm->delta_q_info.delta_lf_res = 1 << aom_rb_read_literal(-1, defmark, rb, 2); + cm->delta_q_info.delta_lf_multi = aom_rb_read_bit(-1, defmark, rb); + av1_reset_loop_filter_delta(xd, av1_num_planes(cm)); + } + } + + xd->cur_frame_force_integer_mv = cm->cur_frame_force_integer_mv; + + for (int i = 0; i < MAX_SEGMENTS; ++i) { + const int qindex = av1_get_qindex(&cm->seg, i, cm->base_qindex); + xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 && + cm->u_dc_delta_q == 0 && cm->u_ac_delta_q == 0 && + cm->v_dc_delta_q == 0 && cm->v_ac_delta_q == 0; + xd->qindex[i] = qindex; + } + cm->coded_lossless = is_coded_lossless(cm, xd); + cm->all_lossless = cm->coded_lossless && !av1_superres_scaled(cm); + setup_segmentation_dequant(cm, xd); + if (cm->coded_lossless) { + cm->lf.filter_level[0] = 0; + cm->lf.filter_level[1] = 0; + } + if (cm->coded_lossless || !seq_params->enable_cdef) { + cm->cdef_info.cdef_bits = 0; + cm->cdef_info.cdef_strengths[0] = 0; + cm->cdef_info.cdef_uv_strengths[0] = 0; + } + if (cm->all_lossless || !seq_params->enable_restoration) { + cm->rst_info[0].frame_restoration_type = RESTORE_NONE; + cm->rst_info[1].frame_restoration_type = RESTORE_NONE; + cm->rst_info[2].frame_restoration_type = RESTORE_NONE; + } + setup_loopfilter(cm, rb); + + if (!cm->coded_lossless && seq_params->enable_cdef) { + setup_cdef(cm, rb); + } + if (!cm->all_lossless && seq_params->enable_restoration) { + decode_restoration_mode(cm, rb); + } + + cm->tx_mode = read_tx_mode(cm, rb); +#endif + + current_frame->reference_mode = read_frame_reference_mode(cm, params); + +#ifdef ORI_CODE + if (current_frame->reference_mode != SINGLE_REFERENCE) + setup_compound_reference_mode(cm); + + +#endif + + av1_setup_skip_mode_allowed(cm); + + /* + the point that ucode send send_bufmgr_info + and wait bufmgr code to return is_skip_mode_allowed + */ + + /* + read_uncompressed_header() end + */ + + av1_setup_motion_field(cm); +#ifdef AML + cm->cur_frame->mi_cols = cm->mi_cols; + cm->cur_frame->mi_rows = cm->mi_rows; + cm->cur_frame->dec_width = cm->dec_width; + + /* + superres_post_decode(AV1Decoder *pbi) => + av1_superres_upscale(cm, pool); => + aom_realloc_frame_buffer( + frame_to_show, cm->superres_upscaled_width, + cm->superres_upscaled_height, seq_params->subsampling_x, + seq_params->subsampling_y, seq_params->use_highbitdepth, + AOM_BORDER_IN_PIXELS, cm->byte_alignment, fb, cb, cb_priv) + */ + aom_realloc_frame_buffer(cm, &cm->cur_frame->buf, + cm->superres_upscaled_width, cm->superres_upscaled_height, + cm->cur_frame->order_hint); +#endif + return 0; +} + +static int are_seq_headers_consistent(const SequenceHeader *seq_params_old, + const SequenceHeader *seq_params_new) { + return !memcmp(seq_params_old, seq_params_new, sizeof(SequenceHeader)); +} + +aom_codec_err_t aom_get_num_layers_from_operating_point_idc( + int operating_point_idc, unsigned int *number_spatial_layers, + unsigned int *number_temporal_layers) { + // derive number of spatial/temporal layers from operating_point_idc + + if (!number_spatial_layers || !number_temporal_layers) + return AOM_CODEC_INVALID_PARAM; + + if (operating_point_idc == 0) { + *number_temporal_layers = 1; + *number_spatial_layers = 1; + } else { + int j; + *number_spatial_layers = 0; + *number_temporal_layers = 0; + for (j = 0; j < MAX_NUM_SPATIAL_LAYERS; j++) { + *number_spatial_layers += + (operating_point_idc >> (j + MAX_NUM_TEMPORAL_LAYERS)) & 0x1; + } + for (j = 0; j < MAX_NUM_TEMPORAL_LAYERS; j++) { + *number_temporal_layers += (operating_point_idc >> j) & 0x1; + } + } + + return AOM_CODEC_OK; +} + +void av1_read_sequence_header(AV1_COMMON *cm, union param_u *params, + SequenceHeader *seq_params) { +#ifdef ORI_CODE + const int num_bits_width = aom_rb_read_literal(-1, "", rb, 4) + 1; + const int num_bits_height = aom_rb_read_literal(-1, "", rb, 4) + 1; + const int max_frame_width = aom_rb_read_literal(-1, "", rb, num_bits_width) + 1; + const int max_frame_height = aom_rb_read_literal(-1, "", rb, num_bits_height) + 1; + + seq_params->num_bits_width = num_bits_width; + seq_params->num_bits_height = num_bits_height; +#endif + seq_params->max_frame_width = params->p.max_frame_width; //max_frame_width; + seq_params->max_frame_height = params->p.max_frame_height; //max_frame_height; + + if (seq_params->reduced_still_picture_hdr) { + seq_params->frame_id_numbers_present_flag = 0; + } else { + seq_params->frame_id_numbers_present_flag = params->p.frame_id_numbers_present_flag; //aom_rb_read_bit(-1, "", rb); + } + if (seq_params->frame_id_numbers_present_flag) { + // We must always have delta_frame_id_length < frame_id_length, + // in order for a frame to be referenced with a unique delta. + // Avoid wasting bits by using a coding that enforces this restriction. +#ifdef ORI_CODE + seq_params->delta_frame_id_length = aom_rb_read_literal(-1, "", rb, 4) + 2; + seq_params->frame_id_length = params->p.frame_id_length + aom_rb_read_literal(-1, "", rb, 3) + seq_params->delta_frame_id_length + 1; +#else + seq_params->delta_frame_id_length = params->p.delta_frame_id_length; + seq_params->frame_id_length = params->p.frame_id_length + seq_params->delta_frame_id_length + 1; +#endif + if (seq_params->frame_id_length > 16) + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Invalid frame_id_length"); + } +#ifdef ORI_CODE + setup_sb_size(seq_params, rb); + seq_params->enable_filter_intra = aom_rb_read_bit(-1, "", rb); + seq_params->enable_intra_edge_filter = aom_rb_read_bit(-1, "", rb); +#endif + + if (seq_params->reduced_still_picture_hdr) { + seq_params->enable_interintra_compound = 0; + seq_params->enable_masked_compound = 0; + seq_params->enable_warped_motion = 0; + seq_params->enable_dual_filter = 0; + seq_params->order_hint_info.enable_order_hint = 0; + seq_params->order_hint_info.enable_dist_wtd_comp = 0; + seq_params->order_hint_info.enable_ref_frame_mvs = 0; + seq_params->force_screen_content_tools = 2; // SELECT_SCREEN_CONTENT_TOOLS + seq_params->force_integer_mv = 2; // SELECT_INTEGER_MV + seq_params->order_hint_info.order_hint_bits_minus_1 = -1; + } else { +#ifdef ORI_CODE + seq_params->enable_interintra_compound = aom_rb_read_bit(-1, "", rb); + seq_params->enable_masked_compound = aom_rb_read_bit(-1, "", rb); + seq_params->enable_warped_motion = aom_rb_read_bit(-1, "", rb); + seq_params->enable_dual_filter = aom_rb_read_bit(-1, "", rb); +#endif + seq_params->order_hint_info.enable_order_hint = params->p.enable_order_hint; //aom_rb_read_bit(-1, "", rb); + seq_params->order_hint_info.enable_dist_wtd_comp = + seq_params->order_hint_info.enable_order_hint ? params->p.enable_dist_wtd_comp : 0; //aom_rb_read_bit(-1, "", rb) : 0; + seq_params->order_hint_info.enable_ref_frame_mvs = + seq_params->order_hint_info.enable_order_hint ? params->p.enable_ref_frame_mvs : 0; //aom_rb_read_bit(-1, "", rb) : 0; + +#ifdef ORI_CODE + if (aom_rb_read_bit(-1, defmark, rb)) { + seq_params->force_screen_content_tools = + 2; // SELECT_SCREEN_CONTENT_TOOLS + } else { + seq_params->force_screen_content_tools = aom_rb_read_bit(-1, defmark, rb); + } + + if (seq_params->force_screen_content_tools > 0) { + if (aom_rb_read_bit(-1, defmark, rb)) { + seq_params->force_integer_mv = 2; // SELECT_INTEGER_MV + } else { + seq_params->force_integer_mv = aom_rb_read_bit(-1, defmark, rb); + } + } else { + seq_params->force_integer_mv = 2; // SELECT_INTEGER_MV + } +#endif + seq_params->order_hint_info.order_hint_bits_minus_1 = + seq_params->order_hint_info.enable_order_hint + ? params->p.order_hint_bits_minus_1 /*aom_rb_read_literal(-1, "", rb, 3)*/ + : -1; + } + seq_params->enable_superres = params->p.enable_superres; //aom_rb_read_bit(-1, defmark, rb); + +#ifdef ORI_CODE + seq_params->enable_cdef = aom_rb_read_bit(-1, defmark, rb); + seq_params->enable_restoration = aom_rb_read_bit(-1, defmark, rb); +#endif +} + +#ifdef ORI_CODE +void av1_read_op_parameters_info(AV1_COMMON *const cm, + struct aom_read_bit_buffer *rb, int op_num) { + // The cm->op_params array has MAX_NUM_OPERATING_POINTS + 1 elements. + if (op_num > MAX_NUM_OPERATING_POINTS) { + aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM, + "AV1 does not support %d decoder model operating points", + op_num + 1); + } + + cm->op_params[op_num].decoder_buffer_delay = aom_rb_read_unsigned_literal(-1, defmark, + rb, cm->buffer_model.encoder_decoder_buffer_delay_length); + + cm->op_params[op_num].encoder_buffer_delay = aom_rb_read_unsigned_literal(-1, defmark, + rb, cm->buffer_model.encoder_decoder_buffer_delay_length); + + cm->op_params[op_num].low_delay_mode_flag = aom_rb_read_bit(-1, defmark, rb); +} +#endif + +static int is_valid_seq_level_idx(AV1_LEVEL seq_level_idx) { + return seq_level_idx < SEQ_LEVELS || seq_level_idx == SEQ_LEVEL_MAX; +} + +static uint32_t read_sequence_header_obu(AV1Decoder *pbi, + union param_u *params) { + AV1_COMMON *const cm = &pbi->common; + int i; + int operating_point; + // Verify rb has been configured to report errors. + //assert(rb->error_handler); + + // Use a local variable to store the information as we decode. At the end, + // if no errors have occurred, cm->seq_params is updated. + SequenceHeader sh = cm->seq_params; + SequenceHeader *const seq_params = &sh; + + seq_params->profile = params->p.profile; //av1_read_profile(rb); + if (seq_params->profile > CONFIG_MAX_DECODE_PROFILE) { + cm->error.error_code = AOM_CODEC_UNSUP_BITSTREAM; + return 0; + } + + // Still picture or not + seq_params->still_picture = params->p.still_picture; //aom_rb_read_bit(-1, "", rb); + seq_params->reduced_still_picture_hdr = params->p.reduced_still_picture_hdr; //aom_rb_read_bit(-1, "", rb); + // Video must have reduced_still_picture_hdr = 0 + if (!seq_params->still_picture && seq_params->reduced_still_picture_hdr) { + cm->error.error_code = AOM_CODEC_UNSUP_BITSTREAM; + return 0; + } + + if (seq_params->reduced_still_picture_hdr) { + cm->timing_info_present = 0; + seq_params->decoder_model_info_present_flag = 0; + seq_params->display_model_info_present_flag = 0; + seq_params->operating_points_cnt_minus_1 = 0; + seq_params->operating_point_idc[0] = 0; + //if (!read_bitstream_level(0, "", &seq_params->seq_level_idx[0], rb)) { + if (!is_valid_seq_level_idx(params->p.seq_level_idx[0])) { + cm->error.error_code = AOM_CODEC_UNSUP_BITSTREAM; + return 0; + } + seq_params->tier[0] = 0; + cm->op_params[0].decoder_model_param_present_flag = 0; + cm->op_params[0].display_model_param_present_flag = 0; + } else { + cm->timing_info_present = params->p.timing_info_present; //aom_rb_read_bit(-1, "", rb); // timing_info_present_flag + if (cm->timing_info_present) { +#ifdef ORI_CODE + av1_read_timing_info_header(cm, rb); +#endif + seq_params->decoder_model_info_present_flag = params->p.decoder_model_info_present_flag; //aom_rb_read_bit(-1, "", rb); +#ifdef ORI_CODE + if (seq_params->decoder_model_info_present_flag) + av1_read_decoder_model_info(cm, rb); +#endif + } else { + seq_params->decoder_model_info_present_flag = 0; + } +#ifdef ORI_CODE + seq_params->display_model_info_present_flag = aom_rb_read_bit(-1, "", rb); +#endif + seq_params->operating_points_cnt_minus_1 = params->p.operating_points_cnt_minus_1; + //aom_rb_read_literal(-1, "", rb, OP_POINTS_CNT_MINUS_1_BITS); + for (i = 0; i < seq_params->operating_points_cnt_minus_1 + 1; i++) { + seq_params->operating_point_idc[i] = params->p.operating_point_idc[i]; + //aom_rb_read_literal(i, "", rb, OP_POINTS_IDC_BITS); + //if (!read_bitstream_level(i, "", &seq_params->seq_level_idx[i], rb)) { + if (!is_valid_seq_level_idx(params->p.seq_level_idx[i])) { + cm->error.error_code = AOM_CODEC_UNSUP_BITSTREAM; + return 0; + } + // This is the seq_level_idx[i] > 7 check in the spec. seq_level_idx 7 + // is equivalent to level 3.3. +#ifdef ORI_CODE + if (seq_params->seq_level_idx[i] >= SEQ_LEVEL_4_0) + seq_params->tier[i] = aom_rb_read_bit(i, "", rb); + else + seq_params->tier[i] = 0; +#endif + if (seq_params->decoder_model_info_present_flag) { + cm->op_params[i].decoder_model_param_present_flag = params->p.decoder_model_param_present_flag[i]; //aom_rb_read_bit(-1, defmark, rb); +#ifdef ORI_CODE + if (cm->op_params[i].decoder_model_param_present_flag) + av1_read_op_parameters_info(cm, rb, i); +#endif + } else { + cm->op_params[i].decoder_model_param_present_flag = 0; + } +#ifdef ORI_CODE + if (cm->timing_info_present && + (cm->timing_info.equal_picture_interval || + cm->op_params[i].decoder_model_param_present_flag)) { + cm->op_params[i].bitrate = av1_max_level_bitrate( + seq_params->profile, seq_params->seq_level_idx[i], + seq_params->tier[i]); + // Level with seq_level_idx = 31 returns a high "dummy" bitrate to pass + // the check + if (cm->op_params[i].bitrate == 0) + aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM, + "AV1 does not support this combination of " + "profile, level, and tier."); + // Buffer size in bits/s is bitrate in bits/s * 1 s + cm->op_params[i].buffer_size = cm->op_params[i].bitrate; + } +#endif + if (cm->timing_info_present && cm->timing_info.equal_picture_interval && + !cm->op_params[i].decoder_model_param_present_flag) { + // When the decoder_model_parameters are not sent for this op, set + // the default ones that can be used with the resource availability mode + cm->op_params[i].decoder_buffer_delay = 70000; + cm->op_params[i].encoder_buffer_delay = 20000; + cm->op_params[i].low_delay_mode_flag = 0; + } + +#ifdef ORI_CODE + if (seq_params->display_model_info_present_flag) { + cm->op_params[i].display_model_param_present_flag = aom_rb_read_bit(-1, defmark, rb); + if (cm->op_params[i].display_model_param_present_flag) { + cm->op_params[i].initial_display_delay = + aom_rb_read_literal(-1, defmark, rb, 4) + 1; + if (cm->op_params[i].initial_display_delay > 10) + aom_internal_error( + &cm->error, AOM_CODEC_UNSUP_BITSTREAM, + "AV1 does not support more than 10 decoded frames delay"); + } else { + cm->op_params[i].initial_display_delay = 10; + } + } else { + cm->op_params[i].display_model_param_present_flag = 0; + cm->op_params[i].initial_display_delay = 10; + } +#endif + } + } + // This decoder supports all levels. Choose operating point provided by + // external means + operating_point = pbi->operating_point; + if (operating_point < 0 || + operating_point > seq_params->operating_points_cnt_minus_1) + operating_point = 0; + pbi->current_operating_point = + seq_params->operating_point_idc[operating_point]; + if (aom_get_num_layers_from_operating_point_idc( + pbi->current_operating_point, &cm->number_spatial_layers, + &cm->number_temporal_layers) != AOM_CODEC_OK) { + cm->error.error_code = AOM_CODEC_ERROR; + return 0; + } + + av1_read_sequence_header(cm, params, seq_params); +#ifdef ORI_CODE + av1_read_color_config(rb, pbi->allow_lowbitdepth, seq_params, &cm->error); + if (!(seq_params->subsampling_x == 0 && seq_params->subsampling_y == 0) && + !(seq_params->subsampling_x == 1 && seq_params->subsampling_y == 1) && + !(seq_params->subsampling_x == 1 && seq_params->subsampling_y == 0)) { + aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM, + "Only 4:4:4, 4:2:2 and 4:2:0 are currently supported, " + "%d %d subsampling is not supported.\n", + seq_params->subsampling_x, seq_params->subsampling_y); + } + seq_params->film_grain_params_present = aom_rb_read_bit(-1, "", rb); + + if (av1_check_trailing_bits(pbi, rb) != 0) { + // cm->error.error_code is already set. + return 0; + } +#endif + + // If a sequence header has been decoded before, we check if the new + // one is consistent with the old one. + if (pbi->sequence_header_ready) { + if (!are_seq_headers_consistent(&cm->seq_params, seq_params)) + pbi->sequence_header_changed = 1; + } + + cm->seq_params = *seq_params; + pbi->sequence_header_ready = 1; + return 0; + +} + +int aom_decode_frame_from_obus(AV1Decoder *pbi, union param_u *params, int obu_type) +{ + AV1_COMMON *const cm = &pbi->common; + ObuHeader obu_header; + int frame_decoding_finished = 0; + uint32_t frame_header_size = 0; + + //struct aom_read_bit_buffer rb; + size_t payload_size = 0; + size_t decoded_payload_size = 0; + size_t obu_payload_offset = 0; + //size_t bytes_read = 0; + + memset(&obu_header, 0, sizeof(obu_header)); +#ifdef ORI_CODE + pbi->seen_frame_header = 0; +#else + /* set in the test.c*/ +#endif + + obu_header.type = obu_type; + pbi->cur_obu_type = obu_header.type; + if (av1_is_debug(AOM_DEBUG_PRINT_LIST_INFO)) + dump_params(pbi, params); + switch (obu_header.type) { + case OBU_SEQUENCE_HEADER: + decoded_payload_size = read_sequence_header_obu(pbi, params); + if (cm->error.error_code != AOM_CODEC_OK) return -1; + break; + + case OBU_FRAME_HEADER: + case OBU_REDUNDANT_FRAME_HEADER: + case OBU_FRAME: + if (obu_header.type == OBU_REDUNDANT_FRAME_HEADER) { + if (!pbi->seen_frame_header) { + cm->error.error_code = AOM_CODEC_CORRUPT_FRAME; + return -1; + } + } else { + // OBU_FRAME_HEADER or OBU_FRAME. + if (pbi->seen_frame_header) { + cm->error.error_code = AOM_CODEC_CORRUPT_FRAME; + return -1; + } + } + // Only decode first frame header received + if (!pbi->seen_frame_header || + (cm->large_scale_tile && !pbi->camera_frame_header_ready)) { + frame_header_size = av1_decode_frame_headers_and_setup( + pbi, /*&rb, data, p_data_end,*/obu_header.type != OBU_FRAME, params); + pbi->seen_frame_header = 1; + if (!pbi->ext_tile_debug && cm->large_scale_tile) + pbi->camera_frame_header_ready = 1; + } else { + // TODO(wtc): Verify that the frame_header_obu is identical to the + // original frame_header_obu. For now just skip frame_header_size + // bytes in the bit buffer. + if (frame_header_size > payload_size) { + cm->error.error_code = AOM_CODEC_CORRUPT_FRAME; + return -1; + } + assert(rb.bit_offset == 0); +#ifdef ORI_CODE + rb.bit_offset = 8 * frame_header_size; +#endif + } + + decoded_payload_size = frame_header_size; + pbi->frame_header_size = frame_header_size; + + if (cm->show_existing_frame) { + if (obu_header.type == OBU_FRAME) { + cm->error.error_code = AOM_CODEC_UNSUP_BITSTREAM; + return -1; + } + frame_decoding_finished = 1; + pbi->seen_frame_header = 0; + break; + } + + // In large scale tile coding, decode the common camera frame header + // before any tile list OBU. + if (!pbi->ext_tile_debug && pbi->camera_frame_header_ready) { + frame_decoding_finished = 1; + // Skip the rest of the frame data. + decoded_payload_size = payload_size; + // Update data_end. +#ifdef ORI_CODE + *p_data_end = data_end; +#endif + break; + } +#if 0 //def AML + frame_decoding_finished = 1; +#endif + if (obu_header.type != OBU_FRAME) break; + obu_payload_offset = frame_header_size; + // Byte align the reader before reading the tile group. + // byte_alignment() has set cm->error.error_code if it returns -1. +#ifdef ORI_CODE + if (byte_alignment(cm, &rb)) return -1; + AOM_FALLTHROUGH_INTENDED; // fall through to read tile group. +#endif + default: + break; + } + return frame_decoding_finished; +} + +int get_buffer_index(AV1Decoder *pbi, RefCntBuffer *buffer) +{ + AV1_COMMON *const cm = &pbi->common; + int i = -1; + + if (buffer) { + for (i = 0; i < FRAME_BUFFERS; i++) { + RefCntBuffer *buf = + &cm->buffer_pool->frame_bufs[i]; + if (buf == buffer) { + break; + } + } + } + return i; +} + +void dump_buffer(RefCntBuffer *buf) +{ + int i; + pr_info("ref_count %d, vf_ref %d, order_hint %d, w/h(%d,%d) showable_frame %d frame_type %d canvas(%d,%d) w/h(%d,%d) mi_c/r(%d,%d) header 0x%x ref_deltas(", + buf->ref_count, buf->buf.vf_ref, buf->order_hint, buf->width, buf->height, buf->showable_frame, buf->frame_type, + buf->buf.mc_canvas_y, buf->buf.mc_canvas_u_v, + buf->buf.y_crop_width, buf->buf.y_crop_height, + buf->mi_cols, buf->mi_rows, + buf->buf.header_adr); + for (i = 0; i < REF_FRAMES; i++) + pr_info("%d,", buf->ref_deltas[i]); + pr_info("), ref_order_hints("); + + for (i = 0; i < INTER_REFS_PER_FRAME; i++) + pr_info("%d ", buf->ref_order_hints[i]); + pr_info(")"); +} + +void dump_ref_buffer_info(AV1Decoder *pbi, int i) +{ + AV1_COMMON *const cm = &pbi->common; + pr_info("remapped_ref_idx %d, ref_frame_sign_bias %d, ref_frame_id %d, valid_for_referencing %d ref_frame_side %d ref_frame_map idx %d, next_ref_frame_map idx %d", + cm->remapped_ref_idx[i], + cm->ref_frame_sign_bias[i], + cm->ref_frame_id[i], + cm->valid_for_referencing[i], + cm->ref_frame_side[i], + get_buffer_index(pbi, cm->ref_frame_map[i]), + get_buffer_index(pbi, cm->next_ref_frame_map[i])); +} + +void dump_mv_refs(AV1Decoder *pbi) +{ + int i, j; + AV1_COMMON *const cm = &pbi->common; + for (i = 0; i < cm->mv_ref_id_index; i++) { + pr_info("%d: ref_id %d cal_tpl_mvs %d mv_ref_offset: ", + i, cm->mv_ref_id[i], cm->mv_cal_tpl_mvs[i]); + for (j = 0; j < REF_FRAMES; j++) + pr_info("%d ", cm->mv_ref_offset[i][j]); + pr_info("\n"); + } +} + +void dump_ref_spec_bufs(AV1Decoder *pbi) +{ + int i; + AV1_COMMON *const cm = &pbi->common; + for (i = 0; i < INTER_REFS_PER_FRAME; ++i) { + PIC_BUFFER_CONFIG *pic_config = av1_get_ref_frame_spec_buf(cm, LAST_FRAME + i); + if (pic_config == NULL) continue; + pr_info("%d: index %d order_hint %d header 0x%x dw_header 0x%x canvas(%d,%d) mv_wr_start 0x%x lcu_total %d\n", + i, pic_config->index, + pic_config->order_hint, + pic_config->header_adr, +#ifdef AOM_AV1_MMU_DW + pic_config->header_dw_adr, +#else + 0, +#endif + pic_config->mc_canvas_y, + pic_config->mc_canvas_u_v, + pic_config->mpred_mv_wr_start_addr, + pic_config->lcu_total + ); + } +} + +#ifdef SUPPORT_SCALE_FACTOR +void dump_scale_factors(AV1Decoder *pbi) +{ + int i; + AV1_COMMON *const cm = &pbi->common; + for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) { + struct scale_factors *const sf = + get_ref_scale_factors(cm, i); + if (sf) + pr_info("%d: is_scaled %d x_scale_fp %d, y_scale_fp %d\n", + i, av1_is_scaled(sf), + sf->x_scale_fp, sf->y_scale_fp); + else + pr_info("%d: sf null\n", i); + } +} + +#endif + +void dump_buffer_status(AV1Decoder *pbi) +{ + int i; + AV1_COMMON *const cm = &pbi->common; + BufferPool *const pool = cm->buffer_pool; + unsigned long flags; + + lock_buffer_pool(pool, flags); + + pr_info("%s: pbi %p cm %p cur_frame %p\n", __func__, pbi, cm, cm->cur_frame); + + pr_info("Buffer Pool:\n"); + for (i = 0; i < FRAME_BUFFERS; i++) { + RefCntBuffer *buf = + &cm->buffer_pool->frame_bufs[i]; + pr_info("%d: ", i); + if (buf) + dump_buffer(buf); + pr_info("\n"); + } + + if (cm->prev_frame) { + pr_info("prev_frame (%d): ", + get_buffer_index(pbi, cm->prev_frame)); + dump_buffer(cm->prev_frame); + pr_info("\n"); + } + if (cm->cur_frame) { + pr_info("cur_frame (%d): ", + get_buffer_index(pbi, cm->cur_frame)); + dump_buffer(cm->cur_frame); + pr_info("\n"); + } + pr_info("REF_FRAMES Info(ref buf is ref_frame_map[remapped_ref_idx[i-1]], i=1~7):\n"); + for (i = 0; i < REF_FRAMES; i++) { + pr_info("%d: ", i); + dump_ref_buffer_info(pbi, i); + pr_info("\n"); + } + pr_info("Ref Spec Buffers:\n"); + dump_ref_spec_bufs(pbi); + + pr_info("MV refs:\n"); + dump_mv_refs(pbi); + +#ifdef SUPPORT_SCALE_FACTOR + pr_info("Scale factors:\n"); + dump_scale_factors(pbi); +#endif + unlock_buffer_pool(pool, flags); +} + + +struct param_dump_item_s { + unsigned int size; + char* name; + unsigned int adr_off; +} param_dump_items[] = { + {1, "profile", (unsigned long)&(((union param_u *)0)->p.profile )}, + {1, "still_picture", (unsigned long)&(((union param_u *)0)->p.still_picture )}, + {1, "reduced_still_picture_hdr", (unsigned long)&(((union param_u *)0)->p.reduced_still_picture_hdr )}, + {1, "decoder_model_info_present_flag", (unsigned long)&(((union param_u *)0)->p.decoder_model_info_present_flag)}, + {1, "max_frame_width", (unsigned long)&(((union param_u *)0)->p.max_frame_width )}, + {1, "max_frame_height", (unsigned long)&(((union param_u *)0)->p.max_frame_height )}, + {1, "frame_id_numbers_present_flag", (unsigned long)&(((union param_u *)0)->p.frame_id_numbers_present_flag )}, + {1, "delta_frame_id_length", (unsigned long)&(((union param_u *)0)->p.delta_frame_id_length )}, + {1, "frame_id_length", (unsigned long)&(((union param_u *)0)->p.frame_id_length )}, + {1, "order_hint_bits_minus_1", (unsigned long)&(((union param_u *)0)->p.order_hint_bits_minus_1 )}, + {1, "enable_order_hint", (unsigned long)&(((union param_u *)0)->p.enable_order_hint )}, + {1, "enable_dist_wtd_comp", (unsigned long)&(((union param_u *)0)->p.enable_dist_wtd_comp )}, + {1, "enable_ref_frame_mvs", (unsigned long)&(((union param_u *)0)->p.enable_ref_frame_mvs )}, + {1, "enable_superres", (unsigned long)&(((union param_u *)0)->p.enable_superres )}, + {1, "superres_scale_denominator", (unsigned long)&(((union param_u *)0)->p.superres_scale_denominator )}, + {1, "show_existing_frame", (unsigned long)&(((union param_u *)0)->p.show_existing_frame )}, + {1, "frame_type", (unsigned long)&(((union param_u *)0)->p.frame_type )}, + {1, "show_frame", (unsigned long)&(((union param_u *)0)->p.show_frame )}, + {1, "e.r.r.o.r_resilient_mode", (unsigned long)&(((union param_u *)0)->p.error_resilient_mode )}, + {1, "refresh_frame_flags", (unsigned long)&(((union param_u *)0)->p.refresh_frame_flags )}, + {1, "showable_frame", (unsigned long)&(((union param_u *)0)->p.showable_frame )}, + {1, "current_frame_id", (unsigned long)&(((union param_u *)0)->p.current_frame_id )}, + {1, "frame_size_override_flag", (unsigned long)&(((union param_u *)0)->p.frame_size_override_flag )}, + {1, "order_hint", (unsigned long)&(((union param_u *)0)->p.order_hint )}, + {1, "primary_ref_frame", (unsigned long)&(((union param_u *)0)->p.primary_ref_frame )}, + {1, "frame_refs_short_signaling", (unsigned long)&(((union param_u *)0)->p.frame_refs_short_signaling )}, + {1, "frame_width", (unsigned long)&(((union param_u *)0)->p.frame_width )}, + {1, "dec_frame_width", (unsigned long)&(((union param_u *)0)->p.dec_frame_width )}, + {1, "frame_width_scaled", (unsigned long)&(((union param_u *)0)->p.frame_width_scaled )}, + {1, "frame_height", (unsigned long)&(((union param_u *)0)->p.frame_height )}, + {1, "reference_mode", (unsigned long)&(((union param_u *)0)->p.reference_mode )}, + {1, "update_parameters", (unsigned long)&(((union param_u *)0)->p.update_parameters )}, + {1, "film_grain_params_ref_idx", (unsigned long)&(((union param_u *)0)->p.film_grain_params_ref_idx )}, + {1, "allow_ref_frame_mvs", (unsigned long)&(((union param_u *)0)->p.allow_ref_frame_mvs )}, + {1, "lst_ref", (unsigned long)&(((union param_u *)0)->p.lst_ref )}, + {1, "gld_ref", (unsigned long)&(((union param_u *)0)->p.gld_ref )}, + {INTER_REFS_PER_FRAME, "remapped_ref_idx", (unsigned long)&(((union param_u *)0)->p.remapped_ref_idx[0] )}, + {INTER_REFS_PER_FRAME, "delta_frame_id_minus_1", (unsigned long)&(((union param_u *)0)->p.delta_frame_id_minus_1[0] )}, + {REF_FRAMES, "ref_order_hint", (unsigned long)&(((union param_u *)0)->p.ref_order_hint[0] )}, +}; + +void dump_params(AV1Decoder *pbi, union param_u *params) +{ + int i, j; + unsigned char *start_adr = (unsigned char*)params; + + pr_info("============ params:\n"); + for (i = 0; i < sizeof(param_dump_items) / sizeof(param_dump_items[0]); i++) { + for (j = 0; j < param_dump_items[i].size; j++) { + if (param_dump_items[i].size > 1) + pr_info("%s(%d): 0x%x\n", + param_dump_items[i].name, j, + *((unsigned short*)(start_adr + param_dump_items[i].adr_off + j * 2))); + else + pr_info("%s: 0x%x\n", param_dump_items[i].name, + *((unsigned short*)(start_adr + param_dump_items[i].adr_off + j * 2))); + } + } +} + +/*static void raw_write_image(AV1Decoder *pbi, PIC_BUFFER_CONFIG *sd) +{ + printf("$$$$$$$ output image\n"); +}*/ + +/* + return 0, need decoding data + 1, decoding done + -1, decoding error + +*/ +int av1_bufmgr_process(AV1Decoder *pbi, union param_u *params, + unsigned char new_compressed_data, int obu_type) +{ + AV1_COMMON *const cm = &pbi->common; + int j; + // Release any pending output frames from the previous decoder_decode call. + // We need to do this even if the decoder is being flushed or the input + // arguments are invalid. + BufferPool *const pool = cm->buffer_pool; + int frame_decoded; + av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "%s: pbi %p cm %p cur_frame %p\n", __func__, pbi, cm, cm->cur_frame); + av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "%s: new_compressed_data= %d\n", __func__, new_compressed_data); + for (j = 0; j < pbi->num_output_frames; j++) { + decrease_ref_count(pbi, pbi->output_frames[j], pool); + } + pbi->num_output_frames = 0; + // + if (new_compressed_data) { + if (assign_cur_frame_new_fb(cm) == NULL) { + cm->error.error_code = AOM_CODEC_MEM_ERROR; + return -1; + } + pbi->seen_frame_header = 0; + av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "New_compressed_data (%d)\n", new_compressed_data_count++); + + } + + frame_decoded = + aom_decode_frame_from_obus(pbi, params, obu_type); + + if (pbi->cur_obu_type == OBU_FRAME_HEADER || + pbi->cur_obu_type == OBU_REDUNDANT_FRAME_HEADER || + pbi->cur_obu_type == OBU_FRAME) { + if (av1_is_debug(AOM_DEBUG_PRINT_LIST_INFO)) { + pr_info("after bufmgr (frame_decoded %d seen_frame_header %d): ", + frame_decoded, pbi->seen_frame_header); + dump_buffer_status(pbi); + } + } + av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "%s: pbi %p cm %p cur_frame %p\n", __func__, pbi, cm, cm->cur_frame); + + return frame_decoded; + +} + +int av1_get_raw_frame(AV1Decoder *pbi, size_t index, PIC_BUFFER_CONFIG **sd) { + if (index >= pbi->num_output_frames) return -1; + *sd = &pbi->output_frames[index]->buf; + //*grain_params = &pbi->output_frames[index]->film_grain_params; + //aom_clear_system_state(); + return 0; +} + +int av1_bufmgr_postproc(AV1Decoder *pbi, unsigned char frame_decoded) +{ + PIC_BUFFER_CONFIG *sd; + int index; +#if 0 + if (frame_decoded) { + printf("before swap_frame_buffers: "); + dump_buffer_status(pbi); + } +#endif + swap_frame_buffers(pbi, frame_decoded); + if (frame_decoded) { + if (av1_is_debug(AOM_DEBUG_PRINT_LIST_INFO)) { + pr_info("after swap_frame_buffers: "); + dump_buffer_status(pbi); + } + } + if (frame_decoded) { + pbi->decoding_first_frame = 0; + } + + + for (index = 0;;index++) { + if (av1_get_raw_frame(pbi, index, &sd) < 0) + break; + av1_raw_write_image(pbi, sd); + } + return 0; +} + +int aom_realloc_frame_buffer(AV1_COMMON *cm, PIC_BUFFER_CONFIG *pic, + int width, int height, unsigned int order_hint) +{ + av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "%s, index 0x%x, width 0x%x, height 0x%x order_hint 0x%x\n", + __func__, pic->index, width, height, order_hint); + pic->y_crop_width = width; + pic->y_crop_height = height; + pic->order_hint = order_hint; + return 0; +} + + +unsigned char av1_frame_is_inter(const AV1_COMMON *const cm) { + unsigned char is_inter = cm->cur_frame && (cm->cur_frame->frame_type != KEY_FRAME) + && (cm->current_frame.frame_type != INTRA_ONLY_FRAME); + return is_inter; +} + +PIC_BUFFER_CONFIG *av1_get_ref_frame_spec_buf( + const AV1_COMMON *const cm, const MV_REFERENCE_FRAME ref_frame) { + RefCntBuffer *buf = get_ref_frame_buf(cm, ref_frame); + if (buf) { + buf->buf.order_hint = buf->order_hint; + return &(buf->buf); + } + return NULL; +} + +struct scale_factors *av1_get_ref_scale_factors( + AV1_COMMON *const cm, const MV_REFERENCE_FRAME ref_frame) +{ + return get_ref_scale_factors(cm, ref_frame); +} + +void av1_set_next_ref_frame_map(AV1Decoder *pbi) { + int ref_index = 0; + int mask; + AV1_COMMON *const cm = &pbi->common; + int check_on_show_existing_frame; + av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "%s, %d, mask 0x%x, show_existing_frame %d, reset_decoder_state %d\n", + __func__, pbi->camera_frame_header_ready, + cm->current_frame.refresh_frame_flags, + cm->show_existing_frame, + pbi->reset_decoder_state + ); + if (!pbi->camera_frame_header_ready) { + for (mask = cm->current_frame.refresh_frame_flags; mask; mask >>= 1) { + cm->next_used_ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index]; + ++ref_index; + } + + check_on_show_existing_frame = + !cm->show_existing_frame || pbi->reset_decoder_state; + for (; ref_index < REF_FRAMES && check_on_show_existing_frame; + ++ref_index) { + cm->next_used_ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index]; + } + } +} + +unsigned int av1_get_next_used_ref_info( + const AV1_COMMON *const cm, int i) { + /* + i = 0~1 orde_hint map + i = 2~10 size map[i-2] + */ + unsigned int info = 0; + int j; + if (i < 2) { + /*next_used_ref_frame_map has 8 items*/ + for (j = 0; j < 4; j++) { + RefCntBuffer *buf = + cm->next_used_ref_frame_map[(i * 4) + j]; + if (buf) + info |= ((buf->buf.order_hint & 0xff) + << (j * 8)); + } + } else if (i < 10) { + RefCntBuffer *buf = + cm->next_used_ref_frame_map[i-2]; + if (buf) + info = (buf->buf.y_crop_width << 16) | (buf->buf.y_crop_height & 0xffff); + } else { + for (j = 0; j < 4; j++) { + RefCntBuffer *buf = + cm->next_used_ref_frame_map[((i - 10) * 4) + j]; + if (buf) + info |= ((buf->buf.index & 0xff) + << (j * 8)); + } + } + return info; +} + +RefCntBuffer *av1_get_primary_ref_frame_buf( + const AV1_COMMON *const cm) +{ + return get_primary_ref_frame_buf(cm); +} diff --git a/drivers/frame_provider/decoder/vav1/av1_global.h b/drivers/frame_provider/decoder/vav1/av1_global.h new file mode 100644 index 0000000..06a527a --- a/dev/null +++ b/drivers/frame_provider/decoder/vav1/av1_global.h @@ -0,0 +1,2310 @@ +#ifndef AV1_GLOBAL_H_ +#define AV1_GLOBAL_H_ +#define AOM_AV1_MMU_DW +#ifndef HAVE_NEON +#define HAVE_NEON 0 +#endif +#ifndef CONFIG_ACCOUNTING +#define CONFIG_ACCOUNTING 0 +#endif +#ifndef CONFIG_INSPECTION +#define CONFIG_INSPECTION 0 +#endif +#ifndef CONFIG_LPF_MASK +#define CONFIG_LPF_MASK 0 +#endif +#ifndef CONFIG_SIZE_LIMIT +#define CONFIG_SIZE_LIMIT 0 +#endif + +#define SUPPORT_SCALE_FACTOR +#define USE_SCALED_WIDTH_FROM_UCODE +#define AML +#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC +#define AML_DEVICE +#endif +#ifdef BUFMGR_FOR_SIM +#define printf io_printf +#endif + +#ifndef INT_MAX +#define INT_MAX 0x7FFFFFFF +#endif +#define AOMMIN(x, y) (((x) < (y)) ? (x) : (y)) +#define AOMMAX(x, y) (((x) > (y)) ? (x) : (y)) + +//typedef char int8_t; +//#ifndef BUFMGR_FOR_SIM +typedef unsigned char uint8_t; +//#endif +typedef unsigned int uint32_t; +//typedef int int32_t; +//typedef long long int64_t; + +#ifdef AML +#define AOM_AV1_MMU +#define FILM_GRAIN_REG_SIZE 39 +typedef struct buff_s +{ + uint32_t buf_start; + uint32_t buf_size; + uint32_t buf_end; +} buff_t; + +typedef struct BuffInfo_s +{ + uint32_t max_width; + uint32_t max_height; + uint32_t start_adr; + uint32_t end_adr; + buff_t ipp; + buff_t sao_abv; + buff_t sao_vb; + buff_t short_term_rps; + buff_t vps; + buff_t seg_map; + buff_t daala_top; + buff_t sao_up; + buff_t swap_buf; + buff_t cdf_buf; + buff_t gmc_buf; + buff_t scalelut; + buff_t dblk_para; + buff_t dblk_data; + buff_t cdef_data; + buff_t ups_data; +#ifdef AOM_AV1_MMU + buff_t mmu_vbh; + buff_t cm_header; +#endif +#ifdef AOM_AV1_MMU_DW + buff_t mmu_vbh_dw; + buff_t cm_header_dw; +#endif + buff_t fgs_table; + buff_t mpred_above; + buff_t mpred_mv; + buff_t rpm; + buff_t lmem; +} BuffInfo_t; +#endif + +#define va_start(v,l) __builtin_va_start(v,l) +#define va_end(v) __builtin_va_end(v) +#define va_arg(v,l) __builtin_va_arg(v,l) +/* +mem.h +*/ +#if (defined(__GNUC__) && __GNUC__) || defined(__SUNPRO_C) +#define DECLARE_ALIGNED(n, typ, val) typ val __attribute__((aligned(n))) +#elif defined(_MSC_VER) +#define DECLARE_ALIGNED(n, typ, val) __declspec(align(n)) typ val +#else +#warning No alignment directives known for this compiler. +#define DECLARE_ALIGNED(n, typ, val) typ val +#endif + +/* Indicates that the usage of the specified variable has been audited to assure + * that it's safe to use uninitialized. Silences 'may be used uninitialized' + * warnings on gcc. + */ +#if defined(__GNUC__) && __GNUC__ +#define UNINITIALIZED_IS_SAFE(x) x = x +#else +#define UNINITIALIZED_IS_SAFE(x) x +#endif + +#if HAVE_NEON && defined(_MSC_VER) +#define __builtin_prefetch(x) +#endif + +/* Shift down with rounding for use when n >= 0, value >= 0 */ +#define ROUND_POWER_OF_TWO(value, n) (((value) + (((1 << (n)) >> 1))) >> (n)) + +/* Shift down with rounding for signed integers, for use when n >= 0 */ +#define ROUND_POWER_OF_TWO_SIGNED(value, n) \ + (((value) < 0) ? -ROUND_POWER_OF_TWO(-(value), (n)) \ + : ROUND_POWER_OF_TWO((value), (n))) + +/* Shift down with rounding for use when n >= 0, value >= 0 for (64 bit) */ +#define ROUND_POWER_OF_TWO_64(value, n) \ + (((value) + ((((int64_t)1 << (n)) >> 1))) >> (n)) +/* Shift down with rounding for signed integers, for use when n >= 0 (64 bit) */ +#define ROUND_POWER_OF_TWO_SIGNED_64(value, n) \ + (((value) < 0) ? -ROUND_POWER_OF_TWO_64(-(value), (n)) \ + : ROUND_POWER_OF_TWO_64((value), (n))) + +/* shift right or left depending on sign of n */ +#define RIGHT_SIGNED_SHIFT(value, n) \ + ((n) < 0 ? ((value) << (-(n))) : ((value) >> (n))) + +#define ALIGN_POWER_OF_TWO(value, n) \ + (((value) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1)) + +#define DIVIDE_AND_ROUND(x, y) (((x) + ((y) >> 1)) / (y)) + +#define CONVERT_TO_SHORTPTR(x) ((uint16_t *)(((uintptr_t)(x)) << 1)) +#define CONVERT_TO_BYTEPTR(x) ((uint8_t *)(((uintptr_t)(x)) >> 1)) + +#ifdef AML +#define TYPEDEF typedef +#define UENUM1BYTE(enumvar) enumvar +#define SENUM1BYTE(enumvar) enumvar +#define UENUM2BYTE(enumvar) enumvar +#define SENUM2BYTE(enumvar) enumvar +#define UENUM4BYTE(enumvar) enumvar +#define SENUM4BYTE(enumvar) enumvar + +#else +#define TYPEDEF +/*!\brief force enum to be unsigned 1 byte*/ +#define UENUM1BYTE(enumvar) \ + ; \ + typedef uint8_t enumvar + +/*!\brief force enum to be signed 1 byte*/ +#define SENUM1BYTE(enumvar) \ + ; \ + typedef int8_t enumvar + +/*!\brief force enum to be unsigned 2 byte*/ +#define UENUM2BYTE(enumvar) \ + ; \ + typedef uint16_t enumvar + +/*!\brief force enum to be signed 2 byte*/ +#define SENUM2BYTE(enumvar) \ + ; \ + typedef int16_t enumvar + +/*!\brief force enum to be unsigned 4 byte*/ +#define UENUM4BYTE(enumvar) \ + ; \ + typedef uint32_t enumvar + +/*!\brief force enum to be unsigned 4 byte*/ +#define SENUM4BYTE(enumvar) \ + ; \ + typedef int32_t enumvar +#endif + + +/* +#include "enums.h" +*/ +#undef MAX_SB_SIZE + +// Max superblock size +#define MAX_SB_SIZE_LOG2 7 +#define MAX_SB_SIZE (1 << MAX_SB_SIZE_LOG2) +#define MAX_SB_SQUARE (MAX_SB_SIZE * MAX_SB_SIZE) + +// Min superblock size +#define MIN_SB_SIZE_LOG2 6 + +// Pixels per Mode Info (MI) unit +#define MI_SIZE_LOG2 2 +#define MI_SIZE (1 << MI_SIZE_LOG2) + +// MI-units per max superblock (MI Block - MIB) +#define MAX_MIB_SIZE_LOG2 (MAX_SB_SIZE_LOG2 - MI_SIZE_LOG2) +#define MAX_MIB_SIZE (1 << MAX_MIB_SIZE_LOG2) + +// MI-units per min superblock +#define MIN_MIB_SIZE_LOG2 (MIN_SB_SIZE_LOG2 - MI_SIZE_LOG2) + +// Mask to extract MI offset within max MIB +#define MAX_MIB_MASK (MAX_MIB_SIZE - 1) + +// Maximum number of tile rows and tile columns +#define MAX_TILE_ROWS 64 +#define MAX_TILE_COLS 64 + +#define MAX_VARTX_DEPTH 2 + +#define MI_SIZE_64X64 (64 >> MI_SIZE_LOG2) +#define MI_SIZE_128X128 (128 >> MI_SIZE_LOG2) + +#define MAX_PALETTE_SQUARE (64 * 64) +// Maximum number of colors in a palette. +#define PALETTE_MAX_SIZE 8 +// Minimum number of colors in a palette. +#define PALETTE_MIN_SIZE 2 + +#define FRAME_OFFSET_BITS 5 +#define MAX_FRAME_DISTANCE ((1 << FRAME_OFFSET_BITS) - 1) + +// 4 frame filter levels: y plane vertical, y plane horizontal, +// u plane, and v plane +#define FRAME_LF_COUNT 4 +#define DEFAULT_DELTA_LF_MULTI 0 +#define MAX_MODE_LF_DELTAS 2 + +#define DIST_PRECISION_BITS 4 +#define DIST_PRECISION (1 << DIST_PRECISION_BITS) // 16 + +#define PROFILE_BITS 3 +// The following three profiles are currently defined. +// Profile 0. 8-bit and 10-bit 4:2:0 and 4:0:0 only. +// Profile 1. 8-bit and 10-bit 4:4:4 +// Profile 2. 8-bit and 10-bit 4:2:2 +// 12-bit 4:0:0, 4:2:2 and 4:4:4 +// Since we have three bits for the profiles, it can be extended later. +TYPEDEF enum { + PROFILE_0, + PROFILE_1, + PROFILE_2, + MAX_PROFILES, +} SENUM1BYTE(BITSTREAM_PROFILE); + +#define OP_POINTS_CNT_MINUS_1_BITS 5 +#define OP_POINTS_IDC_BITS 12 + +// Note: Some enums use the attribute 'packed' to use smallest possible integer +// type, so that we can save memory when they are used in structs/arrays. + +typedef enum ATTRIBUTE_PACKED { + BLOCK_4X4, + BLOCK_4X8, + BLOCK_8X4, + BLOCK_8X8, + BLOCK_8X16, + BLOCK_16X8, + BLOCK_16X16, + BLOCK_16X32, + BLOCK_32X16, + BLOCK_32X32, + BLOCK_32X64, + BLOCK_64X32, + BLOCK_64X64, + BLOCK_64X128, + BLOCK_128X64, + BLOCK_128X128, + BLOCK_4X16, + BLOCK_16X4, + BLOCK_8X32, + BLOCK_32X8, + BLOCK_16X64, + BLOCK_64X16, + BLOCK_SIZES_ALL, + BLOCK_SIZES = BLOCK_4X16, + BLOCK_INVALID = 255, + BLOCK_LARGEST = (BLOCK_SIZES - 1) +} BLOCK_SIZE2; + +// 4X4, 8X8, 16X16, 32X32, 64X64, 128X128 +#define SQR_BLOCK_SIZES 6 + +TYPEDEF enum { + PARTITION_NONE, + PARTITION_HORZ, + PARTITION_VERT, + PARTITION_SPLIT, + PARTITION_HORZ_A, // HORZ split and the top partition is split again + PARTITION_HORZ_B, // HORZ split and the bottom partition is split again + PARTITION_VERT_A, // VERT split and the left partition is split again + PARTITION_VERT_B, // VERT split and the right partition is split again + PARTITION_HORZ_4, // 4:1 horizontal partition + PARTITION_VERT_4, // 4:1 vertical partition + EXT_PARTITION_TYPES, + PARTITION_TYPES = PARTITION_SPLIT + 1, + PARTITION_INVALID = 255 +} UENUM1BYTE(PARTITION_TYPE); + +typedef char PARTITION_CONTEXT; +#define PARTITION_PLOFFSET 4 // number of probability models per block size +#define PARTITION_BLOCK_SIZES 5 +#define PARTITION_CONTEXTS (PARTITION_BLOCK_SIZES * PARTITION_PLOFFSET) + +// block transform size +TYPEDEF enum { + TX_4X4, // 4x4 transform + TX_8X8, // 8x8 transform + TX_16X16, // 16x16 transform + TX_32X32, // 32x32 transform + TX_64X64, // 64x64 transform + TX_4X8, // 4x8 transform + TX_8X4, // 8x4 transform + TX_8X16, // 8x16 transform + TX_16X8, // 16x8 transform + TX_16X32, // 16x32 transform + TX_32X16, // 32x16 transform + TX_32X64, // 32x64 transform + TX_64X32, // 64x32 transform + TX_4X16, // 4x16 transform + TX_16X4, // 16x4 transform + TX_8X32, // 8x32 transform + TX_32X8, // 32x8 transform + TX_16X64, // 16x64 transform + TX_64X16, // 64x16 transform + TX_SIZES_ALL, // Includes rectangular transforms + TX_SIZES = TX_4X8, // Does NOT include rectangular transforms + TX_SIZES_LARGEST = TX_64X64, + TX_INVALID = 255 // Invalid transform size +} UENUM1BYTE(TX_SIZE); + +#define TX_SIZE_LUMA_MIN (TX_4X4) +/* We don't need to code a transform size unless the allowed size is at least + one more than the minimum. */ +#define TX_SIZE_CTX_MIN (TX_SIZE_LUMA_MIN + 1) + +// Maximum tx_size categories +#define MAX_TX_CATS (TX_SIZES - TX_SIZE_CTX_MIN) +#define MAX_TX_DEPTH 2 + +#define MAX_TX_SIZE_LOG2 (6) +#define MAX_TX_SIZE (1 << MAX_TX_SIZE_LOG2) +#define MIN_TX_SIZE_LOG2 2 +#define MIN_TX_SIZE (1 << MIN_TX_SIZE_LOG2) +#define MAX_TX_SQUARE (MAX_TX_SIZE * MAX_TX_SIZE) + +// Pad 4 extra columns to remove horizontal availability check. +#define TX_PAD_HOR_LOG2 2 +#define TX_PAD_HOR 4 +// Pad 6 extra rows (2 on top and 4 on bottom) to remove vertical availability +// check. +#define TX_PAD_TOP 0 +#define TX_PAD_BOTTOM 4 +#define TX_PAD_VER (TX_PAD_TOP + TX_PAD_BOTTOM) +// Pad 16 extra bytes to avoid reading overflow in SIMD optimization. +#define TX_PAD_END 16 +#define TX_PAD_2D ((32 + TX_PAD_HOR) * (32 + TX_PAD_VER) + TX_PAD_END) + +// Number of maxium size transform blocks in the maximum size superblock +#define MAX_TX_BLOCKS_IN_MAX_SB_LOG2 ((MAX_SB_SIZE_LOG2 - MAX_TX_SIZE_LOG2) * 2) +#define MAX_TX_BLOCKS_IN_MAX_SB (1 << MAX_TX_BLOCKS_IN_MAX_SB_LOG2) + +// frame transform mode +TYPEDEF enum { + ONLY_4X4, // use only 4x4 transform + TX_MODE_LARGEST, // transform size is the largest possible for pu size + TX_MODE_SELECT, // transform specified for each block + TX_MODES, +} UENUM1BYTE(TX_MODE); + +// 1D tx types +TYPEDEF enum { + DCT_1D, + ADST_1D, + FLIPADST_1D, + IDTX_1D, + TX_TYPES_1D, +} UENUM1BYTE(TX_TYPE_1D); + +TYPEDEF enum { + DCT_DCT, // DCT in both horizontal and vertical + ADST_DCT, // ADST in vertical, DCT in horizontal + DCT_ADST, // DCT in vertical, ADST in horizontal + ADST_ADST, // ADST in both directions + FLIPADST_DCT, // FLIPADST in vertical, DCT in horizontal + DCT_FLIPADST, // DCT in vertical, FLIPADST in horizontal + FLIPADST_FLIPADST, // FLIPADST in both directions + ADST_FLIPADST, // ADST in vertical, FLIPADST in horizontal + FLIPADST_ADST, // FLIPADST in vertical, ADST in horizontal + IDTX, // Identity in both directions + V_DCT, // DCT in vertical, identity in horizontal + H_DCT, // Identity in vertical, DCT in horizontal + V_ADST, // ADST in vertical, identity in horizontal + H_ADST, // Identity in vertical, ADST in horizontal + V_FLIPADST, // FLIPADST in vertical, identity in horizontal + H_FLIPADST, // Identity in vertical, FLIPADST in horizontal + TX_TYPES, +} UENUM1BYTE(TX_TYPE); + +TYPEDEF enum { + REG_REG, + REG_SMOOTH, + REG_SHARP, + SMOOTH_REG, + SMOOTH_SMOOTH, + SMOOTH_SHARP, + SHARP_REG, + SHARP_SMOOTH, + SHARP_SHARP, +} UENUM1BYTE(DUAL_FILTER_TYPE); + +TYPEDEF enum { + // DCT only + EXT_TX_SET_DCTONLY, + // DCT + Identity only + EXT_TX_SET_DCT_IDTX, + // Discrete Trig transforms w/o flip (4) + Identity (1) + EXT_TX_SET_DTT4_IDTX, + // Discrete Trig transforms w/o flip (4) + Identity (1) + 1D Hor/vert DCT (2) + EXT_TX_SET_DTT4_IDTX_1DDCT, + // Discrete Trig transforms w/ flip (9) + Identity (1) + 1D Hor/Ver DCT (2) + EXT_TX_SET_DTT9_IDTX_1DDCT, + // Discrete Trig transforms w/ flip (9) + Identity (1) + 1D Hor/Ver (6) + EXT_TX_SET_ALL16, + EXT_TX_SET_TYPES +} UENUM1BYTE(TxSetType); + +#define IS_2D_TRANSFORM(tx_type) (tx_type < IDTX) + +#define EXT_TX_SIZES 4 // number of sizes that use extended transforms +#define EXT_TX_SETS_INTER 4 // Sets of transform selections for INTER +#define EXT_TX_SETS_INTRA 3 // Sets of transform selections for INTRA + +TYPEDEF enum { + AOM_LAST_FLAG = 1 << 0, + AOM_LAST2_FLAG = 1 << 1, + AOM_LAST3_FLAG = 1 << 2, + AOM_GOLD_FLAG = 1 << 3, + AOM_BWD_FLAG = 1 << 4, + AOM_ALT2_FLAG = 1 << 5, + AOM_ALT_FLAG = 1 << 6, + AOM_REFFRAME_ALL = (1 << 7) - 1 +} UENUM1BYTE(AOM_REFFRAME); + +TYPEDEF enum { + UNIDIR_COMP_REFERENCE, + BIDIR_COMP_REFERENCE, + COMP_REFERENCE_TYPES, +} UENUM1BYTE(COMP_REFERENCE_TYPE); + +/*enum { PLANE_TYPE_Y, PLANE_TYPE_UV, PLANE_TYPES } UENUM1BYTE(PLANE_TYPE);*/ + +#define CFL_ALPHABET_SIZE_LOG2 4 +#define CFL_ALPHABET_SIZE (1 << CFL_ALPHABET_SIZE_LOG2) +#define CFL_MAGS_SIZE ((2 << CFL_ALPHABET_SIZE_LOG2) + 1) +#define CFL_IDX_U(idx) (idx >> CFL_ALPHABET_SIZE_LOG2) +#define CFL_IDX_V(idx) (idx & (CFL_ALPHABET_SIZE - 1)) + +/*enum { CFL_PRED_U, CFL_PRED_V, CFL_PRED_PLANES } UENUM1BYTE(CFL_PRED_TYPE);*/ + +TYPEDEF enum { + CFL_SIGN_ZERO, + CFL_SIGN_NEG, + CFL_SIGN_POS, + CFL_SIGNS +} UENUM1BYTE(CFL_SIGN_TYPE); + +TYPEDEF enum { + CFL_DISALLOWED, + CFL_ALLOWED, + CFL_ALLOWED_TYPES +} UENUM1BYTE(CFL_ALLOWED_TYPE); + +// CFL_SIGN_ZERO,CFL_SIGN_ZERO is invalid +#define CFL_JOINT_SIGNS (CFL_SIGNS * CFL_SIGNS - 1) +// CFL_SIGN_U is equivalent to (js + 1) / 3 for js in 0 to 8 +#define CFL_SIGN_U(js) (((js + 1) * 11) >> 5) +// CFL_SIGN_V is equivalent to (js + 1) % 3 for js in 0 to 8 +#define CFL_SIGN_V(js) ((js + 1) - CFL_SIGNS * CFL_SIGN_U(js)) + +// There is no context when the alpha for a given plane is zero. +// So there are 2 fewer contexts than joint signs. +#define CFL_ALPHA_CONTEXTS (CFL_JOINT_SIGNS + 1 - CFL_SIGNS) +#define CFL_CONTEXT_U(js) (js + 1 - CFL_SIGNS) +// Also, the contexts are symmetric under swapping the planes. +#define CFL_CONTEXT_V(js) \ + (CFL_SIGN_V(js) * CFL_SIGNS + CFL_SIGN_U(js) - CFL_SIGNS) + +TYPEDEF enum { + PALETTE_MAP, + COLOR_MAP_TYPES, +} UENUM1BYTE(COLOR_MAP_TYPE); + +TYPEDEF enum { + TWO_COLORS, + THREE_COLORS, + FOUR_COLORS, + FIVE_COLORS, + SIX_COLORS, + SEVEN_COLORS, + EIGHT_COLORS, + PALETTE_SIZES +} UENUM1BYTE(PALETTE_SIZE); + +TYPEDEF enum { + PALETTE_COLOR_ONE, + PALETTE_COLOR_TWO, + PALETTE_COLOR_THREE, + PALETTE_COLOR_FOUR, + PALETTE_COLOR_FIVE, + PALETTE_COLOR_SIX, + PALETTE_COLOR_SEVEN, + PALETTE_COLOR_EIGHT, + PALETTE_COLORS +} UENUM1BYTE(PALETTE_COLOR); + +// Note: All directional predictors must be between V_PRED and D67_PRED (both +// inclusive). +TYPEDEF enum { + DC_PRED, // Average of above and left pixels + V_PRED, // Vertical + H_PRED, // Horizontal + D45_PRED, // Directional 45 degree + D135_PRED, // Directional 135 degree + D113_PRED, // Directional 113 degree + D157_PRED, // Directional 157 degree + D203_PRED, // Directional 203 degree + D67_PRED, // Directional 67 degree + SMOOTH_PRED, // Combination of horizontal and vertical interpolation + SMOOTH_V_PRED, // Vertical interpolation + SMOOTH_H_PRED, // Horizontal interpolation + PAETH_PRED, // Predict from the direction of smallest gradient + NEARESTMV, + NEARMV, + GLOBALMV, + NEWMV, + // Compound ref compound modes + NEAREST_NEARESTMV, + NEAR_NEARMV, + NEAREST_NEWMV, + NEW_NEARESTMV, + NEAR_NEWMV, + NEW_NEARMV, + GLOBAL_GLOBALMV, + NEW_NEWMV, + MB_MODE_COUNT, + INTRA_MODE_START = DC_PRED, + INTRA_MODE_END = NEARESTMV, + INTRA_MODE_NUM = INTRA_MODE_END - INTRA_MODE_START, + SINGLE_INTER_MODE_START = NEARESTMV, + SINGLE_INTER_MODE_END = NEAREST_NEARESTMV, + SINGLE_INTER_MODE_NUM = SINGLE_INTER_MODE_END - SINGLE_INTER_MODE_START, + COMP_INTER_MODE_START = NEAREST_NEARESTMV, + COMP_INTER_MODE_END = MB_MODE_COUNT, + COMP_INTER_MODE_NUM = COMP_INTER_MODE_END - COMP_INTER_MODE_START, + INTER_MODE_START = NEARESTMV, + INTER_MODE_END = MB_MODE_COUNT, + INTRA_MODES = PAETH_PRED + 1, // PAETH_PRED has to be the last intra mode. + INTRA_INVALID = MB_MODE_COUNT // For uv_mode in inter blocks +} UENUM1BYTE(PREDICTION_MODE); + +// TODO(ltrudeau) Do we really want to pack this? +// TODO(ltrudeau) Do we match with PREDICTION_MODE? +TYPEDEF enum { + UV_DC_PRED, // Average of above and left pixels + UV_V_PRED, // Vertical + UV_H_PRED, // Horizontal + UV_D45_PRED, // Directional 45 degree + UV_D135_PRED, // Directional 135 degree + UV_D113_PRED, // Directional 113 degree + UV_D157_PRED, // Directional 157 degree + UV_D203_PRED, // Directional 203 degree + UV_D67_PRED, // Directional 67 degree + UV_SMOOTH_PRED, // Combination of horizontal and vertical interpolation + UV_SMOOTH_V_PRED, // Vertical interpolation + UV_SMOOTH_H_PRED, // Horizontal interpolation + UV_PAETH_PRED, // Predict from the direction of smallest gradient + UV_CFL_PRED, // Chroma-from-Luma + UV_INTRA_MODES, + UV_MODE_INVALID, // For uv_mode in inter blocks +} UENUM1BYTE(UV_PREDICTION_MODE); + +TYPEDEF enum { + SIMPLE_TRANSLATION, + OBMC_CAUSAL, // 2-sided OBMC + WARPED_CAUSAL, // 2-sided WARPED + MOTION_MODES +} UENUM1BYTE(MOTION_MODE); + +TYPEDEF enum { + II_DC_PRED, + II_V_PRED, + II_H_PRED, + II_SMOOTH_PRED, + INTERINTRA_MODES +} UENUM1BYTE(INTERINTRA_MODE); + +TYPEDEF enum { + COMPOUND_AVERAGE, + COMPOUND_DISTWTD, + COMPOUND_WEDGE, + COMPOUND_DIFFWTD, + COMPOUND_TYPES, + MASKED_COMPOUND_TYPES = 2, +} UENUM1BYTE(COMPOUND_TYPE); + +TYPEDEF enum { + FILTER_DC_PRED, + FILTER_V_PRED, + FILTER_H_PRED, + FILTER_D157_PRED, + FILTER_PAETH_PRED, + FILTER_INTRA_MODES, +} UENUM1BYTE(FILTER_INTRA_MODE); + +TYPEDEF enum { + SEQ_LEVEL_2_0, + SEQ_LEVEL_2_1, + SEQ_LEVEL_2_2, + SEQ_LEVEL_2_3, + SEQ_LEVEL_3_0, + SEQ_LEVEL_3_1, + SEQ_LEVEL_3_2, + SEQ_LEVEL_3_3, + SEQ_LEVEL_4_0, + SEQ_LEVEL_4_1, + SEQ_LEVEL_4_2, + SEQ_LEVEL_4_3, + SEQ_LEVEL_5_0, + SEQ_LEVEL_5_1, + SEQ_LEVEL_5_2, + SEQ_LEVEL_5_3, + SEQ_LEVEL_6_0, + SEQ_LEVEL_6_1, + SEQ_LEVEL_6_2, + SEQ_LEVEL_6_3, + SEQ_LEVEL_7_0, + SEQ_LEVEL_7_1, + SEQ_LEVEL_7_2, + SEQ_LEVEL_7_3, + SEQ_LEVELS, + SEQ_LEVEL_MAX = 31 +} UENUM1BYTE(AV1_LEVEL); + +#define LEVEL_BITS 5 + +#define DIRECTIONAL_MODES 8 +#define MAX_ANGLE_DELTA 3 +#define ANGLE_STEP 3 + +#define INTER_MODES (1 + NEWMV - NEARESTMV) + +#define INTER_COMPOUND_MODES (1 + NEW_NEWMV - NEAREST_NEARESTMV) + +#define SKIP_CONTEXTS 3 +#define SKIP_MODE_CONTEXTS 3 + +#define COMP_INDEX_CONTEXTS 6 +#define COMP_GROUP_IDX_CONTEXTS 6 + +#define NMV_CONTEXTS 3 + +#define NEWMV_MODE_CONTEXTS 6 +#define GLOBALMV_MODE_CONTEXTS 2 +#define REFMV_MODE_CONTEXTS 6 +#define DRL_MODE_CONTEXTS 3 + +#define GLOBALMV_OFFSET 3 +#define REFMV_OFFSET 4 + +#define NEWMV_CTX_MASK ((1 << GLOBALMV_OFFSET) - 1) +#define GLOBALMV_CTX_MASK ((1 << (REFMV_OFFSET - GLOBALMV_OFFSET)) - 1) +#define REFMV_CTX_MASK ((1 << (8 - REFMV_OFFSET)) - 1) + +#define COMP_NEWMV_CTXS 5 +#define INTER_MODE_CONTEXTS 8 + +#define DELTA_Q_SMALL 3 +#define DELTA_Q_PROBS (DELTA_Q_SMALL) +#define DEFAULT_DELTA_Q_RES_PERCEPTUAL 4 +#define DEFAULT_DELTA_Q_RES_OBJECTIVE 4 + +#define DELTA_LF_SMALL 3 +#define DELTA_LF_PROBS (DELTA_LF_SMALL) +#define DEFAULT_DELTA_LF_RES 2 + +/* Segment Feature Masks */ +#define MAX_MV_REF_CANDIDATES 2 + +#define MAX_REF_MV_STACK_SIZE 8 +#define REF_CAT_LEVEL 640 + +#define INTRA_INTER_CONTEXTS 4 +#define COMP_INTER_CONTEXTS 5 +#define REF_CONTEXTS 3 + +#define COMP_REF_TYPE_CONTEXTS 5 +#define UNI_COMP_REF_CONTEXTS 3 + +#define TXFM_PARTITION_CONTEXTS ((TX_SIZES - TX_8X8) * 6 - 3) +#ifdef ORI_CODE +typedef uint8_t TXFM_CONTEXT; +#endif +// An enum for single reference types (and some derived values). +enum { + NONE_FRAME = -1, + INTRA_FRAME, + LAST_FRAME, + LAST2_FRAME, + LAST3_FRAME, + GOLDEN_FRAME, + BWDREF_FRAME, + ALTREF2_FRAME, + ALTREF_FRAME, + REF_FRAMES, + + // Extra/scratch reference frame. It may be: + // - used to update the ALTREF2_FRAME ref (see lshift_bwd_ref_frames()), or + // - updated from ALTREF2_FRAME ref (see rshift_bwd_ref_frames()). + EXTREF_FRAME = REF_FRAMES, + + // Number of inter (non-intra) reference types. + INTER_REFS_PER_FRAME = ALTREF_FRAME - LAST_FRAME + 1, + + // Number of forward (aka past) reference types. + FWD_REFS = GOLDEN_FRAME - LAST_FRAME + 1, + + // Number of backward (aka future) reference types. + BWD_REFS = ALTREF_FRAME - BWDREF_FRAME + 1, + + SINGLE_REFS = FWD_REFS + BWD_REFS, +}; + +#define REF_FRAMES_LOG2 3 + +// REF_FRAMES for the cm->ref_frame_map array, 1 scratch frame for the new +// frame in cm->cur_frame, INTER_REFS_PER_FRAME for scaled references on the +// encoder in the cpi->scaled_ref_buf array. +#define FRAME_BUFFERS (REF_FRAMES + 1 + INTER_REFS_PER_FRAME) + +#define FWD_RF_OFFSET(ref) (ref - LAST_FRAME) +#define BWD_RF_OFFSET(ref) (ref - BWDREF_FRAME) + +TYPEDEF enum { + LAST_LAST2_FRAMES, // { LAST_FRAME, LAST2_FRAME } + LAST_LAST3_FRAMES, // { LAST_FRAME, LAST3_FRAME } + LAST_GOLDEN_FRAMES, // { LAST_FRAME, GOLDEN_FRAME } + BWDREF_ALTREF_FRAMES, // { BWDREF_FRAME, ALTREF_FRAME } + LAST2_LAST3_FRAMES, // { LAST2_FRAME, LAST3_FRAME } + LAST2_GOLDEN_FRAMES, // { LAST2_FRAME, GOLDEN_FRAME } + LAST3_GOLDEN_FRAMES, // { LAST3_FRAME, GOLDEN_FRAME } + BWDREF_ALTREF2_FRAMES, // { BWDREF_FRAME, ALTREF2_FRAME } + ALTREF2_ALTREF_FRAMES, // { ALTREF2_FRAME, ALTREF_FRAME } + TOTAL_UNIDIR_COMP_REFS, + // NOTE: UNIDIR_COMP_REFS is the number of uni-directional reference pairs + // that are explicitly signaled. + UNIDIR_COMP_REFS = BWDREF_ALTREF_FRAMES + 1, +} UENUM1BYTE(UNIDIR_COMP_REF); + +#define TOTAL_COMP_REFS (FWD_REFS * BWD_REFS + TOTAL_UNIDIR_COMP_REFS) + +#define COMP_REFS (FWD_REFS * BWD_REFS + UNIDIR_COMP_REFS) + +// NOTE: A limited number of unidirectional reference pairs can be signalled for +// compound prediction. The use of skip mode, on the other hand, makes it +// possible to have a reference pair not listed for explicit signaling. +#define MODE_CTX_REF_FRAMES (REF_FRAMES + TOTAL_COMP_REFS) + +// Note: It includes single and compound references. So, it can take values from +// NONE_FRAME to (MODE_CTX_REF_FRAMES - 1). Hence, it is not defined as an enum. +typedef int8_t MV_REFERENCE_FRAME; + +TYPEDEF enum { + RESTORE_NONE, + RESTORE_WIENER, + RESTORE_SGRPROJ, + RESTORE_SWITCHABLE, + RESTORE_SWITCHABLE_TYPES = RESTORE_SWITCHABLE, + RESTORE_TYPES = 4, +} UENUM1BYTE(RestorationType); + +// Picture prediction structures (0-12 are predefined) in scalability metadata. +TYPEDEF enum { + SCALABILITY_L1T2 = 0, + SCALABILITY_L1T3 = 1, + SCALABILITY_L2T1 = 2, + SCALABILITY_L2T2 = 3, + SCALABILITY_L2T3 = 4, + SCALABILITY_S2T1 = 5, + SCALABILITY_S2T2 = 6, + SCALABILITY_S2T3 = 7, + SCALABILITY_L2T1h = 8, + SCALABILITY_L2T2h = 9, + SCALABILITY_L2T3h = 10, + SCALABILITY_S2T1h = 11, + SCALABILITY_S2T2h = 12, + SCALABILITY_S2T3h = 13, + SCALABILITY_SS = 14 +} UENUM1BYTE(SCALABILITY_STRUCTURES); + +#define SUPERRES_SCALE_BITS 3 +#define SUPERRES_SCALE_DENOMINATOR_MIN (SCALE_NUMERATOR + 1) + +// In large_scale_tile coding, external references are used. +#define MAX_EXTERNAL_REFERENCES 128 +#define MAX_TILES 512 + + +#define CONFIG_MULTITHREAD 0 +#define CONFIG_ENTROPY_STATS 0 + +#define CONFIG_MAX_DECODE_PROFILE 2 + +/* +from: +seg_common.h +*/ +#ifdef ORI_CODE + +#define MAX_SEGMENTS 8 +#define SEG_TREE_PROBS (MAX_SEGMENTS - 1) + +#define SEG_TEMPORAL_PRED_CTXS 3 +#define SPATIAL_PREDICTION_PROBS 3 + +enum { + SEG_LVL_ALT_Q, // Use alternate Quantizer .... + SEG_LVL_ALT_LF_Y_V, // Use alternate loop filter value on y plane vertical + SEG_LVL_ALT_LF_Y_H, // Use alternate loop filter value on y plane horizontal + SEG_LVL_ALT_LF_U, // Use alternate loop filter value on u plane + SEG_LVL_ALT_LF_V, // Use alternate loop filter value on v plane + SEG_LVL_REF_FRAME, // Optional Segment reference frame + SEG_LVL_SKIP, // Optional Segment (0,0) + skip mode + SEG_LVL_GLOBALMV, + SEG_LVL_MAX +} UENUM1BYTE(SEG_LVL_FEATURES); + +struct segmentation { + uint8_t enabled; + uint8_t update_map; + uint8_t update_data; + uint8_t temporal_update; + + int16_t feature_data[MAX_SEGMENTS][SEG_LVL_MAX]; + unsigned int feature_mask[MAX_SEGMENTS]; + int last_active_segid; // The highest numbered segment id that has some + // enabled feature. + uint8_t segid_preskip; // Whether the segment id will be read before the + // skip syntax element. + // 1: the segment id will be read first. + // 0: the skip syntax element will be read first. +}; + +/* +from av1_loopfilter.h +*/ +#define MAX_LOOP_FILTER 63 + + +/* from +quant_common.h: +*/ +#define MAXQ 255 + +#endif + +/* +from: +aom/av1/common/common.h +*/ +#define av1_zero(dest) memset(&(dest), 0, sizeof(dest)) +#define av1_zero_array(dest, n) memset(dest, 0, n * sizeof(*(dest))) +/* +from: +aom/av1/common/alloccommon.h +*/ +#define INVALID_IDX -1 // Invalid buffer index. + +/* +from: +aom/av1/common/timing.h +*/ +typedef struct aom_timing { + uint32_t num_units_in_display_tick; + uint32_t time_scale; + int equal_picture_interval; + uint32_t num_ticks_per_picture; +} aom_timing_info_t; + +typedef struct aom_dec_model_info { + uint32_t num_units_in_decoding_tick; + int encoder_decoder_buffer_delay_length; + int buffer_removal_time_length; + int frame_presentation_time_length; +} aom_dec_model_info_t; + +typedef struct aom_dec_model_op_parameters { + int decoder_model_param_present_flag; + int64_t bitrate; + int64_t buffer_size; + uint32_t decoder_buffer_delay; + uint32_t encoder_buffer_delay; + int low_delay_mode_flag; + int display_model_param_present_flag; + int initial_display_delay; +} aom_dec_model_op_parameters_t; + +typedef struct aom_op_timing_info_t { + uint32_t buffer_removal_time; +} aom_op_timing_info_t; +/* +from: +aom/aom_codec.h +*/ +/*!\brief OBU types. */ +typedef enum { + OBU_SEQUENCE_HEADER = 1, + OBU_TEMPORAL_DELIMITER = 2, + OBU_FRAME_HEADER = 3, + OBU_TILE_GROUP = 4, + OBU_METADATA = 5, + OBU_FRAME = 6, + OBU_REDUNDANT_FRAME_HEADER = 7, + OBU_TILE_LIST = 8, + OBU_PADDING = 15, +} OBU_TYPE; + +typedef enum aom_bit_depth { + AOM_BITS_8 = 8, /**< 8 bits */ + AOM_BITS_10 = 10, /**< 10 bits */ + AOM_BITS_12 = 12, /**< 12 bits */ +} aom_bit_depth_t; + +/*!\brief Algorithm return codes */ +typedef enum { + /*!\brief Operation completed without error */ + AOM_CODEC_OK, + + /*!\brief Unspecified error */ + AOM_CODEC_ERROR, + + /*!\brief Memory operation failed */ + AOM_CODEC_MEM_ERROR, + + /*!\brief ABI version mismatch */ + AOM_CODEC_ABI_MISMATCH, + + /*!\brief Algorithm does not have required capability */ + AOM_CODEC_INCAPABLE, + + /*!\brief The given bitstream is not supported. + * + * The bitstream was unable to be parsed at the highest level. The decoder + * is unable to proceed. This error \ref SHOULD be treated as fatal to the + * stream. */ + AOM_CODEC_UNSUP_BITSTREAM, + + /*!\brief Encoded bitstream uses an unsupported feature + * + * The decoder does not implement a feature required by the encoder. This + * return code should only be used for features that prevent future + * pictures from being properly decoded. This error \ref MAY be treated as + * fatal to the stream or \ref MAY be treated as fatal to the current GOP. + */ + AOM_CODEC_UNSUP_FEATURE, + + /*!\brief The coded data for this stream is corrupt or incomplete + * + * There was a problem decoding the current frame. This return code + * should only be used for failures that prevent future pictures from + * being properly decoded. This error \ref MAY be treated as fatal to the + * stream or \ref MAY be treated as fatal to the current GOP. If decoding + * is continued for the current GOP, artifacts may be present. + */ + AOM_CODEC_CORRUPT_FRAME, + + /*!\brief An application-supplied parameter is not valid. + * + */ + AOM_CODEC_INVALID_PARAM, + + /*!\brief An iterator reached the end of list. + * + */ + AOM_CODEC_LIST_END + +} aom_codec_err_t; + +typedef struct cfg_options { + /*!\brief Reflects if ext_partition should be enabled + * + * If this value is non-zero it enabled the feature + */ + unsigned int ext_partition; +} cfg_options_t; + +/* +from: +aom/av1/common/obu_util.h +*/ +typedef struct { + size_t size; // Size (1 or 2 bytes) of the OBU header (including the + // optional OBU extension header) in the bitstream. + OBU_TYPE type; + int has_size_field; + int has_extension; + // The following fields come from the OBU extension header and therefore are + // only used if has_extension is true. + int temporal_layer_id; + int spatial_layer_id; +} ObuHeader; + + +/* +from: +aom/internal/aom_codec_internal.h +*/ + +struct aom_internal_error_info { + aom_codec_err_t error_code; + int has_detail; + char detail[80]; + int setjmp; // Boolean: whether 'jmp' is valid. +#ifdef ORI_CODE + jmp_buf jmp; +#endif +}; + +/* +from: +aom/aom_frame_buffer.h +*/ +typedef struct aom_codec_frame_buffer { + uint8_t *data; /**< Pointer to the data buffer */ + size_t size; /**< Size of data in bytes */ + void *priv; /**< Frame's private data */ +} aom_codec_frame_buffer_t; + +/* +from: +aom/aom_image.h +*/ +#define AOM_IMAGE_ABI_VERSION (5) /**<\hideinitializer*/ + +#define AOM_IMG_FMT_PLANAR 0x100 /**< Image is a planar format. */ +#define AOM_IMG_FMT_UV_FLIP 0x200 /**< V plane precedes U in memory. */ +/** 0x400 used to signal alpha channel, skipping for backwards compatibility. */ +#define AOM_IMG_FMT_HIGHBITDEPTH 0x800 /**< Image uses 16bit framebuffer. */ + +/*!\brief List of supported image formats */ +typedef enum aom_img_fmt { + AOM_IMG_FMT_NONE, + AOM_IMG_FMT_YV12 = + AOM_IMG_FMT_PLANAR | AOM_IMG_FMT_UV_FLIP | 1, /**< planar YVU */ + AOM_IMG_FMT_I420 = AOM_IMG_FMT_PLANAR | 2, + AOM_IMG_FMT_AOMYV12 = AOM_IMG_FMT_PLANAR | AOM_IMG_FMT_UV_FLIP | + 3, /** < planar 4:2:0 format with aom color space */ + AOM_IMG_FMT_AOMI420 = AOM_IMG_FMT_PLANAR | 4, + AOM_IMG_FMT_I422 = AOM_IMG_FMT_PLANAR | 5, + AOM_IMG_FMT_I444 = AOM_IMG_FMT_PLANAR | 6, + AOM_IMG_FMT_I42016 = AOM_IMG_FMT_I420 | AOM_IMG_FMT_HIGHBITDEPTH, + AOM_IMG_FMT_YV1216 = AOM_IMG_FMT_YV12 | AOM_IMG_FMT_HIGHBITDEPTH, + AOM_IMG_FMT_I42216 = AOM_IMG_FMT_I422 | AOM_IMG_FMT_HIGHBITDEPTH, + AOM_IMG_FMT_I44416 = AOM_IMG_FMT_I444 | AOM_IMG_FMT_HIGHBITDEPTH, +} aom_img_fmt_t; /**< alias for enum aom_img_fmt */ + +/*!\brief List of supported color primaries */ +typedef enum aom_color_primaries { + AOM_CICP_CP_RESERVED_0 = 0, /**< For future use */ + AOM_CICP_CP_BT_709 = 1, /**< BT.709 */ + AOM_CICP_CP_UNSPECIFIED = 2, /**< Unspecified */ + AOM_CICP_CP_RESERVED_3 = 3, /**< For future use */ + AOM_CICP_CP_BT_470_M = 4, /**< BT.470 System M (historical) */ + AOM_CICP_CP_BT_470_B_G = 5, /**< BT.470 System B, G (historical) */ + AOM_CICP_CP_BT_601 = 6, /**< BT.601 */ + AOM_CICP_CP_SMPTE_240 = 7, /**< SMPTE 240 */ + AOM_CICP_CP_GENERIC_FILM = + 8, /**< Generic film (color filters using illuminant C) */ + AOM_CICP_CP_BT_2020 = 9, /**< BT.2020, BT.2100 */ + AOM_CICP_CP_XYZ = 10, /**< SMPTE 428 (CIE 1921 XYZ) */ + AOM_CICP_CP_SMPTE_431 = 11, /**< SMPTE RP 431-2 */ + AOM_CICP_CP_SMPTE_432 = 12, /**< SMPTE EG 432-1 */ + AOM_CICP_CP_RESERVED_13 = 13, /**< For future use (values 13 - 21) */ + AOM_CICP_CP_EBU_3213 = 22, /**< EBU Tech. 3213-E */ + AOM_CICP_CP_RESERVED_23 = 23 /**< For future use (values 23 - 255) */ +} aom_color_primaries_t; /**< alias for enum aom_color_primaries */ + +/*!\brief List of supported transfer functions */ +typedef enum aom_transfer_characteristics { + AOM_CICP_TC_RESERVED_0 = 0, /**< For future use */ + AOM_CICP_TC_BT_709 = 1, /**< BT.709 */ + AOM_CICP_TC_UNSPECIFIED = 2, /**< Unspecified */ + AOM_CICP_TC_RESERVED_3 = 3, /**< For future use */ + AOM_CICP_TC_BT_470_M = 4, /**< BT.470 System M (historical) */ + AOM_CICP_TC_BT_470_B_G = 5, /**< BT.470 System B, G (historical) */ + AOM_CICP_TC_BT_601 = 6, /**< BT.601 */ + AOM_CICP_TC_SMPTE_240 = 7, /**< SMPTE 240 M */ + AOM_CICP_TC_LINEAR = 8, /**< Linear */ + AOM_CICP_TC_LOG_100 = 9, /**< Logarithmic (100 : 1 range) */ + AOM_CICP_TC_LOG_100_SQRT10 = + 10, /**< Logarithmic (100 * Sqrt(10) : 1 range) */ + AOM_CICP_TC_IEC_61966 = 11, /**< IEC 61966-2-4 */ + AOM_CICP_TC_BT_1361 = 12, /**< BT.1361 */ + AOM_CICP_TC_SRGB = 13, /**< sRGB or sYCC*/ + AOM_CICP_TC_BT_2020_10_BIT = 14, /**< BT.2020 10-bit systems */ + AOM_CICP_TC_BT_2020_12_BIT = 15, /**< BT.2020 12-bit systems */ + AOM_CICP_TC_SMPTE_2084 = 16, /**< SMPTE ST 2084, ITU BT.2100 PQ */ + AOM_CICP_TC_SMPTE_428 = 17, /**< SMPTE ST 428 */ + AOM_CICP_TC_HLG = 18, /**< BT.2100 HLG, ARIB STD-B67 */ + AOM_CICP_TC_RESERVED_19 = 19 /**< For future use (values 19-255) */ +} aom_transfer_characteristics_t; /**< alias for enum aom_transfer_function */ + +/*!\brief List of supported matrix coefficients */ +typedef enum aom_matrix_coefficients { + AOM_CICP_MC_IDENTITY = 0, /**< Identity matrix */ + AOM_CICP_MC_BT_709 = 1, /**< BT.709 */ + AOM_CICP_MC_UNSPECIFIED = 2, /**< Unspecified */ + AOM_CICP_MC_RESERVED_3 = 3, /**< For future use */ + AOM_CICP_MC_FCC = 4, /**< US FCC 73.628 */ + AOM_CICP_MC_BT_470_B_G = 5, /**< BT.470 System B, G (historical) */ + AOM_CICP_MC_BT_601 = 6, /**< BT.601 */ + AOM_CICP_MC_SMPTE_240 = 7, /**< SMPTE 240 M */ + AOM_CICP_MC_SMPTE_YCGCO = 8, /**< YCgCo */ + AOM_CICP_MC_BT_2020_NCL = + 9, /**< BT.2020 non-constant luminance, BT.2100 YCbCr */ + AOM_CICP_MC_BT_2020_CL = 10, /**< BT.2020 constant luminance */ + AOM_CICP_MC_SMPTE_2085 = 11, /**< SMPTE ST 2085 YDzDx */ + AOM_CICP_MC_CHROMAT_NCL = + 12, /**< Chromaticity-derived non-constant luminance */ + AOM_CICP_MC_CHROMAT_CL = 13, /**< Chromaticity-derived constant luminance */ + AOM_CICP_MC_ICTCP = 14, /**< BT.2100 ICtCp */ + AOM_CICP_MC_RESERVED_15 = 15 /**< For future use (values 15-255) */ +} aom_matrix_coefficients_t; + +/*!\brief List of supported color range */ +typedef enum aom_color_range { + AOM_CR_STUDIO_RANGE = 0, /**< Y [16..235], UV [16..240] */ + AOM_CR_FULL_RANGE = 1 /**< YUV/RGB [0..255] */ +} aom_color_range_t; /**< alias for enum aom_color_range */ + +/*!\brief List of chroma sample positions */ +typedef enum aom_chroma_sample_position { + AOM_CSP_UNKNOWN = 0, /**< Unknown */ + AOM_CSP_VERTICAL = 1, /**< Horizontally co-located with luma(0, 0)*/ + /**< sample, between two vertical samples */ + AOM_CSP_COLOCATED = 2, /**< Co-located with luma(0, 0) sample */ + AOM_CSP_RESERVED = 3 /**< Reserved value */ +} aom_chroma_sample_position_t; /**< alias for enum aom_transfer_function */ + +/* +from: +aom/aom_scale/yv12config.h +*/ +typedef struct PIC_BUFFER_CONFIG_s { + union { + struct { + int y_width; + int uv_width; + }; + int widths[2]; + }; + union { + struct { + int y_height; + int uv_height; + }; + int heights[2]; + }; + union { + struct { + int y_crop_width; + int uv_crop_width; + }; + int crop_widths[2]; + }; + union { + struct { + int y_crop_height; + int uv_crop_height; + }; + int crop_heights[2]; + }; + union { + struct { + int y_stride; + int uv_stride; + }; + int strides[2]; + }; + union { + struct { + uint8_t *y_buffer; + uint8_t *u_buffer; + uint8_t *v_buffer; + }; + uint8_t *buffers[3]; + }; + + // Indicate whether y_buffer, u_buffer, and v_buffer points to the internally + // allocated memory or external buffers. + int use_external_reference_buffers; + // This is needed to store y_buffer, u_buffer, and v_buffer when set reference + // uses an external refernece, and restore those buffer pointers after the + // external reference frame is no longer used. + uint8_t *store_buf_adr[3]; + + // If the frame is stored in a 16-bit buffer, this stores an 8-bit version + // for use in global motion detection. It is allocated on-demand. + uint8_t *y_buffer_8bit; + int buf_8bit_valid; + + uint8_t *buffer_alloc; + size_t buffer_alloc_sz; + int border; + size_t frame_size; + int subsampling_x; + int subsampling_y; + unsigned int bit_depth; + aom_color_primaries_t color_primaries; + aom_transfer_characteristics_t transfer_characteristics; + aom_matrix_coefficients_t matrix_coefficients; + uint8_t monochrome; + aom_chroma_sample_position_t chroma_sample_position; + aom_color_range_t color_range; + int render_width; + int render_height; + + int corrupted; + int flags; + +#ifdef AML + int32_t index; + int32_t decode_idx; + int32_t slice_type; + int32_t RefNum_L0; + int32_t RefNum_L1; + int32_t num_reorder_pic; + int32_t stream_offset; + uint8_t referenced; + uint8_t output_mark; + uint8_t recon_mark; + uint8_t output_ready; + uint8_t error_mark; + /**/ + int32_t slice_idx; + /*buffer*/ + uint32_t fgs_table_adr; +#ifdef AOM_AV1_MMU + uint32_t header_adr; +#endif +#ifdef AOM_AV1_MMU_DW + uint32_t header_dw_adr; +#endif + uint32_t mpred_mv_wr_start_addr; + uint32_t mc_y_adr; + uint32_t mc_u_v_adr; + int32_t mc_canvas_y; + int32_t mc_canvas_u_v; + + int32_t lcu_total; + /**/ + unsigned int order_hint; +#endif +#ifdef AML_DEVICE + int mv_buf_index; + unsigned long cma_alloc_addr; + int BUF_index; + int buf_size; + int comp_body_size; + unsigned int dw_y_adr; + unsigned int dw_u_v_adr; + int double_write_mode; + int y_canvas_index; + int uv_canvas_index; + int vf_ref; + struct canvas_config_s canvas_config[2]; + char *aux_data_buf; + int aux_data_size; + u32 pts; + u64 pts64; + /* picture qos infomation*/ + int max_qp; + int avg_qp; + int min_qp; + int max_skip; + int avg_skip; + int min_skip; + int max_mv; + int min_mv; + int avg_mv; +#endif +} PIC_BUFFER_CONFIG; + +/* +from: +common/blockd.h +*/ +TYPEDEF enum { + KEY_FRAME = 0, + INTER_FRAME = 1, + INTRA_ONLY_FRAME = 2, // replaces intra-only + S_FRAME = 3, + FRAME_TYPES, +} UENUM1BYTE(FRAME_TYPE); + +/*from: +mv.h +*/ +#ifdef ORI_CODE +typedef struct mv32 { + int32_t row; + int32_t col; +} MV32; +#endif +/*from: + aom_filter.h +*/ +#define SUBPEL_BITS 4 +#define SUBPEL_MASK ((1 << SUBPEL_BITS) - 1) +#define SUBPEL_SHIFTS (1 << SUBPEL_BITS) +#define SUBPEL_TAPS 8 + +#define SCALE_SUBPEL_BITS 10 +#define SCALE_SUBPEL_SHIFTS (1 << SCALE_SUBPEL_BITS) +#define SCALE_SUBPEL_MASK (SCALE_SUBPEL_SHIFTS - 1) +#define SCALE_EXTRA_BITS (SCALE_SUBPEL_BITS - SUBPEL_BITS) +#define SCALE_EXTRA_OFF ((1 << SCALE_EXTRA_BITS) / 2) + +#define RS_SUBPEL_BITS 6 +#define RS_SUBPEL_MASK ((1 << RS_SUBPEL_BITS) - 1) +#define RS_SCALE_SUBPEL_BITS 14 +#define RS_SCALE_SUBPEL_MASK ((1 << RS_SCALE_SUBPEL_BITS) - 1) +#define RS_SCALE_EXTRA_BITS (RS_SCALE_SUBPEL_BITS - RS_SUBPEL_BITS) +#define RS_SCALE_EXTRA_OFF (1 << (RS_SCALE_EXTRA_BITS - 1)) + +/*from: +scale.h +*/ +#define SCALE_NUMERATOR 8 + +#define REF_SCALE_SHIFT 14 +#define REF_NO_SCALE (1 << REF_SCALE_SHIFT) +#define REF_INVALID_SCALE -1 + +struct scale_factors { + int x_scale_fp; // horizontal fixed point scale factor + int y_scale_fp; // vertical fixed point scale factor + int x_step_q4; + int y_step_q4; + + int (*scale_value_x)(int val, const struct scale_factors *sf); + int (*scale_value_y)(int val, const struct scale_factors *sf); +#ifdef ORI_CODE + // convolve_fn_ptr[subpel_x != 0][subpel_y != 0][is_compound] + aom_convolve_fn_t convolve[2][2][2]; + aom_highbd_convolve_fn_t highbd_convolve[2][2][2]; +#endif +}; + +#ifdef ORI_CODE +MV32 av1_scale_mv(const MV *mv, int x, int y, const struct scale_factors *sf); +#endif +void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w, + int other_h, int this_w, int this_h); + +static inline int av1_is_valid_scale(const struct scale_factors *sf) { +#ifdef ORI_CODE + assert(sf != NULL); +#endif + return sf->x_scale_fp != REF_INVALID_SCALE && + sf->y_scale_fp != REF_INVALID_SCALE; +} + +static inline int av1_is_scaled(const struct scale_factors *sf) { +#ifdef ORI_CODE + assert(sf != NULL); +#endif + return av1_is_valid_scale(sf) && + (sf->x_scale_fp != REF_NO_SCALE || sf->y_scale_fp != REF_NO_SCALE); +} + + +/* +from: +common/onyxc_int.h +*/ + +#define CDEF_MAX_STRENGTHS 16 + +/* Constant values while waiting for the sequence header */ +#define FRAME_ID_LENGTH 15 +#define DELTA_FRAME_ID_LENGTH 14 + +#define FRAME_CONTEXTS (FRAME_BUFFERS + 1) +// Extra frame context which is always kept at default values +#define FRAME_CONTEXT_DEFAULTS (FRAME_CONTEXTS - 1) +#define PRIMARY_REF_BITS 3 +#define PRIMARY_REF_NONE 7 + +#define NUM_PING_PONG_BUFFERS 2 + +#define MAX_NUM_TEMPORAL_LAYERS 8 +#define MAX_NUM_SPATIAL_LAYERS 4 +/* clang-format off */ +// clang-format seems to think this is a pointer dereference and not a +// multiplication. +#define MAX_NUM_OPERATING_POINTS \ + MAX_NUM_TEMPORAL_LAYERS * MAX_NUM_SPATIAL_LAYERS +/* clang-format on*/ + +// TODO(jingning): Turning this on to set up transform coefficient +// processing timer. +#define TXCOEFF_TIMER 0 +#define TXCOEFF_COST_TIMER 0 + +TYPEDEF enum { + SINGLE_REFERENCE = 0, + COMPOUND_REFERENCE = 1, + REFERENCE_MODE_SELECT = 2, + REFERENCE_MODES = 3, +} UENUM1BYTE(REFERENCE_MODE); + +TYPEDEF enum { + /** + * Frame context updates are disabled + */ + REFRESH_FRAME_CONTEXT_DISABLED, + /** + * Update frame context to values resulting from backward probability + * updates based on entropy/counts in the decoded frame + */ + REFRESH_FRAME_CONTEXT_BACKWARD, +} UENUM1BYTE(REFRESH_FRAME_CONTEXT_MODE); + +#define MFMV_STACK_SIZE 3 + +#ifdef AML +#define MV_REF_SIZE 8 +#endif + +#ifdef ORI_CODE +typedef struct { + int_mv mfmv0; + uint8_t ref_frame_offset; +} TPL_MV_REF; +typedef struct { + int_mv mv; + MV_REFERENCE_FRAME ref_frame; +} MV_REF; +#endif + +typedef struct RefCntBuffer_s { + // For a RefCntBuffer, the following are reference-holding variables: + // - cm->ref_frame_map[] + // - cm->cur_frame + // - cm->scaled_ref_buf[] (encoder only) + // - cm->next_ref_frame_map[] (decoder only) + // - pbi->output_frame_index[] (decoder only) + // With that definition, 'ref_count' is the number of reference-holding + // variables that are currently referencing this buffer. + // For example: + // - suppose this buffer is at index 'k' in the buffer pool, and + // - Total 'n' of the variables / array elements above have value 'k' (that + // is, they are pointing to buffer at index 'k'). + // Then, pool->frame_bufs[k].ref_count = n. + int ref_count; + + unsigned int order_hint; + unsigned int ref_order_hints[INTER_REFS_PER_FRAME]; + + int intra_only; + int segmentation_enabled; + unsigned int segment_feature[8]; +#ifdef AML + int segmentation_update_map; + int prev_segmentation_enabled; + int seg_mi_rows; + int seg_mi_cols; + + unsigned int seg_lf_info_y[8]; + unsigned int seg_lf_info_c[8]; + int8_t ref_deltas[REF_FRAMES]; + int8_t mode_deltas[MAX_MODE_LF_DELTAS]; +#endif + //MV_REF *mvs; + uint8_t *seg_map; +#ifdef ORI_CODE + struct segmentation seg; +#endif + + int mi_rows; + int mi_cols; + // Width and height give the size of the buffer (before any upscaling, unlike + // the sizes that can be derived from the buf structure) + int width; + int height; +#ifdef ORI_CODE + WarpedMotionParams global_motion[REF_FRAMES]; +#endif + int showable_frame; // frame can be used as show existing frame in future + uint8_t film_grain_params_present; +#ifdef ORI_CODE + aom_film_grain_t film_grain_params; +#endif +#ifdef AML + int dec_width; + uint8_t film_grain_reg_valid; + uint32_t film_grain_reg[FILM_GRAIN_REG_SIZE]; +#endif + aom_codec_frame_buffer_t raw_frame_buffer; + PIC_BUFFER_CONFIG buf; +#ifdef ORI_CODE + hash_table hash_table; +#endif + FRAME_TYPE frame_type; + + // This is only used in the encoder but needs to be indexed per ref frame + // so it's extremely convenient to keep it here. +#ifdef ORI_CODE + int interp_filter_selected[SWITCHABLE]; +#endif + // Inter frame reference frame delta for loop filter +#ifndef AML + int8_t ref_deltas[REF_FRAMES]; +#endif +#ifdef ORI_CODE + // 0 = ZERO_MV, MV + int8_t mode_deltas[MAX_MODE_LF_DELTAS]; + + FRAME_CONTEXT frame_context; +#endif +} RefCntBuffer; + +typedef struct BufferPool_s { +// Protect BufferPool from being accessed by several FrameWorkers at +// the same time during frame parallel decode. +// TODO(hkuang): Try to use atomic variable instead of locking the whole pool. +// TODO(wtc): Remove this. See +// https://chromium-review.googlesource.com/c/webm/libvpx/+/560630. +#if CONFIG_MULTITHREAD + pthread_mutex_t pool_mutex; +#endif + + // Private data associated with the frame buffer callbacks. + void *cb_priv; +#ifdef ORI_CODE + aom_get_frame_buffer_cb_fn_t get_fb_cb; + aom_release_frame_buffer_cb_fn_t release_fb_cb; +#endif + RefCntBuffer frame_bufs[FRAME_BUFFERS]; + +#ifdef ORI_CODE + // Frame buffers allocated internally by the codec. + InternalFrameBufferList int_frame_buffers; +#endif +#ifdef AML_DEVICE + spinlock_t lock; +#endif +} BufferPool; + +typedef struct { + int cdef_pri_damping; + int cdef_sec_damping; + int nb_cdef_strengths; + int cdef_strengths[CDEF_MAX_STRENGTHS]; + int cdef_uv_strengths[CDEF_MAX_STRENGTHS]; + int cdef_bits; +} CdefInfo; + +typedef struct { + int delta_q_present_flag; + // Resolution of delta quant + int delta_q_res; + int delta_lf_present_flag; + // Resolution of delta lf level + int delta_lf_res; + // This is a flag for number of deltas of loop filter level + // 0: use 1 delta, for y_vertical, y_horizontal, u, and v + // 1: use separate deltas for each filter level + int delta_lf_multi; +} DeltaQInfo; + +typedef struct { + int enable_order_hint; // 0 - disable order hint, and related tools + int order_hint_bits_minus_1; // dist_wtd_comp, ref_frame_mvs, + // frame_sign_bias + // if 0, enable_dist_wtd_comp and + // enable_ref_frame_mvs must be set as 0. + int enable_dist_wtd_comp; // 0 - disable dist-wtd compound modes + // 1 - enable it + int enable_ref_frame_mvs; // 0 - disable ref frame mvs + // 1 - enable it +} OrderHintInfo; + +// Sequence header structure. +// Note: All syntax elements of sequence_header_obu that need to be +// bit-identical across multiple sequence headers must be part of this struct, +// so that consistency is checked by are_seq_headers_consistent() function. +typedef struct SequenceHeader { + int num_bits_width; + int num_bits_height; + int max_frame_width; + int max_frame_height; + uint8_t frame_id_numbers_present_flag; + int frame_id_length; + int delta_frame_id_length; + BLOCK_SIZE2 sb_size; // Size of the superblock used for this frame + int mib_size; // Size of the superblock in units of MI blocks + int mib_size_log2; // Log 2 of above. + + OrderHintInfo order_hint_info; + + uint8_t force_screen_content_tools; // 0 - force off + // 1 - force on + // 2 - adaptive + uint8_t still_picture; // Video is a single frame still picture + uint8_t reduced_still_picture_hdr; // Use reduced header for still picture + uint8_t force_integer_mv; // 0 - Don't force. MV can use subpel + // 1 - force to integer + // 2 - adaptive + uint8_t enable_filter_intra; // enables/disables filterintra + uint8_t enable_intra_edge_filter; // enables/disables edge upsampling + uint8_t enable_interintra_compound; // enables/disables interintra_compound + uint8_t enable_masked_compound; // enables/disables masked compound + uint8_t enable_dual_filter; // 0 - disable dual interpolation filter + // 1 - enable vert/horz filter selection + uint8_t enable_warped_motion; // 0 - disable warp for the sequence + // 1 - enable warp for the sequence + uint8_t enable_superres; // 0 - Disable superres for the sequence + // and no frame level superres flag + // 1 - Enable superres for the sequence + // enable per-frame superres flag + uint8_t enable_cdef; // To turn on/off CDEF + uint8_t enable_restoration; // To turn on/off loop restoration + BITSTREAM_PROFILE profile; + + // Operating point info. + int operating_points_cnt_minus_1; + int operating_point_idc[MAX_NUM_OPERATING_POINTS]; + uint8_t display_model_info_present_flag; + uint8_t decoder_model_info_present_flag; + AV1_LEVEL seq_level_idx[MAX_NUM_OPERATING_POINTS]; + uint8_t tier[MAX_NUM_OPERATING_POINTS]; // seq_tier in the spec. One bit: 0 + // or 1. + + // Color config. + aom_bit_depth_t bit_depth; // AOM_BITS_8 in profile 0 or 1, + // AOM_BITS_10 or AOM_BITS_12 in profile 2 or 3. + uint8_t use_highbitdepth; // If true, we need to use 16bit frame buffers. + uint8_t monochrome; // Monochorme video + aom_color_primaries_t color_primaries; + aom_transfer_characteristics_t transfer_characteristics; + aom_matrix_coefficients_t matrix_coefficients; + int color_range; + int subsampling_x; // Chroma subsampling for x + int subsampling_y; // Chroma subsampling for y + aom_chroma_sample_position_t chroma_sample_position; + uint8_t separate_uv_delta_q; + uint8_t film_gry_dequant_QTXain_params_present; +} SequenceHeader; + +typedef struct { + int skip_mode_allowed; + int skip_mode_flag; + int ref_frame_idx_0; + int ref_frame_idx_1; +} SkipModeInfo; + +typedef struct { + FRAME_TYPE frame_type; + REFERENCE_MODE reference_mode; + + unsigned int order_hint; + unsigned int frame_number; + SkipModeInfo skip_mode_info; + int refresh_frame_flags; // Which ref frames are overwritten by this frame + int frame_refs_short_signaling; +} CurrentFrame; + +typedef struct AV1_Common_s { + CurrentFrame current_frame; + struct aom_internal_error_info error; + int width; + int height; + int render_width; + int render_height; + int timing_info_present; + aom_timing_info_t timing_info; + int buffer_removal_time_present; + aom_dec_model_info_t buffer_model; + aom_dec_model_op_parameters_t op_params[MAX_NUM_OPERATING_POINTS + 1]; + aom_op_timing_info_t op_frame_timing[MAX_NUM_OPERATING_POINTS + 1]; + uint32_t frame_presentation_time; + + int context_update_tile_id; +#ifdef SUPPORT_SCALE_FACTOR + // Scale of the current frame with respect to itself. + struct scale_factors sf_identity; +#endif + RefCntBuffer *prev_frame; + + // TODO(hkuang): Combine this with cur_buf in macroblockd. + RefCntBuffer *cur_frame; + + // For encoder, we have a two-level mapping from reference frame type to the + // corresponding buffer in the buffer pool: + // * 'remapped_ref_idx[i - 1]' maps reference type 'i' (range: LAST_FRAME ... + // EXTREF_FRAME) to a remapped index 'j' (in range: 0 ... REF_FRAMES - 1) + // * Later, 'cm->ref_frame_map[j]' maps the remapped index 'j' to a pointer to + // the reference counted buffer structure RefCntBuffer, taken from the buffer + // pool cm->buffer_pool->frame_bufs. + // + // LAST_FRAME, ..., EXTREF_FRAME + // | | + // v v + // remapped_ref_idx[LAST_FRAME - 1], ..., remapped_ref_idx[EXTREF_FRAME - 1] + // | | + // v v + // ref_frame_map[], ..., ref_frame_map[] + // + // Note: INTRA_FRAME always refers to the current frame, so there's no need to + // have a remapped index for the same. + int remapped_ref_idx[REF_FRAMES]; + +#ifdef SUPPORT_SCALE_FACTOR + struct scale_factors ref_scale_factors[REF_FRAMES]; +#endif + // For decoder, ref_frame_map[i] maps reference type 'i' to a pointer to + // the buffer in the buffer pool 'cm->buffer_pool.frame_bufs'. + // For encoder, ref_frame_map[j] (where j = remapped_ref_idx[i]) maps + // remapped reference index 'j' (that is, original reference type 'i') to + // a pointer to the buffer in the buffer pool 'cm->buffer_pool.frame_bufs'. + RefCntBuffer *ref_frame_map[REF_FRAMES]; + + // Prepare ref_frame_map for the next frame. + // Only used in frame parallel decode. + RefCntBuffer *next_ref_frame_map[REF_FRAMES]; +#ifdef AML + RefCntBuffer *next_used_ref_frame_map[REF_FRAMES]; +#endif + FRAME_TYPE last_frame_type; /* last frame's frame type for motion search.*/ + + int show_frame; + int showable_frame; // frame can be used as show existing frame in future + int show_existing_frame; + + uint8_t disable_cdf_update; + int allow_high_precision_mv; + uint8_t cur_frame_force_integer_mv; // 0 the default in AOM, 1 only integer + + uint8_t allow_screen_content_tools; + int allow_intrabc; + int allow_warped_motion; + + // MBs, mb_rows/cols is in 16-pixel units; mi_rows/cols is in + // MB_MODE_INFO (8-pixel) units. + int MBs; + int mb_rows, mi_rows; + int mb_cols, mi_cols; + int mi_stride; + + /* profile settings */ + TX_MODE tx_mode; + +#if CONFIG_ENTROPY_STATS + int coef_cdf_category; +#endif + + int base_qindex; + int y_dc_delta_q; + int u_dc_delta_q; + int v_dc_delta_q; + int u_ac_delta_q; + int v_ac_delta_q; + +#ifdef ORI_CODE + // The dequantizers below are true dequantizers used only in the + // dequantization process. They have the same coefficient + // shift/scale as TX. + int16_t y_dequant_QTX[MAX_SEGMENTS][2]; + int16_t u_dequant_QTX[MAX_SEGMENTS][2]; + int16_t v_dequant_QTX[MAX_SEGMENTS][2]; + + // Global quant matrix tables + const qm_val_t *giqmatrix[NUM_QM_LEVELS][3][TX_SIZES_ALL]; + const qm_val_t *gqmatrix[NUM_QM_LEVELS][3][TX_SIZES_ALL]; + + // Local quant matrix tables for each frame + const qm_val_t *y_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL]; + const qm_val_t *u_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL]; + const qm_val_t *v_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL]; +#endif + // Encoder + int using_qmatrix; + int qm_y; + int qm_u; + int qm_v; + int min_qmlevel; + int max_qmlevel; + int use_quant_b_adapt; + + /* We allocate a MB_MODE_INFO struct for each macroblock, together with + an extra row on top and column on the left to simplify prediction. */ + int mi_alloc_size; + +#ifdef ORI_CODE + MB_MODE_INFO *mip; /* Base of allocated array */ + MB_MODE_INFO *mi; /* Corresponds to upper left visible macroblock */ + + // TODO(agrange): Move prev_mi into encoder structure. + // prev_mip and prev_mi will only be allocated in encoder. + MB_MODE_INFO *prev_mip; /* MB_MODE_INFO array 'mip' from last decoded frame */ + MB_MODE_INFO *prev_mi; /* 'mi' from last frame (points into prev_mip) */ + + // Separate mi functions between encoder and decoder. + int (*alloc_mi)(struct AV1Common *cm, int mi_size); + void (*free_mi)(struct AV1Common *cm); + void (*setup_mi)(struct AV1Common *cm); + + // Grid of pointers to 8x8 MB_MODE_INFO structs. Any 8x8 not in the visible + // area will be NULL. + MB_MODE_INFO **mi_grid_base; + MB_MODE_INFO **mi_grid_visible; + MB_MODE_INFO **prev_mi_grid_base; + MB_MODE_INFO **prev_mi_grid_visible; +#endif + // Whether to use previous frames' motion vectors for prediction. + int allow_ref_frame_mvs; + + uint8_t *last_frame_seg_map; + +#ifdef ORI_CODE + InterpFilter interp_filter; +#endif + int switchable_motion_mode; +#ifdef ORI_CODE + loop_filter_info_n lf_info; +#endif + // The denominator of the superres scale; the numerator is fixed. + uint8_t superres_scale_denominator; + int superres_upscaled_width; + int superres_upscaled_height; + +#ifdef ORI_CODE + RestorationInfo rst_info[MAX_MB_PLANE]; +#endif + // Pointer to a scratch buffer used by self-guided restoration + int32_t *rst_tmpbuf; +#ifdef ORI_CODE + RestorationLineBuffers *rlbs; +#endif + // Output of loop restoration + PIC_BUFFER_CONFIG rst_frame; + + // Flag signaling how frame contexts should be updated at the end of + // a frame decode + REFRESH_FRAME_CONTEXT_MODE refresh_frame_context; + + int ref_frame_sign_bias[REF_FRAMES]; /* Two state 0, 1 */ + +#ifdef ORI_CODE + struct loopfilter lf; + struct segmentation seg; +#endif + + int coded_lossless; // frame is fully lossless at the coded resolution. + int all_lossless; // frame is fully lossless at the upscaled resolution. + + int reduced_tx_set_used; + +#ifdef ORI_CODE + // Context probabilities for reference frame prediction + MV_REFERENCE_FRAME comp_fwd_ref[FWD_REFS]; + MV_REFERENCE_FRAME comp_bwd_ref[BWD_REFS]; + + FRAME_CONTEXT *fc; /* this frame entropy */ + FRAME_CONTEXT *default_frame_context; +#endif + int primary_ref_frame; + + int error_resilient_mode; + + int tile_cols, tile_rows; + + int max_tile_width_sb; + int min_log2_tile_cols; + int max_log2_tile_cols; + int max_log2_tile_rows; + int min_log2_tile_rows; + int min_log2_tiles; + int max_tile_height_sb; + int uniform_tile_spacing_flag; + int log2_tile_cols; // only valid for uniform tiles + int log2_tile_rows; // only valid for uniform tiles + int tile_col_start_sb[MAX_TILE_COLS + 1]; // valid for 0 <= i <= tile_cols + int tile_row_start_sb[MAX_TILE_ROWS + 1]; // valid for 0 <= i <= tile_rows + int tile_width, tile_height; // In MI units + int min_inner_tile_width; // min width of non-rightmost tile + + unsigned int large_scale_tile; + unsigned int single_tile_decoding; + + int byte_alignment; + int skip_loop_filter; + int skip_film_grain; + + // External BufferPool passed from outside. + BufferPool *buffer_pool; + +#ifdef ORI_CODE + PARTITION_CONTEXT **above_seg_context; + ENTROPY_CONTEXT **above_context[MAX_MB_PLANE]; + TXFM_CONTEXT **above_txfm_context; + WarpedMotionParams global_motion[REF_FRAMES]; + aom_film_grain_t film_grain_params; + + CdefInfo cdef_info; + DeltaQInfo delta_q_info; // Delta Q and Delta LF parameters +#endif + int num_tg; + SequenceHeader seq_params; + int current_frame_id; + int ref_frame_id[REF_FRAMES]; + int valid_for_referencing[REF_FRAMES]; +#ifdef ORI_CODE + TPL_MV_REF *tpl_mvs; +#endif + int tpl_mvs_mem_size; + // TODO(jingning): This can be combined with sign_bias later. + int8_t ref_frame_side[REF_FRAMES]; + + int is_annexb; + + int temporal_layer_id; + int spatial_layer_id; + unsigned int number_temporal_layers; + unsigned int number_spatial_layers; + int num_allocated_above_context_mi_col; + int num_allocated_above_contexts; + int num_allocated_above_context_planes; + +#if TXCOEFF_TIMER + int64_t cum_txcoeff_timer; + int64_t txcoeff_timer; + int txb_count; +#endif + +#if TXCOEFF_COST_TIMER + int64_t cum_txcoeff_cost_timer; + int64_t txcoeff_cost_timer; + int64_t txcoeff_cost_count; +#endif + const cfg_options_t *options; + int is_decoding; +#ifdef AML + int mv_ref_offset[MV_REF_SIZE][REF_FRAMES]; + int mv_ref_id[MV_REF_SIZE]; + unsigned char mv_cal_tpl_mvs[MV_REF_SIZE]; + int mv_ref_id_index; + int prev_fb_idx; + int new_fb_idx; + int32_t dec_width; +#endif +#ifdef AML_DEVICE + int cur_fb_idx_mmu; +#ifdef AOM_AV1_MMU_DW + int cur_fb_idx_mmu_dw; +#endif + int current_video_frame; + int use_prev_frame_mvs; + int frame_type; + int intra_only; + struct RefCntBuffer_s frame_refs[INTER_REFS_PER_FRAME]; + +#endif +} AV1_COMMON; + + +/* +from: + decoder/decoder.h +*/ + +typedef struct EXTERNAL_REFERENCES { + PIC_BUFFER_CONFIG refs[MAX_EXTERNAL_REFERENCES]; + int num; +} EXTERNAL_REFERENCES; + +typedef struct AV1Decoder { + //DECLARE_ALIGNED(32, MACROBLOCKD, mb); + + //DECLARE_ALIGNED(32, AV1_COMMON, common); + AV1_COMMON common; + +#ifdef ORI_CODE + AVxWorker lf_worker; + AV1LfSync lf_row_sync; + AV1LrSync lr_row_sync; + AV1LrStruct lr_ctxt; + AVxWorker *tile_workers; + int num_workers; + DecWorkerData *thread_data; + ThreadData td; + TileDataDec *tile_data; + int allocated_tiles; + TileBufferDec tile_buffers[MAX_TILE_ROWS][MAX_TILE_COLS]; + AV1DecTileMT tile_mt_info; +#endif + + // Each time the decoder is called, we expect to receive a full temporal unit. + // This can contain up to one shown frame per spatial layer in the current + // operating point (note that some layers may be entirely omitted). + // If the 'output_all_layers' option is true, we save all of these shown + // frames so that they can be returned to the application. If the + // 'output_all_layers' option is false, then we only output one image per + // temporal unit. + // + // Note: The saved buffers are released at the start of the next time the + // application calls aom_codec_decode(). + int output_all_layers; + RefCntBuffer *output_frames[MAX_NUM_SPATIAL_LAYERS]; + size_t num_output_frames; // How many frames are queued up so far? + + // In order to properly support random-access decoding, we need + // to behave slightly differently for the very first frame we decode. + // So we track whether this is the first frame or not. + int decoding_first_frame; + + int allow_lowbitdepth; + int max_threads; + int inv_tile_order; + int need_resync; // wait for key/intra-only frame. + int hold_ref_buf; // Boolean: whether we are holding reference buffers in + // common.next_ref_frame_map. + int reset_decoder_state; + + int tile_size_bytes; + int tile_col_size_bytes; + int dec_tile_row, dec_tile_col; // always -1 for non-VR tile encoding +#if CONFIG_ACCOUNTING + int acct_enabled; + Accounting accounting; +#endif + int tg_size; // Number of tiles in the current tilegroup + int tg_start; // First tile in the current tilegroup + int tg_size_bit_offset; + int sequence_header_ready; + int sequence_header_changed; +#if CONFIG_INSPECTION + aom_inspect_cb inspect_cb; + void *inspect_ctx; +#endif + int operating_point; + int current_operating_point; + int seen_frame_header; + + // State if the camera frame header is already decoded while + // large_scale_tile = 1. + int camera_frame_header_ready; + size_t frame_header_size; +#ifdef ORI_CODE + DataBuffer obu_size_hdr; +#endif + int output_frame_width_in_tiles_minus_1; + int output_frame_height_in_tiles_minus_1; + int tile_count_minus_1; + uint32_t coded_tile_data_size; + unsigned int ext_tile_debug; // for ext-tile software debug & testing + unsigned int row_mt; + EXTERNAL_REFERENCES ext_refs; + PIC_BUFFER_CONFIG tile_list_outbuf; + +#ifdef ORI_CODE + CB_BUFFER *cb_buffer_base; +#endif + int cb_buffer_alloc_size; + + int allocated_row_mt_sync_rows; + +#if CONFIG_MULTITHREAD + pthread_mutex_t *row_mt_mutex_; + pthread_cond_t *row_mt_cond_; +#endif + +#ifdef ORI_CODE + AV1DecRowMTInfo frame_row_mt_info; +#endif + +#ifdef AML + unsigned char pred_inter_read_enable; + int cur_obu_type; + int decode_idx; + int bufmgr_proc_count; + int obu_frame_frame_head_come_after_tile; + uint32_t frame_width; + uint32_t frame_height; + BuffInfo_t* work_space_buf; + buff_t* mc_buf; + //unsigned short *rpm_ptr; + void *private_data; + u32 pre_stream_offset; +#endif +} AV1Decoder; + +#define RPM_BEGIN 0x200 +#define RPM_END 0x280 + +typedef union param_u { + struct { + unsigned short data[RPM_END - RPM_BEGIN]; + } l; + struct { + /*sequence head*/ + unsigned short profile; + unsigned short still_picture; + unsigned short reduced_still_picture_hdr; + unsigned short decoder_model_info_present_flag; + unsigned short max_frame_width; + unsigned short max_frame_height; + unsigned short frame_id_numbers_present_flag; + unsigned short delta_frame_id_length; + unsigned short frame_id_length; + unsigned short order_hint_bits_minus_1; + unsigned short enable_order_hint; + unsigned short enable_dist_wtd_comp; + unsigned short enable_ref_frame_mvs; + + /*frame head*/ + unsigned short show_existing_frame; + unsigned short frame_type; + unsigned short show_frame; + unsigned short error_resilient_mode; + unsigned short refresh_frame_flags; + unsigned short showable_frame; + unsigned short current_frame_id; + unsigned short frame_size_override_flag; + unsigned short order_hint; + unsigned short primary_ref_frame; + unsigned short frame_refs_short_signaling; + unsigned short frame_width; + unsigned short dec_frame_width; + unsigned short frame_width_scaled; + unsigned short frame_height; + unsigned short reference_mode; + unsigned short allow_ref_frame_mvs; + unsigned short superres_scale_denominator; + unsigned short lst_ref; + unsigned short gld_ref; + unsigned short existing_frame_idx; + + unsigned short remapped_ref_idx[INTER_REFS_PER_FRAME]; + unsigned short delta_frame_id_minus_1[INTER_REFS_PER_FRAME]; + unsigned short ref_order_hint[REF_FRAMES]; + /*other not in reference*/ + unsigned short bit_depth; + unsigned short seq_flags; + unsigned short update_parameters; + unsigned short film_grain_params_ref_idx; + + /*loop_filter & segmentation*/ + unsigned short loop_filter_sharpness_level; + unsigned short loop_filter_mode_ref_delta_enabled; + unsigned short loop_filter_ref_deltas_0; + unsigned short loop_filter_ref_deltas_1; + unsigned short loop_filter_ref_deltas_2; + unsigned short loop_filter_ref_deltas_3; + unsigned short loop_filter_ref_deltas_4; + unsigned short loop_filter_ref_deltas_5; + unsigned short loop_filter_ref_deltas_6; + unsigned short loop_filter_ref_deltas_7; + unsigned short loop_filter_mode_deltas_0; + unsigned short loop_filter_mode_deltas_1; + unsigned short loop_filter_level_0; + unsigned short loop_filter_level_1; + unsigned short loop_filter_level_u; + unsigned short loop_filter_level_v; + + unsigned short segmentation_enabled; + /* + SEG_LVL_ALT_LF_Y_V feature_enable: seg_lf_info_y[bit7] + SEG_LVL_ALT_LF_Y_V data: seg_lf_info_y[bit0~6] + SEG_LVL_ALT_LF_Y_H feature enable: seg_lf_info_y[bit15] + SEG_LVL_ALT_LF_Y_H data: seg_lf_info_y[bit8~14] + */ + unsigned short seg_lf_info_y[8]; + /* + SEG_LVL_ALT_LF_U feature_enable: seg_lf_info_y[bit7] + SEG_LVL_ALT_LF_U data: seg_lf_info_y[bit0~6] + SEG_LVL_ALT_LF_V feature enable: seg_lf_info_y[bit15] + SEG_LVL_ALT_LF_V data: seg_lf_info_y[bit8~14] + */ + unsigned short seg_lf_info_c[8]; + unsigned short video_signal_type; + unsigned short color_description; + + /*ucode end*/ + /*other*/ + unsigned short enable_superres; + + /*seqence not use*/ + unsigned short operating_points_cnt_minus_1; + unsigned short operating_point_idc[MAX_NUM_OPERATING_POINTS]; + unsigned short seq_level_idx[MAX_NUM_OPERATING_POINTS]; + unsigned short decoder_model_param_present_flag[MAX_NUM_OPERATING_POINTS]; + unsigned short timing_info_present; + /*frame head not use*/ + unsigned short display_frame_id; + unsigned short frame_presentation_time; + unsigned short buffer_removal_time_present; + unsigned short op_frame_timing[MAX_NUM_OPERATING_POINTS + 1]; + unsigned short valid_ref_frame_bits; + + } p; +}param_t; + +PIC_BUFFER_CONFIG *av1_get_ref_frame_spec_buf( + const AV1_COMMON *const cm, const MV_REFERENCE_FRAME ref_frame); + +int av1_bufmgr_process(AV1Decoder *pbi, union param_u *params, + unsigned char new_compressed_data, int obu_type); + +struct scale_factors *av1_get_ref_scale_factors( + AV1_COMMON *const cm, const MV_REFERENCE_FRAME ref_frame); + +void av1_set_next_ref_frame_map(AV1Decoder *pbi); + +unsigned int av1_get_next_used_ref_info( + const AV1_COMMON *const cm, int i); + +void av1_release_buf(AV1Decoder *pbi, RefCntBuffer *const buf); + +int av1_bufmgr_postproc(AV1Decoder *pbi, unsigned char frame_decoded); + +AV1Decoder *av1_decoder_create(BufferPool *const pool); + +unsigned char av1_frame_is_inter(const AV1_COMMON *const cm); + +RefCntBuffer *av1_get_primary_ref_frame_buf( + const AV1_COMMON *const cm); + +void av1_raw_write_image(AV1Decoder *pbi, PIC_BUFFER_CONFIG *sd); + +#if 1 +#define lock_buffer_pool(pool, flags) \ + spin_lock_irqsave(&pool->lock, flags) + +#define unlock_buffer_pool(pool, flags) \ + spin_unlock_irqrestore(&pool->lock, flags) +#else +#define lock_buffer_pool(pool, flags) flags=1; + +#define unlock_buffer_pool(pool, flags) flags=0; + +#endif + +#define AV1_DEBUG_BUFMGR 0x01 +#define AV1_DEBUG_BUFMGR_MORE 0x02 +#define AV1_DEBUG_BUFMGR_DETAIL 0x04 +#define AV1_DEBUG_OUT_PTS 0x10 +#define AOM_DEBUG_HW_MORE 0x20 +#define AOM_DEBUG_VFRAME 0x40 +#define AOM_DEBUG_PRINT_LIST_INFO 0x80 +#define AOM_AV1_DEBUG_SEND_PARAM_WITH_REG 0x100 +#define AV1_DEBUG_IGNORE_VF_REF 0x200 +#define AV1_DEBUG_DBG_LF_PRINT 0x400 +#define AV1_DEBUG_REG 0x800 +#define AOM_DEBUG_BUFMGR_ONLY 0x1000 +#define AOM_DEBUG_AUX_DATA 0x2000 +#define AV1_DEBUG_QOS_INFO 0x4000 +#define AOM_DEBUG_DW_DISP_MAIN 0x8000 +#define AV1_DEBUG_DIS_LOC_ERROR_PROC 0x10000 +#define AV1_DEBUG_DIS_SYS_ERROR_PROC 0x20000 +#define AV1_DEBUG_DUMP_PIC_LIST 0x40000 +#define AV1_DEBUG_TRIG_SLICE_SEGMENT_PROC 0x80000 +#define AV1_DEBUG_NO_TRIGGER_FRAME 0x100000 +#define AV1_DEBUG_LOAD_UCODE_FROM_FILE 0x200000 +#define AV1_DEBUG_FORCE_SEND_AGAIN 0x400000 +#define AV1_DEBUG_DUMP_DATA 0x800000 +#define AV1_DEBUG_CACHE 0x1000000 +#define AV1_DEBUG_CACHE_HIT_RATE 0x2000000 +#define IGNORE_PARAM_FROM_CONFIG 0x8000000 +#if 1 +/*def MULTI_INSTANCE_SUPPORT*/ +#define PRINT_FLAG_ERROR 0x0 +#define PRINT_FLAG_V4L_DETAIL 0x10000000 +#define PRINT_FLAG_VDEC_STATUS 0x20000000 +#define PRINT_FLAG_VDEC_DETAIL 0x40000000 +#define PRINT_FLAG_VDEC_DATA 0x80000000 +#endif + +int av1_print2(int flag, const char *fmt, ...); + +unsigned char av1_is_debug(int flag); + +#endif + diff --git a/drivers/frame_provider/decoder/vav1/vav1.c b/drivers/frame_provider/decoder/vav1/vav1.c new file mode 100644 index 0000000..9cecb72 --- a/dev/null +++ b/drivers/frame_provider/decoder/vav1/vav1.c @@ -0,0 +1,9946 @@ + /* + * drivers/amlogic/amports/vav1.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + */ +#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../../stream_input/amports/amports_priv.h" +#include +#include "../utils/decoder_mmu_box.h" +#include "../utils/decoder_bmmu_box.h" + +#define MEM_NAME "codec_av1" +/* #include */ +#include +#include "../utils/vdec.h" +#include "../utils/amvdec.h" +#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC +#include "../utils/vdec_profile.h" +#endif + +#include +#include +#include "../utils/config_parser.h" +#include "../utils/firmware.h" +#include "../../../common/chips/decoder_cpu_ver_info.h" +#include "../../../amvdec_ports/vdec_drv_base.h" + +#define SUPPORT_V4L2 +//#define DEBUG_USE_VP9_DEVICE_NAME +//#define BUFMGR_ONLY_OLD_CHIP + +#ifdef SUPPORT_V4L2 +#include "../utils/vdec_v4l2_buffer_ops.h" +#endif + +#define AML +#include "aom_av1_define.h" +#include "av1_global.h" + +#define DUMP_FILMGRAIN +#define MIX_STREAM_SUPPORT +//#define MV_USE_FIXED_BUF +//#define USE_SPEC_BUF_FOR_MMU_HEAD + +#define AOM_AV1_DBLK_INIT +#define AOM_AV1_UPSCALE_INIT + +#define USE_DEC_PIC_END + + +#include "vav1.h" + +#define FGS_TABLE_SIZE (512 * 128 / 8) + +#define AV1_GMC_PARAM_BUFF_ADDR 0x316d +#define HEVCD_MPP_DECOMP_AXIURG_CTL 0x34c7 +#define HEVC_FGS_IDX 0x3660 +#define HEVC_FGS_DATA 0x3661 +#define HEVC_FGS_CTRL 0x3662 +#define AV1_SKIP_MODE_INFO 0x316c +#define AV1_QUANT_WR 0x3146 +#define AV1_SEG_W_ADDR 0x3165 +#define AV1_SEG_R_ADDR 0x3166 +#define AV1_REF_SEG_INFO 0x3171 +#define HEVC_ASSIST_PIC_SIZE_FB_READ 0x300d +#define PARSER_REF_SCALE_ENBL 0x316b +#define HEVC_MPRED_MV_RPTR_1 0x3263 +#define HEVC_MPRED_MV_RPTR_2 0x3264 +#define HEVC_SAO_CTRL9 0x362d +#define HEVC_FGS_TABLE_START 0x3666 +#define HEVC_FGS_TABLE_LENGTH 0x3667 +#define HEVC_DBLK_CDEF0 0x3515 +#define HEVC_DBLK_CDEF1 0x3516 +#define HEVC_DBLK_UPS1 0x351c +#define HEVC_DBLK_UPS2 0x351d +#define HEVC_DBLK_UPS3 0x351e +#define HEVC_DBLK_UPS4 0x351f +#define HEVC_DBLK_UPS5 0x3520 +#define AV1_UPSCALE_X0_QN 0x316e +#define AV1_UPSCALE_STEP_QN 0x316f +#define HEVC_DBLK_DBLK0 0x3523 +#define HEVC_DBLK_DBLK1 0x3524 +#define HEVC_DBLK_DBLK2 0x3525 + +#define HW_MASK_FRONT 0x1 +#define HW_MASK_BACK 0x2 + +#define AV1D_MPP_REFINFO_TBL_ACCCONFIG 0x3442 +#define AV1D_MPP_REFINFO_DATA 0x3443 +#define AV1D_MPP_REF_SCALE_ENBL 0x3441 +#define HEVC_MPRED_CTRL4 0x324c +#define HEVC_CM_HEADER_START_ADDR 0x3628 +#define HEVC_DBLK_CFGB 0x350b +#define HEVCD_MPP_ANC2AXI_TBL_DATA 0x3464 +#define HEVC_SAO_MMU_VH1_ADDR 0x363b +#define HEVC_SAO_MMU_VH0_ADDR 0x363a + +#define HEVC_MV_INFO 0x310d +#define HEVC_QP_INFO 0x3137 +#define HEVC_SKIP_INFO 0x3136 + +#define HEVC_CM_BODY_LENGTH2 0x3663 +#define HEVC_CM_HEADER_OFFSET2 0x3664 +#define HEVC_CM_HEADER_LENGTH2 0x3665 + +#define HEVC_CM_HEADER_START_ADDR2 0x364a +#define HEVC_SAO_MMU_DMA_CTRL2 0x364c +#define HEVC_SAO_MMU_VH0_ADDR2 0x364d +#define HEVC_SAO_MMU_VH1_ADDR2 0x364e +#define HEVC_DW_VH0_ADDDR 0x365e +#define HEVC_DW_VH1_ADDDR 0x365f + +#ifdef BUFMGR_ONLY_OLD_CHIP +#undef AV1_SKIP_MODE_INFO +#define AV1_SKIP_MODE_INFO HEVC_ASSIST_SCRATCH_B +#endif + + +#define AOM_AV1_DEC_IDLE 0 +#define AOM_AV1_DEC_FRAME_HEADER 1 +#define AOM_AV1_DEC_TILE_END 2 +#define AOM_AV1_DEC_TG_END 3 +#define AOM_AV1_DEC_LCU_END 4 +#define AOM_AV1_DECODE_SLICE 5 +#define AOM_AV1_SEARCH_HEAD 6 +#define AOM_AV1_DUMP_LMEM 7 +#define AOM_AV1_FGS_PARAM_CONT 8 +#define AOM_AV1_DISCARD_NAL 0x10 + +/*status*/ +#define AOM_AV1_DEC_PIC_END 0xe0 +/*AOM_AV1_FGS_PARA: +Bit[11] - 0 Read, 1 - Write +Bit[10:8] - film_grain_params_ref_idx, For Write request +*/ +#define AOM_AV1_FGS_PARAM 0xe1 +#define AOM_AV1_DEC_PIC_END_PRE 0xe2 +#define AOM_AV1_HEAD_PARSER_DONE 0xf0 +#define AOM_AV1_HEAD_SEARCH_DONE 0xf1 +#define AOM_AV1_SEQ_HEAD_PARSER_DONE 0xf2 +#define AOM_AV1_FRAME_HEAD_PARSER_DONE 0xf3 +#define AOM_AV1_FRAME_PARSER_DONE 0xf4 +#define AOM_AV1_REDUNDANT_FRAME_HEAD_PARSER_DONE 0xf5 +#define HEVC_ACTION_DONE 0xff + +#define AOM_DECODE_BUFEMPTY 0x20 +#define AOM_DECODE_TIMEOUT 0x21 +#define AOM_SEARCH_BUFEMPTY 0x22 +#define AOM_DECODE_OVER_SIZE 0x23 +#define AOM_EOS 0x24 +#define AOM_NAL_DECODE_DONE 0x25 + + +#define VF_POOL_SIZE 32 + +#undef pr_info +#define pr_info printk + +#define DECODE_MODE_SINGLE ((0x80 << 24) | 0) +#define DECODE_MODE_MULTI_STREAMBASE ((0x80 << 24) | 1) +#define DECODE_MODE_MULTI_FRAMEBASE ((0x80 << 24) | 2) +#define DECODE_MODE_SINGLE_LOW_LATENCY ((0x80 << 24) | 3) +#define DECODE_MODE_MULTI_FRAMEBASE_NOHEAD ((0x80 << 24) | 4) + +#define AV1_TRIGGER_FRAME_DONE 0x100 +#define AV1_TRIGGER_FRAME_ENABLE 0x200 + +#define MV_MEM_UNIT 0x240 +/*--------------------------------------------------- + * Include "parser_cmd.h" + *--------------------------------------------------- + */ +#define PARSER_CMD_SKIP_CFG_0 0x0000090b + +#define PARSER_CMD_SKIP_CFG_1 0x1b14140f + +#define PARSER_CMD_SKIP_CFG_2 0x001b1910 + +#define PARSER_CMD_NUMBER 37 + +/*#define HEVC_PIC_STRUCT_SUPPORT*/ +/* to remove, fix build error */ + +/*#define CODEC_MM_FLAGS_FOR_VDECODER 0*/ + +#define MULTI_INSTANCE_SUPPORT +#define SUPPORT_10BIT +/* #define ERROR_HANDLE_DEBUG */ + +#ifndef STAT_KTHREAD +#define STAT_KTHREAD 0x40 +#endif + +#ifdef MULTI_INSTANCE_SUPPORT +#define MAX_DECODE_INSTANCE_NUM 9 + +#ifdef DEBUG_USE_VP9_DEVICE_NAME +#define MULTI_DRIVER_NAME "ammvdec_vp9" +#else +#define MULTI_DRIVER_NAME "ammvdec_av1" +#endif + +#define AUX_BUF_ALIGN(adr) ((adr + 0xf) & (~0xf)) +static u32 prefix_aux_buf_size = (16 * 1024); +static u32 suffix_aux_buf_size; + +static unsigned int max_decode_instance_num + = MAX_DECODE_INSTANCE_NUM; +static unsigned int decode_frame_count[MAX_DECODE_INSTANCE_NUM]; +static unsigned int display_frame_count[MAX_DECODE_INSTANCE_NUM]; +static unsigned int max_process_time[MAX_DECODE_INSTANCE_NUM]; +static unsigned int run_count[MAX_DECODE_INSTANCE_NUM]; +static unsigned int input_empty[MAX_DECODE_INSTANCE_NUM]; +static unsigned int not_run_ready[MAX_DECODE_INSTANCE_NUM]; +#ifdef AOM_AV1_MMU_DW +static unsigned int dw_mmu_enable[MAX_DECODE_INSTANCE_NUM]; +#endif +/* disable timeout for av1 mosaic JIRA SWPL-23326 */ +static u32 decode_timeout_val = 0; +static int start_decode_buf_level = 0x8000; +static u32 work_buf_size; +static u32 force_pts_unstable; +static u32 mv_buf_margin = 16; + +/* DOUBLE_WRITE_MODE is enabled only when NV21 8 bit output is needed */ +/* double_write_mode: + * 0, no double write; + * 1, 1:1 ratio; + * 2, (1/4):(1/4) ratio; + * 3, (1/4):(1/4) ratio, with both compressed frame included + * 4, (1/2):(1/2) ratio; + * 5, (1/2):(1/2) ratio, with both compressed frame included + * 0x10, double write only + * 0x20, mmu double write + * 0x100, if > 1080p,use mode 4,else use mode 1; + * 0x200, if > 1080p,use mode 2,else use mode 1; + * 0x300, if > 720p, use mode 4, else use mode 1; + */ +static u32 double_write_mode; + +#ifdef DEBUG_USE_VP9_DEVICE_NAME +#define DRIVER_NAME "amvdec_vp9" +#define MODULE_NAME "amvdec_vp9" +#define DRIVER_HEADER_NAME "amvdec_vp9_header" +#else +#define DRIVER_NAME "amvdec_av1" +#define MODULE_NAME "amvdec_av1" +#define DRIVER_HEADER_NAME "amvdec_av1_header" +#endif + +#define PUT_INTERVAL (HZ/100) +#define ERROR_SYSTEM_RESET_COUNT 200 + +#define PTS_NORMAL 0 +#define PTS_NONE_REF_USE_DURATION 1 + +#define PTS_MODE_SWITCHING_THRESHOLD 3 +#define PTS_MODE_SWITCHING_RECOVERY_THREASHOLD 3 + +#define DUR2PTS(x) ((x)*90/96) +#define PTS2DUR(x) ((x)*96/90) + + +struct AV1HW_s; +static int vav1_vf_states(struct vframe_states *states, void *); +static struct vframe_s *vav1_vf_peek(void *); +static struct vframe_s *vav1_vf_get(void *); +static void vav1_vf_put(struct vframe_s *, void *); +static int vav1_event_cb(int type, void *data, void *private_data); + +static int vav1_stop(struct AV1HW_s *hw); +#ifdef MULTI_INSTANCE_SUPPORT +static s32 vav1_init(struct vdec_s *vdec); +#else +static s32 vav1_init(struct AV1HW_s *hw); +#endif +static void vav1_prot_init(struct AV1HW_s *hw, u32 mask); +static int vav1_local_init(struct AV1HW_s *hw); +static void vav1_put_timer_func(unsigned long arg); +static void dump_data(struct AV1HW_s *hw, int size); +static unsigned char get_data_check_sum + (struct AV1HW_s *hw, int size); +static void dump_pic_list(struct AV1HW_s *hw); +static int av1_alloc_mmu( + struct AV1HW_s *hw, + int cur_buf_idx, + int pic_width, + int pic_height, + unsigned short bit_depth, + unsigned int *mmu_index_adr); + +#ifdef DEBUG_USE_VP9_DEVICE_NAME +static const char vav1_dec_id[] = "vvp9-dev"; + +#define PROVIDER_NAME "decoder.vp9" +#define MULTI_INSTANCE_PROVIDER_NAME "vdec.vp9" +#else +static const char vav1_dec_id[] = "vav1-dev"; + +#define PROVIDER_NAME "decoder.av1" +#define MULTI_INSTANCE_PROVIDER_NAME "vdec.av1" +#endif +#define DV_PROVIDER_NAME "dvbldec" + +static const struct vframe_operations_s vav1_vf_provider = { + .peek = vav1_vf_peek, + .get = vav1_vf_get, + .put = vav1_vf_put, + .event_cb = vav1_event_cb, + .vf_states = vav1_vf_states, +}; + +static struct vframe_provider_s vav1_vf_prov; + +static u32 bit_depth_luma; +static u32 bit_depth_chroma; +static u32 frame_width; +static u32 frame_height; +static u32 video_signal_type; +static u32 force_dv_enable; +static u32 on_no_keyframe_skiped; +static u32 without_display_mode; + +#define PROB_SIZE (496 * 2 * 4) +#define PROB_BUF_SIZE (0x5000) +#define COUNT_BUF_SIZE (0x300 * 4 * 4) +/*compute_losless_comp_body_size(4096, 2304, 1) = 18874368(0x1200000)*/ +#define MAX_FRAME_4K_NUM 0x1200 +#define MAX_FRAME_8K_NUM 0x4800 + +#define HEVC_ASSIST_MMU_MAP_ADDR 0x3009 + + +/*USE_BUF_BLOCK*/ +struct BUF_s { + int index; + unsigned int alloc_flag; + /*buffer */ + unsigned int cma_page_count; + unsigned long alloc_addr; + unsigned long start_adr; + unsigned int size; + + unsigned int free_start_adr; + ulong v4l_ref_buf_addr; +} /*BUF_t */; + +struct MVBUF_s { + unsigned long start_adr; + unsigned int size; + int used_flag; +} /*MVBUF_t */; + +/*#define TEST_WR_PTR_INC*/ +/*#define WR_PTR_INC_NUM 128*/ +#define WR_PTR_INC_NUM 1 + +//#define SIMULATION +#define DOS_PROJECT +#undef MEMORY_MAP_IN_REAL_CHIP + +/*#undef DOS_PROJECT*/ +/*#define MEMORY_MAP_IN_REAL_CHIP*/ + +/*#define CONFIG_HEVC_CLK_FORCED_ON*/ +/*#define ENABLE_SWAP_TEST*/ +#ifndef BUFMGR_ONLY_OLD_CHIP +#define MCRCC_ENABLE +#endif + +#ifdef AV1_10B_NV21 +#else +#define LOSLESS_COMPRESS_MODE +#endif + +typedef unsigned int u32; +typedef unsigned short u16; + + +static u32 get_picture_qos; + +static u32 debug; + +static bool is_reset; +/*for debug*/ +/* + udebug_flag: + bit 0, enable ucode print + bit 1, enable ucode detail print + bit [31:16] not 0, pos to dump lmem + bit 2, pop bits to lmem + bit [11:8], pre-pop bits for alignment (when bit 2 is 1) +*/ +static u32 udebug_flag; +/* + when udebug_flag[1:0] is not 0 + udebug_pause_pos not 0, + pause position +*/ +static u32 udebug_pause_pos; +/* + when udebug_flag[1:0] is not 0 + and udebug_pause_pos is not 0, + pause only when DEBUG_REG2 is equal to this val +*/ +static u32 udebug_pause_val; + +static u32 udebug_pause_decode_idx; + + +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION +static u32 dv_toggle_prov_name; +#endif + + +#define DEBUG_REG +#ifdef DEBUG_REG +void AV1_WRITE_VREG_DBG2(unsigned int adr, unsigned int val, int line) +{ + if (debug & AV1_DEBUG_REG) + pr_info("%d:%s(%x, %x)\n", line, __func__, adr, val); + if (adr != 0) + WRITE_VREG(adr, val); +} + +#undef WRITE_VREG +#define WRITE_VREG(a,v) AV1_WRITE_VREG_DBG2(a,v,__LINE__) +#endif + +#define FRAME_CNT_WINDOW_SIZE 59 +#define RATE_CORRECTION_THRESHOLD 5 +/************************************************** + +AV1 buffer management start + +***************************************************/ + +#define MMU_COMPRESS_HEADER_SIZE 0x48000 +#define MMU_COMPRESS_HEADER_SIZE_DW MMU_COMPRESS_HEADER_SIZE +#define MMU_COMPRESS_8K_HEADER_SIZE (0x48000*4) +#define MAX_SIZE_8K (8192 * 4608) +#define MAX_SIZE_4K (4096 * 2304) +#define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K) + +#define INVALID_IDX -1 /* Invalid buffer index.*/ + + +/*4 scratch frames for the new frames to support a maximum of 4 cores decoding + *in parallel, 3 for scaled references on the encoder. + *TODO(hkuang): Add ondemand frame buffers instead of hardcoding the number + * // of framebuffers. + *TODO(jkoleszar): These 3 extra references could probably come from the + *normal reference pool. + */ +//#define FRAME_BUFFERS (REF_FRAMES + 16) +//#define REF_FRAMES_4K (6) +#define REF_FRAMES_4K REF_FRAMES + +#ifdef USE_SPEC_BUF_FOR_MMU_HEAD +#define HEADER_FRAME_BUFFERS (0) +#elif (defined AOM_AV1_MMU_DW) +#define HEADER_FRAME_BUFFERS (2 * FRAME_BUFFERS) +#else +#define HEADER_FRAME_BUFFERS (FRAME_BUFFERS) +#endif +#define MAX_BUF_NUM (FRAME_BUFFERS) +#define MV_BUFFER_NUM FRAME_BUFFERS + +//#define FRAME_CONTEXTS_LOG2 2 +//#define FRAME_CONTEXTS (1 << FRAME_CONTEXTS_LOG2) +/*buffer + header buffer + workspace*/ +#ifdef MV_USE_FIXED_BUF +#define MAX_BMMU_BUFFER_NUM (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + 1) +#define VF_BUFFER_IDX(n) (n) +#define HEADER_BUFFER_IDX(n) (FRAME_BUFFERS + n) +#define WORK_SPACE_BUF_ID (FRAME_BUFFERS + HEADER_FRAME_BUFFERS) +#else +#define MAX_BMMU_BUFFER_NUM \ + (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + MV_BUFFER_NUM + 1) +#define VF_BUFFER_IDX(n) (n) +#define HEADER_BUFFER_IDX(n) (FRAME_BUFFERS + n) +#define MV_BUFFER_IDX(n) (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + n) +#define WORK_SPACE_BUF_ID \ + (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + MV_BUFFER_NUM) +#endif +#ifdef AOM_AV1_MMU_DW +#define DW_HEADER_BUFFER_IDX(n) (HEADER_BUFFER_IDX(HEADER_FRAME_BUFFERS/2) + n) +#endif + + +static void set_canvas(struct AV1HW_s *hw, + struct PIC_BUFFER_CONFIG_s *pic_config); + +static void fill_frame_info(struct AV1HW_s *hw, + struct PIC_BUFFER_CONFIG_s *frame, + unsigned int framesize, + unsigned int pts); + + +static int compute_losless_comp_body_size(int width, int height, + uint8_t is_bit_depth_10); + + + +#ifdef MULTI_INSTANCE_SUPPORT +#define DEC_RESULT_NONE 0 +#define DEC_RESULT_DONE 1 +#define DEC_RESULT_AGAIN 2 +#define DEC_RESULT_CONFIG_PARAM 3 +#define DEC_RESULT_ERROR 4 +#define DEC_INIT_PICLIST 5 +#define DEC_UNINIT_PICLIST 6 +#define DEC_RESULT_GET_DATA 7 +#define DEC_RESULT_GET_DATA_RETRY 8 +#define DEC_RESULT_EOS 9 +#define DEC_RESULT_FORCE_EXIT 10 + +#define DEC_S1_RESULT_NONE 0 +#define DEC_S1_RESULT_DONE 1 +#define DEC_S1_RESULT_FORCE_EXIT 2 +#define DEC_S1_RESULT_TEST_TRIGGER_DONE 0xf0 + +#ifdef FB_DECODING_TEST_SCHEDULE +#define TEST_SET_NONE 0 +#define TEST_SET_PIC_DONE 1 +#define TEST_SET_S2_DONE 2 +#endif + +static void av1_work(struct work_struct *work); +#endif + +#ifdef DUMP_FILMGRAIN +u32 fg_dump_index = 0xff; +#endif + +#ifdef AOM_AV1_DBLK_INIT +struct loop_filter_info_n_s; +struct loopfilter; +struct segmentation_lf; +#endif +struct AV1HW_s { + AV1Decoder *pbi; + union param_u aom_param; + unsigned char frame_decoded; + unsigned char one_compressed_data_done; + unsigned char new_compressed_data; +#if 1 +/*def CHECK_OBU_REDUNDANT_FRAME_HEADER*/ + int obu_frame_frame_head_come_after_tile; +#endif + unsigned char index; + + struct device *cma_dev; + struct platform_device *platform_dev; + void (*vdec_cb)(struct vdec_s *, void *); + void *vdec_cb_arg; + struct vframe_chunk_s *chunk; + int dec_result; + struct work_struct work; + struct work_struct set_clk_work; + u32 start_shift_bytes; + u32 data_size; + + struct BuffInfo_s work_space_buf_store; + unsigned long buf_start; + u32 buf_size; + u32 cma_alloc_count; + unsigned long cma_alloc_addr; + uint8_t eos; + unsigned long int start_process_time; + unsigned last_lcu_idx; + int decode_timeout_count; + unsigned timeout_num; + int save_buffer_mode; + + int double_write_mode; + + long used_4k_num; + + unsigned char m_ins_flag; + char *provider_name; + union param_u param; + int frame_count; + int pic_count; + u32 stat; + struct timer_list timer; + u32 frame_dur; + u32 frame_ar; + int fatal_error; + uint8_t init_flag; + uint8_t config_next_ref_info_flag; + uint8_t first_sc_checked; + uint8_t process_busy; +#define PROC_STATE_INIT 0 +#define PROC_STATE_DECODESLICE 1 +#define PROC_STATE_SENDAGAIN 2 + uint8_t process_state; + u32 ucode_pause_pos; + + int show_frame_num; + struct buff_s mc_buf_spec; + struct dec_sysinfo vav1_amstream_dec_info; + void *rpm_addr; + void *lmem_addr; + dma_addr_t rpm_phy_addr; + dma_addr_t lmem_phy_addr; + unsigned short *lmem_ptr; + unsigned short *debug_ptr; +#ifdef DUMP_FILMGRAIN + dma_addr_t fg_phy_addr; + unsigned char *fg_ptr; + void *fg_addr; +#endif + u32 fgs_valid; + + u8 aux_data_dirty; + u32 prefix_aux_size; + u32 suffix_aux_size; + void *aux_addr; + dma_addr_t aux_phy_addr; + char *dv_data_buf; + int dv_data_size; + + void *prob_buffer_addr; + void *count_buffer_addr; + dma_addr_t prob_buffer_phy_addr; + dma_addr_t count_buffer_phy_addr; + + void *frame_mmu_map_addr; + dma_addr_t frame_mmu_map_phy_addr; +#ifdef AOM_AV1_MMU_DW + void *dw_frame_mmu_map_addr; + dma_addr_t dw_frame_mmu_map_phy_addr; +#endif + unsigned int use_cma_flag; + + struct BUF_s m_BUF[MAX_BUF_NUM]; + struct MVBUF_s m_mv_BUF[MV_BUFFER_NUM]; + u32 used_buf_num; + DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE); + DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); + DECLARE_KFIFO(pending_q, struct vframe_s *, VF_POOL_SIZE); + struct vframe_s vfpool[VF_POOL_SIZE]; + u32 vf_pre_count; + u32 vf_get_count; + u32 vf_put_count; + int buf_num; + int pic_num; + int lcu_size_log2; + unsigned int losless_comp_body_size; + + u32 video_signal_type; + + u32 frame_mode_pts_save[FRAME_BUFFERS]; + u64 frame_mode_pts64_save[FRAME_BUFFERS]; + + int pts_mode; + int last_lookup_pts; + int last_pts; + u64 last_lookup_pts_us64; + u64 last_pts_us64; + u64 shift_byte_count; + + u32 pts_unstable; + u32 frame_cnt_window; + u32 pts1, pts2; + u32 last_duration; + u32 duration_from_pts_done; + bool av1_first_pts_ready; + + u32 shift_byte_count_lo; + u32 shift_byte_count_hi; + int pts_mode_switching_count; + int pts_mode_recovery_count; + + bool get_frame_dur; + u32 saved_resolution; + + /**/ + struct AV1_Common_s common; + struct RefCntBuffer_s *cur_buf; + int refresh_frame_flags; + uint8_t need_resync; + uint8_t hold_ref_buf; + uint8_t ready_for_new_data; + struct BufferPool_s av1_buffer_pool; + + struct BuffInfo_s *work_space_buf; + + struct buff_s *mc_buf; + + unsigned int frame_width; + unsigned int frame_height; + + unsigned short *rpm_ptr; + int init_pic_w; + int init_pic_h; + int lcu_total; + + int current_lcu_size; + + int slice_type; + + int skip_flag; + int decode_idx; + int result_done_count; + uint8_t has_keyframe; + uint8_t wait_buf; + uint8_t error_flag; + + /* bit 0, for decoding; bit 1, for displaying */ + uint8_t ignore_bufmgr_error; + int PB_skip_mode; + int PB_skip_count_after_decoding; + /*hw*/ + + /**/ + struct vdec_info *gvs; + + u32 pre_stream_offset; + + unsigned int dec_status; + u32 last_put_idx; + int new_frame_displayed; + void *mmu_box; + void *bmmu_box; + int mmu_enable; +#ifdef AOM_AV1_MMU_DW + void *mmu_box_dw; + int dw_mmu_enable; +#endif + struct vframe_master_display_colour_s vf_dp; + struct firmware_s *fw; + int max_pic_w; + int max_pic_h; + + int need_cache_size; + u64 sc_start_time; + bool postproc_done; + int low_latency_flag; + bool no_head; + bool pic_list_init_done; + bool pic_list_init_done2; + bool is_used_v4l; + void *v4l2_ctx; + int frameinfo_enable; + struct vframe_qos_s vframe_qos; + +#ifdef AOM_AV1_DBLK_INIT + /* + * malloc may not work in real chip, please allocate memory for the following structures + */ + struct loop_filter_info_n_s *lfi; + struct loopfilter *lf; + struct segmentation_lf *seg_4lf; +#endif + +}; +static void av1_dump_state(struct vdec_s *vdec); + +int av1_print(struct AV1HW_s *hw, + int flag, const char *fmt, ...) +{ +#define HEVC_PRINT_BUF 256 + unsigned char buf[HEVC_PRINT_BUF]; + int len = 0; + + if (hw == NULL || + (flag == 0) || + (debug & flag)) { + va_list args; + + va_start(args, fmt); + if (hw) + len = sprintf(buf, "[%d]", hw->index); + vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args); + pr_info("%s", buf); + va_end(args); + } + return 0; +} + +unsigned char av1_is_debug(int flag) +{ + if ((flag == 0) || (debug & flag)) + return 1; + + return 0; +} + +int av1_print2(int flag, const char *fmt, ...) +{ + unsigned char buf[HEVC_PRINT_BUF]; + int len = 0; + + if ((flag == 0) || + (debug & flag)) { + va_list args; + + va_start(args, fmt); + vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args); + pr_info("%s", buf); + va_end(args); + } + return 0; + +} + +static int is_oversize(int w, int h) +{ + int max = (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)? + MAX_SIZE_8K : MAX_SIZE_4K; + + if (w <= 0 || h <= 0) + return true; + + if (h != 0 && (w > max / h)) + return true; + + return false; +} + +static int v4l_get_fb(struct aml_vcodec_ctx *ctx, struct vdec_fb **out) +{ + int ret = 0; + + ret = ctx->dec_if->get_param(ctx->drv_handle, + GET_PARAM_FREE_FRAME_BUFFER, out); + + return ret; +} + + +static inline bool close_to(int a, int b, int m) +{ + return (abs(a - b) < m) ? true : false; +} + +#ifdef MULTI_INSTANCE_SUPPORT +static int av1_print_cont(struct AV1HW_s *hw, + int flag, const char *fmt, ...) +{ + unsigned char buf[HEVC_PRINT_BUF]; + int len = 0; + + if (hw == NULL || + (flag == 0) || + (debug & flag)) { + va_list args; + + va_start(args, fmt); + vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args); + pr_info("%s", buf); + va_end(args); + } + return 0; +} + +static void trigger_schedule(struct AV1HW_s *hw) +{ + if (hw->vdec_cb) + hw->vdec_cb(hw_to_vdec(hw), hw->vdec_cb_arg); +} + +static void reset_process_time(struct AV1HW_s *hw) +{ + if (hw->start_process_time) { + unsigned process_time = + 1000 * (jiffies - hw->start_process_time) / HZ; + hw->start_process_time = 0; + if (process_time > max_process_time[hw->index]) + max_process_time[hw->index] = process_time; + } +} + +static void start_process_time(struct AV1HW_s *hw) +{ + hw->start_process_time = jiffies; + hw->decode_timeout_count = 0; + hw->last_lcu_idx = 0; +} + +static void timeout_process(struct AV1HW_s *hw) +{ + reset_process_time(hw); + if (hw->process_busy) { + av1_print(hw, + 0, "%s decoder timeout but process_busy\n", __func__); + if (debug) + av1_print(hw, 0, "debug disable timeout notify\n"); + return; + } + hw->timeout_num++; + amhevc_stop(); + av1_print(hw, + 0, "%s decoder timeout\n", __func__); + + hw->dec_result = DEC_RESULT_DONE; + vdec_schedule_work(&hw->work); +} + +static u32 get_valid_double_write_mode(struct AV1HW_s *hw) +{ + u32 dw = ((double_write_mode & 0x80000000) == 0) ? + hw->double_write_mode : + (double_write_mode & 0x7fffffff); + if ((dw & 0x20) && + ((dw & 0xf) == 2 || (dw & 0xf) == 3)) { + pr_info("MMU doueble write 1:4 not supported !!!\n"); + dw = 0; + } + return dw; +} + +static int get_double_write_mode(struct AV1HW_s *hw) +{ + u32 valid_dw_mode = get_valid_double_write_mode(hw); + u32 dw; + int w, h; + struct AV1_Common_s *cm = &hw->pbi->common; + struct PIC_BUFFER_CONFIG_s *cur_pic_config; + + if (!cm->cur_frame) + return 1;/*no valid frame,*/ + cur_pic_config = &cm->cur_frame->buf; + w = cur_pic_config->y_crop_width; + h = cur_pic_config->y_crop_height; + + dw = 0x1; /*1:1*/ + switch (valid_dw_mode) { + case 0x100: + if (w > 1920 && h > 1088) + dw = 0x4; /*1:2*/ + break; + case 0x200: + if (w > 1920 && h > 1088) + dw = 0x2; /*1:4*/ + break; + case 0x300: + if (w > 1280 && h > 720) + dw = 0x4; /*1:2*/ + break; + default: + dw = valid_dw_mode; + break; + } + return dw; +} + +/* for double write buf alloc */ +static int get_double_write_mode_init(struct AV1HW_s *hw) +{ + u32 valid_dw_mode = get_valid_double_write_mode(hw); + u32 dw; + int w = hw->init_pic_w; + int h = hw->init_pic_h; + + dw = 0x1; /*1:1*/ + switch (valid_dw_mode) { + case 0x100: + if (w > 1920 && h > 1088) + dw = 0x4; /*1:2*/ + break; + case 0x200: + if (w > 1920 && h > 1088) + dw = 0x2; /*1:4*/ + break; + case 0x300: + if (w > 1280 && h > 720) + dw = 0x4; /*1:2*/ + break; + default: + dw = valid_dw_mode; + break; + } + return dw; +} +#endif + +static int get_double_write_ratio(struct AV1HW_s *hw, + int dw_mode) +{ + int ratio = 1; + int dw_mode_ratio = dw_mode & 0xf; + if ((dw_mode_ratio == 2) || + (dw_mode_ratio == 3)) + ratio = 4; + else if (dw_mode_ratio == 4) + ratio = 2; + return ratio; +} + +//#define MAX_4K_NUM 0x1200 +int av1_alloc_mmu( + struct AV1HW_s *hw, + int cur_buf_idx, + int pic_width, + int pic_height, + unsigned short bit_depth, + unsigned int *mmu_index_adr) +{ + int ret = 0; + int bit_depth_10 = (bit_depth == AOM_BITS_10); + int picture_size; + int cur_mmu_4k_number, max_frame_num; + if (!hw->mmu_box) { + pr_err("error no mmu box!\n"); + return -1; + } + if (hw->double_write_mode & 0x10) + return 0; + if (bit_depth >= AOM_BITS_12) { + hw->fatal_error = DECODER_FATAL_ERROR_SIZE_OVERFLOW; + pr_err("fatal_error, un support bit depth 12!\n\n"); + return -1; + } + picture_size = compute_losless_comp_body_size(pic_width, pic_height, + bit_depth_10); + cur_mmu_4k_number = ((picture_size + (1 << 12) - 1) >> 12); + + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) + max_frame_num = MAX_FRAME_8K_NUM; + else + max_frame_num = MAX_FRAME_4K_NUM; + + if (cur_mmu_4k_number > max_frame_num) { + pr_err("over max !! cur_mmu_4k_number 0x%x width %d height %d\n", + cur_mmu_4k_number, pic_width, pic_height); + return -1; + } + ret = decoder_mmu_box_alloc_idx( + hw->mmu_box, + cur_buf_idx, + cur_mmu_4k_number, + mmu_index_adr); + return ret; +} + +#ifdef AOM_AV1_MMU_DW +static int compute_losless_comp_body_size_dw(int width, int height, + uint8_t is_bit_depth_10); + +int av1_alloc_mmu_dw( + struct AV1HW_s *hw, + int cur_buf_idx, + int pic_width, + int pic_height, + unsigned short bit_depth, + unsigned int *mmu_index_adr) +{ + int ret = 0; + int bit_depth_10 = (bit_depth == AOM_BITS_10); + int picture_size; + int cur_mmu_4k_number, max_frame_num; + if (!hw->mmu_box_dw) { + pr_err("error no mmu box!\n"); + return -1; + } + if (hw->double_write_mode & 0x10) + return 0; + if (bit_depth >= AOM_BITS_12) { + hw->fatal_error = DECODER_FATAL_ERROR_SIZE_OVERFLOW; + pr_err("fatal_error, un support bit depth 12!\n\n"); + return -1; + } + picture_size = compute_losless_comp_body_size_dw(pic_width, pic_height, + bit_depth_10); + cur_mmu_4k_number = ((picture_size + (1 << 12) - 1) >> 12); + + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) + max_frame_num = MAX_FRAME_8K_NUM; + else + max_frame_num = MAX_FRAME_4K_NUM; + + if (cur_mmu_4k_number > max_frame_num) { + pr_err("over max !! cur_mmu_4k_number 0x%x width %d height %d\n", + cur_mmu_4k_number, pic_width, pic_height); + return -1; + } + ret = decoder_mmu_box_alloc_idx( + hw->mmu_box_dw, + cur_buf_idx, + cur_mmu_4k_number, + mmu_index_adr); + return ret; +} +#endif + +#ifndef MV_USE_FIXED_BUF +static void dealloc_mv_bufs(struct AV1HW_s *hw) +{ + int i; + for (i = 0; i < MV_BUFFER_NUM; i++) { + if (hw->m_mv_BUF[i].start_adr) { + if (debug) + pr_info( + "dealloc mv buf(%d) adr %ld size 0x%x used_flag %d\n", + i, hw->m_mv_BUF[i].start_adr, + hw->m_mv_BUF[i].size, + hw->m_mv_BUF[i].used_flag); + decoder_bmmu_box_free_idx( + hw->bmmu_box, + MV_BUFFER_IDX(i)); + hw->m_mv_BUF[i].start_adr = 0; + hw->m_mv_BUF[i].size = 0; + hw->m_mv_BUF[i].used_flag = 0; + } + } +} + +static int alloc_mv_buf(struct AV1HW_s *hw, + int i, int size) +{ + int ret = 0; + if (decoder_bmmu_box_alloc_buf_phy + (hw->bmmu_box, + MV_BUFFER_IDX(i), size, + DRIVER_NAME, + &hw->m_mv_BUF[i].start_adr) < 0) { + hw->m_mv_BUF[i].start_adr = 0; + ret = -1; + } else { + hw->m_mv_BUF[i].size = size; + hw->m_mv_BUF[i].used_flag = 0; + ret = 0; + if (debug) { + pr_info( + "MV Buffer %d: start_adr %p size %x\n", + i, + (void *)hw->m_mv_BUF[i].start_adr, + hw->m_mv_BUF[i].size); + } + } + return ret; +} + +static int init_mv_buf_list(struct AV1HW_s *hw) +{ + int i; + int ret = 0; + int count = MV_BUFFER_NUM; + int pic_width = hw->init_pic_w; + int pic_height = hw->init_pic_h; + int lcu_size = 64; /*fixed 64*/ /* !!!!! TO DO ...*/ + int pic_width_64 = (pic_width + 63) & (~0x3f); + int pic_height_32 = (pic_height + 31) & (~0x1f); + int pic_width_lcu = (pic_width_64 % lcu_size) ? + pic_width_64 / lcu_size + 1 + : pic_width_64 / lcu_size; + int pic_height_lcu = (pic_height_32 % lcu_size) ? + pic_height_32 / lcu_size + 1 + : pic_height_32 / lcu_size; + int lcu_total = pic_width_lcu * pic_height_lcu; + int size = ((lcu_total * MV_MEM_UNIT) + 0xffff) & + (~0xffff); +#if 0 + if (mv_buf_margin > 0) + count = REF_FRAMES + mv_buf_margin; + if (hw->init_pic_w > 2048 && hw->init_pic_h > 1088) + count = REF_FRAMES_4K + mv_buf_margin; +#else + if (debug) + pr_info("%s, calculated mv size 0x%x\n", + __func__, size); + if (hw->init_pic_w > 4096 && hw->init_pic_h > 2048) { + count = REF_FRAMES_4K + mv_buf_margin; + size = 0x260000; + } else if (hw->init_pic_w > 2048 && hw->init_pic_h > 1088) { + count = REF_FRAMES_4K + mv_buf_margin; + size = 0x130000; + } else { + count = REF_FRAMES + mv_buf_margin; + size = 0x130000; + } +#endif + if (debug) { + pr_info("%s w:%d, h:%d, count: %d, size 0x%x\n", + __func__, hw->init_pic_w, hw->init_pic_h, count, size); + } + + for (i = 0; + i < count && i < MV_BUFFER_NUM; i++) { + if (alloc_mv_buf(hw, i, size) < 0) { + ret = -1; + break; + } + } + return ret; +} + +static int get_mv_buf(struct AV1HW_s *hw, + int *mv_buf_index, + uint32_t *mpred_mv_wr_start_addr) +{ + int i; + int ret = -1; + for (i = 0; i < MV_BUFFER_NUM; i++) { + if (hw->m_mv_BUF[i].start_adr && + hw->m_mv_BUF[i].used_flag == 0) { + hw->m_mv_BUF[i].used_flag = 1; + ret = i; + break; + } + } + + if (ret >= 0) { + *mv_buf_index = ret; + *mpred_mv_wr_start_addr = + (hw->m_mv_BUF[ret].start_adr + 0xffff) & + (~0xffff); + if (debug & AV1_DEBUG_BUFMGR_MORE) + pr_info( + "%s => %d (%d) size 0x%x\n", + __func__, ret, + *mpred_mv_wr_start_addr, + hw->m_mv_BUF[ret].size); + } else { + pr_info( + "%s: Error, mv buf is not enough\n", + __func__); + } + return ret; +} +static void put_mv_buf(struct AV1HW_s *hw, + int *mv_buf_index) +{ + int i = *mv_buf_index; + if (i >= MV_BUFFER_NUM) { + if (debug & AV1_DEBUG_BUFMGR_MORE) + pr_info( + "%s: index %d beyond range\n", + __func__, i); + return; + } + if (debug & AV1_DEBUG_BUFMGR_MORE) + pr_info( + "%s(%d): used_flag(%d)\n", + __func__, i, + hw->m_mv_BUF[i].used_flag); + + *mv_buf_index = -1; + if (hw->m_mv_BUF[i].start_adr && + hw->m_mv_BUF[i].used_flag) + hw->m_mv_BUF[i].used_flag = 0; +} +static void put_un_used_mv_bufs(struct AV1HW_s *hw) +{ + struct AV1_Common_s *const cm = &hw->pbi->common; + struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs; + int i; + for (i = 0; i < hw->used_buf_num; ++i) { + if ((frame_bufs[i].ref_count == 0) && + (frame_bufs[i].buf.index != -1) && + (frame_bufs[i].buf.mv_buf_index >= 0) + ) + put_mv_buf(hw, &frame_bufs[i].buf.mv_buf_index); + } +} +#endif + + +static int get_free_buf_count(struct AV1HW_s *hw) +{ + struct AV1_Common_s *const cm = &hw->pbi->common; + struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs; + int i; + int free_buf_count = 0; + for (i = 0; i < hw->used_buf_num; ++i) + if ((frame_bufs[i].ref_count == 0) && + (frame_bufs[i].buf.vf_ref == 0) && + (frame_bufs[i].buf.index != -1) + ) + free_buf_count++; + return free_buf_count; +} + +int aom_bufmgr_init(struct AV1HW_s *hw, struct BuffInfo_s *buf_spec_i, + struct buff_s *mc_buf_i) { + struct AV1_Common_s *cm = &hw->pbi->common; + if (debug) + pr_info("%s %d %p\n", __func__, __LINE__, hw->pbi); + hw->frame_count = 0; + hw->pic_count = 0; + hw->pre_stream_offset = 0; + spin_lock_init(&cm->buffer_pool->lock); + cm->prev_fb_idx = INVALID_IDX; + cm->new_fb_idx = INVALID_IDX; + hw->used_4k_num = -1; + cm->cur_fb_idx_mmu = INVALID_IDX; + pr_debug + ("After aom_bufmgr_init, prev_fb_idx : %d, new_fb_idx : %d\r\n", + cm->prev_fb_idx, cm->new_fb_idx); + hw->need_resync = 1; + + cm->current_video_frame = 0; + hw->ready_for_new_data = 1; + + /* private init */ + hw->work_space_buf = buf_spec_i; + if (!hw->mmu_enable) + hw->mc_buf = mc_buf_i; + + hw->rpm_addr = NULL; + hw->lmem_addr = NULL; +#ifdef DUMP_FILMGRAIN + hw->fg_addr = NULL; +#endif + hw->use_cma_flag = 0; + hw->decode_idx = 0; + hw->result_done_count = 0; + /*int m_uiMaxCUWidth = 1<<7;*/ + /*int m_uiMaxCUHeight = 1<<7;*/ + hw->has_keyframe = 0; + hw->skip_flag = 0; + hw->wait_buf = 0; + hw->error_flag = 0; + + hw->pts_mode = PTS_NORMAL; + hw->last_pts = 0; + hw->last_lookup_pts = 0; + hw->last_pts_us64 = 0; + hw->last_lookup_pts_us64 = 0; + hw->shift_byte_count = 0; + hw->shift_byte_count_lo = 0; + hw->shift_byte_count_hi = 0; + hw->pts_mode_switching_count = 0; + hw->pts_mode_recovery_count = 0; + + hw->buf_num = 0; + hw->pic_num = 0; + + return 0; +} + +/* +struct AV1HW_s av1_decoder; +union param_u av1_param; +*/ +/************************************************** + * + *AV1 buffer management end + * + *************************************************** + */ + + +#define HEVC_CM_BODY_START_ADDR 0x3626 +#define HEVC_CM_BODY_LENGTH 0x3627 +#define HEVC_CM_HEADER_LENGTH 0x3629 +#define HEVC_CM_HEADER_OFFSET 0x362b + +#define LOSLESS_COMPRESS_MODE + +/*#define DECOMP_HEADR_SURGENT*/ +#ifdef AV1_10B_NV21 +static u32 mem_map_mode = 2 /* 0:linear 1:32x32 2:64x32*/ +#else +static u32 mem_map_mode; /* 0:linear 1:32x32 2:64x32 ; m8baby test1902 */ +#endif +static u32 enable_mem_saving = 1; +static u32 force_w_h; + +static u32 force_fps; + + +const u32 av1_version = 201602101; +static u32 debug; +static u32 radr; +static u32 rval; +static u32 pop_shorts; +static u32 dbg_cmd; +static u32 dbg_skip_decode_index; +static u32 endian = 0xff0; +static u32 multi_frames_in_one_pack = 1; +#ifdef ERROR_HANDLE_DEBUG +static u32 dbg_nal_skip_flag; + /* bit[0], skip vps; bit[1], skip sps; bit[2], skip pps */ +static u32 dbg_nal_skip_count; +#endif +/*for debug*/ +static u32 decode_pic_begin; +static uint slice_parse_begin; +static u32 step; +#ifdef MIX_STREAM_SUPPORT +static u32 buf_alloc_width = 4096; +static u32 buf_alloc_height = 2304; +static u32 av1_max_pic_w = 4096; +static u32 av1_max_pic_h = 2304; + +static u32 dynamic_buf_num_margin; +#else +static u32 buf_alloc_width; +static u32 buf_alloc_height; +static u32 dynamic_buf_num_margin = 7; +#endif +static u32 buf_alloc_depth = 10; +static u32 buf_alloc_size; +/* + *bit[0]: 0, + * bit[1]: 0, always release cma buffer when stop + * bit[1]: 1, never release cma buffer when stop + *bit[0]: 1, when stop, release cma buffer if blackout is 1; + *do not release cma buffer is blackout is not 1 + * + *bit[2]: 0, when start decoding, check current displayed buffer + * (only for buffer decoded by AV1) if blackout is 0 + * 1, do not check current displayed buffer + * + *bit[3]: 1, if blackout is not 1, do not release current + * displayed cma buffer always. + */ +/* set to 1 for fast play; + * set to 8 for other case of "keep last frame" + */ +static u32 buffer_mode = 1; +/* buffer_mode_dbg: debug only*/ +static u32 buffer_mode_dbg = 0xffff0000; +/**/ + +/* + *bit 0, 1: only display I picture; + *bit 1, 1: only decode I picture; + */ +static u32 i_only_flag; + +static u32 low_latency_flag; + +static u32 no_head; + +static u32 max_decoding_time; +/* + *error handling + */ +/*error_handle_policy: + *bit 0: 0, auto skip error_skip_nal_count nals before error recovery; + *1, skip error_skip_nal_count nals before error recovery; + *bit 1 (valid only when bit0 == 1): + *1, wait vps/sps/pps after error recovery; + *bit 2 (valid only when bit0 == 0): + *0, auto search after error recovery (av1_recover() called); + *1, manual search after error recovery + *(change to auto search after get IDR: WRITE_VREG(NAL_SEARCH_CTL, 0x2)) + * + *bit 4: 0, set error_mark after reset/recover + * 1, do not set error_mark after reset/recover + *bit 5: 0, check total lcu for every picture + * 1, do not check total lcu + * + */ + +static u32 error_handle_policy; +/*static u32 parser_sei_enable = 1;*/ +#define MAX_BUF_NUM_NORMAL 16 +#define MAX_BUF_NUM_LESS 16 +static u32 max_buf_num = MAX_BUF_NUM_NORMAL; +#define MAX_BUF_NUM_SAVE_BUF 8 + +static u32 run_ready_min_buf_num = 2; + + +static DEFINE_MUTEX(vav1_mutex); +#ifndef MULTI_INSTANCE_SUPPORT +static struct device *cma_dev; +#endif +#define HEVC_DEC_STATUS_REG HEVC_ASSIST_SCRATCH_0 +#define HEVC_FG_STATUS HEVC_ASSIST_SCRATCH_B +#define HEVC_RPM_BUFFER HEVC_ASSIST_SCRATCH_1 +#define AOM_AV1_ADAPT_PROB_REG HEVC_ASSIST_SCRATCH_3 +#define AOM_AV1_MMU_MAP_BUFFER HEVC_ASSIST_SCRATCH_4 // changed to use HEVC_ASSIST_MMU_MAP_ADDR +#define AOM_AV1_DAALA_TOP_BUFFER HEVC_ASSIST_SCRATCH_5 +#define HEVC_SAO_UP HEVC_ASSIST_SCRATCH_6 +//#define HEVC_STREAM_SWAP_BUFFER HEVC_ASSIST_SCRATCH_7 +#define AOM_AV1_CDF_BUFFER_W HEVC_ASSIST_SCRATCH_8 +#define AOM_AV1_CDF_BUFFER_R HEVC_ASSIST_SCRATCH_9 +#define AOM_AV1_COUNT_SWAP_BUFFER HEVC_ASSIST_SCRATCH_A +#define AOM_AV1_SEG_MAP_BUFFER_W AV1_SEG_W_ADDR // HEVC_ASSIST_SCRATCH_B +#define AOM_AV1_SEG_MAP_BUFFER_R AV1_SEG_R_ADDR // HEVC_ASSIST_SCRATCH_C +//#define HEVC_sao_vb_size HEVC_ASSIST_SCRATCH_B +//#define HEVC_SAO_VB HEVC_ASSIST_SCRATCH_C +//#define HEVC_SCALELUT HEVC_ASSIST_SCRATCH_D +#define HEVC_WAIT_FLAG HEVC_ASSIST_SCRATCH_E +#define RPM_CMD_REG HEVC_ASSIST_SCRATCH_F +//#define HEVC_STREAM_SWAP_TEST HEVC_ASSIST_SCRATCH_L + +#ifdef MULTI_INSTANCE_SUPPORT +#define HEVC_DECODE_COUNT HEVC_ASSIST_SCRATCH_M +#define HEVC_DECODE_SIZE HEVC_ASSIST_SCRATCH_N +#else +#define HEVC_DECODE_PIC_BEGIN_REG HEVC_ASSIST_SCRATCH_M +#define HEVC_DECODE_PIC_NUM_REG HEVC_ASSIST_SCRATCH_N +#endif +#define AOM_AV1_SEGMENT_FEATURE AV1_QUANT_WR + +#define DEBUG_REG1 HEVC_ASSIST_SCRATCH_G +#define DEBUG_REG2 HEVC_ASSIST_SCRATCH_H + +#define LMEM_DUMP_ADR HEVC_ASSIST_SCRATCH_I +#define CUR_NAL_UNIT_TYPE HEVC_ASSIST_SCRATCH_J +#define DECODE_STOP_POS HEVC_ASSIST_SCRATCH_K + +#define PIC_END_LCU_COUNT HEVC_ASSIST_SCRATCH_2 + +#define HEVC_AUX_ADR HEVC_ASSIST_SCRATCH_L +#define HEVC_AUX_DATA_SIZE HEVC_ASSIST_SCRATCH_7 + +/* + *ucode parser/search control + *bit 0: 0, header auto parse; 1, header manual parse + *bit 1: 0, auto skip for noneseamless stream; 1, no skip + *bit [3:2]: valid when bit1==0; + *0, auto skip nal before first vps/sps/pps/idr; + *1, auto skip nal before first vps/sps/pps + *2, auto skip nal before first vps/sps/pps, + * and not decode until the first I slice (with slice address of 0) + * + *3, auto skip before first I slice (nal_type >=16 && nal_type<=21) + *bit [15:4] nal skip count (valid when bit0 == 1 (manual mode) ) + *bit [16]: for NAL_UNIT_EOS when bit0 is 0: + * 0, send SEARCH_DONE to arm ; 1, do not send SEARCH_DONE to arm + *bit [17]: for NAL_SEI when bit0 is 0: + * 0, do not parse SEI in ucode; 1, parse SEI in ucode + *bit [31:20]: used by ucode for debug purpose + */ +#define NAL_SEARCH_CTL HEVC_ASSIST_SCRATCH_I + /*[31:24] chip feature + 31: 0, use MBOX1; 1, use MBOX0 + [24:16] debug + 0x1, bufmgr only + */ +#define DECODE_MODE HEVC_ASSIST_SCRATCH_J +#define DECODE_STOP_POS HEVC_ASSIST_SCRATCH_K + +#define RPM_BUF_SIZE ((RPM_END - RPM_BEGIN) * 2) +#define LMEM_BUF_SIZE (0x600 * 2) + +#ifdef MAP_8K +static u32 seg_map_size = 0xd8000; +#else +static u32 seg_map_size = 0x36000; +#endif + +#define WORK_BUF_SPEC_NUM 2 +static struct BuffInfo_s aom_workbuff_spec[WORK_BUF_SPEC_NUM]={ + { //8M bytes + .max_width = 1920, + .max_height = 1088, + .ipp = { + // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k + .buf_size = 0x4000, + }, + .sao_abv = { + .buf_size = 0x30000, + }, + .sao_vb = { + .buf_size = 0x30000, + }, + .short_term_rps = { + // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800) + .buf_size = 0x800, + }, + .vps = { + // VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, total 0x0800 bytes + .buf_size = 0x800, + }, + .seg_map = { + // SEGMENT MAP AREA - 1920x1088/4/4 * 3 bits = 0xBF40 Bytes * 16 = 0xBF400 + .buf_size = 0xBF400, + }, + .daala_top = { + // DAALA TOP STORE AREA - 224 Bytes (use 256 Bytes for LPDDR4) per 128. Total 4096/128*256 = 0x2000 + .buf_size = 0x2000, + }, + .sao_up = { + // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes + .buf_size = 0x2800, + }, + .swap_buf = { + // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid) + .buf_size = 0x800, + }, + .cdf_buf = { + // for context store/load 1024x256 x16 = 512K bytes 16*0x8000 + .buf_size = 0x80000, + }, + .gmc_buf = { + // for gmc_parameter store/load 128 x 16 = 2K bytes 0x800 + .buf_size = 0x800, + }, + .scalelut = { + // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000) + .buf_size = 0x8000, + }, + .dblk_para = { + // DBLK -> Max 256(4096/16) LCU, each para 1024bytes(total:0x40000), data 1024bytes(total:0x40000) + .buf_size = 0x80000, + }, + .dblk_data = { + .buf_size = 0x80000, + }, + .cdef_data = { + .buf_size = 0x40000, + }, + .ups_data = { + .buf_size = 0x60000, + }, + .fgs_table = { + .buf_size = FGS_TABLE_SIZE * FRAME_BUFFERS, // 512x128bits + }, +#ifdef AOM_AV1_MMU +#define VBH_BUF_SIZE (2 * 16 * 2304) +#define VBH_BUF_COUNT 4 + .mmu_vbh = { + .buf_size = VBH_BUF_SIZE * VBH_BUF_COUNT, + //.buf_size = 0x5000, //2*16*(more than 2304)/4, 4K + }, + .cm_header = { + //.buf_size = MMU_COMPRESS_HEADER_SIZE*8, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) + .buf_size = MMU_COMPRESS_HEADER_SIZE*FRAME_BUFFERS, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) + }, +#endif +#ifdef AOM_AV1_MMU_DW + .mmu_vbh_dw = { + .buf_size = VBH_BUF_SIZE * VBH_BUF_COUNT, + //.buf_size = 0x5000, //2*16*(more than 2304)/4, 4K + }, + .cm_header_dw = { + //.buf_size = MMU_COMPRESS_HEADER_SIZE*8, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) + .buf_size = MMU_COMPRESS_HEADER_SIZE_DW*FRAME_BUFFERS, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) + }, +#endif + .mpred_above = { + .buf_size = 0x10000, /* 2 * size of hw*/ + }, +#ifdef MV_USE_FIXED_BUF + .mpred_mv = { + .buf_size = 0x40000*FRAME_BUFFERS, //1080p, 0x40000 per buffer + }, +#endif + .rpm = { + .buf_size = 0x80*2, + }, + .lmem = { + .buf_size = 0x400 * 2, + } + }, + { +#ifdef VPU_FILMGRAIN_DUMP + .max_width = 640, + .max_height = 480, +#else + .max_width = 4096, + .max_height = 2304, +#endif + .ipp = { + // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k + .buf_size = 0x4000, + }, + .sao_abv = { + .buf_size = 0x30000, + }, + .sao_vb = { + .buf_size = 0x30000, + }, + .short_term_rps = { + // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800) + .buf_size = 0x800, + }, + .vps = { + // VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, total 0x0800 bytes + .buf_size = 0x800, + }, + .seg_map = { + // SEGMENT MAP AREA - 4096x2304/4/4 * 3 bits = 0x36000 Bytes * 16 = 0x360000 + .buf_size = 0x360000, + }, + .daala_top = { + // DAALA TOP STORE AREA - 224 Bytes (use 256 Bytes for LPDDR4) per 128. Total 4096/128*256 = 0x2000 + .buf_size = 0x2000, + }, + .sao_up = { + // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes + .buf_size = 0x2800, + }, + .swap_buf = { + // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid) + .buf_size = 0x800, + }, + .cdf_buf = { + // for context store/load 1024x256 x16 = 512K bytes 16*0x8000 + .buf_size = 0x80000, + }, + .gmc_buf = { + // for gmc_parameter store/load 128 x 16 = 2K bytes 0x800 + .buf_size = 0x800, + }, + .scalelut = { + // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000) + .buf_size = 0x8000, + }, + .dblk_para = { + // DBLK -> Max 256(4096/16) LCU, each para 1024bytes(total:0x40000), data 1024bytes(total:0x40000) + .buf_size = 0x80000, + }, + .dblk_data = { + .buf_size = 0x80000, + }, + .cdef_data = { + .buf_size = 0x40000, + }, + .ups_data = { + .buf_size = 0x60000, + }, + .fgs_table = { + .buf_size = FGS_TABLE_SIZE * FRAME_BUFFERS, // 512x128bits + }, +#ifdef AOM_AV1_MMU + .mmu_vbh = { + .buf_size = VBH_BUF_SIZE * VBH_BUF_COUNT, + //.buf_size = 0x5000, //2*16*(more than 2304)/4, 4K + }, + .cm_header = { + //.buf_size = MMU_COMPRESS_HEADER_SIZE*8, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) + .buf_size = MMU_COMPRESS_HEADER_SIZE*FRAME_BUFFERS, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) + }, +#endif +#ifdef AOM_AV1_MMU_DW + .mmu_vbh_dw = { + .buf_size = VBH_BUF_SIZE * VBH_BUF_COUNT, + //.buf_size = 0x5000, //2*16*(more than 2304)/4, 4K + }, + .cm_header_dw = { + //.buf_size = MMU_COMPRESS_HEADER_SIZE*8, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) + .buf_size = MMU_COMPRESS_HEADER_SIZE_DW*FRAME_BUFFERS, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) + }, +#endif + .mpred_above = { + .buf_size = 0x10000, /* 2 * size of hw*/ + }, +#ifdef MV_USE_FIXED_BUF + .mpred_mv = { + /* .buf_size = 0x100000*16, + //4k2k , 0x100000 per buffer */ + /* 4096x2304 , 0x120000 per buffer */ +#if (defined MAP_8K) +#define MAX_ONE_MV_BUFFER_SIZE 0x260000 +#else +#define MAX_ONE_MV_BUFFER_SIZE 0x130000 +#endif + .buf_size = MAX_ONE_MV_BUFFER_SIZE * FRAME_BUFFERS, + }, +#endif + .rpm = { + .buf_size = 0x80*2, + }, + .lmem = { + .buf_size = 0x400 * 2, + } + + } +}; + + +/* +* AUX DATA Process +*/ +static u32 init_aux_size; +static int aux_data_is_avaible(struct AV1HW_s *hw) +{ + u32 reg_val; + + reg_val = READ_VREG(HEVC_AUX_DATA_SIZE); + if (reg_val != 0 && reg_val != init_aux_size) + return 1; + else + return 0; +} + +static void config_aux_buf(struct AV1HW_s *hw) +{ + WRITE_VREG(HEVC_AUX_ADR, hw->aux_phy_addr); + init_aux_size = ((hw->prefix_aux_size >> 4) << 16) | + (hw->suffix_aux_size >> 4); + WRITE_VREG(HEVC_AUX_DATA_SIZE, init_aux_size); +} + +/* +* dv_meta_flag: 1, dolby meta (T35) only; 2, not include dolby meta (T35) +*/ +static void set_aux_data(struct AV1HW_s *hw, + char **aux_data_buf, int *aux_data_size, + unsigned char suffix_flag, + unsigned char dv_meta_flag) +{ + int i; + unsigned short *aux_adr; + unsigned int size_reg_val = + READ_VREG(HEVC_AUX_DATA_SIZE); + unsigned int aux_count = 0; + int aux_size = 0; + if (0 == aux_data_is_avaible(hw)) + return; + + if (hw->aux_data_dirty || + hw->m_ins_flag == 0) { + + hw->aux_data_dirty = 0; + } + + if (suffix_flag) { + aux_adr = (unsigned short *) + (hw->aux_addr + + hw->prefix_aux_size); + aux_count = + ((size_reg_val & 0xffff) << 4) + >> 1; + aux_size = + hw->suffix_aux_size; + } else { + aux_adr = + (unsigned short *)hw->aux_addr; + aux_count = + ((size_reg_val >> 16) << 4) + >> 1; + aux_size = + hw->prefix_aux_size; + } + if (debug & AV1_DEBUG_BUFMGR_MORE) { + av1_print(hw, 0, + "%s:old size %d count %d,suf %d dv_flag %d\r\n", + __func__, *aux_data_size, + aux_count, suffix_flag, dv_meta_flag); + } + if (aux_size > 0 && aux_count > 0) { + int heads_size = 0; + int new_size; + char *new_buf; + + for (i = 0; i < aux_count; i++) { + unsigned char tag = aux_adr[i] >> 8; + if (tag != 0 && tag != 0xff) { + if (dv_meta_flag == 0) + heads_size += 8; + else if (dv_meta_flag == 1 && tag == 0x14) + heads_size += 8; + else if (dv_meta_flag == 2 && tag != 0x14) + heads_size += 8; + } + } + new_size = *aux_data_size + aux_count + heads_size; + new_buf = vmalloc(new_size); + if (new_buf) { + unsigned char valid_tag = 0; + unsigned char *h = + new_buf + + *aux_data_size; + unsigned char *p = h + 8; + int len = 0; + int padding_len = 0; + if (*aux_data_buf) { + memcpy(new_buf, *aux_data_buf, *aux_data_size); + vfree(*aux_data_buf); + } + *aux_data_buf = new_buf; + for (i = 0; i < aux_count; i += 4) { + int ii; + unsigned char tag = aux_adr[i + 3] >> 8; + if (tag != 0 && tag != 0xff) { + if (dv_meta_flag == 0) + valid_tag = 1; + else if (dv_meta_flag == 1 + && tag == 0x14) + valid_tag = 1; + else if (dv_meta_flag == 2 + && tag != 0x14) + valid_tag = 1; + else + valid_tag = 0; + if (valid_tag && len > 0) { + *aux_data_size += + (len + 8); + h[0] = (len >> 24) + & 0xff; + h[1] = (len >> 16) + & 0xff; + h[2] = (len >> 8) + & 0xff; + h[3] = (len >> 0) + & 0xff; + h[6] = + (padding_len >> 8) + & 0xff; + h[7] = (padding_len) + & 0xff; + h += (len + 8); + p += 8; + len = 0; + padding_len = 0; + } + if (valid_tag) { + h[4] = tag; + h[5] = 0; + h[6] = 0; + h[7] = 0; + } + } + if (valid_tag) { + for (ii = 0; ii < 4; ii++) { + unsigned short aa = + aux_adr[i + 3 + - ii]; + *p = aa & 0xff; + p++; + len++; + if ((aa >> 8) == 0xff) + padding_len++; + } + } + } + if (len > 0) { + *aux_data_size += (len + 8); + h[0] = (len >> 24) & 0xff; + h[1] = (len >> 16) & 0xff; + h[2] = (len >> 8) & 0xff; + h[3] = (len >> 0) & 0xff; + h[6] = (padding_len >> 8) & 0xff; + h[7] = (padding_len) & 0xff; + } + if (debug & AV1_DEBUG_BUFMGR_MORE) { + av1_print(hw, 0, + "aux: (size %d) suffix_flag %d\n", + *aux_data_size, suffix_flag); + for (i = 0; i < *aux_data_size; i++) { + av1_print_cont(hw, 0, + "%02x ", (*aux_data_buf)[i]); + if (((i + 1) & 0xf) == 0) + av1_print_cont(hw, 0, "\n"); + } + av1_print_cont(hw, 0, "\n"); + } + + } else { + av1_print(hw, 0, "new buf alloc failed\n"); + if (*aux_data_buf) + vfree(*aux_data_buf); + *aux_data_buf = NULL; + *aux_data_size = 0; + } + } + +} + +static void set_dv_data(struct AV1HW_s *hw) +{ + set_aux_data(hw, &hw->dv_data_buf, + &hw->dv_data_size, 0, 1); + +} + +static void set_pic_aux_data(struct AV1HW_s *hw, + struct PIC_BUFFER_CONFIG_s *pic, unsigned char suffix_flag, + unsigned char dv_meta_flag) +{ + if (pic == NULL) + return; + set_aux_data(hw, &pic->aux_data_buf, + &pic->aux_data_size, suffix_flag, dv_meta_flag); +} + +static void copy_dv_data(struct AV1HW_s *hw, + struct PIC_BUFFER_CONFIG_s *pic) +{ + char *new_buf; + int new_size; + new_size = pic->aux_data_size + hw->dv_data_size; + new_buf = vmalloc(new_size); + if (new_buf) { + if (debug & AV1_DEBUG_BUFMGR_MORE) { + av1_print(hw, 0, + "%s: (size %d) pic index %d\n", + __func__, + hw->dv_data_size, pic->index); + } + if (pic->aux_data_buf) { + memcpy(new_buf, pic->aux_data_buf, pic->aux_data_size); + vfree(pic->aux_data_buf); + } + memcpy(new_buf + pic->aux_data_size, hw->dv_data_buf, hw->dv_data_size); + pic->aux_data_size += hw->dv_data_size; + pic->aux_data_buf = new_buf; + vfree(hw->dv_data_buf); + hw->dv_data_buf = NULL; + hw->dv_data_size = 0; + } + +} + +static void release_aux_data(struct AV1HW_s *hw, + struct PIC_BUFFER_CONFIG_s *pic) +{ + if (pic->aux_data_buf) + vfree(pic->aux_data_buf); + pic->aux_data_buf = NULL; + pic->aux_data_size = 0; +} + +static void dump_aux_buf(struct AV1HW_s *hw) +{ + int i; + unsigned short *aux_adr = + (unsigned short *) + hw->aux_addr; + unsigned int aux_size = + (READ_VREG(HEVC_AUX_DATA_SIZE) + >> 16) << 4; + + if (hw->prefix_aux_size > 0) { + av1_print(hw, 0, + "prefix aux: (size %d)\n", + aux_size); + for (i = 0; i < + (aux_size >> 1); i++) { + av1_print_cont(hw, 0, + "%04x ", + *(aux_adr + i)); + if (((i + 1) & 0xf) + == 0) + av1_print_cont(hw, + 0, "\n"); + } + } + if (hw->suffix_aux_size > 0) { + aux_adr = (unsigned short *) + (hw->aux_addr + + hw->prefix_aux_size); + aux_size = + (READ_VREG(HEVC_AUX_DATA_SIZE) & 0xffff) + << 4; + av1_print(hw, 0, + "suffix aux: (size %d)\n", + aux_size); + for (i = 0; i < + (aux_size >> 1); i++) { + av1_print_cont(hw, 0, + "%04x ", *(aux_adr + i)); + if (((i + 1) & 0xf) == 0) + av1_print_cont(hw, 0, "\n"); + } + } +} + +/* +* +*/ + +/*Losless compression body buffer size 4K per 64x32 (jt)*/ +static int compute_losless_comp_body_size(int width, int height, + uint8_t is_bit_depth_10) +{ + int width_x64; + int height_x32; + int bsize; + + width_x64 = width + 63; + width_x64 >>= 6; + height_x32 = height + 31; + height_x32 >>= 5; + bsize = (is_bit_depth_10?4096:3200)*width_x64*height_x32; + if (debug & AV1_DEBUG_BUFMGR_MORE) + pr_info("%s(%d,%d,%d)=>%d\n", + __func__, width, height, + is_bit_depth_10, bsize); + + return bsize; +} + +/* Losless compression header buffer size 32bytes per 128x64 (jt)*/ +static int compute_losless_comp_header_size(int width, int height) +{ + int width_x128; + int height_x64; + int hsize; + + width_x128 = width + 127; + width_x128 >>= 7; + height_x64 = height + 63; + height_x64 >>= 6; + + hsize = 32 * width_x128 * height_x64; + if (debug & AV1_DEBUG_BUFMGR_MORE) + pr_info("%s(%d,%d)=>%d\n", + __func__, width, height, + hsize); + + return hsize; +} + +#ifdef AOM_AV1_MMU_DW +static int compute_losless_comp_body_size_dw(int width, int height, + uint8_t is_bit_depth_10) +{ + + return compute_losless_comp_body_size(width, height, is_bit_depth_10); +} + +/* Losless compression header buffer size 32bytes per 128x64 (jt)*/ +static int compute_losless_comp_header_size_dw(int width, int height) +{ + return compute_losless_comp_header_size(width, height); +} +#endif + +static void init_buff_spec(struct AV1HW_s *hw, + struct BuffInfo_s *buf_spec) +{ + void *mem_start_virt; + + buf_spec->ipp.buf_start = + buf_spec->start_adr; + buf_spec->sao_abv.buf_start = + buf_spec->ipp.buf_start + buf_spec->ipp.buf_size; + + buf_spec->sao_vb.buf_start = + buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size; + buf_spec->short_term_rps.buf_start = + buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size; + buf_spec->vps.buf_start = + buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size; + buf_spec->seg_map.buf_start = + buf_spec->vps.buf_start + buf_spec->vps.buf_size; + buf_spec->daala_top.buf_start = + buf_spec->seg_map.buf_start + buf_spec->seg_map.buf_size; + buf_spec->sao_up.buf_start = + buf_spec->daala_top.buf_start + buf_spec->daala_top.buf_size; + buf_spec->swap_buf.buf_start = + buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size; + buf_spec->cdf_buf.buf_start = + buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size; + buf_spec->gmc_buf.buf_start = + buf_spec->cdf_buf.buf_start + buf_spec->cdf_buf.buf_size; + buf_spec->scalelut.buf_start = + buf_spec->gmc_buf.buf_start + buf_spec->gmc_buf.buf_size; + buf_spec->dblk_para.buf_start = + buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size; + buf_spec->dblk_data.buf_start = + buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size; + buf_spec->cdef_data.buf_start = + buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size; + buf_spec->ups_data.buf_start = + buf_spec->cdef_data.buf_start + buf_spec->cdef_data.buf_size; + buf_spec->fgs_table.buf_start = + buf_spec->ups_data.buf_start + buf_spec->ups_data.buf_size; +#ifdef AOM_AV1_MMU + buf_spec->mmu_vbh.buf_start = + buf_spec->fgs_table.buf_start + buf_spec->fgs_table.buf_size; + buf_spec->cm_header.buf_start = + buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size; +#ifdef AOM_AV1_MMU_DW + buf_spec->mmu_vbh_dw.buf_start = + buf_spec->cm_header.buf_start + buf_spec->cm_header.buf_size; + buf_spec->cm_header_dw.buf_start = + buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size; + buf_spec->mpred_above.buf_start = + buf_spec->cm_header_dw.buf_start + buf_spec->cm_header_dw.buf_size; +#else + buf_spec->mpred_above.buf_start = + buf_spec->cm_header.buf_start + buf_spec->cm_header.buf_size; +#endif +#else + buf_spec->mpred_above.buf_start = + buf_spec->fgs_table.buf_start + buf_spec->fgs_table.buf_size; +#endif + +#ifdef MV_USE_FIXED_BUF + buf_spec->mpred_mv.buf_start = + buf_spec->mpred_above.buf_start + + buf_spec->mpred_above.buf_size; + + buf_spec->rpm.buf_start = + buf_spec->mpred_mv.buf_start + + buf_spec->mpred_mv.buf_size; +#else + buf_spec->rpm.buf_start = + buf_spec->mpred_above.buf_start + + buf_spec->mpred_above.buf_size; + +#endif + buf_spec->lmem.buf_start = + buf_spec->rpm.buf_start + + buf_spec->rpm.buf_size; + buf_spec->end_adr = + buf_spec->lmem.buf_start + + buf_spec->lmem.buf_size; + + if (!hw) + return; + + if (!vdec_secure(hw_to_vdec(hw))) { + mem_start_virt = + codec_mm_phys_to_virt(buf_spec->dblk_para.buf_start); + if (mem_start_virt) { + memset(mem_start_virt, 0, + buf_spec->dblk_para.buf_size); + codec_mm_dma_flush(mem_start_virt, + buf_spec->dblk_para.buf_size, + DMA_TO_DEVICE); + } else { + mem_start_virt = codec_mm_vmap( + buf_spec->dblk_para.buf_start, + buf_spec->dblk_para.buf_size); + if (mem_start_virt) { + memset(mem_start_virt, 0, + buf_spec->dblk_para.buf_size); + codec_mm_dma_flush(mem_start_virt, + buf_spec->dblk_para.buf_size, + DMA_TO_DEVICE); + codec_mm_unmap_phyaddr(mem_start_virt); + } else { + /*not virt for tvp playing, + may need clear on ucode.*/ + pr_err("mem_start_virt failed\n"); + } + } + } + + if (debug) { + pr_info("%s workspace (%x %x) size = %x\n", __func__, + buf_spec->start_adr, buf_spec->end_adr, + buf_spec->end_adr - buf_spec->start_adr); + } + + if (debug) { + pr_info("ipp.buf_start :%x\n", + buf_spec->ipp.buf_start); + pr_info("sao_abv.buf_start :%x\n", + buf_spec->sao_abv.buf_start); + pr_info("sao_vb.buf_start :%x\n", + buf_spec->sao_vb.buf_start); + pr_info("short_term_rps.buf_start :%x\n", + buf_spec->short_term_rps.buf_start); + pr_info("vps.buf_start :%x\n", + buf_spec->vps.buf_start); + pr_info("seg_map.buf_start :%x\n", + buf_spec->seg_map.buf_start); + pr_info("daala_top.buf_start :%x\n", + buf_spec->daala_top.buf_start); + pr_info("swap_buf.buf_start :%x\n", + buf_spec->swap_buf.buf_start); + pr_info("cdf_buf.buf_start :%x\n", + buf_spec->cdf_buf.buf_start); + pr_info("gmc_buf.buf_start :%x\n", + buf_spec->gmc_buf.buf_start); + pr_info("scalelut.buf_start :%x\n", + buf_spec->scalelut.buf_start); + pr_info("dblk_para.buf_start :%x\n", + buf_spec->dblk_para.buf_start); + pr_info("dblk_data.buf_start :%x\n", + buf_spec->dblk_data.buf_start); + pr_info("cdef_data.buf_start :%x\n", + buf_spec->cdef_data.buf_start); + pr_info("ups_data.buf_start :%x\n", + buf_spec->ups_data.buf_start); + +#ifdef AOM_AV1_MMU + pr_info("mmu_vbh.buf_start :%x\n", + buf_spec->mmu_vbh.buf_start); +#endif + pr_info("mpred_above.buf_start :%x\n", + buf_spec->mpred_above.buf_start); +#ifdef MV_USE_FIXED_BUF + pr_info("mpred_mv.buf_start :%x\n", + buf_spec->mpred_mv.buf_start); +#endif + if ((debug & AOM_AV1_DEBUG_SEND_PARAM_WITH_REG) == 0) { + pr_info("rpm.buf_start :%x\n", + buf_spec->rpm.buf_start); + } + } +} + + + +static void uninit_mmu_buffers(struct AV1HW_s *hw) +{ +#ifndef MV_USE_FIXED_BUF + dealloc_mv_bufs(hw); +#endif + if (hw->mmu_box) + decoder_mmu_box_free(hw->mmu_box); + hw->mmu_box = NULL; + +#ifdef AOM_AV1_MMU_DW + if (hw->mmu_box_dw) + decoder_mmu_box_free(hw->mmu_box_dw); + hw->mmu_box_dw = NULL; +#endif + if (hw->bmmu_box) + decoder_bmmu_box_free(hw->bmmu_box); + hw->bmmu_box = NULL; +} + + +static int config_pic(struct AV1HW_s *hw, + struct PIC_BUFFER_CONFIG_s *pic_config) +{ + int ret = -1; + int i; + int pic_width = hw->init_pic_w; + int pic_height = hw->init_pic_h; + //int lcu_size = ((params->p.seq_flags >> 6) & 0x1) ? 128 : 64; + int lcu_size = hw->current_lcu_size; + + int pic_width_64 = (pic_width + 63) & (~0x3f); + int pic_height_32 = (pic_height + 31) & (~0x1f); + int pic_width_lcu = (pic_width_64 % lcu_size) ? + pic_width_64 / lcu_size + 1 + : pic_width_64 / lcu_size; + int pic_height_lcu = (pic_height_32 % lcu_size) ? + pic_height_32 / lcu_size + 1 + : pic_height_32 / lcu_size; + int lcu_total = pic_width_lcu * pic_height_lcu; +#ifdef MV_USE_FIXED_BUF + u32 mpred_mv_end = hw->work_space_buf->mpred_mv.buf_start + + hw->work_space_buf->mpred_mv.buf_size; +#ifdef USE_DYNAMIC_MV_BUFFER + int32_t MV_MEM_UNIT = (lcu_size == 128) ? (19*4*16) : (19*16); + int32_t mv_buffer_size = (lcu_total*MV_MEM_UNIT); +#else + int32_t mv_buffer_size = MAX_ONE_MV_BUFFER_SIZE; +#endif + +#endif + + u32 y_adr = 0; + int buf_size = 0; + + int losless_comp_header_size = + compute_losless_comp_header_size(pic_width, + pic_height); + int losless_comp_body_size = compute_losless_comp_body_size(pic_width, + pic_height, buf_alloc_depth == 10); + int mc_buffer_size = losless_comp_header_size + losless_comp_body_size; + int mc_buffer_size_h = (mc_buffer_size + 0xffff) >> 16; + int mc_buffer_size_u_v = 0; + int mc_buffer_size_u_v_h = 0; + int dw_mode = get_double_write_mode_init(hw); + struct vdec_v4l2_buffer *fb = NULL; + + hw->lcu_total = lcu_total; + + if (dw_mode && (dw_mode & 0x20) == 0) { + int pic_width_dw = pic_width / + get_double_write_ratio(hw, dw_mode); + int pic_height_dw = pic_height / + get_double_write_ratio(hw, dw_mode); + + int pic_width_64_dw = (pic_width_dw + 63) & (~0x3f); + int pic_height_32_dw = (pic_height_dw + 31) & (~0x1f); + int pic_width_lcu_dw = (pic_width_64_dw % lcu_size) ? + pic_width_64_dw / lcu_size + 1 + : pic_width_64_dw / lcu_size; + int pic_height_lcu_dw = (pic_height_32_dw % lcu_size) ? + pic_height_32_dw / lcu_size + 1 + : pic_height_32_dw / lcu_size; + int lcu_total_dw = pic_width_lcu_dw * pic_height_lcu_dw; + mc_buffer_size_u_v = lcu_total_dw * lcu_size * lcu_size / 2; + mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff) >> 16; + /*64k alignment*/ + buf_size = ((mc_buffer_size_u_v_h << 16) * 3); + buf_size = ((buf_size + 0xffff) >> 16) << 16; + } + + if (mc_buffer_size & 0xffff) /*64k alignment*/ + mc_buffer_size_h += 1; + if ((!hw->mmu_enable) && ((dw_mode & 0x10) == 0)) + buf_size += (mc_buffer_size_h << 16); + +#ifdef USE_SPEC_BUF_FOR_MMU_HEAD + if (hw->mmu_enable) { + pic_config->header_adr = + hw->work_space_buf->cm_header.buf_start + + (pic_config->index * MMU_COMPRESS_HEADER_SIZE); + +#ifdef AOM_AV1_MMU_DW + if (hw->dw_mmu_enable) { + pic_config->header_dw_adr = + hw->work_space_buf->cm_header_dw.buf_start + + (pic_config->index * MMU_COMPRESS_HEADER_SIZE_DW); + + } +#endif + } + +#else +/*!USE_SPEC_BUF_FOR_MMU_HEAD*/ + if (hw->mmu_enable) { + pic_config->header_adr = decoder_bmmu_box_get_phy_addr( + hw->bmmu_box, HEADER_BUFFER_IDX(pic_config->index)); + +#ifdef AOM_AV1_MMU_DW + if (hw->dw_mmu_enable) { + pic_config->header_dw_adr = decoder_bmmu_box_get_phy_addr( + hw->bmmu_box, DW_HEADER_BUFFER_IDX(pic_config->index)); + + } + if (debug & AV1_DEBUG_BUFMGR_MORE) { + pr_info("MMU dw header_adr (%d, %d) %d: %d\n", + hw->dw_mmu_enable, + DW_HEADER_BUFFER_IDX(pic_config->index), + pic_config->index, + pic_config->header_dw_adr); + } +#endif + + if (debug & AV1_DEBUG_BUFMGR_MORE) { + pr_info("MMU header_adr %d: %d\n", + pic_config->index, pic_config->header_adr); + } + } +#endif + + i = pic_config->index; +#ifdef MV_USE_FIXED_BUF + if ((hw->work_space_buf->mpred_mv.buf_start + + ((i + 1) * mv_buffer_size)) + <= mpred_mv_end + ) { +#endif + if (buf_size > 0) { + if (hw->is_used_v4l) { +#ifdef SUPPORT_V4L2 + ret = vdec_v4l_get_buffer(hw->v4l2_ctx, &fb); +#endif + if (ret) { + av1_print(hw, PRINT_FLAG_ERROR, + "[%d] get fb fail.\n", + ((struct aml_vcodec_ctx *) + (hw->v4l2_ctx))->id); + return ret; + } + + hw->m_BUF[i].v4l_ref_buf_addr = (ulong)fb; +#ifdef SUPPORT_V4L2 + pic_config->cma_alloc_addr = fb->m.mem[0].addr; +#endif + av1_print(hw, PRINT_FLAG_V4L_DETAIL, + "[%d] %s(), v4l ref buf addr: 0x%x\n", + ((struct aml_vcodec_ctx *) + (hw->v4l2_ctx))->id, __func__, fb); + } else { + ret = decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, + VF_BUFFER_IDX(i), + buf_size, DRIVER_NAME, + &pic_config->cma_alloc_addr); + if (ret < 0) { + pr_info( + "decoder_bmmu_box_alloc_buf_phy idx %d size %d fail\n", + VF_BUFFER_IDX(i), + buf_size + ); + return ret; + } + } + + if (pic_config->cma_alloc_addr) + y_adr = pic_config->cma_alloc_addr; + else { + pr_info( + "decoder_bmmu_box_alloc_buf_phy idx %d size %d return null\n", + VF_BUFFER_IDX(i), + buf_size + ); + return -1; + } + } + { + /*ensure get_pic_by_POC() + not get the buffer not decoded*/ + pic_config->BUF_index = i; + pic_config->lcu_total = lcu_total; + + pic_config->comp_body_size = losless_comp_body_size; + pic_config->buf_size = buf_size; + + pic_config->mc_canvas_y = pic_config->index; + pic_config->mc_canvas_u_v = pic_config->index; + if (dw_mode & 0x10) { + pic_config->dw_y_adr = y_adr; + pic_config->dw_u_v_adr = y_adr + + ((mc_buffer_size_u_v_h << 16) << 1); + + pic_config->mc_canvas_y = + (pic_config->index << 1); + pic_config->mc_canvas_u_v = + (pic_config->index << 1) + 1; + } else if (dw_mode && (dw_mode & 0x20) == 0) { + pic_config->dw_y_adr = y_adr; + pic_config->dw_u_v_adr = pic_config->dw_y_adr + + ((mc_buffer_size_u_v_h << 16) << 1); + } +#ifdef MV_USE_FIXED_BUF + pic_config->mpred_mv_wr_start_addr = + hw->work_space_buf->mpred_mv.buf_start + + (pic_config->index * mv_buffer_size); +#endif +#ifdef DUMP_FILMGRAIN + if (pic_config->index == fg_dump_index) { + pic_config->fgs_table_adr = hw->fg_phy_addr; + pr_info("set buffer %d film grain table 0x%x\n", + pic_config->index, pic_config->fgs_table_adr); + } else +#endif + pic_config->fgs_table_adr = + hw->work_space_buf->fgs_table.buf_start + + (pic_config->index * FGS_TABLE_SIZE); + + if (debug) { + pr_info + ("%s index %d BUF_index %d ", + __func__, pic_config->index, + pic_config->BUF_index); + pr_info + ("comp_body_size %x comp_buf_size %x ", + pic_config->comp_body_size, + pic_config->buf_size); + pr_info + ("mpred_mv_wr_start_adr %d\n", + pic_config->mpred_mv_wr_start_addr); + pr_info("dw_y_adr %d, pic_config->dw_u_v_adr =%d\n", + pic_config->dw_y_adr, + pic_config->dw_u_v_adr); + } + ret = 0; + } +#ifdef MV_USE_FIXED_BUF + } +#endif + return ret; +} + +#ifndef USE_SPEC_BUF_FOR_MMU_HEAD +static int vav1_mmu_compress_header_size(struct AV1HW_s *hw) +{ + if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && + IS_8K_SIZE(hw->max_pic_w, hw->max_pic_h)) + return (MMU_COMPRESS_8K_HEADER_SIZE); + + return (MMU_COMPRESS_HEADER_SIZE); +} +#endif +/*#define FRAME_MMU_MAP_SIZE (MAX_FRAME_4K_NUM * 4)*/ +static int vav1_frame_mmu_map_size(struct AV1HW_s *hw) +{ + if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && + IS_8K_SIZE(hw->max_pic_w, hw->max_pic_h)) + return (MAX_FRAME_8K_NUM * 4); + + return (MAX_FRAME_4K_NUM * 4); +} + +#ifdef AOM_AV1_MMU_DW +static int vaom_dw_frame_mmu_map_size(struct AV1HW_s *hw) +{ + if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && + IS_8K_SIZE(hw->max_pic_w, hw->max_pic_h)) + return (MAX_FRAME_8K_NUM * 4); + + return (MAX_FRAME_4K_NUM * 4); +} +#endif + +static void init_pic_list(struct AV1HW_s *hw) +{ + int i; + struct AV1_Common_s *cm = &hw->pbi->common; + struct PIC_BUFFER_CONFIG_s *pic_config; + struct vdec_s *vdec = hw_to_vdec(hw); + +#ifndef USE_SPEC_BUF_FOR_MMU_HEAD + u32 header_size; + if (hw->mmu_enable && ((hw->double_write_mode & 0x10) == 0)) { + header_size = vav1_mmu_compress_header_size(hw); + /*alloc AV1 compress header first*/ + for (i = 0; i < hw->used_buf_num; i++) { + unsigned long buf_addr; + if (decoder_bmmu_box_alloc_buf_phy + (hw->bmmu_box, + HEADER_BUFFER_IDX(i), header_size, + DRIVER_HEADER_NAME, + &buf_addr) < 0) { + av1_print(hw, 0, "%s malloc compress header failed %d\n", + DRIVER_HEADER_NAME, i); + hw->fatal_error |= DECODER_FATAL_ERROR_NO_MEM; + return; + } +#ifdef AOM_AV1_MMU_DW + if (hw->dw_mmu_enable) { + if (decoder_bmmu_box_alloc_buf_phy + (hw->bmmu_box, + DW_HEADER_BUFFER_IDX(i), header_size, + DRIVER_HEADER_NAME, + &buf_addr) < 0) { + av1_print(hw, 0, "%s malloc compress dw header failed %d\n", + DRIVER_HEADER_NAME, i); + hw->fatal_error |= DECODER_FATAL_ERROR_NO_MEM; + return; + } + } +#endif + } + } +#endif + for (i = 0; i < hw->used_buf_num; i++) { + pic_config = &cm->buffer_pool->frame_bufs[i].buf; + pic_config->index = i; + pic_config->BUF_index = -1; + pic_config->mv_buf_index = -1; + if (vdec->parallel_dec == 1) { + pic_config->y_canvas_index = -1; + pic_config->uv_canvas_index = -1; + } + if (config_pic(hw, pic_config) < 0) { + if (debug) + av1_print(hw, 0, "Config_pic %d fail\n", + pic_config->index); + pic_config->index = -1; + break; + } + pic_config->y_crop_width = hw->init_pic_w; + pic_config->y_crop_height = hw->init_pic_h; + pic_config->double_write_mode = get_double_write_mode(hw); + + if (pic_config->double_write_mode && + (pic_config->double_write_mode & 0x20) == 0) { + set_canvas(hw, pic_config); + } + } + for (; i < hw->used_buf_num; i++) { + pic_config = &cm->buffer_pool->frame_bufs[i].buf; + pic_config->index = -1; + pic_config->BUF_index = -1; + pic_config->mv_buf_index = -1; + if (vdec->parallel_dec == 1) { + pic_config->y_canvas_index = -1; + pic_config->uv_canvas_index = -1; + } + } + av1_print(hw, AV1_DEBUG_BUFMGR, "%s ok, used_buf_num = %d\n", + __func__, hw->used_buf_num); + +} + +static void init_pic_list_hw(struct AV1HW_s *hw) +{ + int i; + struct AV1_Common_s *cm = &hw->pbi->common; + struct PIC_BUFFER_CONFIG_s *pic_config; + /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x0);*/ + WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, + (0x1 << 1) | (0x1 << 2)); + + + for (i = 0; i < hw->used_buf_num; i++) { + pic_config = &cm->buffer_pool->frame_bufs[i].buf; + if (pic_config->index < 0) + break; + + if (hw->mmu_enable && ((pic_config->double_write_mode & 0x10) == 0)) { + + WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, + pic_config->header_adr >> 5); + } else { + /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, + * pic_config->mc_y_adr + * | (pic_config->mc_canvas_y << 8) | 0x1); + */ + WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, + pic_config->dw_y_adr >> 5); + } +#ifndef LOSLESS_COMPRESS_MODE + /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, + * pic_config->mc_u_v_adr + * | (pic_config->mc_canvas_u_v << 8)| 0x1); + */ + WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, + pic_config->dw_u_v_adr >> 5); +#else + if (pic_config->double_write_mode & 0x10) { + WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, + pic_config->dw_u_v_adr >> 5); + } +#endif + } + WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1); + +#ifdef CHANGE_REMOVED + /*Zero out canvas registers in IPP -- avoid simulation X*/ + WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, + (0 << 8) | (0 << 1) | 1); +#else + WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, + (1 << 8) | (0 << 1) | 1); +#endif + for (i = 0; i < 32; i++) + WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0); +} + + +static void dump_pic_list(struct AV1HW_s *hw) +{ + struct AV1_Common_s *const cm = &hw->pbi->common; + struct PIC_BUFFER_CONFIG_s *pic_config; + int i; + for (i = 0; i < FRAME_BUFFERS; i++) { + pic_config = &cm->buffer_pool->frame_bufs[i].buf; + av1_print(hw, 0, + "Buf(%d) index %d mv_buf_index %d ref_count %d vf_ref %d dec_idx %d slice_type %d w/h %d/%d adr%ld\n", + i, + pic_config->index, +#ifndef MV_USE_FIXED_BUF + pic_config->mv_buf_index, +#else + -1, +#endif + cm->buffer_pool-> + frame_bufs[i].ref_count, + pic_config->vf_ref, + pic_config->decode_idx, + pic_config->slice_type, + pic_config->y_crop_width, + pic_config->y_crop_height, + pic_config->cma_alloc_addr + ); + } + return; +} + +void av1_release_buf(AV1Decoder *pbi, RefCntBuffer *const buf) +{ + +#if 0 + //def CHANGE_DONE + struct AV1HW_s *hw = (struct AV1HW_s *)(pbi->private_data); + if (!hw->mmu_enable) + return; + //release_buffer_4k(&av1_mmumgr_m, buf->buf.index); + decoder_mmu_box_free_idx(hw->mmu_box, buf->buf.index); +#ifdef AOM_AV1_MMU_DW + //release_buffer_4k(&av1_mmumgr_dw, buf->buf.index); + decoder_mmu_box_free_idx(hw->mmu_box_dw, buf->buf.index); +#endif + +#endif +} + +void av1_release_bufs(struct AV1HW_s *hw) +{ + /*struct AV1HW_s *hw = (struct AV1HW_s *)(pbi->private_data);*/ + AV1_COMMON *cm = &hw->pbi->common; + RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; + int i; + if (!hw->mmu_enable) + return; + + for (i = 0; i < FRAME_BUFFERS; ++i) { + if (frame_bufs[i].buf.vf_ref == 0 && + frame_bufs[i].ref_count == 0 && + frame_bufs[i].buf.index >= 0) { + //release_buffer_4k(&av1_mmumgr_m, i); + decoder_mmu_box_free_idx(hw->mmu_box, i); +#ifdef AOM_AV1_MMU_DW + //release_buffer_4k(&av1_mmumgr_dw, i); + if (hw->dw_mmu_enable) + decoder_mmu_box_free_idx(hw->mmu_box_dw, i); +#endif + if (frame_bufs[i].buf.aux_data_buf) + release_aux_data(hw, &frame_bufs[i].buf); + } + } +} + +static int config_pic_size(struct AV1HW_s *hw, unsigned short bit_depth) +{ + uint32_t data32; + struct AV1_Common_s *cm = &hw->pbi->common; + struct PIC_BUFFER_CONFIG_s *cur_pic_config = &cm->cur_frame->buf; + int losless_comp_header_size, losless_comp_body_size; +#ifdef AOM_AV1_MMU_DW + int losless_comp_header_size_dw, losless_comp_body_size_dw; +#endif + av1_print(hw, AOM_DEBUG_HW_MORE, + " #### config_pic_size ####, bit_depth = %d\n", bit_depth); + + frame_width = cur_pic_config->y_crop_width; + frame_height = cur_pic_config->y_crop_height; + cur_pic_config->bit_depth = bit_depth; + cur_pic_config->double_write_mode = get_double_write_mode(hw); + + /* use fixed maximum size // 128x128/4/4*3-bits = 384 Bytes + seg_map_size = + ((frame_width + 127) >> 7) * ((frame_height + 127) >> 7) * 384 ; + */ + WRITE_VREG(HEVC_PARSER_PICTURE_SIZE, + (frame_height << 16) | frame_width); +#ifdef DUAL_DECODE +#else + WRITE_VREG(HEVC_ASSIST_PIC_SIZE_FB_READ, + (frame_height << 16) | frame_width); +#endif +#ifdef AOM_AV1_MMU + + //alloc_mmu(&av1_mmumgr_m, cm->cur_frame->buf.index, frame_width, frame_height, bit_depth); +#endif +#ifdef AOM_AV1_MMU_DW + + //alloc_mmu(&av1_mmumgr_dw, cm->cur_frame->buf.index, frame_width, frame_height, bit_depth); + losless_comp_header_size_dw = + compute_losless_comp_header_size_dw(frame_width, frame_height); + losless_comp_body_size_dw = + compute_losless_comp_body_size_dw(frame_width, frame_height, + (bit_depth == AOM_BITS_10)); +#endif + + losless_comp_header_size = + compute_losless_comp_header_size + (frame_width, frame_height); + losless_comp_body_size = + compute_losless_comp_body_size(frame_width, + frame_height, (bit_depth == AOM_BITS_10)); + + cur_pic_config->comp_body_size = losless_comp_body_size; + + av1_print(hw, AOM_DEBUG_HW_MORE, + "%s: width %d height %d depth %d head_size 0x%x body_size 0x%x\r\n", + __func__, frame_width, frame_height, bit_depth, + losless_comp_header_size, losless_comp_body_size); +#ifdef LOSLESS_COMPRESS_MODE + data32 = READ_VREG(HEVC_SAO_CTRL5); + if (bit_depth == AOM_BITS_10) + data32 &= ~(1<<9); + else + data32 |= (1<<9); + + WRITE_VREG(HEVC_SAO_CTRL5, data32); + + if (hw->mmu_enable) { + WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,(0x1<< 4)); // bit[4] : paged_mem_mode + } else { + if (bit_depth == AOM_BITS_10) + WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3)); // bit[3] smem mdoe + else + WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (1<<3)); // bit[3] smem mdoe + } + WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, + (losless_comp_body_size >> 5)); + /* + WRITE_VREG(HEVCD_MPP_DECOMP_CTL3, + (0xff<<20) | (0xff<<10) | 0xff); //8-bit mode + */ + WRITE_VREG(HEVC_CM_BODY_LENGTH, + losless_comp_body_size); + WRITE_VREG(HEVC_CM_HEADER_OFFSET, + losless_comp_body_size); + WRITE_VREG(HEVC_CM_HEADER_LENGTH, + losless_comp_header_size); + + if (get_double_write_mode(hw) & 0x10) + WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31); + +#else + WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,0x1 << 31); +#endif +#ifdef AOM_AV1_MMU_DW + if (hw->dw_mmu_enable) { + WRITE_VREG(HEVC_CM_BODY_LENGTH2, losless_comp_body_size_dw); + WRITE_VREG(HEVC_CM_HEADER_OFFSET2, losless_comp_body_size_dw); + WRITE_VREG(HEVC_CM_HEADER_LENGTH2, losless_comp_header_size_dw); + } +#endif + return 0; + +} + +static int config_mc_buffer(struct AV1HW_s *hw, unsigned short bit_depth, unsigned char inter_flag) +{ + int32_t i; + AV1_COMMON *cm = &hw->pbi->common; + PIC_BUFFER_CONFIG* cur_pic_config = &cm->cur_frame->buf; + uint8_t scale_enable = 0; + + av1_print(hw, AOM_DEBUG_HW_MORE, + " #### config_mc_buffer %s ####\n", + inter_flag ? "inter" : "intra"); + +#ifdef DEBUG_PRINT + if (debug&AOM_AV1_DEBUG_BUFMGR) + av1_print(hw, AOM_DEBUG_HW_MORE, + "config_mc_buffer entered .....\n"); +#endif + + WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, + (0 << 8) | (0<<1) | 1); + WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, + (cur_pic_config->order_hint<<24) | + (cur_pic_config->mc_canvas_u_v<<16) | + (cur_pic_config->mc_canvas_u_v<<8)| + cur_pic_config->mc_canvas_y); + for (i = LAST_FRAME; i <= ALTREF_FRAME; i++) { + PIC_BUFFER_CONFIG *pic_config; //cm->frame_refs[i].buf; + if (inter_flag) + pic_config = av1_get_ref_frame_spec_buf(cm, i); + else + pic_config = cur_pic_config; + if (pic_config) { + WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, + (pic_config->order_hint<<24) | + (pic_config->mc_canvas_u_v<<16) | + (pic_config->mc_canvas_u_v<<8) | + pic_config->mc_canvas_y); + if (inter_flag) + av1_print(hw, AOM_DEBUG_HW_MORE, + "refid 0x%x mc_canvas_u_v 0x%x mc_canvas_y 0x%x order_hint 0x%x\n", + i, pic_config->mc_canvas_u_v, + pic_config->mc_canvas_y, pic_config->order_hint); + } else { + WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0); + } + } + + WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, + (16 << 8) | (0 << 1) | 1); + WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, + (cur_pic_config->order_hint << 24) | + (cur_pic_config->mc_canvas_u_v << 16) | + (cur_pic_config->mc_canvas_u_v << 8) | + cur_pic_config->mc_canvas_y); + for (i = LAST_FRAME; i <= ALTREF_FRAME; i++) { + PIC_BUFFER_CONFIG *pic_config; + if (inter_flag) + pic_config = av1_get_ref_frame_spec_buf(cm, i); + else + pic_config = cur_pic_config; + + if (pic_config) { + WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, + (pic_config->order_hint << 24)| + (pic_config->mc_canvas_u_v << 16) | + (pic_config->mc_canvas_u_v << 8) | + pic_config->mc_canvas_y); + } else { + WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0); + } + } + + WRITE_VREG(AV1D_MPP_REFINFO_TBL_ACCCONFIG, + (0x1 << 2) | (0x0 <<3)); // auto_inc start index:0 field:0 + for (i = 0; i <= ALTREF_FRAME; i++) { + int32_t ref_pic_body_size; + struct scale_factors * sf = NULL; + PIC_BUFFER_CONFIG *pic_config; + + if (inter_flag && i >= LAST_FRAME) + pic_config = av1_get_ref_frame_spec_buf(cm, i); + else + pic_config = cur_pic_config; + + if (pic_config) { + ref_pic_body_size = + compute_losless_comp_body_size(pic_config->y_crop_width, + pic_config->y_crop_height, (bit_depth == AOM_BITS_10)); + + WRITE_VREG(AV1D_MPP_REFINFO_DATA, pic_config->y_crop_width); + WRITE_VREG(AV1D_MPP_REFINFO_DATA, pic_config->y_crop_height); + if (inter_flag && i >= LAST_FRAME) { + av1_print(hw, AOM_DEBUG_HW_MORE, + "refid %d: ref width/height(%d,%d), cur width/height(%d,%d) ref_pic_body_size 0x%x\n", + i, pic_config->y_crop_width, pic_config->y_crop_height, + cur_pic_config->y_crop_width, cur_pic_config->y_crop_height, + ref_pic_body_size); + } + } else { + ref_pic_body_size = 0; + WRITE_VREG(AV1D_MPP_REFINFO_DATA, 0); + WRITE_VREG(AV1D_MPP_REFINFO_DATA, 0); + } + + if (inter_flag && i >= LAST_FRAME) + sf = av1_get_ref_scale_factors(cm, i); + + if ((sf != NULL) && av1_is_scaled(sf)) { + scale_enable |= (1 << i); + } + + if (sf) { + WRITE_VREG(AV1D_MPP_REFINFO_DATA, sf->x_scale_fp); + WRITE_VREG(AV1D_MPP_REFINFO_DATA, sf->y_scale_fp); + + av1_print(hw, AOM_DEBUG_HW_MORE, + "x_scale_fp %d, y_scale_fp %d\n", + sf->x_scale_fp, sf->y_scale_fp); + } else { + WRITE_VREG(AV1D_MPP_REFINFO_DATA, REF_NO_SCALE); //1<<14 + WRITE_VREG(AV1D_MPP_REFINFO_DATA, REF_NO_SCALE); + } + if (hw->mmu_enable) + WRITE_VREG(AV1D_MPP_REFINFO_DATA, 0); + else + WRITE_VREG(AV1D_MPP_REFINFO_DATA, + ref_pic_body_size >> 5); + } + WRITE_VREG(AV1D_MPP_REF_SCALE_ENBL, scale_enable); + WRITE_VREG(PARSER_REF_SCALE_ENBL, scale_enable); + av1_print(hw, AOM_DEBUG_HW_MORE, + "WRITE_VREG(PARSER_REF_SCALE_ENBL, 0x%x)\n", + scale_enable); + return 0; +} + +static void clear_mpred_hw(struct AV1HW_s *hw) +{ + unsigned int data32; + + data32 = READ_VREG(HEVC_MPRED_CTRL4); + data32 &= (~(1 << 6)); + WRITE_VREG(HEVC_MPRED_CTRL4, data32); +} + +static void config_mpred_hw(struct AV1HW_s *hw, unsigned char inter_flag) +{ + AV1_COMMON *cm = &hw->pbi->common; + PIC_BUFFER_CONFIG *cur_pic_config = &cm->cur_frame->buf; + //PIC_BUFFER_CONFIG *last_frame_pic_config = NULL; + int i, j, pos, reg_i; + int mv_cal_tpl_count = 0; + unsigned int mv_ref_id[MFMV_STACK_SIZE] = {0, 0, 0}; + unsigned ref_offset_reg[] = { + HEVC_MPRED_L0_REF06_POC, + HEVC_MPRED_L0_REF07_POC, + HEVC_MPRED_L0_REF08_POC, + HEVC_MPRED_L0_REF09_POC, + HEVC_MPRED_L0_REF10_POC, + HEVC_MPRED_L0_REF11_POC, + }; + unsigned ref_buf_reg[] = { + HEVC_MPRED_L0_REF03_POC, + HEVC_MPRED_L0_REF04_POC, + HEVC_MPRED_L0_REF05_POC + }; + unsigned ref_offset_val[6] = + {0, 0, 0, 0, 0, 0}; + unsigned ref_buf_val[3] = {0, 0, 0}; + + uint32_t data32; + int32_t mpred_curr_lcu_x; + int32_t mpred_curr_lcu_y; + //int32_t mpred_mv_rd_end_addr; + + av1_print(hw, AOM_DEBUG_HW_MORE, + " #### config_mpred_hw ####\n"); + + /*if (cm->prev_frame) + last_frame_pic_config = &cm->prev_frame->buf; + mpred_mv_rd_end_addr = last_frame_pic_config->mpred_mv_wr_start_addr + + (last_frame_pic_config->lcu_total * MV_MEM_UNIT); + */ + + data32 = READ_VREG(HEVC_MPRED_CURR_LCU); + mpred_curr_lcu_x =data32 & 0xffff; + mpred_curr_lcu_y =(data32>>16) & 0xffff; + + av1_print(hw, AOM_DEBUG_HW_MORE, + "cur pic index %d\n", cur_pic_config->index); + /*printk("cur pic index %d col pic index %d\n", + cur_pic_config->index, last_frame_pic_config->index);*/ + + //WRITE_VREG(HEVC_MPRED_CTRL3,0x24122412); + WRITE_VREG(HEVC_MPRED_CTRL3, 0x13151315); // 'd19, 'd21 for AV1 + WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, + hw->pbi->work_space_buf->mpred_above.buf_start); + +#if 0 + data32 = READ_VREG(HEVC_MPRED_CTRL4); + data32 &= (~(1<<6)); + data32 |= (cm->use_prev_frame_mvs << 6); + WRITE_VREG(HEVC_MPRED_CTRL4, data32); +#endif + if (inter_flag) { + /* config sign_bias */ + //data32 = (cm->cur_frame_force_integer_mv & 0x1) << 9; + data32 = READ_VREG(HEVC_MPRED_CTRL4); + data32 &= (~(0xff << 12)); + //for (i = LAST_FRAME; i <= ALTREF_FRAME; i++) { + /* HEVC_MPRED_CTRL4[bit 12] is for cm->ref_frame_sign_bias[0] + instead of cm->ref_frame_sign_bias[LAST_FRAME] */ + for (i = 0; i <= ALTREF_FRAME; i++) { + data32 |= ((cm->ref_frame_sign_bias[i] & 0x1) << (12 + i)); + } + WRITE_VREG(HEVC_MPRED_CTRL4, data32); + av1_print(hw, AOM_DEBUG_HW_MORE, + "WRITE_VREG(HEVC_MPRED_CTRL4, 0x%x)\n", data32); + } +#if 1 + data32 = ( + (cm->seq_params.order_hint_info.enable_order_hint << 27) | + (cm->seq_params.order_hint_info.order_hint_bits_minus_1 << 24) | + (cm->cur_frame->order_hint <<16 ) | + (0x13 << 8) | (0x13 << 0)); +#else + data32 = READ_VREG(HEVC_MPRED_L0_REF00_POC); + data32 &= (~(0xff << 16)); + data32 |= (cm->cur_frame->order_hint & 0xff); + data32 &= (~(1 << 27)); + data32 |= (cm->seq_params.order_hint_info.enable_order_hint << 27); +#endif + WRITE_VREG(HEVC_MPRED_L0_REF00_POC, data32); + av1_print(hw, AOM_DEBUG_HW_MORE, + "WRITE_VREG(HEVC_MPRED_L0_REF00_POC, 0x%x)\n", data32); + + if (inter_flag) { + /* config ref_buf id and order hint */ + data32 = 0; + pos = 25; + reg_i = 0; + for (i = ALTREF_FRAME; i >= LAST_FRAME; i--) { + PIC_BUFFER_CONFIG *pic_config = + av1_get_ref_frame_spec_buf(cm, i); + if (pic_config) { + av1_print(hw, AOM_DEBUG_HW_MORE, + "pic_config for %d th ref: index %d, reg[%d] pos %d\n", + i, pic_config->index, reg_i, pos); + data32 |= ((pic_config->index < 0)? 0 : pic_config->index) << pos; + } else + av1_print(hw, AOM_DEBUG_HW_MORE, + "pic_config is null for %d th ref\n", i); + if (pos == 0) { + //WRITE_VREG(ref_buf_reg[reg_i], data32); + ref_buf_val[reg_i] = data32; + av1_print(hw, AOM_DEBUG_HW_MORE, + "ref_buf_reg[%d], WRITE_VREG(0x%x, 0x%x)\n", + reg_i, ref_buf_reg[reg_i], data32); + reg_i++; + data32 = 0; + pos = 24; //for P_HEVC_MPRED_L0_REF04_POC + } else { + if (pos == 24) + pos -= 8; //for P_HEVC_MPRED_L0_REF04_POC + else + pos -= 5; //for P_HEVC_MPRED_L0_REF03_POC + } + } + for (i = ALTREF_FRAME; i >= LAST_FRAME; i--) { + PIC_BUFFER_CONFIG *pic_config = + av1_get_ref_frame_spec_buf(cm, i); + if (pic_config) { + av1_print(hw, AOM_DEBUG_HW_MORE, + "pic_config for %d th ref: order_hint %d, reg[%d] pos %d\n", + i, pic_config->order_hint, reg_i, pos); + data32 |= ((pic_config->index < 0)? 0 : pic_config->order_hint) << pos; + } else + av1_print(hw, AOM_DEBUG_HW_MORE, + "pic_config is null for %d th ref\n", i); + if (pos == 0) { + //WRITE_VREG(ref_buf_reg[reg_i], data32); + ref_buf_val[reg_i] = data32; + av1_print(hw, AOM_DEBUG_HW_MORE, + "ref_buf_reg[%d], WRITE_VREG(0x%x, 0x%x)\n", + reg_i, ref_buf_reg[reg_i], data32); + reg_i++; + data32 = 0; + pos = 24; + } else + pos -= 8; + } + if (pos != 24) { + //WRITE_VREG(ref_buf_reg[reg_i], data32); + ref_buf_val[reg_i] = data32; + av1_print(hw, AOM_DEBUG_HW_MORE, + "ref_buf_reg[%d], WRITE_VREG(0x%x, 0x%x)\n", + reg_i, ref_buf_reg[reg_i], data32); + } + /* config ref_offset */ + data32 = 0; + pos = 24; + mv_cal_tpl_count = 0; + reg_i = 0; + for (i = 0; i < cm->mv_ref_id_index; i++) { + if (cm->mv_cal_tpl_mvs[i]) { + mv_ref_id[mv_cal_tpl_count] = cm->mv_ref_id[i]; + mv_cal_tpl_count++; + for (j = LAST_FRAME; j <= ALTREF_FRAME; j++) { + /*offset can be negative*/ + unsigned char offval = + cm->mv_ref_offset[i][j] & 0xff; + data32 |= (offval << pos); + if (pos == 0) { + //WRITE_VREG(ref_offset_reg[reg_i], data32); + ref_offset_val[reg_i] = data32; + av1_print(hw, AOM_DEBUG_HW_MORE, + "ref_offset_reg[%d], WRITE_VREG(0x%x, 0x%x)\n", + reg_i, ref_offset_reg[reg_i], data32); + reg_i++; + data32 = 0; + pos = 24; + } else + pos -= 8; + } + } + } + if (pos != 24) { + //WRITE_VREG(ref_offset_reg[reg_i], data32); + ref_offset_val[reg_i] = data32; + av1_print(hw, AOM_DEBUG_HW_MORE, + "ref_offset_reg[%d], WRITE_VREG(0x%x, 0x%x)\n", + reg_i, ref_offset_reg[reg_i], data32); + } + + data32 = ref_offset_val[5] | //READ_VREG(HEVC_MPRED_L0_REF11_POC) | + mv_cal_tpl_count | (mv_ref_id[0] << 2) | + (mv_ref_id[1] << 5) | (mv_ref_id[2] << 8); + ref_offset_val[5] = data32; + //WRITE_VREG(HEVC_MPRED_L0_REF11_POC, data32); + av1_print(hw, AOM_DEBUG_HW_MORE, + "WRITE_VREG(HEVC_MPRED_L0_REF11_POC 0x%x, 0x%x)\n", + HEVC_MPRED_L0_REF11_POC, data32); + } + for (i = 0; i < 3; i++) + WRITE_VREG(ref_buf_reg[i], ref_buf_val[i]); + for (i = 0; i < 6; i++) + WRITE_VREG(ref_offset_reg[i], ref_offset_val[i]); + + WRITE_VREG(HEVC_MPRED_MV_WR_START_ADDR, + cur_pic_config->mpred_mv_wr_start_addr); + WRITE_VREG(HEVC_MPRED_MV_WPTR, + cur_pic_config->mpred_mv_wr_start_addr); + + if (inter_flag) { + for (i = 0; i < mv_cal_tpl_count; i++) { + PIC_BUFFER_CONFIG *pic_config = + av1_get_ref_frame_spec_buf(cm, mv_ref_id[i]); + if (pic_config == NULL) + continue; + if (i == 0) { + WRITE_VREG(HEVC_MPRED_MV_RD_START_ADDR, + pic_config->mpred_mv_wr_start_addr); + WRITE_VREG(HEVC_MPRED_MV_RPTR, + pic_config->mpred_mv_wr_start_addr); + } else if (i == 1) { + WRITE_VREG(HEVC_MPRED_L0_REF01_POC, + pic_config->mpred_mv_wr_start_addr); + WRITE_VREG(HEVC_MPRED_MV_RPTR_1, + pic_config->mpred_mv_wr_start_addr); + } else if (i == 2) { + WRITE_VREG(HEVC_MPRED_L0_REF02_POC, + pic_config->mpred_mv_wr_start_addr); + WRITE_VREG(HEVC_MPRED_MV_RPTR_2, + pic_config->mpred_mv_wr_start_addr); + } else { + av1_print(hw, AOM_DEBUG_HW_MORE, + "%s: mv_ref_id error\n", __func__); + } + } + } + data32 = READ_VREG(HEVC_MPRED_CTRL0); + data32 &= ~((1 << 10) | (1 << 11)); + data32 |= (1 << 10); /*write enable*/ + av1_print(hw, AOM_DEBUG_HW_MORE, + "current_frame.frame_type=%d, cur_frame->frame_type=%d, allow_ref_frame_mvs=%d\n", + cm->current_frame.frame_type, cm->cur_frame->frame_type, + cm->allow_ref_frame_mvs); + + if (av1_frame_is_inter(&hw->pbi->common)) { + if (cm->allow_ref_frame_mvs) { + data32 |= (1 << 11); /*read enable*/ + } + } + av1_print(hw, AOM_DEBUG_HW_MORE, + "WRITE_VREG(HEVC_MPRED_CTRL0 0x%x, 0x%x)\n", + HEVC_MPRED_CTRL0, data32); + WRITE_VREG(HEVC_MPRED_CTRL0, data32); + /* + printk("config_mpred: (%x) wr_start_addr %x from indx %d; + (%x) rd_start_addr %x from index %d\n", + cur_pic_config, cur_pic_config->mpred_mv_wr_start_addr, cur_pic_config->index, + last_frame_pic_config, last_frame_pic_config->mpred_mv_wr_start_addr, last_frame_pic_config->index); + data32 = ((pbi->lcu_x_num - pbi->tile_width_lcu)*MV_MEM_UNIT); + WRITE_VREG(HEVC_MPRED_MV_WR_ROW_JUMP,data32); + WRITE_VREG(HEVC_MPRED_MV_RD_ROW_JUMP,data32); + + WRITE_VREG(HEVC_MPRED_MV_RD_END_ADDR, mpred_mv_rd_end_addr); + */ +} + +static void config_sao_hw(struct AV1HW_s *hw, union param_u *params) +{ + /* + !!!!!!!!!!!!!!!!!!!!!!!!!TODO .... !!!!!!!!!!! + mem_map_mode, endian, get_double_write_mode + */ + AV1_COMMON *cm = &hw->pbi->common; + PIC_BUFFER_CONFIG* pic_config = &cm->cur_frame->buf; + uint32_t data32; + int32_t lcu_size = + ((params->p.seq_flags >> 6) & 0x1) ? 128 : 64; + int32_t mc_buffer_size_u_v = + pic_config->lcu_total*lcu_size*lcu_size/2; + int32_t mc_buffer_size_u_v_h = + (mc_buffer_size_u_v + 0xffff)>>16; //64k alignment + av1_print(hw, AOM_DEBUG_HW_MORE, + "[test.c] #### config_sao_hw ####, lcu_size %d\n", lcu_size); + av1_print(hw, AOM_DEBUG_HW_MORE, + "[config_sao_hw] lcu_total : %d\n", pic_config->lcu_total); + av1_print(hw, AOM_DEBUG_HW_MORE, + "[config_sao_hw] mc_y_adr : 0x%x\n", pic_config->mc_y_adr); + av1_print(hw, AOM_DEBUG_HW_MORE, + "[config_sao_hw] mc_u_v_adr : 0x%x\n", pic_config->mc_u_v_adr); + av1_print(hw, AOM_DEBUG_HW_MORE, + "[config_sao_hw] header_adr : 0x%x\n", pic_config->header_adr); +#ifdef AOM_AV1_MMU_DW + if (hw->dw_mmu_enable) + av1_print(hw, AOM_DEBUG_HW_MORE, + "[config_sao_hw] header_dw_adr : 0x%x\n", pic_config->header_dw_adr); +#endif + data32 = READ_VREG(HEVC_SAO_CTRL9) | (1 << 1); + WRITE_VREG(HEVC_SAO_CTRL9, data32); + + data32 = READ_VREG(HEVC_SAO_CTRL5); + data32 |= (0x1 << 14); /* av1 mode */ + data32 |= (0xff << 16); /* dw {v1,v0,h1,h0} ctrl_y_cbus */ + WRITE_VREG(HEVC_SAO_CTRL5, data32); + + WRITE_VREG(HEVC_SAO_CTRL0, + lcu_size == 128 ? 0x7 : 0x6); /*lcu_size_log2*/ +#ifdef LOSLESS_COMPRESS_MODE + WRITE_VREG(HEVC_CM_BODY_START_ADDR, pic_config->mc_y_adr); +#ifdef AOM_AV1_MMU + WRITE_VREG(HEVC_CM_HEADER_START_ADDR, pic_config->header_adr); +#endif +#ifdef AOM_AV1_MMU_DW + if (hw->dw_mmu_enable) + WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, pic_config->header_dw_adr); +#endif +#else +/*!LOSLESS_COMPRESS_MODE*/ + WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic_config->mc_y_adr); +#endif + + av1_print(hw, AOM_DEBUG_HW_MORE, + "[config_sao_hw] sao_body_addr:%x\n", pic_config->mc_y_adr); + //printk("[config_sao_hw] sao_header_addr:%x\n", pic_config->mc_y_adr + losless_comp_body_size ); + +#ifdef VPU_FILMGRAIN_DUMP + // Let Microcode to increase + // WRITE_VREG(HEVC_FGS_TABLE_START, pic_config->fgs_table_adr); +#else + WRITE_VREG(HEVC_FGS_TABLE_START, pic_config->fgs_table_adr); +#endif + WRITE_VREG(HEVC_FGS_TABLE_LENGTH, FGS_TABLE_SIZE * 8); + av1_print(hw, AOM_DEBUG_HW_MORE, + "[config_sao_hw] fgs_table adr:0x%x , length 0x%x bits\n", + pic_config->fgs_table_adr, FGS_TABLE_SIZE * 8); + + data32 = (mc_buffer_size_u_v_h<<16)<<1; + //printk("data32 = %x, mc_buffer_size_u_v_h = %x, lcu_total = %x\n", data32, mc_buffer_size_u_v_h, pic_config->lcu_total); + WRITE_VREG(HEVC_SAO_Y_LENGTH ,data32); + +#ifndef LOSLESS_COMPRESS_MODE + WRITE_VREG(HEVC_SAO_C_START_ADDR, pic_config->mc_u_v_adr); +#else +#endif + + data32 = (mc_buffer_size_u_v_h<<16); + WRITE_VREG(HEVC_SAO_C_LENGTH ,data32); + +#ifndef LOSLESS_COMPRESS_MODE + /* multi tile to do... */ + WRITE_VREG(HEVC_SAO_Y_WPTR, pic_config->mc_y_adr); + + WRITE_VREG(HEVC_SAO_C_WPTR, pic_config->mc_u_v_adr); +#else + if (get_double_write_mode(hw) && + (get_double_write_mode(hw) & 0x20) == 0) { + WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic_config->dw_y_adr); + WRITE_VREG(HEVC_SAO_C_START_ADDR, pic_config->dw_u_v_adr); + WRITE_VREG(HEVC_SAO_Y_WPTR, pic_config->dw_y_adr); + WRITE_VREG(HEVC_SAO_C_WPTR, pic_config->dw_u_v_adr); + } else { + //WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff); + //WRITE_VREG(HEVC_SAO_C_START_ADDR, 0xffffffff); + } +#endif + + +#ifndef AOM_AV1_NV21 +#ifdef AOM_AV1_MMU_DW + if (hw->dw_mmu_enable) { + } +#endif +#endif + +#ifdef AOM_AV1_NV21 +#ifdef DOS_PROJECT + data32 = READ_VREG(HEVC_SAO_CTRL1); + data32 &= (~0x3000); + data32 |= (MEM_MAP_MODE << 12); // [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 + data32 &= (~0x3); + data32 |= 0x1; // [1]:dw_disable [0]:cm_disable + WRITE_VREG(HEVC_SAO_CTRL1, data32); + + data32 = READ_VREG(HEVC_SAO_CTRL5); // [23:22] dw_v1_ctrl [21:20] dw_v0_ctrl [19:18] dw_h1_ctrl [17:16] dw_h0_ctrl + data32 &= ~(0xff << 16); // set them all 0 for AOM_AV1_NV21 (no down-scale) + WRITE_VREG(HEVC_SAO_CTRL5, data32); + + data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG); + data32 &= (~0x30); + data32 |= (MEM_MAP_MODE << 4); // [5:4] -- address_format 00:linear 01:32x32 10:64x32 + WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32); +#else +// m8baby test1902 + data32 = READ_VREG(HEVC_SAO_CTRL1); + data32 &= (~0x3000); + data32 |= (MEM_MAP_MODE << 12); // [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 + data32 &= (~0xff0); + //data32 |= 0x670; // Big-Endian per 64-bit + data32 |= 0x880; // Big-Endian per 64-bit + data32 &= (~0x3); + data32 |= 0x1; // [1]:dw_disable [0]:cm_disable + WRITE_VREG(HEVC_SAO_CTRL1, data32); + + data32 = READ_VREG(HEVC_SAO_CTRL5); // [23:22] dw_v1_ctrl [21:20] dw_v0_ctrl [19:18] dw_h1_ctrl [17:16] dw_h0_ctrl + data32 &= ~(0xff << 16); // set them all 0 for AOM_AV1_NV21 (no down-scale) + WRITE_VREG(HEVC_SAO_CTRL5, data32); + + data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG); + data32 &= (~0x30); + data32 |= (MEM_MAP_MODE << 4); // [5:4] -- address_format 00:linear 01:32x32 10:64x32 + data32 &= (~0xF); + data32 |= 0x8; // Big-Endian per 64-bit + WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32); +#endif +#else +/*CHANGE_DONE nnn*/ + data32 = READ_VREG(HEVC_SAO_CTRL1); + data32 &= (~0x3000); + data32 |= (mem_map_mode << + 12); + +/* [13:12] axi_aformat, 0-Linear, + * 1-32x32, 2-64x32 + */ + data32 &= (~0xff0); + /* data32 |= 0x670; // Big-Endian per 64-bit */ +#ifdef AOM_AV1_MMU_DW + if (hw->dw_mmu_enable == 0) + data32 |= endian; /* Big-Endian per 64-bit */ +#else + data32 |= endian; /* Big-Endian per 64-bit */ +#endif + if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) { + data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/ + if (get_double_write_mode(hw) == 0) + data32 |= 0x2; /*disable double write*/ + else if (get_double_write_mode(hw) & 0x10) + data32 |= 0x1; /*disable cm*/ + } else { /* >= G12A dw write control */ + unsigned int data; + data = READ_VREG(HEVC_DBLK_CFGB); + data &= (~0x300); /*[8]:first write enable (compress) [9]:double write enable (uncompress)*/ + if (get_double_write_mode(hw) == 0) + data |= (0x1 << 8); /*enable first write*/ + else if (get_double_write_mode(hw) & 0x10) + data |= (0x1 << 9); /*double write only*/ + else + data |= ((0x1 << 8) |(0x1 << 9)); + WRITE_VREG(HEVC_DBLK_CFGB, data); + } + WRITE_VREG(HEVC_SAO_CTRL1, data32); + + if (get_double_write_mode(hw) & 0x10) { + /* [23:22] dw_v1_ctrl + *[21:20] dw_v0_ctrl + *[19:18] dw_h1_ctrl + *[17:16] dw_h0_ctrl + */ + data32 = READ_VREG(HEVC_SAO_CTRL5); + /*set them all 0 for H265_NV21 (no down-scale)*/ + data32 &= ~(0xff << 16); + WRITE_VREG(HEVC_SAO_CTRL5, data32); + } else { + data32 = READ_VREG(HEVC_SAO_CTRL5); + data32 &= (~(0xff << 16)); + if ((get_double_write_mode(hw) & 0xf) == 2 || + (get_double_write_mode(hw) & 0xf) == 3) + data32 |= (0xff<<16); + else if ((get_double_write_mode(hw) & 0xf) == 4 || + (get_double_write_mode(hw) & 0xf) == 5) + data32 |= (0x33<<16); + WRITE_VREG(HEVC_SAO_CTRL5, data32); + } + + data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG); + data32 &= (~0x30); + /* [5:4] -- address_format 00:linear 01:32x32 10:64x32 */ + data32 |= (mem_map_mode << + 4); + data32 &= (~0xF); + data32 |= 0xf; /* valid only when double write only */ + /*data32 |= 0x8;*/ /* Big-Endian per 64-bit */ + WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32); + +#endif + +} + + +#ifdef AOM_AV1_DBLK_INIT +/* + * Defines, declarations, sub-functions for av1 de-block loop filter Thr/Lvl table update + * - struct segmentation_lf is for loop filter only (removed something) + * - function "av1_loop_filter_init" and "av1_loop_filter_frame_init" will be instantiated in C_Entry + * - av1_loop_filter_init run once before decoding start + * - av1_loop_filter_frame_init run before every frame decoding start + * - set video format to AOM_AV1 is in av1_loop_filter_init + */ +#define MAX_LOOP_FILTER 63 +#define MAX_MODE_LF_DELTAS 2 +#define MAX_SEGMENTS 8 +#define MAX_MB_PLANE 3 + +typedef enum { + SEG_LVL_ALT_Q, // Use alternate Quantizer .... + SEG_LVL_ALT_LF_Y_V, // Use alternate loop filter value on y plane vertical + SEG_LVL_ALT_LF_Y_H, // Use alternate loop filter value on y plane horizontal + SEG_LVL_ALT_LF_U, // Use alternate loop filter value on u plane + SEG_LVL_ALT_LF_V, // Use alternate loop filter value on v plane + SEG_LVL_REF_FRAME, // Optional Segment reference frame + SEG_LVL_SKIP, // Optional Segment (0,0) + skip mode + SEG_LVL_GLOBALMV, + SEG_LVL_MAX +} SEG_LVL_FEATURES; + +static const SEG_LVL_FEATURES seg_lvl_lf_lut[MAX_MB_PLANE][2] = { + { SEG_LVL_ALT_LF_Y_V, SEG_LVL_ALT_LF_Y_H }, + { SEG_LVL_ALT_LF_U, SEG_LVL_ALT_LF_U }, + { SEG_LVL_ALT_LF_V, SEG_LVL_ALT_LF_V } +}; + +struct segmentation_lf { // for loopfilter only + uint8_t enabled; + /* + SEG_LVL_ALT_LF_Y_V feature_enable: seg_lf_info_y[bit7] + SEG_LVL_ALT_LF_Y_V data: seg_lf_info_y[bit0~6] + SEG_LVL_ALT_LF_Y_H feature enable: seg_lf_info_y[bit15] + SEG_LVL_ALT_LF_Y_H data: seg_lf_info_y[bit8~14] + */ + uint16_t seg_lf_info_y[8]; + /* + SEG_LVL_ALT_LF_U feature_enable: seg_lf_info_c[bit7] + SEG_LVL_ALT_LF_U data: seg_lf_info_c[bit0~6] + SEG_LVL_ALT_LF_V feature enable: seg_lf_info_c[bit15] + SEG_LVL_ALT_LF_V data: seg_lf_info_c[bit8~14] + */ + uint16_t seg_lf_info_c[8]; +}; + +typedef struct { + uint8_t mblim; + uint8_t lim; + uint8_t hev_thr; +} loop_filter_thresh; + +typedef struct loop_filter_info_n_s { + loop_filter_thresh lfthr[MAX_LOOP_FILTER + 1]; + uint8_t lvl[MAX_MB_PLANE][MAX_SEGMENTS][2][REF_FRAMES][MAX_MODE_LF_DELTAS]; +} loop_filter_info_n; + +struct loopfilter { + int32_t filter_level[2]; + int32_t filter_level_u; + int32_t filter_level_v; + + int32_t sharpness_level; + + uint8_t mode_ref_delta_enabled; + uint8_t mode_ref_delta_update; + + // 0 = Intra, Last, Last2+Last3, + // GF, BRF, ARF2, ARF + int8_t ref_deltas[REF_FRAMES]; + + // 0 = ZERO_MV, MV + int8_t mode_deltas[MAX_MODE_LF_DELTAS]; + + int32_t combine_vert_horz_lf; + + int32_t lf_pic_cnt; + +//#if LOOP_FILTER_BITMASK + //LoopFilterMask *lfm; + //size_t lfm_num; + //int lfm_stride; + //LpfSuperblockInfo neighbor_sb_lpf_info; +//#endif // LOOP_FILTER_BITMASK +}; + +static int32_t myclamp(int32_t value, int32_t low, int32_t high) { + return value < low ? low : (value > high ? high : value); +} + +/*static int8_t extend_sign_7bits(uint8_t value) { + return (((value>>6) & 0x1)<<7) | (value&0x7f); +}*/ + +// convert data to int8_t variable +// value : signed data (with any bitwidth<8) which is assigned to uint8_t variable as an input +// bw : bitwidth of signed data, (from 1 to 7) +static int8_t conv2int8 (uint8_t value, uint8_t bw) { + if (bw<1 || bw>7) return (int8_t)value; + else { + const uint8_t data_bits = value & ((1<>(bw-1)) & 0x1; + const uint8_t sign_bit_ext = sign_bit | sign_bit<<1 | sign_bit<<2 | sign_bit<<3 | sign_bit<<4 | sign_bit<<5 | sign_bit<<6 | sign_bit<<7; + return (int8_t)((sign_bit_ext<> ((sharpness_lvl > 0) + (sharpness_lvl > 4)); + + if (sharpness_lvl > 0) { + if (block_inside_limit > (9 - sharpness_lvl)) + block_inside_limit = (9 - sharpness_lvl); + } + + if (block_inside_limit < 1) + block_inside_limit = 1; + + lfi->lfthr[lvl].lim = (uint8_t)block_inside_limit; + lfi->lfthr[lvl].mblim = (uint8_t)(2 * (lvl + 2) + block_inside_limit); + } +} + +// instantiate this function once when decode is started +void av1_loop_filter_init(loop_filter_info_n *lfi, struct loopfilter *lf) { + int32_t i; + uint32_t data32; + + // init limits for given sharpness + av1_update_sharpness(lfi, lf->sharpness_level); + + // Write to register + for (i = 0; i < 32; i++) { + uint32_t thr; + thr = ((lfi->lfthr[i*2+1].lim & 0x3f)<<8) | + (lfi->lfthr[i*2+1].mblim & 0xff); + thr = (thr<<16) | ((lfi->lfthr[i*2].lim & 0x3f)<<8) | + (lfi->lfthr[i*2].mblim & 0xff); + WRITE_VREG(HEVC_DBLK_CFG9, thr); + } + // video format is AOM_AV1 + data32 = (0x57 << 8) | // 1st/2nd write both enable + (0x4 << 0); // aom_av1 video format + WRITE_VREG(HEVC_DBLK_CFGB, data32); + av1_print2(AOM_DEBUG_HW_MORE, + "[DBLK DEBUG] CFGB : 0x%x\n", data32); +} + +// perform this function per frame +void av1_loop_filter_frame_init(AV1Decoder* pbi, struct segmentation_lf *seg, + loop_filter_info_n *lfi, + struct loopfilter *lf, + int32_t pic_width) { + BuffInfo_t* buf_spec = pbi->work_space_buf; + int32_t i,dir; + int32_t filt_lvl[MAX_MB_PLANE], filt_lvl_r[MAX_MB_PLANE]; + int32_t plane; + int32_t seg_id; + // n_shift is the multiplier for lf_deltas + // the multiplier is 1 for when filter_lvl is between 0 and 31; + // 2 when filter_lvl is between 32 and 63 + + // update limits if sharpness has changed + av1_update_sharpness(lfi, lf->sharpness_level); + + // Write to register + for (i = 0; i < 32; i++) { + uint32_t thr; + thr = ((lfi->lfthr[i*2+1].lim & 0x3f)<<8) + | (lfi->lfthr[i*2+1].mblim & 0xff); + thr = (thr<<16) | ((lfi->lfthr[i*2].lim & 0x3f)<<8) + | (lfi->lfthr[i*2].mblim & 0xff); + WRITE_VREG(HEVC_DBLK_CFG9, thr); + } + + filt_lvl[0] = lf->filter_level[0]; + filt_lvl[1] = lf->filter_level_u; + filt_lvl[2] = lf->filter_level_v; + + filt_lvl_r[0] = lf->filter_level[1]; + filt_lvl_r[1] = lf->filter_level_u; + filt_lvl_r[2] = lf->filter_level_v; + +#ifdef DBG_LPF_PRINT + printk("LF_PRINT: pic_cnt(%d) base_filter_level(%d,%d,%d,%d)\n", + lf->lf_pic_cnt, lf->filter_level[0], + lf->filter_level[1], lf->filter_level_u, lf->filter_level_v); +#endif + + for (plane = 0; plane < 3; plane++) { + if (plane == 0 && !filt_lvl[0] && !filt_lvl_r[0]) + break; + else if (plane == 1 && !filt_lvl[1]) + continue; + else if (plane == 2 && !filt_lvl[2]) + continue; + + for (seg_id = 0; seg_id < MAX_SEGMENTS; seg_id++) { // MAX_SEGMENTS==8 + for (dir = 0; dir < 2; ++dir) { + int32_t lvl_seg = (dir == 0) ? filt_lvl[plane] : filt_lvl_r[plane]; + //assert(plane >= 0 && plane <= 2); + const uint8_t seg_lf_info_y0 = seg->seg_lf_info_y[seg_id] & 0xff; + const uint8_t seg_lf_info_y1 = (seg->seg_lf_info_y[seg_id]>>8) & 0xff; + const uint8_t seg_lf_info_u = seg->seg_lf_info_c[seg_id] & 0xff; + const uint8_t seg_lf_info_v = (seg->seg_lf_info_c[seg_id]>>8) & 0xff; + const uint8_t seg_lf_info = (plane==2) ? seg_lf_info_v : (plane==1) ? + seg_lf_info_u : ((dir==0) ? seg_lf_info_y0 : seg_lf_info_y1); + const int8_t seg_lf_active = ((seg->enabled) && ((seg_lf_info>>7) & 0x1)); + const int8_t seg_lf_data = conv2int8(seg_lf_info,7); +#ifdef DBG_LPF_PRINT + const int8_t seg_lf_data_clip = (seg_lf_data>63) ? 63 : + (seg_lf_data<-63) ? -63 : seg_lf_data; +#endif + if (seg_lf_active) { + lvl_seg = myclamp(lvl_seg + (int32_t)seg_lf_data, 0, MAX_LOOP_FILTER); + } + +#ifdef DBG_LPF_PRINT + printk("LF_PRINT:plane(%d) seg_id(%d) dir(%d) seg_lf_info(%d,0x%x),lvl_seg(0x%x)\n", + plane,seg_id,dir,seg_lf_active,seg_lf_data_clip,lvl_seg); +#endif + + if (!lf->mode_ref_delta_enabled) { + // we could get rid of this if we assume that deltas are set to + // zero when not in use; encoder always uses deltas + memset(lfi->lvl[plane][seg_id][dir], lvl_seg, + sizeof(lfi->lvl[plane][seg_id][dir])); + } else { + int32_t ref, mode; + const int32_t scale = 1 << (lvl_seg >> 5); + const int32_t intra_lvl = lvl_seg + lf->ref_deltas[INTRA_FRAME] * scale; + lfi->lvl[plane][seg_id][dir][INTRA_FRAME][0] = + myclamp(intra_lvl, 0, MAX_LOOP_FILTER); +#ifdef DBG_LPF_PRINT + printk("LF_PRINT:ref_deltas[INTRA_FRAME](%d)\n",lf->ref_deltas[INTRA_FRAME]); +#endif + for (ref = LAST_FRAME; ref < REF_FRAMES; ++ref) { // LAST_FRAME==1 REF_FRAMES==8 + for (mode = 0; mode < MAX_MODE_LF_DELTAS; ++mode) { // MAX_MODE_LF_DELTAS==2 + const int32_t inter_lvl = + lvl_seg + lf->ref_deltas[ref] * scale + + lf->mode_deltas[mode] * scale; + lfi->lvl[plane][seg_id][dir][ref][mode] = + myclamp(inter_lvl, 0, MAX_LOOP_FILTER); +#ifdef DBG_LPF_PRINT + printk("LF_PRINT:ref_deltas(%d) mode_deltas(%d)\n", + lf->ref_deltas[ref], lf->mode_deltas[mode]); +#endif + } + } + } + } + } + } + +#ifdef DBG_LPF_PRINT + for (i = 0; i <= MAX_LOOP_FILTER; i++) { + printk("LF_PRINT:(%2d) thr=%d,blim=%3d,lim=%2d\n", + i, lfi->lfthr[i].hev_thr, + lfi->lfthr[i].mblim, lfi->lfthr[i].lim); + } + for (plane = 0; plane < 3; plane++) { + for (seg_id = 0; seg_id < MAX_SEGMENTS; seg_id++) { // MAX_SEGMENTS==8 + for (dir = 0; dir < 2; ++dir) { + int32_t mode; + for (mode = 0; mode < 2; ++mode) { + printk("assign {lvl[%d][%d][%d][0][%d],lvl[%d][%d][%d][1][%d],lvl[%d][%d][%d][2][%d],lvl[%d][%d][%d][3][%d],lvl[%d][%d][%d][4][%d],lvl[%d][%d][%d][5][%d],lvl[%d][%d][%d][6][%d],lvl[%d][%d][%d][7][%d]}={6'd%2d,6'd%2d,6'd%2d,6'd%2d,6'd%2d,6'd%2d,6'd%2d,6'd%2d};\n", + plane, seg_id, dir, mode, + plane, seg_id, dir, mode, + plane, seg_id, dir, mode, + plane, seg_id, dir, mode, + plane, seg_id, dir, mode, + plane, seg_id, dir, mode, + plane, seg_id, dir, mode, + plane, seg_id, dir, mode, + lfi->lvl[plane][seg_id][dir][0][mode], + lfi->lvl[plane][seg_id][dir][1][mode], + lfi->lvl[plane][seg_id][dir][2][mode], + lfi->lvl[plane][seg_id][dir][3][mode], + lfi->lvl[plane][seg_id][dir][4][mode], + lfi->lvl[plane][seg_id][dir][5][mode], + lfi->lvl[plane][seg_id][dir][6][mode], + lfi->lvl[plane][seg_id][dir][7][mode]); + } + } + } + } +#endif + // Write to register + for (i = 0; i < 192; i++) { + uint32_t level; + level = ((lfi->lvl[i>>6&3][i>>3&7][1][i&7][1] & 0x3f)<<24) | + ((lfi->lvl[i>>6&3][i>>3&7][1][i&7][0] & 0x3f)<<16) | + ((lfi->lvl[i>>6&3][i>>3&7][0][i&7][1] & 0x3f)<<8) | + (lfi->lvl[i>>6&3][i>>3&7][0][i&7][0] & 0x3f); + if (!lf->filter_level[0] && !lf->filter_level[1]) + level = 0; + WRITE_VREG(HEVC_DBLK_CFGA, level); + } +#ifdef DBG_LPF_DBLK_FORCED_OFF + if (lf->lf_pic_cnt == 2) { + printk("LF_PRINT: pic_cnt(%d) dblk forced off !!!\n", lf->lf_pic_cnt); + WRITE_VREG(HEVC_DBLK_DBLK0, 0); + } else + WRITE_VREG(HEVC_DBLK_DBLK0, + lf->filter_level[0] | lf->filter_level[1] << 6 | + lf->filter_level_u << 12 | lf->filter_level_v << 18); +#else + WRITE_VREG(HEVC_DBLK_DBLK0, + lf->filter_level[0] | lf->filter_level[1]<<6 | + lf->filter_level_u<<12 | lf->filter_level_v<<18); +#endif + for (i =0; i < 10; i++) + WRITE_VREG(HEVC_DBLK_DBLK1, + ((i<2) ? lf->mode_deltas[i&1] : lf->ref_deltas[(i-2)&7])); + for (i = 0; i < 8; i++) + WRITE_VREG(HEVC_DBLK_DBLK2, + (uint32_t)(seg->seg_lf_info_y[i]) | (uint32_t)(seg->seg_lf_info_c[i]<<16)); + + // Set P_HEVC_DBLK_CFGB again + { + uint32_t lpf_data32 = READ_VREG(HEVC_DBLK_CFGB); + if (lf->mode_ref_delta_enabled) + lpf_data32 |= (0x1<<28); // mode_ref_delta_enabled + else + lpf_data32 &= ~(0x1<<28); + if (seg->enabled) + lpf_data32 |= (0x1<<29); // seg enable + else + lpf_data32 &= ~(0x1<<29); + if (pic_width >= 1280) + lpf_data32 |= (0x1 << 4); // dblk pipeline mode=1 for performance + else + lpf_data32 &= ~(0x3 << 4); + WRITE_VREG(HEVC_DBLK_CFGB, lpf_data32); + } + // Set CDEF + WRITE_VREG(HEVC_DBLK_CDEF0, buf_spec->cdef_data.buf_start); + { + uint32_t cdef_data32 = (READ_VREG(HEVC_DBLK_CDEF1) & 0xffffff00); + cdef_data32 |= 17; // TODO ERROR :: cdef temp dma address left offset + WRITE_VREG(HEVC_DBLK_CDEF1, cdef_data32); + } + // Picture count + lf->lf_pic_cnt++; +} +#endif // #ifdef AOM_AV1_DBLK_INIT + +#ifdef AOM_AV1_UPSCALE_INIT +/* + * these functions here for upscaling updated in every picture + */ +#define RS_SUBPEL_BITS 6 +#define RS_SUBPEL_MASK ((1 << RS_SUBPEL_BITS) - 1) +#define RS_SCALE_SUBPEL_BITS 14 +#define RS_SCALE_SUBPEL_MASK ((1 << RS_SCALE_SUBPEL_BITS) - 1) +#define RS_SCALE_EXTRA_BITS (RS_SCALE_SUBPEL_BITS - RS_SUBPEL_BITS) +#define RS_SCALE_EXTRA_OFF (1 << (RS_SCALE_EXTRA_BITS - 1)) + +static int32_t av1_get_upscale_convolve_step(int32_t in_length, int32_t out_length) { + return ((in_length << RS_SCALE_SUBPEL_BITS) + out_length / 2) / out_length; +} + +static int32_t get_upscale_convolve_x0(int32_t in_length, int32_t out_length, + int32_t x_step_qn) { + const int32_t err = out_length * x_step_qn - (in_length << RS_SCALE_SUBPEL_BITS); + const int32_t x0 = + (-((out_length - in_length) << (RS_SCALE_SUBPEL_BITS - 1)) + + out_length / 2) / + out_length + + RS_SCALE_EXTRA_OFF - err / 2; + return (int32_t)((uint32_t)x0 & RS_SCALE_SUBPEL_MASK); +} + +void av1_upscale_frame_init(AV1Decoder* pbi, AV1_COMMON *cm, param_t* params) +{ + BuffInfo_t* buf_spec = pbi->work_space_buf; + //uint32_t data32; + const int32_t width = cm->dec_width; + const int32_t superres_upscaled_width = cm->superres_upscaled_width; + const int32_t x_step_qn_luma = av1_get_upscale_convolve_step(width, superres_upscaled_width); + const int32_t x0_qn_luma = get_upscale_convolve_x0(width, superres_upscaled_width, x_step_qn_luma); + const int32_t x_step_qn_chroma = av1_get_upscale_convolve_step((width+1)>>1, (superres_upscaled_width+1)>>1); + const int32_t x0_qn_chroma = get_upscale_convolve_x0((width+1)>>1, (superres_upscaled_width+1)>>1, x_step_qn_chroma); + av1_print2(AOM_DEBUG_HW_MORE, + "UPS_PRINT: width(%d -> %d)\n", + width, superres_upscaled_width); + av1_print2(AOM_DEBUG_HW_MORE, + "UPS_PRINT: xstep(%d,%d)(0x%X, 0x%X) x0qn(%d,%d)(0x%X, 0x%X)\n", + x_step_qn_luma,x_step_qn_chroma, + x_step_qn_luma,x_step_qn_chroma, + x0_qn_luma,x0_qn_chroma, + x0_qn_luma,x0_qn_chroma); + WRITE_VREG(HEVC_DBLK_UPS1, buf_spec->ups_data.buf_start); + WRITE_VREG(HEVC_DBLK_UPS2, x0_qn_luma); // x0_qn y + WRITE_VREG(HEVC_DBLK_UPS3, x0_qn_chroma); // x0_qn c + WRITE_VREG(HEVC_DBLK_UPS4, x_step_qn_luma); // x_step y + WRITE_VREG(HEVC_DBLK_UPS5, x_step_qn_chroma); // x_step c + WRITE_VREG(AV1_UPSCALE_X0_QN, (x0_qn_chroma<<16)|x0_qn_luma); + WRITE_VREG(AV1_UPSCALE_STEP_QN, (x_step_qn_chroma<<16)|x_step_qn_luma); + +/* + * TileR calculation here if cm needs an exactly accurate value + */ +//#define AV1_UPSCALE_TILER_CALCULATION +#ifdef AV1_UPSCALE_TILER_CALCULATION + uint32_t upscl_enabled = 1; // 1 just for example, actually this is use_superres flag + uint32_t tiler_x = 192; // 192 just for example, actually this is tile end + uint32_t ux; + uint32_t ux_tiler,ux_tiler_rnd32; + uint32_t xqn_y; + uint32_t xqn_c; + uint32_t tiler_x_y = tiler_x - 8 - 3; // dblk/cdef left-shift-8 plus upscaling extra-3 + uint32_t tiler_x_c = (tiler_x/2) - 4 - 3; // dblk/cdef left-shift-4 plus upscaling extra-3 + + xqn_y = x0_qn_luma; + xqn_c = x0_qn_chroma; + ux_tiler = 0; + ux_tiler_rnd32 = 0; + for (ux=0; ux<16384; ux+=8) { + uint32_t x1qn_y = xqn_y + x_step_qn_luma *( 7+3); // extra-3 is for lrf + uint32_t x1qn_c = xqn_c + x_step_qn_chroma*( 3+3); // extra-3 is for lrf + uint32_t x1qn_y_nxt = xqn_y + x_step_qn_luma *(8+7+3); // extra-3 is for lrf + uint32_t x1qn_c_nxt = xqn_c + x_step_qn_chroma*(4+3+3); // extra-3 is for lrf + + uint32_t x1_y = upscl_enabled ? (x1qn_y>>14) : ux +7+3; + uint32_t x1_c = upscl_enabled ? (x1qn_c>>14) : (ux/2)+3+3; + uint32_t x1_y_nxt = upscl_enabled ? (x1qn_y_nxt>>14) : ux +8+7+3; + uint32_t x1_c_nxt = upscl_enabled ? (x1qn_c_nxt>>14) : (ux/2)+4+3+3; + + if ((x1_y=tiler_x_y || x1_c_nxt>=tiler_x_c)) { + ux_tiler = ux; + ux_tiler_rnd32 = (ux_tiler/32 + (ux_tiler%32 ? 1 : 0)) * 32; + break; + } + + xqn_y += x_step_qn_luma*8; + xqn_c += x_step_qn_chroma*4; + } + + av1_print(hw, AOM_DEBUG_HW_MORE, + "UPS_PRINT: xqn_y(0x%x), xqn_c(0x%x), x1qn_y(0x%x), x1qn_c(0x%x)\n", + xqn_y, xqn_c, x1qn_y, x1qn_c); + av1_print(hw, AOM_DEBUG_HW_MORE, + "UPS_PRINT: ux_tiler(%d)(0x%x), ux_tiler_rnd32(%d)(0x%x)\n", + ux_tiler, ux_tiler, ux_tiler_rnd32, ux_tiler_rnd32); +#endif + + // TEMP write lrf register here + //WRITE_VREG(HEVC_DBLK_LRF0, 1<<0 | 1<<2); // LRF UNIT SIZE + //WRITE_VREG(HEVC_DBLK_LRF1, 3<<0 | 1<<8 | 1<<16 | 1<<24); // LRF UNIT NUMBER + + // TEMP Global Enables write here + /* + const uint32_t dblk_enable = (!cm->allow_intrabc && !cm->single_tile_decoding && (cm->lf.filter_level[0] || cm->lf.filter_level[1])); + const uint32_t cdef_enable = (!cm->allow_intrabc && !cm->single_tile_decoding && !cm->skip_loop_filter && !cm->coded_lossless && (cm->cdef_bits || cm->cdef_strengths[0] || cm->cdef_uv_strengths[0])); + printk("LPF_ENABLES : dblk(%d) cdef(%d)\n", dblk_enable, cdef_enable); + data32 = READ_VREG(HEVC_DBLK_CFGB ); + data32 &= ~(0xf<<20); + data32 |= (dblk_enable<<20); + data32 |= (cdef_enable<<23); + WRITE_VREG(HEVC_DBLK_CFGB, data32); + */ +} + +#endif // #ifdef AOM_AV1_UPSCALE_INIT + +static void release_dblk_struct(struct AV1HW_s *hw) +{ +#ifdef AOM_AV1_DBLK_INIT + if (hw->lfi) + vfree(hw->lfi); + if (hw->lf) + vfree(hw->lf); + if (hw->seg_4lf) + vfree(hw->seg_4lf); + hw->lfi = NULL; + hw->lf = NULL; + hw->seg_4lf = NULL; +#endif +} + +static int init_dblk_struc(struct AV1HW_s *hw) +{ +#ifdef AOM_AV1_DBLK_INIT + hw->lfi = vmalloc(sizeof(loop_filter_info_n)); + hw->lf = vmalloc(sizeof(struct loopfilter)); + hw->seg_4lf = vmalloc(sizeof(struct segmentation_lf)); + + if (hw->lfi == NULL || hw->lf == NULL || hw->seg_4lf == NULL) { + printk("[test.c] aom_loop_filter init malloc error!!!\n"); + release_dblk_struct(hw); + return -1; + } + + hw->lf->mode_ref_delta_enabled = 1; // set default here + hw->lf->mode_ref_delta_update = 1; // set default here + hw->lf->sharpness_level = 0; // init to 0 + hw->lf->lf_pic_cnt = 0; // init to 0 +#endif + return 0; +} + +static void config_dblk_hw(struct AV1HW_s *hw) +{ + AV1Decoder *pbi = hw->pbi; + AV1_COMMON *cm = &hw->pbi->common; + loop_filter_info_n *lfi = hw->lfi; + struct loopfilter *lf = hw->lf; + struct segmentation_lf *seg_4lf = hw->seg_4lf; + BuffInfo_t* buf_spec = pbi->work_space_buf; + PIC_BUFFER_CONFIG* cur_pic_config = &cm->cur_frame->buf; + PIC_BUFFER_CONFIG* prev_pic_config = &cm->prev_frame->buf; + int i; + +#ifdef AOM_AV1_DBLK_INIT +#ifdef DUAL_DECODE +#else + av1_print(hw, AOM_DEBUG_HW_MORE, + "[test.c ref_delta] cur_frame : %p prev_frame : %p - %p \n", + cm->cur_frame, cm->prev_frame, + av1_get_primary_ref_frame_buf(cm)); + // get lf parameters from parser + lf->mode_ref_delta_enabled = + (hw->aom_param.p.loop_filter_mode_ref_delta_enabled & 1); + lf->mode_ref_delta_update = + ((hw->aom_param.p.loop_filter_mode_ref_delta_enabled >> 1) & 1); + lf->sharpness_level = + hw->aom_param.p.loop_filter_sharpness_level; + if (((hw->aom_param.p.loop_filter_mode_ref_delta_enabled)&3) == 3) { // enabled but and update + if (cm->prev_frame <= 0) { + // already initialized in Microcode + lf->ref_deltas[0] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_0),7); + lf->ref_deltas[1] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_0>>8),7); + lf->ref_deltas[2] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_1),7); + lf->ref_deltas[3] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_1>>8),7); + lf->ref_deltas[4] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_2),7); + lf->ref_deltas[5] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_2>>8),7); + lf->ref_deltas[6] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_3),7); + lf->ref_deltas[7] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_3>>8),7); + lf->mode_deltas[0] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_mode_deltas_0),7); + lf->mode_deltas[1] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_mode_deltas_0>>8),7); + } else { + lf->ref_deltas[0] = (hw->aom_param.p.loop_filter_ref_deltas_0 & 0x80) ? + conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_0),7) : + cm->prev_frame->ref_deltas[0]; + lf->ref_deltas[1] = (hw->aom_param.p.loop_filter_ref_deltas_0 & 0x8000) ? + conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_0>>8),7) : + cm->prev_frame->ref_deltas[1]; + lf->ref_deltas[2] = (hw->aom_param.p.loop_filter_ref_deltas_1 & 0x80) ? + conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_1),7) : + cm->prev_frame->ref_deltas[2]; + lf->ref_deltas[3] = (hw->aom_param.p.loop_filter_ref_deltas_1 & 0x8000) ? + conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_1>>8),7) : + cm->prev_frame->ref_deltas[3]; + lf->ref_deltas[4] = (hw->aom_param.p.loop_filter_ref_deltas_2 & 0x80) ? + conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_2),7) : + cm->prev_frame->ref_deltas[4]; + lf->ref_deltas[5] = (hw->aom_param.p.loop_filter_ref_deltas_2 & 0x8000) ? + conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_2>>8),7) : + cm->prev_frame->ref_deltas[5]; + lf->ref_deltas[6] = (hw->aom_param.p.loop_filter_ref_deltas_3 & 0x80) ? + conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_3),7) : + cm->prev_frame->ref_deltas[6]; + lf->ref_deltas[7] = (hw->aom_param.p.loop_filter_ref_deltas_3 & 0x8000) ? + conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_3>>8),7) : + cm->prev_frame->ref_deltas[7]; + lf->mode_deltas[0] = (hw->aom_param.p.loop_filter_mode_deltas_0 & 0x80) ? + conv2int8((uint8_t)(hw->aom_param.p.loop_filter_mode_deltas_0),7) : + cm->prev_frame->mode_deltas[0]; + lf->mode_deltas[1] = (hw->aom_param.p.loop_filter_mode_deltas_0 & 0x8000) ? + conv2int8((uint8_t)(hw->aom_param.p.loop_filter_mode_deltas_0>>8),7) : + cm->prev_frame->mode_deltas[1]; + } + } //else if (hw->aom_param.p.loop_filter_mode_ref_delta_enabled == 1) { // enabled but no update + else { // match c code -- not enabled, still need to copy prev to used for next + if ((cm->prev_frame <= 0) | (hw->aom_param.p.loop_filter_mode_ref_delta_enabled & 4)) { + av1_print(hw, AOM_DEBUG_HW_MORE, + "[test.c] mode_ref_delta set to default\n"); + lf->ref_deltas[0] = conv2int8((uint8_t)1,7); + lf->ref_deltas[1] = conv2int8((uint8_t)0,7); + lf->ref_deltas[2] = conv2int8((uint8_t)0,7); + lf->ref_deltas[3] = conv2int8((uint8_t)0,7); + lf->ref_deltas[4] = conv2int8((uint8_t)0xff,7); + lf->ref_deltas[5] = conv2int8((uint8_t)0,7); + lf->ref_deltas[6] = conv2int8((uint8_t)0xff,7); + lf->ref_deltas[7] = conv2int8((uint8_t)0xff,7); + lf->mode_deltas[0] = conv2int8((uint8_t)0,7); + lf->mode_deltas[1] = conv2int8((uint8_t)0,7); + } else { + av1_print(hw, AOM_DEBUG_HW_MORE, + "[test.c] mode_ref_delta copy from prev_frame\n"); + lf->ref_deltas[0] = cm->prev_frame->ref_deltas[0]; + lf->ref_deltas[1] = cm->prev_frame->ref_deltas[1]; + lf->ref_deltas[2] = cm->prev_frame->ref_deltas[2]; + lf->ref_deltas[3] = cm->prev_frame->ref_deltas[3]; + lf->ref_deltas[4] = cm->prev_frame->ref_deltas[4]; + lf->ref_deltas[5] = cm->prev_frame->ref_deltas[5]; + lf->ref_deltas[6] = cm->prev_frame->ref_deltas[6]; + lf->ref_deltas[7] = cm->prev_frame->ref_deltas[7]; + lf->mode_deltas[0] = cm->prev_frame->mode_deltas[0]; + lf->mode_deltas[1] = cm->prev_frame->mode_deltas[1]; + } + } + lf->filter_level[0] = hw->aom_param.p.loop_filter_level_0; + lf->filter_level[1] = hw->aom_param.p.loop_filter_level_1; + lf->filter_level_u = hw->aom_param.p.loop_filter_level_u; + lf->filter_level_v = hw->aom_param.p.loop_filter_level_v; + + cm->cur_frame->ref_deltas[0] = lf->ref_deltas[0]; + cm->cur_frame->ref_deltas[1] = lf->ref_deltas[1]; + cm->cur_frame->ref_deltas[2] = lf->ref_deltas[2]; + cm->cur_frame->ref_deltas[3] = lf->ref_deltas[3]; + cm->cur_frame->ref_deltas[4] = lf->ref_deltas[4]; + cm->cur_frame->ref_deltas[5] = lf->ref_deltas[5]; + cm->cur_frame->ref_deltas[6] = lf->ref_deltas[6]; + cm->cur_frame->ref_deltas[7] = lf->ref_deltas[7]; + cm->cur_frame->mode_deltas[0] = lf->mode_deltas[0]; + cm->cur_frame->mode_deltas[1] = lf->mode_deltas[1]; + + // get seg_4lf parameters from parser + seg_4lf->enabled = hw->aom_param.p.segmentation_enabled & 1; + cm->cur_frame->segmentation_enabled = hw->aom_param.p.segmentation_enabled & 1; + cm->cur_frame->intra_only = (hw->aom_param.p.segmentation_enabled >> 2) & 1; + cm->cur_frame->segmentation_update_map = (hw->aom_param.p.segmentation_enabled >> 3) & 1; + + if (hw->aom_param.p.segmentation_enabled & 1) { // segmentation_enabled + if (hw->aom_param.p.segmentation_enabled & 2) { // segmentation_update_data + for (i = 0; i < MAX_SEGMENTS; i++) { + seg_4lf->seg_lf_info_y[i] = hw->aom_param.p.seg_lf_info_y[i]; + seg_4lf->seg_lf_info_c[i] = hw->aom_param.p.seg_lf_info_c[i]; + #ifdef DBG_LPF_PRINT + printk(" read seg_lf_info [%d] : 0x%x, 0x%x\n", + i, seg_4lf->seg_lf_info_y[i], seg_4lf->seg_lf_info_c[i]); + #endif + } + } // segmentation_update_data + else { // no segmentation_update_data + if (cm->prev_frame <= 0) { + for (i=0;iseg_lf_info_y[i] = 0; + seg_4lf->seg_lf_info_c[i] = 0; + } + } else { + for (i = 0; i < MAX_SEGMENTS; i++) { + seg_4lf->seg_lf_info_y[i] = cm->prev_frame->seg_lf_info_y[i]; + seg_4lf->seg_lf_info_c[i] = cm->prev_frame->seg_lf_info_c[i]; + #ifdef DBG_LPF_PRINT + printk(" Refrence seg_lf_info [%d] : 0x%x, 0x%x\n", + i, seg_4lf->seg_lf_info_y[i], seg_4lf->seg_lf_info_c[i]); + #endif + } + } + } // no segmentation_update_data + } // segmentation_enabled + else { + for (i=0;iseg_lf_info_y[i] = 0; + seg_4lf->seg_lf_info_c[i] = 0; + } + } // NOT segmentation_enabled + for (i=0;icur_frame->seg_lf_info_y[i] = seg_4lf->seg_lf_info_y[i]; + cm->cur_frame->seg_lf_info_c[i] = seg_4lf->seg_lf_info_c[i]; +#ifdef DBG_LPF_PRINT + printk(" SAVE seg_lf_info [%d] : 0x%x, 0x%x\n", + i, cm->cur_frame->seg_lf_info_y[i], + cm->cur_frame->seg_lf_info_c[i]); +#endif + } + + /* + * Update loop filter Thr/Lvl table for every frame + */ + av1_print(hw, AOM_DEBUG_HW_MORE, + "[test.c] av1_loop_filter_frame_init (run before every frame decoding start)\n"); + av1_loop_filter_frame_init(pbi, seg_4lf, lfi, lf, cm->dec_width); +#endif // not DUAL_DECODE +#endif + +#ifdef AOM_AV1_UPSCALE_INIT + /* + * init for upscaling + */ + av1_print(hw, AOM_DEBUG_HW_MORE, + "[test.c] av1_upscale_frame_init (run before every frame decoding start)\n"); + av1_upscale_frame_init(pbi, + &pbi->common, &hw->aom_param); +#endif // #ifdef AOM_AV1_UPSCALE_INIT + + //BuffInfo_t* buf_spec = pbi->work_space_buf; + av1_print(hw, AOM_DEBUG_HW_MORE, + "[test.c] cur_frame : %p prev_frame : %p - %p \n", + cm->cur_frame, cm->prev_frame, av1_get_primary_ref_frame_buf(cm)); + if (cm->cur_frame <= 0) { + WRITE_VREG(AOM_AV1_CDF_BUFFER_W, buf_spec->cdf_buf.buf_start); + WRITE_VREG(AOM_AV1_SEG_MAP_BUFFER_W, buf_spec->seg_map.buf_start); + } + else { + av1_print(hw, AOM_DEBUG_HW_MORE, + "[test.c] Config WRITE CDF_BUF/SEG_MAP_BUF : %d\n", + cur_pic_config->index); + WRITE_VREG(AOM_AV1_CDF_BUFFER_W, + buf_spec->cdf_buf.buf_start + (0x8000*cur_pic_config->index)); + WRITE_VREG(AOM_AV1_SEG_MAP_BUFFER_W, + buf_spec->seg_map.buf_start + (seg_map_size*cur_pic_config->index)); + } + cm->cur_frame->seg_mi_rows = cm->cur_frame->mi_rows; + cm->cur_frame->seg_mi_cols = cm->cur_frame->mi_cols; + if (cm->prev_frame <= 0) { + WRITE_VREG(AOM_AV1_CDF_BUFFER_R, buf_spec->cdf_buf.buf_start); + WRITE_VREG(AOM_AV1_SEG_MAP_BUFFER_R, buf_spec->seg_map.buf_start); + } else { + av1_print(hw, AOM_DEBUG_HW_MORE, + "[test.c] Config READ CDF_BUF/SEG_MAP_BUF : %d\n", + prev_pic_config->index); + WRITE_VREG(AOM_AV1_CDF_BUFFER_R, + buf_spec->cdf_buf.buf_start + (0x8000*prev_pic_config->index)); + WRITE_VREG(AOM_AV1_SEG_MAP_BUFFER_R, + buf_spec->seg_map.buf_start + (seg_map_size*prev_pic_config->index)); + + // segmentation_enabled but no segmentation_update_data + if ((hw->aom_param.p.segmentation_enabled & 3) == 1) { + av1_print(hw, AOM_DEBUG_HW_MORE, + "[test.c] segfeatures_copy from prev_frame\n"); + for (i = 0; i < 8; i++) { + WRITE_VREG(AOM_AV1_SEGMENT_FEATURE, + cm->prev_frame->segment_feature[i]); + } + } + // segmentation_enabled but no segmentation_update_map + if ((hw->aom_param.p.segmentation_enabled & 9) == 1) { + av1_print(hw, AOM_DEBUG_HW_MORE, + "[test.c] seg_map_size copy from prev_frame\n"); + cm->cur_frame->seg_mi_rows = cm->prev_frame->seg_mi_rows; + cm->cur_frame->seg_mi_cols = cm->prev_frame->seg_mi_cols; + } + } +#ifdef PRINT_HEVC_DATA_PATH_MONITOR + { + uint32_t total_clk_count; + uint32_t path_transfer_count; + uint32_t path_wait_count; + float path_wait_ratio; + if (pbi->decode_idx > 1) { + WRITE_VREG(HEVC_PATH_MONITOR_CTRL, 0); // Disabble monitor and set rd_idx to 0 + total_clk_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + + WRITE_VREG(HEVC_PATH_MONITOR_CTRL, (1<<4)); // Disabble monitor and set rd_idx to 0 + + // parser --> iqit + path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + if (path_transfer_count == 0) + path_wait_ratio = 0.0; + else + path_wait_ratio = + (float)path_wait_count/(float)path_transfer_count; + printk("[P%d HEVC PATH] Parser/IQIT/IPP/DBLK/OW/DDR/CMD WAITING \% : %.2f", + pbi->decode_idx - 2, + path_wait_ratio); + + // iqit --> ipp + path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + if (path_transfer_count == 0) + path_wait_ratio = 0.0; + else + path_wait_ratio = (float)path_wait_count/(float)path_transfer_count; + printk(" %.2f", path_wait_ratio); + + // dblk <-- ipp + path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + if (path_transfer_count == 0) + path_wait_ratio = 0.0; + else + path_wait_ratio = (float)path_wait_count/(float)path_transfer_count; + printk(" %.2f", path_wait_ratio); + + // dblk --> ow + path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + if (path_transfer_count == 0) + path_wait_ratio = 0.0; + else path_wait_ratio = + (float)path_wait_count/(float)path_transfer_count; + printk(" %.2f", path_wait_ratio); + + // <--> DDR + path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + if (path_transfer_count == 0) + path_wait_ratio = 0.0; + else path_wait_ratio = + (float)path_wait_count/(float)path_transfer_count; + printk(" %.2f", path_wait_ratio); + + // CMD + path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + if (path_transfer_count == 0) + path_wait_ratio = 0.0; + else + path_wait_ratio = (float)path_wait_count/(float)path_transfer_count; + printk(" %.2f\n", path_wait_ratio); + } + } + +#endif + +} + +static void aom_config_work_space_hw(struct AV1HW_s *hw, u32 mask) +{ + struct BuffInfo_s *buf_spec = hw->work_space_buf; + unsigned int data32; + av1_print(hw, AOM_DEBUG_HW_MORE, "%s %d\n", __func__, __LINE__); + if (debug && hw->init_flag == 0) + av1_print(hw, AOM_DEBUG_HW_MORE, "%s %x %x %x %x %x %x %x %x\n", + __func__, + buf_spec->ipp.buf_start, + buf_spec->start_adr, + buf_spec->short_term_rps.buf_start, + buf_spec->sao_up.buf_start, + buf_spec->swap_buf.buf_start, + buf_spec->scalelut.buf_start, + buf_spec->dblk_para.buf_start, + buf_spec->dblk_data.buf_start); + if (mask & HW_MASK_FRONT) { + av1_print(hw, AOM_DEBUG_HW_MORE, "%s %d\n", __func__, __LINE__); + if ((debug & AOM_AV1_DEBUG_SEND_PARAM_WITH_REG) == 0) + WRITE_VREG(HEVC_RPM_BUFFER, (u32)hw->rpm_phy_addr); + + /*WRITE_VREG(HEVC_STREAM_SWAP_BUFFER, + buf_spec->swap_buf.buf_start);*/ + WRITE_VREG(LMEM_DUMP_ADR, (u32)hw->lmem_phy_addr); + + } + + av1_print(hw, AOM_DEBUG_HW_MORE, "%s %d\n", __func__, __LINE__); + + WRITE_VREG(AOM_AV1_DAALA_TOP_BUFFER, + buf_spec->daala_top.buf_start); + WRITE_VREG(AV1_GMC_PARAM_BUFF_ADDR, + buf_spec->gmc_buf.buf_start); + + WRITE_VREG(HEVC_DBLK_CFG4, + buf_spec->dblk_para.buf_start); // cfg_addr_cif + WRITE_VREG(HEVC_DBLK_CFG5, + buf_spec->dblk_data.buf_start); // cfg_addr_xio + + if (mask & HW_MASK_BACK) { +#ifdef LOSLESS_COMPRESS_MODE + int losless_comp_header_size = + compute_losless_comp_header_size(hw->init_pic_w, + hw->init_pic_h); + int losless_comp_body_size = + compute_losless_comp_body_size(hw->init_pic_w, + hw->init_pic_h, buf_alloc_depth == 10); +#endif +#ifdef AOM_AV1_MMU_DW + int losless_comp_header_size_dw = + compute_losless_comp_header_size_dw(hw->init_pic_w, + hw->init_pic_h); + int losless_comp_body_size_dw = + compute_losless_comp_body_size_dw(hw->init_pic_w, + hw->init_pic_h, buf_alloc_depth == 10); +#endif + WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE, + buf_spec->ipp.buf_start); + WRITE_VREG(HEVC_SAO_UP, buf_spec->sao_up.buf_start); + //WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start); +#ifdef CHANGE_REMOVED + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { + /* cfg_addr_adp*/ + WRITE_VREG(HEVC_DBLK_CFGE, buf_spec->dblk_para.buf_start); + if (debug & AV1_DEBUG_BUFMGR_MORE) + pr_info("Write HEVC_DBLK_CFGE\n"); + } +#endif + /* cfg_p_addr */ + WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start); + /* cfg_d_addr */ + WRITE_VREG(HEVC_DBLK_CFG5, buf_spec->dblk_data.buf_start); + +#ifdef CHANGE_REMOVED + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { + /* + * data32 = (READ_VREG(HEVC_DBLK_CFG3)>>8) & 0xff; // xio left offset, default is 0x40 + * data32 = data32 * 2; + * data32 = (READ_VREG(HEVC_DBLK_CFG3)>>16) & 0xff; // adp left offset, default is 0x040 + * data32 = data32 * 2; + */ + WRITE_VREG(HEVC_DBLK_CFG3, 0x808010); // make left storage 2 x 4k] + } +#endif +#ifdef LOSLESS_COMPRESS_MODE + if (hw->mmu_enable) { + /*bit[4] : paged_mem_mode*/ + WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0x1 << 4)); +#ifdef CHANGE_REMOVED + if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1) +#endif + WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, 0); + } else { + /*if (cur_pic_config->bit_depth == AOM_BITS_10) + * WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3)); + */ + /*bit[3] smem mdoe*/ + /*else WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (1<<3));*/ + /*bit[3] smem mdoe*/ + WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, + (losless_comp_body_size >> 5)); + } + /*WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, + (losless_comp_body_size >> 5));*/ + /*WRITE_VREG(HEVCD_MPP_DECOMP_CTL3, + (0xff<<20) | (0xff<<10) | 0xff);*/ + /*8-bit mode */ + WRITE_VREG(HEVC_CM_BODY_LENGTH, losless_comp_body_size); + WRITE_VREG(HEVC_CM_HEADER_OFFSET, losless_comp_body_size); + WRITE_VREG(HEVC_CM_HEADER_LENGTH, losless_comp_header_size); + if (get_double_write_mode(hw) & 0x10) + WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31); +#else + WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31); +#endif + + if (hw->mmu_enable) { + WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR, buf_spec->mmu_vbh.buf_start); + WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR, buf_spec->mmu_vbh.buf_start + + VBH_BUF_SIZE); + /*data32 = READ_VREG(HEVC_SAO_CTRL9);*/ + /*data32 |= 0x1;*/ + /*WRITE_VREG(HEVC_SAO_CTRL9, data32);*/ + + /* use HEVC_CM_HEADER_START_ADDR */ + data32 = READ_VREG(HEVC_SAO_CTRL5); + data32 |= (1<<10); + WRITE_VREG(HEVC_SAO_CTRL5, data32); + } +#ifdef AOM_AV1_MMU_DW + data32 = READ_VREG(HEVC_SAO_CTRL5); + if (hw->dw_mmu_enable) { + data32 = READ_VREG(HEVC_SAO_CTRL9); + data32 |= (1<<10); + WRITE_VREG(HEVC_SAO_CTRL9, data32); + + WRITE_VREG(HEVC_CM_BODY_LENGTH2,losless_comp_body_size_dw); + WRITE_VREG(HEVC_CM_HEADER_OFFSET2,losless_comp_body_size_dw); + WRITE_VREG(HEVC_CM_HEADER_LENGTH2,losless_comp_header_size_dw); + + WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR2, buf_spec->mmu_vbh_dw.buf_start); + WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR2, buf_spec->mmu_vbh_dw.buf_start + + VBH_BUF_SIZE); + + WRITE_VREG(HEVC_DW_VH0_ADDDR, buf_spec->mmu_vbh_dw.buf_start + + (2 * VBH_BUF_SIZE)); + WRITE_VREG(HEVC_DW_VH1_ADDDR, buf_spec->mmu_vbh_dw.buf_start + + (3 * VBH_BUF_SIZE)); + + /* use HEVC_CM_HEADER_START_ADDR */ + data32 |= (1<<15); + } else + data32 &= ~(1<<15); + WRITE_VREG(HEVC_SAO_CTRL5, data32); +#endif + + WRITE_VREG(LMEM_DUMP_ADR, (u32)hw->lmem_phy_addr); +#ifdef CHANGE_REMOVED + + WRITE_VREG(AV1_SEG_MAP_BUFFER, buf_spec->seg_map.buf_start); + + /**/ + WRITE_VREG(AV1_PROB_SWAP_BUFFER, hw->prob_buffer_phy_addr); + WRITE_VREG(AV1_COUNT_SWAP_BUFFER, hw->count_buffer_phy_addr); + if (hw->mmu_enable) { + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) + WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR, hw->frame_mmu_map_phy_addr); + else + WRITE_VREG(AV1_MMU_MAP_BUFFER, hw->frame_mmu_map_phy_addr); + } +#else + if (hw->mmu_enable) + WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL, hw->frame_mmu_map_phy_addr); +#ifdef AOM_AV1_MMU_DW + if (hw->dw_mmu_enable) { + WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2, hw->dw_frame_mmu_map_phy_addr); + //default of 0xffffffff will disable dw + WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0); + WRITE_VREG(HEVC_SAO_C_START_ADDR, 0); + } +#endif +#endif + } + + config_aux_buf(hw); +} + +#ifdef MCRCC_ENABLE +static u32 mcrcc_cache_alg_flag = 1; +static void mcrcc_perfcount_reset(struct AV1HW_s *hw); +static void decomp_perfcount_reset(struct AV1HW_s *hw); +#endif + +static void aom_init_decoder_hw(struct AV1HW_s *hw, u32 mask) +{ + unsigned int data32; + int i; + const unsigned short parser_cmd[PARSER_CMD_NUMBER] = { + 0x0401, 0x8401, 0x0800, 0x0402, 0x9002, 0x1423, + 0x8CC3, 0x1423, 0x8804, 0x9825, 0x0800, 0x04FE, + 0x8406, 0x8411, 0x1800, 0x8408, 0x8409, 0x8C2A, + 0x9C2B, 0x1C00, 0x840F, 0x8407, 0x8000, 0x8408, + 0x2000, 0xA800, 0x8410, 0x04DE, 0x840C, 0x840D, + 0xAC00, 0xA000, 0x08C0, 0x08E0, 0xA40E, 0xFC00, + 0x7C00 + }; +#if 0 + if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_G12A) { + /* Set MCR fetch priorities*/ + data32 = 0x1 | (0x1 << 2) | (0x1 <<3) | + (24 << 4) | (32 << 11) | (24 << 18) | (32 << 25); + WRITE_VREG(HEVCD_MPP_DECOMP_AXIURG_CTL, data32); + } +#endif + /*if (debug & AV1_DEBUG_BUFMGR_MORE) + pr_info("%s\n", __func__);*/ + if (mask & HW_MASK_FRONT) { + data32 = READ_VREG(HEVC_PARSER_INT_CONTROL); +#ifdef CHANGE_REMOVED +#if 1 + /* set bit 31~29 to 3 if HEVC_STREAM_FIFO_CTL[29] is 1 */ + data32 &= ~(7 << 29); + data32 |= (3 << 29); +#endif + data32 = data32 | + (1 << 24) |/*stream_buffer_empty_int_amrisc_enable*/ + (1 << 22) |/*stream_fifo_empty_int_amrisc_enable*/ + (1 << 7) |/*dec_done_int_cpu_enable*/ + (1 << 4) |/*startcode_found_int_cpu_enable*/ + (0 << 3) |/*startcode_found_int_amrisc_enable*/ + (1 << 0) /*parser_int_enable*/ + ; +#else + data32 = data32 & 0x03ffffff; + data32 = data32 | + (3 << 29) | // stream_buffer_empty_int_ctl ( 0x200 interrupt) + (3 << 26) | // stream_fifo_empty_int_ctl ( 4 interrupt) + (1 << 24) | // stream_buffer_empty_int_amrisc_enable + (1 << 22) | // stream_fifo_empty_int_amrisc_enable +#ifdef AOM_AV1_HED_FB +#ifdef DUAL_DECODE + // For HALT CCPU test. Use Pull inside CCPU to generate interrupt + // (1 << 9) | // fed_fb_slice_done_int_amrisc_enable +#else + (1 << 10) | // fed_fb_slice_done_int_cpu_enable +#endif +#endif + (1 << 7) | // dec_done_int_cpu_enable + (1 << 4) | // startcode_found_int_cpu_enable + (0 << 3) | // startcode_found_int_amrisc_enable + (1 << 0) // parser_int_enable + ; +#endif + WRITE_VREG(HEVC_PARSER_INT_CONTROL, data32); + + data32 = READ_VREG(HEVC_SHIFT_STATUS); + data32 = data32 | + (0 << 1) |/*emulation_check_off AV1 + do not have emulation*/ + (1 << 0)/*startcode_check_on*/ + ; + WRITE_VREG(HEVC_SHIFT_STATUS, data32); + WRITE_VREG(HEVC_SHIFT_CONTROL, + (0 << 14) | /*disable_start_code_protect*/ + (1 << 10) | /*length_zero_startcode_en for AV1*/ + (1 << 9) | /*length_valid_startcode_en for AV1*/ + (3 << 6) | /*sft_valid_wr_position*/ + (2 << 4) | /*emulate_code_length_sub_1*/ + (3 << 1) | /*start_code_length_sub_1 + AV1 use 0x00000001 as startcode (4 Bytes)*/ + (1 << 0) /*stream_shift_enable*/ + ); + + WRITE_VREG(HEVC_CABAC_CONTROL, + (1 << 0)/*cabac_enable*/ + ); + + WRITE_VREG(HEVC_PARSER_CORE_CONTROL, + (1 << 0)/* hevc_parser_core_clk_en*/ + ); + + WRITE_VREG(HEVC_DEC_STATUS_REG, 0); + } + + if (mask & HW_MASK_BACK) { + /*Initial IQIT_SCALELUT memory + -- just to avoid X in simulation*/ + + WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/ + for (i = 0; i < 1024; i++) + WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0); + } + + if (mask & HW_MASK_FRONT) { + u32 decode_mode; +/* +#ifdef ENABLE_SWAP_TEST + WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100); +#else + WRITE_VREG(HEVC_STREAM_SWAP_TEST, 0); +#endif +*/ +#ifdef MULTI_INSTANCE_SUPPORT + if (!hw->m_ins_flag) { + if (hw->low_latency_flag) + decode_mode = DECODE_MODE_SINGLE_LOW_LATENCY; + else + decode_mode = DECODE_MODE_SINGLE; + } else if (vdec_frame_based(hw_to_vdec(hw))) + decode_mode = hw->no_head ? + DECODE_MODE_MULTI_FRAMEBASE_NOHEAD : + DECODE_MODE_MULTI_FRAMEBASE; + else + decode_mode = DECODE_MODE_MULTI_STREAMBASE; + if (debug & AOM_DEBUG_BUFMGR_ONLY) + decode_mode |= (1 << 16); + WRITE_VREG(DECODE_MODE, decode_mode); + WRITE_VREG(HEVC_DECODE_SIZE, 0); + WRITE_VREG(HEVC_DECODE_COUNT, 0); +#else + WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); + WRITE_VREG(HEVC_DECODE_PIC_BEGIN_REG, 0); + WRITE_VREG(HEVC_DECODE_PIC_NUM_REG, 0x7fffffff); /*to remove*/ +#endif + /*Send parser_cmd*/ + WRITE_VREG(HEVC_PARSER_CMD_WRITE, (1 << 16) | (0 << 0)); + for (i = 0; i < PARSER_CMD_NUMBER; i++) + WRITE_VREG(HEVC_PARSER_CMD_WRITE, parser_cmd[i]); + WRITE_VREG(HEVC_PARSER_CMD_SKIP_0, PARSER_CMD_SKIP_CFG_0); + WRITE_VREG(HEVC_PARSER_CMD_SKIP_1, PARSER_CMD_SKIP_CFG_1); + WRITE_VREG(HEVC_PARSER_CMD_SKIP_2, PARSER_CMD_SKIP_CFG_2); + + + WRITE_VREG(HEVC_PARSER_IF_CONTROL, + /* (1 << 8) |*/ /*sao_sw_pred_enable*/ + (1 << 5) | /*parser_sao_if_en*/ + (1 << 2) | /*parser_mpred_if_en*/ + (1 << 0) /*parser_scaler_if_en*/ + ); + } + + if (mask & HW_MASK_BACK) { + /*Changed to Start MPRED in microcode*/ + /* + pr_info("[test.c] Start MPRED\n"); + WRITE_VREG(HEVC_MPRED_INT_STATUS, + (1<<31) + ); + */ + WRITE_VREG(HEVCD_IPP_TOP_CNTL, + (0 << 1) | /*enable ipp*/ + (1 << 0) /*software reset ipp and mpp*/ + ); +#ifdef CHANGE_REMOVED + WRITE_VREG(HEVCD_IPP_TOP_CNTL, + (1 << 1) | /*enable ipp*/ + (0 << 0) /*software reset ipp and mpp*/ + ); +#else + WRITE_VREG(HEVCD_IPP_TOP_CNTL, + (3 << 4) | // av1 + (1 << 1) | /*enable ipp*/ + (0 << 0) /*software reset ipp and mpp*/ + ); +#endif + if (get_double_write_mode(hw) & 0x10) { + /*Enable NV21 reference read mode for MC*/ + WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31); + } +#ifdef MCRCC_ENABLE + /*Initialize mcrcc and decomp perf counters*/ + if (mcrcc_cache_alg_flag && + hw->init_flag == 0) { + mcrcc_perfcount_reset(hw); + decomp_perfcount_reset(hw); + } +#endif + } +#ifdef CHANGE_REMOVED +#else +// Set MCR fetch priorities + data32 = 0x1 | (0x1 << 2) | (0x1 <<3) | + (24 << 4) | (32 << 11) | (24 << 18) | (32 << 25); + WRITE_VREG(HEVCD_MPP_DECOMP_AXIURG_CTL, data32); +#endif + return; +} + + +#ifdef CONFIG_HEVC_CLK_FORCED_ON +static void config_av1_clk_forced_on(void) +{ + unsigned int rdata32; + /*IQIT*/ + rdata32 = READ_VREG(HEVC_IQIT_CLK_RST_CTRL); + WRITE_VREG(HEVC_IQIT_CLK_RST_CTRL, rdata32 | (0x1 << 2)); + + /* DBLK*/ + rdata32 = READ_VREG(HEVC_DBLK_CFG0); + WRITE_VREG(HEVC_DBLK_CFG0, rdata32 | (0x1 << 2)); + + /* SAO*/ + rdata32 = READ_VREG(HEVC_SAO_CTRL1); + WRITE_VREG(HEVC_SAO_CTRL1, rdata32 | (0x1 << 2)); + + /*MPRED*/ + rdata32 = READ_VREG(HEVC_MPRED_CTRL1); + WRITE_VREG(HEVC_MPRED_CTRL1, rdata32 | (0x1 << 24)); + + /* PARSER*/ + rdata32 = READ_VREG(HEVC_STREAM_CONTROL); + WRITE_VREG(HEVC_STREAM_CONTROL, rdata32 | (0x1 << 15)); + rdata32 = READ_VREG(HEVC_SHIFT_CONTROL); + WRITE_VREG(HEVC_SHIFT_CONTROL, rdata32 | (0x1 << 15)); + rdata32 = READ_VREG(HEVC_CABAC_CONTROL); + WRITE_VREG(HEVC_CABAC_CONTROL, rdata32 | (0x1 << 13)); + rdata32 = READ_VREG(HEVC_PARSER_CORE_CONTROL); + WRITE_VREG(HEVC_PARSER_CORE_CONTROL, rdata32 | (0x1 << 15)); + rdata32 = READ_VREG(HEVC_PARSER_INT_CONTROL); + WRITE_VREG(HEVC_PARSER_INT_CONTROL, rdata32 | (0x1 << 15)); + rdata32 = READ_VREG(HEVC_PARSER_IF_CONTROL); + WRITE_VREG(HEVC_PARSER_IF_CONTROL, + rdata32 | (0x1 << 6) | (0x1 << 3) | (0x1 << 1)); + + /*IPP*/ + rdata32 = READ_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG); + WRITE_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG, rdata32 | 0xffffffff); + + /* MCRCC*/ + rdata32 = READ_VREG(HEVCD_MCRCC_CTL1); + WRITE_VREG(HEVCD_MCRCC_CTL1, rdata32 | (0x1 << 3)); +} +#endif + + +static void av1_local_uninit(struct AV1HW_s *hw) +{ + hw->rpm_ptr = NULL; + hw->lmem_ptr = NULL; +#ifdef DUMP_FILMGRAIN + hw->fg_ptr = NULL; + if (hw->fg_addr) { + if (hw->fg_phy_addr) + dma_free_coherent(amports_get_dma_device(), + FGS_TABLE_SIZE, hw->fg_addr, + hw->fg_phy_addr); + hw->fg_addr = NULL; + } +#endif + if (hw->rpm_addr) { + dma_free_coherent(amports_get_dma_device(), + RPM_BUF_SIZE, + hw->rpm_addr, + hw->rpm_phy_addr); + hw->rpm_addr = NULL; + } + if (hw->aux_addr) { + dma_free_coherent(amports_get_dma_device(), + hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr, + hw->aux_phy_addr); + hw->aux_addr = NULL; + } + if (hw->lmem_addr) { + if (hw->lmem_phy_addr) + dma_free_coherent(amports_get_dma_device(), + LMEM_BUF_SIZE, hw->lmem_addr, + hw->lmem_phy_addr); + hw->lmem_addr = NULL; + } + if (hw->prob_buffer_addr) { + if (hw->prob_buffer_phy_addr) + dma_free_coherent(amports_get_dma_device(), + PROB_BUF_SIZE, hw->prob_buffer_addr, + hw->prob_buffer_phy_addr); + + hw->prob_buffer_addr = NULL; + } + if (hw->count_buffer_addr) { + if (hw->count_buffer_phy_addr) + dma_free_coherent(amports_get_dma_device(), + COUNT_BUF_SIZE, hw->count_buffer_addr, + hw->count_buffer_phy_addr); + + hw->count_buffer_addr = NULL; + } + if (hw->mmu_enable) { + u32 mmu_map_size = vav1_frame_mmu_map_size(hw); + if (hw->frame_mmu_map_addr) { + if (hw->frame_mmu_map_phy_addr) + dma_free_coherent(amports_get_dma_device(), + mmu_map_size, + hw->frame_mmu_map_addr, + hw->frame_mmu_map_phy_addr); + hw->frame_mmu_map_addr = NULL; + } + } +#ifdef AOM_AV1_MMU_DW + if (hw->dw_mmu_enable) { + u32 mmu_map_size = vaom_dw_frame_mmu_map_size(hw); + if (hw->dw_frame_mmu_map_addr) { + if (hw->dw_frame_mmu_map_phy_addr) + dma_free_coherent(amports_get_dma_device(), + mmu_map_size, + hw->dw_frame_mmu_map_addr, + hw->dw_frame_mmu_map_phy_addr); + hw->dw_frame_mmu_map_addr = NULL; + } + } +#endif + if (hw->gvs) + vfree(hw->gvs); + hw->gvs = NULL; +} + +static int av1_local_init(struct AV1HW_s *hw) +{ + int ret = -1; + /*int losless_comp_header_size, losless_comp_body_size;*/ + + struct BuffInfo_s *cur_buf_info = NULL; + + memset(&hw->param, 0, sizeof(union param_u)); +#ifdef MULTI_INSTANCE_SUPPORT + cur_buf_info = &hw->work_space_buf_store; + hw->pbi->work_space_buf = cur_buf_info; + + if (vdec_is_support_4k()) { + memcpy(cur_buf_info, &aom_workbuff_spec[1], /* 8k */ + sizeof(struct BuffInfo_s)); + } else + memcpy(cur_buf_info, &aom_workbuff_spec[0],/* 1080p */ + sizeof(struct BuffInfo_s)); + + cur_buf_info->start_adr = hw->buf_start; + if (!hw->mmu_enable) + hw->mc_buf_spec.buf_end = hw->buf_start + hw->buf_size; + +#else +/*! MULTI_INSTANCE_SUPPORT*/ + if (vdec_is_support_4k()) { + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) + cur_buf_info = &aom_workbuff_spec[1];/* 8k work space */ + else + cur_buf_info = &aom_workbuff_spec[1];/* 4k2k work space */ + } else + cur_buf_info = &aom_workbuff_spec[0];/* 1080p work space */ + +#endif + + init_buff_spec(hw, cur_buf_info); + aom_bufmgr_init(hw, cur_buf_info, NULL); + + if (!vdec_is_support_4k() + && (buf_alloc_width > 1920 && buf_alloc_height > 1088)) { + buf_alloc_width = 1920; + buf_alloc_height = 1088; + if (hw->max_pic_w > 1920 && hw->max_pic_h > 1088) { + hw->max_pic_w = 1920; + hw->max_pic_h = 1088; + } + } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { +#if 0 + buf_alloc_width = 8192; + buf_alloc_height = 4608; +#else + buf_alloc_width = 4096; + buf_alloc_height = 2304; +#endif + } + hw->init_pic_w = hw->max_pic_w ? hw->max_pic_w : + (buf_alloc_width ? buf_alloc_width : + (hw->vav1_amstream_dec_info.width ? + hw->vav1_amstream_dec_info.width : + hw->work_space_buf->max_width)); + hw->init_pic_h = hw->max_pic_h ? hw->max_pic_h : + (buf_alloc_height ? buf_alloc_height : + (hw->vav1_amstream_dec_info.height ? + hw->vav1_amstream_dec_info.height : + hw->work_space_buf->max_height)); + + hw->pbi->frame_width = hw->init_pic_w; + hw->pbi->frame_height = hw->init_pic_h; + + /* video is not support unaligned with 64 in tl1 + ** vdec canvas mode will be linear when dump yuv is set + */ + if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && + (hw->double_write_mode != 0) && + (((hw->max_pic_w % 64) != 0) || + (hw->vav1_amstream_dec_info.width % 64) != 0)) { + if (hw_to_vdec(hw)->canvas_mode != + CANVAS_BLKMODE_LINEAR) + mem_map_mode = 2; + else { + mem_map_mode = 0; + av1_print(hw, AOM_DEBUG_HW_MORE, "vdec blkmod linear, force mem_map_mode 0\n"); + } + } + +#if 0 +//ndef MV_USE_FIXED_BUF + if (init_mv_buf_list(hw) < 0) { + pr_err("%s: init_mv_buf_list fail\n", __func__); + return -1; + } +#endif + if (hw->save_buffer_mode) + hw->used_buf_num = MAX_BUF_NUM_SAVE_BUF; + else + hw->used_buf_num = max_buf_num; + if (hw->used_buf_num > MAX_BUF_NUM) + hw->used_buf_num = MAX_BUF_NUM; + if (hw->used_buf_num > FRAME_BUFFERS) + hw->used_buf_num = FRAME_BUFFERS; + + hw->pts_unstable = ((unsigned long)(hw->vav1_amstream_dec_info.param) + & 0x40) >> 6; + + if ((debug & AOM_AV1_DEBUG_SEND_PARAM_WITH_REG) == 0) { + hw->rpm_addr = dma_alloc_coherent(amports_get_dma_device(), + RPM_BUF_SIZE, + &hw->rpm_phy_addr, GFP_KERNEL); + if (hw->rpm_addr == NULL) { + pr_err("%s: failed to alloc rpm buffer\n", __func__); + return -1; + } + + hw->rpm_ptr = hw->rpm_addr; + } + + if (prefix_aux_buf_size > 0 || + suffix_aux_buf_size > 0) { + u32 aux_buf_size; + + hw->prefix_aux_size = AUX_BUF_ALIGN(prefix_aux_buf_size); + hw->suffix_aux_size = AUX_BUF_ALIGN(suffix_aux_buf_size); + aux_buf_size = hw->prefix_aux_size + hw->suffix_aux_size; + hw->aux_addr =dma_alloc_coherent(amports_get_dma_device(), + aux_buf_size, &hw->aux_phy_addr, GFP_KERNEL); + if (hw->aux_addr == NULL) { + pr_err("%s: failed to alloc rpm buffer\n", __func__); + return -1; + } + } +#ifdef DUMP_FILMGRAIN + hw->fg_addr = dma_alloc_coherent(amports_get_dma_device(), + FGS_TABLE_SIZE, + &hw->fg_phy_addr, GFP_KERNEL); + if (hw->fg_addr == NULL) { + pr_err("%s: failed to alloc fg buffer\n", __func__); + } + hw->fg_ptr = hw->fg_addr; +#endif + hw->lmem_addr = dma_alloc_coherent(amports_get_dma_device(), + LMEM_BUF_SIZE, + &hw->lmem_phy_addr, GFP_KERNEL); + if (hw->lmem_addr == NULL) { + pr_err("%s: failed to alloc lmem buffer\n", __func__); + return -1; + } + hw->lmem_ptr = hw->lmem_addr; + + hw->prob_buffer_addr = dma_alloc_coherent(amports_get_dma_device(), + PROB_BUF_SIZE, + &hw->prob_buffer_phy_addr, GFP_KERNEL); + if (hw->prob_buffer_addr == NULL) { + pr_err("%s: failed to alloc prob_buffer\n", __func__); + return -1; + } + memset(hw->prob_buffer_addr, 0, PROB_BUF_SIZE); + hw->count_buffer_addr = dma_alloc_coherent(amports_get_dma_device(), + COUNT_BUF_SIZE, + &hw->count_buffer_phy_addr, GFP_KERNEL); + if (hw->count_buffer_addr == NULL) { + pr_err("%s: failed to alloc count_buffer\n", __func__); + return -1; + } + memset(hw->count_buffer_addr, 0, COUNT_BUF_SIZE); + + if (hw->mmu_enable) { + u32 mmu_map_size = vav1_frame_mmu_map_size(hw); + hw->frame_mmu_map_addr = + dma_alloc_coherent(amports_get_dma_device(), + mmu_map_size, + &hw->frame_mmu_map_phy_addr, GFP_KERNEL); + if (hw->frame_mmu_map_addr == NULL) { + pr_err("%s: failed to alloc count_buffer\n", __func__); + return -1; + } + memset(hw->frame_mmu_map_addr, 0, mmu_map_size); + } +#ifdef AOM_AV1_MMU_DW + if (hw->dw_mmu_enable) { + u32 mmu_map_size = vaom_dw_frame_mmu_map_size(hw); + hw->dw_frame_mmu_map_addr = + dma_alloc_coherent(amports_get_dma_device(), + mmu_map_size, + &hw->dw_frame_mmu_map_phy_addr, GFP_KERNEL); + if (hw->dw_frame_mmu_map_addr == NULL) { + pr_err("%s: failed to alloc count_buffer\n", __func__); + return -1; + } + memset(hw->dw_frame_mmu_map_addr, 0, mmu_map_size); + } +#endif + ret = 0; + return ret; +} + + +#define spec2canvas(x) \ + (((x)->uv_canvas_index << 16) | \ + ((x)->uv_canvas_index << 8) | \ + ((x)->y_canvas_index << 0)) + + +static void set_canvas(struct AV1HW_s *hw, + struct PIC_BUFFER_CONFIG_s *pic_config) +{ + struct vdec_s *vdec = hw_to_vdec(hw); + int canvas_w = ALIGN(pic_config->y_crop_width, 64)/4; + int canvas_h = ALIGN(pic_config->y_crop_height, 32)/4; + int blkmode = mem_map_mode; + /*CANVAS_BLKMODE_64X32*/ + if (pic_config->double_write_mode) { + canvas_w = pic_config->y_crop_width / + get_double_write_ratio(hw, + pic_config->double_write_mode); + canvas_h = pic_config->y_crop_height / + get_double_write_ratio(hw, + pic_config->double_write_mode); + + if (mem_map_mode == 0) + canvas_w = ALIGN(canvas_w, 32); + else + canvas_w = ALIGN(canvas_w, 64); + canvas_h = ALIGN(canvas_h, 32); + + if (vdec->parallel_dec == 1) { + if (pic_config->y_canvas_index == -1) + pic_config->y_canvas_index = + vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id); + if (pic_config->uv_canvas_index == -1) + pic_config->uv_canvas_index = + vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id); + } else { + pic_config->y_canvas_index = 128 + pic_config->index * 2; + pic_config->uv_canvas_index = 128 + pic_config->index * 2 + 1; + } + + canvas_config_ex(pic_config->y_canvas_index, + pic_config->dw_y_adr, canvas_w, canvas_h, + CANVAS_ADDR_NOWRAP, blkmode, 0x7); + canvas_config_ex(pic_config->uv_canvas_index, + pic_config->dw_u_v_adr, canvas_w, canvas_h, + CANVAS_ADDR_NOWRAP, blkmode, 0x7); + +#ifdef MULTI_INSTANCE_SUPPORT + pic_config->canvas_config[0].phy_addr = + pic_config->dw_y_adr; + pic_config->canvas_config[0].width = + canvas_w; + pic_config->canvas_config[0].height = + canvas_h; + pic_config->canvas_config[0].block_mode = + blkmode; + pic_config->canvas_config[0].endian = 7; + + pic_config->canvas_config[1].phy_addr = + pic_config->dw_u_v_adr; + pic_config->canvas_config[1].width = + canvas_w; + pic_config->canvas_config[1].height = + canvas_h; + pic_config->canvas_config[1].block_mode = + blkmode; + pic_config->canvas_config[1].endian = 7; +#endif + } +} + +static void set_frame_info(struct AV1HW_s *hw, struct vframe_s *vf) +{ + unsigned int ar; + vf->duration = hw->frame_dur; + vf->duration_pulldown = 0; + vf->flag = 0; + vf->prop.master_display_colour = hw->vf_dp; + vf->signal_type = hw->video_signal_type; + if (vf->compWidth && vf->compHeight) + hw->frame_ar = vf->compHeight * 0x100 / vf->compWidth; + ar = min_t(u32, hw->frame_ar, DISP_RATIO_ASPECT_RATIO_MAX); + vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT); + +} + +static int vav1_vf_states(struct vframe_states *states, void *op_arg) +{ + struct AV1HW_s *hw = (struct AV1HW_s *)op_arg; + + states->vf_pool_size = VF_POOL_SIZE; + states->buf_free_num = kfifo_len(&hw->newframe_q); + states->buf_avail_num = kfifo_len(&hw->display_q); + + if (step == 2) + states->buf_avail_num = 0; + return 0; +} + +static struct vframe_s *vav1_vf_peek(void *op_arg) +{ + struct vframe_s *vf[2] = {0, 0}; + struct AV1HW_s *hw = (struct AV1HW_s *)op_arg; + + if (step == 2) + return NULL; + + if (kfifo_out_peek(&hw->display_q, (void *)&vf, 2)) { + if (vf[1]) { + vf[0]->next_vf_pts_valid = true; + vf[0]->next_vf_pts = vf[1]->pts; + } else + vf[0]->next_vf_pts_valid = false; + return vf[0]; + } + + return NULL; +} + +static struct vframe_s *vav1_vf_get(void *op_arg) +{ + struct vframe_s *vf; + struct AV1HW_s *hw = (struct AV1HW_s *)op_arg; + + if (step == 2) + return NULL; + else if (step == 1) + step = 2; + + if (kfifo_get(&hw->display_q, &vf)) { + struct vframe_s *next_vf; + uint8_t index = vf->index & 0xff; + if (index < hw->used_buf_num) { + hw->vf_get_count++; + if (debug & AOM_DEBUG_VFRAME) { + struct BufferPool_s *pool = hw->pbi->common.buffer_pool; + struct PIC_BUFFER_CONFIG_s *pic = + &pool->frame_bufs[index].buf; + unsigned long flags; + lock_buffer_pool(hw->pbi->common.buffer_pool, flags); + av1_print(hw, AOM_DEBUG_VFRAME, "%s index 0x%x type 0x%x w/h %d/%d, aux size %d, pts %d, %lld\n", + __func__, vf->index, vf->type, + vf->width, vf->height, + pic->aux_data_size, + vf->pts, + vf->pts_us64); + unlock_buffer_pool(hw->pbi->common.buffer_pool, flags); + } + + if (kfifo_peek(&hw->display_q, &next_vf)) { + vf->next_vf_pts_valid = true; + vf->next_vf_pts = next_vf->pts; + } else + vf->next_vf_pts_valid = false; +#ifdef DUMP_FILMGRAIN + if (index == fg_dump_index) { + unsigned long flags; + int ii; + lock_buffer_pool(hw->pbi->common.buffer_pool, flags); + pr_info("FGS_TABLE for buffer %d:\n", index); + for (ii = 0; ii < FGS_TABLE_SIZE; ii++) { + pr_info("%02x ", hw->fg_ptr[ii]); + if (((ii+ 1) & 0xf) == 0) + pr_info("\n"); + } + unlock_buffer_pool(hw->pbi->common.buffer_pool, flags); + } +#endif + + return vf; + } + } + return NULL; +} + +static void vav1_vf_put(struct vframe_s *vf, void *op_arg) +{ + struct AV1HW_s *hw = (struct AV1HW_s *)op_arg; + uint8_t index = vf->index & 0xff; + unsigned long flags; + + if ((vf == NULL) || (hw == NULL)) + return; + + kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); + hw->vf_put_count++; + if (debug & AOM_DEBUG_VFRAME) { + lock_buffer_pool(hw->pbi->common.buffer_pool, flags); + av1_print(hw, AOM_DEBUG_VFRAME, "%s index 0x%x type 0x%x w/h %d/%d, pts %d, %lld\n", + __func__, vf->index, vf->type, + vf->width, vf->height, + vf->pts, + vf->pts_us64); + unlock_buffer_pool(hw->pbi->common.buffer_pool, flags); + } + + if (index < hw->used_buf_num) { + struct AV1_Common_s *cm = &hw->pbi->common; + struct BufferPool_s *pool = cm->buffer_pool; + + lock_buffer_pool(hw->pbi->common.buffer_pool, flags); + if ((debug & AV1_DEBUG_IGNORE_VF_REF) == 0) { + if (pool->frame_bufs[index].buf.vf_ref > 0) + pool->frame_bufs[index].buf.vf_ref--; + } + if (hw->wait_buf) + WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, + 0x1); + hw->last_put_idx = index; + hw->new_frame_displayed++; + unlock_buffer_pool(hw->pbi->common.buffer_pool, flags); + } + +} + +static int vav1_event_cb(int type, void *data, void *op_arg) +{ + unsigned long flags; + struct AV1HW_s *hw = (struct AV1HW_s *)op_arg; + struct AV1_Common_s *cm = &hw->pbi->common; + struct BufferPool_s *pool = cm->buffer_pool; + + if (type & VFRAME_EVENT_RECEIVER_RESET) { +#if 0 + unsigned long flags; + + amhevc_stop(); +#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER + vf_light_unreg_provider(&vav1_vf_prov); +#endif + spin_lock_irqsave(&hw->lock, flags); + vav1_local_init(); + vav1_prot_init(); + spin_unlock_irqrestore(&hw->lock, flags); +#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER + vf_reg_provider(&vav1_vf_prov); +#endif + amhevc_start(); +#endif + } else if (type & VFRAME_EVENT_RECEIVER_GET_AUX_DATA) { + struct provider_aux_req_s *req = + (struct provider_aux_req_s *)data; + unsigned char index; + + lock_buffer_pool(hw->pbi->common.buffer_pool, flags); + index = req->vf->index & 0xff; + req->aux_buf = NULL; + req->aux_size = 0; + if (req->bot_flag) + index = (req->vf->index >> 8) & 0xff; + if (index != 0xff + && index < hw->used_buf_num) { + struct PIC_BUFFER_CONFIG_s *pic_config = + &pool->frame_bufs[index].buf; + req->aux_buf = pic_config->aux_data_buf; + req->aux_size = pic_config->aux_data_size; +#if 0 +//def CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + if (hw->bypass_dvenl && !dolby_meta_with_el) + req->dv_enhance_exist = false; + else + req->dv_enhance_exist = + pic_config->dv_enhance_exist; + av1_print(hw, AOM_DEBUG_VFRAME, + "query dv_enhance_exist for pic (vf 0x%p, poc %d index %d) flag => %d, aux sizd 0x%x\n", + req->vf, + pic_config->POC, index, + req->dv_enhance_exist, req->aux_size); +#else + req->dv_enhance_exist = 0; +#endif + } + unlock_buffer_pool(hw->pbi->common.buffer_pool, flags); + + if (debug & AOM_DEBUG_AUX_DATA) + av1_print(hw, 0, + "%s(type 0x%x vf index 0x%x)=>size 0x%x\n", + __func__, type, index, req->aux_size); +#if 0 +//def CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + } else if (type & VFRAME_EVENT_RECEIVER_DOLBY_BYPASS_EL) { + if ((force_bypass_dvenl & 0x80000000) == 0) { + av1_print(hw, 0, + "%s: VFRAME_EVENT_RECEIVER_DOLBY_BYPASS_EL\n", + __func__); + hw->bypass_dvenl_enable = 1; + } + +#endif + } + return 0; +} + +void av1_inc_vf_ref(struct AV1HW_s *hw, int index) +{ + struct AV1_Common_s *cm = &hw->pbi->common; + + if ((debug & AV1_DEBUG_IGNORE_VF_REF) == 0) { + cm->buffer_pool->frame_bufs[index].buf.vf_ref++; + + av1_print(hw, AV1_DEBUG_BUFMGR_MORE, "%s index = %d new vf_ref = %d\r\n", + __func__, index, + cm->buffer_pool->frame_bufs[index].buf.vf_ref); + } +} + +static int frame_duration_adapt(struct AV1HW_s *hw, struct vframe_s *vf, u32 valid) +{ + u32 old_duration, pts_duration = 0; + u32 pts = vf->pts; + + if (hw->get_frame_dur == true) + return true; + + hw->frame_cnt_window++; + if (!(hw->av1_first_pts_ready == 1)) { + if (valid) { + hw->pts1 = pts; + hw->frame_cnt_window = 0; + hw->duration_from_pts_done = 0; + hw->av1_first_pts_ready = 1; + } else { + return false; + } + } else { + if (pts < hw->pts1) { + if (hw->frame_cnt_window > FRAME_CNT_WINDOW_SIZE) { + hw->pts1 = pts; + hw->frame_cnt_window = 0; + } + } + + if (valid && (hw->frame_cnt_window > FRAME_CNT_WINDOW_SIZE) && + (pts > hw->pts1) && (hw->duration_from_pts_done == 0)) { + old_duration = hw->frame_dur; + hw->pts2 = pts; + pts_duration = (((hw->pts2 - hw->pts1) * 16) / + (hw->frame_cnt_window * 15)); + + if (close_to(pts_duration, old_duration, 2000)) { + hw->frame_dur = pts_duration; + av1_print(hw, AV1_DEBUG_OUT_PTS, + "use calc duration %d\n", pts_duration); + } + + if (hw->duration_from_pts_done == 0) { + if (close_to(pts_duration, old_duration, RATE_CORRECTION_THRESHOLD)) { + hw->duration_from_pts_done = 1; + } else { + if (!close_to(pts_duration, + old_duration, 1000) && + !close_to(pts_duration, + hw->frame_dur, 1000) && + close_to(pts_duration, + hw->last_duration, 200)) { + /* frame_dur must + * wrong,recover it. + */ + hw->frame_dur = pts_duration; + } + hw->pts1 = hw->pts2; + hw->frame_cnt_window = 0; + hw->duration_from_pts_done = 0; + } + } + hw->last_duration = pts_duration; + } + } + return true; +} + +static void update_vf_memhandle(struct AV1HW_s *hw, + struct vframe_s *vf, struct PIC_BUFFER_CONFIG_s *pic) +{ + if (pic->index < 0) { + vf->mem_handle = NULL; + vf->mem_head_handle = NULL; + } else if (vf->type & VIDTYPE_SCATTER) { +#ifdef AOM_AV1_MMU_DW + if (pic->double_write_mode & 0x20 && + (debug & AOM_DEBUG_DW_DISP_MAIN) == 0) { + vf->mem_handle = + decoder_mmu_box_get_mem_handle( + hw->mmu_box_dw, pic->index); + vf->mem_head_handle = + decoder_bmmu_box_get_mem_handle( + hw->bmmu_box, + DW_HEADER_BUFFER_IDX(pic->BUF_index)); + } else +#endif + { + vf->mem_handle = + decoder_mmu_box_get_mem_handle( + hw->mmu_box, pic->index); + vf->mem_head_handle = + decoder_bmmu_box_get_mem_handle( + hw->bmmu_box, + HEADER_BUFFER_IDX(pic->BUF_index)); + } +#ifdef USE_SPEC_BUF_FOR_MMU_HEAD + vf->mem_head_handle = NULL; +#endif + } else { + vf->mem_handle = + decoder_bmmu_box_get_mem_handle( + hw->bmmu_box, VF_BUFFER_IDX(pic->BUF_index)); + vf->mem_head_handle = NULL; + /*vf->mem_head_handle = + *decoder_bmmu_box_get_mem_handle( + *hw->bmmu_box, VF_BUFFER_IDX(BUF_index)); + */ + } +} + +static int prepare_display_buf(struct AV1HW_s *hw, + struct PIC_BUFFER_CONFIG_s *pic_config) +{ + struct vframe_s *vf = NULL; + int stream_offset = pic_config->stream_offset; + unsigned short slice_type = pic_config->slice_type; + u32 pts_valid = 0, pts_us64_valid = 0; + u32 pts_save; + u64 pts_us64_save; + u32 frame_size; + int i; + + av1_print(hw, AOM_DEBUG_VFRAME, "%s index = %d\r\n", __func__, pic_config->index); + if (kfifo_get(&hw->newframe_q, &vf) == 0) { + av1_print(hw, 0, "fatal error, no available buffer slot."); + return -1; + } + + if (pic_config->double_write_mode && + (pic_config->double_write_mode & 0x20) == 0) + set_canvas(hw, pic_config); + + display_frame_count[hw->index]++; + if (vf) { + if (!force_pts_unstable) { + if ((pic_config->pts == 0) || (pic_config->pts <= hw->last_pts)) { + for (i = (FRAME_BUFFERS - 1); i > 0; i--) { + if ((hw->last_pts == hw->frame_mode_pts_save[i]) || + (hw->last_pts_us64 == hw->frame_mode_pts64_save[i])) { + pic_config->pts = hw->frame_mode_pts_save[i - 1]; + pic_config->pts64 = hw->frame_mode_pts64_save[i - 1]; + break; + } + } + if ((i == 0) || (pic_config->pts <= hw->last_pts)) { + av1_print(hw, AV1_DEBUG_OUT_PTS, + "no found pts %d, set 0. %d, %d\n", + i, pic_config->pts, hw->last_pts); + pic_config->pts = 0; + pic_config->pts64 = 0; + } + } + } + if (hw->is_used_v4l) { + vf->v4l_mem_handle + = hw->m_BUF[pic_config->BUF_index].v4l_ref_buf_addr; + av1_print(hw, PRINT_FLAG_V4L_DETAIL, + "[%d] %s(), v4l mem handle: 0x%lx\n", + ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id, + __func__, vf->v4l_mem_handle); + } + +#ifdef MULTI_INSTANCE_SUPPORT + if (vdec_frame_based(hw_to_vdec(hw))) { + vf->pts = pic_config->pts; + vf->pts_us64 = pic_config->pts64; + if (vf->pts != 0 || vf->pts_us64 != 0) { + pts_valid = 1; + pts_us64_valid = 1; + } else { + pts_valid = 0; + pts_us64_valid = 0; + } + } else +#endif + /* if (pts_lookup_offset(PTS_TYPE_VIDEO, + * stream_offset, &vf->pts, 0) != 0) { + */ + if (pts_lookup_offset_us64 + (PTS_TYPE_VIDEO, stream_offset, &vf->pts, + &frame_size, 0, + &vf->pts_us64) != 0) { +#ifdef DEBUG_PTS + hw->pts_missed++; +#endif + vf->pts = 0; + vf->pts_us64 = 0; + pts_valid = 0; + pts_us64_valid = 0; + } else { +#ifdef DEBUG_PTS + hw->pts_hit++; +#endif + pts_valid = 1; + pts_us64_valid = 1; + } + /* + if (vdec_frame_based(hw_to_vdec(hw)) && (!hw->get_frame_dur) && hw->last_lookup_pts_us64 && hw->last_pts + && ((vf->pts_us64 > hw->last_lookup_pts_us64) ||(vf->pts > hw->last_pts) )) { + if (vf->pts > hw->last_pts) + hw->frame_dur = PTS2DUR(vf->pts -hw->last_pts); + av1_print(hw, 0, + "AV1 frame mode dur=%d,pts(%d,%lld) last pts(%d,%lld)\n", + hw->frame_dur, vf->pts, + vf->pts_us64, hw->last_pts, hw->last_lookup_pts_us64); + hw->get_frame_dur = true; + hw->pts_mode = PTS_NONE_REF_USE_DURATION; + hw->duration_from_pts_done = 1; + } + */ + fill_frame_info(hw, pic_config, frame_size, vf->pts); + + pts_save = vf->pts; + pts_us64_save = vf->pts_us64; + if (hw->pts_unstable) { + frame_duration_adapt(hw, vf, pts_valid); + if (hw->duration_from_pts_done) { + hw->pts_mode = PTS_NONE_REF_USE_DURATION; + } else { + if (pts_valid || pts_us64_valid) + hw->pts_mode = PTS_NORMAL; + } + } + + if ((hw->pts_mode == PTS_NORMAL) && (vf->pts != 0) + && hw->get_frame_dur) { + int pts_diff = (int)vf->pts - hw->last_lookup_pts; + + if (pts_diff < 0) { + hw->pts_mode_switching_count++; + hw->pts_mode_recovery_count = 0; + + if (hw->pts_mode_switching_count >= + PTS_MODE_SWITCHING_THRESHOLD) { + hw->pts_mode = + PTS_NONE_REF_USE_DURATION; + pr_info + ("HEVC: switch to n_d mode.\n"); + } + + } else { + int p = PTS_MODE_SWITCHING_RECOVERY_THREASHOLD; + + hw->pts_mode_recovery_count++; + if (hw->pts_mode_recovery_count > p) { + hw->pts_mode_switching_count = 0; + hw->pts_mode_recovery_count = 0; + } + } + } + + if (vf->pts != 0) + hw->last_lookup_pts = vf->pts; + + if ((hw->pts_mode == PTS_NONE_REF_USE_DURATION) + && (slice_type != KEY_FRAME)) + vf->pts = hw->last_pts + DUR2PTS(hw->frame_dur); + hw->last_pts = vf->pts; + + if (vf->pts_us64 != 0) + hw->last_lookup_pts_us64 = vf->pts_us64; + + if ((hw->pts_mode == PTS_NONE_REF_USE_DURATION) + && (slice_type != KEY_FRAME)) { + vf->pts_us64 = + hw->last_pts_us64 + + (DUR2PTS(hw->frame_dur) * 100 / 9); + } + hw->last_pts_us64 = vf->pts_us64; + + av1_print(hw, AV1_DEBUG_OUT_PTS, + "AV1 dec out slice_type %d pts: pts_mode=%d,dur=%d,pts(%d, %lld)(%d, %lld)\n", + slice_type, hw->pts_mode, hw->frame_dur, vf->pts, + vf->pts_us64, pts_save, pts_us64_save); + + + if (hw->pts_mode == PTS_NONE_REF_USE_DURATION) { + vf->disp_pts = vf->pts; + vf->disp_pts_us64 = vf->pts_us64; + vf->pts = pts_save; + vf->pts_us64 = pts_us64_save; + } else { + vf->disp_pts = 0; + vf->disp_pts_us64 = 0; + } + + vf->index = 0xff00 | pic_config->index; + + if (pic_config->double_write_mode & 0x10) { + /* double write only */ + vf->compBodyAddr = 0; + vf->compHeadAddr = 0; +#ifdef AOM_AV1_MMU_DW + vf->dwBodyAddr = 0; + vf->dwHeadAddr = 0; +#endif + } else { + if (hw->mmu_enable) { + vf->compBodyAddr = 0; + vf->compHeadAddr = pic_config->header_adr; + vf->fgs_table_adr = pic_config->fgs_table_adr; + vf->fgs_valid = hw->fgs_valid; +#ifdef AOM_AV1_MMU_DW + vf->dwBodyAddr = 0; + vf->dwHeadAddr = 0; + if (pic_config->double_write_mode & 0x20) { + u32 mode = pic_config->double_write_mode & 0xf; + if (mode == 5 || mode == 3) + vf->dwHeadAddr = pic_config->header_dw_adr; + else if ((mode == 1 || mode == 2 || mode == 4) + && (debug & AOM_DEBUG_DW_DISP_MAIN) == 0) { + vf->compHeadAddr = pic_config->header_dw_adr; + vf->fgs_valid = 0; + av1_print(hw, AOM_DEBUG_VFRAME, + "Use dw mmu for display\n"); + } + } +#endif + } else { + /*vf->compBodyAddr = pic_config->mc_y_adr; + *vf->compHeadAddr = pic_config->mc_y_adr + + *pic_config->comp_body_size; */ + /*head adr*/ + } + vf->canvas0Addr = vf->canvas1Addr = 0; + } + if (pic_config->double_write_mode && + (pic_config->double_write_mode & 0x20) == 0) { + vf->type = VIDTYPE_PROGRESSIVE | + VIDTYPE_VIU_FIELD; + vf->type |= VIDTYPE_VIU_NV21; + if ((pic_config->double_write_mode == 3 || + pic_config->double_write_mode == 5) && + (!IS_8K_SIZE(pic_config->y_crop_width, + pic_config->y_crop_height))) { + vf->type |= VIDTYPE_COMPRESS; + if (hw->mmu_enable) + vf->type |= VIDTYPE_SCATTER; + } +#ifdef MULTI_INSTANCE_SUPPORT + if (hw->m_ins_flag) { + vf->canvas0Addr = vf->canvas1Addr = -1; + vf->plane_num = 2; + vf->canvas0_config[0] = + pic_config->canvas_config[0]; + vf->canvas0_config[1] = + pic_config->canvas_config[1]; + vf->canvas1_config[0] = + pic_config->canvas_config[0]; + vf->canvas1_config[1] = + pic_config->canvas_config[1]; + + } else +#endif + vf->canvas0Addr = vf->canvas1Addr = + spec2canvas(pic_config); + } else { + vf->canvas0Addr = vf->canvas1Addr = 0; + vf->type = VIDTYPE_COMPRESS | VIDTYPE_VIU_FIELD; + if (hw->mmu_enable) + vf->type |= VIDTYPE_SCATTER; + } + + switch (pic_config->bit_depth) { + case AOM_BITS_8: + vf->bitdepth = BITDEPTH_Y8 | + BITDEPTH_U8 | BITDEPTH_V8; + break; + case AOM_BITS_10: + case AOM_BITS_12: + vf->bitdepth = BITDEPTH_Y10 | + BITDEPTH_U10 | BITDEPTH_V10; + break; + default: + vf->bitdepth = BITDEPTH_Y10 | + BITDEPTH_U10 | BITDEPTH_V10; + break; + } + if ((vf->type & VIDTYPE_COMPRESS) == 0) + vf->bitdepth = + BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8; + if (pic_config->bit_depth == AOM_BITS_8) + vf->bitdepth |= BITDEPTH_SAVING_MODE; + + /* if ((vf->width!=pic_config->width)| + * (vf->height!=pic_config->height)) + */ + /* pr_info("aaa: %d/%d, %d/%d\n", + vf->width,vf->height, pic_config->width, + pic_config->height); */ + vf->width = pic_config->y_crop_width / + get_double_write_ratio(hw, + pic_config->double_write_mode); + vf->height = pic_config->y_crop_height / + get_double_write_ratio(hw, + pic_config->double_write_mode); + if (force_w_h != 0) { + vf->width = (force_w_h >> 16) & 0xffff; + vf->height = force_w_h & 0xffff; + } + if ((pic_config->double_write_mode & 0x20) && + ((pic_config->double_write_mode & 0xf) == 2 || + (pic_config->double_write_mode & 0xf) == 4)) { + vf->compWidth = pic_config->y_crop_width / + get_double_write_ratio(hw, + pic_config->double_write_mode); + vf->compHeight = pic_config->y_crop_height / + get_double_write_ratio(hw, + pic_config->double_write_mode); + } else { + vf->compWidth = pic_config->y_crop_width; + vf->compHeight = pic_config->y_crop_height; + } + set_frame_info(hw, vf); + if (force_fps & 0x100) { + u32 rate = force_fps & 0xff; + + if (rate) + vf->duration = 96000/rate; + else + vf->duration = 0; + } + update_vf_memhandle(hw, vf, pic_config); + if (!(pic_config->y_crop_width == 196 + && pic_config->y_crop_height == 196 + && (debug & AV1_DEBUG_NO_TRIGGER_FRAME) == 0 + && (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TXLX))) { + av1_inc_vf_ref(hw, pic_config->index); + decoder_do_frame_check(hw_to_vdec(hw), vf); + kfifo_put(&hw->display_q, (const struct vframe_s *)vf); + ATRACE_COUNTER(MODULE_NAME, vf->pts); + hw->vf_pre_count++; +#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC + /*count info*/ + gvs->frame_dur = hw->frame_dur; + vdec_count_info(gvs, 0, stream_offset); +#endif + hw_to_vdec(hw)->vdec_fps_detec(hw_to_vdec(hw)->id); + if (without_display_mode == 0) { + vf_notify_receiver(hw->provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + } else + vav1_vf_put(vav1_vf_get(hw), hw); + } else { + hw->stat |= AV1_TRIGGER_FRAME_DONE; + hevc_source_changed(VFORMAT_AV1, 196, 196, 30); + pr_debug("[%s %d] drop trigger frame width %d height %d state 0x%x\n", + __func__, __LINE__, vf->width, + vf->height, hw->stat); + } + } + + return 0; +} + +void av1_raw_write_image(AV1Decoder *pbi, PIC_BUFFER_CONFIG *sd) +{ + sd->stream_offset = pbi->pre_stream_offset; + prepare_display_buf((struct AV1HW_s *)(pbi->private_data), sd); + pbi->pre_stream_offset = READ_VREG(HEVC_SHIFT_BYTE_COUNT); +} + +static int notify_v4l_eos(struct vdec_s *vdec) +{ + struct AV1HW_s *hw = (struct AV1HW_s *)vdec->private; + struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); + struct vframe_s *vf = NULL; + struct vdec_fb *fb = NULL; + + if (hw->is_used_v4l && hw->eos) { + if (kfifo_get(&hw->newframe_q, &vf) == 0 || vf == NULL) { + av1_print(hw, 0, + "%s fatal error, no available buffer slot.\n", + __func__); + return -1; + } + + if (v4l_get_fb(hw->v4l2_ctx, &fb)) { + pr_err("[%d] get fb fail.\n", ctx->id); + return -1; + } + + vf->timestamp = ULONG_MAX; + vf->v4l_mem_handle = (unsigned long)fb; + vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L; + + kfifo_put(&hw->display_q, (const struct vframe_s *)vf); + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + + av1_print(hw, AOM_DEBUG_HW_MORE, "[%d] AV1 EOS notify.\n", ctx->id); + } + + return 0; +} + +static void get_rpm_param(union param_u *params) +{ + int i; + unsigned int data32; + + if (debug & AV1_DEBUG_BUFMGR) + pr_info("enter %s\r\n", __func__); + for (i = 0; i < 128; i++) { + do { + data32 = READ_VREG(RPM_CMD_REG); + /*pr_info("%x\n", data32);*/ + } while ((data32 & 0x10000) == 0); + params->l.data[i] = data32&0xffff; + /*pr_info("%x\n", data32);*/ + WRITE_VREG(RPM_CMD_REG, 0); + } + if (debug & AV1_DEBUG_BUFMGR) + pr_info("leave %s\r\n", __func__); +} + +static void av1_recycle_mmu_buf_tail(struct AV1HW_s *hw) +{ +#ifdef CHANGE_REMOVED + struct AV1_Common_s *const cm = &hw->pbi->common; + if (hw->double_write_mode & 0x10) + return; + if (cm->cur_fb_idx_mmu != INVALID_IDX) { + if (hw->used_4k_num == -1) { + hw->used_4k_num = + (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16); + if (hw->m_ins_flag) + hevc_mmu_dma_check(hw_to_vdec(hw)); + } + decoder_mmu_box_free_idx_tail(hw->mmu_box, + cm->cur_fb_idx_mmu, hw->used_4k_num); + cm->cur_fb_idx_mmu = INVALID_IDX; + hw->used_4k_num = -1; + } +#endif +} + +#ifdef MULTI_INSTANCE_SUPPORT +static void av1_recycle_mmu_buf(struct AV1HW_s *hw) +{ +#ifdef CHANGE_REMOVED + struct AV1_Common_s *const cm = &hw->pbi->common; + if (hw->double_write_mode & 0x10) + return; + if (cm->cur_fb_idx_mmu != INVALID_IDX) { + decoder_mmu_box_free_idx(hw->mmu_box, + cm->cur_fb_idx_mmu); + + cm->cur_fb_idx_mmu = INVALID_IDX; + hw->used_4k_num = -1; + } +#endif +} +#endif + + +static void dec_again_process(struct AV1HW_s *hw) +{ + amhevc_stop(); + hw->dec_result = DEC_RESULT_AGAIN; + if (hw->process_state == + PROC_STATE_DECODESLICE) { + hw->process_state = + PROC_STATE_SENDAGAIN; + if (hw->mmu_enable) + av1_recycle_mmu_buf(hw); + } + reset_process_time(hw); + vdec_schedule_work(&hw->work); +} + +static void read_film_grain_reg(struct AV1HW_s *hw) +{ + AV1_COMMON *cm = &hw->pbi->common; + int i; + if (cm->cur_frame == NULL) { + av1_print(hw, AOM_DEBUG_HW_MORE, "%s, cur_frame not exist!!!\n", __func__); + return; + } else + av1_print(hw, AOM_DEBUG_HW_MORE, "%s\n", __func__); + WRITE_VREG(HEVC_FGS_IDX, 0); + for (i = 0; i < FILM_GRAIN_REG_SIZE; i++) { + cm->cur_frame->film_grain_reg[i] = READ_VREG(HEVC_FGS_DATA); + } + cm->cur_frame->film_grain_reg_valid = 1; +} + +static void config_film_grain_reg(struct AV1HW_s *hw, int film_grain_params_ref_idx) +{ + + AV1_COMMON *cm = &hw->pbi->common; + int i; + unsigned char found = 0; + RefCntBuffer *buf; + av1_print(hw, AOM_DEBUG_HW_MORE, + " ## %s frome reference idx %d\n", + __func__, film_grain_params_ref_idx); + for (i = 0; i < INTER_REFS_PER_FRAME; ++i) { + if (film_grain_params_ref_idx == cm->remapped_ref_idx[i]) { + found = 1; + break; + } + } + if (!found) { + av1_print(hw, AOM_DEBUG_HW_MORE, + "%s Error, Invalid film grain reference idx %d\n", + __func__, film_grain_params_ref_idx); + return; + } + buf = cm->ref_frame_map[film_grain_params_ref_idx]; + + if (buf->film_grain_reg_valid == 0) { + av1_print(hw, AOM_DEBUG_HW_MORE, + "%s Error, film grain register data invalid for reference idx %d\n", + __func__, film_grain_params_ref_idx); + return; + } + + if (cm->cur_frame == NULL) { + av1_print(hw, AOM_DEBUG_HW_MORE, + "%s, cur_frame not exist!!!\n", __func__); + } + WRITE_VREG(HEVC_FGS_IDX, 0); + for (i = 0; i < FILM_GRAIN_REG_SIZE; i++) { + WRITE_VREG(HEVC_FGS_DATA, buf->film_grain_reg[i]); + if (cm->cur_frame) + cm->cur_frame->film_grain_reg[i] = buf->film_grain_reg[i]; + } + if (cm->cur_frame) + cm->cur_frame->film_grain_reg_valid = 1; + WRITE_VREG(HEVC_FGS_CTRL, READ_VREG(HEVC_FGS_CTRL) | 1); // set fil_grain_start +} + + +void config_next_ref_info_hw(struct AV1HW_s *hw) +{ + int j; + AV1_COMMON *const cm = &hw->pbi->common; + av1_set_next_ref_frame_map(hw->pbi); + WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x1000); + for (j = 0; j < 12; j++) { + unsigned int info = + av1_get_next_used_ref_info(cm, j); + WRITE_VREG(HEVC_PARSER_MEM_RW_DATA, info); + av1_print(hw, AOM_DEBUG_HW_MORE, + "config next ref info %d 0x%x\n", j, info); + } +} + + + +#ifdef PRINT_HEVC_DATA_PATH_MONITOR +void datapath_monitor(struct AV1HW_s *hw) +{ + uint32_t total_clk_count; + uint32_t path_transfer_count; + uint32_t path_wait_count; + float path_wait_ratio; + if (pbi->decode_idx > 1) { + WRITE_VREG(HEVC_PATH_MONITOR_CTRL, 0); // Disabble monitor and set rd_idx to 0 + total_clk_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + + WRITE_VREG(HEVC_PATH_MONITOR_CTRL, (1<<4)); // Disabble monitor and set rd_idx to 0 + +// parser --> iqit + path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + if (path_transfer_count == 0) path_wait_ratio = 0.0; + else path_wait_ratio = (float)path_wait_count/(float)path_transfer_count; + printk("[P%d HEVC PATH] Parser/IQIT/IPP/DBLK/OW/DDR/CMD WAITING \% : %.2f", + pbi->decode_idx - 2, path_wait_ratio); + +// iqit --> ipp + path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + if (path_transfer_count == 0) path_wait_ratio = 0.0; + else path_wait_ratio = (float)path_wait_count/(float)path_transfer_count; + printk(" %.2f", path_wait_ratio); + +// dblk <-- ipp + path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + if (path_transfer_count == 0) path_wait_ratio = 0.0; + else path_wait_ratio = (float)path_wait_count/(float)path_transfer_count; + printk(" %.2f", path_wait_ratio); + +// dblk --> ow + path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + if (path_transfer_count == 0) path_wait_ratio = 0.0; + else path_wait_ratio = (float)path_wait_count/(float)path_transfer_count; + printk(" %.2f", path_wait_ratio); + +// <--> DDR + path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + if (path_transfer_count == 0) path_wait_ratio = 0.0; + else path_wait_ratio = (float)path_wait_count/(float)path_transfer_count; + printk(" %.2f", path_wait_ratio); + +// CMD + path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA); + if (path_transfer_count == 0) path_wait_ratio = 0.0; + else path_wait_ratio = (float)path_wait_count/(float)path_transfer_count; + printk(" %.2f\n", path_wait_ratio); + } +} + +#endif + +#ifdef MCRCC_ENABLE + +static int mcrcc_hit_rate; +static int mcrcc_bypass_rate; + +#define C_Reg_Wr WRITE_VREG +static void C_Reg_Rd(unsigned int adr, unsigned int *val) +{ + *val = READ_VREG(adr); +} + +static void mcrcc_perfcount_reset(struct AV1HW_s *hw) +{ + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, + "[cache_util.c] Entered mcrcc_perfcount_reset...\n"); + C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)0x1); + C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)0x0); + return; +} + +static unsigned raw_mcr_cnt_total_prev; +static unsigned hit_mcr_0_cnt_total_prev; +static unsigned hit_mcr_1_cnt_total_prev; +static unsigned byp_mcr_cnt_nchcanv_total_prev; +static unsigned byp_mcr_cnt_nchoutwin_total_prev; + +static void mcrcc_get_hitrate(struct AV1HW_s *hw, unsigned reset_pre) +{ + unsigned delta_hit_mcr_0_cnt; + unsigned delta_hit_mcr_1_cnt; + unsigned delta_raw_mcr_cnt; + unsigned delta_mcr_cnt_nchcanv; + unsigned delta_mcr_cnt_nchoutwin; + + unsigned tmp; + unsigned raw_mcr_cnt; + unsigned hit_mcr_cnt; + unsigned byp_mcr_cnt_nchoutwin; + unsigned byp_mcr_cnt_nchcanv; + int hitrate; + + if (reset_pre) { + raw_mcr_cnt_total_prev = 0; + hit_mcr_0_cnt_total_prev = 0; + hit_mcr_1_cnt_total_prev = 0; + byp_mcr_cnt_nchcanv_total_prev = 0; + byp_mcr_cnt_nchoutwin_total_prev = 0; + } + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "[cache_util.c] Entered mcrcc_get_hitrate...\n"); + C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x0<<1)); + C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &raw_mcr_cnt); + C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x1<<1)); + C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &hit_mcr_cnt); + C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x2<<1)); + C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &byp_mcr_cnt_nchoutwin); + C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x3<<1)); + C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &byp_mcr_cnt_nchcanv); + + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "raw_mcr_cnt_total: %d\n",raw_mcr_cnt); + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "hit_mcr_cnt_total: %d\n",hit_mcr_cnt); + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "byp_mcr_cnt_nchoutwin_total: %d\n",byp_mcr_cnt_nchoutwin); + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "byp_mcr_cnt_nchcanv_total: %d\n",byp_mcr_cnt_nchcanv); + + delta_raw_mcr_cnt = raw_mcr_cnt - raw_mcr_cnt_total_prev; + delta_mcr_cnt_nchcanv = byp_mcr_cnt_nchcanv - byp_mcr_cnt_nchcanv_total_prev; + delta_mcr_cnt_nchoutwin = byp_mcr_cnt_nchoutwin - byp_mcr_cnt_nchoutwin_total_prev; + raw_mcr_cnt_total_prev = raw_mcr_cnt; + byp_mcr_cnt_nchcanv_total_prev = byp_mcr_cnt_nchcanv; + byp_mcr_cnt_nchoutwin_total_prev = byp_mcr_cnt_nchoutwin; + + C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x4<<1)); + C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &tmp); + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "miss_mcr_0_cnt_total: %d\n",tmp); + C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x5<<1)); + C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &tmp); + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "miss_mcr_1_cnt_total: %d\n",tmp); + C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x6<<1)); + C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &tmp); + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "hit_mcr_0_cnt_total: %d\n",tmp); + delta_hit_mcr_0_cnt = tmp - hit_mcr_0_cnt_total_prev; + hit_mcr_0_cnt_total_prev = tmp; + C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x7<<1)); + C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &tmp); + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "hit_mcr_1_cnt_total: %d\n",tmp); + delta_hit_mcr_1_cnt = tmp - hit_mcr_1_cnt_total_prev; + hit_mcr_1_cnt_total_prev = tmp; + + if ( delta_raw_mcr_cnt != 0 ) { + hitrate = 100 * delta_hit_mcr_0_cnt/ delta_raw_mcr_cnt; + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "CANV0_HIT_RATE : %d\n", hitrate); + hitrate = 100 * delta_hit_mcr_1_cnt/delta_raw_mcr_cnt; + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "CANV1_HIT_RATE : %d\n", hitrate); + hitrate = 100 * delta_mcr_cnt_nchcanv/delta_raw_mcr_cnt; + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "NONCACH_CANV_BYP_RATE : %d\n", hitrate); + hitrate = 100 * delta_mcr_cnt_nchoutwin/delta_raw_mcr_cnt; + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "CACHE_OUTWIN_BYP_RATE : %d\n", hitrate); + } + + if (raw_mcr_cnt != 0) + { + hitrate = 100*hit_mcr_cnt/raw_mcr_cnt; + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_HIT_RATE : %d\n", hitrate); + hitrate = 100*(byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv)/raw_mcr_cnt; + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_BYP_RATE : %d\n", hitrate); + } else { + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_HIT_RATE : na\n"); + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_BYP_RATE : na\n"); + } + mcrcc_hit_rate = 100*hit_mcr_cnt/raw_mcr_cnt; + mcrcc_bypass_rate = 100*(byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv)/raw_mcr_cnt; + + return; +} + +static void decomp_perfcount_reset(struct AV1HW_s *hw) +{ + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "[cache_util.c] Entered decomp_perfcount_reset...\n"); + C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)0x1); + C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)0x0); + return; +} + +static void decomp_get_hitrate(struct AV1HW_s *hw) +{ + unsigned raw_mcr_cnt; + unsigned hit_mcr_cnt; + int hitrate; + + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "[cache_util.c] Entered decomp_get_hitrate...\n"); + C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x0<<1)); + C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &raw_mcr_cnt); + C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x1<<1)); + C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &hit_mcr_cnt); + + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "hcache_raw_cnt_total: %d\n",raw_mcr_cnt); + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "hcache_hit_cnt_total: %d\n",hit_mcr_cnt); + + if ( raw_mcr_cnt != 0 ) { + hitrate = 100*hit_mcr_cnt/raw_mcr_cnt; + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_HCACHE_HIT_RATE : %.2f\%\n", hitrate); + } else { + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_HCACHE_HIT_RATE : na\n"); + } + C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x2<<1)); + C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &raw_mcr_cnt); + C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x3<<1)); + C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &hit_mcr_cnt); + + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "dcache_raw_cnt_total: %d\n",raw_mcr_cnt); + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "dcache_hit_cnt_total: %d\n",hit_mcr_cnt); + + if ( raw_mcr_cnt != 0 ) { + hitrate = 100*hit_mcr_cnt/raw_mcr_cnt; + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_DCACHE_HIT_RATE : %d\n", hitrate); + + //hitrate = ((float)hit_mcr_cnt/(float)raw_mcr_cnt); + //hitrate = (mcrcc_hit_rate + (mcrcc_bypass_rate * hitrate))*100; + hitrate = mcrcc_hit_rate + (mcrcc_bypass_rate * hit_mcr_cnt/raw_mcr_cnt); + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_DECOMP_DCACHE_EFFECTIVE_HIT_RATE : %d\n", hitrate); + + } else { + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_DCACHE_HIT_RATE : na\n"); + } + + return; +} + +static void decomp_get_comprate(struct AV1HW_s *hw) +{ + unsigned raw_ucomp_cnt; + unsigned fast_comp_cnt; + unsigned slow_comp_cnt; + int comprate; + + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "[cache_util.c] Entered decomp_get_comprate...\n"); + C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x4<<1)); + C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &fast_comp_cnt); + C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x5<<1)); + C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &slow_comp_cnt); + C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x6<<1)); + C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &raw_ucomp_cnt); + + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "decomp_fast_comp_total: %d\n",fast_comp_cnt); + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "decomp_slow_comp_total: %d\n",slow_comp_cnt); + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "decomp_raw_uncomp_total: %d\n",raw_ucomp_cnt); + + if ( raw_ucomp_cnt != 0 ) + { + comprate = 100*(fast_comp_cnt + slow_comp_cnt)/raw_ucomp_cnt; + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_COMP_RATIO : %d\n", comprate); + } else + { + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_COMP_RATIO : na\n"); + } + return; +} + +static void dump_hit_rate(struct AV1HW_s *hw) +{ + if (debug & AV1_DEBUG_CACHE_HIT_RATE) { + mcrcc_get_hitrate(hw, hw->m_ins_flag); + decomp_get_hitrate(hw); + decomp_get_comprate(hw); + } +} + +static uint32_t mcrcc_get_abs_frame_distance(struct AV1HW_s *hw, uint32_t refid, uint32_t ref_ohint, uint32_t curr_ohint, uint32_t ohint_bits_min1) +{ + int32_t diff_ohint0; + int32_t diff_ohint1; + uint32_t abs_dist; + uint32_t m; + uint32_t m_min1; + + diff_ohint0 = ref_ohint - curr_ohint; + + m = (1 << ohint_bits_min1); + m_min1 = m -1; + + diff_ohint1 = (diff_ohint0 & m_min1 ) - (diff_ohint0 & m); + + abs_dist = (diff_ohint1 < 0) ? -diff_ohint1 : diff_ohint1; + + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, + "[cache_util.c] refid:%0x ref_orderhint:%0x curr_orderhint:%0x orderhint_bits_min1:%0x abd_dist:%0x\n", + refid, ref_ohint, curr_ohint, ohint_bits_min1,abs_dist); + + return abs_dist; +} + +static void config_mcrcc_axi_hw_nearest_ref(struct AV1HW_s *hw) +{ + uint32_t i; + uint32_t rdata32; + uint32_t dist_array[8]; + uint32_t refcanvas_array[2]; + uint32_t orderhint_bits; + unsigned char is_inter; + AV1_COMMON *cm = &hw->pbi->common; + PIC_BUFFER_CONFIG *curr_pic_config; + int32_t curr_orderhint; + int cindex0 = LAST_FRAME; + uint32_t last_ref_orderhint_dist = 1023; // large distance + uint32_t curr_ref_orderhint_dist = 1023; // large distance + int cindex1; + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, + "[test.c] #### config_mcrcc_axi_hw ####\n"); + + WRITE_VREG(HEVCD_MCRCC_CTL1, 0x2); // reset mcrcc + + is_inter = av1_frame_is_inter(&hw->pbi->common); //((pbi->common.frame_type != KEY_FRAME) && (!pbi->common.intra_only)) ? 1 : 0; + if ( !is_inter ) { // I-PIC + //WRITE_VREG(HEVCD_MCRCC_CTL1, 0x1); // remove reset -- disables clock + WRITE_VREG(HEVCD_MCRCC_CTL2, 0xffffffff); // Replace with current-frame canvas + WRITE_VREG(HEVCD_MCRCC_CTL3, 0xffffffff); // + WRITE_VREG(HEVCD_MCRCC_CTL1, 0xff0); // enable mcrcc progressive-mode + return; + } + +#if 0 + //printk("before call mcrcc_get_hitrate\r\n"); + mcrcc_get_hitrate(hw); + decomp_get_hitrate(hw); + decomp_get_comprate(hw); +#endif + + // Find absolute orderhint delta + curr_pic_config = &cm->cur_frame->buf; + curr_orderhint = curr_pic_config->order_hint; + orderhint_bits = cm->seq_params.order_hint_info.order_hint_bits_minus_1; + for (i = LAST_FRAME; i <= ALTREF_FRAME; i++) { + int32_t ref_orderhint = 0; + PIC_BUFFER_CONFIG *pic_config; + //int32_t tmp; + pic_config = av1_get_ref_frame_spec_buf(cm,i); + if (pic_config) + ref_orderhint = pic_config->order_hint; + //tmp = curr_orderhint - ref_orderhint; + //dist_array[i] = (tmp < 0) ? -tmp : tmp; + dist_array[i] = mcrcc_get_abs_frame_distance(hw, i,ref_orderhint, curr_orderhint, orderhint_bits); + } + // Get smallest orderhint distance refid + for (i = LAST_FRAME; i <= ALTREF_FRAME; i++) { + PIC_BUFFER_CONFIG *pic_config; + pic_config = av1_get_ref_frame_spec_buf(cm, i); + curr_ref_orderhint_dist = dist_array[i]; + if ( curr_ref_orderhint_dist < last_ref_orderhint_dist) { + cindex0 = i; + last_ref_orderhint_dist = curr_ref_orderhint_dist; + } + } + WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (cindex0 << 8) | (1<<1) | 0); + refcanvas_array[0] = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR) & 0xffff; + + last_ref_orderhint_dist = 1023; // large distance + curr_ref_orderhint_dist = 1023; // large distance + // Get 2nd smallest orderhint distance refid + cindex1 = LAST_FRAME; + for (i = LAST_FRAME; i <= ALTREF_FRAME; i++) { + PIC_BUFFER_CONFIG *pic_config; + pic_config = av1_get_ref_frame_spec_buf(cm, i); + curr_ref_orderhint_dist = dist_array[i]; + WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (i << 8) | (1<<1) | 0); + refcanvas_array[1] = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR) & 0xffff; + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "[cache_util.c] curr_ref_orderhint_dist:%x last_ref_orderhint_dist:%x refcanvas_array[0]:%x refcanvas_array[1]:%x\n", + curr_ref_orderhint_dist, last_ref_orderhint_dist, refcanvas_array[0],refcanvas_array[1]); + if ((curr_ref_orderhint_dist < last_ref_orderhint_dist) && (refcanvas_array[0] != refcanvas_array[1])) { + cindex1 = i; + last_ref_orderhint_dist = curr_ref_orderhint_dist; + } + } + + WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (cindex0 << 8) | (1<<1) | 0); + refcanvas_array[0] = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR); + WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (cindex1 << 8) | (1<<1) | 0); + refcanvas_array[1] = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR); + + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "[cache_util.c] refcanvas_array[0](index %d):%x refcanvas_array[1](index %d):%x\n", + cindex0, refcanvas_array[0], cindex1, refcanvas_array[1]); + + // lowest delta_picnum + rdata32 = refcanvas_array[0]; + rdata32 = rdata32 & 0xffff; + rdata32 = rdata32 | ( rdata32 << 16); + WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32); + + // 2nd-lowest delta_picnum + rdata32 = refcanvas_array[1]; + rdata32 = rdata32 & 0xffff; + rdata32 = rdata32 | ( rdata32 << 16); + WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32); + + WRITE_VREG(HEVCD_MCRCC_CTL1, 0xff0); // enable mcrcc progressive-mode + return; +} + + +#endif + +int av1_continue_decoding(struct AV1HW_s *hw, int obu_type) +{ + int ret; +#if 1 + //def CHANGE_DONE + AV1Decoder *pbi = hw->pbi; + AV1_COMMON *const cm = &pbi->common; + int i; + + av1_print(hw, AOM_DEBUG_HW_MORE, + "%s: pbi %p cm %p cur_frame %p %d\n", + __func__, pbi, cm, cm->cur_frame, + pbi->bufmgr_proc_count); + + //pre_decode_idx = pbi->decode_idx; + if (pbi->bufmgr_proc_count == 0 || + hw->one_compressed_data_done) { + hw->new_compressed_data = 1; + hw->one_compressed_data_done = 0; + } else { + hw->new_compressed_data = 0; + } + ret = av1_bufmgr_process(pbi, &hw->aom_param, + hw->new_compressed_data, obu_type); + av1_print(hw, AOM_DEBUG_HW_MORE, + "%s: pbi %p cm %p cur_frame %p\n", + __func__, pbi, cm, cm->cur_frame); + + av1_print(hw, AOM_DEBUG_HW_MORE, + "1+++++++++++++++++++++++++++++++++++%d %p\n", + ret, cm->cur_frame); + if (hw->new_compressed_data) + WRITE_VREG(PIC_END_LCU_COUNT, 0); + + if (ret > 0) { + /* the case when cm->show_existing_frame is 1 */ + /*case 3016*/ + av1_print(hw, AOM_DEBUG_HW_MORE, + "Decoding done (index=%d, show_existing_frame = %d)\n", + cm->cur_frame? cm->cur_frame->buf.index:-1, + cm->show_existing_frame + ); + + if (cm->cur_frame) { + PIC_BUFFER_CONFIG* cur_pic_config = &cm->cur_frame->buf; + if (debug & + AV1_DEBUG_BUFMGR_MORE) + dump_aux_buf(hw); + set_pic_aux_data(hw, + cur_pic_config, 0, 0); + } + config_next_ref_info_hw(hw); + + av1_print(hw, AOM_DEBUG_HW_MORE, + "aom_bufmgr_process=> %d,decode done, AOM_AV1_SEARCH_HEAD\r\n", ret); + WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD); + pbi->decode_idx++; + pbi->bufmgr_proc_count++; + hw->frame_decoded = 1; + return 0; + } + else if (ret < 0) { + hw->frame_decoded = 1; + av1_print(hw, AOM_DEBUG_HW_MORE, + "aom_bufmgr_process=> %d, bufmgr e.r.r.o.r., AOM_AV1_SEARCH_HEAD\r\n", ret); + WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD); + return 0; + } + else if (ret == 0) { + PIC_BUFFER_CONFIG* cur_pic_config = &cm->cur_frame->buf; + PIC_BUFFER_CONFIG* prev_pic_config = &cm->prev_frame->buf; + //struct segmentation_lf *seg_4lf = &hw->seg_4lf_store; + if (debug & + AV1_DEBUG_BUFMGR_MORE) + dump_aux_buf(hw); + set_dv_data(hw); + if (cm->show_frame && + hw->dv_data_buf != NULL) + copy_dv_data(hw, cur_pic_config); + /* to do:.. + set_pic_aux_data(hw, + cur_pic_config, 0, 2);*/ + hw->frame_decoded = 0; + pbi->bufmgr_proc_count++; + if (hw->new_compressed_data == 0) { + WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_DECODE_SLICE); + return 0; + } + av1_print(hw, AOM_DEBUG_HW_MORE, + " [PICTURE %d] cm->cur_frame->mi_size : (%d X %d) y_crop_size :(%d X %d)\n", + hw->frame_count, + cm->cur_frame->mi_cols, + cm->cur_frame->mi_rows, + cur_pic_config->y_crop_width, + cur_pic_config->y_crop_height); + if (cm->prev_frame > 0) { + av1_print(hw, AOM_DEBUG_HW_MORE, + " [SEGMENT] cm->prev_frame->segmentation_enabled : %d\n", + cm->prev_frame->segmentation_enabled); + av1_print(hw, AOM_DEBUG_HW_MORE, + " [SEGMENT] cm->prev_frame->mi_size : (%d X %d)\n", + cm->prev_frame->mi_cols, cm->prev_frame->mi_rows); + } + cm->cur_frame->prev_segmentation_enabled = (cm->prev_frame > 0) ? + (cm->prev_frame->segmentation_enabled & (cm->prev_frame->segmentation_update_map + | cm->prev_frame->prev_segmentation_enabled) & + (cm->cur_frame->mi_rows == cm->prev_frame->mi_rows) & + (cm->cur_frame->mi_cols == cm->prev_frame->mi_cols)) : 0; + WRITE_VREG(AV1_SKIP_MODE_INFO, + (cm->cur_frame->prev_segmentation_enabled << 31) | + (((cm->prev_frame > 0) ? cm->prev_frame->intra_only : 0) << 30) | + (((cm->prev_frame > 0) ? prev_pic_config->index : 0x1f) << 24) | + (((cm->cur_frame > 0) ? cur_pic_config->index : 0x1f) << 16) | + (cm->current_frame.skip_mode_info.ref_frame_idx_0 & 0xf) | + ((cm->current_frame.skip_mode_info.ref_frame_idx_1 & 0xf) << 4) | + (cm->current_frame.skip_mode_info.skip_mode_allowed << 8)); + cur_pic_config->decode_idx = pbi->decode_idx; + + av1_print(hw, AOM_DEBUG_HW_MORE, + "Decode Frame Data %d frame_type %d (%d) bufmgr_proc_count %d\n", + pbi->decode_idx, + cm->cur_frame->frame_type, + cm->current_frame.frame_type, + pbi->bufmgr_proc_count); + pbi->decode_idx++; + hw->frame_count++; + cur_pic_config->slice_type = cm->cur_frame->frame_type; + if (hw->chunk) { + cur_pic_config->pts = hw->chunk->pts; + cur_pic_config->pts64 = hw->chunk->pts64; + hw->chunk->pts = 0; + hw->chunk->pts64 = 0; + //pr_info("continue_decode: pic %p, pts %d\n",cur_pic_config, hw->chunk->pts); + } +#ifdef DUAL_DECODE +#else + config_pic_size(hw, hw->aom_param.p.bit_depth); +#endif + if (get_mv_buf(hw, + &cm->cur_frame->buf.mv_buf_index, + &cm->cur_frame->buf.mpred_mv_wr_start_addr + ) < 0) { + av1_print(hw, 0, + "%s: Error get_mv_buf fail\n", + __func__); + ret = -1; + } + + if (ret >= 0 && hw->mmu_enable && ((hw->double_write_mode & 0x10) == 0)) { + ret = av1_alloc_mmu(hw, + cm->cur_frame->buf.index, + cur_pic_config->y_crop_width, + cur_pic_config->y_crop_height, + hw->aom_param.p.bit_depth, + hw->frame_mmu_map_addr); + if (ret >= 0) + cm->cur_fb_idx_mmu = cm->cur_frame->buf.index; + else + pr_err("can't alloc need mmu1,idx %d ret =%d\n", + cm->cur_frame->buf.index, ret); +#ifdef AOM_AV1_MMU_DW + if (hw->dw_mmu_enable) { + ret = av1_alloc_mmu_dw(hw, + cm->cur_frame->buf.index, + cur_pic_config->y_crop_width, + cur_pic_config->y_crop_height, + hw->aom_param.p.bit_depth, + hw->dw_frame_mmu_map_addr); + if (ret >= 0) + cm->cur_fb_idx_mmu_dw = cm->cur_frame->buf.index; + else + pr_err("can't alloc need dw mmu1,idx %d ret =%d\n", + cm->cur_frame->buf.index, ret); + } +#endif + } else { + ret = 0; + } + if (av1_frame_is_inter(&hw->pbi->common)) { + //if ((pbi->common.frame_type != KEY_FRAME) && (!pbi->common.intra_only)) { +#ifdef DUAL_DECODE +#else + config_mc_buffer(hw, hw->aom_param.p.bit_depth, 1); +#endif + config_mpred_hw(hw, 1); + } + else { + config_mc_buffer(hw, hw->aom_param.p.bit_depth, 0); + clear_mpred_hw(hw); + config_mpred_hw(hw, 0); + } +#ifdef DUAL_DECODE +#else +#ifdef MCRCC_ENABLE + config_mcrcc_axi_hw_nearest_ref(hw); +#endif + config_sao_hw(hw, &hw->aom_param); +#endif + + config_dblk_hw(hw); + + av1_print(hw, AOM_DEBUG_HW_MORE, "HEVC_DEC_STATUS_REG <= AOM_AV1_DECODE_SLICE\n"); + WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_DECODE_SLICE); + + // Save segment_feature while hardware decoding + if (hw->seg_4lf->enabled) { + for (i = 0; i < 8; i++) { + cm->cur_frame->segment_feature[i] = READ_VREG(AOM_AV1_SEGMENT_FEATURE); + } + } else { + for (i = 0; i < 8; i++) { + cm->cur_frame->segment_feature[i] = (0x80000000 | (i << 22)); + } + } + WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x1010 + (cur_pic_config->index)); + if (hw->aom_param.p.segmentation_enabled & 1) // segmentation_enabled + WRITE_VREG(HEVC_PARSER_MEM_RW_DATA, READ_VREG(AV1_REF_SEG_INFO)); + else + WRITE_VREG(HEVC_PARSER_MEM_RW_DATA, 0); + } else { + av1_print(hw, AOM_DEBUG_HW_MORE, "Sequence head, Search next start code\n"); + cm->prev_fb_idx = INVALID_IDX; + //skip, search next start code + WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_DECODE_SLICE); + } + return ret; + +#else + + bit_depth_luma = av1_param.p.bit_depth; + bit_depth_chroma = av1_param.p.bit_depth; + + if (hw->process_state != PROC_STATE_SENDAGAIN) { + ret = av1_bufmgr_process(hw, &av1_param); + if (!hw->m_ins_flag) + hw->result_done_count++; + } else { + union param_u *params = &av1_param; + if (hw->mmu_enable && ((hw->double_write_mode & 0x10) == 0)) { + ret = av1_alloc_mmu(hw, + cm->new_fb_idx, + params->p.width, + params->p.height, + params->p.bit_depth, + hw->frame_mmu_map_addr); + if (ret >= 0) + cm->cur_fb_idx_mmu = cm->new_fb_idx; + else + pr_err("can't alloc need mmu1,idx %d ret =%d\n", + cm->new_fb_idx, ret); + } else { + ret = 0; + } + WRITE_VREG(HEVC_PARSER_PICTURE_SIZE, + (params->p.height << 16) | params->p.width); + } + if (ret < 0) { + pr_info("av1_bufmgr_process=> %d, AV1_10B_DISCARD_NAL\r\n", ret); + WRITE_VREG(HEVC_DEC_STATUS_REG, AV1_10B_DISCARD_NAL); + cm->show_frame = 0; + if (hw->mmu_enable) + av1_recycle_mmu_buf(hw); + + if (hw->m_ins_flag) { + hw->dec_result = DEC_RESULT_DONE; + amhevc_stop(); + vdec_schedule_work(&hw->work); + } + return ret; + } else if (ret == 0) { + struct PIC_BUFFER_CONFIG_s *cur_pic_config + = &cm->cur_frame->buf; + cur_pic_config->decode_idx = hw->frame_count; + + if (hw->process_state != PROC_STATE_SENDAGAIN) { + if (!hw->m_ins_flag) { + hw->frame_count++; + decode_frame_count[hw->index] + = hw->frame_count; + } + if (hw->chunk) { + cur_pic_config->pts = hw->chunk->pts; + cur_pic_config->pts64 = hw->chunk->pts64; + } + } + /*pr_info("Decode Frame Data %d\n", hw->frame_count);*/ + config_pic_size(hw, av1_param.p.bit_depth); + + if ((hw->common.frame_type != KEY_FRAME) + && (!hw->common.intra_only)) { + config_mc_buffer(hw, av1_param.p.bit_depth); + config_mpred_hw(hw); + } else { + clear_mpred_hw(hw); + } +#ifdef MCRCC_ENABLE + if (mcrcc_cache_alg_flag) + config_mcrcc_axi_hw_new(hw); + else + config_mcrcc_axi_hw(hw); +#endif + config_sao_hw(hw, &av1_param); + /*pr_info("HEVC_DEC_STATUS_REG <= AV1_10B_DECODE_SLICE\n");*/ + WRITE_VREG(HEVC_DEC_STATUS_REG, AV1_10B_DECODE_SLICE); + } else { + pr_info("Skip search next start code\n"); + cm->prev_fb_idx = INVALID_IDX; + /*skip, search next start code*/ + WRITE_VREG(HEVC_DEC_STATUS_REG, AV1_10B_DECODE_SLICE); + } + hw->process_state = PROC_STATE_DECODESLICE; + if (hw->mmu_enable && ((hw->double_write_mode & 0x10) == 0)) { + if (hw->last_put_idx < hw->used_buf_num) { + struct RefCntBuffer_s *frame_bufs = + cm->buffer_pool->frame_bufs; + int i = hw->last_put_idx; + /*free not used buffers.*/ + if ((frame_bufs[i].ref_count == 0) && + (frame_bufs[i].buf.vf_ref == 0) && + (frame_bufs[i].buf.index != -1)) { + decoder_mmu_box_free_idx(hw->mmu_box, i); + } + hw->last_put_idx = -1; + } + } + return ret; +#endif +} + +static void fill_frame_info(struct AV1HW_s *hw, + struct PIC_BUFFER_CONFIG_s *frame, + unsigned int framesize, + unsigned int pts) +{ + struct vframe_qos_s *vframe_qos = &hw->vframe_qos; + + if (frame->slice_type == KEY_FRAME) + vframe_qos->type = 1; + else if (frame->slice_type == INTER_FRAME) + vframe_qos->type = 2; +/* +#define SHOW_QOS_INFO +*/ + vframe_qos->size = framesize; + vframe_qos->pts = pts; +#ifdef SHOW_QOS_INFO + av1_print(hw, 0, "slice:%d\n", frame->slice_type); +#endif + vframe_qos->max_mv = frame->max_mv; + vframe_qos->avg_mv = frame->avg_mv; + vframe_qos->min_mv = frame->min_mv; +#ifdef SHOW_QOS_INFO + av1_print(hw, 0, "mv: max:%d, avg:%d, min:%d\n", + vframe_qos->max_mv, + vframe_qos->avg_mv, + vframe_qos->min_mv); +#endif + vframe_qos->max_qp = frame->max_qp; + vframe_qos->avg_qp = frame->avg_qp; + vframe_qos->min_qp = frame->min_qp; +#ifdef SHOW_QOS_INFO + av1_print(hw, 0, "qp: max:%d, avg:%d, min:%d\n", + vframe_qos->max_qp, + vframe_qos->avg_qp, + vframe_qos->min_qp); +#endif + vframe_qos->max_skip = frame->max_skip; + vframe_qos->avg_skip = frame->avg_skip; + vframe_qos->min_skip = frame->min_skip; +#ifdef SHOW_QOS_INFO + av1_print(hw, 0, "skip: max:%d, avg:%d, min:%d\n", + vframe_qos->max_skip, + vframe_qos->avg_skip, + vframe_qos->min_skip); +#endif + vframe_qos->num++; + /* + if (hw->frameinfo_enable) + vdec_fill_frame_info(vframe_qos, 1); + */ +} + +/* only when we decoded one field or one frame, +we can call this function to get qos info*/ +static void get_picture_qos_info(struct AV1HW_s *hw) +{ + struct PIC_BUFFER_CONFIG_s *frame = &hw->cur_buf->buf; + + if (!frame) + return; + + if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) { + unsigned char a[3]; + unsigned char i, j, t; + unsigned long data; + + data = READ_VREG(HEVC_MV_INFO); + if (frame->slice_type == KEY_FRAME) + data = 0; + a[0] = data & 0xff; + a[1] = (data >> 8) & 0xff; + a[2] = (data >> 16) & 0xff; + + for (i = 0; i < 3; i++) { + for (j = i+1; j < 3; j++) { + if (a[j] < a[i]) { + t = a[j]; + a[j] = a[i]; + a[i] = t; + } else if (a[j] == a[i]) { + a[i]++; + t = a[j]; + a[j] = a[i]; + a[i] = t; + } + } + } + frame->max_mv = a[2]; + frame->avg_mv = a[1]; + frame->min_mv = a[0]; + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "mv data %x a[0]= %x a[1]= %x a[2]= %x\n", + data, a[0], a[1], a[2]); + + data = READ_VREG(HEVC_QP_INFO); + a[0] = data & 0x1f; + a[1] = (data >> 8) & 0x3f; + a[2] = (data >> 16) & 0x7f; + + for (i = 0; i < 3; i++) { + for (j = i+1; j < 3; j++) { + if (a[j] < a[i]) { + t = a[j]; + a[j] = a[i]; + a[i] = t; + } else if (a[j] == a[i]) { + a[i]++; + t = a[j]; + a[j] = a[i]; + a[i] = t; + } + } + } + frame->max_qp = a[2]; + frame->avg_qp = a[1]; + frame->min_qp = a[0]; + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "qp data %x a[0]= %x a[1]= %x a[2]= %x\n", + data, a[0], a[1], a[2]); + + data = READ_VREG(HEVC_SKIP_INFO); + a[0] = data & 0x1f; + a[1] = (data >> 8) & 0x3f; + a[2] = (data >> 16) & 0x7f; + + for (i = 0; i < 3; i++) { + for (j = i+1; j < 3; j++) { + if (a[j] < a[i]) { + t = a[j]; + a[j] = a[i]; + a[i] = t; + } else if (a[j] == a[i]) { + a[i]++; + t = a[j]; + a[j] = a[i]; + a[i] = t; + } + } + } + frame->max_skip = a[2]; + frame->avg_skip = a[1]; + frame->min_skip = a[0]; + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "skip data %x a[0]= %x a[1]= %x a[2]= %x\n", + data, a[0], a[1], a[2]); + } else { + uint32_t blk88_y_count; + uint32_t blk88_c_count; + uint32_t blk22_mv_count; + uint32_t rdata32; + int32_t mv_hi; + int32_t mv_lo; + uint32_t rdata32_l; + uint32_t mvx_L0_hi; + uint32_t mvy_L0_hi; + uint32_t mvx_L1_hi; + uint32_t mvy_L1_hi; + int64_t value; + uint64_t temp_value; + int pic_number = frame->decode_idx; + + frame->max_mv = 0; + frame->avg_mv = 0; + frame->min_mv = 0; + + frame->max_skip = 0; + frame->avg_skip = 0; + frame->min_skip = 0; + + frame->max_qp = 0; + frame->avg_qp = 0; + frame->min_qp = 0; + + av1_print(hw, AV1_DEBUG_QOS_INFO, "slice_type:%d, poc:%d\n", + frame->slice_type, + pic_number); + + /* set rd_idx to 0 */ + WRITE_VREG(HEVC_PIC_QUALITY_CTRL, 0); + + blk88_y_count = READ_VREG(HEVC_PIC_QUALITY_DATA); + if (blk88_y_count == 0) { + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] NO Data yet.\n", + pic_number); + + /* reset all counts */ + WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8)); + return; + } + /* qp_y_sum */ + rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] Y QP AVG : %d (%d/%d)\n", + pic_number, rdata32/blk88_y_count, + rdata32, blk88_y_count); + + frame->avg_qp = rdata32/blk88_y_count; + /* intra_y_count */ + rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] Y intra rate : %d%c (%d)\n", + pic_number, rdata32*100/blk88_y_count, + '%', rdata32); + + /* skipped_y_count */ + rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] Y skipped rate : %d%c (%d)\n", + pic_number, rdata32*100/blk88_y_count, + '%', rdata32); + + frame->avg_skip = rdata32*100/blk88_y_count; + /* coeff_non_zero_y_count */ + rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] Y ZERO_Coeff rate : %d%c (%d)\n", + pic_number, (100 - rdata32*100/(blk88_y_count*1)), + '%', rdata32); + + /* blk66_c_count */ + blk88_c_count = READ_VREG(HEVC_PIC_QUALITY_DATA); + if (blk88_c_count == 0) { + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] NO Data yet.\n", + pic_number); + /* reset all counts */ + WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8)); + return; + } + /* qp_c_sum */ + rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] C QP AVG : %d (%d/%d)\n", + pic_number, rdata32/blk88_c_count, + rdata32, blk88_c_count); + + /* intra_c_count */ + rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] C intra rate : %d%c (%d)\n", + pic_number, rdata32*100/blk88_c_count, + '%', rdata32); + + /* skipped_cu_c_count */ + rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] C skipped rate : %d%c (%d)\n", + pic_number, rdata32*100/blk88_c_count, + '%', rdata32); + + /* coeff_non_zero_c_count */ + rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] C ZERO_Coeff rate : %d%c (%d)\n", + pic_number, (100 - rdata32*100/(blk88_c_count*1)), + '%', rdata32); + + /* 1'h0, qp_c_max[6:0], 1'h0, qp_c_min[6:0], + 1'h0, qp_y_max[6:0], 1'h0, qp_y_min[6:0] */ + rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] Y QP min : %d\n", + pic_number, (rdata32>>0)&0xff); + + frame->min_qp = (rdata32>>0)&0xff; + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] Y QP max : %d\n", + pic_number, (rdata32>>8)&0xff); + + frame->max_qp = (rdata32>>8)&0xff; + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] C QP min : %d\n", + pic_number, (rdata32>>16)&0xff); + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] C QP max : %d\n", + pic_number, (rdata32>>24)&0xff); + + /* blk22_mv_count */ + blk22_mv_count = READ_VREG(HEVC_PIC_QUALITY_DATA); + if (blk22_mv_count == 0) { + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] NO MV Data yet.\n", + pic_number); + /* reset all counts */ + WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8)); + return; + } + /* mvy_L1_count[39:32], mvx_L1_count[39:32], + mvy_L0_count[39:32], mvx_L0_count[39:32] */ + rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); + /* should all be 0x00 or 0xff */ + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] MV AVG High Bits: 0x%X\n", + pic_number, rdata32); + + mvx_L0_hi = ((rdata32>>0)&0xff); + mvy_L0_hi = ((rdata32>>8)&0xff); + mvx_L1_hi = ((rdata32>>16)&0xff); + mvy_L1_hi = ((rdata32>>24)&0xff); + + /* mvx_L0_count[31:0] */ + rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA); + temp_value = mvx_L0_hi; + temp_value = (temp_value << 32) | rdata32_l; + + if (mvx_L0_hi & 0x80) + value = 0xFFFFFFF000000000 | temp_value; + else + value = temp_value; + + value = div_s64(value, blk22_mv_count); + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] MVX_L0 AVG : %d (%lld/%d)\n", + pic_number, (int)value, + value, blk22_mv_count); + + frame->avg_mv = value; + + /* mvy_L0_count[31:0] */ + rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA); + temp_value = mvy_L0_hi; + temp_value = (temp_value << 32) | rdata32_l; + + if (mvy_L0_hi & 0x80) + value = 0xFFFFFFF000000000 | temp_value; + else + value = temp_value; + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] MVY_L0 AVG : %d (%lld/%d)\n", + pic_number, rdata32_l/blk22_mv_count, + value, blk22_mv_count); + + /* mvx_L1_count[31:0] */ + rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA); + temp_value = mvx_L1_hi; + temp_value = (temp_value << 32) | rdata32_l; + if (mvx_L1_hi & 0x80) + value = 0xFFFFFFF000000000 | temp_value; + else + value = temp_value; + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] MVX_L1 AVG : %d (%lld/%d)\n", + pic_number, rdata32_l/blk22_mv_count, + value, blk22_mv_count); + + /* mvy_L1_count[31:0] */ + rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA); + temp_value = mvy_L1_hi; + temp_value = (temp_value << 32) | rdata32_l; + if (mvy_L1_hi & 0x80) + value = 0xFFFFFFF000000000 | temp_value; + else + value = temp_value; + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] MVY_L1 AVG : %d (%lld/%d)\n", + pic_number, rdata32_l/blk22_mv_count, + value, blk22_mv_count); + + /* {mvx_L0_max, mvx_L0_min} // format : {sign, abs[14:0]} */ + rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); + mv_hi = (rdata32>>16)&0xffff; + if (mv_hi & 0x8000) + mv_hi = 0x8000 - mv_hi; + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] MVX_L0 MAX : %d\n", + pic_number, mv_hi); + + frame->max_mv = mv_hi; + + mv_lo = (rdata32>>0)&0xffff; + if (mv_lo & 0x8000) + mv_lo = 0x8000 - mv_lo; + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] MVX_L0 MIN : %d\n", + pic_number, mv_lo); + + frame->min_mv = mv_lo; + + /* {mvy_L0_max, mvy_L0_min} */ + rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); + mv_hi = (rdata32>>16)&0xffff; + if (mv_hi & 0x8000) + mv_hi = 0x8000 - mv_hi; + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] MVY_L0 MAX : %d\n", + pic_number, mv_hi); + + mv_lo = (rdata32>>0)&0xffff; + if (mv_lo & 0x8000) + mv_lo = 0x8000 - mv_lo; + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] MVY_L0 MIN : %d\n", + pic_number, mv_lo); + + /* {mvx_L1_max, mvx_L1_min} */ + rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); + mv_hi = (rdata32>>16)&0xffff; + if (mv_hi & 0x8000) + mv_hi = 0x8000 - mv_hi; + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] MVX_L1 MAX : %d\n", + pic_number, mv_hi); + + mv_lo = (rdata32>>0)&0xffff; + if (mv_lo & 0x8000) + mv_lo = 0x8000 - mv_lo; + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] MVX_L1 MIN : %d\n", + pic_number, mv_lo); + + /* {mvy_L1_max, mvy_L1_min} */ + rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); + mv_hi = (rdata32>>16)&0xffff; + if (mv_hi & 0x8000) + mv_hi = 0x8000 - mv_hi; + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] MVY_L1 MAX : %d\n", + pic_number, mv_hi); + + mv_lo = (rdata32>>0)&0xffff; + if (mv_lo & 0x8000) + mv_lo = 0x8000 - mv_lo; + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] MVY_L1 MIN : %d\n", + pic_number, mv_lo); + + rdata32 = READ_VREG(HEVC_PIC_QUALITY_CTRL); + + av1_print(hw, AV1_DEBUG_QOS_INFO, + "[Picture %d Quality] After Read : VDEC_PIC_QUALITY_CTRL : 0x%x\n", + pic_number, rdata32); + + /* reset all counts */ + WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8)); + } +} + +static int load_param(struct AV1HW_s *hw, union param_u *params, uint32_t dec_status) +{ + int i; + unsigned long flags; + int head_type = 0; + if (dec_status == AOM_AV1_SEQ_HEAD_PARSER_DONE) + head_type = OBU_SEQUENCE_HEADER; + else if (dec_status == AOM_AV1_FRAME_HEAD_PARSER_DONE) + head_type = OBU_FRAME_HEADER; + else if (dec_status == AOM_AV1_FRAME_PARSER_DONE) + head_type = OBU_FRAME; + else if (dec_status == AOM_AV1_REDUNDANT_FRAME_HEAD_PARSER_DONE) + head_type = OBU_REDUNDANT_FRAME_HEADER; + else { + //printf("Error, dec_status of 0x%x, not supported!!!\n", dec_status); + return -1; + } + av1_print2(AOM_DEBUG_HW_MORE, "load_param: ret 0x%x\n", head_type); + + if (debug&AOM_AV1_DEBUG_SEND_PARAM_WITH_REG) { + get_rpm_param(params); + } + else { + for (i = 0; i < (RPM_END-RPM_BEGIN); i += 4) { + int32_t ii; + for (ii = 0; ii < 4; ii++) { + params->l.data[i+ii]=hw->rpm_ptr[i+3-ii]; + } + } + } + + params->p.enable_ref_frame_mvs = (params->p.seq_flags >> 7) & 0x1; + params->p.enable_superres = (params->p.seq_flags >> 15) & 0x1; + + if (debug & AV1_DEBUG_BUFMGR_MORE) { + lock_buffer_pool(hw->pbi->common.buffer_pool, flags); + pr_info("aom_param: (%d)\n", hw->pbi->decode_idx); + //pbi->slice_idx++; + for ( i = 0; i < (RPM_END-RPM_BEGIN); i++) { + pr_info("%04x ", params->l.data[i]); + if (((i + 1) & 0xf) == 0) + pr_info("\n"); + } + unlock_buffer_pool(hw->pbi->common.buffer_pool, flags); + } + return head_type; +} + +static int av1_postproc(struct AV1HW_s *hw) +{ + if (hw->postproc_done) + return 0; + hw->postproc_done = 1; + return av1_bufmgr_postproc(hw->pbi, hw->frame_decoded); +} + +static irqreturn_t vav1_isr_thread_fn(int irq, void *data) +{ + struct AV1HW_s *hw = (struct AV1HW_s *)data; + unsigned int dec_status = hw->dec_status; + int obu_type; + + /*if (hw->wait_buf) + * pr_info("set wait_buf to 0\r\n"); + */ + if (hw->eos) + return IRQ_HANDLED; + hw->wait_buf = 0; + if ((dec_status == AOM_NAL_DECODE_DONE) || + (dec_status == AOM_SEARCH_BUFEMPTY) || + (dec_status == AOM_DECODE_BUFEMPTY) + ) { + if (hw->m_ins_flag) { + reset_process_time(hw); + if (!vdec_frame_based(hw_to_vdec(hw))) + dec_again_process(hw); + else { + hw->dec_result = DEC_RESULT_DONE; + vdec_schedule_work(&hw->work); + } + } + hw->process_busy = 0; + return IRQ_HANDLED; + } else if (dec_status == AOM_AV1_DEC_PIC_END) { + struct AV1_Common_s *const cm = &hw->pbi->common; +#if 1 + u32 fg_reg0, fg_reg1, num_y_points, num_cb_points, num_cr_points; + WRITE_VREG(HEVC_FGS_IDX, 0); + fg_reg0 = READ_VREG(HEVC_FGS_DATA); + fg_reg1 = READ_VREG(HEVC_FGS_DATA); + num_y_points = fg_reg1 & 0xf; + num_cr_points = (fg_reg1 >> 8) & 0xf; + num_cb_points = (fg_reg1 >> 4) & 0xf; + if ((num_y_points > 0) || + ((num_cb_points > 0) | ((fg_reg0 >> 17) & 0x1)) || + ((num_cr_points > 0) | ((fg_reg0 >> 17) & 0x1))) + hw->fgs_valid = 1; + else + hw->fgs_valid = 0; + av1_print(hw, AOM_DEBUG_HW_MORE, + "fg_data0 0x%x fg_data1 0x%x fg_valid %d\n", + fg_reg0, fg_reg1, hw->fgs_valid); +#else + if (READ_VREG(HEVC_FGS_CTRL) & + ((1 << 4) | (1 << 5) | (1 << 6))) + hw->fgs_valid = 1; + else + hw->fgs_valid = 0; +#endif + decode_frame_count[hw->index] = hw->frame_count; + if (hw->m_ins_flag) { +#ifdef USE_DEC_PIC_END + if (READ_VREG(PIC_END_LCU_COUNT) != 0) { + hw->frame_decoded = 1; + /* + In c module, multi obus are put in one packet, which is decoded + with av1_receive_compressed_data(). + For STREAM_MODE or SINGLE_MODE, there is no packet boundary, + we assume each packet must and only include one picture of data (LCUs) + or cm->show_existing_frame is 1 + */ + av1_print(hw, AOM_DEBUG_HW_MORE, + "Decoding done (index %d), fgs_valid %d data_size 0x%x shiftbyte 0x%x\n", + cm->cur_frame? cm->cur_frame->buf.index:-1, + hw->fgs_valid, + hw->data_size, + READ_VREG(HEVC_SHIFT_BYTE_COUNT)); + hw->config_next_ref_info_flag = 1; /*to do: low_latency_flag case*/ + //config_next_ref_info_hw(hw); + } +#endif + + if (get_picture_qos) + get_picture_qos_info(hw); + + reset_process_time(hw); + + /* + if (debug & + AV1_DEBUG_BUFMGR_MORE) + dump_aux_buf(hw); + set_aux_data(hw, + &cm->cur_frame->buf, 0, 0); + */ + if (/*hw->vf_pre_count == 0 ||*/ hw->low_latency_flag) + av1_postproc(hw); + + if (multi_frames_in_one_pack && + hw->frame_decoded && + READ_VREG(HEVC_SHIFT_BYTE_COUNT) < hw->data_size) { + WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD); + av1_print(hw, AOM_DEBUG_HW_MORE, + "PIC_END, fgs_valid %d search head ...\n", + hw->fgs_valid); + if (hw->config_next_ref_info_flag) + config_next_ref_info_hw(hw); + } else { + hw->dec_result = DEC_RESULT_DONE; + amhevc_stop(); +#ifdef MCRCC_ENABLE + if (mcrcc_cache_alg_flag) + dump_hit_rate(hw); +#endif + vdec_schedule_work(&hw->work); + } + } else { + av1_print(hw, AOM_DEBUG_HW_MORE, + "PIC_END, fgs_valid %d search head ...\n", + hw->fgs_valid); + WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD); +#ifdef USE_DEC_PIC_END + if (READ_VREG(PIC_END_LCU_COUNT) != 0) { + hw->frame_decoded = 1; + /* + In c module, multi obus are put in one packet, which is decoded + with av1_receive_compressed_data(). + For STREAM_MODE or SINGLE_MODE, there is no packet boundary, + we assume each packet must and only include one picture of data (LCUs) + or cm->show_existing_frame is 1 + */ + av1_print(hw, AOM_DEBUG_HW_MORE, "Decoding done (index %d)\n", + cm->cur_frame? cm->cur_frame->buf.index:-1); + config_next_ref_info_hw(hw); + } +#endif + /* + if (debug & + AV1_DEBUG_BUFMGR_MORE) + dump_aux_buf(hw); + set_aux_data(hw, + &cm->cur_frame->buf, 0, 0); + */ + if (hw->low_latency_flag) { + av1_postproc(hw); + vdec_profile(hw_to_vdec(hw), VDEC_PROFILE_EVENT_CB); + if (debug & PRINT_FLAG_VDEC_DETAIL) + pr_info("%s AV1 frame done \n", __func__); + } + } + + hw->process_busy = 0; + return IRQ_HANDLED; + } + + if (dec_status == AOM_EOS) { + if (hw->m_ins_flag) + reset_process_time(hw); + + av1_print(hw, AOM_DEBUG_HW_MORE, "AV1_EOS, flush buffer\r\n"); + + av1_postproc(hw); + + av1_print(hw, AOM_DEBUG_HW_MORE, "send AV1_10B_DISCARD_NAL\r\n"); + WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_DISCARD_NAL); + hw->process_busy = 0; + if (hw->m_ins_flag) { + hw->dec_result = DEC_RESULT_DONE; + amhevc_stop(); + vdec_schedule_work(&hw->work); + } + return IRQ_HANDLED; + } else if (dec_status == AOM_DECODE_OVER_SIZE) { + av1_print(hw, AOM_DEBUG_HW_MORE, "av1 decode oversize !!\n"); + debug |= (AV1_DEBUG_DIS_LOC_ERROR_PROC | + AV1_DEBUG_DIS_SYS_ERROR_PROC); + hw->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW; + hw->process_busy = 0; + if (hw->m_ins_flag) + reset_process_time(hw); + return IRQ_HANDLED; + } + + obu_type = load_param(hw, &hw->aom_param, dec_status); + if (obu_type < 0) { + hw->process_busy = 0; + return IRQ_HANDLED; + } + + if (obu_type == OBU_SEQUENCE_HEADER) { + int next_lcu_size; + av1_bufmgr_process(hw->pbi, &hw->aom_param, 0, obu_type); + + bit_depth_luma = hw->aom_param.p.bit_depth; + bit_depth_chroma = hw->aom_param.p.bit_depth; + next_lcu_size = ((hw->aom_param.p.seq_flags >> 6) & 0x1) ? 128 : 64; + hw->video_signal_type = (hw->aom_param.p.video_signal_type << 16 + | hw->aom_param.p.color_description); + + if (next_lcu_size != hw->current_lcu_size) { + av1_print(hw, AOM_DEBUG_HW_MORE, + " ## lcu_size changed from %d to %d\n", + hw->current_lcu_size, next_lcu_size); + hw->current_lcu_size = next_lcu_size; + } + + if (!hw->pic_list_init_done) { +#if 0 + if (hw->m_ins_flag) { + /* picture list init.*/ + hw->dec_result = DEC_INIT_PICLIST; + vdec_schedule_work(&hw->work); + } else +#endif + { + init_pic_list(hw); + init_pic_list_hw(hw); +#ifndef MV_USE_FIXED_BUF + if (init_mv_buf_list(hw) < 0) { + pr_err("%s: !!!!Error, init_mv_buf_list fail\n", __func__); + } +#endif + } + hw->pic_list_init_done = true; + } + av1_print(hw, AOM_DEBUG_HW_MORE, + "AOM_AV1_SEQ_HEAD_PARSER_DONE, search head ...\n"); + WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD); + hw->process_busy = 0; + return IRQ_HANDLED; + } +#ifndef USE_DEC_PIC_END + //if (pbi->wait_buf) { + if (pbi->bufmgr_proc_count > 0) { + if (READ_VREG(PIC_END_LCU_COUNT) != 0) { + hw->frame_decoded = 1; + /* + In c module, multi obus are put in one packet, which is decoded + with av1_receive_compressed_data(). + For STREAM_MODE or SINGLE_MODE, there is no packet boundary, + we assume each packet must and only include one picture of data (LCUs) + or cm->show_existing_frame is 1 + */ + av1_print(hw, AOM_DEBUG_HW_MORE, "Decoding done (index %d)\n", + cm->cur_frame? cm->cur_frame->buf.index:-1); + } + } +#endif +#if 1 +/*def CHECK_OBU_REDUNDANT_FRAME_HEADER*/ + if (debug & AOM_DEBUG_BUFMGR_ONLY) { + if (READ_VREG(PIC_END_LCU_COUNT) != 0) + hw->obu_frame_frame_head_come_after_tile = 0; + + if (obu_type == OBU_FRAME_HEADER || + obu_type == OBU_FRAME) { + hw->obu_frame_frame_head_come_after_tile = 1; + } else if (obu_type == OBU_REDUNDANT_FRAME_HEADER && + hw->obu_frame_frame_head_come_after_tile == 0) { + if (hw->frame_decoded == 1) { + av1_print(hw, AOM_DEBUG_HW_MORE, + "Warning, OBU_REDUNDANT_FRAME_HEADER come without OBU_FRAME or OBU_FRAME_HEAD\n"); + hw->frame_decoded = 0; + } + } + } +#endif + if (hw->frame_decoded) + hw->one_compressed_data_done = 1; + + if (hw->m_ins_flag) + reset_process_time(hw); + + + if (hw->process_state != PROC_STATE_SENDAGAIN + ) { + if (hw->mmu_enable) + av1_recycle_mmu_buf_tail(hw); + + + if (hw->one_compressed_data_done) { + av1_postproc(hw); + av1_release_bufs(hw); +#ifndef MV_USE_FIXED_BUF + put_un_used_mv_bufs(hw); +#endif + } + } + + av1_continue_decoding(hw, obu_type); + hw->postproc_done = 0; + hw->process_busy = 0; + + if (hw->m_ins_flag) + start_process_time(hw); + + return IRQ_HANDLED; +} + +static irqreturn_t vav1_isr(int irq, void *data) +{ + int i; + unsigned int dec_status; + struct AV1HW_s *hw = (struct AV1HW_s *)data; + //struct AV1_Common_s *const cm = &hw->pbi->common; + uint debug_tag; + + WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1); + + dec_status = READ_VREG(HEVC_DEC_STATUS_REG) & 0xff; + if (!hw) + return IRQ_HANDLED; + if (hw->init_flag == 0) + return IRQ_HANDLED; + if (hw->process_busy)/*on process.*/ + return IRQ_HANDLED; + hw->dec_status = dec_status; + hw->process_busy = 1; + if (debug & AV1_DEBUG_BUFMGR) + av1_print(hw, AV1_DEBUG_BUFMGR, + "av1 isr (%d) dec status = 0x%x, lcu 0x%x shiftbyte 0x%x (%x %x lev %x, wr %x, rd %x)\n", + irq, + dec_status, READ_VREG(HEVC_PARSER_LCU_START), + READ_VREG(HEVC_SHIFT_BYTE_COUNT), + READ_VREG(HEVC_STREAM_START_ADDR), + READ_VREG(HEVC_STREAM_END_ADDR), + READ_VREG(HEVC_STREAM_LEVEL), + READ_VREG(HEVC_STREAM_WR_PTR), + READ_VREG(HEVC_STREAM_RD_PTR) + ); + + debug_tag = READ_HREG(DEBUG_REG1); + if (debug_tag & 0x10000) { + pr_info("LMEM:\n", READ_HREG(DEBUG_REG1)); + for (i = 0; i < 0x400; i += 4) { + int ii; + if ((i & 0xf) == 0) + pr_info("%03x: ", i); + for (ii = 0; ii < 4; ii++) { + pr_info("%04x ", + hw->lmem_ptr[i + 3 - ii]); + } + if (((i + ii) & 0xf) == 0) + pr_info("\n"); + } + if (((udebug_pause_pos & 0xffff) + == (debug_tag & 0xffff)) && + (udebug_pause_decode_idx == 0 || + udebug_pause_decode_idx == hw->result_done_count) && + (udebug_pause_val == 0 || + udebug_pause_val == READ_HREG(DEBUG_REG2))) { + udebug_pause_pos &= 0xffff; + hw->ucode_pause_pos = udebug_pause_pos; + } + else if (debug_tag & 0x20000) + hw->ucode_pause_pos = 0xffffffff; + if (hw->ucode_pause_pos) + reset_process_time(hw); + else + WRITE_HREG(DEBUG_REG1, 0); + } else if (debug_tag != 0) { + pr_info( + "dbg%x: %x lcu %x\n", READ_HREG(DEBUG_REG1), + READ_HREG(DEBUG_REG2), + READ_VREG(HEVC_PARSER_LCU_START)); + + if (((udebug_pause_pos & 0xffff) + == (debug_tag & 0xffff)) && + (udebug_pause_decode_idx == 0 || + udebug_pause_decode_idx == hw->result_done_count) && + (udebug_pause_val == 0 || + udebug_pause_val == READ_HREG(DEBUG_REG2))) { + udebug_pause_pos &= 0xffff; + hw->ucode_pause_pos = udebug_pause_pos; + } + if (hw->ucode_pause_pos) + reset_process_time(hw); + else + WRITE_HREG(DEBUG_REG1, 0); + hw->process_busy = 0; + return IRQ_HANDLED; + } + + //if (READ_VREG(HEVC_FG_STATUS) == AOM_AV1_FGS_PARAM) { + if (hw->dec_status == AOM_AV1_FGS_PARAM) { + uint32_t status_val = READ_VREG(HEVC_FG_STATUS); + WRITE_VREG(HEVC_FG_STATUS, AOM_AV1_FGS_PARAM_CONT); + WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_FGS_PARAM_CONT); + // Bit[11] - 0 Read, 1 - Write + // Bit[10:8] - film_grain_params_ref_idx // For Write request + if ((status_val >> 11) & 0x1) { + uint32_t film_grain_params_ref_idx = (status_val >> 8) & 0x7; + config_film_grain_reg(hw, film_grain_params_ref_idx); + } + else + read_film_grain_reg(hw); + hw->process_busy = 0; + return IRQ_HANDLED; + } + + if (!hw->m_ins_flag) { + av1_print(hw, AV1_DEBUG_BUFMGR, + "error flag = %d\n", hw->error_flag); + if (hw->error_flag == 1) { + hw->error_flag = 2; + hw->process_busy = 0; + return IRQ_HANDLED; + } else if (hw->error_flag == 3) { + hw->process_busy = 0; + return IRQ_HANDLED; + } + } + if (get_free_buf_count(hw) <= 0) { + /* + if (hw->wait_buf == 0) + pr_info("set wait_buf to 1\r\n"); + */ + hw->wait_buf = 1; + hw->process_busy = 0; + av1_print(hw, AV1_DEBUG_BUFMGR, + "free buf not enough = %d\n", + get_free_buf_count(hw)); + return IRQ_HANDLED; + } + return IRQ_WAKE_THREAD; +} + +static void av1_set_clk(struct work_struct *work) +{ + struct AV1HW_s *hw = container_of(work, + struct AV1HW_s, set_clk_work); + int fps = 96000 / hw->frame_dur; + + if (hevc_source_changed(VFORMAT_AV1, + frame_width, frame_height, fps) > 0) + hw->saved_resolution = frame_width * + frame_height * fps; +} + +static void vav1_put_timer_func(unsigned long arg) +{ + struct AV1HW_s *hw = (struct AV1HW_s *)arg; + struct timer_list *timer = &hw->timer; + uint8_t empty_flag; + unsigned int buf_level; + + enum receviver_start_e state = RECEIVER_INACTIVE; + + if (hw->m_ins_flag) { + if (hw_to_vdec(hw)->next_status + == VDEC_STATUS_DISCONNECTED) { + hw->dec_result = DEC_RESULT_FORCE_EXIT; + vdec_schedule_work(&hw->work); + pr_debug( + "vdec requested to be disconnected\n"); + return; + } + } + if (hw->init_flag == 0) { + if (hw->stat & STAT_TIMER_ARM) { + timer->expires = jiffies + PUT_INTERVAL; + add_timer(&hw->timer); + } + return; + } + if (hw->m_ins_flag == 0) { + if (vf_get_receiver(hw->provider_name)) { + state = + vf_notify_receiver(hw->provider_name, + VFRAME_EVENT_PROVIDER_QUREY_STATE, + NULL); + if ((state == RECEIVER_STATE_NULL) + || (state == RECEIVER_STATE_NONE)) + state = RECEIVER_INACTIVE; + } else + state = RECEIVER_INACTIVE; + + empty_flag = (READ_VREG(HEVC_PARSER_INT_STATUS) >> 6) & 0x1; + /* error watchdog */ + if (empty_flag == 0) { + /* decoder has input */ + if ((debug & AV1_DEBUG_DIS_LOC_ERROR_PROC) == 0) { + + buf_level = READ_VREG(HEVC_STREAM_LEVEL); + /* receiver has no buffer to recycle */ + if ((state == RECEIVER_INACTIVE) && + (kfifo_is_empty(&hw->display_q) && + buf_level > 0x200) + ) { + WRITE_VREG + (HEVC_ASSIST_MBOX0_IRQ_REG, + 0x1); + } + } + + if ((debug & AV1_DEBUG_DIS_SYS_ERROR_PROC) == 0) { + /* receiver has no buffer to recycle */ + /*if ((state == RECEIVER_INACTIVE) && + * (kfifo_is_empty(&hw->display_q))) { + *pr_info("AV1 something error,need reset\n"); + *} + */ + } + } + } +#ifdef MULTI_INSTANCE_SUPPORT + else { + if ( + (decode_timeout_val > 0) && + (hw->start_process_time > 0) && + ((1000 * (jiffies - hw->start_process_time) / HZ) + > decode_timeout_val) + ) { + int current_lcu_idx = + READ_VREG(HEVC_PARSER_LCU_START) + & 0xffffff; + if (hw->last_lcu_idx == current_lcu_idx) { + if (hw->decode_timeout_count > 0) + hw->decode_timeout_count--; + if (hw->decode_timeout_count == 0) { + if (input_frame_based( + hw_to_vdec(hw)) || + (READ_VREG(HEVC_STREAM_LEVEL) > 0x200)) + timeout_process(hw); + else { + av1_print(hw, 0, + "timeout & empty, again\n"); + dec_again_process(hw); + } + } + } else { + start_process_time(hw); + hw->last_lcu_idx = current_lcu_idx; + } + } + } +#endif + + if ((hw->ucode_pause_pos != 0) && + (hw->ucode_pause_pos != 0xffffffff) && + udebug_pause_pos != hw->ucode_pause_pos) { + hw->ucode_pause_pos = 0; + WRITE_HREG(DEBUG_REG1, 0); + } +#ifdef MULTI_INSTANCE_SUPPORT + if (debug & AV1_DEBUG_FORCE_SEND_AGAIN) { + av1_print(hw, AOM_DEBUG_HW_MORE, + "Force Send Again\r\n"); + debug &= ~AV1_DEBUG_FORCE_SEND_AGAIN; + reset_process_time(hw); + hw->dec_result = DEC_RESULT_AGAIN; + if (hw->process_state == + PROC_STATE_DECODESLICE) { + if (hw->mmu_enable) + av1_recycle_mmu_buf(hw); + hw->process_state = + PROC_STATE_SENDAGAIN; + } + amhevc_stop(); + + vdec_schedule_work(&hw->work); + } + + if (debug & AV1_DEBUG_DUMP_DATA) { + debug &= ~AV1_DEBUG_DUMP_DATA; + av1_print(hw, 0, + "%s: chunk size 0x%x off 0x%x sum 0x%x\n", + __func__, + hw->chunk->size, + hw->chunk->offset, + get_data_check_sum(hw, hw->chunk->size) + ); + dump_data(hw, hw->chunk->size); + } +#endif + if (debug & AV1_DEBUG_DUMP_PIC_LIST) { + /*dump_pic_list(hw);*/ + av1_dump_state(hw_to_vdec(hw)); + debug &= ~AV1_DEBUG_DUMP_PIC_LIST; + } + if (debug & AV1_DEBUG_TRIG_SLICE_SEGMENT_PROC) { + WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0x1); + debug &= ~AV1_DEBUG_TRIG_SLICE_SEGMENT_PROC; + } + /*if (debug & AV1_DEBUG_HW_RESET) { + }*/ + + if (radr != 0) { + if ((radr >> 24) != 0) { + int count = radr >> 24; + int adr = radr & 0xffffff; + int i; + for (i = 0; i < count; i++) + pr_info("READ_VREG(%x)=%x\n", adr+i, READ_VREG(adr+i)); + } else if (rval != 0) { + WRITE_VREG(radr, rval); + pr_info("WRITE_VREG(%x,%x)\n", radr, rval); + } else + pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr)); + rval = 0; + radr = 0; + } + if (pop_shorts != 0) { + int i; + u32 sum = 0; + + pr_info("pop stream 0x%x shorts\r\n", pop_shorts); + for (i = 0; i < pop_shorts; i++) { + u32 data = + (READ_HREG(HEVC_SHIFTED_DATA) >> 16); + WRITE_HREG(HEVC_SHIFT_COMMAND, + (1<<7)|16); + if ((i & 0xf) == 0) + pr_info("%04x:", i); + pr_info("%04x ", data); + if (((i + 1) & 0xf) == 0) + pr_info("\r\n"); + sum += data; + } + pr_info("\r\nsum = %x\r\n", sum); + pop_shorts = 0; + } + if (dbg_cmd != 0) { + if (dbg_cmd == 1) { + u32 disp_laddr; + + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB && + get_double_write_mode(hw) == 0) { + disp_laddr = + READ_VCBUS_REG(AFBC_BODY_BADDR) << 4; + } else { + struct canvas_s cur_canvas; + + canvas_read((READ_VCBUS_REG(VD1_IF0_CANVAS0) + & 0xff), &cur_canvas); + disp_laddr = cur_canvas.addr; + } + pr_info("current displayed buffer address %x\r\n", + disp_laddr); + } + dbg_cmd = 0; + } + /*don't changed at start.*/ + if (hw->get_frame_dur && hw->show_frame_num > 60 && + hw->frame_dur > 0 && hw->saved_resolution != + frame_width * frame_height * + (96000 / hw->frame_dur)) + vdec_schedule_work(&hw->set_clk_work); + + timer->expires = jiffies + PUT_INTERVAL; + add_timer(timer); +} + + +int vav1_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) +{ + struct AV1HW_s *av1 = + (struct AV1HW_s *)vdec->private; + + if (!av1) + return -1; + + vstatus->frame_width = frame_width; + vstatus->frame_height = frame_height; + if (av1->frame_dur != 0) + vstatus->frame_rate = 96000 / av1->frame_dur; + else + vstatus->frame_rate = -1; + vstatus->error_count = 0; + vstatus->status = av1->stat | av1->fatal_error; + vstatus->frame_dur = av1->frame_dur; +#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC + vstatus->bit_rate = gvs->bit_rate; + vstatus->frame_data = gvs->frame_data; + vstatus->total_data = gvs->total_data; + vstatus->frame_count = gvs->frame_count; + vstatus->error_frame_count = gvs->error_frame_count; + vstatus->drop_frame_count = gvs->drop_frame_count; + vstatus->total_data = gvs->total_data; + vstatus->samp_cnt = gvs->samp_cnt; + vstatus->offset = gvs->offset; + snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name), + "%s", DRIVER_NAME); +#endif + return 0; +} + +int vav1_set_isreset(struct vdec_s *vdec, int isreset) +{ + is_reset = isreset; + return 0; +} + +#if 0 +static void AV1_DECODE_INIT(void) +{ + /* enable av1 clocks */ + WRITE_VREG(DOS_GCLK_EN3, 0xffffffff); + /* *************************************************************** */ + /* Power ON HEVC */ + /* *************************************************************** */ + /* Powerup HEVC */ + WRITE_VREG(AO_RTI_GEN_PWR_SLEEP0, + READ_VREG(AO_RTI_GEN_PWR_SLEEP0) & (~(0x3 << 6))); + WRITE_VREG(DOS_MEM_PD_HEVC, 0x0); + WRITE_VREG(DOS_SW_RESET3, READ_VREG(DOS_SW_RESET3) | (0x3ffff << 2)); + WRITE_VREG(DOS_SW_RESET3, READ_VREG(DOS_SW_RESET3) & (~(0x3ffff << 2))); + /* remove isolations */ + WRITE_VREG(AO_RTI_GEN_PWR_ISO0, + READ_VREG(AO_RTI_GEN_PWR_ISO0) & (~(0x3 << 10))); + +} +#endif + +static void vav1_prot_init(struct AV1HW_s *hw, u32 mask) +{ + unsigned int data32; + /* AV1_DECODE_INIT(); */ + av1_print(hw, AOM_DEBUG_HW_MORE, "%s %d\n", __func__, __LINE__); + + aom_config_work_space_hw(hw, mask); + if (mask & HW_MASK_BACK) { + //to do: .. for single instance, called after init_pic_list() + if (hw->m_ins_flag) + init_pic_list_hw(hw); + } + + aom_init_decoder_hw(hw, mask); + +#ifdef AOM_AV1_DBLK_INIT + av1_print(hw, AOM_DEBUG_HW_MORE, + "[test.c] av1_loop_filter_init (run once before decoding start)\n"); + av1_loop_filter_init(hw->lfi, hw->lf); +#endif + if ((mask & HW_MASK_FRONT) == 0) + return; +#if 1 + if (debug & AV1_DEBUG_BUFMGR_MORE) + pr_info("%s\n", __func__); + data32 = READ_VREG(HEVC_STREAM_CONTROL); + data32 = data32 | + (1 << 0)/*stream_fetch_enable*/ + ; + WRITE_VREG(HEVC_STREAM_CONTROL, data32); + + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { + if (debug & AV1_DEBUG_BUFMGR) + pr_info("[test.c] Config STREAM_FIFO_CTL\n"); + data32 = READ_VREG(HEVC_STREAM_FIFO_CTL); + data32 = data32 | + (1 << 29) // stream_fifo_hole + ; + WRITE_VREG(HEVC_STREAM_FIFO_CTL, data32); + } +#if 0 + data32 = READ_VREG(HEVC_SHIFT_STARTCODE); + if (data32 != 0x00000100) { + pr_info("av1 prot init error %d\n", __LINE__); + return; + } + data32 = READ_VREG(HEVC_SHIFT_EMULATECODE); + if (data32 != 0x00000300) { + pr_info("av1 prot init error %d\n", __LINE__); + return; + } + WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x12345678); + WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x9abcdef0); + data32 = READ_VREG(HEVC_SHIFT_STARTCODE); + if (data32 != 0x12345678) { + pr_info("av1 prot init error %d\n", __LINE__); + return; + } + data32 = READ_VREG(HEVC_SHIFT_EMULATECODE); + if (data32 != 0x9abcdef0) { + pr_info("av1 prot init error %d\n", __LINE__); + return; + } +#endif + WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x000000001); + WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000300); +#endif + + + + WRITE_VREG(HEVC_WAIT_FLAG, 1); + + /* WRITE_VREG(HEVC_MPSR, 1); */ + + /* clear mailbox interrupt */ + WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1); + + /* enable mailbox interrupt */ + WRITE_VREG(HEVC_ASSIST_MBOX0_MASK, 1); + + /* disable PSCALE for hardware sharing */ + WRITE_VREG(HEVC_PSCALE_CTRL, 0); + + WRITE_VREG(DEBUG_REG1, 0x0); + /*check vps/sps/pps/i-slice in ucode*/ + WRITE_VREG(NAL_SEARCH_CTL, 0x8); + + WRITE_VREG(DECODE_STOP_POS, udebug_flag); +} + +static int vav1_local_init(struct AV1HW_s *hw) +{ + int i; + int ret; + int width, height; + + hw->gvs = vzalloc(sizeof(struct vdec_info)); + if (NULL == hw->gvs) { + pr_info("the struct of vdec status malloc failed.\n"); + return -1; + } +#ifdef DEBUG_PTS + hw->pts_missed = 0; + hw->pts_hit = 0; +#endif + hw->new_frame_displayed = 0; + hw->last_put_idx = -1; + hw->saved_resolution = 0; + hw->get_frame_dur = false; + on_no_keyframe_skiped = 0; + hw->duration_from_pts_done = 0; + hw->av1_first_pts_ready = 0; + hw->frame_cnt_window = 0; + width = hw->vav1_amstream_dec_info.width; + height = hw->vav1_amstream_dec_info.height; + hw->frame_dur = + (hw->vav1_amstream_dec_info.rate == + 0) ? 3200 : hw->vav1_amstream_dec_info.rate; + if (width && height) + hw->frame_ar = height * 0x100 / width; +/* + *TODO:FOR VERSION + */ + pr_info("av1: ver (%d,%d) decinfo: %dx%d rate=%d\n", av1_version, + 0, width, height, hw->frame_dur); + + if (hw->frame_dur == 0) + hw->frame_dur = 96000 / 24; + + INIT_KFIFO(hw->display_q); + INIT_KFIFO(hw->newframe_q); + + + for (i = 0; i < VF_POOL_SIZE; i++) { + const struct vframe_s *vf = &hw->vfpool[i]; + + hw->vfpool[i].index = -1; + kfifo_put(&hw->newframe_q, vf); + } + + + ret = av1_local_init(hw); + + if (force_pts_unstable) { + if (!hw->pts_unstable) { + hw->pts_unstable = + (hw->vav1_amstream_dec_info.rate == 0)?1:0; + pr_info("set pts unstable\n"); + } + } + return ret; +} + + +#ifdef MULTI_INSTANCE_SUPPORT +static s32 vav1_init(struct vdec_s *vdec) +{ + struct AV1HW_s *hw = (struct AV1HW_s *)vdec->private; +#else +static s32 vav1_init(struct AV1HW_s *hw) +{ +#endif + int ret; + int fw_size = 0x1000 * 16; + struct firmware_s *fw = NULL; + + hw->stat |= STAT_TIMER_INIT; + + if (vav1_local_init(hw) < 0) + return -EBUSY; + + fw = vmalloc(sizeof(struct firmware_s) + fw_size); + if (IS_ERR_OR_NULL(fw)) + return -ENOMEM; + + av1_print(hw, AOM_DEBUG_HW_MORE, "%s %d\n", __func__, __LINE__); +#ifdef DEBUG_USE_VP9_DEVICE_NAME + if (get_firmware_data(VIDEO_DEC_VP9_MMU, fw->data) < 0) { +#else + if (get_firmware_data(VIDEO_DEC_AV1_MMU, fw->data) < 0) { +#endif + pr_err("get firmware fail.\n"); + printk("%s %d\n", __func__, __LINE__); + vfree(fw); + return -1; + } + av1_print(hw, AOM_DEBUG_HW_MORE, "%s %d\n", __func__, __LINE__); + + fw->len = fw_size; + + INIT_WORK(&hw->set_clk_work, av1_set_clk); + init_timer(&hw->timer); + +#ifdef MULTI_INSTANCE_SUPPORT + if (hw->m_ins_flag) { + hw->timer.data = (ulong) hw; + hw->timer.function = vav1_put_timer_func; + hw->timer.expires = jiffies + PUT_INTERVAL; + + /*add_timer(&hw->timer); + + hw->stat |= STAT_TIMER_ARM; + hw->stat |= STAT_ISR_REG;*/ + + INIT_WORK(&hw->work, av1_work); + hw->fw = fw; + + return 0; /*multi instance return */ + } +#endif + amhevc_enable(); + + ret = amhevc_loadmc_ex(VFORMAT_AV1, NULL, fw->data); + if (ret < 0) { + amhevc_disable(); + vfree(fw); + pr_err("AV1: the %s fw loading failed, err: %x\n", + tee_enabled() ? "TEE" : "local", ret); + return -EBUSY; + } + + vfree(fw); + + hw->stat |= STAT_MC_LOAD; + + /* enable AMRISC side protocol */ + vav1_prot_init(hw, HW_MASK_FRONT | HW_MASK_BACK); + + if (vdec_request_threaded_irq(VDEC_IRQ_0, + vav1_isr, + vav1_isr_thread_fn, + IRQF_ONESHOT,/*run thread on this irq disabled*/ + "vav1-irq", (void *)hw)) { + pr_info("vav1 irq register error.\n"); + amhevc_disable(); + return -ENOENT; + } + + hw->stat |= STAT_ISR_REG; + + if (force_dv_enable) + hw->provider_name = DV_PROVIDER_NAME; + else + hw->provider_name = PROVIDER_NAME; +#ifdef MULTI_INSTANCE_SUPPORT + vf_provider_init(&vav1_vf_prov, hw->provider_name, + &vav1_vf_provider, hw); + vf_reg_provider(&vav1_vf_prov); + vf_notify_receiver(hw->provider_name, VFRAME_EVENT_PROVIDER_START, NULL); + if (hw->frame_dur != 0) { + if (!is_reset) + vf_notify_receiver(hw->provider_name, + VFRAME_EVENT_PROVIDER_FR_HINT, + (void *) + ((unsigned long)hw->frame_dur)); + } +#else + vf_provider_init(&vav1_vf_prov, hw->provider_name, &vav1_vf_provider, + hw); + vf_reg_provider(&vav1_vf_prov); + vf_notify_receiver(hw->provider_name, VFRAME_EVENT_PROVIDER_START, NULL); + if (!is_reset) + vf_notify_receiver(hw->provider_name, VFRAME_EVENT_PROVIDER_FR_HINT, + (void *)((unsigned long)hw->frame_dur)); +#endif + hw->stat |= STAT_VF_HOOK; + + hw->timer.data = (ulong)hw; + hw->timer.function = vav1_put_timer_func; + hw->timer.expires = jiffies + PUT_INTERVAL; + + hw->stat |= STAT_VDEC_RUN; + + add_timer(&hw->timer); + + hw->stat |= STAT_TIMER_ARM; + + amhevc_start(); + + hw->init_flag = 1; + hw->process_busy = 0; + pr_info("%d, vav1_init, RP=0x%x\n", + __LINE__, READ_VREG(HEVC_STREAM_RD_PTR)); + return 0; +} + +static int vmav1_stop(struct AV1HW_s *hw) +{ + hw->init_flag = 0; + + if (hw->stat & STAT_VDEC_RUN) { + amhevc_stop(); + hw->stat &= ~STAT_VDEC_RUN; + } + if (hw->stat & STAT_ISR_REG) { + vdec_free_irq(VDEC_IRQ_0, (void *)hw); + hw->stat &= ~STAT_ISR_REG; + } + if (hw->stat & STAT_TIMER_ARM) { + del_timer_sync(&hw->timer); + hw->stat &= ~STAT_TIMER_ARM; + } + + if (hw->stat & STAT_VF_HOOK) { + if (!is_reset) + vf_notify_receiver(hw->provider_name, + VFRAME_EVENT_PROVIDER_FR_END_HINT, + NULL); + + vf_unreg_provider(&vav1_vf_prov); + hw->stat &= ~STAT_VF_HOOK; + } + av1_local_uninit(hw); + reset_process_time(hw); + cancel_work_sync(&hw->work); + cancel_work_sync(&hw->set_clk_work); + uninit_mmu_buffers(hw); + if (hw->fw) + vfree(hw->fw); + hw->fw = NULL; + return 0; +} + +static int vav1_stop(struct AV1HW_s *hw) +{ + + hw->init_flag = 0; + hw->first_sc_checked = 0; + if (hw->stat & STAT_VDEC_RUN) { + amhevc_stop(); + hw->stat &= ~STAT_VDEC_RUN; + } + + if (hw->stat & STAT_ISR_REG) { +#ifdef MULTI_INSTANCE_SUPPORT + if (!hw->m_ins_flag) +#endif + WRITE_VREG(HEVC_ASSIST_MBOX0_MASK, 0); + vdec_free_irq(VDEC_IRQ_0, (void *)hw); + hw->stat &= ~STAT_ISR_REG; + } + + if (hw->stat & STAT_TIMER_ARM) { + del_timer_sync(&hw->timer); + hw->stat &= ~STAT_TIMER_ARM; + } + + if (hw->stat & STAT_VF_HOOK) { + if (!is_reset) + vf_notify_receiver(hw->provider_name, + VFRAME_EVENT_PROVIDER_FR_END_HINT, + NULL); + + vf_unreg_provider(&vav1_vf_prov); + hw->stat &= ~STAT_VF_HOOK; + } + av1_local_uninit(hw); + + cancel_work_sync(&hw->set_clk_work); +#ifdef MULTI_INSTANCE_SUPPORT + if (hw->m_ins_flag) { + cancel_work_sync(&hw->work); + } else + amhevc_disable(); +#else + amhevc_disable(); +#endif + uninit_mmu_buffers(hw); + + vfree(hw->fw); + hw->fw = NULL; + return 0; +} +static int amvdec_av1_mmu_init(struct AV1HW_s *hw) +{ + int tvp_flag = vdec_secure(hw_to_vdec(hw)) ? + CODEC_MM_FLAGS_TVP : 0; + int buf_size = 48; + + if ((hw->max_pic_w * hw->max_pic_h > 1280*736) && + (hw->max_pic_w * hw->max_pic_h <= 1920*1088)) { + buf_size = 12; + } else if ((hw->max_pic_w * hw->max_pic_h > 0) && + (hw->max_pic_w * hw->max_pic_h <= 1280*736)) { + buf_size = 4; + } + hw->need_cache_size = buf_size * SZ_1M; + hw->sc_start_time = get_jiffies_64(); + if (hw->mmu_enable && ((hw->double_write_mode & 0x10) == 0)) { + int count = FRAME_BUFFERS; + hw->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME, + hw->index /* * 2*/, count, + hw->need_cache_size, + tvp_flag + ); + if (!hw->mmu_box) { + pr_err("av1 alloc mmu box failed!!\n"); + return -1; + } +#ifdef AOM_AV1_MMU_DW + if (hw->dw_mmu_enable) { + hw->mmu_box_dw = decoder_mmu_box_alloc_box(DRIVER_NAME, + hw->index /** 2 + 1*/, count, + hw->need_cache_size, + tvp_flag + ); + if (!hw->mmu_box_dw) { + pr_err("av1 alloc dw mmu box failed!!\n"); + return -1; + } + } +#endif + + } + hw->bmmu_box = decoder_bmmu_box_alloc_box( + DRIVER_NAME, + hw->index, + MAX_BMMU_BUFFER_NUM, + 4 + PAGE_SHIFT, + CODEC_MM_FLAGS_CMA_CLEAR | + CODEC_MM_FLAGS_FOR_VDECODER | + tvp_flag); + av1_print(hw, AV1_DEBUG_BUFMGR, + "%s, MAX_BMMU_BUFFER_NUM = %d\n", + __func__, + MAX_BMMU_BUFFER_NUM); + if (!hw->bmmu_box) { + pr_err("av1 alloc bmmu box failed!!\n"); + return -1; + } + return 0; +} + +static struct AV1HW_s *gHevc; + + +static int amvdec_av1_probe(struct platform_device *pdev) +{ + struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; + struct BUF_s BUF[MAX_BUF_NUM]; + struct AV1HW_s *hw; + AV1Decoder *pbi; + int ret; +#ifndef MULTI_INSTANCE_SUPPORT + int i; +#endif + pr_debug("%s\n", __func__); + + mutex_lock(&vav1_mutex); + hw = vmalloc(sizeof(struct AV1HW_s)); + if (hw == NULL) { + av1_print(hw, 0, "\namvdec_av1 device data allocation failed\n"); + mutex_unlock(&vav1_mutex); + return -ENOMEM; + } + + gHevc = hw; + memcpy(&BUF[0], &hw->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM); + memset(hw, 0, sizeof(struct AV1HW_s)); + memcpy(&hw->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM); + + if (init_dblk_struc(hw) < 0) { + av1_print(hw, 0, "\nammvdec_av1 device data allocation failed\n"); + vfree(hw); + return -ENOMEM; + } + + pbi = av1_decoder_create(&hw->av1_buffer_pool); //&aom_decoder; + hw->pbi = pbi; + if (hw->pbi == NULL) { + pr_info("\nammvdec_av1 device data allocation failed\n"); + release_dblk_struct(hw); + vfree(hw); + return -ENOMEM; + } + //hw->pbi->common.buffer_pool = &hw->av1_buffer_pool; //???? + hw->pbi->private_data = hw; + + hw->init_flag = 0; + hw->first_sc_checked= 0; + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { + av1_max_pic_w = 8192; + av1_max_pic_h = 4608; + } + hw->max_pic_w = av1_max_pic_w; + hw->max_pic_h = av1_max_pic_h; + +#ifdef MULTI_INSTANCE_SUPPORT + hw->eos = 0; + hw->start_process_time = 0; + hw->timeout_num = 0; +#endif + hw->fatal_error = 0; + hw->show_frame_num = 0; + if (pdata == NULL) { + av1_print(hw, 0, "\namvdec_av1 memory resource undefined.\n"); + vfree(hw); + mutex_unlock(&vav1_mutex); + return -EFAULT; + } + hw->m_ins_flag = 0; +#ifdef MULTI_INSTANCE_SUPPORT + hw->platform_dev = pdev; + platform_set_drvdata(pdev, pdata); +#endif + hw->double_write_mode = double_write_mode; + hw->mmu_enable = 1; +#ifdef AOM_AV1_MMU_DW + hw->dw_mmu_enable = + get_double_write_mode_init(hw) & 0x20 ? 1 : 0; +#endif + if (amvdec_av1_mmu_init(hw) < 0) { + vfree(hw); + mutex_unlock(&vav1_mutex); + pr_err("av1 alloc bmmu box failed!!\n"); + return -1; + } + + ret = decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, WORK_SPACE_BUF_ID, + work_buf_size, DRIVER_NAME, &pdata->mem_start); + if (ret < 0) { + uninit_mmu_buffers(hw); + vfree(hw); + mutex_unlock(&vav1_mutex); + return ret; + } + hw->buf_size = work_buf_size; + +#ifdef MULTI_INSTANCE_SUPPORT + hw->buf_start = pdata->mem_start; +#else + if (!hw->mmu_enable) + hw->mc_buf_spec.buf_end = pdata->mem_start + hw->buf_size; + + for (i = 0; i < WORK_BUF_SPEC_NUM; i++) + aom_workbuff_spec[i].start_adr = pdata->mem_start; +#endif + + if (debug) { + av1_print(hw, AOM_DEBUG_HW_MORE, "===AV1 decoder mem resource 0x%lx size 0x%x\n", + pdata->mem_start, hw->buf_size); + } + + if (pdata->sys_info) + hw->vav1_amstream_dec_info = *pdata->sys_info; + else { + hw->vav1_amstream_dec_info.width = 0; + hw->vav1_amstream_dec_info.height = 0; + hw->vav1_amstream_dec_info.rate = 30; + } + hw->no_head = no_head; +#ifdef MULTI_INSTANCE_SUPPORT + hw->cma_dev = pdata->cma_dev; +#else + cma_dev = pdata->cma_dev; +#endif + +#ifdef MULTI_INSTANCE_SUPPORT + pdata->private = hw; + pdata->dec_status = vav1_dec_status; + pdata->set_isreset = vav1_set_isreset; + is_reset = 0; + if (vav1_init(pdata) < 0) { +#else + if (vav1_init(hw) < 0) { +#endif + av1_print(hw, 0, "\namvdec_av1 init failed.\n"); + av1_local_uninit(hw); + uninit_mmu_buffers(hw); + vfree(hw); + pdata->dec_status = NULL; + mutex_unlock(&vav1_mutex); + return -ENODEV; + } + /*set the max clk for smooth playing...*/ + hevc_source_changed(VFORMAT_AV1, + 4096, 2048, 60); + mutex_unlock(&vav1_mutex); + + return 0; +} + +static int amvdec_av1_remove(struct platform_device *pdev) +{ + struct AV1HW_s *hw = gHevc; + struct vdec_s *vdec = hw_to_vdec(hw); + int i; + + if (debug) + av1_print(hw, AOM_DEBUG_HW_MORE, "amvdec_av1_remove\n"); + + mutex_lock(&vav1_mutex); + + vav1_stop(hw); + + hevc_source_changed(VFORMAT_AV1, 0, 0, 0); + + if (vdec->parallel_dec == 1) { + for (i = 0; i < FRAME_BUFFERS; i++) { + vdec->free_canvas_ex(hw->pbi->common.buffer_pool-> + frame_bufs[i].buf.y_canvas_index, vdec->id); + vdec->free_canvas_ex(hw->pbi->common.buffer_pool-> + frame_bufs[i].buf.uv_canvas_index, vdec->id); + } + } + +#ifdef DEBUG_PTS + pr_info("pts missed %ld, pts hit %ld, duration %d\n", + hw->pts_missed, hw->pts_hit, hw->frame_dur); +#endif + vfree(hw->pbi); + release_dblk_struct(hw); + vfree(hw); + mutex_unlock(&vav1_mutex); + + return 0; +} + +/****************************************/ +#ifdef CONFIG_PM +static int av1_suspend(struct device *dev) +{ + amhevc_suspend(to_platform_device(dev), dev->power.power_state); + return 0; +} + +static int av1_resume(struct device *dev) +{ + amhevc_resume(to_platform_device(dev)); + return 0; +} + +static const struct dev_pm_ops av1_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(av1_suspend, av1_resume) +}; +#endif + +static struct platform_driver amvdec_av1_driver = { + .probe = amvdec_av1_probe, + .remove = amvdec_av1_remove, + .driver = { + .name = DRIVER_NAME, +#ifdef CONFIG_PM + .pm = &av1_pm_ops, +#endif + } +}; + +static struct codec_profile_t amvdec_av1_profile = { +#ifdef DEBUG_USE_VP9_DEVICE_NAME + .name = "vp9", +#else + .name = "av1", +#endif + .profile = "" +}; + +static struct codec_profile_t amvdec_av1_profile_mult; + +static unsigned char get_data_check_sum + (struct AV1HW_s *hw, int size) +{ + int jj; + int sum = 0; + u8 *data = NULL; + + if (!hw->chunk->block->is_mapped) + data = codec_mm_vmap(hw->chunk->block->start + + hw->chunk->offset, size); + else + data = ((u8 *)hw->chunk->block->start_virt) + + hw->chunk->offset; + + for (jj = 0; jj < size; jj++) + sum += data[jj]; + + if (!hw->chunk->block->is_mapped) + codec_mm_unmap_phyaddr(data); + return sum; +} + +static void dump_data(struct AV1HW_s *hw, int size) +{ + int jj; + u8 *data = NULL; + int padding_size = hw->chunk->offset & + (VDEC_FIFO_ALIGN - 1); + + if (!hw->chunk->block->is_mapped) + data = codec_mm_vmap(hw->chunk->block->start + + hw->chunk->offset, size); + else + data = ((u8 *)hw->chunk->block->start_virt) + + hw->chunk->offset; + + av1_print(hw, 0, "padding: "); + for (jj = padding_size; jj > 0; jj--) + av1_print_cont(hw, + 0, + "%02x ", *(data - jj)); + av1_print_cont(hw, 0, "data adr %p\n", + data); + + for (jj = 0; jj < size; jj++) { + if ((jj & 0xf) == 0) + av1_print(hw, + 0, + "%06x:", jj); + av1_print_cont(hw, + 0, + "%02x ", data[jj]); + if (((jj + 1) & 0xf) == 0) + av1_print(hw, + 0, + "\n"); + } + av1_print(hw, + 0, + "\n"); + + if (!hw->chunk->block->is_mapped) + codec_mm_unmap_phyaddr(data); +} + +static void av1_work(struct work_struct *work) +{ + struct AV1HW_s *hw = container_of(work, + struct AV1HW_s, work); + struct vdec_s *vdec = hw_to_vdec(hw); + /* finished decoding one frame or error, + * notify vdec core to switch context + */ + av1_print(hw, PRINT_FLAG_VDEC_DETAIL, + "%s dec_result %d %x %x %x\n", + __func__, + hw->dec_result, + READ_VREG(HEVC_STREAM_LEVEL), + READ_VREG(HEVC_STREAM_WR_PTR), + READ_VREG(HEVC_STREAM_RD_PTR)); + if (((hw->dec_result == DEC_RESULT_GET_DATA) || + (hw->dec_result == DEC_RESULT_GET_DATA_RETRY)) + && (hw_to_vdec(hw)->next_status != + VDEC_STATUS_DISCONNECTED)) { + if (!vdec_has_more_input(vdec)) { + hw->dec_result = DEC_RESULT_EOS; + vdec_schedule_work(&hw->work); + return; + } + + if (hw->dec_result == DEC_RESULT_GET_DATA) { + av1_print(hw, PRINT_FLAG_VDEC_STATUS, + "%s DEC_RESULT_GET_DATA %x %x %x\n", + __func__, + READ_VREG(HEVC_STREAM_LEVEL), + READ_VREG(HEVC_STREAM_WR_PTR), + READ_VREG(HEVC_STREAM_RD_PTR)); + vdec_vframe_dirty(vdec, hw->chunk); + vdec_clean_input(vdec); + } + + if (get_free_buf_count(hw) >= + run_ready_min_buf_num) { + int r; + int decode_size; + r = vdec_prepare_input(vdec, &hw->chunk); + if (r < 0) { + hw->dec_result = DEC_RESULT_GET_DATA_RETRY; + + av1_print(hw, + PRINT_FLAG_VDEC_DETAIL, + "amvdec_vh265: Insufficient data\n"); + + vdec_schedule_work(&hw->work); + return; + } + hw->dec_result = DEC_RESULT_NONE; + av1_print(hw, PRINT_FLAG_VDEC_STATUS, + "%s: chunk size 0x%x sum 0x%x\n", + __func__, r, + (debug & PRINT_FLAG_VDEC_STATUS) ? + get_data_check_sum(hw, r) : 0 + ); + + if (debug & PRINT_FLAG_VDEC_DATA) + dump_data(hw, hw->chunk->size); + + decode_size = hw->chunk->size + + (hw->chunk->offset & (VDEC_FIFO_ALIGN - 1)); + + WRITE_VREG(HEVC_DECODE_SIZE, + READ_VREG(HEVC_DECODE_SIZE) + decode_size); + + vdec_enable_input(vdec); + + WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); + + start_process_time(hw); + + } else { + hw->dec_result = DEC_RESULT_GET_DATA_RETRY; + + av1_print(hw, PRINT_FLAG_VDEC_DETAIL, + "amvdec_vh265: Insufficient data\n"); + + vdec_schedule_work(&hw->work); + } + return; + } else if (hw->dec_result == DEC_RESULT_DONE) { + /* if (!hw->ctx_valid) + hw->ctx_valid = 1; */ + hw->result_done_count++; + hw->process_state = PROC_STATE_INIT; + + if (hw->mmu_enable) + hw->used_4k_num = + (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16); + av1_print(hw, PRINT_FLAG_VDEC_STATUS, + "%s (===> %d) dec_result %d (%d) %x %x %x shiftbytes 0x%x decbytes 0x%x\n", + __func__, + hw->frame_count, + hw->dec_result, + hw->result_done_count, + READ_VREG(HEVC_STREAM_LEVEL), + READ_VREG(HEVC_STREAM_WR_PTR), + READ_VREG(HEVC_STREAM_RD_PTR), + READ_VREG(HEVC_SHIFT_BYTE_COUNT), + READ_VREG(HEVC_SHIFT_BYTE_COUNT) - + hw->start_shift_bytes + ); + vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); + } else if (hw->dec_result == DEC_RESULT_AGAIN) { + /* + stream base: stream buf empty or timeout + frame base: vdec_prepare_input fail + */ + if (!vdec_has_more_input(vdec)) { + hw->dec_result = DEC_RESULT_EOS; + vdec_schedule_work(&hw->work); + return; + } + } else if (hw->dec_result == DEC_RESULT_EOS) { + av1_print(hw, PRINT_FLAG_VDEC_STATUS, + "%s: end of stream\n", + __func__); + hw->eos = 1; + av1_postproc(hw); + + if (hw->is_used_v4l) + notify_v4l_eos(hw_to_vdec(hw)); + + vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); + } else if (hw->dec_result == DEC_RESULT_FORCE_EXIT) { + av1_print(hw, PRINT_FLAG_VDEC_STATUS, + "%s: force exit\n", + __func__); + if (hw->stat & STAT_VDEC_RUN) { + amhevc_stop(); + hw->stat &= ~STAT_VDEC_RUN; + } + + if (hw->stat & STAT_ISR_REG) { +#ifdef MULTI_INSTANCE_SUPPORT + if (!hw->m_ins_flag) +#endif + WRITE_VREG(HEVC_ASSIST_MBOX0_MASK, 0); + vdec_free_irq(VDEC_IRQ_0, (void *)hw); + hw->stat &= ~STAT_ISR_REG; + } + } + if (hw->stat & STAT_VDEC_RUN) { + amhevc_stop(); + hw->stat &= ~STAT_VDEC_RUN; + } + + if (hw->stat & STAT_TIMER_ARM) { + del_timer_sync(&hw->timer); + hw->stat &= ~STAT_TIMER_ARM; + } + /* mark itself has all HW resource released and input released */ + if (vdec->parallel_dec == 1) + vdec_core_finish_run(vdec, CORE_MASK_HEVC); + else + vdec_core_finish_run(hw_to_vdec(hw), CORE_MASK_VDEC_1 + | CORE_MASK_HEVC); + trigger_schedule(hw); +} + +static int av1_hw_ctx_restore(struct AV1HW_s *hw) +{ + vav1_prot_init(hw, HW_MASK_FRONT | HW_MASK_BACK); + return 0; +} +static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) +{ + struct AV1HW_s *hw = + (struct AV1HW_s *)vdec->private; + int tvp = vdec_secure(hw_to_vdec(hw)) ? + CODEC_MM_FLAGS_TVP : 0; + unsigned long ret = 0; + + if (!hw->pic_list_init_done2 || hw->eos) + return ret; + if (!hw->first_sc_checked && hw->mmu_enable) { + int size = decoder_mmu_box_sc_check(hw->mmu_box, tvp); + hw->first_sc_checked = 1; + av1_print(hw, 0, "av1 cached=%d need_size=%d speed= %d ms\n", + size, (hw->need_cache_size >> PAGE_SHIFT), + (int)(get_jiffies_64() - hw->sc_start_time) * 1000/HZ); +#ifdef AOM_AV1_MMU_DW + /*!!!!!! To do ... */ + if (hw->dw_mmu_enable) { + + } +#endif + } + + if (get_free_buf_count(hw) >= + run_ready_min_buf_num) { + if (vdec->parallel_dec == 1) + ret = CORE_MASK_HEVC; + else + ret = CORE_MASK_VDEC_1 | CORE_MASK_HEVC; + } + if (ret) + not_run_ready[hw->index] = 0; + else + not_run_ready[hw->index]++; + + /*av1_print(hw, + PRINT_FLAG_VDEC_DETAIL, "%s mask %lx=>%lx\r\n", + __func__, mask, ret);*/ + return ret; +} + +static void av1_frame_mode_pts_save(struct AV1HW_s *hw) +{ + int i; + + if (hw->chunk == NULL) + return; + av1_print(hw, AV1_DEBUG_OUT_PTS, + "run front: pts %d, pts64 %lld\n", hw->chunk->pts, hw->chunk->pts64); + for (i = (FRAME_BUFFERS - 1); i > 0; i--) { + hw->frame_mode_pts_save[i] = hw->frame_mode_pts_save[i - 1]; + hw->frame_mode_pts64_save[i] = hw->frame_mode_pts64_save[i - 1]; + } + hw->frame_mode_pts_save[0] = hw->chunk->pts; + hw->frame_mode_pts64_save[0] = hw->chunk->pts64; +} + +static void run_front(struct vdec_s *vdec) +{ + struct AV1HW_s *hw = + (struct AV1HW_s *)vdec->private; + int ret, size; + + run_count[hw->index]++; + /* hw->chunk = vdec_prepare_input(vdec); */ + hevc_reset_core(vdec); + + size = vdec_prepare_input(vdec, &hw->chunk); + if (size < 0) { + input_empty[hw->index]++; + + hw->dec_result = DEC_RESULT_AGAIN; + + av1_print(hw, PRINT_FLAG_VDEC_DETAIL, + "ammvdec_av1: Insufficient data\n"); + + vdec_schedule_work(&hw->work); + return; + } + input_empty[hw->index] = 0; + hw->dec_result = DEC_RESULT_NONE; + hw->start_shift_bytes = READ_VREG(HEVC_SHIFT_BYTE_COUNT); + + av1_frame_mode_pts_save(hw); + if (debug & PRINT_FLAG_VDEC_STATUS) { + /*int ii;*/ + av1_print(hw, 0, + "%s (%d): size 0x%x (0x%x 0x%x) sum 0x%x (%x %x %x %x %x) bytes 0x%x\n", + __func__, + hw->frame_count, size, + hw->chunk ? hw->chunk->size : 0, + hw->chunk ? hw->chunk->offset : 0, + hw->chunk ? ((vdec_frame_based(vdec) && + (debug & PRINT_FLAG_VDEC_STATUS)) ? + get_data_check_sum(hw, size) : 0) : 0, + READ_VREG(HEVC_STREAM_START_ADDR), + READ_VREG(HEVC_STREAM_END_ADDR), + READ_VREG(HEVC_STREAM_LEVEL), + READ_VREG(HEVC_STREAM_WR_PTR), + READ_VREG(HEVC_STREAM_RD_PTR), + hw->start_shift_bytes); +#if 0 + if (vdec_frame_based(vdec) && hw->chunk) { + u8 *data = NULL; + + if (!hw->chunk->block->is_mapped) + data = codec_mm_vmap(hw->chunk->block->start + + hw->chunk->offset, 8); + else + data = ((u8 *)hw->chunk->block->start_virt) + + hw->chunk->offset; + + av1_print_cont(hw, 0, "data adr %p:", + data); + for (ii = 0; ii < 8; ii++) + av1_print_cont(hw, 0, "%02x ", + data[ii]); + + if (!hw->chunk->block->is_mapped) + codec_mm_unmap_phyaddr(data); + } + av1_print_cont(hw, 0, "\r\n"); +#endif + } + if (vdec->mc_loaded) { + /*firmware have load before, + and not changes to another. + ignore reload. + */ + } else { +#ifdef DEBUG_USE_VP9_DEVICE_NAME + ret = amhevc_loadmc_ex(VFORMAT_VP9, NULL, hw->fw->data); +#else + ret = amhevc_loadmc_ex(VFORMAT_AV1, NULL, hw->fw->data); +#endif + if (ret < 0) { + amhevc_disable(); + av1_print(hw, PRINT_FLAG_ERROR, + "AV1: the %s fw loading failed, err: %x\n", + tee_enabled() ? "TEE" : "local", ret); + hw->dec_result = DEC_RESULT_FORCE_EXIT; + vdec_schedule_work(&hw->work); + return; + } + vdec->mc_loaded = 1; +#ifdef DEBUG_USE_VP9_DEVICE_NAME + vdec->mc_type = VFORMAT_VP9; +#else + vdec->mc_type = VFORMAT_AV1; +#endif + } + + if (av1_hw_ctx_restore(hw) < 0) { + vdec_schedule_work(&hw->work); + return; + } + + vdec_enable_input(vdec); + + WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); + + if (vdec_frame_based(vdec)) { + if (debug & PRINT_FLAG_VDEC_DATA) + dump_data(hw, hw->chunk->size); + + WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0); + size = hw->chunk->size + + (hw->chunk->offset & (VDEC_FIFO_ALIGN - 1)); + } + hw->data_size = size; + WRITE_VREG(HEVC_DECODE_SIZE, size); + WRITE_VREG(HEVC_DECODE_COUNT, hw->result_done_count); + WRITE_VREG(LMEM_DUMP_ADR, (u32)hw->lmem_phy_addr); + if (hw->config_next_ref_info_flag) + config_next_ref_info_hw(hw); + hw->config_next_ref_info_flag = 0; + hw->init_flag = 1; + + av1_print(hw, PRINT_FLAG_VDEC_DETAIL, + "%s: start hw (%x %x %x) HEVC_DECODE_SIZE 0x%x\n", + __func__, + READ_VREG(HEVC_DEC_STATUS_REG), + READ_VREG(HEVC_MPC_E), + READ_VREG(HEVC_MPSR), + READ_VREG(HEVC_DECODE_SIZE)); + + start_process_time(hw); + mod_timer(&hw->timer, jiffies); + hw->stat |= STAT_TIMER_ARM; + hw->stat |= STAT_ISR_REG; + amhevc_start(); + hw->stat |= STAT_VDEC_RUN; +} + +static void run(struct vdec_s *vdec, unsigned long mask, + void (*callback)(struct vdec_s *, void *), void *arg) +{ + struct AV1HW_s *hw = + (struct AV1HW_s *)vdec->private; + + av1_print(hw, + PRINT_FLAG_VDEC_DETAIL, "%s mask %lx\r\n", + __func__, mask); + + run_count[hw->index]++; + hw->vdec_cb_arg = arg; + hw->vdec_cb = callback; + run_front(vdec); +} + +static void reset(struct vdec_s *vdec) +{ + + struct AV1HW_s *hw = + (struct AV1HW_s *)vdec->private; + + av1_print(hw, + PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__); + +} + +static irqreturn_t av1_irq_cb(struct vdec_s *vdec, int irq) +{ + struct AV1HW_s *hw = + (struct AV1HW_s *)vdec->private; + return vav1_isr(0, hw); +} + +static irqreturn_t av1_threaded_irq_cb(struct vdec_s *vdec, int irq) +{ + struct AV1HW_s *hw = + (struct AV1HW_s *)vdec->private; + return vav1_isr_thread_fn(0, hw); +} + +static void av1_dump_state(struct vdec_s *vdec) +{ + struct AV1HW_s *hw = + (struct AV1HW_s *)vdec->private; + struct AV1_Common_s *const cm = &hw->pbi->common; + int i; + av1_print(hw, 0, "====== %s\n", __func__); + + av1_print(hw, 0, + "width/height (%d/%d), used_buf_num %d\n", + cm->width, + cm->height, + hw->used_buf_num + ); + + av1_print(hw, 0, + "is_framebase(%d), eos %d, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d low_latency %d no_head %d \n", + input_frame_based(vdec), + hw->eos, + hw->dec_result, + decode_frame_count[hw->index], + display_frame_count[hw->index], + run_count[hw->index], + not_run_ready[hw->index], + input_empty[hw->index], + hw->low_latency_flag, + hw->no_head + ); + + if (vf_get_receiver(vdec->vf_provider_name)) { + enum receviver_start_e state = + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_QUREY_STATE, + NULL); + av1_print(hw, 0, + "\nreceiver(%s) state %d\n", + vdec->vf_provider_name, + state); + } + + av1_print(hw, 0, + "%s, newq(%d/%d), dispq(%d/%d), vf prepare/get/put (%d/%d/%d), free_buf_count %d (min %d for run_ready)\n", + __func__, + kfifo_len(&hw->newframe_q), + VF_POOL_SIZE, + kfifo_len(&hw->display_q), + VF_POOL_SIZE, + hw->vf_pre_count, + hw->vf_get_count, + hw->vf_put_count, + get_free_buf_count(hw), + run_ready_min_buf_num + ); + + dump_pic_list(hw); + + for (i = 0; i < MAX_BUF_NUM; i++) { + av1_print(hw, 0, + "mv_Buf(%d) start_adr 0x%x size 0x%x used %d\n", + i, + hw->m_mv_BUF[i].start_adr, + hw->m_mv_BUF[i].size, + hw->m_mv_BUF[i].used_flag); + } + + av1_print(hw, 0, + "HEVC_DEC_STATUS_REG=0x%x\n", + READ_VREG(HEVC_DEC_STATUS_REG)); + av1_print(hw, 0, + "HEVC_MPC_E=0x%x\n", + READ_VREG(HEVC_MPC_E)); + av1_print(hw, 0, + "DECODE_MODE=0x%x\n", + READ_VREG(DECODE_MODE)); + av1_print(hw, 0, + "NAL_SEARCH_CTL=0x%x\n", + READ_VREG(NAL_SEARCH_CTL)); + av1_print(hw, 0, + "HEVC_PARSER_LCU_START=0x%x\n", + READ_VREG(HEVC_PARSER_LCU_START)); + av1_print(hw, 0, + "HEVC_DECODE_SIZE=0x%x\n", + READ_VREG(HEVC_DECODE_SIZE)); + av1_print(hw, 0, + "HEVC_SHIFT_BYTE_COUNT=0x%x\n", + READ_VREG(HEVC_SHIFT_BYTE_COUNT)); + av1_print(hw, 0, + "HEVC_STREAM_START_ADDR=0x%x\n", + READ_VREG(HEVC_STREAM_START_ADDR)); + av1_print(hw, 0, + "HEVC_STREAM_END_ADDR=0x%x\n", + READ_VREG(HEVC_STREAM_END_ADDR)); + av1_print(hw, 0, + "HEVC_STREAM_LEVEL=0x%x\n", + READ_VREG(HEVC_STREAM_LEVEL)); + av1_print(hw, 0, + "HEVC_STREAM_WR_PTR=0x%x\n", + READ_VREG(HEVC_STREAM_WR_PTR)); + av1_print(hw, 0, + "HEVC_STREAM_RD_PTR=0x%x\n", + READ_VREG(HEVC_STREAM_RD_PTR)); + av1_print(hw, 0, + "PARSER_VIDEO_RP=0x%x\n", + READ_PARSER_REG(PARSER_VIDEO_RP)); + av1_print(hw, 0, + "PARSER_VIDEO_WP=0x%x\n", + READ_PARSER_REG(PARSER_VIDEO_WP)); + + if (input_frame_based(vdec) && + (debug & PRINT_FLAG_VDEC_DATA) + ) { + int jj; + if (hw->chunk && hw->chunk->block && + hw->chunk->size > 0) { + u8 *data = NULL; + + if (!hw->chunk->block->is_mapped) + data = codec_mm_vmap( + hw->chunk->block->start + + hw->chunk->offset, + hw->chunk->size); + else + data = ((u8 *)hw->chunk->block->start_virt) + + hw->chunk->offset; + av1_print(hw, 0, + "frame data size 0x%x\n", + hw->chunk->size); + for (jj = 0; jj < hw->chunk->size; jj++) { + if ((jj & 0xf) == 0) + av1_print(hw, 0, + "%06x:", jj); + av1_print_cont(hw, 0, + "%02x ", data[jj]); + if (((jj + 1) & 0xf) == 0) + av1_print_cont(hw, 0, + "\n"); + } + + if (!hw->chunk->block->is_mapped) + codec_mm_unmap_phyaddr(data); + } + } + +} + +static int ammvdec_av1_probe(struct platform_device *pdev) +{ + struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; + int ret; + int config_val; + struct vframe_content_light_level_s content_light_level; + struct vframe_master_display_colour_s vf_dp; + + struct BUF_s BUF[MAX_BUF_NUM]; + struct AV1HW_s *hw = NULL; + pr_debug("%s\n", __func__); + + if (pdata == NULL) { + av1_print(hw, 0, "\nammvdec_av1 memory resource undefined.\n"); + return -EFAULT; + } + /*hw = (struct AV1HW_s *)devm_kzalloc(&pdev->dev, + sizeof(struct AV1HW_s), GFP_KERNEL);*/ + memset(&vf_dp, 0, sizeof(struct vframe_master_display_colour_s)); + hw = vmalloc(sizeof(struct AV1HW_s)); + if (hw == NULL) { + av1_print(hw, 0, "\nammvdec_av1 device data allocation failed\n"); + return -ENOMEM; + } + memset(hw, 0, sizeof(struct AV1HW_s)); + + if (init_dblk_struc(hw) < 0) { + av1_print(hw, 0, "\nammvdec_av1 device data allocation failed\n"); + vfree(hw); + return -ENOMEM; + } + + hw->pbi = av1_decoder_create(&hw->av1_buffer_pool); //&aom_decoder; + if (hw->pbi == NULL) { + av1_print(hw, 0, "\nammvdec_av1 device data allocation failed\n"); + release_dblk_struct(hw); + vfree(hw); + return -ENOMEM; + } + hw->pbi->private_data = hw; + /* the ctx from v4l2 driver. */ + hw->v4l2_ctx = pdata->private; + + pdata->private = hw; + pdata->dec_status = vav1_dec_status; + /* pdata->set_trickmode = set_trickmode; */ + pdata->run_ready = run_ready; + pdata->run = run; + pdata->reset = reset; + pdata->irq_handler = av1_irq_cb; + pdata->threaded_irq_handler = av1_threaded_irq_cb; + pdata->dump_state = av1_dump_state; + + memcpy(&BUF[0], &hw->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM); + memcpy(&hw->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM); + + hw->index = pdev->id; + + if (pdata->use_vfm_path) + snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, + VFM_DEC_PROVIDER_NAME); +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + else if (vdec_dual(pdata)) { + struct AV1HW_s *hevc_pair = NULL; + + if (dv_toggle_prov_name) /*debug purpose*/ + snprintf(pdata->vf_provider_name, + VDEC_PROVIDER_NAME_SIZE, + (pdata->master) ? VFM_DEC_DVBL_PROVIDER_NAME : + VFM_DEC_DVEL_PROVIDER_NAME); + else + snprintf(pdata->vf_provider_name, + VDEC_PROVIDER_NAME_SIZE, + (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME : + VFM_DEC_DVBL_PROVIDER_NAME); + if (pdata->master) + hevc_pair = (struct AV1HW_s *)pdata->master->private; + else if (pdata->slave) + hevc_pair = (struct AV1HW_s *)pdata->slave->private; + + if (hevc_pair) + hw->shift_byte_count_lo = hevc_pair->shift_byte_count_lo; + } +#endif + else + snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, + MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff); + + vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, + &vav1_vf_provider, hw); + + hw->provider_name = pdata->vf_provider_name; + platform_set_drvdata(pdev, pdata); + + hw->platform_dev = pdev; + hw->video_signal_type = 0; + hw->m_ins_flag = 1; + + if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TXLX) + hw->stat |= AV1_TRIGGER_FRAME_ENABLE; + + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { + hw->max_pic_w = 8192; + hw->max_pic_h = 4608; + } else { + hw->max_pic_w = 4096; + hw->max_pic_h = 2304; + } +#if 1 + if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 && + pdata->config_len) { +#ifdef MULTI_INSTANCE_SUPPORT + int av1_buf_width = 0; + int av1_buf_height = 0; + /*use ptr config for doubel_write_mode, etc*/ + av1_print(hw, 0, "pdata->config=%s\n", pdata->config); + if (get_config_int(pdata->config, "av1_double_write_mode", + &config_val) == 0) + hw->double_write_mode = config_val; + else + hw->double_write_mode = double_write_mode; + + if (get_config_int(pdata->config, "save_buffer_mode", + &config_val) == 0) + hw->save_buffer_mode = config_val; + else + hw->save_buffer_mode = 0; + if (get_config_int(pdata->config, "av1_buf_width", + &config_val) == 0) { + av1_buf_width = config_val; + } + if (get_config_int(pdata->config, "av1_buf_height", + &config_val) == 0) { + av1_buf_height = config_val; + } + + if (get_config_int(pdata->config, "no_head", + &config_val) == 0) + hw->no_head = config_val; + else + hw->no_head = no_head; + + /*use ptr config for max_pic_w, etc*/ + if (get_config_int(pdata->config, "av1_max_pic_w", + &config_val) == 0) { + hw->max_pic_w = config_val; + } + if (get_config_int(pdata->config, "av1_max_pic_h", + &config_val) == 0) { + hw->max_pic_h = config_val; + } + if ((hw->max_pic_w * hw->max_pic_h) + < (av1_buf_width * av1_buf_height)) { + hw->max_pic_w = av1_buf_width; + hw->max_pic_h = av1_buf_height; + av1_print(hw, 0, "use buf resolution\n"); + } +#endif + if (get_config_int(pdata->config, "HDRStaticInfo", + &vf_dp.present_flag) == 0 + && vf_dp.present_flag == 1) { + get_config_int(pdata->config, "mG.x", + &vf_dp.primaries[0][0]); + get_config_int(pdata->config, "mG.y", + &vf_dp.primaries[0][1]); + get_config_int(pdata->config, "mB.x", + &vf_dp.primaries[1][0]); + get_config_int(pdata->config, "mB.y", + &vf_dp.primaries[1][1]); + get_config_int(pdata->config, "mR.x", + &vf_dp.primaries[2][0]); + get_config_int(pdata->config, "mR.y", + &vf_dp.primaries[2][1]); + get_config_int(pdata->config, "mW.x", + &vf_dp.white_point[0]); + get_config_int(pdata->config, "mW.y", + &vf_dp.white_point[1]); + get_config_int(pdata->config, "mMaxDL", + &vf_dp.luminance[0]); + get_config_int(pdata->config, "mMinDL", + &vf_dp.luminance[1]); + vf_dp.content_light_level.present_flag = 1; + get_config_int(pdata->config, "mMaxCLL", + &content_light_level.max_content); + get_config_int(pdata->config, "mMaxFALL", + &content_light_level.max_pic_average); + vf_dp.content_light_level = content_light_level; + hw->video_signal_type = (1 << 29) + | (5 << 26) /* unspecified */ + | (0 << 25) /* limit */ + | (1 << 24) /* color available */ + | (9 << 16) /* 2020 */ + | (16 << 8) /* 2084 */ + | (9 << 0); /* 2020 */ + } + hw->vf_dp = vf_dp; + } else +#endif + { + /*hw->vav1_amstream_dec_info.width = 0; + hw->vav1_amstream_dec_info.height = 0; + hw->vav1_amstream_dec_info.rate = 30;*/ + hw->double_write_mode = double_write_mode; + } + if (is_oversize(hw->max_pic_w, hw->max_pic_h)) { + pr_err("over size: %dx%d, probe failed\n", + hw->max_pic_w, hw->max_pic_h); + return -1; + } + hw->mmu_enable = 1; + video_signal_type = hw->video_signal_type; + + if (pdata->sys_info) { + hw->vav1_amstream_dec_info = *pdata->sys_info; + if ((unsigned long) hw->vav1_amstream_dec_info.param + & 0x08) { + hw->low_latency_flag = 1; + } else + hw->low_latency_flag = 0; + } else { + hw->vav1_amstream_dec_info.width = 0; + hw->vav1_amstream_dec_info.height = 0; + hw->vav1_amstream_dec_info.rate = 30; + } + + hw->is_used_v4l = (((unsigned long) + hw->vav1_amstream_dec_info.param & 0x80) >> 7); + if (hw->is_used_v4l) { + hw->double_write_mode = 0x10; + hw->mmu_enable = 0; + hw->max_pic_w = 1920; + hw->max_pic_h = 1080; + } +#ifdef AOM_AV1_MMU_DW + hw->dw_mmu_enable = + get_double_write_mode_init(hw) & 0x20 ? 1 : 0; + +#endif + av1_print(hw, 0, + "no_head %d low_latency %d\n", + hw->no_head, hw->low_latency_flag); +#if 0 + hw->buf_start = pdata->mem_start; + hw->buf_size = pdata->mem_end - pdata->mem_start + 1; +#else + if (amvdec_av1_mmu_init(hw) < 0) { + pr_err("av1 alloc bmmu box failed!!\n"); + /* devm_kfree(&pdev->dev, (void *)hw); */ + vfree((void *)hw); + pdata->dec_status = NULL; + return -1; + } + + hw->cma_alloc_count = PAGE_ALIGN(work_buf_size) / PAGE_SIZE; + ret = decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, WORK_SPACE_BUF_ID, + hw->cma_alloc_count * PAGE_SIZE, DRIVER_NAME, + &hw->cma_alloc_addr); + if (ret < 0) { + uninit_mmu_buffers(hw); + /* devm_kfree(&pdev->dev, (void *)hw); */ + vfree((void *)hw); + pdata->dec_status = NULL; + return ret; + } + hw->buf_start = hw->cma_alloc_addr; + hw->buf_size = work_buf_size; +#endif + + hw->init_flag = 0; + hw->first_sc_checked = 0; + hw->fatal_error = 0; + hw->show_frame_num = 0; + + if (debug) { + av1_print(hw, AOM_DEBUG_HW_MORE, "===AV1 decoder mem resource 0x%lx size 0x%x\n", + hw->buf_start, + hw->buf_size); + } + + hw->cma_dev = pdata->cma_dev; + if (vav1_init(pdata) < 0) { + av1_print(hw, 0, "\namvdec_av1 init failed.\n"); + av1_local_uninit(hw); + uninit_mmu_buffers(hw); + /* devm_kfree(&pdev->dev, (void *)hw); */ + vfree((void *)hw); + pdata->dec_status = NULL; + return -ENODEV; + } + vdec_set_prepare_level(pdata, start_decode_buf_level); + hevc_source_changed(VFORMAT_AV1, + 4096, 2048, 60); + + if (pdata->parallel_dec == 1) + vdec_core_request(pdata, CORE_MASK_HEVC); + else + vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC + | CORE_MASK_COMBINE); + + hw->pic_list_init_done2 = true; + return 0; +} + +static int ammvdec_av1_remove(struct platform_device *pdev) +{ + struct AV1HW_s *hw = (struct AV1HW_s *) + (((struct vdec_s *)(platform_get_drvdata(pdev)))->private); + struct vdec_s *vdec = hw_to_vdec(hw); + int i; + if (debug) + av1_print(hw, AOM_DEBUG_HW_MORE, "amvdec_av1_remove\n"); + + vmav1_stop(hw); + + if (vdec->parallel_dec == 1) + vdec_core_release(hw_to_vdec(hw), CORE_MASK_HEVC); + else + vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC); + + vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED); + + if (vdec->parallel_dec == 1) { + for (i = 0; i < FRAME_BUFFERS; i++) { + vdec->free_canvas_ex + (hw->pbi->common.buffer_pool->frame_bufs[i].buf.y_canvas_index, + vdec->id); + vdec->free_canvas_ex + (hw->pbi->common.buffer_pool->frame_bufs[i].buf.uv_canvas_index, + vdec->id); + } + } + + +#ifdef DEBUG_PTS + pr_info("pts missed %ld, pts hit %ld, duration %d\n", + hw->pts_missed, hw->pts_hit, hw->frame_dur); +#endif + /* devm_kfree(&pdev->dev, (void *)hw); */ + vfree(hw->pbi); + release_dblk_struct(hw); + vfree((void *)hw); + return 0; +} + +static struct platform_driver ammvdec_av1_driver = { + .probe = ammvdec_av1_probe, + .remove = ammvdec_av1_remove, + .driver = { + .name = MULTI_DRIVER_NAME, +#ifdef CONFIG_PM + .pm = &av1_pm_ops, +#endif + } +}; +#endif +static struct mconfig av1_configs[] = { + MC_PU32("bit_depth_luma", &bit_depth_luma), + MC_PU32("bit_depth_chroma", &bit_depth_chroma), + MC_PU32("frame_width", &frame_width), + MC_PU32("frame_height", &frame_height), + MC_PU32("debug", &debug), + MC_PU32("radr", &radr), + MC_PU32("rval", &rval), + MC_PU32("pop_shorts", &pop_shorts), + MC_PU32("dbg_cmd", &dbg_cmd), + MC_PU32("dbg_skip_decode_index", &dbg_skip_decode_index), + MC_PU32("endian", &endian), + MC_PU32("step", &step), + MC_PU32("udebug_flag", &udebug_flag), + MC_PU32("decode_pic_begin", &decode_pic_begin), + MC_PU32("slice_parse_begin", &slice_parse_begin), + MC_PU32("i_only_flag", &i_only_flag), + MC_PU32("error_handle_policy", &error_handle_policy), + MC_PU32("buf_alloc_width", &buf_alloc_width), + MC_PU32("buf_alloc_height", &buf_alloc_height), + MC_PU32("buf_alloc_depth", &buf_alloc_depth), + MC_PU32("buf_alloc_size", &buf_alloc_size), + MC_PU32("buffer_mode", &buffer_mode), + MC_PU32("buffer_mode_dbg", &buffer_mode_dbg), + MC_PU32("max_buf_num", &max_buf_num), + MC_PU32("dynamic_buf_num_margin", &dynamic_buf_num_margin), + MC_PU32("mem_map_mode", &mem_map_mode), + MC_PU32("double_write_mode", &double_write_mode), + MC_PU32("enable_mem_saving", &enable_mem_saving), + MC_PU32("force_w_h", &force_w_h), + MC_PU32("force_fps", &force_fps), + MC_PU32("max_decoding_time", &max_decoding_time), + MC_PU32("on_no_keyframe_skiped", &on_no_keyframe_skiped), + MC_PU32("start_decode_buf_level", &start_decode_buf_level), + MC_PU32("decode_timeout_val", &decode_timeout_val), + MC_PU32("av1_max_pic_w", &av1_max_pic_w), + MC_PU32("av1_max_pic_h", &av1_max_pic_h), +}; +static struct mconfig_node av1_node; + +static int __init amvdec_av1_driver_init_module(void) +{ + + struct BuffInfo_s *p_buf_info; +#ifdef BUFMGR_ONLY_OLD_CHIP + debug |= AOM_DEBUG_BUFMGR_ONLY; +#endif + + if (vdec_is_support_4k()) { + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) + p_buf_info = &aom_workbuff_spec[1]; + else + p_buf_info = &aom_workbuff_spec[1]; + } else + p_buf_info = &aom_workbuff_spec[0]; + + init_buff_spec(NULL, p_buf_info); + work_buf_size = + (p_buf_info->end_adr - p_buf_info->start_adr + + 0xffff) & (~0xffff); + + pr_debug("amvdec_av1 module init\n"); + + error_handle_policy = 0; + +#ifdef ERROR_HANDLE_DEBUG + dbg_nal_skip_flag = 0; + dbg_nal_skip_count = 0; +#endif + udebug_flag = 0; + decode_pic_begin = 0; + slice_parse_begin = 0; + step = 0; + buf_alloc_size = 0; +#ifdef MULTI_INSTANCE_SUPPORT + if (platform_driver_register(&ammvdec_av1_driver)) + pr_err("failed to register ammvdec_av1 driver\n"); + +#endif + if (platform_driver_register(&amvdec_av1_driver)) { + pr_err("failed to register amvdec_av1 driver\n"); + return -ENODEV; + } + + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_TM2) { + amvdec_av1_profile.profile = + "4k, 10bit, dwrite, compressed, no_head"; + } else { + amvdec_av1_profile.name = "av1_unsupport"; + } + + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) + max_buf_num = MAX_BUF_NUM_LESS; + + vcodec_profile_register(&amvdec_av1_profile); + amvdec_av1_profile_mult = amvdec_av1_profile; +#ifdef DEBUG_USE_VP9_DEVICE_NAME + + amvdec_av1_profile_mult.name = "mvp9"; + vcodec_profile_register(&amvdec_av1_profile_mult); + INIT_REG_NODE_CONFIGS("media.decoder", &av1_node, + "vp9", av1_configs, CONFIG_FOR_RW); + +#else + amvdec_av1_profile_mult.name = "mav1"; + vcodec_profile_register(&amvdec_av1_profile_mult); + INIT_REG_NODE_CONFIGS("media.decoder", &av1_node, + "av1", av1_configs, CONFIG_FOR_RW); +#endif + + return 0; +} + +static void __exit amvdec_av1_driver_remove_module(void) +{ + pr_debug("amvdec_av1 module remove.\n"); +#ifdef MULTI_INSTANCE_SUPPORT + platform_driver_unregister(&ammvdec_av1_driver); +#endif + platform_driver_unregister(&amvdec_av1_driver); +} + +/****************************************/ +module_param(force_dv_enable, uint, 0664); +MODULE_PARM_DESC(force_dv_enable, "\n amvdec_av1 force_dv_enable\n"); + +module_param(bit_depth_luma, uint, 0664); +MODULE_PARM_DESC(bit_depth_luma, "\n amvdec_av1 bit_depth_luma\n"); + +module_param(bit_depth_chroma, uint, 0664); +MODULE_PARM_DESC(bit_depth_chroma, "\n amvdec_av1 bit_depth_chroma\n"); + +module_param(frame_width, uint, 0664); +MODULE_PARM_DESC(frame_width, "\n amvdec_av1 frame_width\n"); + +module_param(frame_height, uint, 0664); +MODULE_PARM_DESC(frame_height, "\n amvdec_av1 frame_height\n"); + +module_param(multi_frames_in_one_pack, uint, 0664); +MODULE_PARM_DESC(multi_frames_in_one_pack, "\n multi_frames_in_one_pack\n"); + +module_param(debug, uint, 0664); +MODULE_PARM_DESC(debug, "\n amvdec_av1 debug\n"); + +module_param(radr, uint, 0664); +MODULE_PARM_DESC(radr, "\n radr\n"); + +module_param(rval, uint, 0664); +MODULE_PARM_DESC(rval, "\n rval\n"); + +module_param(pop_shorts, uint, 0664); +MODULE_PARM_DESC(pop_shorts, "\n rval\n"); + +module_param(dbg_cmd, uint, 0664); +MODULE_PARM_DESC(dbg_cmd, "\n dbg_cmd\n"); + +module_param(dbg_skip_decode_index, uint, 0664); +MODULE_PARM_DESC(dbg_skip_decode_index, "\n dbg_skip_decode_index\n"); + +module_param(endian, uint, 0664); +MODULE_PARM_DESC(endian, "\n rval\n"); + +module_param(step, uint, 0664); +MODULE_PARM_DESC(step, "\n amvdec_av1 step\n"); + +module_param(decode_pic_begin, uint, 0664); +MODULE_PARM_DESC(decode_pic_begin, "\n amvdec_av1 decode_pic_begin\n"); + +module_param(slice_parse_begin, uint, 0664); +MODULE_PARM_DESC(slice_parse_begin, "\n amvdec_av1 slice_parse_begin\n"); + +module_param(i_only_flag, uint, 0664); +MODULE_PARM_DESC(i_only_flag, "\n amvdec_av1 i_only_flag\n"); + +module_param(low_latency_flag, uint, 0664); +MODULE_PARM_DESC(low_latency_flag, "\n amvdec_av1 low_latency_flag\n"); + +module_param(no_head, uint, 0664); +MODULE_PARM_DESC(no_head, "\n amvdec_av1 no_head\n"); + +module_param(error_handle_policy, uint, 0664); +MODULE_PARM_DESC(error_handle_policy, "\n amvdec_av1 error_handle_policy\n"); + +module_param(buf_alloc_width, uint, 0664); +MODULE_PARM_DESC(buf_alloc_width, "\n buf_alloc_width\n"); + +module_param(buf_alloc_height, uint, 0664); +MODULE_PARM_DESC(buf_alloc_height, "\n buf_alloc_height\n"); + +module_param(buf_alloc_depth, uint, 0664); +MODULE_PARM_DESC(buf_alloc_depth, "\n buf_alloc_depth\n"); + +module_param(buf_alloc_size, uint, 0664); +MODULE_PARM_DESC(buf_alloc_size, "\n buf_alloc_size\n"); + +module_param(buffer_mode, uint, 0664); +MODULE_PARM_DESC(buffer_mode, "\n buffer_mode\n"); + +module_param(buffer_mode_dbg, uint, 0664); +MODULE_PARM_DESC(buffer_mode_dbg, "\n buffer_mode_dbg\n"); +/*USE_BUF_BLOCK*/ +module_param(max_buf_num, uint, 0664); +MODULE_PARM_DESC(max_buf_num, "\n max_buf_num\n"); + +module_param(dynamic_buf_num_margin, uint, 0664); +MODULE_PARM_DESC(dynamic_buf_num_margin, "\n dynamic_buf_num_margin\n"); + +module_param(mv_buf_margin, uint, 0664); +MODULE_PARM_DESC(mv_buf_margin, "\n mv_buf_margin\n"); + +module_param(run_ready_min_buf_num, uint, 0664); +MODULE_PARM_DESC(run_ready_min_buf_num, "\n run_ready_min_buf_num\n"); + +/**/ + +module_param(mem_map_mode, uint, 0664); +MODULE_PARM_DESC(mem_map_mode, "\n mem_map_mode\n"); + +#ifdef SUPPORT_10BIT +module_param(double_write_mode, uint, 0664); +MODULE_PARM_DESC(double_write_mode, "\n double_write_mode\n"); + +module_param(enable_mem_saving, uint, 0664); +MODULE_PARM_DESC(enable_mem_saving, "\n enable_mem_saving\n"); + +module_param(force_w_h, uint, 0664); +MODULE_PARM_DESC(force_w_h, "\n force_w_h\n"); +#endif + +module_param(force_fps, uint, 0664); +MODULE_PARM_DESC(force_fps, "\n force_fps\n"); + +module_param(max_decoding_time, uint, 0664); +MODULE_PARM_DESC(max_decoding_time, "\n max_decoding_time\n"); + +module_param(on_no_keyframe_skiped, uint, 0664); +MODULE_PARM_DESC(on_no_keyframe_skiped, "\n on_no_keyframe_skiped\n"); + +#ifdef MCRCC_ENABLE +module_param(mcrcc_cache_alg_flag, uint, 0664); +MODULE_PARM_DESC(mcrcc_cache_alg_flag, "\n mcrcc_cache_alg_flag\n"); +#endif + +#ifdef MULTI_INSTANCE_SUPPORT +module_param(start_decode_buf_level, int, 0664); +MODULE_PARM_DESC(start_decode_buf_level, + "\n av1 start_decode_buf_level\n"); + +module_param(decode_timeout_val, uint, 0664); +MODULE_PARM_DESC(decode_timeout_val, + "\n av1 decode_timeout_val\n"); + +module_param(av1_max_pic_w, uint, 0664); +MODULE_PARM_DESC(av1_max_pic_w, "\n av1_max_pic_w\n"); + +module_param(av1_max_pic_h, uint, 0664); +MODULE_PARM_DESC(av1_max_pic_h, "\n av1_max_pic_h\n"); + +module_param_array(decode_frame_count, uint, + &max_decode_instance_num, 0664); + +module_param_array(display_frame_count, uint, + &max_decode_instance_num, 0664); + +module_param_array(max_process_time, uint, + &max_decode_instance_num, 0664); + +module_param_array(run_count, uint, + &max_decode_instance_num, 0664); + +module_param_array(input_empty, uint, + &max_decode_instance_num, 0664); + +module_param_array(not_run_ready, uint, + &max_decode_instance_num, 0664); + +#ifdef AOM_AV1_MMU_DW +module_param_array(dw_mmu_enable, uint, + &max_decode_instance_num, 0664); +#endif + +module_param(prefix_aux_buf_size, uint, 0664); +MODULE_PARM_DESC(prefix_aux_buf_size, "\n prefix_aux_buf_size\n"); + +module_param(suffix_aux_buf_size, uint, 0664); +MODULE_PARM_DESC(suffix_aux_buf_size, "\n suffix_aux_buf_size\n"); + +#endif + +#ifdef DUMP_FILMGRAIN +module_param(fg_dump_index, uint, 0664); +MODULE_PARM_DESC(fg_dump_index, "\n fg_dump_index\n"); +#endif + +module_param(get_picture_qos, uint, 0664); +MODULE_PARM_DESC(get_picture_qos, "\n amvdec_av1 get_picture_qos\n"); + +module_param(udebug_flag, uint, 0664); +MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 udebug_flag\n"); + +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION +module_param(dv_toggle_prov_name, uint, 0664); +MODULE_PARM_DESC(dv_toggle_prov_name, "\n dv_toggle_prov_name\n"); +#endif + +module_param(udebug_pause_pos, uint, 0664); +MODULE_PARM_DESC(udebug_pause_pos, "\n udebug_pause_pos\n"); + +module_param(udebug_pause_val, uint, 0664); +MODULE_PARM_DESC(udebug_pause_val, "\n udebug_pause_val\n"); + +module_param(udebug_pause_decode_idx, uint, 0664); +MODULE_PARM_DESC(udebug_pause_decode_idx, "\n udebug_pause_decode_idx\n"); + +module_param(force_pts_unstable, uint, 0664); +MODULE_PARM_DESC(force_pts_unstable, "\n force_pts_unstable\n"); + +module_param(without_display_mode, uint, 0664); +MODULE_PARM_DESC(without_display_mode, "\n without_display_mode\n"); + +module_init(amvdec_av1_driver_init_module); +module_exit(amvdec_av1_driver_remove_module); + +MODULE_DESCRIPTION("AMLOGIC av1 Video Decoder Driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/frame_provider/decoder/vav1/vav1.h b/drivers/frame_provider/decoder/vav1/vav1.h new file mode 100644 index 0000000..0f2b765 --- a/dev/null +++ b/drivers/frame_provider/decoder/vav1/vav1.h @@ -0,0 +1,22 @@ +/* + * drivers/amlogic/amports/vav1.h + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + */ + +#ifndef VAV1_H +#define VAV1_H +void adapt_coef_probs(int pic_count, int prev_kf, int cur_kf, int pre_fc, +unsigned int *prev_prob, unsigned int *cur_prob, unsigned int *count); +#endif diff --git a/drivers/frame_provider/decoder/vc1/vvc1.c b/drivers/frame_provider/decoder/vc1/vvc1.c index 1616893..3904fd5 100644 --- a/drivers/frame_provider/decoder/vc1/vvc1.c +++ b/drivers/frame_provider/decoder/vc1/vvc1.c @@ -101,7 +101,7 @@ static int vvc1_vf_states(struct vframe_states *states, void *); static int vvc1_event_cb(int type, void *data, void *private_data); static int vvc1_prot_init(void); -static void vvc1_local_init(void); +static void vvc1_local_init(bool is_reset); static const char vvc1_dec_id[] = "vvc1-dev"; @@ -496,7 +496,6 @@ static irqreturn_t vvc1_isr(int irq, void *dev_id) decoder_bmmu_box_get_mem_handle( mm_blk_handle, buffer_index); - kfifo_put(&display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); @@ -556,7 +555,6 @@ static irqreturn_t vvc1_isr(int irq, void *dev_id) decoder_bmmu_box_get_mem_handle( mm_blk_handle, buffer_index); - kfifo_put(&display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); @@ -642,6 +640,7 @@ static irqreturn_t vvc1_isr(int irq, void *dev_id) decoder_bmmu_box_get_mem_handle( mm_blk_handle, buffer_index); + kfifo_put(&display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); @@ -719,7 +718,7 @@ static int vvc1_event_cb(int type, void *data, void *private_data) vf_light_unreg_provider(&vvc1_vf_prov); #endif spin_lock_irqsave(&lock, flags); - vvc1_local_init(); + vvc1_local_init(true); vvc1_prot_init(); spin_unlock_irqrestore(&lock, flags); #ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER @@ -920,7 +919,7 @@ static int vvc1_prot_init(void) return r; } -static void vvc1_local_init(void) +static void vvc1_local_init(bool is_reset) { int i; @@ -942,25 +941,28 @@ static void vvc1_local_init(void) memset(&frm, 0, sizeof(frm)); - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) - vfbuf_use[i] = 0; + if (!is_reset) { + for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) + vfbuf_use[i] = 0; - INIT_KFIFO(display_q); - INIT_KFIFO(recycle_q); - INIT_KFIFO(newframe_q); - cur_pool_idx ^= 1; - for (i = 0; i < VF_POOL_SIZE; i++) { - const struct vframe_s *vf; + INIT_KFIFO(display_q); + INIT_KFIFO(recycle_q); + INIT_KFIFO(newframe_q); + cur_pool_idx ^= 1; + for (i = 0; i < VF_POOL_SIZE; i++) { + const struct vframe_s *vf; - if (cur_pool_idx == 0) { - vf = &vfpool[i]; - vfpool[i].index = DECODE_BUFFER_NUM_MAX; + if (cur_pool_idx == 0) { + vf = &vfpool[i]; + vfpool[i].index = DECODE_BUFFER_NUM_MAX; } else { - vf = &vfpool2[i]; - vfpool2[i].index = DECODE_BUFFER_NUM_MAX; + vf = &vfpool2[i]; + vfpool2[i].index = DECODE_BUFFER_NUM_MAX; } - kfifo_put(&newframe_q, (const struct vframe_s *)vf); + kfifo_put(&newframe_q, (const struct vframe_s *)vf); + } } + if (mm_blk_handle) { decoder_bmmu_box_free(mm_blk_handle); mm_blk_handle = NULL; @@ -980,7 +982,7 @@ static void vvc1_ppmgr_reset(void) { vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); - vvc1_local_init(); + vvc1_local_init(true); /* vf_notify_receiver(PROVIDER_NAME, * VFRAME_EVENT_PROVIDER_START,NULL); @@ -1008,7 +1010,7 @@ static void error_do_work(struct work_struct *work) vvc1_ppmgr_reset(); #else vf_light_unreg_provider(&vvc1_vf_prov); - vvc1_local_init(); + vvc1_local_init(true); vf_reg_provider(&vvc1_vf_prov); #endif vvc1_prot_init(); @@ -1062,7 +1064,7 @@ static s32 vvc1_init(void) intra_output = 0; amvdec_enable(); - vvc1_local_init(); + vvc1_local_init(false); if (vvc1_amstream_dec_info.format == VIDEO_DEC_FORMAT_WMV3) { pr_info("WMV3 dec format\n"); diff --git a/drivers/frame_provider/decoder/vp9/vvp9.c b/drivers/frame_provider/decoder/vp9/vvp9.c index 6db0aa3..7a8df62 100644 --- a/drivers/frame_provider/decoder/vp9/vvp9.c +++ b/drivers/frame_provider/decoder/vp9/vvp9.c @@ -295,6 +295,8 @@ struct BUF_s { ulong header_addr; u32 header_size; u32 luma_size; + ulong chroma_addr; + u32 chroma_size; } /*BUF_t */; struct MVBUF_s { @@ -582,6 +584,8 @@ struct PIC_BUFFER_CONFIG_s { int min_mv; int avg_mv; + u32 hw_decode_time; + u32 frame_size2; // For frame base mode bool vframe_bound; } PIC_BUFFER_CONFIG; @@ -994,6 +998,7 @@ struct VP9Decoder_s { struct vframe_chunk_s *chunk; int dec_result; struct work_struct work; + struct work_struct recycle_mmu_work; struct work_struct set_clk_work; u32 start_shift_bytes; @@ -1191,6 +1196,9 @@ struct VP9Decoder_s { u32 mem_map_mode; u32 dynamic_buf_num_margin; struct vframe_s vframe_dummy; + unsigned int res_ch_flag; + /*struct VP9Decoder_s vp9_decoder;*/ + union param_u vp9_param; }; static int vp9_print(struct VP9Decoder_s *pbi, @@ -1589,6 +1597,41 @@ static u32 get_valid_double_write_mode(struct VP9Decoder_s *pbi) (double_write_mode & 0x7fffffff); } +static int v4l_parser_get_double_write_mode(struct VP9Decoder_s *pbi) +{ + u32 valid_dw_mode = get_valid_double_write_mode(pbi); + u32 dw; + int w, h; + + /* mask for supporting double write value bigger than 0x100 */ + if (valid_dw_mode & 0xffffff00) { + w = pbi->frame_width; + h = pbi->frame_height; + + dw = 0x1; /*1:1*/ + switch (valid_dw_mode) { + case 0x100: + if (w > 1920 && h > 1088) + dw = 0x4; /*1:2*/ + break; + case 0x200: + if (w > 1920 && h > 1088) + dw = 0x2; /*1:4*/ + break; + case 0x300: + if (w > 1280 && h > 720) + dw = 0x4; /*1:2*/ + break; + default: + break; + } + return dw; + } + + return valid_dw_mode; +} + + static int get_double_write_mode(struct VP9Decoder_s *pbi) { u32 valid_dw_mode = get_valid_double_write_mode(pbi); @@ -1687,7 +1730,7 @@ int vp9_alloc_mmu( pr_err("error no mmu box!\n"); return -1; } - if (pbi->double_write_mode & 0x10) + if (get_double_write_mode(pbi) == 0x10) return 0; if (bit_depth >= VPX_BITS_12) { pbi->fatal_error = DECODER_FATAL_ERROR_SIZE_OVERFLOW; @@ -2832,9 +2875,6 @@ int vp9_bufmgr_postproc(struct VP9Decoder_s *pbi) return 0; } -/*struct VP9Decoder_s vp9_decoder;*/ -union param_u vp9_param; - /************************************************** * *VP9 buffer management end @@ -4779,6 +4819,9 @@ static int v4l_alloc_and_config_pic(struct VP9Decoder_s *pbi, #endif struct vdec_v4l2_buffer *fb = NULL; + if (i < 0) + return ret; + ret = vdec_v4l_get_buffer(pbi->v4l2_ctx, &fb); if (ret < 0) { vp9_print(pbi, 0, "[%d] VP9 get buffer fail.\n", @@ -4804,15 +4847,20 @@ static int v4l_alloc_and_config_pic(struct VP9Decoder_s *pbi, pic->cma_alloc_addr = fb->m.mem[0].addr; if (fb->num_planes == 1) { pbi->m_BUF[i].start_adr = fb->m.mem[0].addr; - pbi->m_BUF[i].size = fb->m.mem[0].size; pbi->m_BUF[i].luma_size = fb->m.mem[0].offset; + pbi->m_BUF[i].size = fb->m.mem[0].size; fb->m.mem[0].bytes_used = fb->m.mem[0].size; + pic->dw_y_adr = pbi->m_BUF[i].start_adr; + pic->dw_u_v_adr = pic->dw_y_adr + pbi->m_BUF[i].luma_size; } else if (fb->num_planes == 2) { pbi->m_BUF[i].start_adr = fb->m.mem[0].addr; - pbi->m_BUF[i].size = fb->m.mem[0].size + fb->m.mem[1].size; - pbi->m_BUF[i].luma_size = fb->m.mem[0].size; + pbi->m_BUF[i].size = fb->m.mem[0].size; + pbi->m_BUF[i].chroma_addr = fb->m.mem[1].addr; + pbi->m_BUF[i].chroma_size = fb->m.mem[1].size; fb->m.mem[0].bytes_used = fb->m.mem[0].size; fb->m.mem[1].bytes_used = fb->m.mem[1].size; + pic->dw_y_adr = pbi->m_BUF[i].start_adr; + pic->dw_u_v_adr = pbi->m_BUF[i].chroma_addr; } /* config frame buffer */ @@ -4825,13 +4873,8 @@ static int v4l_alloc_and_config_pic(struct VP9Decoder_s *pbi, pic->mc_canvas_u_v = pic->index; if (dw_mode & 0x10) { - pic->dw_y_adr = pbi->m_BUF[i].start_adr; - pic->dw_u_v_adr = pic->dw_y_adr + pbi->m_BUF[i].luma_size; pic->mc_canvas_y = (pic->index << 1); pic->mc_canvas_u_v = (pic->index << 1) + 1; - } else if (dw_mode) { - pic->dw_y_adr = pbi->m_BUF[i].start_adr; - pic->dw_u_v_adr = pic->dw_y_adr + pbi->m_BUF[i].luma_size; } #ifdef MV_USE_FIXED_BUF @@ -7006,16 +7049,36 @@ static void update_vf_memhandle(struct VP9Decoder_s *pbi, } } +static inline void pbi_update_gvs(struct VP9Decoder_s *pbi) +{ + if (pbi->gvs->frame_height != frame_height) { + pbi->gvs->frame_width = frame_width; + pbi->gvs->frame_height = frame_height; + } + if (pbi->gvs->frame_dur != pbi->frame_dur) { + pbi->gvs->frame_dur = pbi->frame_dur; + if (pbi->frame_dur != 0) + pbi->gvs->frame_rate = 96000 / pbi->frame_dur; + else + pbi->gvs->frame_rate = -1; + } + pbi->gvs->status = pbi->stat | pbi->fatal_error; +} + static int prepare_display_buf(struct VP9Decoder_s *pbi, struct PIC_BUFFER_CONFIG_s *pic_config) { struct vframe_s *vf = NULL; + struct vdec_s *pvdec = hw_to_vdec(pbi); int stream_offset = pic_config->stream_offset; unsigned short slice_type = pic_config->slice_type; + struct aml_vcodec_ctx * v4l2_ctx = pbi->v4l2_ctx; + ulong nv_order = VIDTYPE_VIU_NV21; u32 pts_valid = 0, pts_us64_valid = 0; u32 pts_save; u64 pts_us64_save; - u32 frame_size; + u32 frame_size = 0; + if (debug & VP9_DEBUG_BUFMGR) pr_info("%s index = %d\r\n", __func__, pic_config->index); @@ -7024,6 +7087,13 @@ static int prepare_display_buf(struct VP9Decoder_s *pbi, return -1; } + /* swap uv */ + if (pbi->is_used_v4l) { + if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) || + (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M)) + nv_order = VIDTYPE_VIU_NV12; + } + if (pic_config->double_write_mode) set_canvas(pbi, pic_config); @@ -7041,7 +7111,7 @@ static int prepare_display_buf(struct VP9Decoder_s *pbi, } #ifdef MULTI_INSTANCE_SUPPORT - if (vdec_frame_based(hw_to_vdec(pbi))) { + if (vdec_frame_based(pvdec)) { vf->pts = pic_config->pts; vf->pts_us64 = pic_config->pts64; vf->timestamp = pic_config->timestamp; @@ -7173,7 +7243,7 @@ static int prepare_display_buf(struct VP9Decoder_s *pbi, if (pic_config->double_write_mode) { vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; - vf->type |= VIDTYPE_VIU_NV21; + vf->type |= nv_order; if ((pic_config->double_write_mode == 3) && (!IS_8K_SIZE(pic_config->y_crop_width, pic_config->y_crop_height))) { @@ -7258,17 +7328,23 @@ static int prepare_display_buf(struct VP9Decoder_s *pbi, && pic_config->y_crop_height == 196 && (debug & VP9_DEBUG_NO_TRIGGER_FRAME) == 0 && (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TXLX))) { + struct vdec_info tmp4x; + inc_vf_ref(pbi, pic_config->index); - decoder_do_frame_check(hw_to_vdec(pbi), vf); + decoder_do_frame_check(pvdec, vf); kfifo_put(&pbi->display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); pbi->vf_pre_count++; -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC + pbi_update_gvs(pbi); /*count info*/ - gvs->frame_dur = pbi->frame_dur; - vdec_count_info(gvs, 0, stream_offset); -#endif - hw_to_vdec(pbi)->vdec_fps_detec(hw_to_vdec(pbi)->id); + vdec_count_info(pbi->gvs, 0, stream_offset); + memcpy(&tmp4x, pbi->gvs, sizeof(struct vdec_info)); + tmp4x.bit_depth_luma = pbi->vp9_param.p.bit_depth; + tmp4x.bit_depth_chroma = pbi->vp9_param.p.bit_depth; + tmp4x.double_write_mode = get_double_write_mode(pbi); + vdec_fill_vdec_frame(pvdec, &pbi->vframe_qos, &tmp4x, + vf, pic_config->hw_decode_time); + pvdec->vdec_fps_detec(pvdec->id); if (without_display_mode == 0) { vf_notify_receiver(pbi->provider_name, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); @@ -7353,66 +7429,66 @@ static void debug_buffer_mgr_more(struct VP9Decoder_s *pbi) return; pr_info("vp9_param: (%d)\n", pbi->slice_idx); for (i = 0; i < (RPM_END-RPM_BEGIN); i++) { - pr_info("%04x ", vp9_param.l.data[i]); + pr_info("%04x ", pbi->vp9_param.l.data[i]); if (((i + 1) & 0xf) == 0) pr_info("\n"); } pr_info("=============param==========\r\n"); - pr_info("profile %x\r\n", vp9_param.p.profile); + pr_info("profile %x\r\n", pbi->vp9_param.p.profile); pr_info("show_existing_frame %x\r\n", - vp9_param.p.show_existing_frame); + pbi->vp9_param.p.show_existing_frame); pr_info("frame_to_show_idx %x\r\n", - vp9_param.p.frame_to_show_idx); - pr_info("frame_type %x\r\n", vp9_param.p.frame_type); - pr_info("show_frame %x\r\n", vp9_param.p.show_frame); + pbi->vp9_param.p.frame_to_show_idx); + pr_info("frame_type %x\r\n", pbi->vp9_param.p.frame_type); + pr_info("show_frame %x\r\n", pbi->vp9_param.p.show_frame); pr_info("e.r.r.o.r_resilient_mode %x\r\n", - vp9_param.p.error_resilient_mode); - pr_info("intra_only %x\r\n", vp9_param.p.intra_only); + pbi->vp9_param.p.error_resilient_mode); + pr_info("intra_only %x\r\n", pbi->vp9_param.p.intra_only); pr_info("display_size_present %x\r\n", - vp9_param.p.display_size_present); + pbi->vp9_param.p.display_size_present); pr_info("reset_frame_context %x\r\n", - vp9_param.p.reset_frame_context); + pbi->vp9_param.p.reset_frame_context); pr_info("refresh_frame_flags %x\r\n", - vp9_param.p.refresh_frame_flags); - pr_info("bit_depth %x\r\n", vp9_param.p.bit_depth); - pr_info("width %x\r\n", vp9_param.p.width); - pr_info("height %x\r\n", vp9_param.p.height); - pr_info("display_width %x\r\n", vp9_param.p.display_width); - pr_info("display_height %x\r\n", vp9_param.p.display_height); - pr_info("ref_info %x\r\n", vp9_param.p.ref_info); - pr_info("same_frame_size %x\r\n", vp9_param.p.same_frame_size); + pbi->vp9_param.p.refresh_frame_flags); + pr_info("bit_depth %x\r\n", pbi->vp9_param.p.bit_depth); + pr_info("width %x\r\n", pbi->vp9_param.p.width); + pr_info("height %x\r\n", pbi->vp9_param.p.height); + pr_info("display_width %x\r\n", pbi->vp9_param.p.display_width); + pr_info("display_height %x\r\n", pbi->vp9_param.p.display_height); + pr_info("ref_info %x\r\n", pbi->vp9_param.p.ref_info); + pr_info("same_frame_size %x\r\n", pbi->vp9_param.p.same_frame_size); if (!(debug & VP9_DEBUG_DBG_LF_PRINT)) return; pr_info("mode_ref_delta_enabled: 0x%x\r\n", - vp9_param.p.mode_ref_delta_enabled); + pbi->vp9_param.p.mode_ref_delta_enabled); pr_info("sharpness_level: 0x%x\r\n", - vp9_param.p.sharpness_level); + pbi->vp9_param.p.sharpness_level); pr_info("ref_deltas: 0x%x, 0x%x, 0x%x, 0x%x\r\n", - vp9_param.p.ref_deltas[0], vp9_param.p.ref_deltas[1], - vp9_param.p.ref_deltas[2], vp9_param.p.ref_deltas[3]); - pr_info("mode_deltas: 0x%x, 0x%x\r\n", vp9_param.p.mode_deltas[0], - vp9_param.p.mode_deltas[1]); - pr_info("filter_level: 0x%x\r\n", vp9_param.p.filter_level); - pr_info("seg_enabled: 0x%x\r\n", vp9_param.p.seg_enabled); - pr_info("seg_abs_delta: 0x%x\r\n", vp9_param.p.seg_abs_delta); + pbi->vp9_param.p.ref_deltas[0], pbi->vp9_param.p.ref_deltas[1], + pbi->vp9_param.p.ref_deltas[2], pbi->vp9_param.p.ref_deltas[3]); + pr_info("mode_deltas: 0x%x, 0x%x\r\n", pbi->vp9_param.p.mode_deltas[0], + pbi->vp9_param.p.mode_deltas[1]); + pr_info("filter_level: 0x%x\r\n", pbi->vp9_param.p.filter_level); + pr_info("seg_enabled: 0x%x\r\n", pbi->vp9_param.p.seg_enabled); + pr_info("seg_abs_delta: 0x%x\r\n", pbi->vp9_param.p.seg_abs_delta); pr_info("seg_lf_feature_enabled: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\r\n", - (vp9_param.p.seg_lf_info[0]>>15 & 1), - (vp9_param.p.seg_lf_info[1]>>15 & 1), - (vp9_param.p.seg_lf_info[2]>>15 & 1), - (vp9_param.p.seg_lf_info[3]>>15 & 1), - (vp9_param.p.seg_lf_info[4]>>15 & 1), - (vp9_param.p.seg_lf_info[5]>>15 & 1), - (vp9_param.p.seg_lf_info[6]>>15 & 1), - (vp9_param.p.seg_lf_info[7]>>15 & 1)); + (pbi->vp9_param.p.seg_lf_info[0]>>15 & 1), + (pbi->vp9_param.p.seg_lf_info[1]>>15 & 1), + (pbi->vp9_param.p.seg_lf_info[2]>>15 & 1), + (pbi->vp9_param.p.seg_lf_info[3]>>15 & 1), + (pbi->vp9_param.p.seg_lf_info[4]>>15 & 1), + (pbi->vp9_param.p.seg_lf_info[5]>>15 & 1), + (pbi->vp9_param.p.seg_lf_info[6]>>15 & 1), + (pbi->vp9_param.p.seg_lf_info[7]>>15 & 1)); pr_info("seg_lf_feature_data: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\r\n", - (vp9_param.p.seg_lf_info[0] & 0x13f), - (vp9_param.p.seg_lf_info[1] & 0x13f), - (vp9_param.p.seg_lf_info[2] & 0x13f), - (vp9_param.p.seg_lf_info[3] & 0x13f), - (vp9_param.p.seg_lf_info[4] & 0x13f), - (vp9_param.p.seg_lf_info[5] & 0x13f), - (vp9_param.p.seg_lf_info[6] & 0x13f), - (vp9_param.p.seg_lf_info[7] & 0x13f)); + (pbi->vp9_param.p.seg_lf_info[0] & 0x13f), + (pbi->vp9_param.p.seg_lf_info[1] & 0x13f), + (pbi->vp9_param.p.seg_lf_info[2] & 0x13f), + (pbi->vp9_param.p.seg_lf_info[3] & 0x13f), + (pbi->vp9_param.p.seg_lf_info[4] & 0x13f), + (pbi->vp9_param.p.seg_lf_info[5] & 0x13f), + (pbi->vp9_param.p.seg_lf_info[6] & 0x13f), + (pbi->vp9_param.p.seg_lf_info[7] & 0x13f)); } @@ -7450,6 +7526,14 @@ static void vp9_recycle_mmu_buf(struct VP9Decoder_s *pbi) pbi->used_4k_num = -1; } } + +void vp9_recycle_mmu_work(struct work_struct *work) +{ + struct VP9Decoder_s *pbi = container_of(work, + struct VP9Decoder_s, recycle_mmu_work); + + vp9_recycle_mmu_buf(pbi); +} #endif @@ -7461,8 +7545,13 @@ static void dec_again_process(struct VP9Decoder_s *pbi) PROC_STATE_DECODESLICE) { pbi->process_state = PROC_STATE_SENDAGAIN; - if (pbi->mmu_enable) - vp9_recycle_mmu_buf(pbi); + if (pbi->mmu_enable) { + /* + * Because vp9_recycle_mmu_buf has sleep function,we can't + * call it directly. Use a recycle_mmu_work to substitude it. + */ + vdec_schedule_work(&pbi->recycle_mmu_work); + } } reset_process_time(pbi); vdec_schedule_work(&pbi->work); @@ -7473,25 +7562,28 @@ int continue_decoding(struct VP9Decoder_s *pbi) int ret; int i; struct VP9_Common_s *const cm = &pbi->common; + struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(pbi->v4l2_ctx); debug_buffer_mgr_more(pbi); - bit_depth_luma = vp9_param.p.bit_depth; - bit_depth_chroma = vp9_param.p.bit_depth; + if (pbi->is_used_v4l && ctx->param_sets_from_ucode) + pbi->res_ch_flag = 0; + bit_depth_luma = pbi->vp9_param.p.bit_depth; + bit_depth_chroma = pbi->vp9_param.p.bit_depth; - if ((vp9_param.p.bit_depth >= VPX_BITS_10) && + if ((pbi->vp9_param.p.bit_depth >= VPX_BITS_10) && (get_double_write_mode(pbi) == 0x10)) { pbi->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW; pr_err("fatal err, bit_depth %d, unsupport dw 0x10\n", - vp9_param.p.bit_depth); + pbi->vp9_param.p.bit_depth); return -1; } if (pbi->process_state != PROC_STATE_SENDAGAIN) { - ret = vp9_bufmgr_process(pbi, &vp9_param); + ret = vp9_bufmgr_process(pbi, &pbi->vp9_param); if (!pbi->m_ins_flag) pbi->slice_idx++; } else { - union param_u *params = &vp9_param; + union param_u *params = &pbi->vp9_param; if (pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) { ret = vp9_alloc_mmu(pbi, cm->new_fb_idx, @@ -7549,11 +7641,11 @@ int continue_decoding(struct VP9Decoder_s *pbi) #endif } /*pr_info("Decode Frame Data %d\n", pbi->frame_count);*/ - config_pic_size(pbi, vp9_param.p.bit_depth); + config_pic_size(pbi, pbi->vp9_param.p.bit_depth); if ((pbi->common.frame_type != KEY_FRAME) && (!pbi->common.intra_only)) { - config_mc_buffer(pbi, vp9_param.p.bit_depth); + config_mc_buffer(pbi, pbi->vp9_param.p.bit_depth); #ifdef SUPPORT_FB_DECODING if (pbi->used_stage_buf_num == 0) #endif @@ -7570,34 +7662,34 @@ int continue_decoding(struct VP9Decoder_s *pbi) else config_mcrcc_axi_hw(pbi); #endif - config_sao_hw(pbi, &vp9_param); + config_sao_hw(pbi, &pbi->vp9_param); #ifdef VP9_LPF_LVL_UPDATE /* * Get loop filter related picture level parameters from Parser */ - pbi->lf->mode_ref_delta_enabled = vp9_param.p.mode_ref_delta_enabled; - pbi->lf->sharpness_level = vp9_param.p.sharpness_level; + pbi->lf->mode_ref_delta_enabled = pbi->vp9_param.p.mode_ref_delta_enabled; + pbi->lf->sharpness_level = pbi->vp9_param.p.sharpness_level; for (i = 0; i < 4; i++) - pbi->lf->ref_deltas[i] = vp9_param.p.ref_deltas[i]; + pbi->lf->ref_deltas[i] = pbi->vp9_param.p.ref_deltas[i]; for (i = 0; i < 2; i++) - pbi->lf->mode_deltas[i] = vp9_param.p.mode_deltas[i]; - pbi->default_filt_lvl = vp9_param.p.filter_level; - pbi->seg_4lf->enabled = vp9_param.p.seg_enabled; - pbi->seg_4lf->abs_delta = vp9_param.p.seg_abs_delta; + pbi->lf->mode_deltas[i] = pbi->vp9_param.p.mode_deltas[i]; + pbi->default_filt_lvl = pbi->vp9_param.p.filter_level; + pbi->seg_4lf->enabled = pbi->vp9_param.p.seg_enabled; + pbi->seg_4lf->abs_delta = pbi->vp9_param.p.seg_abs_delta; for (i = 0; i < MAX_SEGMENTS; i++) - pbi->seg_4lf->feature_mask[i] = (vp9_param.p.seg_lf_info[i] & + pbi->seg_4lf->feature_mask[i] = (pbi->vp9_param.p.seg_lf_info[i] & 0x8000) ? (1 << SEG_LVL_ALT_LF) : 0; for (i = 0; i < MAX_SEGMENTS; i++) pbi->seg_4lf->feature_data[i][SEG_LVL_ALT_LF] - = (vp9_param.p.seg_lf_info[i] - & 0x100) ? -(vp9_param.p.seg_lf_info[i] - & 0x3f) : (vp9_param.p.seg_lf_info[i] & 0x3f); + = (pbi->vp9_param.p.seg_lf_info[i] + & 0x100) ? -(pbi->vp9_param.p.seg_lf_info[i] + & 0x3f) : (pbi->vp9_param.p.seg_lf_info[i] & 0x3f); if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { /*Set pipeline mode*/ uint32_t lpf_data32 = READ_VREG(HEVC_DBLK_CFGB); /*dblk pipeline mode=1 for performance*/ - if (vp9_param.p.width >= 1280) + if (pbi->vp9_param.p.width >= 1280) lpf_data32 |= (0x1 << 4); else lpf_data32 &= ~(0x3 << 4); @@ -7651,7 +7743,10 @@ static void fill_frame_info(struct VP9Decoder_s *pbi, /* #define SHOW_QOS_INFO */ - vframe_qos->size = framesize; + if (input_frame_based(hw_to_vdec(pbi))) + vframe_qos->size = frame->frame_size2; + else + vframe_qos->size = framesize; vframe_qos->pts = pts; #ifdef SHOW_QOS_INFO vp9_print(pbi, 0, "slice:%d\n", frame->slice_type); @@ -7684,9 +7779,6 @@ static void fill_frame_info(struct VP9Decoder_s *pbi, vframe_qos->min_skip); #endif vframe_qos->num++; - - if (pbi->frameinfo_enable) - vdec_fill_frame_info(vframe_qos, 1); } /* only when we decoded one field or one frame, @@ -7694,9 +7786,15 @@ we can call this function to get qos info*/ static void get_picture_qos_info(struct VP9Decoder_s *pbi) { struct PIC_BUFFER_CONFIG_s *frame = &pbi->cur_buf->buf; + struct vdec_s *vdec = hw_to_vdec(pbi); if (!frame) return; + if (vdec->mvfrm) { + frame->frame_size2 = vdec->mvfrm->frame_size; + frame->hw_decode_time = + local_clock() - vdec->mvfrm->hw_decode_start; + } if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) { unsigned char a[3]; @@ -8102,6 +8200,54 @@ static void get_picture_qos_info(struct VP9Decoder_s *pbi) } } +static int vvp9_get_ps_info(struct VP9Decoder_s *pbi, struct aml_vdec_ps_infos *ps) +{ + int dw_mode = v4l_parser_get_double_write_mode(pbi); + + ps->visible_width = pbi->frame_width / get_double_write_ratio(pbi, dw_mode); + ps->visible_height = pbi->frame_height / get_double_write_ratio(pbi, dw_mode); + ps->coded_width = ALIGN(pbi->frame_width, 32) / get_double_write_ratio(pbi, dw_mode); + ps->coded_height = ALIGN(pbi->frame_height, 32) / get_double_write_ratio(pbi, dw_mode); + ps->dpb_size = pbi->used_buf_num; + + return 0; +} + + +static int v4l_res_change(struct VP9Decoder_s *pbi) +{ + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(pbi->v4l2_ctx); + struct VP9_Common_s *const cm = &pbi->common; + int ret = 0; + + if (ctx->param_sets_from_ucode && + pbi->res_ch_flag == 0) { + struct aml_vdec_ps_infos ps; + if ((cm->width != 0 && + cm->height != 0) && + (pbi->frame_width != cm->width || + pbi->frame_height != cm->height)) { + + vp9_print(pbi, 0, "%s (%d,%d)=>(%d,%d)\r\n", __func__, cm->width, + cm->height, pbi->frame_width, pbi->frame_height); + vvp9_get_ps_info(pbi, &ps); + vdec_v4l_set_ps_infos(ctx, &ps); + vdec_v4l_res_ch_event(ctx); + pbi->v4l_params_parsed = false; + pbi->res_ch_flag = 1; + pbi->eos = 1; + vp9_bufmgr_postproc(pbi); + //del_timer_sync(&pbi->timer); + notify_v4l_eos(hw_to_vdec(pbi)); + ret = 1; + } + } + + return ret; +} + + static irqreturn_t vvp9_isr_thread_fn(int irq, void *data) { struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)data; @@ -8261,7 +8407,7 @@ static irqreturn_t vvp9_isr_thread_fn(int irq, void *data) } if (debug & VP9_DEBUG_SEND_PARAM_WITH_REG) { - get_rpm_param(&vp9_param); + get_rpm_param(&pbi->vp9_param); } else { #ifdef SUPPORT_FB_DECODING if (pbi->used_stage_buf_num > 0) { @@ -8316,7 +8462,7 @@ static irqreturn_t vvp9_isr_thread_fn(int irq, void *data) for (i = 0; i < (RPM_END - RPM_BEGIN); i += 4) { int ii; for (ii = 0; ii < 4; ii++) - vp9_param.l.data[i + ii] = + pbi->vp9_param.l.data[i + ii] = pbi->rpm_ptr[i + 3 - ii]; } } @@ -8326,29 +8472,34 @@ static irqreturn_t vvp9_isr_thread_fn(int irq, void *data) struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(pbi->v4l2_ctx); - pbi->frame_width = vp9_param.p.width; - pbi->frame_height = vp9_param.p.height; - if (ctx->param_sets_from_ucode && !pbi->v4l_params_parsed) { - struct aml_vdec_ps_infos ps; - - ps.visible_width = pbi->frame_width; - ps.visible_height = pbi->frame_height; - ps.coded_width = ALIGN(pbi->frame_width, 32); - ps.coded_height = ALIGN(pbi->frame_height, 32); - ps.dpb_size = pbi->used_buf_num; - pbi->v4l_params_parsed = true; - vdec_v4l_set_ps_infos(ctx, &ps); + pbi->frame_width = pbi->vp9_param.p.width; + pbi->frame_height = pbi->vp9_param.p.height; + + if (!v4l_res_change(pbi)) { + if (ctx->param_sets_from_ucode && !pbi->v4l_params_parsed) { + struct aml_vdec_ps_infos ps; + + pr_debug("set ucode parse\n"); + vvp9_get_ps_info(pbi, &ps); + /*notice the v4l2 codec.*/ + vdec_v4l_set_ps_infos(ctx, &ps); + pbi->v4l_params_parsed = true; + pbi->postproc_done = 0; + pbi->process_busy = 0; + dec_again_process(pbi); + return IRQ_HANDLED; + } + } else { + pbi->postproc_done = 0; + pbi->process_busy = 0; + dec_again_process(pbi); + return IRQ_HANDLED; } } - if (pbi->is_used_v4l) { - pbi->dec_result = DEC_V4L2_CONTINUE_DECODING; - vdec_schedule_work(&pbi->work); - } else { - continue_decoding(pbi); - pbi->postproc_done = 0; - pbi->process_busy = 0; - } + continue_decoding(pbi); + pbi->postproc_done = 0; + pbi->process_busy = 0; #ifdef MULTI_INSTANCE_SUPPORT if (pbi->m_ins_flag) @@ -8520,7 +8671,8 @@ static void vvp9_put_timer_func(unsigned long arg) if (pbi->m_ins_flag) { if (hw_to_vdec(pbi)->next_status - == VDEC_STATUS_DISCONNECTED) { + == VDEC_STATUS_DISCONNECTED && + !pbi->is_used_v4l) { #ifdef SUPPORT_FB_DECODING if (pbi->run2_busy) return; @@ -8741,19 +8893,17 @@ int vvp9_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) vstatus->error_count = 0; vstatus->status = vp9->stat | vp9->fatal_error; vstatus->frame_dur = vp9->frame_dur; -#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC - vstatus->bit_rate = gvs->bit_rate; - vstatus->frame_data = gvs->frame_data; - vstatus->total_data = gvs->total_data; - vstatus->frame_count = gvs->frame_count; - vstatus->error_frame_count = gvs->error_frame_count; - vstatus->drop_frame_count = gvs->drop_frame_count; - vstatus->total_data = gvs->total_data; - vstatus->samp_cnt = gvs->samp_cnt; - vstatus->offset = gvs->offset; + vstatus->bit_rate = vp9->gvs->bit_rate; + vstatus->frame_data = vp9->gvs->frame_data; + vstatus->total_data = vp9->gvs->total_data; + vstatus->frame_count = vp9->gvs->frame_count; + vstatus->error_frame_count = vp9->gvs->error_frame_count; + vstatus->drop_frame_count = vp9->gvs->drop_frame_count; + vstatus->total_data = vp9->gvs->total_data; + vstatus->samp_cnt = vp9->gvs->samp_cnt; + vstatus->offset = vp9->gvs->offset; snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name), "%s", DRIVER_NAME); -#endif return 0; } @@ -8921,6 +9071,7 @@ static int vvp9_local_init(struct VP9Decoder_s *pbi) pr_info("the struct of vdec status malloc failed.\n"); return -1; } + vdec_set_vframe_comm(hw_to_vdec(pbi), DRIVER_NAME); #ifdef DEBUG_PTS pbi->pts_missed = 0; pbi->pts_hit = 0; @@ -9017,6 +9168,7 @@ static s32 vvp9_init(struct VP9Decoder_s *pbi) pbi->stat |= STAT_ISR_REG;*/ INIT_WORK(&pbi->work, vp9_work); + INIT_WORK(&pbi->recycle_mmu_work, vp9_recycle_mmu_work); #ifdef SUPPORT_FB_DECODING if (pbi->used_stage_buf_num > 0) INIT_WORK(&pbi->s1_work, vp9_s1_work); @@ -9134,6 +9286,7 @@ static int vmvp9_stop(struct VP9Decoder_s *pbi) vp9_local_uninit(pbi); reset_process_time(pbi); cancel_work_sync(&pbi->work); + cancel_work_sync(&pbi->recycle_mmu_work); #ifdef SUPPORT_FB_DECODING if (pbi->used_stage_buf_num > 0) cancel_work_sync(&pbi->s1_work); @@ -9189,6 +9342,7 @@ static int vvp9_stop(struct VP9Decoder_s *pbi) cancel_work_sync(&pbi->s1_work); #endif cancel_work_sync(&pbi->work); + cancel_work_sync(&pbi->recycle_mmu_work); } else amhevc_disable(); #else @@ -9528,25 +9682,6 @@ static void vp9_work(struct work_struct *work) return; } - if (pbi->dec_result == DEC_V4L2_CONTINUE_DECODING) { - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(pbi->v4l2_ctx); - - if (ctx->param_sets_from_ucode) { - reset_process_time(pbi); - if (wait_event_interruptible_timeout(ctx->wq, - ctx->v4l_codec_ready, - msecs_to_jiffies(500)) < 0) - return; - } - - continue_decoding(pbi); - pbi->postproc_done = 0; - pbi->process_busy = 0; - - return; - } - if (((pbi->dec_result == DEC_RESULT_GET_DATA) || (pbi->dec_result == DEC_RESULT_GET_DATA_RETRY)) && (hw_to_vdec(pbi)->next_status != @@ -9815,11 +9950,19 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(pbi->v4l2_ctx); - if (ctx->param_sets_from_ucode && - !ctx->v4l_codec_ready && - pbi->v4l_params_parsed) { - ret = 0; /*the params has parsed.*/ - } else if (!ctx->v4l_codec_dpb_ready) { + if (ctx->param_sets_from_ucode) { + if (pbi->v4l_params_parsed) { + if ((ctx->cap_pool.in < ctx->dpb_size) && + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < + run_ready_min_buf_num) + ret = 0; + } else { + if ((pbi->res_ch_flag == 1) && + ((ctx->state <= AML_STATE_INIT) || + (ctx->state >= AML_STATE_FLUSHING))) + ret = 0; + } + } else if (ctx->cap_pool.in < ctx->dpb_size) { if (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < run_ready_min_buf_num) ret = 0; @@ -9948,6 +10091,8 @@ static void run_front(struct vdec_s *vdec) WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0); size = pbi->chunk->size + (pbi->chunk->offset & (VDEC_FIFO_ALIGN - 1)); + if (vdec->mvfrm) + vdec->mvfrm->frame_size = pbi->chunk->size; } WRITE_VREG(HEVC_DECODE_SIZE, size); WRITE_VREG(HEVC_DECODE_COUNT, pbi->slice_idx); @@ -10089,7 +10234,7 @@ static void run_back(struct vdec_s *vdec) for (i = 0; i < (RPM_END - RPM_BEGIN); i += 4) { int ii; for (ii = 0; ii < 4; ii++) - vp9_param.l.data[i + ii] = + pbi->vp9_param.l.data[i + ii] = pbi->s2_buf->rpm[i + 3 - ii]; } #ifndef FB_DECODING_TEST_SCHEDULE @@ -10113,6 +10258,8 @@ static void run(struct vdec_s *vdec, unsigned long mask, PRINT_FLAG_VDEC_DETAIL, "%s mask %lx\r\n", __func__, mask); + if (vdec->mvfrm) + vdec->mvfrm->hw_decode_start = local_clock(); run_count[pbi->index]++; pbi->vdec_cb_arg = arg; pbi->vdec_cb = callback; @@ -10127,6 +10274,7 @@ static void run(struct vdec_s *vdec, unsigned long mask, #else run_front(vdec); #endif + } static void init_frame_bufs(struct VP9Decoder_s *pbi) @@ -10142,6 +10290,7 @@ static void init_frame_bufs(struct VP9Decoder_s *pbi) frame_bufs[i].buf.decode_idx = 0; frame_bufs[i].buf.cma_alloc_addr = 0; frame_bufs[i].buf.index = i; + frame_bufs[i].buf.vframe_bound = 0; } if (vdec->parallel_dec == 1) { diff --git a/drivers/frame_sink/encoder/h264/encoder.c b/drivers/frame_sink/encoder/h264/encoder.c index 294c600..358866d 100644 --- a/drivers/frame_sink/encoder/h264/encoder.c +++ b/drivers/frame_sink/encoder/h264/encoder.c @@ -2850,6 +2850,8 @@ void amvenc_avc_start_cmd(struct encode_wq_s *wq, ie_me_mode = (0 & ME_PIXEL_MODE_MASK) << ME_PIXEL_MODE_SHIFT; if (encode_manager.need_reset) { + amvenc_stop(); + reload_flag = 1; encode_manager.need_reset = false; encode_manager.encode_hw_status = ENCODER_IDLE; amvenc_reset(); diff --git a/drivers/stream_input/Makefile b/drivers/stream_input/Makefile index 6518166..a6cedab 100644 --- a/drivers/stream_input/Makefile +++ b/drivers/stream_input/Makefile @@ -8,11 +8,16 @@ stream_input-objs += parser/esparser.o stream_input-objs += parser/tsdemux.o stream_input-objs += parser/psparser.o stream_input-objs += parser/rmparser.o +stream_input-objs += parser/dvb_common.o stream_input-objs += subtitle/subtitle.o obj-$(CONFIG_AMLOGIC_DVB) += parser/hw_demux/ obj-$(CONFIG_AMLOGIC_DVB) += parser/demux/ obj-$(CONFIG_AMLOGIC_DVB) += parser/dvb_ci/ + +ccflags-y += -I. +ccflags-y += -I$(srctree)/drivers/media/dvb-core + #obj-y += tv_frontend/ # obj-y += box-frontend/avl6211/ # obj-y += box-frontend/atbm8881/ diff --git a/drivers/stream_input/amports/amstream.c b/drivers/stream_input/amports/amstream.c index 51fd4b7..95ea2ae 100644 --- a/drivers/stream_input/amports/amstream.c +++ b/drivers/stream_input/amports/amstream.c @@ -30,10 +30,12 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -120,9 +122,6 @@ static int def_vstreambuf_sizeM = (DEFAULT_VIDEO_BUFFER_SIZE >> 20); static int slow_input; - - - /* #define DATA_DEBUG */ static int use_bufferlevelx10000 = 10000; static int reset_canuse_buferlevel(int level); @@ -430,6 +429,13 @@ static struct stream_port_s ports[] = { .fops = &vbuf_fops, .vformat = VFORMAT_HEVC, }, + { + .name = "amstream_dves_av1", + .type = PORT_TYPE_ES | PORT_TYPE_VIDEO | PORT_TYPE_HEVC | PORT_TYPE_FRAME | + PORT_TYPE_DECODER_SCHED | PORT_TYPE_DUALDEC, + .fops = &vframe_fops, + .vformat = VFORMAT_AV1, + }, #endif #endif }; @@ -634,6 +640,19 @@ static int video_port_init(struct port_priv_s *priv, return r; } + if (vdec_dual(vdec)) { + if (port->vformat == VFORMAT_AV1) /* av1 dv only single layer */ + return 0; + r = vdec_init(vdec->slave, + (priv->vdec->sys_info->height * + priv->vdec->sys_info->width) > 1920*1088); + if (r < 0) { + pr_err("video_port_init %d, vdec_init failed\n", + __LINE__); + video_port_release(priv, pbuf, 2); + return r; + } + } return 0; } @@ -770,6 +789,9 @@ static int audio_port_reset(struct stream_port_s *port, r = pts_start(PTS_TYPE_AUDIO); + //clear audio break flag after reset + //tsync_audio_break(0); + pr_info("audio_port_reset done\n"); mutex_unlock(&amstream_mutex); return r; @@ -882,6 +904,16 @@ static void amstream_user_buffer_init(void) pubuf->buf_rp = 0; } +#if 1 +/*DDD*/ +struct stream_buf_s *get_vbuf(void) +{ + return &bufs[BUF_TYPE_VIDEO]; +} + +EXPORT_SYMBOL(get_vbuf); +#endif + static int amstream_port_init(struct port_priv_s *priv) { int r = 0; @@ -931,6 +963,7 @@ static int amstream_port_init(struct port_priv_s *priv) if (has_hevc_vdec()) { if (port->vformat == VFORMAT_HEVC || port->vformat == VFORMAT_AVS2 || + port->vformat == VFORMAT_AV1 || port->vformat == VFORMAT_VP9) pvbuf = &bufs[BUF_TYPE_HEVC]; } @@ -961,6 +994,7 @@ static int amstream_port_init(struct port_priv_s *priv) (port->pcr_inited == 1) ? port->pcrid : 0xffff, (port->vformat == VFORMAT_HEVC) || (port->vformat == VFORMAT_AVS2) || + (port->vformat == VFORMAT_AV1) || (port->vformat == VFORMAT_VP9), vdec); } else { @@ -1041,6 +1075,7 @@ static int amstream_port_release(struct port_priv_s *priv) if (has_hevc_vdec()) { if (port->vformat == VFORMAT_HEVC || port->vformat == VFORMAT_AVS2 + || port->vformat == VFORMAT_AV1 || port->vformat == VFORMAT_VP9) pvbuf = &bufs[BUF_TYPE_HEVC]; } @@ -1197,6 +1232,7 @@ static ssize_t amstream_mpts_write(struct file *file, const char *buf, if (has_hevc_vdec()) { pvbuf = (port->vformat == VFORMAT_HEVC || port->vformat == VFORMAT_AVS2 || + port->vformat == VFORMAT_AV1 || port->vformat == VFORMAT_VP9) ? &bufs[BUF_TYPE_HEVC] : &bufs[BUF_TYPE_VIDEO]; } else @@ -1588,6 +1624,7 @@ static int amstream_open(struct inode *inode, struct file *file) struct stream_port_s *s; struct stream_port_s *port = &ports[iminor(inode)]; struct port_priv_s *priv; + VDEC_PRINT_FUN_LINENO(__func__, __LINE__); #ifdef G12A_BRINGUP_DEBUG if (vdec_get_debug_flags() & 0xff0000) { pr_info("%s force open port %d\n", @@ -1600,6 +1637,8 @@ static int amstream_open(struct inode *inode, struct file *file) if (iminor(inode) >= amstream_port_num) return -ENODEV; + //pr_err("%s, port name %s\n", __func__, port->name); + //pr_err("%s [pid=%d,tgid=%d]\n", __func__, current->pid, current->tgid); mutex_lock(&amstream_mutex); if (port->type & PORT_TYPE_VIDEO) { @@ -1788,6 +1827,7 @@ static int amstream_release(struct inode *inode, struct file *file) if ((port->vformat == VFORMAT_HEVC || port->vformat == VFORMAT_AVS2 + || port->vformat == VFORMAT_AV1 || port->vformat == VFORMAT_VP9)) { vdec_poweroff(VDEC_HEVC); } else { @@ -2084,7 +2124,7 @@ static long amstream_ioctl_set(struct port_priv_s *priv, ulong arg) this->flag |= PORT_FLAG_AID; if (port_get_inited(priv)) { - tsync_audio_break(1); + //tsync_audio_break(1); amstream_change_avid(this); } } else @@ -2335,6 +2375,7 @@ static long amstream_ioctl_get_ex(struct port_priv_s *priv, ulong arg) buf = (this->vformat == VFORMAT_HEVC || this->vformat == VFORMAT_AVS2 || + this->vformat == VFORMAT_AV1 || this->vformat == VFORMAT_VP9) ? &bufs[BUF_TYPE_HEVC] : &bufs[BUF_TYPE_VIDEO]; @@ -2595,17 +2636,99 @@ static long amstream_do_ioctl_new(struct port_priv_s *priv, r = -EINVAL; break; case AMSTREAM_IOC_GET_QOSINFO: + case AMSTREAM_IOC_GET_MVDECINFO: { - struct av_param_qosinfo_t __user *uarg = (void *)arg; - struct vframe_qos_s *qos_info = vdec_get_qos_info(); - if (this->type & PORT_TYPE_VIDEO) { - if (qos_info != NULL && copy_to_user((void *)uarg->vframe_qos, - qos_info, - QOS_FRAME_NUM*sizeof(struct vframe_qos_s))) { - r = -EFAULT; + u32 slots = 0; + u32 struct_size = 0; + int vdec_id = 0; + struct vdec_s *vdec = NULL; + struct vframe_counter_s tmpbuf[QOS_FRAME_NUM] = {0}; + struct av_param_mvdec_t __user *uarg = (void *)arg; + + if (AMSTREAM_IOC_GET_MVDECINFO == cmd) { + if (get_user(vdec_id, &uarg->vdec_id) < 0 + || get_user(struct_size, &uarg->struct_size) < 0) { + r = -EFAULT; + break; + } + if (struct_size != sizeof(struct av_param_mvdec_t)) { + pr_err("pass in size %u != expected size %u\n", + struct_size, (u32)sizeof(struct av_param_mvdec_t)); + pr_err("App using old structue,we will support it.\n"); + //Here will add the compatibility for old structure when + //current struecture be substituded by newer structure. + //msleep(1000); let app handle it. break; } } + vdec = vdec_get_vdec_by_id(vdec_id); + if (!vdec) { + r = 0; + break; + } + + slots = vdec_get_frame_vdec(vdec, tmpbuf); + if (AMSTREAM_IOC_GET_MVDECINFO == cmd) + put_user(slots, &uarg->slots); + if (slots) { + if (AMSTREAM_IOC_GET_MVDECINFO == cmd) { + if (copy_to_user((void *)&uarg->comm, + &vdec->mvfrm->comm, + sizeof(struct vframe_comm_s))) { + r = -EFAULT; + break; + } + if (copy_to_user((void *)&uarg->minfo[0], + tmpbuf, + slots*sizeof(struct vframe_counter_s))) { + r = -EFAULT; + kfree(tmpbuf); + break; + } + }else { //For compatibility, only copy the qos + struct av_param_qosinfo_t __user *uarg = (void *)arg; + int i; + for (i=0; ivframe_qos[i], + &tmpbuf[i].qos, + sizeof(struct vframe_qos_s))) { + r = -EFAULT; + break; + } + } + } else { + /*Vdec didn't produce item,wait for 10 ms to avoid user application + infinitely calling*/ + //msleep(10); let user app handle it. + } + } + break; + case AMSTREAM_IOC_GET_AVINFO: + { + struct av_param_info_t __user *uarg = (void *)arg; + struct av_info_t av_info; + int delay; + u32 avgbps; + if (this->type & PORT_TYPE_VIDEO) { + av_info.first_pic_coming = get_first_pic_coming(); + av_info.current_fps = -1; + av_info.vpts = timestamp_vpts_get(); + av_info.vpts_err = tsync_get_vpts_error_num(); + av_info.apts = timestamp_apts_get(); + av_info.apts_err = tsync_get_apts_error_num(); + av_info.ts_error = get_discontinue_counter(); + av_info.first_vpts = timestamp_firstvpts_get(); + av_info.toggle_frame_count = get_toggle_frame_count(); + delay = calculation_stream_delayed_ms( + PTS_TYPE_VIDEO, NULL, &avgbps); + if (delay >= 0) + av_info.dec_video_bps = avgbps; + else + av_info.dec_video_bps = 0; + } + if (copy_to_user((void *)&uarg->av_info, (void *)&av_info, + sizeof(struct av_info_t))) + r = -EFAULT; } break; default: @@ -2706,7 +2829,7 @@ static long amstream_do_ioctl_old(struct port_priv_s *priv, this->flag |= PORT_FLAG_AID; if (port_get_inited(priv)) { - tsync_audio_break(1); + //tsync_audio_break(1); amstream_change_avid(this); } } else @@ -2739,6 +2862,7 @@ static long amstream_do_ioctl_old(struct port_priv_s *priv, buf = (this->vformat == VFORMAT_HEVC || this->vformat == VFORMAT_AVS2 || + this->vformat == VFORMAT_AV1 || this->vformat == VFORMAT_VP9) ? &bufs[BUF_TYPE_HEVC] : &bufs[BUF_TYPE_VIDEO]; @@ -3409,6 +3533,8 @@ static long amstream_do_ioctl(struct port_priv_s *priv, case AMSTREAM_IOC_SET_PTR: case AMSTREAM_IOC_SYSINFO: case AMSTREAM_IOC_GET_QOSINFO: + case AMSTREAM_IOC_GET_MVDECINFO: + case AMSTREAM_IOC_GET_AVINFO: r = amstream_do_ioctl_new(priv, cmd, arg); break; default: @@ -3951,6 +4077,117 @@ static ssize_t audio_path_store(struct class *class, return size; } +ssize_t dump_stream_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + char *p_buf = buf; + + p_buf += sprintf(p_buf, "\nmdkir -p /data/tmp -m 777;setenforce 0;\n\n"); + p_buf += sprintf(p_buf, "video:\n\t echo 0 > /sys/class/amstream/dump_stream;\n"); + p_buf += sprintf(p_buf, "hevc :\n\t echo 4 > /sys/class/amstream/dump_stream;\n"); + + return p_buf - buf; +} + +#define DUMP_STREAM_FILE "/data/tmp/dump_stream.h264" +ssize_t dump_stream_store(struct class *class, + struct class_attribute *attr, + const char *buf, size_t size) +{ + struct stream_buf_s *p_buf; + int ret = 0, id = 0; + unsigned int stride, remain, level, vmap_size; + int write_size; + void *stbuf_vaddr; + unsigned long offset; + struct file *fp; + mm_segment_t old_fs; + loff_t fpos; + + ret = sscanf(buf, "%d", &id); + if (ret < 0) { + pr_info("paser buf id fail, default id = 0\n"); + id = 0; + } + if (id != BUF_TYPE_VIDEO && id != BUF_TYPE_HEVC) { + pr_info("buf id out of range, max %d, id %d, set default id 0\n", BUF_MAX_NUM - 1, id); + id = 0; + } + p_buf = get_stream_buffer(id); + if (!p_buf) { + pr_info("get buf fail, id %d\n", id); + return size; + } + if ((!p_buf->buf_size) || (p_buf->is_secure) || (!(p_buf->flag & BUF_FLAG_IN_USE))) { + pr_info("buf size %d, is_secure %d, in_use %d, it can not dump\n", + p_buf->buf_size, p_buf->is_secure, (p_buf->flag & BUF_FLAG_IN_USE)); + return size; + } + + level = stbuf_level(p_buf); + if (!level || level > p_buf->buf_size) { + pr_info("stream buf level %d, buf size %d, error return\n", level, p_buf->buf_size); + return size; + } + + fp = filp_open(DUMP_STREAM_FILE, O_CREAT | O_RDWR, 0666); + if (IS_ERR(fp)) { + fp = NULL; + pr_info("create dump stream file failed\n"); + return size; + } + + offset = p_buf->buf_start; + remain = level; + stride = SZ_1M; + vmap_size = 0; + fpos = 0; + pr_info("create file success, it will dump from addr 0x%lx, size 0x%x\n", offset, remain); + while (remain > 0) { + if (remain > stride) + vmap_size = stride; + else { + stride = remain; + vmap_size = stride; + } + + stbuf_vaddr = codec_mm_vmap(offset, vmap_size); + if (stbuf_vaddr == NULL) { + stride >>= 1; + pr_info("vmap fail change vmap stide size 0x%x\n", stride); + continue; + } + codec_mm_dma_flush(stbuf_vaddr, vmap_size, DMA_FROM_DEVICE); + + old_fs = get_fs(); + set_fs(KERNEL_DS); + write_size = vfs_write(fp, stbuf_vaddr, vmap_size, &fpos); + if (write_size < vmap_size) { + write_size += vfs_write(fp, stbuf_vaddr + write_size, vmap_size - write_size, &fpos); + pr_info("fail write retry, total %d, write %d\n", vmap_size, write_size); + if (write_size < vmap_size) { + pr_info("retry fail, interrupt dump stream, break\n"); + break; + } + } + set_fs(old_fs); + vfs_fsync(fp, 0); + pr_info("vmap_size 0x%x dump size 0x%x\n", vmap_size, write_size); + + offset += vmap_size; + remain -= vmap_size; + codec_mm_unmap_phyaddr(stbuf_vaddr); + } + + filp_close(fp, current->files); + pr_info("dump stream buf end\n"); + + return size; +} + + + + static struct class_attribute amstream_class_attrs[] = { __ATTR_RO(ports), __ATTR_RO(bufs), @@ -3962,6 +4199,8 @@ static struct class_attribute amstream_class_attrs[] = { store_maxdelay), __ATTR(reset_audio_port, S_IRUGO | S_IWUSR | S_IWGRP, NULL, audio_path_store), + __ATTR(dump_stream, S_IRUGO | S_IWUSR | S_IWGRP, + dump_stream_show, dump_stream_store), __ATTR_NULL }; diff --git a/drivers/stream_input/parser/demux/aml_dvb.h b/drivers/stream_input/parser/demux/aml_dvb.h index eda7928..539025d 100644 --- a/drivers/stream_input/parser/demux/aml_dvb.h +++ b/drivers/stream_input/parser/demux/aml_dvb.h @@ -30,11 +30,6 @@ #define DSC_DEV_COUNT 2 #define FE_DEV_COUNT 2 -struct aml_tuner { - struct tuner_config cfg; - unsigned int i2c_adapter_id; - struct i2c_adapter *i2c_adp; -}; struct aml_dvb { struct dvb_device dvb_dev; diff --git a/drivers/stream_input/parser/demux/hw_demux/demod_gt.h b/drivers/stream_input/parser/demux/hw_demux/demod_gt.h index 0535da7..b2e42d5 100644 --- a/drivers/stream_input/parser/demux/hw_demux/demod_gt.h +++ b/drivers/stream_input/parser/demux/hw_demux/demod_gt.h @@ -21,65 +21,7 @@ #ifndef __AML_DEMOD_GT_H__ #define __AML_DEMOD_GT_H__ -#include "dvb_frontend.h" +#include "../../dvb_common.h" -struct amlfe_exp_config { - /*config by aml_fe ?*/ - /* */ - int set_mode; -}; -struct amlfe_demod_config { - int dev_id; - u32 ts; - struct i2c_adapter *i2c_adap; - int i2c_addr; - int reset_gpio; - int reset_value; -}; - -/* For configure different tuners */ -/* It can add fields as extensions */ -struct tuner_config { - u8 id; - u8 i2c_addr; - u8 xtal; /* 0: 16MHz, 1: 24MHz, 3: 27MHz */ - u8 xtal_cap; - u8 xtal_mode; -}; - -static inline struct dvb_frontend* aml_dtvdm_attach (const struct amlfe_exp_config *config) { - return NULL; -} - -static inline struct dvb_frontend* si2151_attach (struct dvb_frontend *fe,struct i2c_adapter *i2c, struct tuner_config *cfg) -{ - return NULL; -} - -static inline struct dvb_frontend* mxl661_attach (struct dvb_frontend *fe,struct i2c_adapter *i2c, struct tuner_config *cfg) -{ - return NULL; -} - -static inline struct dvb_frontend* si2159_attach (struct dvb_frontend *fe,struct i2c_adapter *i2c, struct tuner_config *cfg) -{ - return NULL; -} - -static inline struct dvb_frontend* r842_attach (struct dvb_frontend *fe, struct i2c_adapter *i2c, struct tuner_config *cfg) -{ - return NULL; -} - -static inline struct dvb_frontend* r840_attach (struct dvb_frontend *fe, struct i2c_adapter *i2c, struct tuner_config *cfg) -{ - return NULL; -} - -static inline struct dvb_frontend* atbm8881_attach (const struct amlfe_demod_config *config) -{ - return NULL; -} - -#endif /*__AML_DEMOD_GT_H__*/ +#endif /*__AML_DEMOD_GT_H__*/ diff --git a/drivers/stream_input/parser/demux/hw_demux/frontend.c b/drivers/stream_input/parser/demux/hw_demux/frontend.c index 2e40179..90a70c4 100644 --- a/drivers/stream_input/parser/demux/hw_demux/frontend.c +++ b/drivers/stream_input/parser/demux/hw_demux/frontend.c @@ -38,6 +38,7 @@ #include #include #include +#include #include //#include #include "c_stb_define.h" @@ -45,94 +46,16 @@ #include "../aml_dvb.h" #include "dvb_reg.h" -#include "../../../tv_frontend/aml_fe.h" #include "demod_gt.h" #include "../../../../common/media_clock/switch/amports_gate.h" #define pr_error(fmt, args...) printk("DVB: " fmt, ## args) #define pr_inf(fmt, args...) printk("DVB: " fmt, ## args) -typedef enum __demod_type -{ - DEMOD_INVALID, - DEMOD_INTERNAL, - DEMOD_ATBM8881, - DEMOD_MAX_NUM -}demod_type; - -typedef enum __tuner_type -{ - TUNER_INVALID, - TUNER_SI2151, - TUNER_MXL661, - TUNER_SI2159, - TUNER_R842, - TUNER_R840, - TUNER_MAX_NUM -}tuner_type; - static struct dvb_frontend *frontend[FE_DEV_COUNT] = {NULL, NULL}; -static demod_type s_demod_type[FE_DEV_COUNT] = {DEMOD_INVALID, DEMOD_INVALID}; -static tuner_type s_tuner_type[FE_DEV_COUNT] = {TUNER_INVALID, TUNER_INVALID}; - -static int dvb_attach_tuner(struct dvb_frontend *fe, struct aml_tuner *tuner, tuner_type *type) -{ - struct tuner_config *cfg = &tuner->cfg; - struct i2c_adapter *i2c_adap = tuner->i2c_adp; - - switch (cfg->id) { - case AM_TUNER_R840: - if (!dvb_attach(r840_attach, fe, i2c_adap, cfg)) { - pr_error("dvb attach r840_attach tuner error\n"); - return -1; - } else { - pr_inf("r840_attach attach sucess\n"); - *type = TUNER_R840; - } - break; - case AM_TUNER_R842: - if (!dvb_attach(r842_attach, fe, i2c_adap, cfg)) { - pr_error("dvb attach r842_attach tuner error\n"); - return -1; - } else { - pr_inf("r842_attach attach sucess\n"); - *type = TUNER_R842; - } - break; - case AM_TUNER_SI2151: - if (!dvb_attach(si2151_attach, fe, i2c_adap, cfg)) { - pr_error("dvb attach tuner error\n"); - return -1; - } else { - pr_inf("si2151 attach sucess\n"); - *type = TUNER_SI2151; - } - break; - case AM_TUNER_SI2159: - if (!dvb_attach(si2159_attach, fe, i2c_adap, cfg)) { - pr_error("dvb attach si2159_attach tuner error\n"); - return -1; - } else { - pr_inf("si2159_attach attach sucess\n"); - *type = TUNER_SI2159; - } - break; - case AM_TUNER_MXL661: - if (!dvb_attach(mxl661_attach, fe, i2c_adap, cfg)) { - pr_error("dvb attach mxl661_attach tuner error\n"); - return -1; - } else { - pr_inf("mxl661_attach attach sucess\n"); - *type = TUNER_MXL661; - } - break; - default: - pr_error("can't support tuner type: %d\n", cfg->id); - break; - } +static enum dtv_demod_type s_demod_type[FE_DEV_COUNT] = {AM_DTV_DEMOD_NONE, AM_DTV_DEMOD_NONE}; +static enum tuner_type s_tuner_type[FE_DEV_COUNT] = {AM_TUNER_NONE, AM_TUNER_NONE}; - return 0; -} ssize_t stb_show_tuner_setting(struct class *class, struct class_attribute *attr, char *buf) @@ -196,9 +119,13 @@ ssize_t stb_store_tuner_setting(struct class *class, if (frontend[i] == NULL) continue; - if (dvb_attach_tuner(frontend[i], tuner, &s_tuner_type[i]) < 0) { - pr_error("attach tuner %d failed\n", dvb->tuner_cur); + if (aml_attach_tuner(tuner->cfg.id, frontend[i], &tuner->cfg) == NULL) { + s_tuner_type[i] = AM_TUNER_NONE; + pr_error("tuner[%d] [type = %d] attach error.\n", dvb->tuner_cur, tuner->cfg.id); goto EXIT; + } else { + s_tuner_type[i] = tuner->cfg.id; + pr_error("tuner[%d] [type = %d] attach sucess.\n", dvb->tuner_cur, tuner->cfg.id); } } @@ -213,13 +140,13 @@ EXIT: int frontend_probe(struct platform_device *pdev) { - struct amlfe_exp_config config; + struct demod_config config; + struct tuner_config *tuner_cfg = NULL; char buf[32]; const char *str = NULL; struct device_node *node_tuner = NULL; struct device_node *node_i2c = NULL; u32 i2c_addr = 0xFFFFFFFF; - struct tuner_config *cfg = NULL; u32 value = 0; int i = 0; int ret =0; @@ -227,25 +154,28 @@ int frontend_probe(struct platform_device *pdev) struct aml_dvb *advb = aml_get_dvb_device(); for (i=0; idev.of_node, buf, &str); if (ret) { continue; } - if (!strcmp(str,"internal")) - { - config.set_mode = 0; - frontend[i] = dvb_attach(aml_dtvdm_attach,&config); + + if (!strcmp(str, "internal")) { + config.mode = 0; + config.id = AM_DTV_DEMOD_AMLDTV; + frontend[i] = aml_attach_dtvdemod(config.id, &config); if (frontend[i] == NULL) { - pr_error("dvb attach demod error\n"); + s_demod_type[i] = AM_DTV_DEMOD_NONE; + pr_error("internal dtvdemod [type = %d] attach error.\n", config.id); goto error_fe; } else { - pr_inf("dtvdemod attatch sucess\n"); - s_demod_type[i] = DEMOD_INTERNAL; + s_demod_type[i] = config.id; + pr_error("internal dtvdemod [type = %d] attach success.\n", config.id); } - memset(&cfg, 0, sizeof(struct tuner_config)); memset(buf, 0, 32); snprintf(buf, sizeof(buf), "fe%d_tuner",i); node_tuner = of_parse_phandle(pdev->dev.of_node, buf, 0); @@ -281,20 +211,9 @@ int frontend_probe(struct platform_device *pdev) ret = 0; continue; } else { - if (!strncmp(str, "mxl661_tuner", 12)) - advb->tuners[j].cfg.id = AM_TUNER_MXL661; - else if (!strncmp(str, "si2151_tuner", 12)) - advb->tuners[j].cfg.id = AM_TUNER_SI2151; - else if (!strncmp(str, "si2159_tuner", 12)) - advb->tuners[j].cfg.id = AM_TUNER_SI2159; - else if (!strncmp(str, "r840_tuner", 10)) - advb->tuners[j].cfg.id = AM_TUNER_R840; - else if (!strncmp(str, "r842_tuner", 10)) - advb->tuners[j].cfg.id = AM_TUNER_R842; - else { - pr_err("nonsupport tuner: %s.\n", str); - advb->tuners[j].cfg.id = AM_TUNER_NONE; - } + advb->tuners[j].cfg.id = aml_get_tuner_type(str); + if (advb->tuners[j].cfg.id == AM_TUNER_NONE) + pr_err("can't support tuner: %s.\n", str); } snprintf(buf, sizeof(buf), "tuner_i2c_adap_%d", j); @@ -302,9 +221,9 @@ int frontend_probe(struct platform_device *pdev) if (!node_i2c) { pr_error("tuner_i2c_adap_id error\n"); } else { - advb->tuners[j].i2c_adp = of_find_i2c_adapter_by_node(node_i2c); + advb->tuners[j].cfg.i2c_adap = of_find_i2c_adapter_by_node(node_i2c); of_node_put(node_i2c); - if (advb->tuners[j].i2c_adp == NULL) { + if (advb->tuners[j].cfg.i2c_adap == NULL) { pr_error("i2c_get_adapter error\n"); of_node_put(node_tuner); goto error_fe; @@ -347,9 +266,14 @@ int frontend_probe(struct platform_device *pdev) frontend[i]->callback = NULL; if (advb->tuner_cur >= 0) { - if (dvb_attach_tuner(frontend[i], &advb->tuners[advb->tuner_cur], &s_tuner_type[i]) < 0) { - pr_error("attach tuner failed\n"); + tuner_cfg = &advb->tuners[advb->tuner_cur].cfg; + if (aml_attach_tuner(tuner_cfg->id, frontend[i], tuner_cfg) == NULL) { + s_tuner_type[i] = AM_TUNER_NONE; + pr_error("tuner [type = %d] attach error.\n", tuner_cfg->id); goto error_fe; + } else { + s_tuner_type[i] = tuner_cfg->id; + pr_error("tuner [type = %d] attach sucess.\n", tuner_cfg->id); } } @@ -358,81 +282,36 @@ int frontend_probe(struct platform_device *pdev) pr_error("register dvb frontend failed\n"); goto error_fe; } - } else if(!strcmp(str,"external")) { - const char *name = NULL; - struct amlfe_demod_config config; - - config.dev_id = i; - memset(buf, 0, 32); - snprintf(buf, sizeof(buf), "fe%d_demod",i); - ret = of_property_read_string(pdev->dev.of_node, buf, &name); + } else if(!strcmp(str, "external")) { + config.mode = 1; + config.id = AM_DTV_DEMOD_NONE; + ret = aml_get_dts_demod_config(pdev->dev.of_node, &config, i); if (ret) { - ret = 0; + pr_err("can't find demod %d.\n", i); continue; } memset(buf, 0, 32); - snprintf(buf, sizeof(buf), "fe%d_i2c_adap_id",i); - node_i2c = of_parse_phandle(pdev->dev.of_node,buf,0); - if (!node_i2c) { - pr_error("demod%d_i2c_adap_id error\n", i); - } else { - config.i2c_adap = of_find_i2c_adapter_by_node(node_i2c); - of_node_put(node_i2c); - if (config.i2c_adap == NULL) { - pr_error("i2c_get_adapter error\n"); - goto error_fe; - } - } + snprintf(buf, sizeof(buf), "fe%d_tuner", i); + node_tuner = of_parse_phandle(pdev->dev.of_node, buf, 0); + if (node_tuner) { + aml_get_dts_tuner_config(node_tuner, &config.tuner0, 0); + aml_get_dts_tuner_config(node_tuner, &config.tuner1, 1); + } else + pr_err("can't find %s.\n", buf); - memset(buf, 0, 32); - snprintf(buf, sizeof(buf), "fe%d_demod_i2c_addr",i); - ret = of_property_read_u32(pdev->dev.of_node, buf,&config.i2c_addr); - if (ret) { - pr_error("i2c_addr error\n"); - goto error_fe; - } + of_node_put(node_tuner); - memset(buf, 0, 32); - snprintf(buf, sizeof(buf), "fe%d_ts",i); - ret = of_property_read_u32(pdev->dev.of_node, buf,&config.ts); - if (ret) { - pr_error("ts error\n"); + frontend[i] = aml_attach_dtvdemod(config.id, &config); + if (frontend[i] == NULL) { + s_demod_type[i] = AM_DTV_DEMOD_NONE; + pr_error("external dtvdemod [type = %d] attach error.\n", config.id); goto error_fe; - } - - memset(buf, 0, 32); - snprintf(buf, sizeof(buf), "fe%d_reset_gpio",i); - ret = of_property_read_string(pdev->dev.of_node, buf, &str); - if (!ret) { - config.reset_gpio = - of_get_named_gpio_flags(pdev->dev.of_node, - buf, 0, NULL); - pr_inf("%s: %d\n", buf, config.reset_gpio); } else { - config.reset_gpio = -1; - pr_error("cannot find resource \"%s\"\n", buf); - goto error_fe; - } - - memset(buf, 0, 32); - snprintf(buf, sizeof(buf), "fe%d_reset_value",i); - ret = of_property_read_u32(pdev->dev.of_node, buf,&config.reset_value); - if (ret) { - pr_error("reset_value error\n"); - goto error_fe; + s_demod_type[i] = config.id; + pr_error("external dtvdemod [type = %d] attach success.\n", config.id); } - if (!strcmp(name,"Atbm8881")) { - frontend[i] = dvb_attach(atbm8881_attach,&config); - if (frontend[i] == NULL) { - pr_error("dvb attach demod error\n"); - goto error_fe; - } else { - pr_inf("dtvdemod attatch sucess\n"); - s_demod_type[i] = DEMOD_ATBM8881; - } - } if (frontend[i]) { ret = dvb_register_frontend(&advb->dvb_adapter, frontend[i]); if (ret) { @@ -447,31 +326,12 @@ int frontend_probe(struct platform_device *pdev) return 0; error_fe: for (i=0; ituners) @@ -485,33 +345,24 @@ int frontend_remove(void) int i; for (i=0; i +#include + +#include "dvb_frontend.h" + +#endif /* __DVB_COMMON_H__ */ diff --git a/drivers/stream_input/parser/esparser.c b/drivers/stream_input/parser/esparser.c index 1cc3ac9..f81ba0c 100644 --- a/drivers/stream_input/parser/esparser.c +++ b/drivers/stream_input/parser/esparser.c @@ -166,6 +166,7 @@ static ssize_t _esparser_write(const char __user *buf, dma_addr_t dma_addr = 0; u32 type = stbuf->type; + VDEC_PRINT_FUN_LINENO(__func__, __LINE__); if (type == BUF_TYPE_HEVC) parser_type = PARSER_VIDEO; else if (type == BUF_TYPE_VIDEO) @@ -250,6 +251,8 @@ static ssize_t _esparser_write(const char __user *buf, audio_data_parsed += len; threadrw_update_buffer_level(stbuf, len); + VDEC_PRINT_FUN_LINENO(__func__, __LINE__); + return len; } @@ -393,6 +396,8 @@ s32 esparser_init(struct stream_buf_s *buf, struct vdec_s *vdec) u32 parser_sub_rp; bool first_use = false; /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ + VDEC_PRINT_FUN_LINENO(__func__, __LINE__); + if (has_hevc_vdec() && (buf->type == BUF_TYPE_HEVC)) pts_type = PTS_TYPE_HEVC; else @@ -518,7 +523,9 @@ s32 esparser_init(struct stream_buf_s *buf, struct vdec_s *vdec) vdec->input.start); WRITE_PARSER_REG(PARSER_VIDEO_END_PTR, vdec->input.start + vdec->input.size - 8); - if (vdec_single(vdec)) { + if (vdec_single(vdec) || (vdec_get_debug_flags() & 0x2)) { + if (vdec_get_debug_flags() & 0x2) + pr_info("%s %d\n", __func__, __LINE__); CLEAR_PARSER_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR); @@ -596,6 +603,7 @@ s32 esparser_init(struct stream_buf_s *buf, struct vdec_s *vdec) pr_info("esparser_init: irq register failed.\n"); goto Err_2; } + VDEC_PRINT_FUN_LINENO(__func__, __LINE__); WRITE_PARSER_REG(PARSER_INT_STATUS, 0xffff); WRITE_PARSER_REG(PARSER_INT_ENABLE, @@ -849,6 +857,11 @@ ssize_t drm_write(struct file *file, struct stream_buf_s *stbuf, mutex_unlock(&esparser_mutex); } + if ((drm->drm_flag & TYPE_DRMINFO) && (drm->drm_hasesdata == 0)) { + havewritebytes = sizeof(struct drm_info); + } else if (drm->drm_hasesdata == 1) { + havewritebytes += sizeof(struct drm_info); + } return havewritebytes; } EXPORT_SYMBOL(drm_write); diff --git a/drivers/stream_input/parser/hw_demux/aml_demod_gt.h b/drivers/stream_input/parser/hw_demux/aml_demod_gt.h index 7d8ae11..77658b0 100644 --- a/drivers/stream_input/parser/hw_demux/aml_demod_gt.h +++ b/drivers/stream_input/parser/hw_demux/aml_demod_gt.h @@ -20,90 +20,7 @@ #ifndef __AML_DEMOD_GT_H__ #define __AML_DEMOD_GT_H__ -#include "dvb_frontend.h" +#include "../dvb_common.h" -struct amlfe_exp_config { - /*config by aml_fe ?*/ - /* */ - int set_mode; -}; -struct amlfe_demod_config { - int dev_id; - u32 ts; - struct i2c_adapter *i2c_adap; - int i2c_addr; - int reset_gpio; - int reset_value; - int ts_out_mode; //serial or parallel; 0:serial, 1:parallel - int tuner0_i2c_addr; - int tuner1_i2c_addr; - int tuner0_code; - int tuner1_code; -}; - -/* For configure different tuners */ -/* It can add fields as extensions */ -struct tuner_config { - u8 id; - u8 i2c_addr; - u8 xtal; /* 0: 16MHz, 1: 24MHz, 3: 27MHz */ - u8 xtal_cap; - u8 xtal_mode; -}; - -static inline struct dvb_frontend* aml_dtvdm_attach (const struct amlfe_exp_config *config) { - return NULL; -} - -static inline struct dvb_frontend* si2151_attach (struct dvb_frontend *fe,struct i2c_adapter *i2c, struct tuner_config *cfg) -{ - return NULL; -} - -static inline struct dvb_frontend* mxl661_attach (struct dvb_frontend *fe,struct i2c_adapter *i2c, struct tuner_config *cfg) -{ - return NULL; -} - -static inline struct dvb_frontend* si2159_attach (struct dvb_frontend *fe,struct i2c_adapter *i2c, struct tuner_config *cfg) -{ - return NULL; -} - -static inline struct dvb_frontend* r842_attach (struct dvb_frontend *fe, struct i2c_adapter *i2c, struct tuner_config *cfg) -{ - return NULL; -} - -static inline struct dvb_frontend* r840_attach (struct dvb_frontend *fe, struct i2c_adapter *i2c, struct tuner_config *cfg) -{ - return NULL; -} - -static inline struct dvb_frontend* atbm2040_attach (struct dvb_frontend *fe, struct i2c_adapter *i2c, struct tuner_config *cfg) -{ - return NULL; -} - -static inline struct dvb_frontend* atbm8881_attach (const struct amlfe_demod_config *config) -{ - return NULL; -} - -static inline struct dvb_frontend* si2168_attach (const struct amlfe_demod_config *config) -{ - return NULL; -} - -static inline struct dvb_frontend* si2168_attach_1 (const struct amlfe_demod_config *config) -{ - return NULL; -} - -static inline struct dvb_frontend* avl6762_attach (const struct amlfe_demod_config *config) -{ - return NULL; -} - -#endif /*__AML_DEMOD_GT_H__*/ +#endif /*__AML_DEMOD_GT_H__*/ diff --git a/drivers/stream_input/parser/hw_demux/aml_dmx.c b/drivers/stream_input/parser/hw_demux/aml_dmx.c index 52334da..974fcc6 100644 --- a/drivers/stream_input/parser/hw_demux/aml_dmx.c +++ b/drivers/stream_input/parser/hw_demux/aml_dmx.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "../streambuf.h" #include "c_stb_define.h" #include "c_stb_regs_define.h" @@ -73,6 +74,7 @@ #define pr_dbg_ss(args...) pr_dbg_flag(0x8, args) #define pr_dbg_irq_ss(args...) pr_dbg_irq_flag(0x8, args) #define pr_dbg_irq_pes(args...) pr_dbg_irq_flag(0x10, args) +#define pr_dbg_irq_sub(args...) pr_dbg_irq_flag(0x20, args) #ifdef PR_ERROR_SPEED_LIMIT static u32 last_pr_error_time; @@ -315,6 +317,7 @@ static int dsc_set_aes_des_sm4_key(struct aml_dsc_channel *ch, int flags, enum ca_cw_type type, u8 *key); static void aml_ci_plus_disable(void); static void am_ci_plus_set_output(struct aml_dsc_channel *ch); +static int set_subtitle_pes_buffer(struct aml_dmx *dmx); static void dmxn_op_chan(int dmx, int ch, int(*op)(int, int), int ch_op) { @@ -391,6 +394,15 @@ static void dmxn_op_chan(int dmx, int ch, int(*op)(int, int), int ch_op) } while (0) #define NO_SUB +#define SUB_BUF_DMX +#define SUB_PARSER + +#ifndef SUB_BUF_DMX +#undef SUB_PARSER +#endif + +#define SUB_BUF_SHARED +#define PES_BUF_SHARED #define SYS_CHAN_COUNT (4) #define SEC_GRP_LEN_0 (0xc) @@ -436,14 +448,14 @@ static int dmx_timeout_set(struct aml_dmxtimeout *dto, int enable, int force); /*Audio & Video PTS value*/ -static u32 video_pts; -static u32 audio_pts; -static u32 video_pts_bit32; -static u32 audio_pts_bit32; -static u32 first_video_pts; -static u32 first_audio_pts; +static u32 video_pts = 0; +static u32 audio_pts = 0; +static u32 video_pts_bit32 = 0; +static u32 audio_pts_bit32 = 0; +static u32 first_video_pts = 0; +static u32 first_audio_pts = 0; static int demux_skipbyte; -static int tsfile_clkdiv = 4; +static int tsfile_clkdiv = 5; static int asyncfifo_buf_len = ASYNCFIFO_BUFFER_SIZE_DEFAULT; #define SF_DMX_ID 2 @@ -668,7 +680,7 @@ static int section_crc(struct aml_dmx *dmx, struct aml_filter *f, u8 *p) sec->seclen = sec_len; sec->crc_val = ~0; if (demux->check_crc32(feed, p, sec_len)) { - pr_error("section CRC check failed!\n"); + pr_error("section CRC check failed! pid[%d]\n", feed->pid); #if 0 { @@ -1110,9 +1122,12 @@ static void process_sub(struct aml_dmx *dmx) u32 end_ptr = READ_MPEG_REG(PARSER_SUB_END_PTR); u32 buffer1 = 0, buffer2 = 0; - unsigned char *buffer1_virt = 0, *buffer2_virt = 0; + u8 *buffer1_virt = 0, *buffer2_virt = 0; u32 len1 = 0, len2 = 0; + if (!dmx->sub_buf_base_virt) + return; + rd_ptr = READ_MPEG_REG(PARSER_SUB_RP); if (!rd_ptr) return; @@ -1134,13 +1149,23 @@ static void process_sub(struct aml_dmx *dmx) } if (buffer1 && len1) - buffer1_virt = codec_mm_phys_to_virt(buffer1); +#ifdef SUB_BUF_DMX + buffer1_virt = (void *)dmx->sub_pages + (buffer1 - start_ptr); +#else + buffer1_virt = (void *)dmx->sub_buf_base_virt + (buffer1 - start_ptr); +#endif if (buffer2 && len2) - buffer2_virt = codec_mm_phys_to_virt(buffer2); +#ifdef SUB_BUF_DMX + buffer2_virt = (void *)dmx->sub_pages + (buffer2 - start_ptr); +#else + buffer2_virt = (void *)dmx->sub_buf_base_virt + (buffer2 - start_ptr); +#endif -// printk("rd_ptr %p buffer1 %p len1 %d buffer2 %p len2 %d buffer1_virt %p buffer2_virt %p\n", -// (void*)rd_ptr, (void*)buffer1, len1, (void*)buffer2, len2, buffer1_virt, buffer2_virt); + pr_dbg_irq_sub("sub: rd_ptr:%x buf1:%x len1:%d buf2:%x len2:%d\n", + rd_ptr, buffer1, len1, buffer2, len2); + pr_dbg_irq_sub("sub: buf1_virt:%p buf2_virt:%p\n", + buffer1_virt, buffer2_virt); if (len1) dma_sync_single_for_cpu(dmx_get_dev(dmx), @@ -1153,7 +1178,7 @@ static void process_sub(struct aml_dmx *dmx) if (dmx->channel[2].used) { if (dmx->channel[2].feed && dmx->channel[2].feed->cb.ts && - ((buffer1_virt != NULL && len1 !=0 ) | (buffer2_virt != NULL && len2 != 0))) + ((buffer1_virt != NULL && len1 !=0 ) || (buffer2_virt != NULL && len2 != 0))) { dmx->channel[2].feed->cb.ts(buffer1_virt, len1, buffer2_virt, len2, @@ -2429,13 +2454,22 @@ static int dmx_alloc_sec_buffer(struct aml_dmx *dmx) #ifdef NO_SUB /*Set subtitle buffer*/ -static int dmx_alloc_sub_buffer(struct aml_dmx *dmx) +static int dmx_alloc_sub_buffer(struct aml_dvb *dvb, struct aml_dmx *dmx) { +#ifdef SUB_BUF_DMX unsigned long addr; if (dmx->sub_pages) return 0; + /*check if use shared buf*/ + if (dvb->sub_pages) { + dmx->sub_pages = dvb->sub_pages; + dmx->sub_buf_len = dvb->sub_buf_len; + dmx->sub_pages_map = dvb->sub_pages_map; + goto end_alloc; + } + dmx->sub_buf_len = 64 * 1024; dmx->sub_pages = __get_free_pages(GFP_KERNEL, get_order(dmx->sub_buf_len)); @@ -2447,21 +2481,59 @@ static int dmx_alloc_sub_buffer(struct aml_dmx *dmx) dma_map_single(dmx_get_dev(dmx), (void *)dmx->sub_pages, dmx->sub_buf_len, DMA_FROM_DEVICE); +end_alloc: addr = virt_to_phys((void *)dmx->sub_pages); +#ifndef SUB_PARSER DMX_WRITE_REG(dmx->id, SB_START, addr >> 12); DMX_WRITE_REG(dmx->id, SB_LAST_ADDR, (dmx->sub_buf_len >> 3) - 1); +#endif + pr_inf("sub buff: (%d) %lx %x\n", dmx->id, addr, dmx->sub_buf_len); +#endif + return 0; +} +#ifdef SUB_BUF_SHARED +static int dmx_alloc_sub_buffer_shared(struct aml_dvb *dvb) +{ +#ifdef SUB_BUF_DMX + if (dvb->sub_pages) + return 0; + + dvb->sub_buf_len = 64 * 1024; + dvb->sub_pages = + __get_free_pages(GFP_KERNEL, get_order(dvb->sub_buf_len)); + if (!dvb->sub_pages) { + pr_error("cannot allocate subtitle buffer\n"); + return -1; + } + dvb->sub_pages_map = + dma_map_single(dvb->dev, (void *)dvb->sub_pages, + dvb->sub_buf_len, DMA_FROM_DEVICE); + + pr_inf("sub buff shared: %lx %x\n", + (unsigned long)virt_to_phys((void *)dvb->sub_pages), + dvb->sub_buf_len); +#endif return 0; } +#endif #endif /*NO_SUB */ /*Set PES buffer*/ -static int dmx_alloc_pes_buffer(struct aml_dmx *dmx) +static int dmx_alloc_pes_buffer(struct aml_dvb *dvb, struct aml_dmx *dmx) { unsigned long addr; if (dmx->pes_pages) return 0; + /*check if use shared buf*/ + if (dvb->pes_pages) { + dmx->pes_pages = dvb->pes_pages; + dmx->pes_buf_len = dvb->pes_buf_len; + dmx->pes_pages_map = dvb->pes_pages_map; + goto end_alloc; + } + dmx->pes_buf_len = 64 * 1024; dmx->pes_pages = __get_free_pages(GFP_KERNEL, get_order(dmx->pes_buf_len)); @@ -2472,12 +2544,37 @@ static int dmx_alloc_pes_buffer(struct aml_dmx *dmx) dmx->pes_pages_map = dma_map_single(dmx_get_dev(dmx), (void *)dmx->pes_pages, dmx->pes_buf_len, DMA_FROM_DEVICE); - +end_alloc: addr = virt_to_phys((void *)dmx->pes_pages); DMX_WRITE_REG(dmx->id, OB_START, addr >> 12); DMX_WRITE_REG(dmx->id, OB_LAST_ADDR, (dmx->pes_buf_len >> 3) - 1); + + pr_inf("pes buff: (%d) %lx %x\n", dmx->id, addr, dmx->pes_buf_len); + return 0; +} +#ifdef PES_BUF_SHARED +static int dmx_alloc_pes_buffer_shared(struct aml_dvb *dvb) +{ + if (dvb->pes_pages) + return 0; + + dvb->pes_buf_len = 64 * 1024; + dvb->pes_pages = + __get_free_pages(GFP_KERNEL, get_order(dvb->pes_buf_len)); + if (!dvb->pes_pages) { + pr_error("cannot allocate pes buffer\n"); + return -1; + } + dvb->pes_pages_map = + dma_map_single(dvb->dev, (void *)dvb->pes_pages, + dvb->pes_buf_len, DMA_FROM_DEVICE); + + pr_inf("pes buff shared: %lx %x\n", + (unsigned long)virt_to_phys((void *)dvb->pes_pages), + dvb->pes_buf_len); return 0; } +#endif /*Allocate ASYNC FIFO Buffer*/ static unsigned long asyncfifo_alloc_buffer(int len) @@ -2791,12 +2888,19 @@ static int dmx_init(struct aml_dmx *dmx) if (dmx_alloc_sec_buffer(dmx) < 0) return -1; #ifdef NO_SUB - if (dmx_alloc_sub_buffer(dmx) < 0) +#ifdef SUB_BUF_SHARED + if (dmx_alloc_sub_buffer_shared(dvb) < 0) return -1; #endif - if (dmx_alloc_pes_buffer(dmx) < 0) + if (dmx_alloc_sub_buffer(dvb, dmx) < 0) + return -1; +#endif +#ifdef PES_BUF_SHARED + if (dmx_alloc_pes_buffer_shared(dvb) < 0) + return -1; +#endif + if (dmx_alloc_pes_buffer(dvb, dmx) < 0) return -1; - /*Reset the hardware */ if (!dvb->dmx_init) { init_timer(&dvb->watchdog_timer); @@ -2848,6 +2952,16 @@ static int dmx_deinit(struct aml_dmx *dmx) dmx->sec_pages_map = 0; } #ifdef NO_SUB +#ifdef SUB_BUF_DMX +#ifdef SUB_BUF_SHARED + if (dvb->sub_pages) { + dma_unmap_single(dvb->dev, dvb->sub_pages_map, + dvb->sub_buf_len, DMA_FROM_DEVICE); + free_pages(dvb->sub_pages, get_order(dvb->sub_buf_len)); + dvb->sub_pages = 0; + } + dmx->sub_pages = 0; +#else if (dmx->sub_pages) { dma_unmap_single(dmx_get_dev(dmx), dmx->sub_pages_map, dmx->sub_buf_len, DMA_FROM_DEVICE); @@ -2855,13 +2969,24 @@ static int dmx_deinit(struct aml_dmx *dmx) dmx->sub_pages = 0; } #endif +#endif +#endif +#ifdef PES_BUF_SHARED + if (dvb->pes_pages) { + dma_unmap_single(dvb->dev, dvb->pes_pages_map, + dvb->pes_buf_len, DMA_FROM_DEVICE); + free_pages(dvb->pes_pages, get_order(dvb->pes_buf_len)); + dvb->pes_pages = 0; + } + dmx->pes_pages = 0; +#else if (dmx->pes_pages) { dma_unmap_single(dmx_get_dev(dmx), dmx->pes_pages_map, dmx->pes_buf_len, DMA_FROM_DEVICE); free_pages(dmx->pes_pages, get_order(dmx->pes_buf_len)); dmx->pes_pages = 0; } - +#endif if (dmx->dmx_irq != -1) { free_irq(dmx->dmx_irq, dmx); tasklet_kill(&dmx->dmx_tasklet); @@ -3359,10 +3484,14 @@ static int dmx_set_chan_regs(struct aml_dmx *dmx, int cid) DMX_READ_REG(dmx->id, OM_CMD_STATUS)); } - if (cid == 0) + if (cid == 0) { + video_pts = 0; first_video_pts = 0; - else if (cid == 1) + } + else if (cid == 1) { + audio_pts = 0; first_audio_pts = 0; + } return 0; } @@ -3776,7 +3905,7 @@ void dmx_reset_hw_ex(struct aml_dvb *dvb, int reset_irq) { u32 data; data = READ_MPEG_REG(STB_TOP_CONFIG); - ciplus = 0xF8000000 & data; + ciplus = 0x7C000000 & data; } WRITE_MPEG_REG(STB_TOP_CONFIG, 0); @@ -3850,14 +3979,16 @@ void dmx_reset_hw_ex(struct aml_dvb *dvb, int reset_irq) (SEC_GRP_LEN_2 << 8) | (SEC_GRP_LEN_3 << 12)); } - +#ifdef NO_SUB +#ifndef SUB_PARSER if (dmx->sub_pages) { addr = virt_to_phys((void *)dmx->sub_pages); DMX_WRITE_REG(dmx->id, SB_START, addr >> 12); DMX_WRITE_REG(dmx->id, SB_LAST_ADDR, (dmx->sub_buf_len >> 3) - 1); } - +#endif +#endif if (dmx->pes_pages) { addr = virt_to_phys((void *)dmx->pes_pages); DMX_WRITE_REG(dmx->id, OB_START, addr >> 12); @@ -3870,6 +4001,20 @@ void dmx_reset_hw_ex(struct aml_dvb *dvb, int reset_irq) /*if (chan->used)*/ { +#ifdef NO_SUB +#ifdef SUB_PARSER + /* + check if subtitle channel was running, + the parser will be used in amstream also, + take care of the buff ptr. + */ + u32 v = dmx_get_chan_target(dmx, n); + if (v != 0xFFFF && + (v & (0x7 << PID_TYPE)) + == (SUB_PACKET << PID_TYPE)) + set_subtitle_pes_buffer(dmx); +#endif +#endif dmx_set_chan_regs(dmx, n); } } @@ -3969,7 +4114,7 @@ void dmx_reset_dmx_hw_ex_unlock(struct aml_dvb *dvb, struct aml_dmx *dmx, { u32 data; data = READ_MPEG_REG(STB_TOP_CONFIG); - ciplus = 0xF8000000 & data; + ciplus = 0x7C000000 & data; } { @@ -4039,14 +4184,16 @@ void dmx_reset_dmx_hw_ex_unlock(struct aml_dvb *dvb, struct aml_dmx *dmx, (SEC_GRP_LEN_2 << 8) | (SEC_GRP_LEN_3 << 12)); } - +#ifdef NO_SUB +#ifndef SUB_PARSER if (dmx->sub_pages) { addr = virt_to_phys((void *)dmx->sub_pages); DMX_WRITE_REG(dmx->id, SB_START, addr >> 12); DMX_WRITE_REG(dmx->id, SB_LAST_ADDR, (dmx->sub_buf_len >> 3) - 1); } - +#endif +#endif if (dmx->pes_pages) { addr = virt_to_phys((void *)dmx->pes_pages); DMX_WRITE_REG(dmx->id, OB_START, addr >> 12); @@ -4059,6 +4206,20 @@ void dmx_reset_dmx_hw_ex_unlock(struct aml_dvb *dvb, struct aml_dmx *dmx, /*if (chan->used)*/ { +#ifdef NO_SUB +#ifdef SUB_PARSER + /* + check if subtitle channel was running, + the parser will be used in amstream also, + take care of the buff ptr. + */ + u32 v = dmx_get_chan_target(dmx, n); + if (v != 0xFFFF && + (v & (0x7 << PID_TYPE)) + == (SUB_PACKET << PID_TYPE)) + set_subtitle_pes_buffer(dmx); +#endif +#endif dmx_set_chan_regs(dmx, n); } } @@ -4189,6 +4350,42 @@ exit: } #endif +static int set_subtitle_pes_buffer(struct aml_dmx *dmx) +{ +#ifdef SUB_PARSER + unsigned long addr = virt_to_phys((void *)dmx->sub_pages); + WRITE_MPEG_REG(PARSER_SUB_RP, addr); + WRITE_MPEG_REG(PARSER_SUB_START_PTR, addr); + WRITE_MPEG_REG(PARSER_SUB_END_PTR, addr + dmx->sub_buf_len - 8); + pr_inf("set sub buff: (%d) %lx %x\n", dmx->id, addr, dmx->sub_buf_len); +#endif + return 0; +} + +int dmx_get_sub_buffer(unsigned long *base, unsigned long *virt) +{ +#ifndef SUB_BUF_DMX + unsigned long s = READ_MPEG_REG(PARSER_SUB_START_PTR); + if (base) + *base = s; + if (virt) + *virt = (unsigned long)codec_mm_phys_to_virt(s); +#endif + return 0; +} + +int dmx_init_sub_buffer(struct aml_dmx *dmx, unsigned long base, unsigned long virt) +{ +#ifndef SUB_BUF_DMX + dmx->sub_buf_base = base; + pr_inf("sub buf base: 0x%lx\n", dmx->sub_buf_base); + + dmx->sub_buf_base_virt = (u8 *)virt; + pr_inf("sub buf base virt: 0x%p\n", dmx->sub_buf_base_virt); +#endif + return 0; +} + /*Allocate a new channel*/ int dmx_alloc_chan(struct aml_dmx *dmx, int type, int pes_type, int pid) { @@ -4210,6 +4407,7 @@ int dmx_alloc_chan(struct aml_dmx *dmx, int type, int pes_type, int pid) if (!dmx->channel[2].used) id = 2; //alloc_subtitle_pes_buffer(dmx); + set_subtitle_pes_buffer(dmx); break; case DMX_PES_PCR: if (!dmx->channel[3].used) @@ -5751,3 +5949,17 @@ int aml_unregist_dmx_class(void) return 0; } +static struct mconfig parser_configs[] = { + MC_PU32("video_pts", &video_pts), + MC_PU32("audio_pts", &audio_pts), + MC_PU32("video_pts_bit32", &video_pts_bit32), + MC_PU32("audio_pts_bit32", &audio_pts_bit32), + MC_PU32("first_video_pts", &first_video_pts), + MC_PU32("first_audio_pts", &first_audio_pts), +}; + +void aml_register_parser_mconfig(void) +{ + REG_PATH_CONFIGS("media.parser", parser_configs); +} + diff --git a/drivers/stream_input/parser/hw_demux/aml_dvb.c b/drivers/stream_input/parser/hw_demux/aml_dvb.c index 1a5e174..7be153a 100644 --- a/drivers/stream_input/parser/hw_demux/aml_dvb.c +++ b/drivers/stream_input/parser/hw_demux/aml_dvb.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -54,33 +55,9 @@ #include "aml_dvb.h" #include "aml_dvb_reg.h" -#include "../../tv_frontend/aml_fe.h" #include "aml_demod_gt.h" #include "../../../common/media_clock/switch/amports_gate.h" -typedef enum __demod_type -{ - DEMOD_INVALID, - DEMOD_INTERNAL, - DEMOD_ATBM8881, - DEMOD_SI2168, - DEMOD_AVL6762, - DEMOD_SI2168_1, - DEMOD_MAX_NUM -}demod_type; - -typedef enum __tuner_type -{ - TUNER_INVALID, - TUNER_SI2151, - TUNER_MXL661, - TUNER_SI2159, - TUNER_R842, - TUNER_R840, - TUNER_ATBM2040, - TUNER_MAX_NUM -}tuner_type; - #define pr_dbg(args...)\ do {\ if (debug_dvb)\ @@ -95,7 +72,7 @@ module_param(debug_dvb, int, 0644); #define CARD_NAME "amlogic-dvb" - +#define DVB_VERSION "V2.00" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -107,8 +84,8 @@ static struct aml_dvb aml_dvb_device; static struct class aml_stb_class; static struct dvb_frontend *frontend[FE_DEV_COUNT] = {NULL, NULL}; -static demod_type s_demod_type[FE_DEV_COUNT] = {DEMOD_INVALID, DEMOD_INVALID}; -static tuner_type s_tuner_type[FE_DEV_COUNT] = {TUNER_INVALID, TUNER_INVALID}; +static enum dtv_demod_type s_demod_type[FE_DEV_COUNT] = {AM_DTV_DEMOD_NONE, AM_DTV_DEMOD_NONE}; +static enum tuner_type s_tuner_type[FE_DEV_COUNT] = {AM_TUNER_NONE, AM_TUNER_NONE}; static int dmx_reset_all_flag = 0; #if 0 static struct reset_control *aml_dvb_demux_reset_ctl; @@ -147,74 +124,6 @@ static struct tsdemux_ops aml_tsdemux_ops = { .set_demux = aml_tsdemux_set_demux }; -static int dvb_attach_tuner(struct dvb_frontend *fe, struct aml_tuner *tuner, tuner_type *type) -{ - struct tuner_config *cfg = &tuner->cfg; - struct i2c_adapter *i2c_adap = tuner->i2c_adp; - - switch (cfg->id) { - case AM_TUNER_R840: - if (!dvb_attach(r840_attach, fe, i2c_adap, cfg)) { - pr_error("dvb attach r840_attach tuner error\n"); - return -1; - } else { - pr_inf("r840_attach attach sucess\n"); - *type = TUNER_R840; - } - break; - case AM_TUNER_R842: - if (!dvb_attach(r842_attach, fe, i2c_adap, cfg)) { - pr_error("dvb attach r842_attach tuner error\n"); - return -1; - } else { - pr_inf("r842_attach attach sucess\n"); - *type = TUNER_R842; - } - break; - case AM_TUNER_SI2151: - if (!dvb_attach(si2151_attach, fe, i2c_adap, cfg)) { - pr_error("dvb attach tuner error\n"); - return -1; - } else { - pr_inf("si2151 attach sucess\n"); - *type = TUNER_SI2151; - } - break; - case AM_TUNER_SI2159: - if (!dvb_attach(si2159_attach, fe, i2c_adap, cfg)) { - pr_error("dvb attach si2159_attach tuner error\n"); - return -1; - } else { - pr_inf("si2159_attach attach sucess\n"); - *type = TUNER_SI2159; - } - break; - case AM_TUNER_MXL661: - if (!dvb_attach(mxl661_attach, fe, i2c_adap, cfg)) { - pr_error("dvb attach mxl661_attach tuner error\n"); - return -1; - } else { - pr_inf("mxl661_attach attach sucess\n"); - *type = TUNER_MXL661; - } - break; - case AM_TUNER_ATBM2040: - if (!dvb_attach(atbm2040_attach, fe, i2c_adap, cfg)) { - pr_error("dvb attach atbm2040_attach tuner error\n"); - return -1; - } else { - pr_inf("atbm2040_attach attach sucess\n"); - *type = TUNER_ATBM2040; - } - break; - default: - pr_error("can't support tuner type: %d\n", cfg->id); - break; - } - - return 0; -} - long aml_stb_get_base(int id) { int newbase = 0; @@ -786,7 +695,7 @@ static int aml_dvb_asyncfifo_init(struct aml_dvb *advb, res = platform_get_resource_byname(advb->pdev, IORESOURCE_IRQ, buf); if (res) asyncfifo->asyncfifo_irq = res->start; - pr_info("%s irq num:%d ", buf, asyncfifo->asyncfifo_irq); + pr_inf("%s irq num:%d \n", buf, asyncfifo->asyncfifo_irq); asyncfifo->dvb = advb; asyncfifo->id = id; asyncfifo->init = 0; @@ -1321,7 +1230,7 @@ static ssize_t demux##i##_reset_store(struct class *class, \ {\ if (!strncmp("1", buf, 1)) { \ struct aml_dvb *dvb = &aml_dvb_device; \ - pr_info("Reset demux["#i"], call dmx_reset_dmx_hw\n"); \ + pr_inf("Reset demux["#i"], call dmx_reset_dmx_hw\n"); \ dmx_reset_dmx_id_hw_ex(dvb, i, 0); \ } \ return size; \ @@ -1843,9 +1752,13 @@ static ssize_t stb_store_tuner_setting(struct class *class, if (frontend[i] == NULL) continue; - if (dvb_attach_tuner(frontend[i], tuner, &s_tuner_type[i]) < 0) { - pr_error("attach tuner %d failed\n", dvb->tuner_cur); + if (aml_attach_tuner(tuner->cfg.id, frontend[i], &tuner->cfg) == NULL) { + s_tuner_type[i] = AM_TUNER_NONE; + pr_error("tuner[%d] [type = %d] attach error.\n", dvb->tuner_cur, tuner->cfg.id); goto EXIT; + } else { + s_tuner_type[i] = tuner->cfg.id; + pr_error("tuner[%d] [type = %d] attach sucess.\n", dvb->tuner_cur, tuner->cfg.id); } } @@ -2016,7 +1929,7 @@ static int aml_dvb_probe(struct platform_device *pdev) int i, ret = 0; struct devio_aml_platform_data *pd_dvb; - pr_dbg("probe amlogic dvb driver\n"); + pr_dbg("probe amlogic dvb driver [%s]\n", DVB_VERSION); /*switch_mod_gate_by_name("demux", 1); */ #if 0 @@ -2251,6 +2164,7 @@ static int aml_dvb_probe(struct platform_device *pdev) goto error; } + aml_register_parser_mconfig(); #ifdef ENABLE_DEMUX_DRIVER tsdemux_set_ops(&aml_tsdemux_ops); #else @@ -2259,32 +2173,34 @@ static int aml_dvb_probe(struct platform_device *pdev) //pengcc add for dvb using linux TV frontend api init { - struct amlfe_exp_config config; + struct demod_config config; + struct tuner_config *tuner_cfg = NULL; char buf[32]; const char *str = NULL; struct device_node *node_tuner = NULL; - struct device_node *node_i2c = NULL; - u32 i2c_addr = 0xFFFFFFFF; u32 value = 0; int j = 0; for (i=0; idev.of_node, buf, &str); if (ret) { continue; } - if (!strcmp(str,"internal")) - { - config.set_mode = 0; - frontend[i] = dvb_attach(aml_dtvdm_attach,&config); + if (!strcmp(str, "internal")) { + config.mode = 0; + config.id = AM_DTV_DEMOD_AMLDTV; + frontend[i] = aml_attach_dtvdemod(config.id, &config); if (frontend[i] == NULL) { - pr_error("dvb attach demod error\n"); + s_demod_type[i] = AM_DTV_DEMOD_NONE; + pr_error("internal dtvdemod [type = %d] attach error.\n", config.id); goto error_fe; } else { - pr_inf("dtvdemod attatch sucess\n"); - s_demod_type[i] = DEMOD_INTERNAL; + s_demod_type[i] = config.id; + pr_error("internal dtvdemod [type = %d] attach success.\n", config.id); } memset(buf, 0, 32); @@ -2316,73 +2232,11 @@ static int aml_dvb_probe(struct platform_device *pdev) advb->tuner_cur = value; for (j = 0; j < advb->tuner_num; ++j) { - snprintf(buf, sizeof(buf), "tuner_name_%d", j); - ret = of_property_read_string(node_tuner, buf, &str); + ret = aml_get_dts_tuner_config(node_tuner, &advb->tuners[j].cfg, j); if (ret) { - //pr_error("tuner%d type error\n",i); - ret = 0; - continue; - } else { - if (!strncmp(str, "mxl661_tuner", 12)) - advb->tuners[j].cfg.id = AM_TUNER_MXL661; - else if (!strncmp(str, "si2151_tuner", 12)) - advb->tuners[j].cfg.id = AM_TUNER_SI2151; - else if (!strncmp(str, "si2159_tuner", 12)) - advb->tuners[j].cfg.id = AM_TUNER_SI2159; - else if (!strncmp(str, "r840_tuner", 10)) - advb->tuners[j].cfg.id = AM_TUNER_R840; - else if (!strncmp(str, "r842_tuner", 10)) - advb->tuners[j].cfg.id = AM_TUNER_R842; - else if (!strncmp(str, "atbm2040_tuner", 14)) - advb->tuners[i].cfg.id = AM_TUNER_ATBM2040; - else { - pr_err("nonsupport tuner: %s.\n", str); - advb->tuners[j].cfg.id = AM_TUNER_NONE; - } - } - - snprintf(buf, sizeof(buf), "tuner_i2c_adap_%d", j); - node_i2c = of_parse_phandle(node_tuner, buf, 0); - if (!node_i2c) { - pr_error("tuner_i2c_adap_id error\n"); - } else { - advb->tuners[j].i2c_adp = of_find_i2c_adapter_by_node(node_i2c); - of_node_put(node_i2c); - if (advb->tuners[j].i2c_adp == NULL) { - pr_error("i2c_get_adapter error\n"); - of_node_put(node_tuner); - goto error_fe; - } - } - - snprintf(buf, sizeof(buf), "tuner_i2c_addr_%d", j); - ret = of_property_read_u32(node_tuner, buf, &i2c_addr); - if (ret) { - pr_error("i2c_addr error\n"); + pr_err("can't find tuner.\n"); + goto error_fe; } - else - advb->tuners[j].cfg.i2c_addr = i2c_addr; - - snprintf(buf, sizeof(buf), "tuner_xtal_%d", j); - ret = of_property_read_u32(node_tuner, buf, &value); - if (ret) - pr_err("tuner_xtal error.\n"); - else - advb->tuners[j].cfg.xtal = value; - - snprintf(buf, sizeof(buf), "tuner_xtal_mode_%d", j); - ret = of_property_read_u32(node_tuner, buf, &value); - if (ret) - pr_err("tuner_xtal_mode error.\n"); - else - advb->tuners[j].cfg.xtal_mode = value; - - snprintf(buf, sizeof(buf), "tuner_xtal_cap_%d", j); - ret = of_property_read_u32(node_tuner, buf, &value); - if (ret) - pr_err("tuner_xtal_cap error.\n"); - else - advb->tuners[j].cfg.xtal_cap = value; } of_node_put(node_tuner); @@ -2391,9 +2245,14 @@ static int aml_dvb_probe(struct platform_device *pdev) frontend[i]->callback = NULL; if (advb->tuner_cur >= 0) { - if (dvb_attach_tuner(frontend[i], &advb->tuners[advb->tuner_cur], &s_tuner_type[i]) < 0) { - pr_error("attach tuner failed\n"); + tuner_cfg = &advb->tuners[advb->tuner_cur].cfg; + if (aml_attach_tuner(tuner_cfg->id, frontend[i], tuner_cfg) == NULL) { + s_tuner_type[i] = AM_TUNER_NONE; + pr_error("tuner [type = %d] attach error.\n", tuner_cfg->id); goto error_fe; + } else { + s_tuner_type[i] = tuner_cfg->id; + pr_error("tuner [type = %d] attach sucess.\n", tuner_cfg->id); } } @@ -2402,140 +2261,41 @@ static int aml_dvb_probe(struct platform_device *pdev) pr_error("register dvb frontend failed\n"); goto error_fe; } - } else if(!strcmp(str,"external")) { - const char *name = NULL; - struct amlfe_demod_config config; - - config.dev_id = i; - memset(buf, 0, 32); - snprintf(buf, sizeof(buf), "fe%d_demod",i); - ret = of_property_read_string(pdev->dev.of_node, buf, &name); + } else if(!strcmp(str, "external")) { + config.mode = 1; + config.id = AM_DTV_DEMOD_NONE; + ret = aml_get_dts_demod_config(pdev->dev.of_node, &config, i); if (ret) { - ret = 0; + pr_err("can't find demod %d.\n", i); continue; } memset(buf, 0, 32); - snprintf(buf, sizeof(buf), "fe%d_i2c_adap_id",i); - node_i2c = of_parse_phandle(pdev->dev.of_node,buf,0); - if (!node_i2c) { - pr_error("demod%d_i2c_adap_id error\n", i); - } else { - config.i2c_adap = of_find_i2c_adapter_by_node(node_i2c); - of_node_put(node_i2c); - if (config.i2c_adap == NULL) { - pr_error("i2c_get_adapter error\n"); - goto error_fe; - } - } - - memset(buf, 0, 32); - snprintf(buf, sizeof(buf), "fe%d_demod_i2c_addr",i); - ret = of_property_read_u32(pdev->dev.of_node, buf,&config.i2c_addr); - if (ret) { - pr_error("i2c_addr error\n"); - goto error_fe; - } + snprintf(buf, sizeof(buf), "fe%d_tuner", i); + node_tuner = of_parse_phandle(pdev->dev.of_node, buf, 0); + if (node_tuner) { + aml_get_dts_tuner_config(node_tuner, &config.tuner0, 0); + aml_get_dts_tuner_config(node_tuner, &config.tuner1, 1); + } else + pr_err("can't find %s.\n", buf); - memset(buf, 0, 32); - snprintf(buf, sizeof(buf), "fe%d_ts",i); - ret = of_property_read_u32(pdev->dev.of_node, buf,&config.ts); - if (ret) { - pr_error("ts error\n"); - goto error_fe; - } + of_node_put(node_tuner); - memset(buf, 0, 32); - snprintf(buf, sizeof(buf), "fe%d_reset_gpio",i); - ret = of_property_read_string(pdev->dev.of_node, buf, &str); - if (!ret) { - config.reset_gpio = - of_get_named_gpio_flags(pdev->dev.of_node, - buf, 0, NULL); - pr_inf("%s: %d\n", buf, config.reset_gpio); - } else { - config.reset_gpio = -1; - pr_error("cannot find resource \"%s\"\n", buf); - goto error_fe; - } + if (advb->ts[config.ts].mode == AM_TS_PARALLEL) + config.ts_out_mode = 1; + else + config.ts_out_mode = 0; - memset(buf, 0, 32); - snprintf(buf, sizeof(buf), "fe%d_reset_value",i); - ret = of_property_read_u32(pdev->dev.of_node, buf,&config.reset_value); - if (ret) { - pr_error("reset_value error\n"); + frontend[i] = aml_attach_dtvdemod(config.id, &config); + if (frontend[i] == NULL) { + s_demod_type[i] = AM_DTV_DEMOD_NONE; + pr_error("external dtvdemod [type = %d] attach error.\n", config.id); goto error_fe; - } - memset(buf, 0, 32); - snprintf(buf, sizeof(buf), "fe%d_tuner0_i2c_addr",i); - ret = of_property_read_u32(pdev->dev.of_node, buf,&config.tuner0_i2c_addr); - if (ret) { - pr_error("no tuner0 i2c_addr define\n"); - } - memset(buf, 0, 32); - snprintf(buf, sizeof(buf), "fe%d_tuner1_i2c_addr",i); - ret = of_property_read_u32(pdev->dev.of_node, buf,&config.tuner1_i2c_addr); - if (ret) { - pr_error("no tuner1 addr define\n"); - } - memset(buf, 0, 32); - snprintf(buf, sizeof(buf), "fe%d_tuner0_code",i); - ret = of_property_read_u32(pdev->dev.of_node, buf,&config.tuner0_code); - if (ret) { - pr_error("no tuner0_code define\n"); - } - memset(buf, 0, 32); - snprintf(buf, sizeof(buf), "fe%d_tuner1_code",i); - ret = of_property_read_u32(pdev->dev.of_node, buf,&config.tuner1_code); - if (ret) { - pr_error("no tuner1_code define\n"); - } - if (advb->ts[config.ts].mode == AM_TS_PARALLEL) { - config.ts_out_mode = 1; } else { - config.ts_out_mode = 0; + s_demod_type[i] = config.id; + pr_error("external dtvdemod [type = %d] attach success.\n", config.id); } - if (!strcmp(name,"Atbm8881")) { - frontend[i] = dvb_attach(atbm8881_attach,&config); - if (frontend[i] == NULL) { - pr_error("dvb attach demod error\n"); - goto error_fe; - } else { - pr_inf("dtvdemod attatch sucess\n"); - s_demod_type[i] = DEMOD_ATBM8881; - } - } - if (!strcmp(name,"Si2168")) { - frontend[i] = dvb_attach(si2168_attach,&config); - if (frontend[i] == NULL) { - pr_error("dvb attach demod error\n"); - goto error_fe; - } else { - pr_inf("dtvdemod attatch sucess\n"); - s_demod_type[i] = DEMOD_SI2168; - } - } - if (!strcmp(name,"Si2168-1")) { - frontend[i] = dvb_attach(si2168_attach_1,&config); - if (frontend[i] == NULL) { - pr_error("dvb attach demod error\n"); - goto error_fe; - } else { - pr_inf("si2168_1 dtvdemod attatch sucess\n"); - s_demod_type[i] = DEMOD_SI2168_1; - } - } - if (!strcmp(name,"Avl6762")) { - frontend[i] = dvb_attach(avl6762_attach,&config); - if (frontend[i] == NULL) { - pr_error("dvb attach demod error\n"); - goto error_fe; - } else { - pr_inf("dtvdemod attatch sucess\n"); - s_demod_type[i] = DEMOD_AVL6762; - } - } if (frontend[i]) { ret = dvb_register_frontend(&advb->dvb_adapter, frontend[i]); if (ret) { @@ -2548,44 +2308,14 @@ static int aml_dvb_probe(struct platform_device *pdev) return 0; error_fe: for (i=0; i #include #include -#include #include #include @@ -213,9 +212,16 @@ struct aml_dmx { unsigned long pes_pages; unsigned long pes_pages_map; int pes_buf_len; - unsigned long sub_pages; - unsigned long sub_pages_map; + union { + unsigned long sub_pages; + unsigned long sub_buf_base; + }; + union { + unsigned long sub_pages_map; + u8 *sub_buf_base_virt; + }; int sub_buf_len; + struct aml_channel channel[CHANNEL_COUNT+1]; struct aml_filter filter[FILTER_COUNT+1]; irq_handler_t irq_handler; @@ -301,12 +307,6 @@ struct aml_swfilter { int track_dmx; }; -struct aml_tuner { - struct tuner_config cfg; - unsigned int i2c_adapter_id; - struct i2c_adapter *i2c_adp; -}; - struct aml_dvb { struct dvb_device dvb_dev; int ts_in_total_count; @@ -334,6 +334,16 @@ struct aml_dvb { unsigned int tuner_cur; struct aml_tuner *tuners; bool tuner_attached; + + /*bufs for dmx shared*/ + unsigned long pes_pages; + unsigned long pes_pages_map; + int pes_buf_len; + unsigned long sub_pages; + unsigned long sub_pages_map; + int sub_buf_len; + + }; @@ -359,6 +369,9 @@ extern void dmx_free_chan(struct aml_dmx *dmx, int cid); extern int dmx_get_ts_serial(enum aml_ts_source_t src); +extern int dmx_get_sub_buffer(unsigned long *base, unsigned long *virt); +extern int dmx_init_sub_buffer(struct aml_dmx *dmx, unsigned long base, unsigned long virt); + /*AMLogic dsc interface*/ extern int dsc_set_pid(struct aml_dsc_channel *ch, int pid); extern int dsc_set_key(struct aml_dsc_channel *ch, int flags, @@ -386,6 +399,7 @@ extern struct aml_dvb *aml_get_dvb_device(void); extern int aml_regist_dmx_class(void); extern int aml_unregist_dmx_class(void); +extern void aml_register_parser_mconfig(void); struct devio_aml_platform_data { int (*io_setup)(void *); diff --git a/drivers/stream_input/parser/streambuf.c b/drivers/stream_input/parser/streambuf.c index 256afb9..1060770 100644 --- a/drivers/stream_input/parser/streambuf.c +++ b/drivers/stream_input/parser/streambuf.c @@ -277,6 +277,8 @@ s32 stbuf_init(struct stream_buf_s *buf, struct vdec_s *vdec, bool is_multi) u32 dummy; u32 addr32; + VDEC_PRINT_FUN_LINENO(__func__, __LINE__); + if (!buf->buf_start) { r = _stbuf_alloc(buf, (vdec) ? vdec->port_flag & PORT_FLAG_DRM : 0); @@ -302,10 +304,9 @@ s32 stbuf_init(struct stream_buf_s *buf, struct vdec_s *vdec, bool is_multi) } buf->write_thread = 0; - - if ((vdec && !vdec_single(vdec)) || (is_multi)) + if (((vdec && !vdec_single(vdec)) || (is_multi)) && + (vdec_get_debug_flags() & 0x2) == 0) return 0; - if (has_hevc_vdec() && buf->type == BUF_TYPE_HEVC) { CLEAR_VREG_MASK(HEVC_STREAM_CONTROL, 1); WRITE_VREG(HEVC_STREAM_START_ADDR, addr32); @@ -317,6 +318,8 @@ s32 stbuf_init(struct stream_buf_s *buf, struct vdec_s *vdec, bool is_multi) } if (buf->type == BUF_TYPE_VIDEO) { + VDEC_PRINT_FUN_LINENO(__func__, __LINE__); + _WRITE_ST_REG(CONTROL, 0); /* reset VLD before setting all pointers */ WRITE_VREG(VLD_MEM_VIFIFO_WRAP_COUNT, 0); diff --git a/drivers/stream_input/parser/tsdemux.c b/drivers/stream_input/parser/tsdemux.c index ac34cf7..e3f61fe 100644 --- a/drivers/stream_input/parser/tsdemux.c +++ b/drivers/stream_input/parser/tsdemux.c @@ -597,9 +597,11 @@ s32 tsdemux_init(u32 vid, u32 aid, u32 sid, u32 pcrid, bool is_hevc, WRITE_AIU_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); CLEAR_AIU_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - WRITE_PARSER_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr); - WRITE_PARSER_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr); - WRITE_PARSER_REG(PARSER_SUB_RP, parser_sub_rp); + if (!enable_demux_driver()) { + WRITE_PARSER_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr); + WRITE_PARSER_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr); + WRITE_PARSER_REG(PARSER_SUB_RP, parser_sub_rp); + } SET_PARSER_REG_MASK(PARSER_ES_CONTROL, (7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR); @@ -967,6 +969,12 @@ ssize_t tsdemux_write(struct file *file, return -EAGAIN; } +int get_discontinue_counter(void) +{ + return discontinued_counter; +} +EXPORT_SYMBOL(get_discontinue_counter); + static ssize_t show_discontinue_counter(struct class *class, struct class_attribute *attr, char *buf) { diff --git a/drivers/stream_input/parser/tsdemux.h b/drivers/stream_input/parser/tsdemux.h index f63bcdf..5f82309 100644 --- a/drivers/stream_input/parser/tsdemux.h +++ b/drivers/stream_input/parser/tsdemux.h @@ -88,6 +88,7 @@ extern u8 tsdemux_pcrvideo_valid(void); extern u32 tsdemux_first_pcrscr_get(void); extern void timestamp_pcrscr_enable(u32 enable); extern void timestamp_pcrscr_set(u32 pts); +int get_discontinue_counter(void); int tsdemux_class_register(void); void tsdemux_class_unregister(void); diff --git a/drivers/stream_input/tv_frontend/Makefile b/drivers/stream_input/tv_frontend/Makefile deleted file mode 100644 index 404c513..0000000 --- a/drivers/stream_input/tv_frontend/Makefile +++ b/dev/null @@ -1,16 +0,0 @@ -obj-m += aml_hardware_fe.o - -ccflags-y += -I$(srctree)/drivers/media/dvb-core -I$(srctree)/drivers/gpio -I$(srctree)/include - -aml_hardware_fe-objs += aml_fe.o - -# aml_atvdemod-objs += atv_demod/atvdemod_frontend.o -# aml_atvdemod-objs += atv_demod/atvdemod_func.o - -# aml_dtvdemod-objs += dtv_demod/aml_demod.o -# aml_dtvdemod-objs += dtv_demod/amlfrontend.o -# aml_dtvdemod-objs += dtv_demod/demod_func.o -# aml_dtvdemod-objs += dtv_demod/dvbc_func.o -# aml_dtvdemod-objs += dtv_demod/dvbt_func.o -# aml_dtvdemod-objs += dtv_demod/i2c_func.o -# aml_dtvdemod-objs += dtv_demod/tuner_func.o diff --git a/drivers/stream_input/tv_frontend/aml_fe.c b/drivers/stream_input/tv_frontend/aml_fe.c deleted file mode 100644 index 6253def..0000000 --- a/drivers/stream_input/tv_frontend/aml_fe.c +++ b/dev/null @@ -1,1372 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -/* - * AMLOGIC DVB frontend driver. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/*add for gpio api by hualing.chen*/ -#include - -#include "aml_fe.h" - -#ifdef pr_dbg -#undef pr_dbg -#endif - -#define pr_dbg(fmt, args ...) \ - pr_info("FE: " fmt, ## args) -#define pr_error(fmt, args ...) pr_err("FE: " fmt, ## args) -#define pr_inf(fmt, args ...) pr_info("FE: " fmt, ## args) - -static DEFINE_SPINLOCK(lock); -static struct aml_fe_drv *tuner_drv_list; -static struct aml_fe_drv *atv_demod_drv_list; -static struct aml_fe_drv *dtv_demod_drv_list; -static struct aml_fe_man fe_man; -static long aml_fe_suspended; - -static int aml_fe_set_sys(struct dvb_frontend *dev, - enum fe_delivery_system sys); - -static struct aml_fe_drv **aml_get_fe_drv_list(enum aml_fe_dev_type_t type) -{ - switch (type) { - case AM_DEV_TUNER: - return &tuner_drv_list; - case AM_DEV_ATV_DEMOD: - return &atv_demod_drv_list; - case AM_DEV_DTV_DEMOD: - return &dtv_demod_drv_list; - default: - return NULL; - } -} - - - -int amlogic_gpio_direction_output(unsigned int pin, int value, - const char *owner) -{ - gpio_direction_output(pin, value); - return 0; -} -EXPORT_SYMBOL(amlogic_gpio_direction_output); -int amlogic_gpio_request(unsigned int pin, const char *label) -{ - return 0; -} -EXPORT_SYMBOL(amlogic_gpio_request); -int aml_register_fe_drv(enum aml_fe_dev_type_t type, struct aml_fe_drv *drv) -{ - if (drv) { - struct aml_fe_drv **list = aml_get_fe_drv_list(type); - unsigned long flags; - - spin_lock_irqsave(&lock, flags); - - drv->next = *list; - *list = drv; - - drv->ref = 0; - - spin_unlock_irqrestore(&lock, flags); - } - - return 0; -} -EXPORT_SYMBOL(aml_register_fe_drv); - -int aml_unregister_fe_drv(enum aml_fe_dev_type_t type, struct aml_fe_drv *drv) -{ - int ret = 0; - - if (drv) { - struct aml_fe_drv *pdrv, *pprev; - struct aml_fe_drv **list = aml_get_fe_drv_list(type); - unsigned long flags; - - spin_lock_irqsave(&lock, flags); - - if (!drv->ref) { - for (pprev = NULL, pdrv = *list; - pdrv; pprev = pdrv, pdrv = pdrv->next) { - if (pdrv == drv) { - if (pprev) - pprev->next = pdrv->next; - else - *list = pdrv->next; - break; - } - } - } else { - pr_error("fe driver %d is inused\n", drv->id); - ret = -1; - } - - spin_unlock_irqrestore(&lock, flags); - } - - return ret; -} -EXPORT_SYMBOL(aml_unregister_fe_drv); - -static int aml_fe_support_sys(struct aml_fe *fe, - enum fe_delivery_system sys) -{ - if (fe->dtv_demod - && fe->dtv_demod->drv - && fe->dtv_demod->drv->support) { - if (!fe->dtv_demod->drv->support(fe->dtv_demod, sys)) - return 0; - } - - if (fe->atv_demod - && fe->atv_demod->drv - && fe->atv_demod->drv->support) { - if (!fe->atv_demod->drv->support(fe->atv_demod, sys)) - return 0; - } - - if (fe->tuner - && fe->tuner->drv - && fe->tuner->drv->support) { - if (!fe->tuner->drv->support(fe->tuner, sys)) - return 0; - } - - return 1; -} -/* - *#define DTV_START_BLIND_SCAN 71 - *#define DTV_CANCEL_BLIND_SCAN 72 - *#define DTV_BLIND_SCAN_MIN_FRE 73 - *#define DTV_BLIND_SCAN_MAX_FRE 74 - *#define DTV_BLIND_SCAN_MIN_SRATE 75 - *#define DTV_BLIND_SCAN_MAX_SRATE 76 - *#define DTV_BLIND_SCAN_FRE_RANGE 77 - *#define DTV_BLIND_SCAN_FRE_STEP 78 - *#define DTV_BLIND_SCAN_TIMEOUT 79 - */ -static int aml_fe_blind_cmd(struct dvb_frontend *dev, - struct dtv_property *tvp) -{ - struct aml_fe *fe; - int ret = 0; - - fe = dev->demodulator_priv; - pr_error("fe blind cmd into cmd:[%d]\n", tvp->cmd); - switch (tvp->cmd) { - case DTV_START_BLIND_SCAN: - if (fe->dtv_demod - && fe->dtv_demod->drv - && fe->dtv_demod->drv->start_blind_scan) { - ret = fe->dtv_demod->drv->start_blind_scan( - fe->dtv_demod); - } else { - pr_error("fe dtv_demod not surport blind start\n"); - } - break; - case DTV_CANCEL_BLIND_SCAN: - if (fe->dtv_demod - && fe->dtv_demod->drv - && fe->dtv_demod->drv->stop_blind_scan) { - ret = fe->dtv_demod->drv->stop_blind_scan( - fe->dtv_demod); - } else { - pr_error("fe dtv_demod not surport blind stop\n"); - } - break; - case DTV_BLIND_SCAN_MIN_FRE: - fe->blind_scan_para.minfrequency = tvp->u.data; - break; - case DTV_BLIND_SCAN_MAX_FRE: - fe->blind_scan_para.maxfrequency = tvp->u.data; - break; - case DTV_BLIND_SCAN_MIN_SRATE: - fe->blind_scan_para.minSymbolRate = tvp->u.data; - break; - case DTV_BLIND_SCAN_MAX_SRATE: - fe->blind_scan_para.maxSymbolRate = tvp->u.data; - break; - case DTV_BLIND_SCAN_FRE_RANGE: - fe->blind_scan_para.frequencyRange = tvp->u.data; - break; - case DTV_BLIND_SCAN_FRE_STEP: - fe->blind_scan_para.frequencyStep = tvp->u.data; - break; - case DTV_BLIND_SCAN_TIMEOUT: - fe->blind_scan_para.timeout = tvp->u.data; - break; - default: - ret = 0; - break; - } - return ret; -} - -static int aml_fe_set_property(struct dvb_frontend *dev, - struct dtv_property *tvp) -{ - struct aml_fe *fe; - int r = 0; - - fe = dev->demodulator_priv; - - if (tvp->cmd == DTV_DELIVERY_SYSTEM) { - enum fe_delivery_system sys = tvp->u.data; - - pr_error("fe aml_fe_set_property %d\n", sys); - r = aml_fe_set_sys(dev, sys); - if (r < 0) - return r; - } - - if (tvp->cmd == DTV_DELIVERY_SUB_SYSTEM) { - int sub_sys = tvp->u.data; - - pr_error("fe aml_fe_set_property sub_sys: %d\n", sub_sys); - fe->sub_sys = sub_sys; - r = 0; - } - pr_error("fe aml_fe_set_property -tvp->cmd[%d]\n", tvp->cmd); - switch (tvp->cmd) { - case DTV_START_BLIND_SCAN: - case DTV_CANCEL_BLIND_SCAN: - case DTV_BLIND_SCAN_MIN_FRE: - case DTV_BLIND_SCAN_MAX_FRE: - case DTV_BLIND_SCAN_MIN_SRATE: - case DTV_BLIND_SCAN_MAX_SRATE: - case DTV_BLIND_SCAN_FRE_RANGE: - case DTV_BLIND_SCAN_FRE_STEP: - case DTV_BLIND_SCAN_TIMEOUT: - r = aml_fe_blind_cmd(dev, tvp); - if (r < 0) - return r; - default: - break; - } - - if (fe->set_property) { - pr_error("fe fe->set_property -0\n"); - return fe->set_property(dev, tvp); - } - pr_error("fe aml_fe_set_property -2\n"); - return r; -} - -static int aml_fe_get_property(struct dvb_frontend *dev, - struct dtv_property *tvp) -{ - struct aml_fe *fe; - int r = 0; - - fe = dev->demodulator_priv; - - if (tvp->cmd == DTV_TS_INPUT) - tvp->u.data = fe->ts; - if (tvp->cmd == DTV_DELIVERY_SUB_SYSTEM) { - tvp->u.data = fe->sub_sys; - pr_error("fe aml_fe_get_property sub_sys: %d\n", fe->sub_sys); - r = 0; - } - if (fe->get_property) - return fe->get_property(dev, tvp); - - return r; -} - -static int aml_fe_set_sys(struct dvb_frontend *dev, - enum fe_delivery_system sys) -{ - struct aml_fe *fe = dev->demodulator_priv; - unsigned long flags; - int ret = -1; - - if (fe->sys == sys) { - pr_dbg("[%s]:the mode is not change!!!!\n", __func__); - return 0; - } - /*set dvb-t or dvb-t2 - * if dvb-t or t2 is set - * we only set sys value, not init sys - */ - if (fe->sys != SYS_UNDEFINED) { - pr_dbg("release system %d\n", fe->sys); - - if (fe->dtv_demod - && fe->dtv_demod->drv - && fe->dtv_demod->drv->release_sys) - fe->dtv_demod->drv->release_sys(fe->dtv_demod, fe->sys); - if (fe->atv_demod - && fe->atv_demod->drv - && fe->atv_demod->drv->release_sys) - fe->atv_demod->drv->release_sys(fe->atv_demod, fe->sys); - if (fe->tuner - && fe->tuner->drv - && fe->tuner->drv->release_sys) - fe->tuner->drv->release_sys(fe->tuner, fe->sys); - - fe->set_property = NULL; - fe->get_property = NULL; - - fe->sys = SYS_UNDEFINED; - } - - if (sys == SYS_UNDEFINED) - return 0; - - if (!aml_fe_support_sys(fe, sys)) { - int i; - - spin_lock_irqsave(&lock, flags); - for (i = 0; i < FE_DEV_COUNT; i++) { - if (aml_fe_support_sys(&fe_man.fe[i], sys) - && (fe_man.fe[i].dev_id == fe->dev_id)) - break; - } - spin_unlock_irqrestore(&lock, flags); - - if (i >= FE_DEV_COUNT) { - pr_error("do not support delivery system %d\n", sys); - return -1; - } - - fe = &fe_man.fe[i]; - dev->demodulator_priv = fe; - } - - spin_lock_irqsave(&fe->slock, flags); - - memset(&fe->fe->ops.tuner_ops, 0, sizeof(fe->fe->ops.tuner_ops)); - memset(&fe->fe->ops.analog_ops, 0, sizeof(fe->fe->ops.analog_ops)); - memset(&fe->fe->ops.info, 0, sizeof(fe->fe->ops.info)); - fe->fe->ops.release = NULL; - fe->fe->ops.release_sec = NULL; - fe->fe->ops.init = NULL; - fe->fe->ops.sleep = NULL; - fe->fe->ops.write = NULL; - fe->fe->ops.tune = NULL; - fe->fe->ops.get_frontend_algo = NULL; - fe->fe->ops.set_frontend = NULL; - fe->fe->ops.get_tune_settings = NULL; - fe->fe->ops.get_frontend = NULL; - fe->fe->ops.read_status = NULL; - fe->fe->ops.read_ber = NULL; - fe->fe->ops.read_signal_strength = NULL; - fe->fe->ops.read_snr = NULL; - fe->fe->ops.read_ucblocks = NULL; - fe->fe->ops.diseqc_reset_overload = NULL; - fe->fe->ops.diseqc_send_master_cmd = NULL; - fe->fe->ops.diseqc_recv_slave_reply = NULL; - fe->fe->ops.diseqc_send_burst = NULL; - fe->fe->ops.set_tone = NULL; - fe->fe->ops.set_voltage = NULL; - fe->fe->ops.enable_high_lnb_voltage = NULL; - fe->fe->ops.dishnetwork_send_legacy_command = NULL; - fe->fe->ops.i2c_gate_ctrl = NULL; - fe->fe->ops.ts_bus_ctrl = NULL; - fe->fe->ops.search = NULL; - fe->fe->ops.set_property = NULL; - fe->fe->ops.get_property = NULL; - - if (fe->tuner - && fe->tuner->drv - && fe->tuner->drv->get_ops) - fe->tuner->drv->get_ops(fe->tuner, sys, &fe->fe->ops); - - if (fe->atv_demod - && fe->atv_demod->drv - && fe->atv_demod->drv->get_ops) - fe->atv_demod->drv->get_ops(fe->atv_demod, sys, &fe->fe->ops); - - if (fe->dtv_demod - && fe->dtv_demod->drv - && fe->dtv_demod->drv->get_ops) - fe->dtv_demod->drv->get_ops(fe->dtv_demod, sys, &fe->fe->ops); - - spin_unlock_irqrestore(&fe->slock, flags); - - pr_dbg("init system %d\n", sys); - - if (fe->dtv_demod - && fe->dtv_demod->drv - && fe->dtv_demod->drv->init_sys) - ret = fe->dtv_demod->drv->init_sys(fe->dtv_demod, sys); - if (fe->atv_demod - && fe->atv_demod->drv - && fe->atv_demod->drv->init_sys) - ret = fe->atv_demod->drv->init_sys(fe->atv_demod, sys); - if (fe->tuner - && fe->tuner->drv - && fe->tuner->drv->init_sys) - ret = fe->tuner->drv->init_sys(fe->tuner, sys); - - if (ret != 0) { - pr_error("init system, %d fail, ret %d\n", sys, ret); - goto end; - } - - fe->set_property = fe->fe->ops.set_property; - fe->get_property = fe->fe->ops.get_property; - - strcpy(fe->fe->ops.info.name, "amlogic dvb frontend"); - fe->sys = sys; - pr_dbg("set mode ok\n"); - -end: - fe->fe->ops.set_property = aml_fe_set_property; - fe->fe->ops.get_property = aml_fe_get_property; - - return 0; -} - -static const char *aml_fe_dev_type_str(struct aml_fe_dev *dev) -{ - switch (dev->type) { - case AM_DEV_TUNER: - return "tuner"; - case AM_DEV_ATV_DEMOD: - return "atv_demod"; - case AM_DEV_DTV_DEMOD: - return "dtv_demod"; - } - - return ""; -} - -static void aml_fe_property_name(struct aml_fe_dev *dev, const char *name, - char *buf) -{ - const char *tstr; - - tstr = aml_fe_dev_type_str(dev); - - if (name) - sprintf(buf, "%s%d_%s", tstr, dev->dev_id, name); - else - sprintf(buf, "%s%d", tstr, dev->dev_id); -} - -int aml_fe_of_property_string(struct aml_fe_dev *dev, - const char *name, const char **str) -{ - struct platform_device *pdev = dev->man->pdev; - //char buf[128]; - int r; - - //aml_fe_property_name(dev, name, buf); - pr_error("start find resource: \"%s\" --\n", name); - r = of_property_read_string(pdev->dev.of_node, name, str); - if (r) - pr_error("cannot find resource: \"%s\"\n", name); - - return r; -} -EXPORT_SYMBOL(aml_fe_of_property_string); - -int aml_fe_of_property_u32(struct aml_fe_dev *dev, - const char *name, u32 *v) -{ - struct platform_device *pdev = dev->man->pdev; - //char buf[128]; - int r; - - //aml_fe_property_name(dev, name, buf); - r = of_property_read_u32(pdev->dev.of_node, name, v); - if (r) - pr_error("cannot find resource \"%s\"\n", name); - - return r; -} -EXPORT_SYMBOL(aml_fe_of_property_u32); - -static int aml_fe_dev_init(struct aml_fe_man *man, - enum aml_fe_dev_type_t type, - struct aml_fe_dev *dev, - int id) -{ - struct aml_fe_drv **list = aml_get_fe_drv_list(type); - struct aml_fe_drv *drv; - unsigned long flags; - char buf[128]; - const char *str; - char *name = NULL; - u32 value; - int ret; - struct device_node *node; - - dev->man = man; - dev->dev_id = id; - dev->type = type; - dev->drv = NULL; - dev->fe = NULL; - dev->priv_data = NULL; - - memset(buf, 0, 128); - name = NULL; - aml_fe_property_name(dev, name, buf); - pr_dbg("get string: %s\n", buf); - ret = aml_fe_of_property_string(dev, buf, &str); - if (ret) { - pr_dbg("get string: %s error\n", buf); - return 0; - } - - - spin_lock_irqsave(&lock, flags); - - for (drv = *list; drv; drv = drv->next) - if (!strcmp(drv->name, str)) - break; - - if (dev->drv != drv) { - if (dev->drv) { - dev->drv->ref--; - if (dev->drv->owner) - module_put(dev->drv->owner); - } - if (drv) { - drv->ref++; - if (drv->owner) - try_module_get(drv->owner); - } - dev->drv = drv; - } - - spin_unlock_irqrestore(&lock, flags); - - if (drv) { - pr_inf("found driver: %s\n", str); - } else { - pr_err("cannot find driver: %s\n", str); - return -1; - } - /*get i2c adap and i2c addr*/ - memset(buf, 0, 128); - name = "i2c_adap"; - aml_fe_property_name(dev, name, buf); - pr_dbg("get u32: %s\n", buf); - //ret = aml_fe_of_property_u32(dev, buf, &value); - node = of_parse_phandle(dev->man->pdev->dev.of_node, buf, 0); - if (node) { - dev->i2c_adap = of_find_i2c_adapter_by_node(node); - pr_inf("%s:[%p]\n", buf, dev->i2c_adap); - of_node_put(node); - } else { - dev->i2c_adap_id = -1; - pr_error("cannot find resource \"%s\"\n", buf); - } - memset(buf, 0, 128); - name = "i2c_addr"; - aml_fe_property_name(dev, name, buf); - pr_dbg("get u32: %s\n", buf); - ret = aml_fe_of_property_u32(dev, buf, &value); - if (!ret) { - dev->i2c_addr = value; - pr_inf("%s: %d\n", buf, dev->i2c_addr); - } else { - dev->i2c_addr = -1; - pr_error("cannot find resource \"%s\"\n", buf); - } - /*get i2c reset and reset value*/ - memset(buf, 0, 128); - name = "reset_gpio"; - aml_fe_property_name(dev, name, buf); - pr_dbg("get string: %s\n", buf); - ret = aml_fe_of_property_string(dev, buf, &str); - if (!ret) { - dev->reset_gpio = - of_get_named_gpio_flags(dev->man->pdev->dev.of_node, - buf, 0, NULL); - pr_inf("%s: %s\n", buf, str); - } else { - dev->reset_gpio = -1; - pr_error("cannot find resource \"%s\"\n", buf); - } - memset(buf, 0, 128); - name = "reset_value"; - aml_fe_property_name(dev, name, buf); - pr_dbg("get u32: %s\n", buf); - ret = aml_fe_of_property_u32(dev, buf, &value); - if (!ret) { - dev->reset_value = value; - pr_inf("%s: %d\n", buf, dev->reset_value); - } else { - dev->reset_value = -1; - } - - if (dev->drv && dev->drv->init) { - int ret; - - ret = dev->drv->init(dev); - if (ret != 0) { - dev->drv = NULL; - pr_error("[aml_fe..]%s error.\n", __func__); - return ret; - } - } - - return 0; -} - -static int aml_fe_dev_release(struct aml_fe_dev *dev) -{ - if (dev->drv) { - if (dev->drv->owner) - module_put(dev->drv->owner); - dev->drv->ref--; - if (dev->drv->release) - dev->drv->release(dev); - } - - dev->drv = NULL; - return 0; -} - -static void aml_fe_man_run(struct aml_fe *fe) -{ - if (fe->init) - return; - - if (fe->tuner && fe->tuner->drv) - fe->init = 1; - - if (fe->atv_demod && fe->atv_demod->drv) - fe->init = 1; - - if (fe->dtv_demod && fe->dtv_demod->drv) - fe->init = 1; - - if (fe->init) { - struct aml_dvb *dvb = fe->man->dvb; - int reg = 1; - int ret; - int id; - - spin_lock_init(&fe->slock); - - fe->sys = SYS_UNDEFINED; - - pr_dbg("fe: %p\n", fe); - - for (id = 0; id < FE_DEV_COUNT; id++) { - struct aml_fe *prev_fe = &fe_man.fe[id]; - - if (prev_fe == fe) - continue; - if (prev_fe->init && (prev_fe->dev_id == fe->dev_id)) { - reg = 0; - break; - } - } - - fe->fe = &fe_man.dev[fe->dev_id]; - if (reg) { - fe->fe->demodulator_priv = fe; - fe->fe->ops.set_property = aml_fe_set_property; - fe->fe->ops.get_property = aml_fe_set_property; - } - - if (fe->tuner) - fe->tuner->fe = fe; - if (fe->atv_demod) - fe->atv_demod->fe = fe; - if (fe->dtv_demod) - fe->dtv_demod->fe = fe; - - ret = dvb_register_frontend(&dvb->dvb_adapter, fe->fe); - if (ret) { - pr_error("register fe%d failed\n", fe->dev_id); - return; - } - } -} - -static void fe_property_name(struct aml_fe *fe, const char *name, - char *buf) -{ - if (name) - sprintf(buf, "fe%d_%s", fe->dev_id, name); - else - sprintf(buf, "fe%d", fe->dev_id); -} - -static int fe_of_property_u32(struct aml_fe *fe, - const char *name, u32 *v) -{ - struct platform_device *pdev = fe->man->pdev; - char buf[128]; - int r; - - fe_property_name(fe, name, buf); - r = of_property_read_u32(pdev->dev.of_node, buf, v); - if (r) - pr_error("cannot find resource \"%s\"\n", buf); - - return r; -} - -static int aml_fe_man_init(struct aml_fe_man *man, struct aml_fe *fe, int id) -{ - u32 value; - int ret; - - fe->sys = SYS_UNDEFINED; - fe->man = man; - fe->dev_id = id; - fe->init = 0; - fe->ts = AM_TS_SRC_TS0; - fe->work_running = 0; - fe->work_q = NULL; - fe->tuner = NULL; - fe->atv_demod = NULL; - fe->dtv_demod = NULL; - fe->do_work = NULL; - fe->get_property = NULL; - fe->set_property = NULL; - - init_waitqueue_head(&fe->wait_q); - spin_lock_init(&fe->slock); - - ret = fe_of_property_u32(fe, "tuner", &value); - if (!ret) { - id = value; - - if ((id < 0) || (id >= FE_DEV_COUNT) || !fe_man.tuner[id].drv) { - pr_error("invalid tuner device id %d\n", id); - return -1; - } - - fe->tuner = &fe_man.tuner[id]; - fe_man.tuner[id].fe = fe; - } - - ret = fe_of_property_u32(fe, "atv_demod", &value); - if (!ret) { - id = value; - - if ((id < 0) || - (id >= FE_DEV_COUNT) || - !fe_man.atv_demod[id].drv) { - pr_error("invalid ATV demod device id %d\n", id); - return -1; - } - - fe->atv_demod = &fe_man.atv_demod[id]; - fe_man.atv_demod[id].fe = fe; - } - - ret = fe_of_property_u32(fe, "dtv_demod", &value); - if (!ret) { - id = value; - - if ((id < 0) || - (id >= FE_DEV_COUNT) || - !fe_man.dtv_demod[id].drv) { - pr_error("invalid DTV demod device id %d\n", id); - return -1; - } - - fe->dtv_demod = &fe_man.dtv_demod[id]; - fe_man.dtv_demod[id].fe = fe; - } - - ret = fe_of_property_u32(fe, "ts", &value); - if (!ret) { - enum aml_ts_source_t ts = AM_TS_SRC_TS0; - - switch (value) { - case 0: - ts = AM_TS_SRC_TS0; - break; - case 1: - ts = AM_TS_SRC_TS1; - break; - case 2: - ts = AM_TS_SRC_TS2; - break; - default: - break; - } - - fe->ts = ts; - } - - ret = fe_of_property_u32(fe, "dev", &value); - if (!ret) { - id = value; - - if ((id >= 0) && (id < FE_DEV_COUNT)) - fe->dev_id = id; - else - fe->dev_id = 0; - } - - aml_fe_man_run(fe); - - return 0; -} - -static int aml_fe_man_release(struct aml_fe *fe) -{ - if (fe->init) { - aml_fe_cancel_work(fe); - - if (fe->work_q) - destroy_workqueue(fe->work_q); - - aml_fe_set_sys(fe->fe, SYS_UNDEFINED); - dvb_unregister_frontend(fe->fe); - dvb_frontend_detach(fe->fe); - - fe->tuner = NULL; - fe->atv_demod = NULL; - fe->dtv_demod = NULL; - fe->init = 0; - } - - return 0; -} - -void aml_fe_set_pdata(struct aml_fe_dev *dev, void *pdata) -{ - dev->priv_data = pdata; -} -EXPORT_SYMBOL(aml_fe_set_pdata); - -void *aml_fe_get_pdata(struct aml_fe_dev *dev) -{ - return dev->priv_data; -} -EXPORT_SYMBOL(aml_fe_get_pdata); - -static void aml_fe_do_work(struct work_struct *work) -{ - struct aml_fe *fe; - - fe = container_of(work, struct aml_fe, work); - - if (fe->do_work) - fe->do_work(fe); - - fe->work_running = 0; -} - -void aml_fe_schedule_work(struct aml_fe *fe, void(*func)(struct aml_fe *fe)) -{ - if (fe->work_running) - cancel_work_sync(&fe->work); - - fe->work_running = 1; - fe->do_work = func; - - if (!fe->work_q) { - fe->work_q = create_singlethread_workqueue("amlfe"); - INIT_WORK(&fe->work, aml_fe_do_work); - } - - queue_work(fe->work_q, &fe->work); -} -EXPORT_SYMBOL(aml_fe_schedule_work); - -void aml_fe_cancel_work(struct aml_fe *fe) -{ - if (fe->work_running) { - fe->work_running = 0; - cancel_work_sync(&fe->work); - } - - fe->do_work = NULL; -} -EXPORT_SYMBOL(aml_fe_cancel_work); - - -int aml_fe_work_cancelled(struct aml_fe *fe) -{ - return fe->work_running ? 0 : 1; -} -EXPORT_SYMBOL(aml_fe_work_cancelled); - -int aml_fe_work_sleep(struct aml_fe *fe, unsigned long delay) -{ - wait_event_interruptible_timeout(fe->wait_q, !fe->work_running, delay); - return aml_fe_work_cancelled(fe); -} -EXPORT_SYMBOL(aml_fe_work_sleep); - -static ssize_t tuner_name_show(struct class *cls, struct class_attribute *attr, - char *buf) -{ - size_t len = 0; - struct aml_fe_drv *drv; - unsigned long flags; - - struct aml_fe_drv **list = aml_get_fe_drv_list(AM_DEV_TUNER); - - spin_lock_irqsave(&lock, flags); - for (drv = *list; drv; drv = drv->next) - len += sprintf(buf + len, "%s\n", drv->name); - spin_unlock_irqrestore(&lock, flags); - return len; -} - -static ssize_t atv_demod_name_show(struct class *cls, - struct class_attribute *attr, char *buf) -{ - size_t len = 0; - struct aml_fe_drv *drv; - unsigned long flags; - - struct aml_fe_drv **list = aml_get_fe_drv_list(AM_DEV_ATV_DEMOD); - - spin_lock_irqsave(&lock, flags); - for (drv = *list; drv; drv = drv->next) - len += sprintf(buf + len, "%s\n", drv->name); - spin_unlock_irqrestore(&lock, flags); - return len; -} - -static ssize_t dtv_demod_name_show(struct class *cls, - struct class_attribute *attr, char *buf) -{ - size_t len = 0; - struct aml_fe_drv *drv; - unsigned long flags; - - struct aml_fe_drv **list = aml_get_fe_drv_list(AM_DEV_DTV_DEMOD); - - spin_lock_irqsave(&lock, flags); - for (drv = *list; drv; drv = drv->next) - len += sprintf(buf + len, "%s\n", drv->name); - spin_unlock_irqrestore(&lock, flags); - return len; -} - -static ssize_t setting_show(struct class *cls, struct class_attribute *attr, - char *buf) -{ - int r, total = 0; - int i; - struct aml_fe_man *fm = &fe_man; - - r = sprintf(buf, "tuner:\n"); - buf += r; - total += r; - for (i = 0; i < FE_DEV_COUNT; i++) { - struct aml_fe_dev *dev = &fm->tuner[i]; - - if (dev->drv) { - r = sprintf(buf, "\t%d: %s\n", i, dev->drv->name); - buf += r; - total += r; - } - } - - r = sprintf(buf, "atv_demod:\n"); - buf += r; - total += r; - for (i = 0; i < FE_DEV_COUNT; i++) { - struct aml_fe_dev *dev = &fm->atv_demod[i]; - - if (dev->drv) { - r = sprintf(buf, "\t%d: %s\n", i, dev->drv->name); - buf += r; - total += r; - } - } - - r = sprintf(buf, "dtv_demod:\n"); - buf += r; - total += r; - for (i = 0; i < FE_DEV_COUNT; i++) { - struct aml_fe_dev *dev = &fm->dtv_demod[i]; - - if (dev->drv) { - r = sprintf(buf, "\t%d: %s\n", i, dev->drv->name); - buf += r; - total += r; - } - } - - r = sprintf(buf, "frontend:\n"); - buf += r; - total += r; - for (i = 0; i < FE_DEV_COUNT; i++) { - struct aml_fe *fe = &fm->fe[i]; - - r = sprintf(buf, - "\t%d: %s device: %d ts: %d tuner: %s atv_demod: %s dtv_demod: %s\n", - i, fe->init ? "enabled" : "disabled", fe->dev_id, - fe->ts, fe->tuner ? fe->tuner->drv->name : "none", - fe->atv_demod ? fe->atv_demod->drv->name : "none", - fe->dtv_demod ? fe->dtv_demod->drv->name : "none"); - buf += r; - total += r; - } - - return total; -} - -static void reset_drv(int id, enum aml_fe_dev_type_t type, const char *name) -{ - struct aml_fe_man *fm = &fe_man; - struct aml_fe_drv **list; - struct aml_fe_drv **pdrv; - struct aml_fe_drv *drv; - struct aml_fe_drv *old; - - if ((id < 0) || (id >= FE_DEV_COUNT)) - return; - - if (fm->fe[id].init) { - pr_error("cannot reset driver when the device is inused\n"); - return; - } - - list = aml_get_fe_drv_list(type); - for (drv = *list; drv; drv = drv->next) - if (!strcmp(drv->name, name)) - break; - - switch (type) { - case AM_DEV_TUNER: - pdrv = &fm->tuner[id].drv; - break; - case AM_DEV_ATV_DEMOD: - pdrv = &fm->atv_demod[id].drv; - break; - case AM_DEV_DTV_DEMOD: - pdrv = &fm->dtv_demod[id].drv; - break; - default: - return; - } - - old = *pdrv; - if (old == drv) - return; - - if (old) { - old->ref--; - if (old->owner) - module_put(old->owner); - } - - if (drv) { - drv->ref++; - if (drv->owner) - try_module_get(drv->owner); - } - - *pdrv = drv; -} - -static ssize_t setting_store(struct class *class, struct class_attribute *attr, - const char *buf, size_t size) -{ - struct aml_fe_man *fm = &fe_man; - int id, val; - char dev_name[32]; - unsigned long flags; - - spin_lock_irqsave(&lock, flags); - - if (sscanf(buf, "tuner %i driver %s", &id, dev_name) == 2) { - reset_drv(id, AM_DEV_TUNER, dev_name); - } else if (sscanf(buf, "atv_demod %i driver %s", &id, dev_name) == 2) { - reset_drv(id, AM_DEV_ATV_DEMOD, dev_name); - } else if (sscanf(buf, "dtv_demod %i driver %s", &id, dev_name) == 2) { - reset_drv(id, AM_DEV_DTV_DEMOD, dev_name); - } else if (sscanf(buf, "frontend %i device %i", &id, &val) == 2) { - if ((id >= 0) && (id < FE_DEV_COUNT)) - fm->fe[id].dev_id = val; - } else if (sscanf(buf, "frontend %i ts %i", &id, &val) == 2) { - if ((id >= 0) && (id < FE_DEV_COUNT)) - fm->fe[id].ts = val; - } else if (sscanf(buf, "frontend %i tuner %i", &id, &val) == 2) { - if ((id >= 0) && (id < FE_DEV_COUNT) && (val >= 0) - && (val < FE_DEV_COUNT) && fm->tuner[val].drv) - fm->fe[id].tuner = &fm->tuner[val]; - } else if (sscanf(buf, "frontend %i atv_demod %i", &id, &val) == 2) { - if ((id >= 0) && (id < FE_DEV_COUNT) && (val >= 0) - && (val < FE_DEV_COUNT) && fm->atv_demod[val].drv) - fm->fe[id].atv_demod = &fm->atv_demod[val]; - } else if (sscanf(buf, "frontend %i dtv_demod %i", &id, &val) == 2) { - if ((id >= 0) && (id < FE_DEV_COUNT) && (val >= 0) - && (val < FE_DEV_COUNT) && fm->dtv_demod[val].drv) - fm->fe[id].dtv_demod = &fm->dtv_demod[val]; - } - - spin_unlock_irqrestore(&lock, flags); - - if (sscanf(buf, "enable %i", &id) == 1) { - if ((id >= 0) && (id < FE_DEV_COUNT)) - aml_fe_man_run(&fm->fe[id]); - } else if (sscanf(buf, "disable %i", &id) == 1) { - if ((id >= 0) && (id < FE_DEV_COUNT)) - aml_fe_man_release(&fm->fe[id]); - } else if (strstr(buf, "autoload")) { - for (id = 0; id < FE_DEV_COUNT; id++) { - aml_fe_dev_init(fm, AM_DEV_TUNER, - &fm->tuner[id], id); - aml_fe_dev_init(fm, AM_DEV_ATV_DEMOD, - &fm->atv_demod[id], id); - aml_fe_dev_init(fm, AM_DEV_DTV_DEMOD, - &fm->dtv_demod[id], id); - } - - for (id = 0; id < FE_DEV_COUNT; id++) - aml_fe_man_init(fm, &fm->fe[id], id); - } else if (strstr(buf, "disableall")) { - for (id = 0; id < FE_DEV_COUNT; id++) - aml_fe_man_release(&fm->fe[id]); - - for (id = 0; id < FE_DEV_COUNT; id++) { - aml_fe_dev_release(&fm->dtv_demod[id]); - aml_fe_dev_release(&fm->atv_demod[id]); - aml_fe_dev_release(&fm->tuner[id]); - } - } - - return size; -} - -static ssize_t aml_fe_show_suspended_flag(struct class *class, - struct class_attribute *attr, - char *buf) -{ - ssize_t ret = 0; - - ret = sprintf(buf, "%ld\n", aml_fe_suspended); - - return ret; -} - -static ssize_t aml_fe_store_suspended_flag(struct class *class, - struct class_attribute *attr, - const char *buf, size_t size) -{ - /*aml_fe_suspended = simple_strtol(buf, 0, 0); */ - int ret = kstrtol(buf, 0, &aml_fe_suspended); - - if (ret) - return ret; - return size; -} - -static struct class_attribute aml_fe_cls_attrs[] = { - __ATTR(tuner_name, - 0644, - tuner_name_show, NULL), - __ATTR(atv_demod_name, - 0644, - atv_demod_name_show, NULL), - __ATTR(dtv_demod_name, - 0644, - dtv_demod_name_show, NULL), - __ATTR(setting, - 0644, - setting_show, setting_store), - __ATTR(aml_fe_suspended_flag, - 0644, - aml_fe_show_suspended_flag, - aml_fe_store_suspended_flag), - __ATTR_NULL -}; - -static struct class aml_fe_class = { - .name = "amlfe", - .class_attrs = aml_fe_cls_attrs, -}; - -static int aml_fe_probe(struct platform_device *pdev) -{ - struct aml_dvb *dvb = aml_get_dvb_device(); - int i; - - fe_man.dvb = dvb; - fe_man.pdev = pdev; - - platform_set_drvdata(pdev, &fe_man); - - for (i = 0; i < FE_DEV_COUNT; i++) { - if (aml_fe_dev_init(&fe_man, - AM_DEV_TUNER, - &fe_man.tuner[i], i) < 0) - goto probe_end; - - if (aml_fe_dev_init(&fe_man, - AM_DEV_ATV_DEMOD, - &fe_man.atv_demod[i], i) < 0) - goto probe_end; - - if (aml_fe_dev_init(&fe_man, - AM_DEV_DTV_DEMOD, - &fe_man.dtv_demod[i], i) < 0) - goto probe_end; - } - - for (i = 0; i < FE_DEV_COUNT; i++) { - if (aml_fe_man_init(&fe_man, &fe_man.fe[i], i) < 0) - goto probe_end; - } - - probe_end: - - fe_man.pinctrl = devm_pinctrl_get_select_default(&pdev->dev); - - if (class_register(&aml_fe_class) < 0) - pr_error("[aml_fe..] register class error\n"); - - pr_dbg("[aml_fe..] probe ok.\n"); - - return 0; -} - -static int aml_fe_remove(struct platform_device *pdev) -{ - struct aml_fe_man *fe_man = platform_get_drvdata(pdev); - int i; - - if (fe_man) { - platform_set_drvdata(pdev, NULL); - - for (i = 0; i < FE_DEV_COUNT; i++) - aml_fe_man_release(&fe_man->fe[i]); - for (i = 0; i < FE_DEV_COUNT; i++) { - aml_fe_dev_release(&fe_man->dtv_demod[i]); - aml_fe_dev_release(&fe_man->atv_demod[i]); - aml_fe_dev_release(&fe_man->tuner[i]); - } - - if (fe_man->pinctrl) - devm_pinctrl_put(fe_man->pinctrl); - } - - class_unregister(&aml_fe_class); - - return 0; -} - -static int aml_fe_suspend(struct platform_device *dev, pm_message_t state) -{ - int i; - - for (i = 0; i < FE_DEV_COUNT; i++) { - struct aml_fe *fe = &fe_man.fe[i]; - - if (fe->tuner && fe->tuner->drv->suspend) - fe->tuner->drv->suspend(fe->tuner); - - if (fe->atv_demod && fe->atv_demod->drv->suspend) - fe->atv_demod->drv->suspend(fe->atv_demod); - - if (fe->dtv_demod && fe->dtv_demod->drv->suspend) - fe->dtv_demod->drv->suspend(fe->dtv_demod); - } - - aml_fe_suspended = 1; - - return 0; -} - -static int aml_fe_resume(struct platform_device *dev) -{ - int i; - - aml_fe_suspended = 0; - - for (i = 0; i < FE_DEV_COUNT; i++) { - struct aml_fe *fe = &fe_man.fe[i]; - - if (fe->tuner && fe->tuner->drv->resume) - fe->tuner->drv->resume(fe->tuner); - - if (fe->atv_demod && fe->atv_demod->drv->resume) - fe->atv_demod->drv->resume(fe->atv_demod); - - if (fe->dtv_demod && fe->dtv_demod->drv->resume) - fe->dtv_demod->drv->resume(fe->dtv_demod); - } - - return 0; -} - -#ifdef CONFIG_OF -static const struct of_device_id aml_fe_dt_match[] = { - { - .compatible = "amlogic, dvbfe", - }, - {}, -}; -#endif /*CONFIG_OF */ - -static struct platform_driver aml_fe_driver = { - .probe = aml_fe_probe, - .remove = aml_fe_remove, - .suspend = aml_fe_suspend, - .resume = aml_fe_resume, - .driver = { - .name = "amlogic-dvb-fe", - .owner = THIS_MODULE, -#ifdef CONFIG_OF - .of_match_table = aml_fe_dt_match, -#endif - } -}; - -static int __init aml_fe_init(void) -{ - return platform_driver_register(&aml_fe_driver); -} - -static void __exit aml_fe_exit(void) -{ - platform_driver_unregister(&aml_fe_driver); -} - -module_init(aml_fe_init); -module_exit(aml_fe_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("amlogic frontend driver"); -MODULE_AUTHOR("L+#= +0=1"); - diff --git a/drivers/stream_input/tv_frontend/aml_fe.h b/drivers/stream_input/tv_frontend/aml_fe.h deleted file mode 100644 index f38c646..0000000 --- a/drivers/stream_input/tv_frontend/aml_fe.h +++ b/dev/null @@ -1,213 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#ifndef _AML_FE_H_ -#define _AML_FE_H_ - - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include "../parser/hw_demux/aml_dvb.h" - -enum aml_tuner_type_t { - AM_TUNER_NONE = 0, - AM_TUNER_SI2176 = 1, - AM_TUNER_SI2196 = 2, - AM_TUNER_FQ1216 = 3, - AM_TUNER_HTM = 4, - AM_TUNER_CTC703 = 5, - AM_TUNER_SI2177 = 6, - AM_TUNER_R840 = 7, - AM_TUNER_SI2157 = 8, - AM_TUNER_SI2151 = 9, - AM_TUNER_MXL661 = 10, - AM_TUNER_MXL608 = 11, - AM_TUNER_SI2159 = 12, - AM_TUNER_R842 = 13, - AM_TUNER_ATBM2040 = 14, -}; - -enum aml_atv_demod_type_t { - AM_ATV_DEMOD_SI2176 = 1, - AM_ATV_DEMOD_SI2196 = 2, - AM_ATV_DEMOD_FQ1216 = 3, - AM_ATV_DEMOD_HTM = 4, - AM_ATV_DEMOD_CTC703 = 5, - AM_ATV_DEMOD_SI2177 = 6, - AM_ATV_DEMOD_AML = 7, - AM_ATV_DEMOD_R840 = 8 -}; - -enum aml_dtv_demod_type_t { - AM_DTV_DEMOD_M1 = 0, - AM_DTV_DEMOD_SI2176 = 1, - AM_DTV_DEMOD_MXL101 = 2, - AM_DTV_DEMOD_SI2196 = 3, - AM_DTV_DEMOD_AVL6211 = 4, - AM_DTV_DEMOD_SI2168 = 5, - AM_DTV_DEMOD_ITE9133 = 6, - AM_DTV_DEMOD_ITE9173 = 7, - AM_DTV_DEMOD_DIB8096 = 8, - AM_DTV_DEMOD_ATBM8869 = 9, - AM_DTV_DEMOD_MXL241 = 10, - AM_DTV_DEMOD_AVL68xx = 11, - AM_DTV_DEMOD_MXL683 = 12, - AM_DTV_DEMOD_ATBM8881 = 13 -}; - -enum aml_fe_dev_type_t { - AM_DEV_TUNER, - AM_DEV_ATV_DEMOD, - AM_DEV_DTV_DEMOD -}; - -struct aml_fe_dev; -struct aml_fe_man; -struct aml_fe; - -struct aml_fe_drv { - struct module *owner; - struct aml_fe_drv *next; - enum aml_tuner_type_t id; - char *name; - int (*init)(struct aml_fe_dev *dev); - int (*release)(struct aml_fe_dev *dev); - int (*resume)(struct aml_fe_dev *dev); - int (*suspend)(struct aml_fe_dev *dev); - int (*support)(struct aml_fe_dev *dev, enum fe_delivery_system sys); - int (*get_ops)(struct aml_fe_dev *dev, enum fe_delivery_system sys, - struct dvb_frontend_ops *ops); - int (*init_sys)(struct aml_fe_dev *dev, enum fe_delivery_system sys); - int (*release_sys)(struct aml_fe_dev *dev, enum fe_delivery_system sys); - int (*start_blind_scan)(struct aml_fe_dev *dev); - int (*stop_blind_scan)(struct aml_fe_dev *dev); - int ref; -}; - -struct aml_fe_dev { - /*point to parent aml_fe */ - enum aml_fe_dev_type_t type; - int dev_id; - struct aml_fe *fe; - struct aml_fe_man *man; - struct aml_fe_drv *drv; - void *priv_data; - /*i2c and reset gpio for all demod and tune*/ - int i2c_adap_id; - int i2c_addr; - struct i2c_adapter *i2c_adap; - int reset_gpio; - int reset_value; -}; - -struct aml_fe { - struct dvb_frontend *fe; - struct aml_fe_man *man; -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend es; -#endif /*CONFIG_HAS_EARLYSUSPEND */ - spinlock_t slock; - int init; - int dev_id; - enum fe_delivery_system sys; - int sub_sys; -/*used to identify T T2 OR C-A C-B C-C,S S2,ISDBT ISDBS ISDBC*/ - enum aml_ts_source_t ts; - struct aml_fe_dev *tuner; - struct aml_fe_dev *atv_demod; - struct aml_fe_dev *dtv_demod; - struct workqueue_struct *work_q; - wait_queue_head_t wait_q; - struct work_struct work; - int work_running; - struct dvbsx_blindscanpara blind_scan_para; - - /*Driver's work function.*/ - void (*do_work)(struct aml_fe *fe); - /*Driver's property function.*/ - int (*get_property)(struct dvb_frontend *fe, struct dtv_property *tvp); - int (*set_property)(struct dvb_frontend *fe, struct dtv_property *tvp); -}; - -struct aml_fe_man { - struct aml_dvb *dvb; - struct aml_fe fe[FE_DEV_COUNT]; - struct aml_fe_dev tuner[FE_DEV_COUNT]; - struct aml_fe_dev atv_demod[FE_DEV_COUNT]; - struct aml_fe_dev dtv_demod[FE_DEV_COUNT]; - struct dvb_frontend dev[FE_DEV_COUNT]; - struct pinctrl *pinctrl; - struct platform_device *pdev; -}; - -extern int aml_register_fe_drv(enum aml_fe_dev_type_t type, - struct aml_fe_drv *drv); -extern int aml_unregister_fe_drv(enum aml_fe_dev_type_t type, - struct aml_fe_drv *drv); - -extern int aml_fe_of_property_string(struct aml_fe_dev *dev, - const char *name, const char **str); -extern int aml_fe_of_property_u32(struct aml_fe_dev *dev, - const char *name, u32 *v); - -extern void aml_fe_set_pdata(struct aml_fe_dev *dev, void *pdata); -extern void *aml_fe_get_pdata(struct aml_fe_dev *dev); - -extern void aml_fe_schedule_work(struct aml_fe *fe, - void (*func)(struct aml_fe *fe)); -extern void aml_fe_cancel_work(struct aml_fe *fe); -extern int aml_fe_work_cancelled(struct aml_fe *fe); -extern int aml_fe_work_sleep(struct aml_fe *fe, unsigned long delay); - -#endif /*_AML_FE_H_*/ diff --git a/drivers/stream_input/tv_frontend/atv_demod/atvdemod_frontend.c b/drivers/stream_input/tv_frontend/atv_demod/atvdemod_frontend.c deleted file mode 100644 index 964bc42..0000000 --- a/drivers/stream_input/tv_frontend/atv_demod/atvdemod_frontend.c +++ b/dev/null @@ -1,791 +0,0 @@ -/* - * Silicon labs atvdemod Device Driver - * - * Author: dezhi.kong - * - * - * Copyright (C) 2014 Amlogic Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Standard Liniux Headers */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Amlogic Headers */ - -/* Local Headers */ -#include "atvdemod_func.h" -#include "../aml_fe.h" -#include -#include - -#define ATVDEMOD_DEVICE_NAME "amlatvdemod" -#define ATVDEMOD_DRIVER_NAME "amlatvdemod" -#define ATVDEMOD_MODULE_NAME "amlatvdemod" -#define ATVDEMOD_CLASS_NAME "amlatvdemod" - -struct amlatvdemod_device_s *amlatvdemod_devp; -#define AMLATVDEMOD_VER "Ref.2015/09/01a" - -static int afc_wave_cnt; -static int last_frq, last_std; - -unsigned int reg_23cf = 0x88188832; /*IIR filter*/ -module_param(reg_23cf, uint, 0664); -MODULE_PARM_DESC(reg_23cf, "\n reg_23cf\n"); - -unsigned int atvdemod_scan_mode; /*IIR filter*/ -module_param(atvdemod_scan_mode, uint, 0664); -MODULE_PARM_DESC(atvdemod_scan_mode, "\n atvdemod_scan_mode\n"); - -/* used for resume */ -#define ATVDEMOD_STATE_IDEL 0 -#define ATVDEMOD_STATE_WORK 1 -#define ATVDEMOD_STATE_SLEEP 2 -static int atvdemod_state = ATVDEMOD_STATE_IDEL; - -int is_atvdemod_scan_mode(void) -{ - return atvdemod_scan_mode; -} -EXPORT_SYMBOL(is_atvdemod_scan_mode); - -static int aml_atvdemod_enter_mode(struct aml_fe *fe, int mode); -/*static void sound_store(const char *buff, v4l2_std_id *std);*/ -static ssize_t aml_atvdemod_store(struct class *cls, - struct class_attribute *attr, const char *buf, - size_t count) -{ - int n = 0; - unsigned int ret = 0; - char *buf_orig, *ps, *token; - char *parm[4]; - unsigned int data_snr[128]; - unsigned int data_snr_avg; - int data_afc, block_addr, block_reg, block_val = 0; - int i, val = 0; - unsigned long tmp = 0; - struct aml_fe *atvdemod_fe = NULL; - - buf_orig = kstrdup(buf, GFP_KERNEL); - ps = buf_orig; - block_addr = 0; - block_reg = 0; - while (1) { - token = strsep(&ps, "\n"); - if (token == NULL) - break; - if (*token == '\0') - continue; - parm[n++] = token; - } - if (!strncmp(parm[0], "init", strlen("init"))) { - ret = aml_atvdemod_enter_mode(atvdemod_fe, 0); - if (ret) - pr_info("[tuner..] atv_restart error.\n"); - } else if (!strcmp(parm[0], "tune")) { - /* val = simple_strtol(parm[1], NULL, 10); */ - } else if (!strcmp(parm[0], "set")) { - if (!strncmp(parm[1], "avout_gain", strlen("avout_gain"))) { - if (kstrtoul(buf+strlen("avout_offset")+1, 10, - &tmp) == 0) - val = tmp; - atv_dmd_wr_byte(0x0c, 0x01, val&0xff); - } else if (!strncmp(parm[1], "avout_offset", - strlen("avout_offset"))) { - if (kstrtoul(buf+strlen("avout_offset")+1, 10, - &tmp) == 0) - val = tmp; - atv_dmd_wr_byte(0x0c, 0x04, val&0xff); - } else if (!strncmp(parm[1], "atv_gain", strlen("atv_gain"))) { - if (kstrtoul(buf+strlen("atv_gain")+1, 10, &tmp) == 0) - val = tmp; - atv_dmd_wr_byte(0x19, 0x01, val&0xff); - } else if (!strncmp(parm[1], "atv_offset", - strlen("atv_offset"))) { - if (kstrtoul(buf+strlen("atv_offset")+1, 10, - &tmp) == 0) - val = tmp; - atv_dmd_wr_byte(0x19, 0x04, val&0xff); - } - } else if (!strcmp(parm[0], "get")) { - if (!strncmp(parm[1], "avout_gain", strlen("avout_gain"))) { - val = atv_dmd_rd_byte(0x0c, 0x01); - pr_dbg("avout_gain:0x%x\n", val); - } else if (!strncmp(parm[1], "avout_offset", - strlen("avout_offset"))) { - val = atv_dmd_rd_byte(0x0c, 0x04); - pr_dbg("avout_offset:0x%x\n", val); - } else if (!strncmp(parm[1], "atv_gain", strlen("atv_gain"))) { - val = atv_dmd_rd_byte(0x19, 0x01); - pr_dbg("atv_gain:0x%x\n", val); - } else if (!strncmp(parm[1], "atv_offset", - strlen("atv_offset"))) { - val = atv_dmd_rd_byte(0x19, 0x04); - pr_dbg("atv_offset:0x%x\n", val); - } - } else if (!strncmp(parm[0], "snr_hist", strlen("snr_hist"))) { - data_snr_avg = 0; - for (i = 0; i < 128; i++) { - data_snr[i] = - (atv_dmd_rd_long(APB_BLOCK_ADDR_VDAGC, 0x50) >> 8); - usleep_range(50*1000, 50*1000+100); - data_snr_avg += data_snr[i]; - } - data_snr_avg = data_snr_avg / 128; - pr_dbg("**********snr_hist_128avg:0x%x(%d)*********\n", - data_snr_avg, data_snr_avg); - } else if (!strncmp(parm[0], "afc_info", strlen("afc_info"))) { - data_afc = retrieve_vpll_carrier_afc(); - pr_dbg("[amlatvdemod..]afc %d Khz.\n", data_afc); - } else if (!strncmp(parm[0], "ver_info", strlen("ver_info"))) { - pr_dbg("[amlatvdemod..]aml_atvdemod_ver %s.\n", - AMLATVDEMOD_VER); - } else if (!strncmp(parm[0], "audio_autodet", - strlen("audio_autodet"))) { - aml_audiomode_autodet(NULL); - } else if (!strncmp(parm[0], "overmodule_det", - strlen("overmodule_det"))) { - /* unsigned long over_threshold, */ - /* int det_mode = auto_det_mode; */ - aml_atvdemod_overmodule_det(); - } else if (!strncmp(parm[0], "audio_gain_set", - strlen("audio_gain_set"))) { - if (kstrtoul(buf+strlen("audio_gain_set")+1, 16, &tmp) == 0) - val = tmp; - aml_audio_valume_gain_set(val); - pr_dbg("audio_gain_set : %d\n", val); - } else if (!strncmp(parm[0], "audio_gain_get", - strlen("audio_gain_get"))) { - val = aml_audio_valume_gain_get(); - pr_dbg("audio_gain_get : %d\n", val); - } else if (!strncmp(parm[0], "fix_pwm_adj", strlen("fix_pwm_adj"))) { - if (kstrtoul(parm[1], 10, &tmp) == 0) { - val = tmp; - aml_fix_PWM_adjust(val); - } - } else if (!strncmp(parm[0], "rs", strlen("rs"))) { - if (kstrtoul(parm[1], 16, &tmp) == 0) - block_addr = tmp; - if (kstrtoul(parm[2], 16, &tmp) == 0) - block_reg = tmp; - if (block_addr < APB_BLOCK_ADDR_TOP) - block_val = atv_dmd_rd_long(block_addr, block_reg); - pr_info("rs block_addr:0x%x,block_reg:0x%x,block_val:0x%x\n", - block_addr, block_reg, block_val); - } else if (!strncmp(parm[0], "ws", strlen("ws"))) { - if (kstrtoul(parm[1], 16, &tmp) == 0) - block_addr = tmp; - if (kstrtoul(parm[2], 16, &tmp) == 0) - block_reg = tmp; - if (kstrtoul(parm[3], 16, &tmp) == 0) - block_val = tmp; - if (block_addr < APB_BLOCK_ADDR_TOP) - atv_dmd_wr_long(block_addr, block_reg, block_val); - pr_info("ws block_addr:0x%x,block_reg:0x%x,block_val:0x%x\n", - block_addr, block_reg, block_val); - block_val = atv_dmd_rd_long(block_addr, block_reg); - pr_info("readback_val:0x%x\n", block_val); - } else if (!strncmp(parm[0], "pin_mux", strlen("pin_mux"))) { - amlatvdemod_devp->pin = - devm_pinctrl_get_select(amlatvdemod_devp->dev, - amlatvdemod_devp->pin_name); - pr_dbg("atvdemod agc pinmux name:%s\n", - amlatvdemod_devp->pin_name); - } else if (!strncmp(parm[0], "snr_cur", strlen("snr_cur"))) { - data_snr_avg = aml_atvdemod_get_snr_ex(); - pr_dbg("**********snr_cur:%d*********\n", data_snr_avg); - } else - pr_dbg("invalid command\n"); - kfree(buf_orig); - return count; -} - -static ssize_t aml_atvdemod_show(struct class *cls, - struct class_attribute *attr, char *buff) -{ - pr_dbg("\n usage:\n"); - pr_dbg("[get soft version] echo ver_info > /sys/class/amlatvdemod/atvdemod_debug\n"); - pr_dbg("[get afc value] echo afc_info > /sys/class/amlatvdemod/atvdemod_debug\n"); - pr_dbg("[reinit atvdemod] echo init > /sys/class/amlatvdemod/atvdemod_debug\n"); - pr_dbg("[get av-out-gain/av-out-offset/atv-gain/atv-offset]:\n" - "echo get av_gain/av_offset/atv_gain/atv_offset > /sys/class/amlatvdemod/atvdemod_debug\n"); - pr_dbg("[set av-out-gain/av-out-offset/atv-gain/atv-offset]:\n" - "echo set av_gain/av_offset/atv_gain/atv_offset val(0~255) > /sys/class/amlatvdemod/atvdemod_debug\n"); - return 0; -} -static CLASS_ATTR(atvdemod_debug, 0644, aml_atvdemod_show, aml_atvdemod_store); - -void aml_atvdemod_set_frequency(unsigned int freq) -{ -} - -/*static void aml_atvdemod_set_std(void);*/ - -/*try audmode B,CH,I,DK,return the sound level*/ -/*static unsigned char set_video_audio_mode(unsigned char color, - *unsigned char audmode); - */ -/*static void aml_atvdemod_get_status(struct dvb_frontend *fe, - *void *stat); - */ -/*static void aaaml_atvdemod_get_pll_status(struct dvb_frontend *fe, - *void *stat); - */ - -static int aml_atvdemod_fe_init(struct aml_fe_dev *dev) -{ - - int error_code = 0; - - if (!dev) { - pr_dbg("[amlatvdemod..]%s: null pointer error.\n", __func__); - return -1; - } - return error_code; -} - -static int aml_atvdemod_enter_mode(struct aml_fe *fe, int mode) -{ - int err_code; - - if (amlatvdemod_devp->pin_name != NULL) - amlatvdemod_devp->pin = - devm_pinctrl_get_select(amlatvdemod_devp->dev, - amlatvdemod_devp->pin_name); - /* printk("\n%s: set atvdemod pll...\n",__func__); */ - adc_set_pll_cntl(1, 0x1); - atvdemod_clk_init(); - err_code = atvdemod_init(); - if (err_code) { - pr_dbg("[amlatvdemod..]%s init atvdemod error.\n", __func__); - return err_code; - } - - set_aft_thread_enable(1); - atvdemod_state = ATVDEMOD_STATE_WORK; - return 0; -} - -static int aml_atvdemod_leave_mode(struct aml_fe *fe, int mode) -{ - set_aft_thread_enable(0); - atvdemod_uninit(); - if (amlatvdemod_devp->pin != NULL) { - devm_pinctrl_put(amlatvdemod_devp->pin); - amlatvdemod_devp->pin = NULL; - } - /* reset adc pll flag */ - /* printk("\n%s: init atvdemod flag...\n",__func__); */ - adc_set_pll_cntl(0, 0x1); - atvdemod_state = ATVDEMOD_STATE_IDEL; - return 0; -} - -static int aml_atvdemod_suspend(struct aml_fe_dev *dev) -{ - pr_info("%s\n", __func__); - if (atvdemod_state != ATVDEMOD_STATE_IDEL) { - aml_atvdemod_leave_mode(NULL, 0); - atvdemod_state = ATVDEMOD_STATE_SLEEP; - } - return 0; -} - -static int aml_atvdemod_resume(struct aml_fe_dev *dev) -{ - pr_info("%s\n", __func__); - if (atvdemod_state == ATVDEMOD_STATE_SLEEP) - aml_atvdemod_enter_mode(NULL, 0); - return 0; -} - -/* - *static int aml_atvdemod_get_afc(struct dvb_frontend *fe,int *afc) - *{ - * return 0; - *} - */ - -/*ret:5~100;the val is bigger,the signal is better*/ -int aml_atvdemod_get_snr(struct dvb_frontend *fe) -{ -#if 1 - return get_atvdemod_snr_val(); -#else - unsigned int snr_val; - int ret; - - snr_val = atv_dmd_rd_long(APB_BLOCK_ADDR_VDAGC, 0x50) >> 8; - /* snr_val:900000~0xffffff,ret:5~15 */ - if (snr_val > 900000) - ret = 15 - (snr_val - 900000)*10/(0xffffff - 900000); - /* snr_val:158000~900000,ret:15~30 */ - else if (snr_val > 158000) - ret = 30 - (snr_val - 158000)*15/(900000 - 158000); - /* snr_val:31600~158000,ret:30~50 */ - else if (snr_val > 31600) - ret = 50 - (snr_val - 31600)*20/(158000 - 31600); - /* snr_val:316~31600,ret:50~80 */ - else if (snr_val > 316) - ret = 80 - (snr_val - 316)*30/(31600 - 316); - /* snr_val:0~316,ret:80~100 */ - else - ret = 100 - (316 - snr_val)*20/316; - return ret; -#endif -} -EXPORT_SYMBOL(aml_atvdemod_get_snr); - -int aml_atvdemod_get_snr_ex(void) -{ -#if 1 - return get_atvdemod_snr_val(); -#else - unsigned int snr_val; - int ret; - - snr_val = atv_dmd_rd_long(APB_BLOCK_ADDR_VDAGC, 0x50) >> 8; - /* snr_val:900000~0xffffff,ret:5~15 */ - if (snr_val > 900000) - ret = 15 - (snr_val - 900000)*10/(0xffffff - 900000); - /* snr_val:158000~900000,ret:15~30 */ - else if (snr_val > 158000) - ret = 30 - (snr_val - 158000)*15/(900000 - 158000); - /* snr_val:31600~158000,ret:30~50 */ - else if (snr_val > 31600) - ret = 50 - (snr_val - 31600)*20/(158000 - 31600); - /* snr_val:316~31600,ret:50~80 */ - else if (snr_val > 316) - ret = 80 - (snr_val - 316)*30/(31600 - 316); - /* snr_val:0~316,ret:80~100 */ - else - ret = 100 - (316 - snr_val)*20/316; - return ret; -#endif -} -EXPORT_SYMBOL(aml_atvdemod_get_snr_ex); - -/*tuner lock status & demod lock status should be same in silicon tuner*/ -static int aml_atvdemod_get_status(struct dvb_frontend *fe, void *stat) -{ - int video_lock; - fe_status_t *status = (fe_status_t *) stat; - - retrieve_video_lock(&video_lock); - if ((video_lock & 0x1) == 0) { - /* *status = FE_HAS_LOCK;*/ - *status = FE_TIMEDOUT; - pr_info("video lock:locked\n"); - } else { - pr_info("video lock:unlocked\n"); - *status = FE_TIMEDOUT; - /* *status = FE_HAS_LOCK;*/ - } - return 0; -} - -/*tuner lock status & demod lock status should be same in silicon tuner*/ -/* force return lock, for atvdemo status not sure */ -static void aml_atvdemod_get_pll_status(struct dvb_frontend *fe, void *stat) -{ - int vpll_lock; - fe_status_t *status = (fe_status_t *) stat; - - retrieve_vpll_carrier_lock(&vpll_lock); - if ((vpll_lock&0x1) == 0) { - *status = FE_HAS_LOCK; - pr_info("visual carrier lock:locked\n"); - } else { - pr_info("visual carrier lock:unlocked\n"); - *status = FE_TIMEDOUT; - /* *status = FE_HAS_LOCK;*/ - } -} - -static int aml_atvdemod_get_atv_status(struct dvb_frontend *fe, - struct atv_status_s *atv_status) -{ - int vpll_lock = 0, line_lock = 0; - int try_std = 1; - int loop_cnt = 5; - int cnt = 10; - int try_std_cnt = 0; - static int last_report_freq; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - while (fe && atv_status && loop_cnt--) { - atv_status->afc = retrieve_vpll_carrier_afc(); - retrieve_vpll_carrier_lock(&vpll_lock); - line_lock = atv_dmd_rd_byte(APB_BLOCK_ADDR_VDAGC, 0x4f)&0x10; - if ((vpll_lock&0x1) == 0 || line_lock == 0) { - atv_status->atv_lock = 1; - try_std_cnt = 2; - while (try_std_cnt--) { - atv_status->afc = retrieve_vpll_carrier_afc(); - if (atv_status->afc > 1500 - && atvdemod_scan_mode) { - if ((c->analog.std & 0xff000000) - != V4L2_COLOR_STD_PAL) { - c->analog.std = - V4L2_COLOR_STD_PAL - | V4L2_STD_PAL_BG; - c->frequency += 1; - fe->ops.set_frontend(fe); - msleep(20); - } else { - c->analog.std = - V4L2_COLOR_STD_NTSC - | V4L2_STD_NTSC_M; - c->frequency += 1; - fe->ops.set_frontend(fe); - usleep_range(20*1000, - 20*1000+100); - } - atv_status->afc = - retrieve_vpll_carrier_afc(); - - cnt = 4; - while (cnt--) { - if (atv_status->afc < 1500) - break; - atv_status->afc = - retrieve_vpll_carrier_afc(); - usleep_range(5*1000, 5*1000+100); - } - if (atv_status->afc < 1500) - break; - } - } - - if (atv_status->afc > 4000 && !atvdemod_scan_mode) - atv_status->atv_lock = 0; - - if (last_report_freq != c->frequency) - last_report_freq = c->frequency; - - if (atvdemod_scan_mode) - pr_err("%s,lock freq:%d, afc:%d\n", __func__, - c->frequency, atv_status->afc); - break; - - } else if (try_std%3 == 0 && atvdemod_scan_mode) { - if ((c->analog.std & 0xff000000) - != V4L2_COLOR_STD_PAL) { - c->analog.std = - V4L2_COLOR_STD_PAL | V4L2_STD_PAL_DK; - } - if (abs(c->frequency - last_report_freq) > 1000000) { - c->frequency -= 500000; - pr_err("@@@ %s freq:%d unlock,try back 0.5M\n", - __func__, c->frequency); - } else - c->frequency += 1; - fe->ops.set_frontend(fe); - usleep_range(10*1000, 10*1000+100); - } - if (atvdemod_scan_mode) - pr_err("@@@ %s freq:%d unlock, read lock again\n", - __func__, c->frequency); - if (atvdemod_scan_mode == 0) - usleep_range(10*1000, 10*1000+100); - else - usleep_range(1000, 1200); - - atv_status->atv_lock = 0; - try_std++; - } - if (atvdemod_scan_mode == 0) { - if (abs(atv_status->afc) < 20) - afc_wave_cnt = 0; - if (500*1000 > abs(last_frq - c->frequency) - && 20 < abs(atv_status->afc) - && 200 > abs(atv_status->afc)) { - afc_wave_cnt++; - pr_err("%s play mode,afc_wave_cnt:%d\n", - __func__, afc_wave_cnt); - if (afc_wave_cnt < 20) { - atv_status->afc = 0; - pr_err("%s, afc is wave,ignore\n", __func__); - } - } - } - return 0; -} - -void aml_atvdemod_set_params(struct dvb_frontend *fe, - struct analog_parameters *p) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - if (fe->ops.info.type == FE_ANALOG) { - if ((p->std != amlatvdemod_devp->parm.std) || - (p->tuner_id == AM_TUNER_R840) || - (p->tuner_id == AM_TUNER_SI2151) || - (p->tuner_id == AM_TUNER_MXL661)) { - amlatvdemod_devp->parm.std = p->std; - amlatvdemod_devp->parm.if_freq = p->if_freq; - amlatvdemod_devp->parm.if_inv = p->if_inv; - amlatvdemod_devp->parm.tuner_id = p->tuner_id; - /* open AGC if needed */ - if (amlatvdemod_devp->pin != NULL) - devm_pinctrl_put(amlatvdemod_devp->pin); - if (amlatvdemod_devp->pin_name) - amlatvdemod_devp->pin = - devm_pinctrl_get_select(amlatvdemod_devp->dev, - amlatvdemod_devp->pin_name); - atv_dmd_set_std(); - last_frq = c->frequency; - last_std = c->analog.std; - pr_info("[amlatvdemod..]%s set std color %s, audio type %s.\n", - __func__, - v4l2_std_to_str(0xff000000&amlatvdemod_devp->parm.std), - v4l2_std_to_str(0xffffff&amlatvdemod_devp->parm.std)); - pr_info("[amlatvdemod..]%s set if_freq 0x%x, if_inv 0x%x.\n", - __func__, amlatvdemod_devp->parm.if_freq, - amlatvdemod_devp->parm.if_inv); - } - } -} -static int aml_atvdemod_get_afc(struct dvb_frontend *fe, s32 *afc) -{ - *afc = retrieve_vpll_carrier_afc(); - pr_info("[amlatvdemod..]%s afc %d.\n", __func__, *afc); - return 0; -} - -static int aml_atvdemod_get_ops(struct aml_fe_dev *dev, int mode, void *ops) -{ - struct analog_demod_ops *aml_analog_ops = - (struct analog_demod_ops *)ops; - if (!ops) { - pr_dbg("[amlatvdemod..]%s null pointer error.\n", __func__); - return -1; - } - aml_analog_ops->get_afc = aml_atvdemod_get_afc; - aml_analog_ops->get_snr = aml_atvdemod_get_snr; - aml_analog_ops->get_status = aml_atvdemod_get_status; - aml_analog_ops->set_params = aml_atvdemod_set_params; - aml_analog_ops->get_pll_status = aml_atvdemod_get_pll_status; - aml_analog_ops->get_atv_status = aml_atvdemod_get_atv_status; - return 0; -} - -static struct aml_fe_drv aml_atvdemod_drv = { - .name = "aml_atv_demod", - .capability = AM_FE_ANALOG, - .id = AM_ATV_DEMOD_AML, - .get_ops = aml_atvdemod_get_ops, - .init = aml_atvdemod_fe_init, - .enter_mode = aml_atvdemod_enter_mode, - .leave_mode = aml_atvdemod_leave_mode, - .suspend = aml_atvdemod_suspend, - .resume = aml_atvdemod_resume, -}; - -struct class *aml_atvdemod_clsp; - -static void aml_atvdemod_dt_parse(struct platform_device *pdev) -{ - struct device_node *node; - unsigned int val; - int ret; - - node = pdev->dev.of_node; - /* get integer value */ - if (node) { - ret = of_property_read_u32(node, "reg_23cf", &val); - if (ret) - pr_dbg("Can't find reg_23cf.\n"); - else - reg_23cf = val; - ret = of_property_read_u32(node, "audio_gain_val", &val); - if (ret) - pr_dbg("Can't find audio_gain_val.\n"); - else - set_audio_gain_val(val); - ret = of_property_read_u32(node, "video_gain_val", &val); - if (ret) - pr_dbg("Can't find video_gain_val.\n"); - else - set_video_gain_val(val); - /* agc pin mux */ - ret = of_property_read_string(node, "pinctrl-names", - &amlatvdemod_devp->pin_name); - if (!ret) { - /* amlatvdemod_devp->pin = */ - /* devm_pinctrl_get_select(&pdev->dev, */ - /* amlatvdemod_devp->pin_name); */ - pr_dbg("atvdemod agc pinmux name:%s\n", - amlatvdemod_devp->pin_name); - } - } -} -static struct resource amlatvdemod_memobj; -void __iomem *amlatvdemod_reg_base; -void __iomem *amlatvdemod_hiu_reg_base; -void __iomem *amlatvdemod_periphs_reg_base; -int amlatvdemod_reg_read(unsigned int reg, unsigned int *val) -{ - *val = readl(amlatvdemod_reg_base + reg); - return 0; -} - -int amlatvdemod_reg_write(unsigned int reg, unsigned int val) -{ - writel(val, (amlatvdemod_reg_base + reg)); - return 0; -} - -int amlatvdemod_hiu_reg_read(unsigned int reg, unsigned int *val) -{ - *val = readl(amlatvdemod_hiu_reg_base + ((reg - 0x1000)<<2)); - return 0; -} - -int amlatvdemod_hiu_reg_write(unsigned int reg, unsigned int val) -{ - writel(val, (amlatvdemod_hiu_reg_base + ((reg - 0x1000)<<2))); - return 0; -} -int amlatvdemod_periphs_reg_read(unsigned int reg, unsigned int *val) -{ - *val = readl(amlatvdemod_periphs_reg_base + ((reg - 0x1000)<<2)); - return 0; -} - -int amlatvdemod_periphs_reg_write(unsigned int reg, unsigned int val) -{ - writel(val, (amlatvdemod_periphs_reg_base + ((reg - 0x1000)<<2))); - return 0; -} - -static int aml_atvdemod_probe(struct platform_device *pdev) -{ - int ret = 0; - struct resource *res; - int size_io_reg; - - res = &amlatvdemod_memobj; - amlatvdemod_devp = kmalloc(sizeof(struct amlatvdemod_device_s), - GFP_KERNEL); - if (!amlatvdemod_devp) - goto fail_alloc_region; - memset(amlatvdemod_devp, 0, sizeof(struct amlatvdemod_device_s)); - amlatvdemod_devp->clsp = class_create(THIS_MODULE, - ATVDEMOD_DEVICE_NAME); - if (!amlatvdemod_devp->clsp) - goto fail_create_class; - ret = class_create_file(amlatvdemod_devp->clsp, - &class_attr_atvdemod_debug); - if (ret) - goto fail_class_create_file; - amlatvdemod_devp->dev = &pdev->dev; - - /*reg mem*/ - pr_info("%s:amlatvdemod start get ioremap .\n", __func__); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "missing memory resource\n"); - return -ENODEV; - } - size_io_reg = resource_size(res); - pr_info("amlatvdemod_probe reg=%p,size=%x\n", - (void *)res->start, size_io_reg); - amlatvdemod_reg_base = - devm_ioremap_nocache(&pdev->dev, res->start, size_io_reg); - if (!amlatvdemod_reg_base) { - dev_err(&pdev->dev, "amlatvdemod ioremap failed\n"); - return -ENOMEM; - } - pr_info("%s: amlatvdemod maped reg_base =%p, size=%x\n", - __func__, amlatvdemod_reg_base, size_io_reg); - /*remap hiu mem*/ - amlatvdemod_hiu_reg_base = ioremap(0xc883c000, 0x2000); - /*remap periphs mem*/ - amlatvdemod_periphs_reg_base = ioremap(0xc8834000, 0x2000); - - /*initialize the tuner common struct and register*/ - aml_register_fe_drv(AM_DEV_ATV_DEMOD, &aml_atvdemod_drv); - - aml_atvdemod_dt_parse(pdev); - pr_dbg("[amlatvdemod.] : probe ok.\n"); - return 0; - -fail_class_create_file: - pr_dbg("[amlatvdemod.] : atvdemod class file create error.\n"); - class_destroy(amlatvdemod_devp->clsp); -fail_create_class: - pr_dbg("[amlatvdemod.] : atvdemod class create error.\n"); - kfree(amlatvdemod_devp); -fail_alloc_region: - pr_dbg("[amlatvdemod.] : atvdemod alloc error.\n"); - pr_dbg("[amlatvdemod.] : atvdemod_init fail.\n"); - return ret; -} - -static int __exit aml_atvdemod_remove(struct platform_device *pdev) -{ - if (amlatvdemod_devp == NULL) - return -1; - class_destroy(amlatvdemod_devp->clsp); - aml_unregister_fe_drv(AM_DEV_ATV_DEMOD, &aml_atvdemod_drv); - kfree(amlatvdemod_devp); - pr_dbg("[amlatvdemod.] : amvecm_remove.\n"); - return 0; -} - - -static const struct of_device_id aml_atvdemod_dt_match[] = { - { - .compatible = "amlogic, aml_atv_demod", - }, - {}, -}; - -static struct platform_driver aml_atvdemod_driver = { - .driver = { - .name = "aml_atv_demod", - .owner = THIS_MODULE, - .of_match_table = aml_atvdemod_dt_match, - }, - .probe = aml_atvdemod_probe, - .remove = __exit_p(aml_atvdemod_remove), -}; - - -static int __init aml_atvdemod_init(void) -{ - if (platform_driver_register(&aml_atvdemod_driver)) { - pr_err("failed to register amlatvdemod driver module\n"); - return -ENODEV; - } - pr_dbg("[amlatvdemod..]%s.\n", __func__); - return 0; -} - -static void __exit aml_atvdemod_exit(void) -{ - platform_driver_unregister(&aml_atvdemod_driver); - pr_dbg("[amlatvdemod..]%s: driver removed ok.\n", __func__); -} - -MODULE_AUTHOR("dezhi.kong "); -MODULE_DESCRIPTION("aml atv demod device driver"); -MODULE_LICENSE("GPL"); - -fs_initcall(aml_atvdemod_init); -module_exit(aml_atvdemod_exit); diff --git a/drivers/stream_input/tv_frontend/atv_demod/atvdemod_func.c b/drivers/stream_input/tv_frontend/atv_demod/atvdemod_func.c deleted file mode 100644 index f5a086e..0000000 --- a/drivers/stream_input/tv_frontend/atv_demod/atvdemod_func.c +++ b/dev/null @@ -1,2163 +0,0 @@ -/* - * Silicon labs amlogic Atvdemod Device Driver - * - * Author: dezhi kong - * - * - * Copyright (C) 2014 Amlogic Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Standard Liniux Headers */ -#include -#include -#include -#include -#include -#include -#include - -#include "atvdemod_func.h" -#include "../aml_dvb_reg.h" - -static int broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC; -module_param(broad_std, int, 0644); -MODULE_PARM_DESC(broad_std, "\n broad_std\n"); - -static unsigned long over_threshold = 0xffff; -module_param(over_threshold, ulong, 0644); -MODULE_PARM_DESC(over_threshold, "\n over_threshold\n"); - -static unsigned long input_amplitude = 0xffff; -module_param(input_amplitude, ulong, 0644); -MODULE_PARM_DESC(input_amplitude, "\n input_amplitude\n"); - -static bool audio_det_en; -module_param(audio_det_en, bool, 0644); -MODULE_PARM_DESC(audio_det_en, "\n audio_det_en\n"); - -static bool non_std_en; -module_param(non_std_en, bool, 0644); -MODULE_PARM_DESC(non_std__en, "\n non_std_en\n"); - -static int atv_video_gain; -module_param(atv_video_gain, int, 0644); -MODULE_PARM_DESC(atv_video_gain, "\n atv_video_gain\n"); - -static int audio_det_mode = AUDIO_AUTO_DETECT; -module_param(audio_det_mode, int, 0644); -MODULE_PARM_DESC(audio_det_mode, "\n audio_det_mode\n"); - -static int aud_dmd_jilinTV; -module_param(aud_dmd_jilinTV, int, 0644); -MODULE_PARM_DESC(aud_dmd_jilinTV, "\naud dmodulation setting for jilin TV\n"); - -static unsigned int if_freq = 4250000; /*PAL-DK:3250000;NTSC-M:4250000*/ -module_param(if_freq, uint, 0644); -MODULE_PARM_DESC(if_freq, "\n if_freq\n"); - -static int if_inv; -module_param(if_inv, int, 0644); -MODULE_PARM_DESC(if_inv, "\n if_inv\n"); - -static int afc_default = CARR_AFC_DEFAULT_VAL; -module_param(afc_default, int, 0644); -MODULE_PARM_DESC(afc_default, "\n afc_default\n"); - -/*GDE_Curve - * 0: CURVE-M - * 1: CURVE-A - * 2: CURVE-B - * 3: CURVE-CHINA - * 4: BYPASS - *BG --> CURVE-B(BYPASS) - *DK --> CURVE-CHINA - *NM --> CURVE-M - *I --> BYPASS - *SECAM --> BYPASS - */ -static int gde_curve; -module_param(gde_curve, int, 0644); -MODULE_PARM_DESC(gde_curve, "\n gde_curve\n"); - -static int sound_format; -module_param(sound_format, int, 0644); -MODULE_PARM_DESC(sound_format, "\n sound_format\n"); - -static unsigned int freq_hz_cvrt = AML_ATV_DEMOD_FREQ_60HZ_VERT; -module_param(freq_hz_cvrt, int, 0644); -MODULE_PARM_DESC(freq_hz_cvrt, "\n freq_hz\n"); - -int atvdemod_debug_en; -module_param(atvdemod_debug_en, int, 0644); -MODULE_PARM_DESC(atvdemod_debug_en, "\n atvdemod_debug_en\n"); - -/*1:gpio mode output low;2:pwm mode*/ -static unsigned int atvdemod_agc_pinmux = 2; -module_param(atvdemod_agc_pinmux, int, 0644); -MODULE_PARM_DESC(atvdemod_agc_pinmux, "\n atvdemod_agc_pinmux\n"); - -static unsigned int atvdemod_afc_range = 5; -module_param(atvdemod_afc_range, uint, 0644); -MODULE_PARM_DESC(atvdemod_afc_range, "\n atvdemod_afc_range\n"); - -static unsigned int atvdemod_afc_offset = 500; -module_param(atvdemod_afc_offset, uint, 0644); -MODULE_PARM_DESC(atvdemod_afc_offset, "\n atvdemod_afc_offset\n"); - -static unsigned int atvdemod_timer_en = 1; -module_param(atvdemod_timer_en, uint, 0644); -MODULE_PARM_DESC(atvdemod_timer_en, "\n atvdemod_timer_en\n"); - -static unsigned int atvdemod_afc_en; -module_param(atvdemod_afc_en, uint, 0644); -MODULE_PARM_DESC(atvdemod_afc_en, "\n atvdemod_afc_en\n"); - -static unsigned int atvdemod_monitor_en; -module_param(atvdemod_monitor_en, uint, 0644); -MODULE_PARM_DESC(atvdemod_monitor_en, "\n atvdemod_monitor_en\n"); - -static unsigned int atvdemod_det_snr_en = 1; -module_param(atvdemod_det_snr_en, uint, 0644); -MODULE_PARM_DESC(atvdemod_det_snr_en, "\n atvdemod_det_snr_en\n"); - -static unsigned int pwm_kp = 0x19; -module_param(pwm_kp, uint, 0644); -MODULE_PARM_DESC(pwm_kp, "\n pwm_kp\n"); - -static unsigned int reg_dbg_en; -module_param(reg_dbg_en, uint, 0644); -MODULE_PARM_DESC(reg_dbg_en, "\n reg_dbg_en\n"); - -static unsigned int audio_gain_val = 512; -module_param(audio_gain_val, uint, 0644); -MODULE_PARM_DESC(audio_gain_val, "\n audio_gain_val\n"); - -enum AUDIO_SCAN_ID { - ID_PAL_I = 0, - ID_PAL_M, - ID_PAL_DK, - ID_PAL_BG, - ID_MAX, -}; - -static unsigned int mix1_freq; -static unsigned int timer_init_flag; -struct timer_list atvdemod_timer; -static int snr_val; -int broad_std_except_pal_m; - -int get_atvdemod_snr_val(void) -{ - return snr_val; -} -EXPORT_SYMBOL(get_atvdemod_snr_val); - -void amlatvdemod_set_std(int val) -{ - broad_std = val; -} -EXPORT_SYMBOL(amlatvdemod_set_std); - -void atv_dmd_wr_reg(unsigned char block, unsigned char reg, unsigned long data) -{ - /* unsigned long data_tmp; */ - unsigned long reg_addr = (block<<8) + reg * 4; - - amlatvdemod_reg_write(reg_addr, data); -} - -unsigned long atv_dmd_rd_reg(unsigned char block, unsigned char reg) -{ - unsigned long data = 0; - unsigned long reg_addr = (block<<8) + reg * 4; - - amlatvdemod_reg_read(reg_addr, (unsigned int *)&data); - return data; -} - -unsigned long atv_dmd_rd_byte(unsigned long block_addr, unsigned long reg_addr) -{ - unsigned long data; - - data = atv_dmd_rd_long(block_addr, reg_addr); - /*R_APB_REG((((block_addr & 0xff) <<6) + ((reg_addr & 0xff) >>2)) << 2); - *((volatile unsigned long *) (ATV_DMD_APB_BASE_ADDR+ - ((((block_addr & 0xff) <<6) + ((reg_addr & 0xff) >>2)) << 2))); - */ - if ((reg_addr & 0x3) == 0) - data = data >> 24; - else if ((reg_addr & 0x3) == 1) - data = (data >> 16 & 0xff); - else if ((reg_addr & 0x3) == 2) - data = (data >> 8 & 0xff); - else if ((reg_addr & 0x3) == 3) - data = (data >> 0 & 0xff); - return data; -} - -unsigned long atv_dmd_rd_word(unsigned long block_addr, unsigned long reg_addr) -{ - unsigned long data; - - data = atv_dmd_rd_long(block_addr, reg_addr); - /*R_APB_REG((((block_addr & 0xff) <<6) + ((reg_addr & 0xff) >>2)) << 2); - *((volatile unsigned long *) (ATV_DMD_APB_BASE_ADDR+ - ((((block_addr & 0xff) <<6) + ((reg_addr & 0xff) >>2)) << 2))); - */ - if ((reg_addr & 0x3) == 0) - data = data >> 16; - else if ((reg_addr & 0x3) == 1) - data = (data >> 8 & 0xffff); - else if ((reg_addr & 0x3) == 2) - data = (data >> 0 & 0xffff); - else if ((reg_addr & 0x3) == 3) - data = (((data & 0xff) << 8) | ((data >> 24) & 0xff)); - return data; -} - -unsigned long atv_dmd_rd_long(unsigned long block_addr, unsigned long reg_addr) -{ - unsigned long data; - /*data = *((volatile unsigned long *) (ATV_DMD_APB_BASE_ADDR+ - *((((block_addr & 0xff) <<6) + ((reg_addr & 0xff) >>2)) << 2))); - */ - data = - R_ATVDEMOD_REG((((block_addr & 0xff) << 6) + - ((reg_addr & 0xff) >> 2)) << 2); - - return data; -} -EXPORT_SYMBOL(atv_dmd_rd_long); - -void atv_dmd_wr_long(unsigned long block_addr, unsigned long reg_addr, - unsigned long data) -{ - W_ATVDEMOD_REG((((block_addr & 0xff) << 6) + - ((reg_addr & 0xff) >> 2)) << 2, data); - if (reg_dbg_en) - pr_dbg("block_addr:0x%x,reg_addr:0x%x;data:0x%x\n", - (unsigned int)block_addr, (unsigned int)reg_addr, - (unsigned int)data); - /**((volatile unsigned long *) - * (ATV_DMD_APB_BASE_ADDR+((((block_addr & 0xff) << 6) + - * ((reg_addr & 0xff) >> 2)) << 2))) = data; - */ - -} -EXPORT_SYMBOL(atv_dmd_wr_long); - -void atv_dmd_wr_word(unsigned long block_addr, unsigned long reg_addr, - unsigned long data) -{ - unsigned long data_tmp; - - data_tmp = atv_dmd_rd_long(block_addr, reg_addr); - data = data & 0xffff; - if ((reg_addr & 0x3) == 0) - data = (data << 16 | (data_tmp & 0xffff)); - else if ((reg_addr & 0x3) == 1) - data = - ((data_tmp & 0xff000000) | (data << 8) | (data_tmp & 0xff)); - else if ((reg_addr & 0x3) == 2) - data = (data | (data_tmp & 0xffff0000)); - else if ((reg_addr & 0x3) == 3) - data = - (((data & 0xff) << 24) | ((data_tmp & 0xffff0000) >> 8) | - ((data & 0xff00) >> 8)); - - /**((volatile unsigned long *) (ATV_DMD_APB_BASE_ADDR+ - *((((block_addr & 0xff) <<6) + ((reg_addr & 0xff) >>2)) << 2))) = data; - */ - atv_dmd_wr_long(block_addr, reg_addr, data); - /*W_ATVDEMOD_REG(((((block_addr & 0xff) <<6) + - *((reg_addr & 0xff) >>2)) << 2), data); - */ - -} - -void atv_dmd_wr_byte(unsigned long block_addr, unsigned long reg_addr, - unsigned long data) -{ - unsigned long data_tmp; - - data_tmp = atv_dmd_rd_long(block_addr, reg_addr); - - /*pr_info("atv demod wr byte, read block addr %lx\n",block_addr);*/ - /*pr_info("atv demod wr byte, read reg addr %lx\n", reg_addr);*/ - /*pr_info("atv demod wr byte, wr data %lx\n",data);*/ - /*pr_info("atv demod wr byte, read data out %lx\n",data_tmp);*/ - - data = data & 0xff; - /*pr_info("atv demod wr byte, data & 0xff %lx\n",data);*/ - if ((reg_addr & 0x3) == 0) { - data = (data << 24 | (data_tmp & 0xffffff)); - /*pr_info("atv demod wr byte, reg_addr & 0x3 == 0, - *wr data %lx\n",data); - */ - } else if ((reg_addr & 0x3) == 1) - data = - ((data_tmp & 0xff000000) | (data << 16) | - (data_tmp & 0xffff)); - else if ((reg_addr & 0x3) == 2) - data = - ((data_tmp & 0xffff0000) | (data << 8) | (data_tmp & 0xff)); - else if ((reg_addr & 0x3) == 3) - data = ((data_tmp & 0xffffff00) | (data & 0xff)); - - /*pr_info("atv demod wr byte, wr data %lx\n",data);*/ - - /**((volatile unsigned long *) (ATV_DMD_APB_BASE_ADDR+ - *((((block_addr & 0xff) <<6) + ((reg_addr & 0xff) >>2)) << 2))) = data; - */ - atv_dmd_wr_long(block_addr, reg_addr, data); - /*W_ATVDEMOD_REG(((((block_addr & 0xff) <<6) + - *((reg_addr & 0xff) >>2)) << 2), data); - */ -} - -void set_audio_gain_val(int val) -{ - audio_gain_val = val; -} - -void set_video_gain_val(int val) -{ - atv_video_gain = val; -} - -void atv_dmd_soft_reset(void) -{ - atv_dmd_wr_long(0x1d, 0x0, 0x1035);/* disable dac */ - atv_dmd_wr_byte(APB_BLOCK_ADDR_SYSTEM_MGT, 0x0, 0x0); - atv_dmd_wr_byte(APB_BLOCK_ADDR_SYSTEM_MGT, 0x0, 0x1); - atv_dmd_wr_long(0x1d, 0x0, 0x1037);/* enable dac */ -} - -void atv_dmd_input_clk_32m(void) -{ - atv_dmd_wr_byte(APB_BLOCK_ADDR_ADC_MGR, 0x2, 0x1); -} - -void read_version_register(void) -{ - unsigned long data, Byte1, Byte2, Word; - - pr_info("ATV-DMD read version register\n"); - Byte1 = atv_dmd_rd_byte(APB_BLOCK_ADDR_VERS_REGISTER, 0x0); - Byte2 = atv_dmd_rd_byte(APB_BLOCK_ADDR_VERS_REGISTER, 0x1); - Word = atv_dmd_rd_word(APB_BLOCK_ADDR_VERS_REGISTER, 0x2); - data = atv_dmd_rd_long(APB_BLOCK_ADDR_VERS_REGISTER, 0x0); - - pr_info("atv demod read version register data out %lx\n", data); - - if ((data != 0x516EAB13) - || (((Byte1 << 24) | (Byte2 << 16) | Word) != 0x516EAB13)) - pr_info("atv demod read version reg failed\n"); -} - -void check_communication_interface(void) -{ - unsigned long data_tmp; - - pr_info("ATV-DMD check communication intf\n"); - atv_dmd_wr_long(APB_BLOCK_ADDR_VERS_REGISTER, 0x0, 0xA1B2C3D4); - atv_dmd_wr_byte(APB_BLOCK_ADDR_VERS_REGISTER, 0x1, 0x34); - atv_dmd_wr_word(APB_BLOCK_ADDR_VERS_REGISTER, 0x2, 0xBCDE); - data_tmp = atv_dmd_rd_long(APB_BLOCK_ADDR_VERS_REGISTER, 0x0); - pr_info("atv demod check communication intf data out %lx\n", data_tmp); - - if (data_tmp != 0xa134bcde) - pr_info("atv demod check communication intf failed\n"); - atv_dmd_wr_long(APB_BLOCK_ADDR_VERS_REGISTER, 0x0, 0x516EAB13); -} - -void power_on_receiver(void) -{ - atv_dmd_wr_byte(APB_BLOCK_ADDR_ADC_MGR, 0x2, 0x11); -} - -void atv_dmd_misc(void) -{ - atv_dmd_wr_byte(APB_BLOCK_ADDR_AGC_PWM, 0x08, 0x38); /*zhuangwei*/ - /*cpu.write_byte(8'h1A,8'h0E,8'h06);//zhuangwei*/ - /*cpu.write_byte(8'h19,8'h01,8'h7f);//zhuangwei*/ - atv_dmd_wr_byte(0x0f, 0x45, 0x90); /*zhuangwei*/ - - atv_dmd_wr_long(0x0f, 0x44, 0x5c8808c1);/*zhuangwei*/ - if (amlatvdemod_devp->parm.tuner_id == AM_TUNER_R840) { - atv_dmd_wr_long(0x0f, 0x3c, reg_23cf);/*zhuangwei*/ - /*guanzhong@20150804a*/ - atv_dmd_wr_byte(APB_BLOCK_ADDR_SIF_STG_2, 0x00, 0x1); - atv_dmd_wr_long(APB_BLOCK_ADDR_AGC_PWM, 0x08, 0x60180200); - /*dezhi@20150610a 0x1a maybe better?!*/ - /* atv_dmd_wr_byte(APB_BLOCK_ADDR_AGC_PWM, 0x09, 0x19); */ - } else { - atv_dmd_wr_long(0x0f, 0x3c, 0x88188832);/*zhuangwei*/ - atv_dmd_wr_long(APB_BLOCK_ADDR_AGC_PWM, 0x08, 0x46170200); - } - - if (amlatvdemod_devp->parm.tuner_id == AM_TUNER_MXL661) { - atv_dmd_wr_long(0x0c, 0x04, 0xbffa0000) ;/*test in sky*/ - atv_dmd_wr_long(0x0c, 0x00, 0x5a4000);/*test in sky*/ - /*guanzhong@20151013 fix nonstd def is:0x0c010301;0x0c020601*/ - atv_dmd_wr_long(APB_BLOCK_ADDR_CARR_RCVY, 0x24, 0x0c030901); - } else { - /*zhuangwei 0xdafa0000*/ - atv_dmd_wr_long(0x0c, 0x04, 0xc8fa0000); - atv_dmd_wr_long(0x0c, 0x00, 0x554000);/*zhuangwei*/ - } - atv_dmd_wr_long(0x19, 0x04, 0xdafa0000);/*zhuangwei*/ - atv_dmd_wr_long(0x19, 0x00, 0x4a4000);/*zhuangwei*/ - /*atv_dmd_wr_byte(0x0c,0x01,0x28);//pwd-out gain*/ - /*atv_dmd_wr_byte(0x0c,0x04,0xc0);//pwd-out offset*/ - - aml_audio_valume_gain_set(audio_gain_val); - /* 20160121 fix audio demodulation over */ - atv_dmd_wr_long(0x09, 0x00, 0x1030501); - atv_dmd_wr_long(0x09, 0x04, 0x1900000); - if (aud_dmd_jilinTV) - atv_dmd_wr_long(0x09, 0x00, 0x2030503); - if (non_std_en == 1) { - atv_dmd_wr_long(0x09, 0x00, 0x2030503); - atv_dmd_wr_long(0x0f, 0x44, 0x7c8808c1); - atv_dmd_wr_long(0x06, 0x24, 0x0c010801); - } else { - atv_dmd_wr_long(0x09, 0x00, 0x1030501); - if (atv_video_gain) - atv_dmd_wr_long(0x0f, 0x44, atv_video_gain); - else - atv_dmd_wr_long(0x0f, 0x44, 0xfc0808c1); - atv_dmd_wr_long(0x06, 0x24, 0xc030901); - } - -} - -/*Broadcast_Standard*/ -/* 0: NTSC*/ -/* 1: NTSC-J*/ -/* 2: PAL-M,*/ -/* 3: PAL-BG*/ -/* 4: DTV*/ -/* 5: SECAM- DK2*/ -/* 6: SECAM -DK3*/ -/* 7: PAL-BG, NICAM*/ -/* 8: PAL-DK-CHINA*/ -/* 9: SECAM-L / SECAM-DK3*/ -/* 10: PAL-I*/ -/* 11: PAL-DK1*/ -/*GDE_Curve*/ -/* 0: CURVE-M*/ -/* 1: CURVE-A*/ -/* 2: CURVE-B*/ -/* 3: CURVE-CHINA*/ -/* 4: BYPASS*/ -/*sound format 0: MONO;1:NICAM*/ -void configure_receiver(int Broadcast_Standard, unsigned int Tuner_IF_Frequency, - int Tuner_Input_IF_inverted, int GDE_Curve, - int sound_format) -{ - int tmp_int; - int mixer1 = 0; - int mixer3 = 0; - int mixer3_bypass = 0; - int cv = 0; - /*int if_freq = 0;*/ - - int i = 0; - int super_coef0 = 0; - int super_coef1 = 0; - int super_coef2 = 0; - int gp_coeff_1[37]; - int gp_coeff_2[37]; - int gp_cv_g1 = 0; - int gp_cv_g2 = 0; - int crvy_reg_1 = 0; - int crvy_reg_2 = 0; - int sif_co_mx = 0; - int sif_fi_mx = 0; - int sif_ic_bw = 0; - int sif_bb_bw = 0; - int sif_deemp = 0; - int sif_cfg_demod = 0; - int sif_fm_gain = 0; - int gd_coeff[6]; - int gd_bypass; - - pr_info("ATV-DMD configure receiver register\n"); - - if ((Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC) || - (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_J) || - (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M) || - (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_DK) || - (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_BG) || - (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_I)) { - gp_coeff_1[0] = 0x57777; - gp_coeff_1[1] = 0xdd777; - gp_coeff_1[2] = 0x7d777; - gp_coeff_1[3] = 0x75777; - gp_coeff_1[4] = 0x75777; - gp_coeff_1[5] = 0x7c777; - gp_coeff_1[6] = 0x5c777; - gp_coeff_1[7] = 0x44777; - gp_coeff_1[8] = 0x54777; - gp_coeff_1[9] = 0x47d77; - gp_coeff_1[10] = 0x55d77; - gp_coeff_1[11] = 0x55577; - gp_coeff_1[12] = 0x77577; - gp_coeff_1[13] = 0xc4c77; - gp_coeff_1[14] = 0xd7d77; - gp_coeff_1[15] = 0x75477; - gp_coeff_1[16] = 0xcc477; - gp_coeff_1[17] = 0x575d7; - gp_coeff_1[18] = 0xc4c77; - gp_coeff_1[19] = 0xdd757; - gp_coeff_1[20] = 0xdd477; - gp_coeff_1[21] = 0x77dd7; - gp_coeff_1[22] = 0x5dc77; - gp_coeff_1[23] = 0x47c47; - gp_coeff_1[24] = 0x57477; - gp_coeff_1[25] = 0x5c7c7; - gp_coeff_1[26] = 0xccc77; - gp_coeff_1[27] = 0x5ddd5; - gp_coeff_1[28] = 0x54477; - gp_coeff_1[29] = 0x7757d; - gp_coeff_1[30] = 0x755d7; - gp_coeff_1[31] = 0x47cc4; - gp_coeff_1[32] = 0x57d57; - gp_coeff_1[33] = 0x554cc; - gp_coeff_1[34] = 0x755d7; - gp_coeff_1[35] = 0x7d3b2; - gp_coeff_1[36] = 0x73a91; - gp_coeff_2[0] = 0xd5777; - gp_coeff_2[1] = 0x77777; - gp_coeff_2[2] = 0x7c777; - gp_coeff_2[3] = 0xcc777; - gp_coeff_2[4] = 0xc7777; - gp_coeff_2[5] = 0xdd777; - gp_coeff_2[6] = 0x44c77; - gp_coeff_2[7] = 0x54c77; - gp_coeff_2[8] = 0xdd777; - gp_coeff_2[9] = 0x7c777; - gp_coeff_2[10] = 0xc7c77; - gp_coeff_2[11] = 0x75c77; - gp_coeff_2[12] = 0xdd577; - gp_coeff_2[13] = 0x44777; - gp_coeff_2[14] = 0xd5c77; - gp_coeff_2[15] = 0xdc777; - gp_coeff_2[16] = 0xd7757; - gp_coeff_2[17] = 0x4c757; - gp_coeff_2[18] = 0x7d777; - gp_coeff_2[19] = 0x75477; - gp_coeff_2[20] = 0x57547; - gp_coeff_2[21] = 0xdc747; - gp_coeff_2[22] = 0x74777; - gp_coeff_2[23] = 0x75757; - gp_coeff_2[24] = 0x4cc75; - gp_coeff_2[25] = 0xd4747; - gp_coeff_2[26] = 0x7d7d7; - gp_coeff_2[27] = 0xd5577; - gp_coeff_2[28] = 0xc4c75; - gp_coeff_2[29] = 0xcc477; - gp_coeff_2[30] = 0xdd54c; - gp_coeff_2[31] = 0x7547d; - gp_coeff_2[32] = 0x55547; - gp_coeff_2[33] = 0x5575c; - gp_coeff_2[34] = 0xd543a; - gp_coeff_2[35] = 0x57b3a; - gp_coeff_2[36] = 0x77777; - gp_cv_g1 = 0x2b062d; - gp_cv_g2 = 0x40fa2d; - } else if ((Broadcast_Standard == - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG) || - (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_DK2) || - (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_DK3) || - (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG_NICAM)) { - gp_coeff_1[0] = 0x75777; - gp_coeff_1[1] = 0x57777; - gp_coeff_1[2] = 0x7d777; - gp_coeff_1[3] = 0x75777; - gp_coeff_1[4] = 0x75777; - gp_coeff_1[5] = 0x7c777; - gp_coeff_1[6] = 0x47777; - gp_coeff_1[7] = 0x74777; - gp_coeff_1[8] = 0xd5d77; - gp_coeff_1[9] = 0xc7777; - gp_coeff_1[10] = 0x77577; - gp_coeff_1[11] = 0xd7d77; - gp_coeff_1[12] = 0x75d77; - gp_coeff_1[13] = 0xdd477; - gp_coeff_1[14] = 0x77d77; - gp_coeff_1[15] = 0x75c77; - gp_coeff_1[16] = 0xc4477; - gp_coeff_1[17] = 0x4c777; - gp_coeff_1[18] = 0x5d5d7; - gp_coeff_1[19] = 0xd7d57; - gp_coeff_1[20] = 0x47577; - gp_coeff_1[21] = 0xd7dd7; - gp_coeff_1[22] = 0xd7d57; - gp_coeff_1[23] = 0xdd757; - gp_coeff_1[24] = 0xc75c7; - gp_coeff_1[25] = 0x7d477; - gp_coeff_1[26] = 0x5d747; - gp_coeff_1[27] = 0x7ddc7; - gp_coeff_1[28] = 0xc4c77; - gp_coeff_1[29] = 0xd4c75; - gp_coeff_1[30] = 0xc755d; - gp_coeff_1[31] = 0x47cc7; - gp_coeff_1[32] = 0xdd7d4; - gp_coeff_1[33] = 0x4c75d; - gp_coeff_1[34] = 0xc7dcc; - gp_coeff_1[35] = 0xd52a2; - gp_coeff_1[36] = 0x555a1; - gp_coeff_2[0] = 0x5d777; - gp_coeff_2[1] = 0x47777; - gp_coeff_2[2] = 0x7d777; - gp_coeff_2[3] = 0xcc777; - gp_coeff_2[4] = 0xd7777; - gp_coeff_2[5] = 0x7c777; - gp_coeff_2[6] = 0x7dd77; - gp_coeff_2[7] = 0xdd777; - gp_coeff_2[8] = 0x7c777; - gp_coeff_2[9] = 0x57c77; - gp_coeff_2[10] = 0x7c777; - gp_coeff_2[11] = 0xd5777; - gp_coeff_2[12] = 0xd7c77; - gp_coeff_2[13] = 0xdd777; - gp_coeff_2[14] = 0x77477; - gp_coeff_2[15] = 0xc7d77; - gp_coeff_2[16] = 0xc4777; - gp_coeff_2[17] = 0x57557; - gp_coeff_2[18] = 0xd5577; - gp_coeff_2[19] = 0xd5577; - gp_coeff_2[20] = 0x7d547; - gp_coeff_2[21] = 0x74757; - gp_coeff_2[22] = 0xc7577; - gp_coeff_2[23] = 0xcc7d5; - gp_coeff_2[24] = 0x4c747; - gp_coeff_2[25] = 0xddc77; - gp_coeff_2[26] = 0x54447; - gp_coeff_2[27] = 0xcc447; - gp_coeff_2[28] = 0x5755d; - gp_coeff_2[29] = 0x5dd57; - gp_coeff_2[30] = 0x54747; - gp_coeff_2[31] = 0x5747c; - gp_coeff_2[32] = 0xc77dd; - gp_coeff_2[33] = 0x47557; - gp_coeff_2[34] = 0x7a22a; - gp_coeff_2[35] = 0xc73aa; - gp_coeff_2[36] = 0x77777; - gp_cv_g1 = 0x2b2834; - gp_cv_g2 = 0x3f6c2e; - } else if ((Broadcast_Standard == - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK) || - (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_DK3)) { - gp_coeff_1[0] = 0x47777; - gp_coeff_1[1] = 0x77777; - gp_coeff_1[2] = 0x5d777; - gp_coeff_1[3] = 0x47777; - gp_coeff_1[4] = 0x75777; - gp_coeff_1[5] = 0x5c777; - gp_coeff_1[6] = 0x57777; - gp_coeff_1[7] = 0x44777; - gp_coeff_1[8] = 0x55d77; - gp_coeff_1[9] = 0x7d777; - gp_coeff_1[10] = 0x55577; - gp_coeff_1[11] = 0xd5d77; - gp_coeff_1[12] = 0xd7d77; - gp_coeff_1[13] = 0x47477; - gp_coeff_1[14] = 0xdc777; - gp_coeff_1[15] = 0x4cc77; - gp_coeff_1[16] = 0x77d57; - gp_coeff_1[17] = 0xc4777; - gp_coeff_1[18] = 0xdd7d7; - gp_coeff_1[19] = 0x7c757; - gp_coeff_1[20] = 0xd4477; - gp_coeff_1[21] = 0x755c7; - gp_coeff_1[22] = 0x47d57; - gp_coeff_1[23] = 0xd7c47; - gp_coeff_1[24] = 0xd4cc7; - gp_coeff_1[25] = 0x47577; - gp_coeff_1[26] = 0x5c7d5; - gp_coeff_1[27] = 0x4c75d; - gp_coeff_1[28] = 0xd57d7; - gp_coeff_1[29] = 0x44755; - gp_coeff_1[30] = 0x7557d; - gp_coeff_1[31] = 0xc477d; - gp_coeff_1[32] = 0xd5d44; - gp_coeff_1[33] = 0xdd77d; - gp_coeff_1[34] = 0x5d75b; - gp_coeff_1[35] = 0x74332; - gp_coeff_1[36] = 0xd4311; - gp_coeff_2[0] = 0xd7777; - gp_coeff_2[1] = 0x77777; - gp_coeff_2[2] = 0xdd777; - gp_coeff_2[3] = 0xdc777; - gp_coeff_2[4] = 0xc7777; - gp_coeff_2[5] = 0xdd777; - gp_coeff_2[6] = 0x77d77; - gp_coeff_2[7] = 0x77777; - gp_coeff_2[8] = 0x55777; - gp_coeff_2[9] = 0xc7d77; - gp_coeff_2[10] = 0xd4777; - gp_coeff_2[11] = 0xc7477; - gp_coeff_2[12] = 0x7c777; - gp_coeff_2[13] = 0xd5577; - gp_coeff_2[14] = 0xdd557; - gp_coeff_2[15] = 0x47577; - gp_coeff_2[16] = 0xd7477; - gp_coeff_2[17] = 0x55747; - gp_coeff_2[18] = 0xdd757; - gp_coeff_2[19] = 0xd7477; - gp_coeff_2[20] = 0x7d7d5; - gp_coeff_2[21] = 0xddd47; - gp_coeff_2[22] = 0xdd777; - gp_coeff_2[23] = 0x575d5; - gp_coeff_2[24] = 0x47547; - gp_coeff_2[25] = 0x555c7; - gp_coeff_2[26] = 0x7d447; - gp_coeff_2[27] = 0xd7447; - gp_coeff_2[28] = 0x757dd; - gp_coeff_2[29] = 0x7dc77; - gp_coeff_2[30] = 0x54747; - gp_coeff_2[31] = 0xc743b; - gp_coeff_2[32] = 0xd7c7c; - gp_coeff_2[33] = 0xd7557; - gp_coeff_2[34] = 0x55c7a; - gp_coeff_2[35] = 0x4cc29; - gp_coeff_2[36] = 0x77777; - gp_cv_g1 = 0x20682b; - gp_cv_g2 = 0x29322f; - } else if (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I) { - gp_coeff_1[0] = 0x77777; - gp_coeff_1[1] = 0x75777; - gp_coeff_1[2] = 0x7d777; - gp_coeff_1[3] = 0xd7777; - gp_coeff_1[4] = 0x74777; - gp_coeff_1[5] = 0xcc777; - gp_coeff_1[6] = 0x57777; - gp_coeff_1[7] = 0x5d577; - gp_coeff_1[8] = 0x5dd77; - gp_coeff_1[9] = 0x74777; - gp_coeff_1[10] = 0x77577; - gp_coeff_1[11] = 0x77c77; - gp_coeff_1[12] = 0xdc477; - gp_coeff_1[13] = 0x5d577; - gp_coeff_1[14] = 0x575d7; - gp_coeff_1[15] = 0xc7d57; - gp_coeff_1[16] = 0x77777; - gp_coeff_1[17] = 0x557d7; - gp_coeff_1[18] = 0xc7557; - gp_coeff_1[19] = 0x75c77; - gp_coeff_1[20] = 0x477d7; - gp_coeff_1[21] = 0xcc747; - gp_coeff_1[22] = 0x47dd7; - gp_coeff_1[23] = 0x775d7; - gp_coeff_1[24] = 0x47447; - gp_coeff_1[25] = 0x75cc7; - gp_coeff_1[26] = 0xc7777; - gp_coeff_1[27] = 0xc75d5; - gp_coeff_1[28] = 0x44c7d; - gp_coeff_1[29] = 0x74c47; - gp_coeff_1[30] = 0x47d75; - gp_coeff_1[31] = 0x7d57c; - gp_coeff_1[32] = 0xd5dc4; - gp_coeff_1[33] = 0xdd575; - gp_coeff_1[34] = 0xdb3bb; - gp_coeff_1[35] = 0x5c752; - gp_coeff_1[36] = 0x90880; - gp_coeff_2[0] = 0x5d777; - gp_coeff_2[1] = 0xd7777; - gp_coeff_2[2] = 0x77777; - gp_coeff_2[3] = 0xd5d77; - gp_coeff_2[4] = 0xc7777; - gp_coeff_2[5] = 0xd7777; - gp_coeff_2[6] = 0xddd77; - gp_coeff_2[7] = 0x55777; - gp_coeff_2[8] = 0x57777; - gp_coeff_2[9] = 0x54c77; - gp_coeff_2[10] = 0x4c477; - gp_coeff_2[11] = 0x74777; - gp_coeff_2[12] = 0xd5d77; - gp_coeff_2[13] = 0x47757; - gp_coeff_2[14] = 0x75577; - gp_coeff_2[15] = 0xc7577; - gp_coeff_2[16] = 0x4c747; - gp_coeff_2[17] = 0x7d477; - gp_coeff_2[18] = 0x7c757; - gp_coeff_2[19] = 0x55dd5; - gp_coeff_2[20] = 0x57577; - gp_coeff_2[21] = 0x44c47; - gp_coeff_2[22] = 0x5cc75; - gp_coeff_2[23] = 0x4cc77; - gp_coeff_2[24] = 0x47547; - gp_coeff_2[25] = 0x777d5; - gp_coeff_2[26] = 0xcccc7; - gp_coeff_2[27] = 0x57447; - gp_coeff_2[28] = 0xdc757; - gp_coeff_2[29] = 0x5755c; - gp_coeff_2[30] = 0x44747; - gp_coeff_2[31] = 0x5d5dd; - gp_coeff_2[32] = 0x5747b; - gp_coeff_2[33] = 0x77557; - gp_coeff_2[34] = 0xdcb2a; - gp_coeff_2[35] = 0xd5779; - gp_coeff_2[36] = 0x77777; - gp_cv_g1 = 0x72242f; - gp_cv_g2 = 0x28822a; - } - - if ((Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC) || - (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_J)) { - sif_co_mx = 0xb8; - sif_fi_mx = 0x0; - sif_ic_bw = 0x1; - sif_bb_bw = 0x1; - sif_deemp = 0x1; - sif_cfg_demod = (sound_format == 0) ? 0x0:0x2; - sif_fm_gain = 0x4; - } else if ((Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG) - || (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_BG)) { - sif_co_mx = 0xa6; - sif_fi_mx = 0x10; - sif_ic_bw = 0x2; - sif_bb_bw = 0x0; - sif_deemp = 0x2; - sif_cfg_demod = (sound_format == 0) ? 0x0:0x2; - sif_fm_gain = 0x3; - } else if (Broadcast_Standard == - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK1) { - sif_co_mx = 154; - sif_fi_mx = 240; - sif_ic_bw = 2; - sif_bb_bw = 0; - sif_deemp = 2; - sif_cfg_demod = (sound_format == 0) ? 0:2; - sif_fm_gain = 3; - } else if (Broadcast_Standard == - AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_DK2) { - sif_co_mx = 150; - sif_fi_mx = 16; - sif_ic_bw = 2; - sif_bb_bw = 0; - sif_deemp = 2; - sif_cfg_demod = (sound_format == 0) ? 0:2; - sif_fm_gain = 3; - } else if (Broadcast_Standard == - AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_DK3) { - sif_co_mx = 158; - sif_fi_mx = 208; - sif_ic_bw = 3; - sif_bb_bw = 0; - sif_deemp = 2; - sif_cfg_demod = (sound_format == 0) ? 0:2; - sif_fm_gain = 3; - } else if ((Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I) - || (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_I)) { - sif_co_mx = 153; - sif_fi_mx = 56; - sif_ic_bw = 3; - sif_bb_bw = 0; - sif_deemp = 2; - sif_cfg_demod = (sound_format == 0) ? 0:2; - sif_fm_gain = 3; - } else if (Broadcast_Standard == - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG_NICAM) { - sif_co_mx = 163; - sif_fi_mx = 40; - sif_ic_bw = 0; - sif_bb_bw = 0; - sif_deemp = 2; - sif_cfg_demod = (sound_format == 0) ? 0:2; - sif_fm_gain = 3; - } else if (Broadcast_Standard == - AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_L) { - sif_co_mx = 159; - sif_fi_mx = 200; - sif_ic_bw = 3; - sif_bb_bw = 0; - sif_deemp = 0; - sif_cfg_demod = (sound_format == 0) ? 1:2; - sif_fm_gain = 5; - } else if ((Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK) - || (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_DK)) { - sif_co_mx = 159; - sif_fi_mx = 200; - sif_ic_bw = 3; - sif_bb_bw = 0; - sif_deemp = 2; - sif_cfg_demod = (sound_format == 0) ? 0:2; - sif_fm_gain = 3; - } else if (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M) { - sif_co_mx = 182; - sif_fi_mx = 16; - sif_ic_bw = 1; - sif_bb_bw = 0; - sif_deemp = 1; - sif_cfg_demod = (sound_format == 0) ? 0:2; - sif_fm_gain = 3; - } - sif_fm_gain -= 2; /*avoid sound overflow@guanzhong*/ - /*FE PATH*/ - pr_info("ATV-DMD configure mixer\n"); - if (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_DTV) { - tmp_int = (Tuner_IF_Frequency/125000); - if (Tuner_Input_IF_inverted == 0x0) - mixer1 = -tmp_int; - else - mixer1 = tmp_int; - - mixer3 = 0; - mixer3_bypass = 0; - } else { - tmp_int = (Tuner_IF_Frequency/125000); - pr_info("ATV-DMD configure mixer 1\n"); - - if (Tuner_Input_IF_inverted == 0x0) - mixer1 = 0xe8 - tmp_int; - else - mixer1 = tmp_int - 0x18; - - pr_info("ATV-DMD configure mixer 2\n"); - mixer3 = 0x30; - mixer3_bypass = 0x1; - } - - pr_info("ATV-DMD configure mixer 3\n"); - atv_dmd_wr_byte(APB_BLOCK_ADDR_MIXER_1, 0x0, mixer1); - atv_dmd_wr_word(APB_BLOCK_ADDR_MIXER_3, 0x0, - (((mixer3 & 0xff) << 8) | (mixer3_bypass & 0xff))); - - if (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_L) - atv_dmd_wr_long(APB_BLOCK_ADDR_ADC_SE, 0x0, 0x03180e0f); - else - atv_dmd_wr_long(APB_BLOCK_ADDR_ADC_SE, 0x0, 0x03150e0f); - if (amlatvdemod_devp->parm.tuner_id == AM_TUNER_R840) { - /*config pwm for tuner r840*/ - atv_dmd_wr_byte(APB_BLOCK_ADDR_ADC_SE, 1, 0xf); - } - - /*GP Filter*/ - pr_info("ATV-DMD configure GP_filter\n"); - if (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_DTV) { - cv = gp_cv_g1; - atv_dmd_wr_long(APB_BLOCK_ADDR_GP_VD_FLT, 0x0, - (0x08000000 | (cv & 0x7fffff))); - atv_dmd_wr_byte(APB_BLOCK_ADDR_GP_VD_FLT, 0x4, 0x04); - for (i = 0; i < 9; i = i + 1) { - /*super_coef = {gp_coeff_1[i*4],gp_coeff_1[i*4+1], - *gp_coeff_1[i*4+2],gp_coeff_1[i*4+3]}; - */ - super_coef0 = - (((gp_coeff_1[i * 4 + 2] & 0xfff) << 20) | - (gp_coeff_1[i * 4 + 3] & 0xfffff)); - super_coef1 = - (((gp_coeff_1[i * 4] & 0xf) << 28) | - ((gp_coeff_1[i * 4 + 1] & 0xfffff) << 8) | - ((gp_coeff_1[i * 4 + 2] >> 12) & 0xff)); - super_coef2 = ((gp_coeff_1[i * 4] >> 4) & 0xffff); - - /*atv_dmd_wr_long(APB_BLOCK_ADDR_GP_VD_FLT, - *0x8,super_coef[79:48]); - */ - /*atv_dmd_wr_long(APB_BLOCK_ADDR_GP_VD_FLT, - *0xC,super_coef[47:16]); - */ - /*atv_dmd_wr_word(APB_BLOCK_ADDR_GP_VD_FLT, - *0x10,super_coef[15:0]); - */ - atv_dmd_wr_long(APB_BLOCK_ADDR_GP_VD_FLT, 0x8, - (((super_coef2 & 0xffff) << 16) | - ((super_coef1 & 0xffff0000) >> 16))); - atv_dmd_wr_long(APB_BLOCK_ADDR_GP_VD_FLT, 0xC, - (((super_coef1 & 0xffff) << 16) | - ((super_coef0 & 0xffff0000) >> 16))); - atv_dmd_wr_word(APB_BLOCK_ADDR_GP_VD_FLT, 0x10, - (super_coef0 & 0xffff)); - atv_dmd_wr_byte(APB_BLOCK_ADDR_GP_VD_FLT, 0x05, i); - } - /*atv_dmd_wr_long - *(APB_BLOCK_ADDR_GP_VD_FLT,0x8,{gp_coeff_1[36],12'd0}); - */ - atv_dmd_wr_long(APB_BLOCK_ADDR_GP_VD_FLT, 0x8, - ((gp_coeff_1[36] & 0xfffff) << 12)); - atv_dmd_wr_byte(APB_BLOCK_ADDR_GP_VD_FLT, 0x05, 0x09); - - } else { - cv = gp_cv_g1 - gp_cv_g2; - atv_dmd_wr_long(APB_BLOCK_ADDR_GP_VD_FLT, 0x0, cv & 0x7fffff); - atv_dmd_wr_byte(APB_BLOCK_ADDR_GP_VD_FLT, 0x4, 0x00); - for (i = 0; i < 9; i = i + 1) { - /*super_coef = {gp_coeff_1[i*4],gp_coeff_1[i*4+1], - *gp_coeff_1[i*4+2],gp_coeff_1[i*4+3]}; - */ - super_coef0 = - (((gp_coeff_1[i * 4 + 2] & 0xfff) << 20) | - (gp_coeff_1[i * 4 + 3] & 0xfffff)); - super_coef1 = - (((gp_coeff_1[i * 4] & 0xf) << 28) | - ((gp_coeff_1[i * 4 + 1] & 0xfffff) << 8) | - ((gp_coeff_1[i * 4 + 2] >> 12) & 0xff)); - super_coef2 = ((gp_coeff_1[i * 4] >> 4) & 0xffff); - - /*atv_dmd_wr_long(APB_BLOCK_ADDR_GP_VD_FLT, - *0x8,super_coef[79:48]); - */ - /*atv_dmd_wr_long(APB_BLOCK_ADDR_GP_VD_FLT, - *0xC,super_coef[47:16]); - */ - /*atv_dmd_wr_word(APB_BLOCK_ADDR_GP_VD_FLT, - *0x10,super_coef[15:0]); - */ - atv_dmd_wr_long(APB_BLOCK_ADDR_GP_VD_FLT, 0x8, - (((super_coef2 & 0xffff) << 16) | - ((super_coef1 & 0xffff0000) >> 16))); - atv_dmd_wr_long(APB_BLOCK_ADDR_GP_VD_FLT, 0xC, - (((super_coef1 & 0xffff) << 16) | - ((super_coef0 & 0xffff0000) >> 16))); - atv_dmd_wr_word(APB_BLOCK_ADDR_GP_VD_FLT, 0x10, - (super_coef0 & 0xffff)); - atv_dmd_wr_byte(APB_BLOCK_ADDR_GP_VD_FLT, 0x05, i); - - /*atv_dmd_wr_long(APB_BLOCK_ADDR_GP_VD_FLT, - *0x8,{gp_coeff_1[36],12'd0}); - */ - } - atv_dmd_wr_long(APB_BLOCK_ADDR_GP_VD_FLT, 0x8, - ((gp_coeff_1[36] & 0xfffff) << 12)); - atv_dmd_wr_byte(APB_BLOCK_ADDR_GP_VD_FLT, 0x05, 9); - atv_dmd_wr_byte(APB_BLOCK_ADDR_GP_VD_FLT, 0x4, 0x01); - - for (i = 0; i < 9; i = i + 1) { - /*super_coef = {gp_coeff_2[i*4],gp_coeff_2[i*4+1], - *gp_coeff_2[i*4+2],gp_coeff_2[i*4+3]}; - */ - super_coef0 = - (((gp_coeff_2[i * 4 + 2] & 0xfff) << 20) | - (gp_coeff_2[i * 4 + 3] & 0xfffff)); - super_coef1 = - (((gp_coeff_2[i * 4] & 0xf) << 28) | - ((gp_coeff_2[i * 4 + 1] & 0xfffff) << 8) | - ((gp_coeff_2[i * 4 + 2] >> 12) & 0xff)); - super_coef2 = ((gp_coeff_2[i * 4] >> 4) & 0xffff); - - atv_dmd_wr_long(APB_BLOCK_ADDR_GP_VD_FLT, 0x8, - (((super_coef2 & 0xffff) << 16) | - ((super_coef1 & 0xffff0000) >> 16))); - atv_dmd_wr_long(APB_BLOCK_ADDR_GP_VD_FLT, 0xC, - (((super_coef1 & 0xffff) << 16) | - ((super_coef0 & 0xffff0000) >> 16))); - atv_dmd_wr_word(APB_BLOCK_ADDR_GP_VD_FLT, 0x10, - (super_coef0 & 0xffff)); - atv_dmd_wr_byte(APB_BLOCK_ADDR_GP_VD_FLT, 0x05, i); - } - - atv_dmd_wr_long(APB_BLOCK_ADDR_GP_VD_FLT, 0x8, - ((gp_coeff_2[36] & 0xfffff) << 12)); - atv_dmd_wr_byte(APB_BLOCK_ADDR_GP_VD_FLT, 0x05, 0x09); - } - - /*CRVY*/ - pr_info("ATV-DMD configure CRVY\n"); - if (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_DTV) { - crvy_reg_1 = 0xFF; - crvy_reg_2 = 0x00; - } else { - crvy_reg_1 = 0x04; - crvy_reg_2 = 0x01; - } - - atv_dmd_wr_byte(APB_BLOCK_ADDR_CARR_RCVY, 0x29, crvy_reg_1); - pr_info("ATV-DMD configure rcvy 2\n"); - pr_info("ATV-DMD configure rcvy, crvy_reg_2 = %x\n", crvy_reg_2); - atv_dmd_wr_byte(APB_BLOCK_ADDR_CARR_RCVY, 0x20, crvy_reg_2); - - /*SOUND SUPPRESS*/ - pr_info("ATV-DMD configure sound suppress\n"); - - if ((Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_DTV) || - (sound_format == 0)) - atv_dmd_wr_byte(APB_BLOCK_ADDR_SIF_VD_IF, 0x02, 0x01); - else - atv_dmd_wr_byte(APB_BLOCK_ADDR_SIF_VD_IF, 0x02, 0x00); - - /*SIF*/ - pr_info("ATV-DMD configure sif\n"); - if (!(Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_DTV)) { - atv_dmd_wr_byte(APB_BLOCK_ADDR_SIF_IC_STD, 0x03, sif_ic_bw); - atv_dmd_wr_byte(APB_BLOCK_ADDR_SIF_IC_STD, 0x01, sif_fi_mx); - atv_dmd_wr_byte(APB_BLOCK_ADDR_SIF_IC_STD, 0x02, sif_co_mx); - - atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0x00, - (((sif_bb_bw & 0xff) << 24) | - ((sif_deemp & 0xff) << 16) | 0x0500 | - sif_fm_gain)); - atv_dmd_wr_byte(APB_BLOCK_ADDR_SIF_STG_2, 0x06, sif_cfg_demod); - atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0x24, - (((sif_bb_bw & 0xff) << 24) | - 0xfffff)); - atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0x1c, 0x1f000); - } - - if (Broadcast_Standard != AML_ATV_DEMOD_VIDEO_MODE_PROP_DTV) { - if (sound_format == 0) { - tmp_int = 0; - atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_3, 0x00, - (0x01000000 | (tmp_int & 0xffffff))); - } else { - tmp_int = (256 - sif_co_mx) << 13; - atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_3, 0x00, - (tmp_int & 0xffffff)); - } - } - - if (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_DTV) { - atv_dmd_wr_long(APB_BLOCK_ADDR_IC_AGC, 0x00, 0x02040E0A); - atv_dmd_wr_word(APB_BLOCK_ADDR_IC_AGC, 0x04, 0x0F0D); - } else if (sound_format == 0) - atv_dmd_wr_byte(APB_BLOCK_ADDR_IC_AGC, 0x00, 0x04); - else if (Broadcast_Standard == - AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_L) { - atv_dmd_wr_long(APB_BLOCK_ADDR_IC_AGC, 0x00, 0x0003140A); - atv_dmd_wr_word(APB_BLOCK_ADDR_IC_AGC, 0x04, 0x1244); - } else { - atv_dmd_wr_long(APB_BLOCK_ADDR_IC_AGC, 0x00, 0x00040E0A); - atv_dmd_wr_word(APB_BLOCK_ADDR_IC_AGC, 0x04, 0x0D68); - } - - /*VAGC*/ - pr_info("ATV-DMD configure vagc\n"); - atv_dmd_wr_long(APB_BLOCK_ADDR_VDAGC, 0x48, 0x9B6F2C00); - /*bw select mode*/ - atv_dmd_wr_byte(APB_BLOCK_ADDR_VDAGC, 0x37, 0x1C); - /*disable prefilter*/ - - if (Broadcast_Standard == AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_L) { - atv_dmd_wr_word(APB_BLOCK_ADDR_VDAGC, 0x44, 0x4450); - atv_dmd_wr_byte(APB_BLOCK_ADDR_VDAGC, 0x46, 0x44); - atv_dmd_wr_long(APB_BLOCK_ADDR_VDAGC, 0x4, 0x3E04FC); - atv_dmd_wr_word(APB_BLOCK_ADDR_VDAGC, 0x3C, 0x4848); - atv_dmd_wr_byte(APB_BLOCK_ADDR_VDAGC, 0x3E, 0x48); - } else { - atv_dmd_wr_word(APB_BLOCK_ADDR_VDAGC, 0x44, 0xB800); - atv_dmd_wr_byte(APB_BLOCK_ADDR_VDAGC, 0x46, 0x08); - atv_dmd_wr_long(APB_BLOCK_ADDR_VDAGC, 0x4, 0x3C04FC); - atv_dmd_wr_word(APB_BLOCK_ADDR_VDAGC, 0x3C, 0x1818); - atv_dmd_wr_byte(APB_BLOCK_ADDR_VDAGC, 0x3E, 0x10); - } - - /*tmp_real = $itor(Hz_Freq)/0.23841858; //TODO*/ - /*tmp_int = $rtoi(tmp_real); //TODO*/ - /*tmp_int = Hz_Freq/0.23841858; //TODO*/ - /*tmp_int_2 = ((unsigned long)15625)*10000/23841858;*/ - /*tmp_int_2 = ((unsigned long)Hz_Freq)*10000/23841858;*/ - atv_dmd_wr_word(APB_BLOCK_ADDR_VDAGC, 0x10, - (freq_hz_cvrt >> 8) & 0xffff); - atv_dmd_wr_byte(APB_BLOCK_ADDR_VDAGC, 0x12, (freq_hz_cvrt & 0xff)); - - /*OUTPUT STAGE*/ - pr_info("ATV-DMD configure output stage\n"); - if (Broadcast_Standard != AML_ATV_DEMOD_VIDEO_MODE_PROP_DTV) { - atv_dmd_wr_byte(APB_BLOCK_ADDR_DAC_UPS, 0x0, 0x00); - atv_dmd_wr_byte(APB_BLOCK_ADDR_DAC_UPS, 0x1, 0x40); - atv_dmd_wr_byte(APB_BLOCK_ADDR_DAC_UPS, 0x2, 0x40); - atv_dmd_wr_byte(APB_BLOCK_ADDR_DAC_UPS, 0x4, 0xFA); - atv_dmd_wr_byte(APB_BLOCK_ADDR_DAC_UPS, 0x5, 0xFA); - } - - /*GDE FILTER*/ - pr_info("ATV-DMD configure gde filter\n"); - if (GDE_Curve == 0) { - gd_coeff[0] = 0x020; /*12'sd32;*/ - gd_coeff[1] = 0xf5f; /*-12'sd161;*/ - gd_coeff[2] = 0x1fe; /*12'sd510;*/ - gd_coeff[3] = 0xc0b; /*-12'sd1013;*/ - gd_coeff[4] = 0x536; /*12'sd1334;*/ - gd_coeff[5] = 0xb34; /*-12'sd1228;*/ - gd_bypass = 0x1; - } else if (GDE_Curve == 1) { - gd_coeff[0] = 0x8; /*12'sd8;*/ - gd_coeff[1] = 0xfd5; /*-12'sd43;*/ - gd_coeff[2] = 0x8d; /*12'sd141;*/ - gd_coeff[3] = 0xe69; /*-12'sd407;*/ - gd_coeff[4] = 0x1f1; /*12'sd497;*/ - gd_coeff[5] = 0xe7e; /*-12'sd386;*/ - gd_bypass = 0x1; - } else if (GDE_Curve == 2) { - gd_coeff[0] = 0x35; /*12'sd53;*/ - gd_coeff[1] = 0xf41; /*-12'sd191;*/ - gd_coeff[2] = 0x68; /*12'sd104;*/ - gd_coeff[3] = 0xea5; /*-12'sd347;*/ - gd_coeff[4] = 0x322; /*12'sd802;*/ - gd_coeff[5] = 0x1bb; /*12'sd443;*/ - gd_bypass = 0x1; - } else if (GDE_Curve == 3) { - gd_coeff[0] = 0xf; /*12'sd15;*/ - gd_coeff[1] = 0xfb5; /*-12'sd75;*/ - gd_coeff[2] = 0xcc; /*12'sd204;*/ - gd_coeff[3] = 0xe51; - gd_coeff[4] = 0x226; /*12'sd550;*/ - gd_coeff[5] = 0xd02; - gd_bypass = 0x1; - } else - gd_bypass = 0x0; - - if (gd_bypass == 0x0) - atv_dmd_wr_byte(APB_BLOCK_ADDR_GDE_EQUAL, 0x0D, gd_bypass); - else { - for (i = 0; i < 6; i = i + 1) - atv_dmd_wr_word(APB_BLOCK_ADDR_GDE_EQUAL, i << 1, - gd_coeff[i]); - atv_dmd_wr_byte(APB_BLOCK_ADDR_GDE_EQUAL, 0x0C, 0x01); - atv_dmd_wr_byte(APB_BLOCK_ADDR_GDE_EQUAL, 0x0D, gd_bypass); - } - - /*PWM*/ - pr_info("ATV-DMD configure pwm\n"); - atv_dmd_wr_long(APB_BLOCK_ADDR_AGC_PWM, 0x00, 0x1f40); /*4KHz*/ - atv_dmd_wr_long(APB_BLOCK_ADDR_AGC_PWM, 0x04, 0xc8); - /*26 dB dynamic range*/ - atv_dmd_wr_byte(APB_BLOCK_ADDR_AGC_PWM, 0x09, 0xa); - if (amlatvdemod_devp->parm.tuner_id == AM_TUNER_R840) { - /*config pwm for tuner r840*/ - atv_dmd_wr_long(APB_BLOCK_ADDR_AGC_PWM, 0, 0xc80); - /* guanzhong for Tuner AGC shock */ - atv_dmd_wr_long(APB_BLOCK_ADDR_AGC_PWM, 0x08, 0x46180200); - /* atv_dmd_wr_byte(APB_BLOCK_ADDR_ADC_SE,1,0xf);//Kd = 0xf */ - } -} - -void retrieve_adc_power(int *adc_level) -{ - *adc_level = atv_dmd_rd_long(APB_BLOCK_ADDR_ADC_SE, 0x0c); - /*adc_level = adc_level/32768*100;*/ - *adc_level = (*adc_level) * 100 / 32768; -} - -void retrieve_vpll_carrier_lock(int *lock) -{ - unsigned int data; - - data = atv_dmd_rd_byte(APB_BLOCK_ADDR_CARR_RCVY, 0x43); - *lock = (data & 0x1); -} -int retrieve_vpll_carrier_afc(void) -{ - int data_ret, pll_lock, field_lock, line_lock, line_lock_strong; - unsigned int data_h, data_l, data_exg = 0; - - pll_lock = atv_dmd_rd_byte(APB_BLOCK_ADDR_CARR_RCVY, 0x43)&0x1; - field_lock = atv_dmd_rd_byte(APB_BLOCK_ADDR_VDAGC, 0x4f)&0x4; - line_lock = atv_dmd_rd_byte(APB_BLOCK_ADDR_VDAGC, 0x4f)&0x10; - line_lock_strong = atv_dmd_rd_byte(APB_BLOCK_ADDR_VDAGC, 0x4f)&0x8; - /* if((atv_dmd_rd_byte(APB_BLOCK_ADDR_CARR_RCVY,0x43)&0x1) == 1){ */ - if ((pll_lock == 1) || (line_lock == 0x10)) { - /*if pll unlock, afc is invalid*/ - data_ret = 0xffff;/* 500; */ - return data_ret; - } - data_h = atv_dmd_rd_byte(APB_BLOCK_ADDR_CARR_RCVY, 0x40); - data_l = atv_dmd_rd_byte(APB_BLOCK_ADDR_CARR_RCVY, 0x41); - data_exg = ((data_h&0x7) << 8) | data_l; - if (data_h&0x8) { - data_ret = (((~data_exg)&0x7ff) - 1); - data_ret = data_ret*488*(-1)/1000; - } else { - data_ret = data_exg; - data_ret = data_ret*488/1000; - } - if ((abs(data_ret) < 50) && (line_lock_strong == 0x8) && - (field_lock == 0x4)) { - data_ret = 100; - return data_ret; - } - return data_ret; -} -void set_pll_lpf(unsigned int lock) -{ - atv_dmd_wr_byte(APB_BLOCK_ADDR_CARR_RCVY, 0x24, lock); -} - -void retrieve_frequency_offset(int *freq_offset) -{ - /*unsigned int data; - *data = atv_dmd_rd_word(APB_BLOCK_ADDR_CARR_RCVY,0x40); - **freq_offset = (int)data; - */ - unsigned int data_h, data_l, data_exg; - int data_ret; - - data_h = atv_dmd_rd_byte(APB_BLOCK_ADDR_CARR_RCVY, 0x40); - data_l = atv_dmd_rd_byte(APB_BLOCK_ADDR_CARR_RCVY, 0x41); - data_exg = ((data_h&0x7)<<8) | data_l; - if (data_h&0x8) { - data_ret = (((~data_exg) & 0x7ff) - 1); - data_ret = data_ret*(-1); - /* data_ret = data_ret*488*(-1) /1000; */ - } else - data_ret = data_exg;/* data_ret = data_ret*488/100; */ - *freq_offset = data_ret; -} -EXPORT_SYMBOL(retrieve_frequency_offset); -void retrieve_video_lock(int *lock) -{ - unsigned int data, wlock, slock; - - data = atv_dmd_rd_byte(APB_BLOCK_ADDR_VDAGC, 0x4f); - wlock = data & 0x10; - slock = data & 0x80; - *lock = wlock & slock; -} - -void retrieve_fh_frequency(int *fh) -{ - unsigned long data1, data2; - - data1 = atv_dmd_rd_word(APB_BLOCK_ADDR_VDAGC, 0x58); - data2 = atv_dmd_rd_long(APB_BLOCK_ADDR_VDAGC, 0x10); - data1 = data1 >> 11; - data2 = data2 >> 3; - *fh = data1 + data2; -} -/*tune mix to adapt afc*/ -void atvdemod_afc_tune(void) -{ - /* int adc_level,lock,freq_offset,fh; */ - int freq_offset, lock, mix1_freq_cur, delta_mix1_freq; - - /* retrieve_adc_power(&adc_level); */ - /* pr_info("adc_level: 0x%x\n",adc_level); */ - retrieve_vpll_carrier_lock(&lock); - mix1_freq_cur = atv_dmd_rd_byte(APB_BLOCK_ADDR_MIXER_1, 0x0); - delta_mix1_freq = abs(mix1_freq_cur - mix1_freq); - if ((lock&0x1) == 0) - pr_info("%s visual carrier lock:locked\n", __func__); - else - pr_info("%s visual carrier lock:unlocked\n", __func__); - /* set_pll_lpf(lock); */ - retrieve_frequency_offset(&freq_offset); - freq_offset = freq_offset*488/1000; - /* pr_info("visual carrier offset:%d Hz\n", - *freq_offset*48828125/100000); - */ - /* retrieve_video_lock(&lock); */ - if ((lock&0x1) == 1) { - if (delta_mix1_freq == atvdemod_afc_range) - atv_dmd_wr_byte(APB_BLOCK_ADDR_MIXER_1, 0x0, mix1_freq); - else if ((freq_offset >= atvdemod_afc_offset) && - (delta_mix1_freq < atvdemod_afc_range)) - atv_dmd_wr_byte(APB_BLOCK_ADDR_MIXER_1, 0x0, - mix1_freq_cur-1); - else if ((freq_offset <= (-1)*atvdemod_afc_offset) && - (delta_mix1_freq < atvdemod_afc_range-1)) - atv_dmd_wr_byte(APB_BLOCK_ADDR_MIXER_1, 0x0, - mix1_freq_cur+1); - /* pr_info("video lock:locked\n"); */ - } - /* retrieve_fh_frequency(&fh); */ - /* pr_info("horizontal frequency:%d Hz\n",fh*190735/100000); */ -} -static enum amlatvdemod_snr_level_e aml_atvdemod_get_snr_level(void) -{ - unsigned int snr_val, i, snr_d[8]; - enum amlatvdemod_snr_level_e ret; - unsigned long fsnr; - - snr_val = atv_dmd_rd_long(APB_BLOCK_ADDR_VDAGC, 0x50)>>8; - fsnr = snr_val; - for (i = 1; i < 8; i++) { - snr_d[i] = snr_d[i-1]; - fsnr = fsnr + snr_d[i]; - } - snr_d[0] = snr_val; - fsnr = fsnr >> 3; - if (fsnr < 316) - ret = high; - else if (fsnr < 31600) - ret = ok_plus; - else if (fsnr < 158000) - ret = ok_minus; - else if (fsnr < 700000) - ret = low; - else - ret = very_low; - return ret; -} - -void atvdemod_monitor_serice(void) -{ - enum amlatvdemod_snr_level_e snr_level; - unsigned int vagc_bw_typ, vagc_bw_fast, vpll_kptrack, vpll_kitrack; - unsigned int agc_register, vfmat_reg, agc_pll_kptrack, agc_pll_kitrack; - /*1.get current snr*/ - snr_level = aml_atvdemod_get_snr_level(); - /*2.*/ - if (snr_level > very_low) { - vagc_bw_typ = 0x1818; - vagc_bw_fast = (snr_level == low) ? 0x18:0x10; - vpll_kptrack = 0x05; - vpll_kitrack = 0x0c; - agc_pll_kptrack = 0x6; - agc_pll_kitrack = 0xc; - } else { - vagc_bw_typ = 0x6f6f; - vagc_bw_fast = 0x6f; - vpll_kptrack = 0x06; - vpll_kitrack = 0x0e; - agc_pll_kptrack = 0x8; - agc_pll_kitrack = 0xf; - } - atv_dmd_wr_word(APB_BLOCK_ADDR_VDAGC, 0x3c, vagc_bw_typ); - atv_dmd_wr_byte(APB_BLOCK_ADDR_VDAGC, 0x3e, vagc_bw_fast); - atv_dmd_wr_byte(APB_BLOCK_ADDR_CARR_RCVY, 0x23, vpll_kptrack); - atv_dmd_wr_byte(APB_BLOCK_ADDR_CARR_RCVY, 0x24, vpll_kitrack); - atv_dmd_wr_byte(APB_BLOCK_ADDR_VDAGC, 0x0c, - ((atv_dmd_rd_byte(APB_BLOCK_ADDR_VDAGC, 0x0c) & 0xf0)| - agc_pll_kptrack)); - atv_dmd_wr_byte(APB_BLOCK_ADDR_VDAGC, 0x0d, - ((atv_dmd_rd_byte(APB_BLOCK_ADDR_VDAGC, 0x0d) & 0xf0)| - agc_pll_kitrack)); - /*3.*/ - agc_register = atv_dmd_rd_long(APB_BLOCK_ADDR_VDAGC, 0x28); - if (snr_level < low) { - agc_register = ((agc_register&0xff80fe03) | (25 << 16) | - (15 << 2)); - atv_dmd_wr_long(APB_BLOCK_ADDR_VDAGC, 0x28, agc_register); - } else if (snr_level > low) { - agc_register = ((agc_register&0xff80fe03) | (38 << 16) | - (30 << 2)); - atv_dmd_wr_long(APB_BLOCK_ADDR_VDAGC, 0x28, agc_register); - } - /*4.*/ - if (snr_level < ok_minus) - atv_dmd_wr_byte(APB_BLOCK_ADDR_VDAGC, 0x47, - (atv_dmd_rd_byte(APB_BLOCK_ADDR_VDAGC, 0x47) & 0x7f)); - else - atv_dmd_wr_byte(APB_BLOCK_ADDR_VDAGC, 0x47, - (atv_dmd_rd_byte(APB_BLOCK_ADDR_VDAGC, 0x47) | 0x80)); - /*5.vformat*/ - if (snr_level < ok_minus) { - if (atv_dmd_rd_byte(APB_BLOCK_ADDR_VFORMAT, 0xe) != 0xf) - atv_dmd_wr_byte(APB_BLOCK_ADDR_VFORMAT, 0xe, 0xf); - } else if (snr_level > ok_minus) { - vfmat_reg = atv_dmd_rd_word(APB_BLOCK_ADDR_VFORMAT, 0x16); - if ((vfmat_reg << 4) < 0xf000) { - if (atv_dmd_rd_byte(APB_BLOCK_ADDR_VFORMAT, 0xe) == - 0x0f) - atv_dmd_wr_byte(APB_BLOCK_ADDR_VFORMAT, 0xe, - 0x6); - else - atv_dmd_wr_byte(APB_BLOCK_ADDR_VFORMAT, 0xe, - 0x6); - } - } else { - if (atv_dmd_rd_byte(APB_BLOCK_ADDR_VFORMAT, 0xe) == 0x0f) - atv_dmd_wr_byte(APB_BLOCK_ADDR_VFORMAT, 0xe, 0xe); - else - atv_dmd_wr_byte(APB_BLOCK_ADDR_VFORMAT, 0xe, 0xe); - } -} - -static int atvdemod_get_snr(struct dvb_frontend *fe) -{ - unsigned int snr_val = 0; - int ret = 0; - - snr_val = atv_dmd_rd_long(APB_BLOCK_ADDR_VDAGC, 0x50) >> 8; - /* snr_val:900000~0xffffff,ret:5~15 */ - if (snr_val > 900000) - ret = 15 - (snr_val - 900000)*10/(0xffffff - 900000); - /* snr_val:158000~900000,ret:15~30 */ - else if (snr_val > 158000) - ret = 30 - (snr_val - 158000)*15/(900000 - 158000); - /* snr_val:31600~158000,ret:30~50 */ - else if (snr_val > 31600) - ret = 50 - (snr_val - 31600)*20/(158000 - 31600); - /* snr_val:316~31600,ret:50~80 */ - else if (snr_val > 316) - ret = 80 - (snr_val - 316)*30/(31600 - 316); - /* snr_val:0~316,ret:80~100 */ - else - ret = 100 - (316 - snr_val)*20/316; - return ret; -} - -void atvdemod_det_snr_serice(void) -{ - snr_val = atvdemod_get_snr(NULL); -} - -void atvdemod_timer_handler(unsigned long arg) -{ - if (atvdemod_timer_en == 0) - return; - atvdemod_timer.expires = jiffies + ATVDEMOD_INTERVAL*10;/*100ms timer*/ - add_timer(&atvdemod_timer); - if (atvdemod_afc_en) - atvdemod_afc_tune(); - if (atvdemod_monitor_en) - atvdemod_monitor_serice(); - if (audio_det_en) - aml_atvdemod_overmodule_det(); - if (atvdemod_det_snr_en) - atvdemod_det_snr_serice(); -} - -int atvdemod_clk_init(void) -{ - /* clocks_set_hdtv (); */ - /* 1.set system clock */ -#if 0 /* now set pll in tvafe_general.c */ - if (is_meson_txl_cpu()) { - amlatvdemod_hiu_reg_write(HHI_VDAC_CNTL0, 0x6e0201); - amlatvdemod_hiu_reg_write(HHI_VDAC_CNTL1, 0x8); - /* for TXL(T962) */ - pr_err("%s in TXL\n", __func__); - - /* W_HIU_REG(HHI_ADC_PLL_CNTL, 0x30c54260); */ - #if 0 - W_HIU_REG(HHI_ADC_PLL_CNTL, 0x30f14250); - W_HIU_REG(HHI_ADC_PLL_CNTL1, 0x22000442); - W_HIU_REG(HHI_ADC_PLL_CNTL2, 0x5ba00380); - W_HIU_REG(HHI_ADC_PLL_CNTL3, 0xac6a2114); - W_HIU_REG(HHI_ADC_PLL_CNTL4, 0x02953004); - W_HIU_REG(HHI_ADC_PLL_CNTL5, 0x00030a00); - W_HIU_REG(HHI_ADC_PLL_CNTL6, 0x00005000); - W_HIU_REG(HHI_ADC_PLL_CNTL3, 0x2c6a2114); - #else /* get from feijun 2015/07/19 */ - W_HIU_REG(HHI_ADC_PLL_CNTL3, 0x4a6a2110); - W_HIU_REG(HHI_ADC_PLL_CNTL, 0x30f14250); - W_HIU_REG(HHI_ADC_PLL_CNTL1, 0x22000442); - /*0x5ba00380 from pll;0x5ba00384 clk - *form crystal - */ - W_HIU_REG(HHI_ADC_PLL_CNTL2, 0x5ba00384); - W_HIU_REG(HHI_ADC_PLL_CNTL3, 0x4a6a2110); - W_HIU_REG(HHI_ADC_PLL_CNTL4, 0x02913004); - W_HIU_REG(HHI_ADC_PLL_CNTL5, 0x00034a00); - W_HIU_REG(HHI_ADC_PLL_CNTL6, 0x00005000); - W_HIU_REG(HHI_ADC_PLL_CNTL3, 0xca6a2110); - W_HIU_REG(HHI_ADC_PLL_CNTL3, 0x4a6a2110); - #endif - W_HIU_REG(HHI_DADC_CNTL, 0x00102038); - W_HIU_REG(HHI_DADC_CNTL2, 0x00000406); - W_HIU_REG(HHI_DADC_CNTL3, 0x00082183); - - } else { - W_HIU_REG(HHI_ADC_PLL_CNTL3, 0xca2a2110); - W_HIU_REG(HHI_ADC_PLL_CNTL4, 0x2933800); - W_HIU_REG(HHI_ADC_PLL_CNTL, 0xe0644220); - W_HIU_REG(HHI_ADC_PLL_CNTL2, 0x34e0bf84); - W_HIU_REG(HHI_ADC_PLL_CNTL3, 0x4a2a2110); - - W_HIU_REG(HHI_ATV_DMD_SYS_CLK_CNTL, 0x80); - /* TVFE reset */ - W_HIU_BIT(RESET1_REGISTER, 1, 7, 1); - } -#endif - W_HIU_REG(HHI_ATV_DMD_SYS_CLK_CNTL, 0x80); - - /* read_version_register(); */ - - /*2.set atv demod top page control register*/ - atv_dmd_input_clk_32m(); - atv_dmd_wr_long(APB_BLOCK_ADDR_TOP, ATV_DMD_TOP_CTRL, 0x1037); - atv_dmd_wr_long(APB_BLOCK_ADDR_TOP, (ATV_DMD_TOP_CTRL1 << 2), 0x1f); - - /*3.configure atv demod*/ - check_communication_interface(); - power_on_receiver(); - pr_err("%s done\n", __func__); - - return 0; -} - -int atvdemod_init(void) -{ - /* unsigned long data32; */ - if (atvdemod_timer_en == 1) { - if (timer_init_flag == 1) { - del_timer_sync(&atvdemod_timer); - timer_init_flag = 0; - } - } - - /* 1.set system clock when atv enter*/ - - configure_receiver(broad_std, if_freq, if_inv, gde_curve, sound_format); - atv_dmd_misc(); - /*4.software reset*/ - atv_dmd_soft_reset(); - atv_dmd_soft_reset(); - atv_dmd_soft_reset(); - atv_dmd_soft_reset(); - - /* ????? - *while (!all_lock) { - * data32 = atv_dmd_rd_long(APB_BLOCK_ADDR_VDAGC,0x13<<2); - * if ((data32 & 0x1c) == 0x0) { - * all_lock = 1; - * } - * delay_us(400); - *} - */ - #if 1/* temp mark */ - if (atvdemod_timer_en == 1) { - /*atvdemod timer handler*/ - init_timer(&atvdemod_timer); - /* atvdemod_timer.data = (ulong) devp; */ - atvdemod_timer.function = atvdemod_timer_handler; - /* after 3s enable demod auto detect */ - atvdemod_timer.expires = jiffies + ATVDEMOD_INTERVAL*300; - add_timer(&atvdemod_timer); - mix1_freq = atv_dmd_rd_byte(APB_BLOCK_ADDR_MIXER_1, 0x0); - timer_init_flag = 1; - } - #endif - pr_info("%s done\n", __func__); - return 0; -} -void atvdemod_uninit(void) -{ - /* del the timer */ - if (atvdemod_timer_en == 1) { - if (timer_init_flag == 1) { - del_timer_sync(&atvdemod_timer); - timer_init_flag = 0; - } - } -} - -void atv_dmd_set_std(void) -{ - v4l2_std_id ptstd = amlatvdemod_devp->parm.std; - /* set broad standard of tuner*/ - if ((ptstd & V4L2_COLOR_STD_PAL) && ((ptstd & V4L2_STD_B) || - (ptstd & V4L2_STD_G))) { - amlatvdemod_devp->fre_offset = 2250000; - freq_hz_cvrt = AML_ATV_DEMOD_FREQ_50HZ_VERT; - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG; - if_freq = 3250000; - gde_curve = 2; - } else if ((ptstd & V4L2_COLOR_STD_PAL) && (ptstd & V4L2_STD_DK)) { - amlatvdemod_devp->fre_offset = 2250000; - freq_hz_cvrt = AML_ATV_DEMOD_FREQ_50HZ_VERT; - if_freq = 3250000; - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK; - gde_curve = 3; - } else if ((ptstd & V4L2_COLOR_STD_PAL) && (ptstd & V4L2_STD_PAL_M)) { - amlatvdemod_devp->fre_offset = 2250000; - freq_hz_cvrt = AML_ATV_DEMOD_FREQ_60HZ_VERT; - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M; - if_freq = 4250000; - gde_curve = 0; - } else if ((ptstd & V4L2_COLOR_STD_NTSC) && (ptstd & V4L2_STD_NTSC_M)) { - amlatvdemod_devp->fre_offset = 1750000; - freq_hz_cvrt = AML_ATV_DEMOD_FREQ_60HZ_VERT; - if_freq = 4250000; - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC; - gde_curve = 0; - } else if ((ptstd & V4L2_COLOR_STD_NTSC) && (ptstd & V4L2_STD_DK)) { - amlatvdemod_devp->fre_offset = 1750000; - freq_hz_cvrt = AML_ATV_DEMOD_FREQ_60HZ_VERT; - if_freq = 4250000; - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_DK; - gde_curve = 0; - } else if ((ptstd & V4L2_COLOR_STD_NTSC) && (ptstd & V4L2_STD_BG)) { - amlatvdemod_devp->fre_offset = 1750000; - freq_hz_cvrt = AML_ATV_DEMOD_FREQ_60HZ_VERT; - if_freq = 4250000; - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_BG; - gde_curve = 0; - } else if ((ptstd & V4L2_COLOR_STD_NTSC) && (ptstd & V4L2_STD_PAL_I)) { - amlatvdemod_devp->fre_offset = 1750000; - freq_hz_cvrt = AML_ATV_DEMOD_FREQ_60HZ_VERT; - if_freq = 4250000; - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_I; - gde_curve = 0; - } else if ((ptstd & V4L2_COLOR_STD_NTSC) && - (ptstd & V4L2_STD_NTSC_M_JP)) { - amlatvdemod_devp->fre_offset = 1750000; - freq_hz_cvrt = AML_ATV_DEMOD_FREQ_50HZ_VERT; - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_J; - if_freq = 4250000; - gde_curve = 0; - } else if ((ptstd & V4L2_COLOR_STD_PAL) && (ptstd & V4L2_STD_PAL_I)) { - amlatvdemod_devp->fre_offset = 2750000; - freq_hz_cvrt = AML_ATV_DEMOD_FREQ_50HZ_VERT; - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I; - if_freq = 3250000; - gde_curve = 4; - } else if (ptstd & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)) { - amlatvdemod_devp->fre_offset = 2750000; - freq_hz_cvrt = AML_ATV_DEMOD_FREQ_50HZ_VERT; - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_L; - gde_curve = 4; - } - if (amlatvdemod_devp->parm.tuner_id == AM_TUNER_R840) { - if_freq = amlatvdemod_devp->parm.if_freq; - if_inv = amlatvdemod_devp->parm.if_inv; - } else if (amlatvdemod_devp->parm.tuner_id == AM_TUNER_MXL661) { - if_freq = amlatvdemod_devp->parm.if_freq; - if_inv = amlatvdemod_devp->parm.if_inv; - } else if (amlatvdemod_devp->parm.tuner_id == AM_TUNER_SI2151) { - if_freq = amlatvdemod_devp->parm.if_freq; - if_inv = amlatvdemod_devp->parm.if_inv; - } - pr_info - ("[atvdemod..]%s: broad_std %d,freq_hz_cvrt:0x%x,fre_offset:%d.\n", - __func__, broad_std, freq_hz_cvrt, amlatvdemod_devp->fre_offset); - if (atvdemod_init()) - pr_info("[atvdemod..]%s: atv restart error.\n", __func__); -} - -int aml_audiomode_autodet(struct dvb_frontend *fe) -{ - unsigned long carrier_power = 0; - unsigned long carrier_power_max = 0; - unsigned long carrier_power_average_max = 0; - unsigned long carrier_power_average[4] = {0}; - unsigned long reg_addr = 0x03, temp_data; - int carrier_lock_count = 0; - int lock = 0; - int broad_std_final = 0; - int num = 0, i = 0, final_id = 0; - int delay_ms = 10, delay_ms_default = 10; - int cur_std = ID_PAL_DK; - struct dtv_frontend_properties - *p = fe != NULL ? &fe->dtv_property_cache:NULL; -#if 0 - temp_data = atv_dmd_rd_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02); - temp_data = temp_data | 0x80;/* 0x40 */ - atv_dmd_wr_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data); -#endif - - switch (broad_std) { - case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK: - case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I: - case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG: - case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M: - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M; - break; - case AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_DK: - case AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_I: - case AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_BG: - case AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_M: - case AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC: - - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_M; - atvdemod_init(); - temp_data = atv_dmd_rd_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02); - temp_data = temp_data & (~0x80); /* 0xbf; */ - atv_dmd_wr_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data); - /* pr_err("%s, SECAM ,audio set SECAM_L\n", __func__); */ - return broad_std; - - case AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_L: - case AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_DK2: - case AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_DK3: - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_L; - atvdemod_init(); - temp_data = atv_dmd_rd_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02); - - temp_data = temp_data & (~0x80); /* 0xbf; */ - - atv_dmd_wr_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data); - /* pr_err("%s, SECAM ,audio set SECAM_L\n", __func__); */ - return broad_std; - default: - pr_err("unsupport broadcast_standard!!!\n"); - temp_data = atv_dmd_rd_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02); - temp_data = temp_data & (~0x80); /* 0xbf; */ - atv_dmd_wr_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data); - return broad_std; - } - /* ----------------read carrier_power--------------------- */ - /* SIF_STG_2[0x09],address 0x03 */ - while (1) { - if (num >= 4) { - temp_data = - atv_dmd_rd_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02); - temp_data = temp_data & (~0x80); - atv_dmd_wr_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02, - temp_data); - carrier_power_max = carrier_power_average[0]; - for (i = 0; i < ID_MAX; i++) { - if (carrier_power_max - < carrier_power_average[i]) { - carrier_power_max = - carrier_power_average[i]; - final_id = i; - } - } - switch (final_id) { - case ID_PAL_I: - broad_std_final = - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I; - break; - case ID_PAL_BG: - broad_std_final = - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG; - break; - case ID_PAL_M: - broad_std_final = - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M; - break; - case ID_PAL_DK: - broad_std_final = - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK; - break; - } - carrier_power_average_max = carrier_power_max; - broad_std = broad_std_final; - pr_err("%s:broad_std:%d,carrier_power_average_max:%lu\n", - __func__, broad_std, carrier_power_average_max); - if (carrier_power_average_max < 150) - pr_err("%s,carrier too low error\n", __func__); - if (broad_std == AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M) { - /*the max except palm*/ - carrier_power_average[final_id] = 0; - final_id = 0; - carrier_power_max = carrier_power_average[0]; - for (i = 0; i < ID_MAX; i++) { - if (carrier_power_max - < carrier_power_average[i]) { - carrier_power_max = - carrier_power_average[i]; - final_id = i; - } - } - switch (final_id) { - case ID_PAL_I: - broad_std_except_pal_m = - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I; - break; - case ID_PAL_BG: - broad_std_except_pal_m = - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG; - break; - case ID_PAL_DK: - broad_std_except_pal_m = - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK; - break; - } - } - if (p != NULL) { - p->analog.std = V4L2_COLOR_STD_PAL; - switch (broad_std) { - case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK: - p->analog.std |= V4L2_STD_PAL_DK; - p->analog.audmode = V4L2_STD_PAL_DK; - break; - case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I: - p->analog.std |= V4L2_STD_PAL_I; - p->analog.audmode = V4L2_STD_PAL_I; - break; - case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG: - p->analog.std |= V4L2_STD_PAL_BG; - p->analog.audmode = V4L2_STD_PAL_BG; - break; - case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M: - p->analog.std |= V4L2_STD_PAL_M; - p->analog.audmode = V4L2_STD_PAL_M; - break; - default: - p->analog.std |= V4L2_STD_PAL_DK; - p->analog.audmode = V4L2_STD_PAL_DK; - } - p->frequency += 1; - fe->ops.set_frontend(fe); - } - return broad_std; - } - switch (broad_std) { - case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK: - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I; - cur_std = ID_PAL_I; - if (p != NULL) { - p->analog.std = - V4L2_COLOR_STD_PAL | V4L2_STD_PAL_I; - p->frequency += 1; - p->analog.audmode = V4L2_STD_PAL_I; - } - delay_ms = delay_ms_default; - break; - case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I: - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG; - cur_std = ID_PAL_BG; - if (p != NULL) { - p->analog.std = - V4L2_COLOR_STD_PAL | V4L2_STD_PAL_BG; - p->frequency += 1; - p->analog.audmode = V4L2_STD_PAL_BG; - } - delay_ms = delay_ms_default; - break; - case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG: - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M; - cur_std = ID_PAL_M; - if (p != NULL) { - p->analog.std = - V4L2_COLOR_STD_PAL | V4L2_STD_PAL_M; - p->frequency += 1; - p->analog.audmode = V4L2_STD_PAL_M; - } - delay_ms = delay_ms_default; - break; - case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M: - broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK; - cur_std = ID_PAL_DK; - if (p != NULL) { - p->analog.std = - V4L2_COLOR_STD_PAL | V4L2_STD_PAL_DK; - p->frequency += 1; - p->analog.audmode = V4L2_STD_PAL_DK; - } - delay_ms = delay_ms_default; - break; - - default: - pr_err("unsupport broadcast_standard!!!\n"); - break; - } - if (p != NULL) - fe->ops.set_frontend(fe); - /* atvdemod_init(); //set_frontend has already been called it */ - - /* enable audio detect function */ - temp_data = atv_dmd_rd_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02); - temp_data = temp_data | 0x80;/* 0x40 */ - atv_dmd_wr_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data); - - usleep_range(delay_ms*1000, delay_ms*1000+100); - - carrier_lock_count = 0; - i = 4; - while (i--) { - retrieve_vpll_carrier_lock(&lock); - if (lock == 0) - break; - carrier_lock_count++; - if (carrier_lock_count >= 20) { - pr_err("%s step2, retrieve_vpll_carrier_lock failed\n", - __func__); - /* return broad_std; */ - } - usleep_range(6000, 9000); - } - /* ----------------read carrier_power--------------------- */ - for (i = 0; i < 100; i++) { - carrier_power = - atv_dmd_rd_reg(APB_BLOCK_ADDR_SIF_STG_2, - reg_addr); - carrier_power_max += carrier_power; - } - carrier_power = carrier_power_max/i; - carrier_power_max = 0; - pr_err("[amlatvdemod.. %d,std:%d ]%s: atvdemo audio carrier power report:%lu. @@@@@@@@@@\n", - num, broad_std, __func__, carrier_power); - carrier_power_average[cur_std] += carrier_power; - num++; - } - - return broad_std; -} - -void aml_audio_valume_gain_set(unsigned int audio_gain) -{ - unsigned long audio_gain_data, temp_data; - - if (audio_gain > 0xfff) { - pr_err("Error: atv in gain max 7.998, min 0.002! gain = value/512\n"); - pr_err("value (0~0xfff)\n"); - return; - } - audio_gain_data = audio_gain & 0xfff; - temp_data = atv_dmd_rd_word(APB_BLOCK_ADDR_MONO_PROC, 0x52); - temp_data = (temp_data & 0xf000) | audio_gain_data; - atv_dmd_wr_word(APB_BLOCK_ADDR_MONO_PROC, 0x52, temp_data); -} - -unsigned int aml_audio_valume_gain_get(void) -{ - unsigned long audio_gain_data; - - audio_gain_data = atv_dmd_rd_word(APB_BLOCK_ADDR_MONO_PROC, 0x52); - audio_gain_data = audio_gain_data & 0xfff; - return audio_gain_data; -} - -void aml_atvdemod_overmodule_det(void) -{ - unsigned long temp_data, temp_data2;/* , temp_data3 , temp_data4; */ - unsigned long counter_report; - int carrier_lock_count = 0; - int vlock = 0; - - switch (audio_det_mode) { - case AUDIO_AUTO_DETECT: - aml_audiomode_autodet(NULL); - return; -#if 0 - while (1) { - retrieve_vpll_carrier_lock(&vlock); - if (vlock) - break; - carrier_lock_count++; - if (carrier_lock_count >= 1000) - return; - /* ------------whether need timer delays between the detect lock---- */ - } - /* -----------------enable auto_adjust_en------------- */ - temp_data = atv_dmd_rd_word(APB_BLOCK_ADDR_SIF_STG_2, 0x02); - temp_data = temp_data | 0x100; - /* set the bit 9 of the temp_data to 1 */ - atv_dmd_wr_word(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data); - /* -----------------enable auto_adjust_en end----------------- */ - /* -----------------begain to set ov_cnt_en enable------------- */ - temp_data2 = atv_dmd_rd_word(APB_BLOCK_ADDR_SIF_STG_2, 0x02); - temp_data2 = temp_data2 | 0x80; - /* set the bit 8 of the temp_data to 1 */ - atv_dmd_wr_word(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data2); - /* ------------------set ov_cnt_en enable end---------------- */ - udelay(1000);/* timer delay needed , */ - /* ------------------------------------------------------------ */ - /* -----------------disable auto_adjust_en------------- */ - temp_data3 = atv_dmd_rd_word(APB_BLOCK_ADDR_SIF_STG_2, 0x02); - temp_data3 = temp_data3 & 0xfeff; - /* set the bit 9 of the temp_data to 0 */ - atv_dmd_wr_word(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data3); - /* -----------------disable auto_adjust_en end------------ */ - /* -----------------begain to set ov_cnt_en disable------------- */ - temp_data4 = atv_dmd_rd_word(APB_BLOCK_ADDR_SIF_STG_2, 0x02); - temp_data4 = temp_data4 & 0xff7f; - /* set the bit 8 of the temp_data to 0 */ - atv_dmd_wr_word(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data4); - break; - /* ------------------set ov_cnt_en disable end------ */ -#endif - case AUDIO_MANUAL_DETECT: - while (1) { - retrieve_vpll_carrier_lock(&vlock); - if (vlock) - break; - carrier_lock_count++; - if (carrier_lock_count >= 1000) - return; - } - - /* -----------------begain to set ov_cnt_en enable---- */ - temp_data = atv_dmd_rd_word(APB_BLOCK_ADDR_SIF_STG_2, 0x02); - temp_data = temp_data | 0x80; - /* set the bit 8 of the temp_data to 1 */ - atv_dmd_wr_word(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data); - /* ------------------set ov_cnt_en enable end--------------- */ - /* -----------------disable auto_adjust_en------------- */ - temp_data2 = atv_dmd_rd_word(APB_BLOCK_ADDR_SIF_STG_2, 0x02); - temp_data2 = temp_data2 & 0xfeff; - /* set the bit 9 of the temp_data to 0 */ - atv_dmd_wr_word(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data2); - /* -----------------disable auto_adjust_en end------------ */ - udelay(1000);/* timer delay needed , */ - /* ------------------------------------------------------- */ - counter_report = - atv_dmd_rd_word(APB_BLOCK_ADDR_SIF_STG_2, 0x04); - - while (counter_report > over_threshold) { - unsigned long shift_gain, shift_gain_report; - - temp_data2 = atv_dmd_rd_byte( - APB_BLOCK_ADDR_SIF_STG_2, 0x00); - shift_gain = temp_data2 & 0x07; - shift_gain--; - temp_data2 = (temp_data2 & 0xf8) | shift_gain; - atv_dmd_wr_byte(APB_BLOCK_ADDR_SIF_STG_2, 0x00, - temp_data2); - shift_gain_report = ( - (atv_dmd_rd_long(APB_BLOCK_ADDR_SIF_STG_2, 0x04) - & 0x00070000) >> 16); - if (shift_gain_report != shift_gain) - pr_info("[atvdemo...]:set shift_gain error\n"); - /* ------------------timer delay needed- */ - udelay(1000);/* timer delay needed , */ - /* ----------------------- */ - counter_report = - atv_dmd_rd_word(APB_BLOCK_ADDR_SIF_STG_2, 0x04); - } - break; - default: - pr_info("invalid over_module_det mode!!!\n"); - break; - } -} - -void aml_fix_PWM_adjust(int enable) -{ - unsigned long temp_data; - /* - *temp_data = atv_dmd_rd_byte(APB_BLOCK_ADDR_AGC_PWM, 0x08); - *temp_data = temp_data | 0x01; - *atv_dmd_wr_byte(APB_BLOCK_ADDR_AGC_PWM, 0x08, temp_data); - */ - temp_data = atv_dmd_rd_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02); - if (enable) - temp_data = temp_data & ~((0x3)<<8); - else - temp_data = temp_data & ~((0x1)<<9); - - atv_dmd_wr_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data); - if (enable) { - temp_data = temp_data | ((0x3)<<8); - atv_dmd_wr_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data); - } -} - -void aml_audio_overmodulation(int enable) -{ - static int ov_flag; - unsigned long tmp_v; - unsigned long tmp_v1; - u32 Broadcast_Standard = broad_std; - - if (enable && Broadcast_Standard == - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK) { - tmp_v = atv_dmd_rd_long(APB_BLOCK_ADDR_SIF_STG_2, 0x28); - tmp_v = tmp_v&0xffff; - if (tmp_v >= 0x10 && ov_flag == 0) { - tmp_v1 = - atv_dmd_rd_long(APB_BLOCK_ADDR_SIF_STG_2, 0); - tmp_v1 = (tmp_v1&0xffffff)|(1<<24); - atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0, tmp_v1); - atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, - 0x14, 0x8000015); - atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, - 0x1c, 0x0f000); - } else if (tmp_v >= 0x2500 && ov_flag == 0) { - tmp_v1 = atv_dmd_rd_long(APB_BLOCK_ADDR_SIF_STG_2, 0); - tmp_v1 = (tmp_v1&0xffffff)|(1<<24); - atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0, tmp_v1); - atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, - 0x14, 0xf400015); - atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, - 0x18, 0xc000); - atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, - 0x1c, 0x0f000); - ov_flag = 1; - } else if (tmp_v <= 0x10 && ov_flag == 1) { - tmp_v1 = atv_dmd_rd_long(APB_BLOCK_ADDR_SIF_STG_2, 0); - tmp_v1 = (tmp_v1&0xffffff)|(0<<24); - atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0, tmp_v1); - atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, - 0x14, 0xf400000); - atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, - 0x18, 0xc000); - atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, - 0x1c, 0x1f000); - ov_flag = 0; - } - } -} - diff --git a/drivers/stream_input/tv_frontend/atv_demod/atvdemod_func.h b/drivers/stream_input/tv_frontend/atv_demod/atvdemod_func.h deleted file mode 100644 index 8072392..0000000 --- a/drivers/stream_input/tv_frontend/atv_demod/atvdemod_func.h +++ b/dev/null @@ -1,323 +0,0 @@ -/* - * ATVDEMOD Device Driver - * - * Author: dezhi kong - * - * - * Copyright (C) 2014 Amlogic Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ATVDEMOD_FUN_H -#define __ATVDEMOD_FUN_H - -/*#include "../aml_fe.h"*/ -#include -#include "../aml_fe.h" -#include - -/*#define TVFE_APB_BASE_ADDR 0xd0046000*/ -#define ATV_DMD_APB_BASE_ADDR 0xc8008000 -#define ATV_DMD_APB_BASE_ADDR_GXTVBB 0xc8840000 - -#define HHI_ATV_DMD_SYS_CLK_CNTL 0x10f3 - -extern int atvdemod_debug_en; -extern struct amlatvdemod_device_s *amlatvdemod_devp; -extern unsigned int reg_23cf; /* IIR filter */ -extern int broad_std_except_pal_m; -#undef pr_info -#define pr_info(args...)\ - do {\ - if (atvdemod_debug_en)\ - printk(args);\ - } while (0) -#undef pr_dbg -#define pr_dbg(a...) \ - do {\ - if (1)\ - printk(a);\ - } while (0) - -#define ATVDEMOD_INTERVAL (HZ/100) /*10ms, #define HZ 100*/ - -extern int amlatvdemod_reg_read(unsigned int reg, unsigned int *val); -extern int amlatvdemod_reg_write(unsigned int reg, unsigned int val); -extern int amlatvdemod_hiu_reg_read(unsigned int reg, unsigned int *val); -extern int amlatvdemod_hiu_reg_write(unsigned int reg, unsigned int val); - -static inline uint32_t R_ATVDEMOD_REG(uint32_t reg) -{ - unsigned int val; - - amlatvdemod_reg_read(reg, &val); - return val; -} - -static inline void W_ATVDEMOD_REG(uint32_t reg, - const uint32_t val) -{ - amlatvdemod_reg_write(reg, val); -} - -static inline void W_ATVDEMOD_BIT(uint32_t reg, - const uint32_t value, - const uint32_t start, - const uint32_t len) -{ - W_ATVDEMOD_REG(reg, ((R_ATVDEMOD_REG(reg) & - ~(((1L << (len)) - 1) << (start))) | - (((value) & ((1L << (len)) - 1)) << (start)))); -} - -static inline uint32_t R_ATVDEMOD_BIT(uint32_t reg, - const uint32_t start, - const uint32_t len) -{ - uint32_t val; - - val = ((R_ATVDEMOD_REG(reg) >> (start)) & ((1L << (len)) - 1)); - - return val; -} - -static inline uint32_t R_HIU_REG(uint32_t reg) -{ - unsigned int val; - - amlatvdemod_hiu_reg_read(reg, &val); - return val; -} - -static inline void W_HIU_REG(uint32_t reg, - const uint32_t val) -{ - amlatvdemod_hiu_reg_write(reg, val); -} - -static inline void W_HIU_BIT(uint32_t reg, - const uint32_t value, - const uint32_t start, - const uint32_t len) -{ - W_HIU_REG(reg, ((R_HIU_REG(reg) & - ~(((1L << (len)) - 1) << (start))) | - (((value) & ((1L << (len)) - 1)) << (start)))); -} - -static inline uint32_t R_HIU_BIT(uint32_t reg, - const uint32_t start, - const uint32_t len) -{ - uint32_t val; - - val = ((R_HIU_REG(reg) >> (start)) & ((1L << (len)) - 1)); - - return val; -} - -enum broadcast_standard_e { - ATVDEMOD_STD_NTSC = 0, - ATVDEMOD_STD_NTSC_J, - ATVDEMOD_STD_PAL_M, - ATVDEMOD_STD_PAL_BG, - ATVDEMOD_STD_DTV, - ATVDEMOD_STD_SECAM_DK2, - ATVDEMOD_STD_SECAM_DK3, - ATVDEMOD_STD_PAL_BG_NICAM, - ATVDEMOD_STD_PAL_DK_CHINA, - ATVDEMOD_STD_SECAM_L, - ATVDEMOD_STD_PAL_I, - ATVDEMOD_STD_PAL_DK1, - ATVDEMOD_STD_MAX, -}; -enum gde_curve_e { - ATVDEMOD_CURVE_M = 0, - ATVDEMOD_CURVE_A, - ATVDEMOD_CURVE_B, - ATVDEMOD_CURVE_CHINA, - ATVDEMOD_CURVE_MAX, -}; -enum sound_format_e { - ATVDEMOD_SOUND_STD_MONO = 0, - ATVDEMOD_SOUND_STD_NICAM, - ATVDEMOD_SOUND_STD_MAX, -}; -extern void atv_dmd_wr_reg(unsigned char block, unsigned char reg, - unsigned long data); -extern unsigned long atv_dmd_rd_reg(unsigned char block, unsigned char reg); -extern unsigned long atv_dmd_rd_byte(unsigned long block_address, - unsigned long reg_addr); -extern unsigned long atv_dmd_rd_word(unsigned long block_address, - unsigned long reg_addr); -extern unsigned long atv_dmd_rd_long(unsigned long block_address, - unsigned long reg_addr); -extern void atv_dmd_wr_long(unsigned long block_address, - unsigned long reg_addr, - unsigned long data); -extern void atv_dmd_wr_word(unsigned long block_address, - unsigned long reg_addr, - unsigned long data); -extern void atv_dmd_wr_byte(unsigned long block_address, - unsigned long reg_addr, - unsigned long data); -extern void set_audio_gain_val(int val); -extern void set_video_gain_val(int val); -extern void atv_dmd_soft_reset(void); -extern void atv_dmd_input_clk_32m(void); -extern void read_version_register(void); -extern void check_communication_interface(void); -extern void power_on_receiver(void); -extern void atv_dmd_misc(void); -extern void configure_receiver(int Broadcast_Standard, - unsigned int Tuner_IF_Frequency, - int Tuner_Input_IF_inverted, int GDE_Curve, - int sound_format); -extern int atvdemod_clk_init(void); -extern int atvdemod_init(void); -extern void atvdemod_uninit(void); -extern void atv_dmd_set_std(void); -extern void retrieve_vpll_carrier_lock(int *lock); -extern void retrieve_video_lock(int *lock); -extern int retrieve_vpll_carrier_afc(void); - -extern int get_atvdemod_snr_val(void); -extern int aml_atvdemod_get_snr(struct dvb_frontend *fe); - -/*atv demod block address*/ -/*address interval is 4, because it's 32bit interface, - * but the address is in byte - */ -#define ATV_DMD_TOP_CTRL 0x0 -#define ATV_DMD_TOP_CTRL1 0x4 -#define ATV_DMD_RST_CTRL 0x8 - -#define APB_BLOCK_ADDR_SYSTEM_MGT 0x0 -#define APB_BLOCK_ADDR_AA_LP_NOTCH 0x1 -#define APB_BLOCK_ADDR_MIXER_1 0x2 -#define APB_BLOCK_ADDR_MIXER_3 0x3 -#define APB_BLOCK_ADDR_ADC_SE 0x4 -#define APB_BLOCK_ADDR_PWR_ANL 0x5 -#define APB_BLOCK_ADDR_CARR_RCVY 0x6 -#define APB_BLOCK_ADDR_FE_DROOP_MDF 0x7 -#define APB_BLOCK_ADDR_SIF_IC_STD 0x8 -#define APB_BLOCK_ADDR_SIF_STG_2 0x9 -#define APB_BLOCK_ADDR_SIF_STG_3 0xa -#define APB_BLOCK_ADDR_IC_AGC 0xb -#define APB_BLOCK_ADDR_DAC_UPS 0xc -#define APB_BLOCK_ADDR_GDE_EQUAL 0xd -#define APB_BLOCK_ADDR_VFORMAT 0xe -#define APB_BLOCK_ADDR_VDAGC 0xf -#define APB_BLOCK_ADDR_VERS_REGISTER 0x10 -#define APB_BLOCK_ADDR_INTERPT_MGT 0x11 -#define APB_BLOCK_ADDR_ADC_MGR 0x12 -#define APB_BLOCK_ADDR_GP_VD_FLT 0x13 -#define APB_BLOCK_ADDR_CARR_DMD 0x14 -#define APB_BLOCK_ADDR_SIF_VD_IF 0x15 -#define APB_BLOCK_ADDR_VD_PKING 0x16 -#define APB_BLOCK_ADDR_FE_DR_SMOOTH 0x17 -#define APB_BLOCK_ADDR_AGC_PWM 0x18 -#define APB_BLOCK_ADDR_DAC_UPS_24M 0x19 -#define APB_BLOCK_ADDR_VFORMAT_DP 0x1a -#define APB_BLOCK_ADDR_VD_PKING_DAC 0x1b -#define APB_BLOCK_ADDR_MONO_PROC 0x1c -#define APB_BLOCK_ADDR_TOP 0x1d - -#define SLAVE_BLOCKS_NUMBER 0x1d /*indeed totals 0x1e, adding top*/ - -/*Broadcast_Standard*/ -/* 0: NTSC*/ -/* 1: NTSC-J*/ -/* 2: PAL-M,*/ -/* 3: PAL-BG*/ -/* 4: DTV*/ -/* 5: SECAM- DK2*/ -/* 6: SECAM -DK3*/ -/* 7: PAL-BG, NICAM*/ -/* 8: PAL-DK-CHINA*/ -/* 9: SECAM-L / SECAM-DK3*/ -/* 10: PAL-I*/ -/* 11: PAL-DK1*/ -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC 0 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_J 1 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M 2 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG 3 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_DTV 4 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_DK2 5 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_DK3 6 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG_NICAM 7 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK 8 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_L 9 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I 10 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK1 11 -/* new add @20150813 begin */ -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_DK 12 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_BG 13 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_I 14 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_M 15 -/* new add @20150813 end */ - -/*GDE_Curve*/ -/* 0: CURVE-M*/ -/* 1: CURVE-A*/ -/* 2: CURVE-B*/ -/* 3: CURVE-CHINA*/ -/* 4: BYPASS*/ -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_CURVE_M 0 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_CURVE_A 1 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_CURVE_B 2 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_CURVE_CHINA 3 -#define AML_ATV_DEMOD_VIDEO_MODE_PROP_CURVE_BYPASS 4 - -/*sound format 0: MONO;1:NICAM*/ -#define AML_ATV_DEMOD_SOUND_MODE_PROP_MONO 0 -#define AML_ATV_DEMOD_SOUND_MODE_PROP_NICAM 1 -/** - *freq_hz:hs_freq - *freq_hz_cvrt=hs_freq/0.23841858 - *vs_freq==50,freq_hz=15625;freq_hz_cvrt=0xffff - *vs_freq==60,freq_hz=15734,freq_hz_cvrt=0x101c9 - ** - */ -#define AML_ATV_DEMOD_FREQ_50HZ_VERT 0xffff /*65535*/ -#define AML_ATV_DEMOD_FREQ_60HZ_VERT 0x101c9 /*65993*/ - -#define CARR_AFC_DEFAULT_VAL 0xffff - -enum amlatvdemod_snr_level_e { - very_low = 1, - low, - ok_minus, - ok_plus, - high, -}; - -enum audio_detect_mode { - AUDIO_AUTO_DETECT = 0, - AUDIO_MANUAL_DETECT, -}; - -struct amlatvdemod_device_s { - struct class *clsp; - struct device *dev; - struct analog_parameters parm; - int fre_offset; - struct pinctrl *pin; - const char *pin_name; -}; - -extern void aml_audio_overmodulation(int enable); -extern void amlatvdemod_set_std(int val); -extern struct amlatvdemod_device_s *amlatvdemod_devp; -extern void aml_fix_PWM_adjust(int enable); -extern void aml_audio_valume_gain_set(unsigned int audio_gain); -extern unsigned int aml_audio_valume_gain_get(void); -extern void aml_atvdemod_overmodule_det(void); -extern int aml_audiomode_autodet(struct dvb_frontend *fe); -extern void retrieve_frequency_offset(int *freq_offset); -extern int aml_atvdemod_get_snr_ex(void); - -#endif /* __ATVDEMOD_FUN_H */ diff --git a/drivers/stream_input/tv_frontend/dtv_demod/aml_demod.c b/drivers/stream_input/tv_frontend/dtv_demod/aml_demod.c deleted file mode 100644 index 7ccdfae..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/aml_demod.c +++ b/dev/null @@ -1,725 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/* #include */ -#include -#include - -/* #include */ -#include -#include -#include "demod_func.h" - -#include -#ifdef CONFIG_COMPAT -#include -#endif -/*#include "sdio/sdio_init.h"*/ -#define DRIVER_NAME "aml_demod" -#define MODULE_NAME "aml_demod" -#define DEVICE_NAME "aml_demod" -#define DEVICE_UI_NAME "aml_demod_ui" - -#define pr_dbg(a ...) \ - do { \ - if (1) { \ - printk(a); \ - } \ - } while (0) - - -const char aml_demod_dev_id[] = "aml_demod"; - -/*#ifndef CONFIG_AM_DEMOD_DVBAPI - * static struct aml_demod_i2c demod_i2c; - * static struct aml_demod_sta demod_sta; - * #else - * extern struct aml_demod_i2c demod_i2c; - * extern struct aml_demod_sta demod_sta; - #endif -*/ - -static struct aml_demod_i2c demod_i2c; -static struct aml_demod_sta demod_sta; -static int read_start; - -int sdio_read_ddr(unsigned long sdio_addr, unsigned long byte_count, - unsigned char *data_buf) -{ - return 0; -} - -int sdio_write_ddr(unsigned long sdio_addr, unsigned long byte_count, - unsigned char *data_buf) -{ - return 0; -} - -int read_reg(int addr) -{ - addr = addr + DEMOD_BASE; - return apb_read_reg(addr); -} - -void wait_capture(int cap_cur_addr, int depth_MB, int start) -{ - int readfirst; - int tmp; - int time_out; - int last = 0x90000000; - - time_out = readfirst = 0; - tmp = depth_MB << 20; - while (tmp && (time_out < 1000)) { /*10seconds time out */ - time_out = time_out + 1; - msleep(20); - readfirst = app_apb_read_reg(cap_cur_addr); - if ((last - readfirst) > 0) - tmp = 0; - else - last = readfirst; - /* usleep(1000); */ - /* readsecond= app_apb_read_reg(cap_cur_addr); */ - - /* if((readsecond-start)>tmp) */ -/* tmp=0;*/ -/* if((readsecond-readfirst)<0) // turn around*/ -/* tmp=0;*/ - pr_dbg("First %x = [%08x],[%08x]%x\n", cap_cur_addr, readfirst, - last, (last - readfirst)); -/* printf("Second %x = [%08x]\n",cap_cur_addr, readsecond);*/ - msleep(20); - } - read_start = readfirst + 0x40000000; - pr_dbg("read_start is %x\n", read_start); -} - -int cap_adc_data(struct aml_cap_data *cap) -{ - int tmp; - int tb_depth; - - pr_dbg("capture ADC\n "); - /* printf("set mem_start (you can read in kernel start log - * (memstart is ).(hex) : "); - */ - /* scanf("%x",&tmp);*/ - tmp = 0x94400000; - app_apb_write_reg(0x9d, cap->cap_addr); - app_apb_write_reg(0x9e, cap->cap_addr + cap->cap_size * 0x100000); - /*0x8000000-128m, 0x400000-4m */ - read_start = tmp + 0x40000000; - /*printf("set afifo rate. (hex)(adc_clk/demod_clk)*256+2 : "); // - * (adc_clk/demod_clk)*256+2 - */ - /* scanf("%x",&tmp); */ - cap->cap_afifo = 0x60; - app_apb_write_reg(0x15, 0x18715f2); - app_apb_write_reg(0x15, (app_apb_read_reg(0x15) & 0xfff00fff) | - ((cap->cap_afifo & 0xff) << 12)); /* set afifo */ - app_apb_write_reg(0x9b, 0x1c9); /* capture ADC 10bits */ - app_apb_write_reg(0x7f, 0x00008000); /* enable testbus 0x8000 */ - - tb_depth = cap->cap_size; /*127; */ - tmp = 9; - app_apb_write_reg(0x9b, (app_apb_read_reg(0x9b) & ~0x1f) | tmp); - /* set testbus width */ - - tmp = 0x100000; - app_apb_write_reg(0x9c, tmp); /* by ADC data enable */ - /* printf("Set test mode. (0 is normal ,1 is testmode) : "); //0 */ - /* scanf("%d",&tmp); */ - tmp = 0; - if (tmp == 1) - app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 10)); - /* set test mode; */ - else - app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) & ~(1 << 10)); - /* close test mode; */ - - app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) & ~(1 << 9)); - /* close cap; */ - app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 9)); - /* open cap; */ - - app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 7)); - /* close tb; */ - app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) & ~(1 << 7)); - /* open tb; */ - - app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 5)); - /* close intlv; */ - - app_apb_write_reg(0x303, 0x8); /* open dc_arbit */ - - tmp = 0; - if (tmp) - app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) & ~(1 << 5)); - /* open intlv; */ - - app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) & ~(1 << 8)); - /* go tb; */ - - wait_capture(0x9f, tb_depth, app_apb_read_reg(0x9d)); - - app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 8)); - /* stop tb; */ - app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 7)); - /* close tb; */ - return 0; -} - -static DECLARE_WAIT_QUEUE_HEAD(lock_wq); - -static ssize_t aml_demod_info(struct class *cla, - struct class_attribute *attr, char *buf) -{ - return 0; -} - -static struct class_attribute aml_demod_class_attrs[] = { - __ATTR(info, - 0644, - aml_demod_info, - NULL), - __ATTR_NULL -}; - -static struct class aml_demod_class = { - .name = "aml_demod", - .class_attrs = aml_demod_class_attrs, -}; - -#if 0 - -static irqreturn_t aml_demod_isr(int irq, void *dev_id) -{ - if (demod_sta.dvb_mode == 0) { - /*dvbc_isr(&demod_sta); */ - if (dvbc_isr_islock()) { - pr_dbg("sync4\n"); - /*if (waitqueue_active(&lock_wq)) - *wake_up_interruptible(&lock_wq); - */ - } - } else { - dvbt_isr(&demod_sta); - } - - return IRQ_HANDLED; -} -#endif - -static int aml_demod_open(struct inode *inode, struct file *file) -{ - pr_dbg("Amlogic Demod DVB-T/C Open\n"); - return 0; -} - -static int aml_demod_release(struct inode *inode, struct file *file) -{ - pr_dbg("Amlogic Demod DVB-T/C Release\n"); - return 0; -} - -#if 0 -static int amdemod_islock(void) -{ - struct aml_demod_sts demod_sts; - - if (demod_sta.dvb_mode == 0) { - dvbc_status(&demod_sta, &demod_i2c, &demod_sts); - return demod_sts.ch_sts & 0x1; - } else if (demod_sta.dvb_mode == 1) { - dvbt_status(&demod_sta, &demod_i2c, &demod_sts); - return demod_sts.ch_sts >> 12 & 0x1; - } - return 0; -} -#endif - -void mem_read(struct aml_demod_mem *arg) -{ - int data; - int addr; - - addr = arg->addr; - data = arg->dat; -/* memcpy(mem_buf[addr],data,1);*/ - pr_dbg("[addr %x] data is %x\n", addr, data); -} -static long aml_demod_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - int strength = 0; - struct dvb_frontend *dvbfe; - struct aml_tuner_sys *tuner; - - switch (cmd) { - case AML_DEMOD_GET_RSSI: - pr_dbg("Ioctl Demod GET_RSSI.\n"); - dvbfe = get_si2177_tuner(); - if (dvbfe != NULL) - strength = dvbfe->ops.tuner_ops.get_strength(dvbfe); - pr_dbg("[si2177] strength is %d\n", strength - 256); - if (strength < 0) - strength = 0 - strength; - tuner = (struct aml_tuner_sys *)arg; - tuner->rssi = strength; - break; - - case AML_DEMOD_SET_TUNER: - pr_dbg("Ioctl Demod Set Tuner.\n"); - dvbfe = get_si2177_tuner(); - if (dvbfe != NULL) - dvbfe->ops.tuner_ops.set_tuner(dvbfe, &demod_sta, - &demod_i2c, - (struct aml_tuner_sys *) - arg); - break; - - case AML_DEMOD_SET_SYS: - pr_dbg("Ioctl Demod Set System\n"); - demod_set_sys(&demod_sta, &demod_i2c, - (struct aml_demod_sys *)arg); - break; - - case AML_DEMOD_GET_SYS: - pr_dbg("Ioctl Demod Get System\n"); - - /*demod_get_sys(&demod_i2c, (struct aml_demod_sys *)arg); */ - break; - - case AML_DEMOD_TEST: - pr_dbg("Ioctl Demod Test. It is blank now\n"); - /*demod_msr_clk(13); */ - /*demod_msr_clk(14); */ - /*demod_calc_clk(&demod_sta); */ - break; - - case AML_DEMOD_TURN_ON: - pr_dbg("Ioctl Demod Turn ON.It is blank now\n"); - /*demod_turn_on(&demod_sta, (struct aml_demod_sys *)arg); */ - break; - - case AML_DEMOD_TURN_OFF: - pr_dbg("Ioctl Demod Turn OFF.It is blank now\n"); - /*demod_turn_off(&demod_sta, (struct aml_demod_sys *)arg); */ - break; - - case AML_DEMOD_DVBC_SET_CH: - pr_dbg("Ioctl DVB-C Set Channel.\n"); - dvbc_set_ch(&demod_sta, &demod_i2c, - (struct aml_demod_dvbc *)arg); - break; - - case AML_DEMOD_DVBC_GET_CH: - /* pr_dbg("Ioctl DVB-C Get Channel. It is blank\n"); */ - dvbc_status(&demod_sta, &demod_i2c, - (struct aml_demod_sts *)arg); - break; - case AML_DEMOD_DVBC_TEST: - pr_dbg("Ioctl DVB-C Test. It is blank\n"); - /*dvbc_get_test_out(0xb, 1000, (u32 *)arg); */ - break; - case AML_DEMOD_DVBT_SET_CH: - pr_dbg("Ioctl DVB-T Set Channel\n"); - dvbt_set_ch(&demod_sta, &demod_i2c, - (struct aml_demod_dvbt *)arg); - break; - - case AML_DEMOD_DVBT_GET_CH: - pr_dbg("Ioctl DVB-T Get Channel\n"); - /*dvbt_status(&demod_sta, &demod_i2c, - * (struct aml_demod_sts *)arg); - */ - break; - - case AML_DEMOD_DVBT_TEST: - pr_dbg("Ioctl DVB-T Test. It is blank\n"); - /*dvbt_get_test_out(0x1e, 1000, (u32 *)arg); */ - break; - - case AML_DEMOD_DTMB_SET_CH: - dtmb_set_ch(&demod_sta, &demod_i2c, - (struct aml_demod_dtmb *)arg); - break; - - case AML_DEMOD_DTMB_GET_CH: - break; - - case AML_DEMOD_DTMB_TEST: - break; - - case AML_DEMOD_ATSC_SET_CH: - atsc_set_ch(&demod_sta, &demod_i2c, - (struct aml_demod_atsc *)arg); - break; - - case AML_DEMOD_ATSC_GET_CH: - check_atsc_fsm_status(); - break; - - case AML_DEMOD_ATSC_TEST: - break; - - case AML_DEMOD_SET_REG: - /* pr_dbg("Ioctl Set Register\n"); */ - demod_set_reg((struct aml_demod_reg *)arg); - break; - - case AML_DEMOD_GET_REG: - /* pr_dbg("Ioctl Get Register\n"); */ - demod_get_reg((struct aml_demod_reg *)arg); - break; - -/* case AML_DEMOD_SET_REGS: */ -/* break; */ - -/* case AML_DEMOD_GET_REGS: */ -/* break; */ - - case AML_DEMOD_RESET_MEM: - pr_dbg("set mem ok\n"); - break; - - case AML_DEMOD_READ_MEM: - break; - case AML_DEMOD_SET_MEM: - /*step=(struct aml_demod_mem)arg; - * pr_dbg("[%x]0x%x------------------\n",i,mem_buf[step]); - * for(i=step;i<1024-1;i++){ - * pr_dbg("0x%x,",mem_buf[i]); - * } - */ - mem_read((struct aml_demod_mem *)arg); - break; - - case AML_DEMOD_ATSC_IRQ: - atsc_read_iqr_reg(); - break; - - default: - pr_dbg("Enter Default ! 0x%X\n", cmd); -/* pr_dbg("AML_DEMOD_GET_REGS=0x%08X\n", AML_DEMOD_GET_REGS); */ -/* pr_dbg("AML_DEMOD_SET_REGS=0x%08X\n", AML_DEMOD_SET_REGS); */ - return -EINVAL; - } - - return 0; -} - -#ifdef CONFIG_COMPAT - -static long aml_demod_compat_ioctl(struct file *file, unsigned int cmd, - ulong arg) -{ - return aml_demod_ioctl(file, cmd, (ulong)compat_ptr(arg)); -} - -#endif - - -static const struct file_operations aml_demod_fops = { - .owner = THIS_MODULE, - .open = aml_demod_open, - .release = aml_demod_release, - .unlocked_ioctl = aml_demod_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = aml_demod_compat_ioctl, -#endif -}; - -static int aml_demod_ui_open(struct inode *inode, struct file *file) -{ - pr_dbg("Amlogic aml_demod_ui_open Open\n"); - return 0; -} - -static int aml_demod_ui_release(struct inode *inode, struct file *file) -{ - pr_dbg("Amlogic aml_demod_ui_open Release\n"); - return 0; -} -char buf_all[100]; -static ssize_t aml_demod_ui_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - char *capture_buf = buf_all; - int res = 0; - - if (count >= 4 * 1024 * 1024) - count = 4 * 1024 * 1024; - else if (count == 0) - return 0; - - res = copy_to_user((void *)buf, (char *)capture_buf, count); - if (res < 0) { - pr_dbg("[aml_demod_ui_read]res is %d", res); - return res; - } - - return count; -} - -static ssize_t aml_demod_ui_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - return 0; -} - -static struct device *aml_demod_ui_dev; -static dev_t aml_demod_devno_ui; -static struct cdev *aml_demod_cdevp_ui; -static const struct file_operations aml_demod_ui_fops = { - .owner = THIS_MODULE, - .open = aml_demod_ui_open, - .release = aml_demod_ui_release, - .read = aml_demod_ui_read, - .write = aml_demod_ui_write, - /* .unlocked_ioctl = aml_demod_ui_ioctl, */ -}; - -#if 0 -static ssize_t aml_demod_ui_info(struct class *cla, - struct class_attribute *attr, char *buf) -{ - return 0; -} - -static struct class_attribute aml_demod_ui_class_attrs[] = { - __ATTR(info, - 0644, - aml_demod_ui_info, - NULL), - __ATTR_NULL -}; -#endif - -static struct class aml_demod_ui_class = { - .name = "aml_demod_ui", -/* .class_attrs = aml_demod_ui_class_attrs,*/ -}; - -int aml_demod_ui_init(void) -{ - int r = 0; - - r = class_register(&aml_demod_ui_class); - if (r) { - pr_dbg("create aml_demod class fail\r\n"); - class_unregister(&aml_demod_ui_class); - return r; - } - - r = alloc_chrdev_region(&aml_demod_devno_ui, 0, 1, DEVICE_UI_NAME); - if (r < 0) { - pr_dbg("aml_demod_ui: failed to alloc major number\n"); - r = -ENODEV; - unregister_chrdev_region(aml_demod_devno_ui, 1); - class_unregister(&aml_demod_ui_class); - return r; - } - - aml_demod_cdevp_ui = kmalloc(sizeof(struct cdev), GFP_KERNEL); - if (!aml_demod_cdevp_ui) { - r = -ENOMEM; - unregister_chrdev_region(aml_demod_devno_ui, 1); - kfree(aml_demod_cdevp_ui); - class_unregister(&aml_demod_ui_class); - return r; - } - /* connect the file operation with cdev */ - cdev_init(aml_demod_cdevp_ui, &aml_demod_ui_fops); - aml_demod_cdevp_ui->owner = THIS_MODULE; - /* connect the major/minor number to cdev */ - r = cdev_add(aml_demod_cdevp_ui, aml_demod_devno_ui, 1); - if (r) { - pr_dbg("aml_demod_ui:failed to add cdev\n"); - unregister_chrdev_region(aml_demod_devno_ui, 1); - cdev_del(aml_demod_cdevp_ui); - kfree(aml_demod_cdevp_ui); - class_unregister(&aml_demod_ui_class); - return r; - } - - aml_demod_ui_dev = device_create(&aml_demod_ui_class, NULL, - MKDEV(MAJOR(aml_demod_devno_ui), 0), - NULL, DEVICE_UI_NAME); - - if (IS_ERR(aml_demod_ui_dev)) { - pr_dbg("Can't create aml_demod device\n"); - unregister_chrdev_region(aml_demod_devno_ui, 1); - cdev_del(aml_demod_cdevp_ui); - kfree(aml_demod_cdevp_ui); - class_unregister(&aml_demod_ui_class); - return r; - } - - return r; -} - -void aml_demod_exit_ui(void) -{ - unregister_chrdev_region(aml_demod_devno_ui, 1); - cdev_del(aml_demod_cdevp_ui); - kfree(aml_demod_cdevp_ui); - class_unregister(&aml_demod_ui_class); -} - -static struct device *aml_demod_dev; -static dev_t aml_demod_devno; -static struct cdev *aml_demod_cdevp; - -#ifdef CONFIG_AM_DEMOD_DVBAPI -int aml_demod_init(void) -#else -static int __init aml_demod_init(void) -#endif -{ - int r = 0; - - pr_dbg("Amlogic Demod DVB-T/C DebugIF Init\n"); - - init_waitqueue_head(&lock_wq); - - /* hook demod isr */ - /* r = request_irq(INT_DEMOD, &aml_demod_isr, - * IRQF_SHARED, "aml_demod", - * (void *)aml_demod_dev_id); - * if (r) { - * pr_dbg("aml_demod irq register error.\n"); - * r = -ENOENT; - * goto err0; - * } - */ - - /* sysfs node creation */ - r = class_register(&aml_demod_class); - if (r) { - pr_dbg("create aml_demod class fail\r\n"); - goto err1; - } - - r = alloc_chrdev_region(&aml_demod_devno, 0, 1, DEVICE_NAME); - if (r < 0) { - pr_dbg("aml_demod: failed to alloc major number\n"); - r = -ENODEV; - goto err2; - } - - aml_demod_cdevp = kmalloc(sizeof(struct cdev), GFP_KERNEL); - if (!aml_demod_cdevp) { - r = -ENOMEM; - goto err3; - } - /* connect the file operation with cdev */ - cdev_init(aml_demod_cdevp, &aml_demod_fops); - aml_demod_cdevp->owner = THIS_MODULE; - /* connect the major/minor number to cdev */ - r = cdev_add(aml_demod_cdevp, aml_demod_devno, 1); - if (r) { - pr_dbg("aml_demod:failed to add cdev\n"); - goto err4; - } - - aml_demod_dev = device_create(&aml_demod_class, NULL, - MKDEV(MAJOR(aml_demod_devno), 0), NULL, - DEVICE_NAME); - - if (IS_ERR(aml_demod_dev)) { - pr_dbg("Can't create aml_demod device\n"); - goto err5; - } - pr_dbg("Amlogic Demod DVB-T/C DebugIF Init ok----------------\n"); -#if defined(CONFIG_AM_AMDEMOD_FPGA_VER) && !defined(CONFIG_AM_DEMOD_DVBAPI) - pr_dbg("sdio_init\n"); - sdio_init(); -#endif - aml_demod_ui_init(); - - return 0; - -err5: - cdev_del(aml_demod_cdevp); -err4: - kfree(aml_demod_cdevp); - -err3: - unregister_chrdev_region(aml_demod_devno, 1); - -err2: -/* free_irq(INT_DEMOD, (void *)aml_demod_dev_id);*/ - -err1: - class_unregister(&aml_demod_class); - -/* err0:*/ - return r; -} - -#ifdef CONFIG_AM_DEMOD_DVBAPI -void aml_demod_exit(void) -#else -static void __exit aml_demod_exit(void) -#endif -{ - pr_dbg("Amlogic Demod DVB-T/C DebugIF Exit\n"); - - unregister_chrdev_region(aml_demod_devno, 1); - device_destroy(&aml_demod_class, MKDEV(MAJOR(aml_demod_devno), 0)); - cdev_del(aml_demod_cdevp); - kfree(aml_demod_cdevp); - - /* free_irq(INT_DEMOD, (void *)aml_demod_dev_id); */ - - class_unregister(&aml_demod_class); - - aml_demod_exit_ui(); -} - -#ifndef CONFIG_AM_DEMOD_DVBAPI -module_init(aml_demod_init); -module_exit(aml_demod_exit); - -MODULE_LICENSE("GPL"); -/*MODULE_AUTHOR(DRV_AUTHOR);*/ -/*MODULE_DESCRIPTION(DRV_DESC);*/ -#endif diff --git a/drivers/stream_input/tv_frontend/dtv_demod/amlfrontend.c b/drivers/stream_input/tv_frontend/dtv_demod/amlfrontend.c deleted file mode 100644 index 357b6db..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/amlfrontend.c +++ b/dev/null @@ -1,1402 +0,0 @@ -/***************************************************************** - ** - ** Copyright (C) 2009 Amlogic,Inc. - ** All rights reserved - ** Filename : amlfrontend.c - ** - ** comment: - ** Driver for m6_demod demodulator - ** author : - ** Shijie.Rong@amlogic - ** version : - ** v1.0 12/3/13 - ** v2.0 15/10/12 - **************************************************************** - */ - -/* - * Driver for gxtv_demod demodulator - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef ARC_700 -#include -#else -/* #include */ -#endif -#include -#include -#include "../aml_fe.h" - -#include -#include -#include "demod_func.h" -#include "../aml_dvb.h" -#include "amlfrontend.h" - -MODULE_PARM_DESC(debug_aml, "\n\t\t Enable frontend debug information"); -static int debug_aml; -module_param(debug_aml, int, 0644); - -#define pr_dbg(a ...) \ - do { \ - if (debug_aml) { \ - printk(a); \ - } \ - } while (0) -#define pr_error(fmt, args ...) pr_err("GXTV_DEMOD: "fmt, ## args) -#define pr_inf(fmt, args...) pr_err("GXTV_DEMOD: " fmt, ## args) - -static int last_lock = -1; -#define DEMOD_DEVICE_NAME "gxtv_demod" -static int cci_thread; -static int freq_dvbc; -static struct aml_demod_sta demod_status; -static fe_modulation_t atsc_mode = VSB_8; - -long *mem_buf; - -MODULE_PARM_DESC(frontend_mode, "\n\t\t Frontend mode 0-DVBC, 1-DVBT"); -static int frontend_mode = -1; -module_param(frontend_mode, int, 0444); - -MODULE_PARM_DESC(frontend_i2c, "\n\t\t IIc adapter id of frontend"); -static int frontend_i2c = -1; -module_param(frontend_i2c, int, 0444); - -MODULE_PARM_DESC(frontend_tuner, - "\n\t\t Frontend tuner type 0-NULL, 1-DCT7070, 2-Maxliner, 3-FJ2207, 4-TD1316"); -static int frontend_tuner = -1; -module_param(frontend_tuner, int, 0444); - -MODULE_PARM_DESC(frontend_tuner_addr, "\n\t\t Tuner IIC address of frontend"); -static int frontend_tuner_addr = -1; -module_param(frontend_tuner_addr, int, 0444); -static int autoflags, autoFlagsTrig; -static struct mutex aml_lock; - -static int Gxtv_Demod_Dvbc_Init(struct aml_fe_dev *dev, int mode); - -static ssize_t dvbc_auto_sym_show(struct class *cls, - struct class_attribute *attr, char *buf) -{ - return sprintf(buf, "dvbc_autoflags: %s\n", autoflags ? "on" : "off"); -} - -static ssize_t dvbc_auto_sym_store(struct class *cls, - struct class_attribute *attr, - const char *buf, size_t count) -{ - - return 0; -} - -static unsigned int dtmb_mode; - -enum { - DTMB_READ_STRENGTH = 0, - DTMB_READ_SNR = 1, - DTMB_READ_LOCK = 2, - DTMB_READ_BCH = 3, -}; - - - -int convert_snr(int in_snr) -{ - int out_snr; - static int calce_snr[40] = { - 5, 6, 8, 10, 13, - 16, 20, 25, 32, 40, - 50, 63, 80, 100, 126, - 159, 200, 252, 318, 400, - 504, 634, 798, 1005, 1265, - 1592, 2005, 2524, 3177, 4000, - 5036, 6340, 7981, 10048, 12649, - 15924, 20047, 25238, 31773, 40000}; - for (out_snr = 1 ; out_snr <= 40; out_snr++) - if (in_snr <= calce_snr[out_snr]) - break; - - return out_snr; -} - - -static ssize_t dtmb_para_show(struct class *cls, - struct class_attribute *attr, char *buf) -{ - int snr, lock_status, bch, agc_if_gain; - struct dvb_frontend *dvbfe; - int strength = 0; - - if (dtmb_mode == DTMB_READ_STRENGTH) { - dvbfe = get_si2177_tuner(); - if (dvbfe != NULL) - if (dvbfe->ops.tuner_ops.get_strength) { - strength = - dvbfe->ops.tuner_ops.get_strength(dvbfe); - } - if (strength <= -56) { - agc_if_gain = - ((dtmb_read_reg(DTMB_TOP_FRONT_AGC))&0x3ff); - strength = dtmb_get_power_strength(agc_if_gain); - } - return sprintf(buf, "strength is %d\n", strength); - } else if (dtmb_mode == DTMB_READ_SNR) { - snr = dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR) & 0x3fff; - snr = convert_snr(snr); - return sprintf(buf, "snr is %d\n", snr); - } else if (dtmb_mode == DTMB_READ_LOCK) { - lock_status = - (dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR) >> 14) & 0x1; - return sprintf(buf, "lock_status is %d\n", lock_status); - } else if (dtmb_mode == DTMB_READ_BCH) { - bch = dtmb_read_reg(DTMB_TOP_FEC_BCH_ACC); - return sprintf(buf, "bch is %d\n", bch); - } else { - return sprintf(buf, "dtmb_para_show can't match mode\n"); - } -} - - - -static ssize_t dtmb_para_store(struct class *cls, - struct class_attribute *attr, - const char *buf, size_t count) -{ - if (buf[0] == '0') - dtmb_mode = DTMB_READ_STRENGTH; - else if (buf[0] == '1') - dtmb_mode = DTMB_READ_SNR; - else if (buf[0] == '2') - dtmb_mode = DTMB_READ_LOCK; - else if (buf[0] == '3') - dtmb_mode = DTMB_READ_BCH; - - return count; -} - -static int readregdata; - -static ssize_t dvbc_reg_show(struct class *cls, struct class_attribute *attr, - char *buf) -{ -/* int readregaddr=0;*/ - char *pbuf = buf; - - pbuf += sprintf(pbuf, "%x", readregdata); - - pr_dbg("read dvbc_reg\n"); - return pbuf - buf; -} - -static ssize_t dvbc_reg_store(struct class *cls, struct class_attribute *attr, - const char *buf, size_t count) -{ - return 0; -} - -static CLASS_ATTR(auto_sym, 0644, dvbc_auto_sym_show, dvbc_auto_sym_store); -static CLASS_ATTR(dtmb_para, 0644, dtmb_para_show, dtmb_para_store); -static CLASS_ATTR(dvbc_reg, 0644, dvbc_reg_show, dvbc_reg_store); - -#if 0 -static irqreturn_t amdemod_isr(int irq, void *data) -{ -/* struct aml_fe_dev *state = data; - * - * #define dvb_isr_islock() (((frontend_mode==0)&&dvbc_isr_islock()) \ - * ||((frontend_mode==1)&&dvbt_isr_islock())) - * #define dvb_isr_monitor() do {\ - * if(frontend_mode==1) dvbt_isr_monitor(); }while(0) - * #define dvb_isr_cancel() do { if(frontend_mode==1) dvbt_isr_cancel(); \ - * else if(frontend_mode==0) dvbc_isr_cancel();}while(0) - * - * dvb_isr_islock(); - * { - * if(waitqueue_active(&state->lock_wq)) - * wake_up_interruptible(&state->lock_wq); - * } - * - * dvb_isr_monitor(); - * - * dvb_isr_cancel(); - */ - - return IRQ_HANDLED; -} -#endif - -static int install_isr(struct aml_fe_dev *state) -{ - int r = 0; - - /* hook demod isr */ -/* pr_dbg("amdemod irq register[IRQ(%d)].\n", INT_DEMOD); - * r = request_irq(INT_DEMOD, &amdemod_isr, - * IRQF_SHARED, "amldemod", - * (void *)state); - * if (r) { - * pr_error("amdemod irq register error.\n"); - * } - */ - return r; -} - - -static int amdemod_qam(fe_modulation_t qam) -{ - switch (qam) { - case QAM_16: - return 0; - case QAM_32: - return 1; - case QAM_64: - return 2; - case QAM_128: - return 3; - case QAM_256: - return 4; - case VSB_8: - return 5; - case QAM_AUTO: - return 6; - default: - return 2; - } - return 2; -} - -static int amdemod_stat_islock(struct aml_fe_dev *dev, int mode) -{ - struct aml_demod_sts demod_sts; - int lock_status; - int dvbt_status1; - - if (mode == 0) { - /*DVBC*/ - /*dvbc_status(state->sta, state->i2c, &demod_sts);*/ - demod_sts.ch_sts = apb_read_reg(QAM_BASE + 0x18); - return demod_sts.ch_sts & 0x1; - } else if (mode == 1) { - /*DVBT*/ - dvbt_status1 = - ((apb_read_reg(DVBT_BASE + (0x0a << 2)) >> 20) & 0x3ff); - lock_status = (apb_read_reg(DVBT_BASE + (0x2a << 2))) & 0xf; - if ((((lock_status) == 9) || ((lock_status) == 10)) - && ((dvbt_status1) != 0)) - return 1; - else - return 0; - /*((apb_read_reg(DVBT_BASE+0x0)>>12)&0x1);// - * dvbt_get_status_ops()->get_status(&demod_sts, &demod_sta); - */ - } else if (mode == 2) { - /*ISDBT*/ - /*return dvbt_get_status_ops()->get_status - * (demod_sts, demod_sta); - */ - } else if (mode == 3) { - /*ATSC*/ - if ((atsc_mode == QAM_64) || (atsc_mode == QAM_256)) - return (atsc_read_iqr_reg() >> 16) == 0x1f; - else if (atsc_mode == VSB_8) - return atsc_read_reg(0x0980) == 0x79; - else - return (atsc_read_iqr_reg() >> 16) == 0x1f; - } else if (mode == 4) { - /*DTMB*/ - /* pr_dbg("DTMB lock status is %u\n", - * ((dtmb_read_reg(DTMB_BASE + (0x0e3 << 2)) >> 14) & - * 0x1)); - */ - return (dtmb_read_reg(DTMB_BASE + (0x0e3 << 2)) >> 14) & 0x1; - } - return 0; -} - -#define amdemod_dvbc_stat_islock(dev) amdemod_stat_islock((dev), 0) -#define amdemod_dvbt_stat_islock(dev) amdemod_stat_islock((dev), 1) -#define amdemod_isdbt_stat_islock(dev) amdemod_stat_islock((dev), 2) -#define amdemod_atsc_stat_islock(dev) amdemod_stat_islock((dev), 3) -#define amdemod_dtmb_stat_islock(dev) amdemod_stat_islock((dev), 4) - -static int gxtv_demod_dvbc_set_qam_mode(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct aml_demod_dvbc param; /*mode 0:16, 1:32, 2:64, 3:128, 4:256*/ - - memset(¶m, 0, sizeof(param)); - param.mode = amdemod_qam(c->modulation); - dvbc_set_qam_mode(param.mode); - return 0; -} - -static void gxtv_demod_dvbc_release(struct dvb_frontend *fe) -{ -/* - * struct aml_fe_dev *state = fe->demodulator_priv; - * - * uninstall_isr(state); - * - * kfree(state); - */ -} - -static int gxtv_demod_dvbc_read_status - (struct dvb_frontend *fe, fe_status_t *status) -{ -/* struct aml_fe_dev *dev = afe->dtv_demod;*/ - struct aml_demod_sts demod_sts; -/* struct aml_demod_sta demod_sta;*/ -/* struct aml_demod_i2c demod_i2c;*/ - int ilock; - - demod_sts.ch_sts = apb_read_reg(QAM_BASE + 0x18); -/* dvbc_status(&demod_sta, &demod_i2c, &demod_sts);*/ - if (demod_sts.ch_sts & 0x1) { - ilock = 1; - *status = - FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI | FE_HAS_SYNC; - } else { - ilock = 0; - *status = FE_TIMEDOUT; - } - if (last_lock != ilock) { - pr_error("%s.\n", - ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!"); - last_lock = ilock; - } - - return 0; -} - -static int gxtv_demod_dvbc_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - /*struct aml_fe_dev *dev = afe->dtv_demod;*/ - struct aml_demod_sts demod_sts; - struct aml_demod_i2c demod_i2c; - struct aml_demod_sta demod_sta; - - dvbc_status(&demod_sta, &demod_i2c, &demod_sts); - *ber = demod_sts.ch_ber; - return 0; -} - -static int gxtv_demod_dvbc_read_signal_strength - (struct dvb_frontend *fe, u16 *strength) -{ - struct aml_fe *afe = fe->demodulator_priv; - struct aml_fe_dev *dev = afe->dtv_demod; - - *strength = 256 - tuner_get_ch_power(dev); - - return 0; -} - -static int gxtv_demod_dvbc_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct aml_demod_sts demod_sts; - struct aml_demod_i2c demod_i2c; - struct aml_demod_sta demod_sta; - - dvbc_status(&demod_sta, &demod_i2c, &demod_sts); - *snr = demod_sts.ch_snr / 100; - return 0; -} - -static int gxtv_demod_dvbc_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - *ucblocks = 0; - return 0; -} - -/*extern int aml_fe_analog_set_frontend(struct dvb_frontend *fe);*/ - -static int gxtv_demod_dvbc_set_frontend(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct aml_demod_dvbc param; /*mode 0:16, 1:32, 2:64, 3:128, 4:256*/ - struct aml_demod_sts demod_sts; - struct aml_demod_i2c demod_i2c; - struct aml_fe *afe = fe->demodulator_priv; - struct aml_fe_dev *dev = afe->dtv_demod; - int error, times; - - demod_i2c.tuner = dev->drv->id; - demod_i2c.addr = dev->i2c_addr; - times = 2; - memset(¶m, 0, sizeof(param)); - param.ch_freq = c->frequency / 1000; - param.mode = amdemod_qam(c->modulation); - param.symb_rate = c->symbol_rate / 1000; - if ((param.mode == 3) && (demod_status.tmp != Adc_mode)) { - Gxtv_Demod_Dvbc_Init(dev, Adc_mode); - pr_dbg("Gxtv_Demod_Dvbc_Init,Adc_mode\n"); - } else { - /*Gxtv_Demod_Dvbc_Init(dev,Cry_mode);*/ - } - if (autoflags == 0) { - /*pr_dbg("QAM_TUNING mode\n");*/ - /*flag=0;*/ - } - if ((autoflags == 1) && (autoFlagsTrig == 0) - && (freq_dvbc == param.ch_freq)) { - pr_dbg("now is auto symbrating\n"); - return 0; - } - autoFlagsTrig = 0; - last_lock = -1; - pr_dbg("[gxtv_demod_dvbc_set_frontend]PARA\t" - "demod_i2c.tuner is %d||||demod_i2c.addr is %d||||\t" - "param.ch_freq is %d||||param.symb_rate is %d,\t" - "param.mode is %d\n", - demod_i2c.tuner, demod_i2c.addr, param.ch_freq, - param.symb_rate, param.mode); -retry: - aml_dmx_before_retune(afe->ts, fe); - aml_fe_analog_set_frontend(fe); - dvbc_set_ch(&demod_status, &demod_i2c, ¶m); - if (autoflags == 1) { - pr_dbg("QAM_PLAYING mode,start auto sym\n"); - dvbc_set_auto_symtrack(); - /* flag=1;*/ - } -/*rsj_debug*/ - - dvbc_status(&demod_status, &demod_i2c, &demod_sts); - freq_dvbc = param.ch_freq; - - times--; - if (amdemod_dvbc_stat_islock(dev) && times) { - int lock; - - aml_dmx_start_error_check(afe->ts, fe); - msleep(20); - error = aml_dmx_stop_error_check(afe->ts, fe); - lock = amdemod_dvbc_stat_islock(dev); - if ((error > 200) || !lock) { - pr_error - ("amlfe too many error, error count:%d\t" - "lock statuc:%d, retry\n", - error, lock); - goto retry; - } - } - - aml_dmx_after_retune(afe->ts, fe); - - afe->params = *c; -/* afe->params.frequency = c->frequency; - * afe->params.u.qam.symbol_rate = c->symbol_rate; - * afe->params.u.qam.modulation = c->modulation; - */ - - pr_dbg("AML amldemod => frequency=%d,symbol_rate=%d\r\n", c->frequency, - c->symbol_rate); - return 0; -} - -static int gxtv_demod_dvbc_get_frontend(struct dvb_frontend *fe) -{ /*these content will be writed into eeprom .*/ - struct aml_fe *afe = fe->demodulator_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int qam_mode; - - qam_mode = apb_read_reg(QAM_BASE + 0x008); - afe->params.modulation = (qam_mode & 7) + 1; - pr_dbg("[mode] is %d\n", afe->params.modulation); - - *c = afe->params; -/* c->modulation= afe->params.u.qam.modulation; - * c->frequency= afe->params.frequency; - * c->symbol_rate= afe->params.u.qam.symbol_rate; - */ - return 0; -} - -static int Gxtv_Demod_Dvbc_Init(struct aml_fe_dev *dev, int mode) -{ - struct aml_demod_sys sys; - struct aml_demod_i2c i2c; - - pr_dbg("AML Demod DVB-C init\r\n"); - memset(&sys, 0, sizeof(sys)); - memset(&i2c, 0, sizeof(i2c)); - i2c.tuner = dev->drv->id; - i2c.addr = dev->i2c_addr; - /* 0 -DVBC, 1-DVBT, ISDBT, 2-ATSC*/ - demod_status.dvb_mode = Gxtv_Dvbc; - - if (mode == Adc_mode) { - sys.adc_clk = Adc_Clk_25M; - sys.demod_clk = Demod_Clk_200M; - demod_status.tmp = Adc_mode; - } else { - sys.adc_clk = Adc_Clk_24M; - sys.demod_clk = Demod_Clk_72M; - demod_status.tmp = Cry_mode; - } - demod_status.ch_if = Si2176_5M_If * 1000; - pr_dbg("[%s]adc_clk is %d,demod_clk is %d\n", __func__, sys.adc_clk, - sys.demod_clk); - autoFlagsTrig = 0; - demod_set_sys(&demod_status, &i2c, &sys); - return 0; -} - -static void gxtv_demod_dvbt_release(struct dvb_frontend *fe) -{ -/* - * struct aml_fe_dev *state = fe->demodulator_priv; - * - * uninstall_isr(state); - * - * kfree(state); - */ -} - -static int gxtv_demod_dvbt_read_status - (struct dvb_frontend *fe, fe_status_t *status) -{ -/* struct aml_fe *afe = fe->demodulator_priv;*/ - struct aml_demod_i2c demod_i2c; - struct aml_demod_sta demod_sta; - int ilock; - unsigned char s = 0; - - s = dvbt_get_status_ops()->get_status(&demod_sta, &demod_i2c); - if (s == 1) { - ilock = 1; - *status = - FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI | FE_HAS_SYNC; - } else { - ilock = 0; - *status = FE_TIMEDOUT; - } - if (last_lock != ilock) { - pr_error("%s.\n", - ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!"); - last_lock = ilock; - } - - return 0; -} - -static int gxtv_demod_dvbt_read_ber(struct dvb_frontend *fe, u32 *ber) -{ -/* struct aml_fe *afe = fe->demodulator_priv;*/ - struct aml_demod_i2c demod_i2c; - struct aml_demod_sta demod_sta; - - *ber = dvbt_get_status_ops()->get_ber(&demod_sta, &demod_i2c) & 0xffff; - return 0; -} - -static int gxtv_demod_dvbt_read_signal_strength - (struct dvb_frontend *fe, u16 *strength) -{ - struct aml_fe *afe = fe->demodulator_priv; - struct aml_fe_dev *dev = afe->dtv_demod; - - *strength = 256 - tuner_get_ch_power(dev); - pr_dbg("[RSJ]tuner strength is %d dbm\n", *strength); - return 0; -} - -static int gxtv_demod_dvbt_read_snr(struct dvb_frontend *fe, u16 *snr) -{ -/* struct aml_fe *afe = fe->demodulator_priv;*/ -/* struct aml_demod_sts demod_sts;*/ - struct aml_demod_i2c demod_i2c; - struct aml_demod_sta demod_sta; - - *snr = dvbt_get_status_ops()->get_snr(&demod_sta, &demod_i2c); - *snr /= 8; - pr_dbg("[RSJ]snr is %d dbm\n", *snr); - return 0; -} - -static int gxtv_demod_dvbt_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - *ucblocks = 0; - return 0; -} - -static int gxtv_demod_dvbt_set_frontend(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - /*struct aml_demod_sts demod_sts;*/ - struct aml_demod_i2c demod_i2c; - int error, times; - struct aml_demod_dvbt param; - struct aml_fe *afe = fe->demodulator_priv; - struct aml_fe_dev *dev = afe->dtv_demod; - - demod_i2c.tuner = dev->drv->id; - demod_i2c.addr = dev->i2c_addr; - - times = 2; - - /*////////////////////////////////////*/ - /* bw == 0 : 8M*/ - /* 1 : 7M*/ - /* 2 : 6M*/ - /* 3 : 5M*/ - /* agc_mode == 0: single AGC*/ - /* 1: dual AGC*/ - /*////////////////////////////////////*/ - memset(¶m, 0, sizeof(param)); - param.ch_freq = c->frequency / 1000; - param.bw = c->bandwidth_hz; - param.agc_mode = 1; - /*ISDBT or DVBT : 0 is QAM, 1 is DVBT, 2 is ISDBT, - * 3 is DTMB, 4 is ATSC - */ - param.dat0 = 1; - last_lock = -1; - -retry: - aml_dmx_before_retune(AM_TS_SRC_TS2, fe); - aml_fe_analog_set_frontend(fe); - dvbt_set_ch(&demod_status, &demod_i2c, ¶m); - - /* for(count=0;count<10;count++){ - * if(amdemod_dvbt_stat_islock(dev)){ - * pr_dbg("first lock success\n"); - * break; - * } - * - * msleep(200); - * } - */ -/*rsj_debug*/ - -/**/ - - times--; - if (amdemod_dvbt_stat_islock(dev) && times) { - int lock; - - aml_dmx_start_error_check(AM_TS_SRC_TS2, fe); - msleep(20); - error = aml_dmx_stop_error_check(AM_TS_SRC_TS2, fe); - lock = amdemod_dvbt_stat_islock(dev); - if ((error > 200) || !lock) { - pr_error - ("amlfe too many error,\t" - "error count:%d lock statuc:%d, retry\n", - error, lock); - goto retry; - } - } - - aml_dmx_after_retune(AM_TS_SRC_TS2, fe); - - afe->params = *c; - - /*pr_dbg("AML amldemod => frequency=%d,symbol_rate=%d\r\n", - * p->frequency,p->u.qam.symbol_rate); - */ - return 0; -} - -static int gxtv_demod_dvbt_get_frontend(struct dvb_frontend *fe) -{ /*these content will be writed into eeprom .*/ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct aml_fe *afe = fe->demodulator_priv; - - *c = afe->params; - return 0; -} - -int Gxtv_Demod_Dvbt_Init(struct aml_fe_dev *dev) -{ - struct aml_demod_sys sys; - struct aml_demod_i2c i2c; - - pr_dbg("AML Demod DVB-T init\r\n"); - - memset(&sys, 0, sizeof(sys)); - memset(&i2c, 0, sizeof(i2c)); - memset(&demod_status, 0, sizeof(demod_status)); - i2c.tuner = dev->drv->id; - i2c.addr = dev->i2c_addr; - /* 0 -DVBC, 1-DVBT, ISDBT, 2-ATSC*/ - demod_status.dvb_mode = Gxtv_Dvbt_Isdbt; - sys.adc_clk = Adc_Clk_24M; - sys.demod_clk = Demod_Clk_60M; - demod_status.ch_if = Si2176_5M_If * 1000; - demod_set_sys(&demod_status, &i2c, &sys); - return 0; -} - -static void gxtv_demod_atsc_release(struct dvb_frontend *fe) -{ -/* - * struct aml_fe_dev *state = fe->demodulator_priv; - * - * uninstall_isr(state); - * - * kfree(state); - */ -} - -static int gxtv_demod_atsc_set_qam_mode(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct aml_demod_atsc param; /*mode 3:64, 5:256, 7:vsb*/ - fe_modulation_t mode; - - memset(¶m, 0, sizeof(param)); - mode = c->modulation; - pr_dbg("mode is %d\n", mode); - atsc_qam_set(mode); - return 0; -} - -static int gxtv_demod_atsc_read_status - (struct dvb_frontend *fe, fe_status_t *status) -{ - struct aml_fe *afe = fe->demodulator_priv; - struct aml_fe_dev *dev = afe->dtv_demod; -/* struct aml_demod_i2c demod_i2c;*/ -/* struct aml_demod_sta demod_sta;*/ - int ilock; - unsigned char s = 0; - - s = amdemod_atsc_stat_islock(dev); - if (s == 1) { - ilock = 1; - *status = - FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI | FE_HAS_SYNC; - } else { - ilock = 0; - *status = FE_TIMEDOUT; - } - if (last_lock != ilock) { - pr_error("%s.\n", - ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!"); - last_lock = ilock; - } - - return 0; -} - -static int gxtv_demod_atsc_read_ber(struct dvb_frontend *fe, u32 *ber) -{ -/* struct aml_fe *afe = fe->demodulator_priv;*/ -/* struct aml_fe_dev *dev = afe->dtv_demod;*/ -/* struct aml_demod_sts demod_sts;*/ -/* struct aml_demod_i2c demod_i2c;*/ -/* struct aml_demod_sta demod_sta;*/ - -/* check_atsc_fsm_status();*/ - return 0; -} - -static int gxtv_demod_atsc_read_signal_strength - (struct dvb_frontend *fe, u16 *strength) -{ - struct aml_fe *afe = fe->demodulator_priv; - struct aml_fe_dev *dev = afe->dtv_demod; - - *strength = tuner_get_ch_power(dev); - return 0; -} - -static int gxtv_demod_atsc_read_snr(struct dvb_frontend *fe, u16 *snr) -{ -/* struct aml_fe *afe = fe->demodulator_priv;*/ -/* struct aml_fe_dev *dev = afe->dtv_demod;*/ - -/* struct aml_demod_sts demod_sts;*/ -/* struct aml_demod_i2c demod_i2c;*/ -/* struct aml_demod_sta demod_sta;*/ - -/* * snr=check_atsc_fsm_status();*/ - return 0; -} - -static int gxtv_demod_atsc_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - *ucblocks = 0; - return 0; -} - -static int gxtv_demod_atsc_set_frontend(struct dvb_frontend *fe) -{ -/* struct amlfe_state *state = fe->demodulator_priv;*/ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct aml_demod_atsc param; -/* struct aml_demod_sta demod_sta;*/ -/* struct aml_demod_sts demod_sts;*/ - struct aml_demod_i2c demod_i2c; - int error, times; - struct aml_fe *afe = fe->demodulator_priv; - struct aml_fe_dev *dev = afe->dtv_demod; - - demod_i2c.tuner = dev->drv->id; - demod_i2c.addr = dev->i2c_addr; - times = 2; - - memset(¶m, 0, sizeof(param)); - param.ch_freq = c->frequency / 1000; - - last_lock = -1; - /*p->u.vsb.modulation=QAM_64;*/ - atsc_mode = c->modulation; - /* param.mode = amdemod_qam(p->u.vsb.modulation);*/ - param.mode = c->modulation; - -retry: - aml_dmx_before_retune(AM_TS_SRC_TS2, fe); - aml_fe_analog_set_frontend(fe); - atsc_set_ch(&demod_status, &demod_i2c, ¶m); - - /*{ - * int ret; - * ret = wait_event_interruptible_timeout( - * dev->lock_wq, amdemod_atsc_stat_islock(dev), 4*HZ); - * if(!ret) pr_error("amlfe wait lock timeout.\n"); - * } - */ -/*rsj_debug*/ - /* int count; - * for(count=0;count<10;count++){ - * if(amdemod_atsc_stat_islock(dev)){ - * pr_dbg("first lock success\n"); - * break; - * } - * - * msleep(200); - * } - */ - - times--; - if (amdemod_atsc_stat_islock(dev) && times) { - int lock; - - aml_dmx_start_error_check(AM_TS_SRC_TS2, fe); - msleep(20); - error = aml_dmx_stop_error_check(AM_TS_SRC_TS2, fe); - lock = amdemod_atsc_stat_islock(dev); - if ((error > 200) || !lock) { - pr_error - ("amlfe too many error,\t" - "error count:%d lock statuc:%d, retry\n", - error, lock); - goto retry; - } - } - - aml_dmx_after_retune(AM_TS_SRC_TS2, fe); - - afe->params = *c; - /*pr_dbg("AML amldemod => frequency=%d,symbol_rate=%d\r\n", - * p->frequency,p->u.qam.symbol_rate); - */ - return 0; -} - -static int gxtv_demod_atsc_get_frontend(struct dvb_frontend *fe) -{ /*these content will be writed into eeprom .*/ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct aml_fe *afe = fe->demodulator_priv; - - pr_dbg("c->frequency is %d\n", c->frequency); - *c = afe->params; - return 0; -} - -int Gxtv_Demod_Atsc_Init(struct aml_fe_dev *dev) -{ - struct aml_demod_sys sys; - struct aml_demod_i2c i2c; - - pr_dbg("AML Demod ATSC init\r\n"); - - memset(&sys, 0, sizeof(sys)); - memset(&i2c, 0, sizeof(i2c)); - memset(&demod_status, 0, sizeof(demod_status)); - /* 0 -DVBC, 1-DVBT, ISDBT, 2-ATSC*/ - demod_status.dvb_mode = Gxtv_Atsc; - sys.adc_clk = Adc_Clk_25_2M; /*Adc_Clk_26M;*/ - sys.demod_clk = Demod_Clk_75M; /*Demod_Clk_71M;//Demod_Clk_78M;*/ - demod_status.ch_if = 6350; - demod_status.tmp = Adc_mode; - demod_set_sys(&demod_status, &i2c, &sys); - return 0; -} - -static void gxtv_demod_dtmb_release(struct dvb_frontend *fe) -{ -/* - * struct aml_fe_dev *state = fe->demodulator_priv; - * - * uninstall_isr(state); - * - * kfree(state); - */ -} - -static int gxtv_demod_dtmb_read_status - (struct dvb_frontend *fe, fe_status_t *status) -{ - struct aml_fe *afe = fe->demodulator_priv; - struct aml_fe_dev *dev = afe->dtv_demod; -/* struct aml_demod_i2c demod_i2c;*/ -/* struct aml_demod_sta demod_sta;*/ - int ilock; - unsigned char s = 0; - -/* s = amdemod_dtmb_stat_islock(dev);*/ -/* if(s==1)*/ - if (is_meson_txl_cpu()) - s = dtmb_check_status_txl(fe); - else - s = dtmb_check_status_gxtv(fe); - s = amdemod_dtmb_stat_islock(dev); -/* s=1;*/ - if (s == 1) { - ilock = 1; - *status = - FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI | FE_HAS_SYNC; - } else { - ilock = 0; - *status = FE_TIMEDOUT; - } - if (last_lock != ilock) { - pr_error("%s.\n", - ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!"); - last_lock = ilock; - } - - return 0; -} - -static int gxtv_demod_dtmb_read_ber(struct dvb_frontend *fe, u32 *ber) -{ -/* struct aml_fe *afe = fe->demodulator_priv;*/ -/* struct aml_fe_dev *dev = afe->dtv_demod;*/ -/* struct aml_demod_sts demod_sts;*/ -/* struct aml_demod_i2c demod_i2c;*/ -/* struct aml_demod_sta demod_sta;*/ - -/* check_atsc_fsm_status();*/ -/* int fec_bch_add; */ -/* fec_bch_add = dtmb_read_reg(0xdf); */ -/* *ber = fec_bch_add; */ - return 0; -} - -static int gxtv_demod_dtmb_read_signal_strength - (struct dvb_frontend *fe, u16 *strength) -{ - struct aml_fe *afe = fe->demodulator_priv; - struct aml_fe_dev *dev = afe->dtv_demod; - - *strength = tuner_get_ch_power(dev); - return 0; -} - -static int gxtv_demod_dtmb_read_snr(struct dvb_frontend *fe, u16 *snr) -{ -/* struct aml_fe *afe = fe->demodulator_priv;*/ -/* struct aml_fe_dev *dev = afe->dtv_demod;*/ -#if 1 - int tmp, snr_avg; - - tmp = snr_avg = 0; - tmp = dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR); -/* snr_avg = (tmp >> 16) & 0x3fff; - * if (snr_avg >= 2048) - * snr_avg = snr_avg - 4096; - * snr_avg = snr_avg / 32; - */ - *snr = tmp&0xff; -#endif - return 0; -} - -static int gxtv_demod_dtmb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - *ucblocks = 0; - return 0; -} - -static int gxtv_demod_dtmb_read_fsm(struct dvb_frontend *fe, u32 *fsm_status) -{ - int tmp; - - tmp = dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0); - *fsm_status = tmp&0xffffffff; - pr_dbg("[rsj] fsm_status is %x\n", *fsm_status); - return 0; -} - - -static int gxtv_demod_dtmb_set_frontend(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct aml_demod_dtmb param; -/* struct aml_demod_sta demod_sta;*/ -/* struct aml_demod_sts demod_sts;*/ - struct aml_demod_i2c demod_i2c; - int times; - struct aml_fe *afe = fe->demodulator_priv; - struct aml_fe_dev *dev = afe->dtv_demod; - - demod_i2c.tuner = dev->drv->id; - demod_i2c.addr = dev->i2c_addr; - times = 2; - pr_dbg("gxtv_demod_dtmb_set_frontend,freq is %d\n", c->frequency); - memset(¶m, 0, sizeof(param)); - param.ch_freq = c->frequency / 1000; - - last_lock = -1; -/* demod_power_switch(PWR_OFF); */ - aml_fe_analog_set_frontend(fe); - msleep(100); -/* demod_power_switch(PWR_ON); */ - dtmb_set_ch(&demod_status, &demod_i2c, ¶m); - afe->params = *c; - /* pr_dbg("AML amldemod => frequency=%d,symbol_rate=%d\r\n", - * p->frequency,p->u.qam.symbol_rate); - */ - return 0; -} - -static int gxtv_demod_dtmb_get_frontend(struct dvb_frontend *fe) -{ /*these content will be writed into eeprom .*/ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct aml_fe *afe = fe->demodulator_priv; - - *c = afe->params; -/* pr_dbg("[get frontend]c->frequency is %d\n",c->frequency);*/ - return 0; -} - -int Gxtv_Demod_Dtmb_Init(struct aml_fe_dev *dev) -{ - struct aml_demod_sys sys; - struct aml_demod_i2c i2c; - - pr_dbg("AML Demod DTMB init\r\n"); - - memset(&sys, 0, sizeof(sys)); - memset(&i2c, 0, sizeof(i2c)); - memset(&demod_status, 0, sizeof(demod_status)); - /* 0 -DVBC, 1-DVBT, ISDBT, 2-ATSC*/ - demod_status.dvb_mode = Gxtv_Dtmb; - if (is_meson_txl_cpu()) { - sys.adc_clk = Adc_Clk_25M; /*Adc_Clk_26M;*/ - sys.demod_clk = Demod_Clk_225M; - } else { - sys.adc_clk = Adc_Clk_25M; /*Adc_Clk_26M;*/ - sys.demod_clk = Demod_Clk_200M; - } - demod_status.ch_if = Si2176_5M_If; - demod_status.tmp = Adc_mode; - demod_status.spectrum = dev->spectrum; - demod_set_sys(&demod_status, &i2c, &sys); - return 0; -} - -static int gxtv_demod_fe_get_ops(struct aml_fe_dev *dev, int mode, void *ops) -{ - struct dvb_frontend_ops *fe_ops = (struct dvb_frontend_ops *)ops; - - if (mode == AM_FE_OFDM) { - fe_ops->info.frequency_min = 51000000; - fe_ops->info.frequency_max = 858000000; - fe_ops->info.frequency_stepsize = 0; - fe_ops->info.frequency_tolerance = 0; - fe_ops->info.caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | - FE_CAN_RECOVER | FE_CAN_MUTE_TS; - fe_ops->release = gxtv_demod_dvbt_release; - fe_ops->set_frontend = gxtv_demod_dvbt_set_frontend; - fe_ops->get_frontend = gxtv_demod_dvbt_get_frontend; - fe_ops->read_status = gxtv_demod_dvbt_read_status; - fe_ops->read_ber = gxtv_demod_dvbt_read_ber; - fe_ops->read_signal_strength = - gxtv_demod_dvbt_read_signal_strength; - fe_ops->read_snr = gxtv_demod_dvbt_read_snr; - fe_ops->read_ucblocks = gxtv_demod_dvbt_read_ucblocks; - fe_ops->read_dtmb_fsm = NULL; - - pr_dbg("=========================dvbt demod init\r\n"); - Gxtv_Demod_Dvbt_Init(dev); - } else if (mode == AM_FE_QAM) { - fe_ops->info.frequency_min = 51000000; - fe_ops->info.frequency_max = 858000000; - fe_ops->info.frequency_stepsize = 0; - fe_ops->info.frequency_tolerance = 0; - fe_ops->info.caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 | - FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_QAM_64 | - FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | - FE_CAN_RECOVER | FE_CAN_MUTE_TS; - - fe_ops->release = gxtv_demod_dvbc_release; - fe_ops->set_frontend = gxtv_demod_dvbc_set_frontend; - fe_ops->get_frontend = gxtv_demod_dvbc_get_frontend; - fe_ops->read_status = gxtv_demod_dvbc_read_status; - fe_ops->read_ber = gxtv_demod_dvbc_read_ber; - fe_ops->read_signal_strength = - gxtv_demod_dvbc_read_signal_strength; - fe_ops->read_snr = gxtv_demod_dvbc_read_snr; - fe_ops->read_ucblocks = gxtv_demod_dvbc_read_ucblocks; - fe_ops->set_qam_mode = gxtv_demod_dvbc_set_qam_mode; - fe_ops->read_dtmb_fsm = NULL; - install_isr(dev); - pr_dbg("=========================dvbc demod init\r\n"); - Gxtv_Demod_Dvbc_Init(dev, Adc_mode); - } else if (mode == AM_FE_ATSC) { - fe_ops->info.frequency_min = 51000000; - fe_ops->info.frequency_max = 858000000; - fe_ops->info.frequency_stepsize = 0; - fe_ops->info.frequency_tolerance = 0; - fe_ops->info.caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | - FE_CAN_RECOVER | FE_CAN_MUTE_TS; - - fe_ops->release = gxtv_demod_atsc_release; - fe_ops->set_frontend = gxtv_demod_atsc_set_frontend; - fe_ops->get_frontend = gxtv_demod_atsc_get_frontend; - fe_ops->read_status = gxtv_demod_atsc_read_status; - fe_ops->read_ber = gxtv_demod_atsc_read_ber; - fe_ops->read_signal_strength = - gxtv_demod_atsc_read_signal_strength; - fe_ops->read_snr = gxtv_demod_atsc_read_snr; - fe_ops->read_ucblocks = gxtv_demod_atsc_read_ucblocks; - fe_ops->set_qam_mode = gxtv_demod_atsc_set_qam_mode; - fe_ops->read_dtmb_fsm = NULL; - Gxtv_Demod_Atsc_Init(dev); - } else if (mode == AM_FE_DTMB) { - fe_ops->info.frequency_min = 51000000; - fe_ops->info.frequency_max = 900000000; - fe_ops->info.frequency_stepsize = 0; - fe_ops->info.frequency_tolerance = 0; - fe_ops->info.caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | - FE_CAN_RECOVER | FE_CAN_MUTE_TS; - - fe_ops->release = gxtv_demod_dtmb_release; - fe_ops->set_frontend = gxtv_demod_dtmb_set_frontend; - fe_ops->get_frontend = gxtv_demod_dtmb_get_frontend; - fe_ops->read_status = gxtv_demod_dtmb_read_status; - fe_ops->read_ber = gxtv_demod_dtmb_read_ber; - fe_ops->read_signal_strength = - gxtv_demod_dtmb_read_signal_strength; - fe_ops->read_snr = gxtv_demod_dtmb_read_snr; - fe_ops->read_ucblocks = gxtv_demod_dtmb_read_ucblocks; - fe_ops->read_dtmb_fsm = gxtv_demod_dtmb_read_fsm; - Gxtv_Demod_Dtmb_Init(dev); - } - return 0; -} - -static int gxtv_demod_fe_resume(struct aml_fe_dev *dev) -{ - int memstart_dtmb; - - pr_inf("gxtv_demod_fe_resume\n"); -/* demod_power_switch(PWR_ON);*/ - Gxtv_Demod_Dtmb_Init(dev); - memstart_dtmb = dev->fe->dtv_demod->mem_start; - pr_dbg("[im]memstart is %x\n", memstart_dtmb); - dtmb_write_reg(DTMB_FRONT_MEM_ADDR, memstart_dtmb); - pr_dbg("[dtmb]mem_buf is 0x%x\n", - dtmb_read_reg(DTMB_FRONT_MEM_ADDR)); - return 0; -} - -static int gxtv_demod_fe_suspend(struct aml_fe_dev *dev) -{ - pr_inf("gxtv_demod_fe_suspend\n"); -/* demod_power_switch(PWR_OFF);*/ - return 0; -} - -#ifdef CONFIG_CMA -void dtmb_cma_alloc(struct aml_fe_dev *devp) -{ - unsigned int mem_size = devp->cma_mem_size; - - devp->venc_pages = - dma_alloc_from_contiguous(&(devp->this_pdev->dev), - mem_size >> PAGE_SHIFT, 0); - pr_dbg("[cma]mem_size is %d,%d\n", - mem_size, mem_size >> PAGE_SHIFT); - if (devp->venc_pages) { - devp->mem_start = page_to_phys(devp->venc_pages); - devp->mem_size = mem_size; - pr_dbg("demod mem_start = 0x%x, mem_size = 0x%x\n", - devp->mem_start, devp->mem_size); - pr_dbg("demod cma alloc ok!\n"); - } else { - pr_dbg("demod cma mem undefined2.\n"); - } -} - -void dtmb_cma_release(struct aml_fe_dev *devp) -{ - dma_release_from_contiguous(&(devp->this_pdev->dev), - devp->venc_pages, - devp->cma_mem_size>>PAGE_SHIFT); - pr_dbg("demod cma release ok!\n"); - devp->mem_start = 0; - devp->mem_size = 0; -} -#endif - - -static int gxtv_demod_fe_enter_mode(struct aml_fe *fe, int mode) -{ - struct aml_fe_dev *dev = fe->dtv_demod; - int memstart_dtmb; - - /* must enable the adc ref signal for demod, */ - vdac_enable(1, 0x2); - - autoFlagsTrig = 1; - if (cci_thread) - if (dvbc_get_cci_task() == 1) - dvbc_create_cci_task(); - /*mem_buf = (long *)phys_to_virt(memstart);*/ - if (mode == AM_FE_DTMB) { - Gxtv_Demod_Dtmb_Init(dev); - if (fe->dtv_demod->cma_flag == 1) { - pr_dbg("CMA MODE, cma flag is %d,mem size is %d", - fe->dtv_demod->cma_flag, fe->dtv_demod->cma_mem_size); - dtmb_cma_alloc(dev); - memstart_dtmb = dev->mem_start; - } else { - memstart_dtmb = fe->dtv_demod->mem_start; - } - pr_dbg("[im]memstart is %x\n", memstart_dtmb); - dtmb_write_reg(DTMB_FRONT_MEM_ADDR, memstart_dtmb); - pr_dbg("[dtmb]mem_buf is 0x%x\n", - dtmb_read_reg(DTMB_FRONT_MEM_ADDR)); - /* open arbit */ - demod_set_demod_reg(0x8, DEMOD_REG4); - } else if (mode == AM_FE_QAM) { - Gxtv_Demod_Dvbc_Init(dev, Adc_mode); - } - - return 0; -} - -static int gxtv_demod_fe_leave_mode(struct aml_fe *fe, int mode) -{ - struct aml_fe_dev *dev = fe->dtv_demod; - - dtvpll_init_flag(0); - /*dvbc_timer_exit();*/ - if (cci_thread) - dvbc_kill_cci_task(); - if (mode == AM_FE_DTMB) { - /* close arbit */ - demod_set_demod_reg(0x0, DEMOD_REG4); - if (fe->dtv_demod->cma_flag == 1) - dtmb_cma_release(dev); - } - - /* should disable the adc ref signal for demod */ - vdac_enable(0, 0x2); - - return 0; -} - -static struct aml_fe_drv gxtv_demod_dtv_demod_drv = { - .id = AM_DTV_DEMOD_M1, - .name = "AMLDEMOD", - .capability = - AM_FE_QPSK | AM_FE_QAM | AM_FE_ATSC | AM_FE_OFDM | AM_FE_DTMB, - .get_ops = gxtv_demod_fe_get_ops, - .suspend = gxtv_demod_fe_suspend, - .resume = gxtv_demod_fe_resume, - .enter_mode = gxtv_demod_fe_enter_mode, - .leave_mode = gxtv_demod_fe_leave_mode -}; - -struct class *gxtv_clsp; -struct class *gxtv_para_clsp; - -static int __init gxtvdemodfrontend_init(void) -{ - int ret; - - pr_dbg("register gxtv_demod demod driver\n"); - ret = 0; - - dtvpll_lock_init(); - mutex_init(&aml_lock); - - gxtv_clsp = class_create(THIS_MODULE, DEMOD_DEVICE_NAME); - if (!gxtv_clsp) { - pr_error("[gxtv demod]%s:create class error.\n", __func__); - return PTR_ERR(gxtv_clsp); - } - ret = class_create_file(gxtv_clsp, &class_attr_auto_sym); - if (ret) - pr_error("[gxtv demod]%s create class error.\n", __func__); - - ret = class_create_file(gxtv_clsp, &class_attr_dtmb_para); - if (ret) - pr_error("[gxtv demod]%s create class error.\n", __func__); - - ret = class_create_file(gxtv_clsp, &class_attr_dvbc_reg); - if (ret) - pr_error("[gxtv demod]%s create class error.\n", __func__); - - return aml_register_fe_drv(AM_DEV_DTV_DEMOD, &gxtv_demod_dtv_demod_drv); -} - -static void __exit gxtvdemodfrontend_exit(void) -{ - pr_dbg("unregister gxtv_demod demod driver\n"); - - mutex_destroy(&aml_lock); - - class_remove_file(gxtv_clsp, &class_attr_auto_sym); - class_remove_file(gxtv_clsp, &class_attr_dtmb_para); - class_remove_file(gxtv_clsp, &class_attr_dvbc_reg); - class_destroy(gxtv_clsp); - aml_unregister_fe_drv(AM_DEV_DTV_DEMOD, &gxtv_demod_dtv_demod_drv); -} - -fs_initcall(gxtvdemodfrontend_init); -module_exit(gxtvdemodfrontend_exit); - -MODULE_DESCRIPTION("gxtv_demod DVB-T/DVB-C/DTMB Demodulator driver"); -MODULE_AUTHOR("RSJ"); -MODULE_LICENSE("GPL"); diff --git a/drivers/stream_input/tv_frontend/dtv_demod/demod_func.c b/drivers/stream_input/tv_frontend/dtv_demod/demod_func.c deleted file mode 100644 index a54d82c..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/demod_func.c +++ b/dev/null @@ -1,2996 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -/*#include "register.h"*/ -/*#include "c_arc_pointer_reg.h"*/ -/*#include "a9_func.h"*/ -/*#include "clk_util.h"*/ -/*#include "c_stimulus.h"*/ -/*#include "a9_l2_func.h"*/ - -#include "demod_func.h" -#include -#include -#include -#include "acf_filter_coefficient.h" -#include - -#define M6D - -/* static void __iomem * demod_meson_reg_map[4]; */ - -#define pr_dbg(fmt, args ...) \ - do { \ - if (debug_demod) \ - pr_info("FE: " fmt, ## args); \ - } while (0) -#define pr_error(fmt, args ...) pr_info("FE: " fmt, ## args) - -MODULE_PARM_DESC(debug_demod, "\n\t\t Enable frontend debug information"); -static int debug_demod; -module_param(debug_demod, int, 0644); - -MODULE_PARM_DESC(demod_timeout, "\n\t\t timeout debug information"); -static int demod_timeout = 120; -module_param(demod_timeout, int, 0644); - -MODULE_PARM_DESC(demod_sync_count, "\n\t\t timeout debug information"); -static int demod_sync_count = 60; -module_param(demod_sync_count, int, 0644); - -MODULE_PARM_DESC(demod_sync_delay_time, "\n\t\t timeout debug information"); -static int demod_sync_delay_time = 8; -module_param(demod_sync_delay_time, int, 0644); - - - -MODULE_PARM_DESC(demod_mobile_power, "\n\t\t demod_mobile_power debug information"); -static int demod_mobile_power = 100; -module_param(demod_mobile_power, int, 0644); - -MODULE_PARM_DESC(demod_enable_performance, "\n\t\t demod_enable_performance information"); -static int demod_enable_performance = 1; -module_param(demod_enable_performance, int, 0644); - - -static struct mutex mp; -static struct mutex dtvpll_init_lock; -static int dtvpll_init; -static int dtmb_spectrum = 2; - - -/* 8vsb */ -static struct atsc_cfg list_8vsb[22] = { - {0x0733, 0x00, 0}, - {0x0734, 0xff, 0}, - {0x0716, 0x02, 0}, /* F06[7] invert spectrum 0x02 0x06 */ - {0x05e7, 0x00, 0}, - {0x05e8, 0x00, 0}, - {0x0f06, 0x80, 0}, - {0x0f09, 0x04, 0}, - {0x070c, 0x18, 0}, - {0x070d, 0x9d, 0}, - {0x070e, 0x89, 0}, - {0x070f, 0x6a, 0}, - {0x0710, 0x75, 0}, - {0x0711, 0x6f, 0}, - {0x072a, 0x02, 0}, - {0x072c, 0x02, 0}, - {0x090d, 0x03, 0}, - {0x090e, 0x02, 0}, - {0x090f, 0x00, 0}, - {0x0900, 0x01, 0}, - {0x0900, 0x00, 0}, - {0x0f00, 0x01, 0}, - {0x0000, 0x00, 1} -}; - -/* 64qam */ -static struct atsc_cfg list_qam64[111] = { - {0x0900, 0x01, 0}, - {0x0f04, 0x08, 0}, - {0x0f06, 0x80, 0}, - {0x0f07, 0x00, 0}, - {0x0f00, 0xe0, 0}, - {0x0f00, 0xec, 0}, - {0x0001, 0x05, 0}, - {0x0002, 0x61, 0}, /* /0x61 invert spectrum */ - {0x0003, 0x3e, 0}, - {0x0004, 0xed, 0}, /* 0x9d */ - {0x0005, 0x10, 0}, - {0x0006, 0xc0, 0}, - {0x0007, 0x5c, 0}, - {0x0008, 0x0f, 0}, - {0x0009, 0x4f, 0}, - {0x000a, 0xfc, 0}, - {0x000b, 0x0c, 0}, - {0x000c, 0x6c, 0}, - {0x000d, 0x3a, 0}, - {0x000e, 0x10, 0}, - {0x000f, 0x02, 0}, - {0x0011, 0x00, 0}, - {0x0012, 0xf5, 0}, - {0x0013, 0x74, 0}, - {0x0014, 0xb9, 0}, - {0x0015, 0x1f, 0}, - {0x0016, 0x80, 0}, - {0x0017, 0x1f, 0}, - {0x0018, 0x0f, 0}, - {0x001e, 0x00, 0}, - {0x001f, 0x00, 0}, - {0x0023, 0x03, 0}, - {0x0025, 0x20, 0}, - {0x0026, 0xff, 0}, - {0x0027, 0xff, 0}, - {0x0028, 0xf8, 0}, - {0x0200, 0x20, 0}, - {0x0201, 0x62, 0}, - {0x0202, 0x23, 0}, - {0x0204, 0x19, 0}, - {0x0205, 0x74, 0}, - {0x0206, 0xab, 0}, - {0x0207, 0xff, 0}, - {0x0208, 0xc0, 0}, - {0x0209, 0xff, 0}, - {0x0211, 0xc0, 0}, - {0x0212, 0xb0, 0}, - {0x0213, 0x05, 0}, - {0x0215, 0x08, 0}, - {0x0222, 0xe0, 0}, - {0x0223, 0xf0, 0}, - {0x0226, 0x40, 0}, - {0x0229, 0x23, 0}, - {0x022a, 0x02, 0}, - {0x022c, 0x01, 0}, - {0x022e, 0x01, 0}, - {0x022f, 0x25, 0}, - {0x0230, 0x40, 0}, - {0x0231, 0x01, 0}, - {0x0734, 0xff, 0}, - {0x073a, 0xff, 0}, - {0x073b, 0x04, 0}, - {0x073c, 0x08, 0}, - {0x073d, 0x08, 0}, - {0x073e, 0x01, 0}, - {0x073f, 0xf8, 0}, - {0x0740, 0xf1, 0}, - {0x0741, 0xf3, 0}, - {0x0742, 0xff, 0}, - {0x0743, 0x0f, 0}, - {0x0744, 0x1a, 0}, - {0x0745, 0x16, 0}, - {0x0746, 0x00, 0}, - {0x0747, 0xe3, 0}, - {0x0748, 0xce, 0}, - {0x0749, 0xd4, 0}, - {0x074a, 0x00, 0}, - {0x074b, 0x4b, 0}, - {0x074c, 0x00, 0}, - {0x074d, 0xa2, 0}, - {0x074e, 0x00, 0}, - {0x074f, 0xe6, 0}, - {0x0750, 0x00, 0}, - {0x0751, 0x00, 0}, - {0x0752, 0x01, 0}, - {0x0753, 0x03, 0}, - {0x0400, 0x00, 0}, - {0x0408, 0x04, 0}, - {0x040e, 0xe0, 0}, - {0x0500, 0x02, 0}, - {0x05e7, 0x00, 0}, - {0x05e8, 0x00, 0}, - {0x0f09, 0x18, 0}, - {0x070c, 0x20, 0}, - {0x070d, 0x41, 0}, /* 0x49 */ - {0x070e, 0x04, 0}, /* 0x37 */ - {0x070f, 0x00, 0}, - {0x0710, 0x00, 0}, - {0x0711, 0x00, 0}, - {0x0716, 0xf0, 0}, - {0x090f, 0x00, 0}, - {0x0900, 0x01, 1}, - {0x0900, 0x00, 0}, - {0x0001, 0xf5, 0}, - {0x0001, 0xf5, 1}, - {0x0001, 0xf5, 1}, - {0x0001, 0xf5, 1}, - {0x0001, 0xf5, 1}, - {0x0001, 0x05, 0}, - {0x0001, 0x05, 1}, - {0x0000, 0x00, 1} -}; - -/* 256qam */ -static struct atsc_cfg list_qam256[113] = { - {0x0900, 0x01, 0}, - {0x0f04, 0x08, 0}, - {0x0f06, 0x80, 0}, - {0x0f00, 0xe0, 0}, - {0x0f00, 0xec, 0}, - {0x0001, 0x05, 0}, - {0x0002, 0x01, 0}, /* 0x09 */ - {0x0003, 0x2c, 0}, - {0x0004, 0x91, 0}, - {0x0005, 0x10, 0}, - {0x0006, 0xc0, 0}, - {0x0007, 0x5c, 0}, - {0x0008, 0x0f, 0}, - {0x0009, 0x4f, 0}, - {0x000a, 0xfc, 0}, - {0x000b, 0x0c, 0}, - {0x000c, 0x6c, 0}, - {0x000d, 0x3a, 0}, - {0x000e, 0x10, 0}, - {0x000f, 0x02, 0}, - {0x0011, 0x80, 0}, - {0x0012, 0xf5, 0}, /* a5 */ - {0x0013, 0x74, 0}, - {0x0014, 0xb9, 0}, - {0x0015, 0x1f, 0}, - {0x0016, 0x80, 0}, - {0x0017, 0x1f, 0}, - {0x0018, 0x0f, 0}, - {0x001e, 0x00, 0}, - {0x001f, 0x00, 0}, - {0x0023, 0x03, 0}, - {0x0025, 0x20, 0}, - {0x0026, 0xff, 0}, - {0x0027, 0xff, 0}, - {0x0028, 0xf8, 0}, - {0x0200, 0x20, 0}, - {0x0201, 0x62, 0}, - {0x0202, 0x23, 0}, - {0x0204, 0x19, 0}, - {0x0205, 0x76, 0}, - {0x0206, 0xd2, 0}, - {0x0207, 0xff, 0}, - {0x0208, 0xc0, 0}, - {0x0209, 0xff, 0}, - {0x0211, 0xc0, 0}, - {0x0212, 0xb0, 0}, - {0x0213, 0x05, 0}, - {0x0215, 0x08, 0}, - {0x0222, 0xf0, 0}, - {0x0223, 0xff, 0}, - {0x0226, 0x40, 0}, - {0x0229, 0x23, 0}, - {0x022a, 0x02, 0}, - {0x022c, 0x01, 0}, - {0x022e, 0x01, 0}, - {0x022f, 0x05, 0}, - {0x0230, 0x40, 0}, - {0x0231, 0x01, 0}, - {0x0400, 0x02, 0}, - {0x0401, 0x30, 0}, - {0x0402, 0x13, 0}, - {0x0406, 0x06, 0}, - {0x0408, 0x04, 0}, - {0x040e, 0xe0, 0}, - {0x0411, 0x02, 0}, - {0x073a, 0x02, 0}, - {0x073b, 0x09, 0}, - {0x073c, 0x0c, 0}, - {0x073d, 0x08, 0}, - {0x073e, 0xfd, 0}, - {0x073f, 0xf2, 0}, - {0x0740, 0xed, 0}, - {0x0741, 0xf4, 0}, - {0x0742, 0x03, 0}, - {0x0743, 0x15, 0}, - {0x0744, 0x1d, 0}, - {0x0745, 0x15, 0}, - {0x0746, 0xfc, 0}, - {0x0747, 0xde, 0}, - {0x0748, 0xcc, 0}, - {0x0749, 0xd6, 0}, - {0x074a, 0x04, 0}, - {0x074b, 0x4f, 0}, - {0x074c, 0x00, 0}, - {0x074d, 0xa2, 0}, - {0x074e, 0x00, 0}, - {0x074f, 0xe3, 0}, - {0x0750, 0x00, 0}, - {0x0751, 0xfc, 0}, - {0x0752, 0x00, 0}, - {0x0753, 0x03, 0}, - {0x0500, 0x02, 0}, - {0x05e7, 0x00, 0}, - {0x05e8, 0x00, 0}, - {0x0f09, 0x18, 0}, - {0x070c, 0x20, 0}, - {0x070d, 0x49, 0}, - {0x070e, 0x37, 0}, - {0x070f, 0x00, 0}, - {0x0710, 0x00, 0}, - {0x0711, 0x00, 0}, - {0x0716, 0xf0, 0}, - {0x090f, 0x00, 0}, - {0x0900, 0x01, 1}, - {0x0900, 0x00, 0}, - {0x0001, 0xf5, 0}, - {0x0001, 0xf5, 1}, - {0x0001, 0xf5, 1}, - {0x0001, 0xf5, 1}, - {0x0001, 0xf5, 1}, - {0x0001, 0x05, 0}, - {0x0001, 0x05, 1}, - {0x0000, 0x00, 1} -}; - -void dtvpll_lock_init(void) -{ - mutex_init(&dtvpll_init_lock); -} - -void dtvpll_init_flag(int on) -{ - mutex_lock(&dtvpll_init_lock); - dtvpll_init = on; - mutex_unlock(&dtvpll_init_lock); - pr_err("%s %d\n", __func__, on); -} - -int get_dtvpll_init_flag(void) -{ - int val; - - mutex_lock(&dtvpll_init_lock); - val = dtvpll_init; - mutex_unlock(&dtvpll_init_lock); - if (!val) - pr_err("%s: %d\n", __func__, val); - return val; -} - -void adc_dpll_setup(int clk_a, int clk_b, int clk_sys) -{ - int unit, found, ena, enb, div2; - int pll_m, pll_n, pll_od_a, pll_od_b, pll_xd_a, pll_xd_b; - long freq_osc, freq_dco, freq_b, freq_a, freq_sys; - long freq_b_act, freq_a_act, freq_sys_act, err_tmp, best_err; - union adc_pll_cntl adc_pll_cntl; - union adc_pll_cntl2 adc_pll_cntl2; - union adc_pll_cntl3 adc_pll_cntl3; - union adc_pll_cntl4 adc_pll_cntl4; - union demod_dig_clk dig_clk_cfg; - - adc_pll_cntl.d32 = 0; - adc_pll_cntl2.d32 = 0; - adc_pll_cntl3.d32 = 0; - adc_pll_cntl4.d32 = 0; - - pr_dbg("target clk_a %d clk_b %d\n", clk_a, clk_b); - - unit = 10000; /* 10000 as 1 MHz, 0.1 kHz resolution. */ - freq_osc = 24 * unit; - - if (clk_a < 1000) - freq_a = clk_a * unit; - else - freq_a = clk_a * (unit / 1000); - - if (clk_b < 1000) - freq_b = clk_b * unit; - else - freq_b = clk_b * (unit / 1000); - - ena = clk_a > 0 ? 1 : 0; - enb = clk_b > 0 ? 1 : 0; - - if (ena || enb) - adc_pll_cntl3.b.enable = 1; - adc_pll_cntl3.b.reset = 1; - - found = 0; - best_err = 100 * unit; - pll_od_a = 1; - pll_od_b = 1; - pll_n = 1; - for (pll_m = 1; pll_m < 512; pll_m++) { - /* for (pll_n=1; pll_n<=5; pll_n++) { */ - if (is_meson_txl_cpu()) { - freq_dco = freq_osc * pll_m / pll_n / 2;/*txl add div2*/ - if (freq_dco < 700 * unit || freq_dco > 1000 * unit) - continue; - } else { - freq_dco = freq_osc * pll_m / pll_n; - if (freq_dco < 750 * unit || freq_dco > 1550 * unit) - continue; - } - pll_xd_a = freq_dco / (1 << pll_od_a) / freq_a; - pll_xd_b = freq_dco / (1 << pll_od_b) / freq_b; - - freq_a_act = freq_dco / (1 << pll_od_a) / pll_xd_a; - freq_b_act = freq_dco / (1 << pll_od_b) / pll_xd_b; - - err_tmp = (freq_a_act - freq_a) * ena + (freq_b_act - freq_b) * - enb; - - if (err_tmp >= best_err) - continue; - - adc_pll_cntl.b.pll_m = pll_m; - adc_pll_cntl.b.pll_n = pll_n; - adc_pll_cntl.b.pll_od0 = pll_od_b; - adc_pll_cntl.b.pll_od1 = pll_od_a; - adc_pll_cntl.b.pll_xd0 = pll_xd_b; - adc_pll_cntl.b.pll_xd1 = pll_xd_a; - if (is_meson_txl_cpu()) { - adc_pll_cntl4.b.pll_od3 = 0; - adc_pll_cntl.b.pll_od2 = 0; - } else { - adc_pll_cntl2.b.div2_ctrl = - freq_dco > 1000 * unit ? 1 : 0; - } - found = 1; - best_err = err_tmp; - /* } */ - } - - pll_m = adc_pll_cntl.b.pll_m; - pll_n = adc_pll_cntl.b.pll_n; - pll_od_b = adc_pll_cntl.b.pll_od0; - pll_od_a = adc_pll_cntl.b.pll_od1; - pll_xd_b = adc_pll_cntl.b.pll_xd0; - pll_xd_a = adc_pll_cntl.b.pll_xd1; - - if (is_meson_txl_cpu()) - div2 = 1; - else - div2 = adc_pll_cntl2.b.div2_ctrl; - /* - * p_adc_pll_cntl = adc_pll_cntl.d32; - * p_adc_pll_cntl2 = adc_pll_cntl2.d32; - * p_adc_pll_cntl3 = adc_pll_cntl3.d32; - * p_adc_pll_cntl4 = adc_pll_cntl4.d32; - */ - adc_pll_cntl3.b.reset = 0; - /* *p_adc_pll_cntl3 = adc_pll_cntl3.d32; */ - if (!found) { - pr_dbg(" ERROR can't setup %7ld kHz %7ld kHz\n", - freq_b / (unit / 1000), freq_a / (unit / 1000)); - } else { - if (is_meson_txl_cpu()) - freq_dco = freq_osc * pll_m / pll_n / 2; - else - freq_dco = freq_osc * pll_m / pll_n; - pr_dbg(" ADC PLL M %3d N %3d\n", pll_m, pll_n); - pr_dbg(" ADC PLL DCO %ld kHz\n", freq_dco / (unit / 1000)); - - pr_dbg(" ADC PLL XD %3d OD %3d\n", pll_xd_b, pll_od_b); - pr_dbg(" ADC PLL XD %3d OD %3d\n", pll_xd_a, pll_od_a); - - freq_a_act = freq_dco / (1 << pll_od_a) / pll_xd_a; - freq_b_act = freq_dco / (1 << pll_od_b) / pll_xd_b; - - pr_dbg(" B %7ld kHz %7ld kHz\n", - freq_b / (unit / 1000), freq_b_act / (unit / 1000)); - pr_dbg(" A %7ld kHz %7ld kHz\n", - freq_a / (unit / 1000), freq_a_act / (unit / 1000)); - - if (clk_sys > 0) { - dig_clk_cfg.b.demod_clk_en = 1; - dig_clk_cfg.b.demod_clk_sel = 3; - if (clk_sys < 1000) - freq_sys = clk_sys * unit; - else - freq_sys = clk_sys * (unit / 1000); - - dig_clk_cfg.b.demod_clk_div = freq_dco / (1 + div2) / - freq_sys - 1; - freq_sys_act = freq_dco / (1 + div2) / - (dig_clk_cfg.b.demod_clk_div + 1); - pr_dbg(" SYS %7ld kHz div %d+1 %7ld kHz\n", - freq_sys / (unit / 1000), - dig_clk_cfg.b.demod_clk_div, - freq_sys_act / (unit / 1000)); - } else { - dig_clk_cfg.b.demod_clk_en = 0; - } - - /* *p_demod_dig_clk = dig_clk_cfg.d32; */ - } - if (is_meson_txl_cpu()) { - demod_set_demod_reg(TXLTV_ADC_RESET_VALUE, ADC_REG3); - demod_set_demod_reg(adc_pll_cntl.d32, ADC_REG1); - demod_set_demod_reg(dig_clk_cfg.d32, ADC_REG6); - demod_set_demod_reg(TXLTV_ADC_REG3_VALUE, ADC_REG3); - /* debug */ - pr_dbg("[adc][%x]%x\n", ADC_REG1, - demod_read_demod_reg(ADC_REG1)); - pr_dbg("[adc][%x]%x\n", ADC_REG2, - demod_read_demod_reg(ADC_REG2)); - pr_dbg("[adc][%x]%x\n", ADC_REG3, - demod_read_demod_reg(ADC_REG3)); - pr_dbg("[adc][%x]%x\n", ADC_REG4, - demod_read_demod_reg(ADC_REG4)); - pr_dbg("[adc][%x]%x\n", ADC_REG5, - demod_read_demod_reg(ADC_REG5)); - pr_dbg("[adc][%x]%x\n", ADC_REG6, - demod_read_demod_reg(ADC_REG6)); - pr_dbg("[adc][%x]%x\n", ADC_REG7, - demod_read_demod_reg(ADC_REG7)); - pr_dbg("[adc][%x]%x\n", ADC_REG8, - demod_read_demod_reg(ADC_REG8)); - pr_dbg("[adc][%x]%x\n", ADC_REG9, - demod_read_demod_reg(ADC_REG9)); - pr_dbg("[adc][%x]%x\n", ADC_REGB, - demod_read_demod_reg(ADC_REGB)); - pr_dbg("[adc][%x]%x\n", ADC_REGC, - demod_read_demod_reg(ADC_REGC)); - pr_dbg("[adc][%x]%x\n", ADC_REGD, - demod_read_demod_reg(ADC_REGD)); - pr_dbg("[adc][%x]%x\n", ADC_REGE, - demod_read_demod_reg(ADC_REGE)); - pr_dbg("[demod][%x]%x\n", DEMOD_REG1, - demod_read_demod_reg(DEMOD_REG1)); - pr_dbg("[demod][%x]%x\n", DEMOD_REG2, - demod_read_demod_reg(DEMOD_REG2)); - pr_dbg("[demod][%x]%x\n", DEMOD_REG3, - demod_read_demod_reg(DEMOD_REG3)); - } else { - demod_set_demod_reg(ADC_RESET_VALUE, ADC_REG3); /* adc reset */ - demod_set_demod_reg(adc_pll_cntl.d32, ADC_REG1); - demod_set_demod_reg(dig_clk_cfg.d32, ADC_REG6); - demod_set_demod_reg(ADC_REG3_VALUE, ADC_REG3); - /* debug */ - pr_dbg("[adc][%x]%x\n", ADC_REG1, - demod_read_demod_reg(ADC_REG1)); - pr_dbg("[adc][%x]%x\n", ADC_REG2, - demod_read_demod_reg(ADC_REG2)); - pr_dbg("[adc][%x]%x\n", ADC_REG3, - demod_read_demod_reg(ADC_REG3)); - pr_dbg("[adc][%x]%x\n", ADC_REG4, - demod_read_demod_reg(ADC_REG4)); - pr_dbg("[adc][%x]%x\n", ADC_REG6, - demod_read_demod_reg(ADC_REG6)); - pr_dbg("[demod][%x]%x\n", DEMOD_REG1, - demod_read_demod_reg(DEMOD_REG1)); - pr_dbg("[demod][%x]%x\n", DEMOD_REG2, - demod_read_demod_reg(DEMOD_REG2)); - pr_dbg("[demod][%x]%x\n", DEMOD_REG3, - demod_read_demod_reg(DEMOD_REG3)); - } - dtvpll_init_flag(1); -} - -void demod_set_adc_core_clk(int adc_clk, int sys_clk, int dvb_mode) -{ - adc_dpll_setup(25, adc_clk, sys_clk); -} - -void demod_set_cbus_reg(unsigned int data, unsigned int addr) -{ - void __iomem *vaddr; - - pr_dbg("[cbus][write]%x\n", (IO_CBUS_PHY_BASE + (addr << 2))); - vaddr = ioremap((IO_CBUS_PHY_BASE + (addr << 2)), 0x4); - writel(data, vaddr); - iounmap(vaddr); -} - -unsigned int demod_read_cbus_reg(unsigned int addr) -{ -/* return __raw_readl(CBUS_REG_ADDR(addr)); */ - unsigned int tmp; - void __iomem *vaddr; - - vaddr = ioremap((IO_CBUS_PHY_BASE + (addr << 2)), 0x4); - tmp = readl(vaddr); - iounmap(vaddr); -/* tmp = aml_read_cbus(addr); */ - pr_dbg("[cbus][read]%x,data is %x\n", - (IO_CBUS_PHY_BASE + (addr << 2)), tmp); - return tmp; -} - -void demod_set_ao_reg(unsigned int data, unsigned int addr) -{ - void __iomem *vaddr; - -/* pr_dbg("[ao][write]%x,data is %x\n",(IO_AOBUS_BASE+addr),data); */ - vaddr = ioremap((IO_AOBUS_BASE + addr), 0x4); - writel(data, vaddr); - iounmap(vaddr); -} - -unsigned int demod_read_ao_reg(unsigned int addr) -{ - unsigned int tmp; - void __iomem *vaddr; - -/* pr_dbg("[ao][read]%x\n",(IO_AOBUS_BASE+addr)); */ - vaddr = ioremap((IO_AOBUS_BASE + addr), 0x4); - tmp = readl(vaddr); -/* pr_dbg("[ao][read]%x,data is %x\n",(IO_AOBUS_BASE+addr),tmp); */ - iounmap(vaddr); - return tmp; -} - -void demod_set_demod_reg(unsigned int data, unsigned int addr) -{ - void __iomem *vaddr; - - mutex_lock(&mp); -/* printk("[demod][write]%x,data is %x\n",(addr),data); */ - vaddr = ioremap((addr), 0x4); - writel(data, vaddr); - iounmap(vaddr); - mutex_unlock(&mp); -} - -unsigned int demod_read_demod_reg(unsigned int addr) -{ - unsigned int tmp; - void __iomem *vaddr; - - mutex_lock(&mp); - vaddr = ioremap((addr), 0x4); - tmp = readl(vaddr); - iounmap(vaddr); - mutex_unlock(&mp); -/* printk("[demod][read]%x,data is %x\n",(addr),tmp); */ - return tmp; -} - -void demod_power_switch(int pwr_cntl) -{ - int reg_data; -#if 1 - if (pwr_cntl == PWR_ON) { - pr_dbg("[PWR]: Power on demod_comp %x,%x\n", - AO_RTI_GEN_PWR_SLEEP0, AO_RTI_GEN_PWR_ISO0); - /* Powerup demod_comb */ - reg_data = demod_read_ao_reg(AO_RTI_GEN_PWR_SLEEP0); - demod_set_ao_reg((reg_data & (~(0x1 << 10))), - AO_RTI_GEN_PWR_SLEEP0); - /* [10] power on */ - pr_dbg("[PWR]: Power on demod_comp %x,%x\n", - HHI_DEMOD_MEM_PD_REG, RESET0_LEVEL); - /* Power up memory */ - demod_set_demod_reg((demod_read_demod_reg(HHI_DEMOD_MEM_PD_REG) - & (~0x2fff)), HHI_DEMOD_MEM_PD_REG); - /* reset */ - demod_set_demod_reg((demod_read_demod_reg(RESET0_LEVEL) & - (~(0x1 << 8))), RESET0_LEVEL); - /* msleep(20);*/ - - /* remove isolation */ - demod_set_ao_reg( - (demod_read_ao_reg(AO_RTI_GEN_PWR_ISO0) & - (~(0x3 << 14))), AO_RTI_GEN_PWR_ISO0); - /* pull up reset */ - demod_set_demod_reg((demod_read_demod_reg(RESET0_LEVEL) | - (0x1 << 8)), RESET0_LEVEL); -/* *P_RESET0_LEVEL |= (0x1<<8); */ - } else { - pr_dbg("[PWR]: Power off demod_comp\n"); - /* add isolation */ - - demod_set_ao_reg( - (demod_read_ao_reg(AO_RTI_GEN_PWR_ISO0) | - (0x3 << 14)), AO_RTI_GEN_PWR_ISO0); - - /* power down memory */ - demod_set_demod_reg((demod_read_demod_reg(HHI_DEMOD_MEM_PD_REG) - | 0x2fff), HHI_DEMOD_MEM_PD_REG); - /* power down demod_comb */ - reg_data = demod_read_ao_reg(AO_RTI_GEN_PWR_SLEEP0); - demod_set_ao_reg((reg_data | (0x1 << 10)), - AO_RTI_GEN_PWR_SLEEP0); - /* [10] power on */ - } -#endif -} - -static void clocks_set_sys_defaults(unsigned char dvb_mode) -{ - union demod_cfg0 cfg0; - union demod_cfg2 cfg2; - - demod_power_switch(PWR_ON); - - if (is_meson_gxtvbb_cpu()) { - pr_dbg("GX_TV config\n"); - demod_set_demod_reg(ADC_RESET_VALUE, ADC_REG3); - demod_set_demod_reg(ADC_REG1_VALUE, ADC_REG1); - demod_set_demod_reg(ADC_REG2_VALUE, ADC_REG2); - demod_set_demod_reg(ADC_REG4_VALUE, ADC_REG4); - demod_set_demod_reg(ADC_REG3_VALUE, ADC_REG3); - /* dadc */ - demod_set_demod_reg(ADC_REG7_VALUE, ADC_REG7); - demod_set_demod_reg(ADC_REG8_VALUE, ADC_REG8); - demod_set_demod_reg(ADC_REG9_VALUE, ADC_REG9); - demod_set_demod_reg(ADC_REGA_VALUE, ADC_REGA); - } else if (is_meson_txl_cpu()) { - pr_dbg("TXL_TV config\n"); - demod_set_demod_reg(TXLTV_ADC_REG3_VALUE, ADC_REG3); - demod_set_demod_reg(TXLTV_ADC_REG1_VALUE, ADC_REG1); - demod_set_demod_reg(TXLTV_ADC_REGB_VALUE, ADC_REGB); - demod_set_demod_reg(TXLTV_ADC_REG2_VALUE, ADC_REG2); - demod_set_demod_reg(TXLTV_ADC_REG3_VALUE, ADC_REG3); - demod_set_demod_reg(TXLTV_ADC_REG4_VALUE, ADC_REG4); - demod_set_demod_reg(TXLTV_ADC_REGC_VALUE, ADC_REGC); - demod_set_demod_reg(TXLTV_ADC_REGD_VALUE, ADC_REGD); - demod_set_demod_reg(TXLTV_ADC_RESET_VALUE, ADC_REG3); - demod_set_demod_reg(TXLTV_ADC_REG3_VALUE, ADC_REG3); - - /* dadc */ - demod_set_demod_reg(TXLTV_ADC_REG7_VALUE, ADC_REG7); - demod_set_demod_reg(TXLTV_ADC_REG8_VALUE, ADC_REG8); - demod_set_demod_reg(TXLTV_ADC_REG9_VALUE, ADC_REG9); - demod_set_demod_reg(TXLTV_ADC_REGE_VALUE, ADC_REGE); - } - - demod_set_demod_reg(DEMOD_REG1_VALUE, DEMOD_REG1); - demod_set_demod_reg(DEMOD_REG2_VALUE, DEMOD_REG2); - demod_set_demod_reg(DEMOD_REG3_VALUE, DEMOD_REG3); - cfg0.b.mode = 7; - cfg0.b.adc_format = 1; - if (dvb_mode == Gxtv_Dvbc) { /* // 0 -DVBC, 1-DVBT, ISDBT, 2-ATSC */ - cfg0.b.ts_sel = 2; - } else if ((dvb_mode == Gxtv_Dvbt_Isdbt) || (dvb_mode == Gxtv_Dtmb)) { - cfg0.b.ts_sel = 1; - cfg0.b.adc_regout = 1; - } else if (dvb_mode == Gxtv_Atsc) { - cfg0.b.ts_sel = 4; - } - demod_set_demod_reg(cfg0.d32, DEMOD_REG1); - cfg2.b.biasgen_en = 1; - cfg2.b.en_adc = 1; - demod_set_demod_reg(cfg2.d32, DEMOD_REG3); - pr_dbg("0xc8020c00 is %x,dvb_mode is %d\n", - demod_read_demod_reg(DEMOD_REG1), dvb_mode); -} - -void dtmb_write_reg(int reg_addr, int reg_data) -{ - if (!get_dtvpll_init_flag()) - return; - demod_set_demod_reg(reg_data, reg_addr); -/* apb_write_reg(reg_addr,reg_data); */ -} - -int dtmb_read_reg(int reg_addr) -{ - if (!get_dtvpll_init_flag()) - return 0; - return demod_read_demod_reg(reg_addr); /* apb_read_reg(reg_addr); */ -} - -void atsc_write_reg(int reg_addr, int reg_data) -{ - if (!get_dtvpll_init_flag()) - return; - apb_write_reg(ATSC_BASE, (reg_addr & 0xffff) << 8 | (reg_data & 0xff)); -} - -unsigned long atsc_read_reg(int reg_addr) -{ - unsigned long tmp; - - if (!get_dtvpll_init_flag()) - return 0; - apb_write_reg(ATSC_BASE + 4, (reg_addr & 0xffff) << 8); - tmp = apb_read_reg(ATSC_BASE); - - return tmp & 0xff; -} - -unsigned long atsc_read_iqr_reg(void) -{ - unsigned long tmp; - - tmp = apb_read_reg(ATSC_BASE + 8); - pr_dbg("[atsc irq] is %lx\n", tmp); - return tmp & 0xffffffff; -} - -int atsc_qam_set(fe_modulation_t mode) -{ - int i, j; - - if (mode == VSB_8) { /* 5-8vsb, 2-64qam, 4-256qam */ - for (i = 0; list_8vsb[i].adr != 0; i++) { - if (list_8vsb[i].rw) - atsc_read_reg(list_8vsb[i].adr); - /* msleep(20); */ - else - atsc_write_reg(list_8vsb[i].adr, - list_8vsb[i].dat); - /* msleep(20); */ - } - j = 15589; - pr_dbg("8-vsb mode\n"); - } else if (mode == QAM_64) { - for (i = 0; list_qam64[i].adr != 0; i++) { - if (list_qam64[i].rw) { - atsc_read_reg(list_qam64[i].adr); - msleep(20); - } else { - atsc_write_reg(list_qam64[i].adr, - list_qam64[i].dat); - msleep(20); - } - } - j = 16588; /* 33177; */ - pr_dbg("64qam mode\n"); - } else if (mode == QAM_256) { - for (i = 0; list_qam256[i].adr != 0; i++) { - if (list_qam256[i].rw) { - atsc_read_reg(list_qam256[i].adr); - msleep(20); - } else { - atsc_write_reg(list_qam256[i].adr, - list_qam256[i].dat); - msleep(20); - } - } - j = 15649; /* 31298; */ - pr_dbg("256qam mode\n"); - } else { - for (i = 0; list_qam256[i].adr != 0; i++) { - if (list_qam256[i].rw) { - atsc_read_reg(list_qam256[i].adr); - msleep(20); - } else { - atsc_write_reg(list_qam256[i].adr, - list_qam256[i].dat); - msleep(20); - } - } - j = 15649; /* 31298; */ - pr_dbg("256qam mode\n"); - } - return j; -} - -void atsc_initial(struct aml_demod_sta *demod_sta) -{ - int fc, fs, cr, ck, j; - fe_modulation_t mode; - - mode = demod_sta->ch_mode; - - j = atsc_qam_set(mode); /* set mode */ - - fs = demod_sta->adc_freq; /* KHZ 25200 */ - fc = demod_sta->ch_if; /* KHZ 6350 */ - - cr = (fc * (1 << 17) / fs) * (1 << 6); - ck = fs * j / 10 - (1 << 25); - /* ck_rate = (f_samp / f_vsb /2 -1)*(1<<25); - *double f_vsb = 10.76238;// double f_64q = 5.056941; - * // double f_256q = 5.360537; - */ - - atsc_write_reg(0x070e, cr & 0xff); - atsc_write_reg(0x070d, (cr >> 8) & 0xff); - atsc_write_reg(0x070c, (cr >> 16) & 0xff); - - if (demod_sta->ch_mode == VSB_8) { - atsc_write_reg(0x0711, ck & 0xff); - atsc_write_reg(0x0710, (ck >> 8) & 0xff); - atsc_write_reg(0x070f, (ck >> 16) & 0xff); - } - pr_dbg("0x70e is %x, 0x70d is %x, 0x70c is %x\n", cr & 0xff, - (cr >> 8) & 0xff, (cr >> 16) & 0xff); - pr_dbg("fs is %d(SR),fc is %d(IF),cr is %x,ck is %x\n", fs, fc, cr, ck); -} - -int atsc_set_ch(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c, - struct aml_demod_atsc *demod_atsc) -{ - int ret = 0; - u8 demod_mode; - u8 bw, sr, ifreq, agc_mode; - u32 ch_freq; - - bw = demod_atsc->bw; - sr = demod_atsc->sr; - ifreq = demod_atsc->ifreq; - agc_mode = demod_atsc->agc_mode; - ch_freq = demod_atsc->ch_freq; - demod_mode = demod_atsc->dat0; - demod_sta->ch_mode = demod_atsc->mode; /* TODO */ - demod_sta->agc_mode = agc_mode; - demod_sta->ch_freq = ch_freq; - demod_sta->dvb_mode = demod_mode; - demod_sta->ch_bw = (8 - bw) * 1000; - atsc_initial(demod_sta); - pr_dbg("ATSC mode\n"); - return ret; -} - -#if 0 -static dtmb_cfg_t list_dtmb_v1[99] = { - {0x00000000, 0x01, 0}, - {0x00001000, 0x02, 0}, - {0x00000000, 0x03, 0}, - {0x00000000, 0x04, 0}, - {0x00000000, 0x05, 0}, - {0x00000000, 0x06, 0}, - {0x007fffff, 0x07, 0}, - {0x0000000f, 0x08, 0}, - {0x00003000, 0x09, 0}, - {0x00000001, 0x0a, 0}, - {0x0c403006, 0x0b, 0}, - {0x44444400, 0x0c, 0}, - {0x1412c320, 0x0d, 0}, - {0x00000152, 0x10, 0}, - {0x47080137, 0x11, 0}, - {0x02200a16, 0x12, 0}, - {0x42190190, 0x13, 0}, - {0x7f807f80, 0x14, 0}, - {0x0000199a, 0x15, 0}, - {0x000a1466, 0x18, 0}, - {0x00274217, 0x1a, 0}, - {0x00131036, 0x1b, 1}, - {0x00000396, 0x1c, 0}, - {0x0037f3cc, 0x1d, 0}, - {0x00000029, 0x1e, 0}, - {0x0004f031, 0x1f, 0}, - {0x00f3cbd4, 0x20, 0}, - {0x0000007e, 0x21, 0}, - {0x23270b6a, 0x22, 0}, - {0x5f700c1b, 0x23, 0}, - {0x00133c2b, 0x24, 0}, - {0x2d3e0f12, 0x25, 0}, - {0x06363038, 0x26, 0}, - {0x060e0a3e, 0x27, 0}, - {0x0015161f, 0x28, 0}, - {0x0809031b, 0x29, 0}, - {0x181c0307, 0x2a, 0}, - {0x051f1a1b, 0x2b, 0}, - {0x00451dce, 0x2c, 0}, - {0x242fde12, 0x2d, 0}, - {0x0034e8fa, 0x2e, 0}, - {0x00000007, 0x30, 0}, - {0x16000d0c, 0x31, 0}, - {0x0000011f, 0x32, 0}, - {0x01000200, 0x33, 0}, - {0x10bbf376, 0x34, 0}, - {0x00000044, 0x35, 0}, - {0x00000000, 0x36, 0}, - {0x00000000, 0x37, 0}, - {0x00000000, 0x38, 0}, - {0x00000000, 0x39, 0}, - {0x00000031, 0x3a, 0}, - {0x4d6b0a58, 0x3b, 0}, - {0x00000c04, 0x3c, 0}, - {0x0d3b0a50, 0x3d, 0}, - {0x03140480, 0x3e, 0}, - {0x05e60452, 0x3f, 0}, - {0x05780400, 0x40, 0}, - {0x0063c025, 0x41, 0}, - {0x05050202, 0x42, 0}, - {0x5e4a0a14, 0x43, 0}, - {0x00003b42, 0x44, 0}, - {0xa53080ff, 0x45, 0}, - {0x00000000, 0x46, 0}, - {0x00133202, 0x47, 0}, - {0x01f00000, 0x48, 0}, - {0x00000000, 0x49, 0}, - {0x00000000, 0x4a, 0}, - {0x00000000, 0x4b, 0}, - {0x00000000, 0x4c, 0}, - {0x20405dc8, 0x4d, 0}, - {0x00000000, 0x4e, 0}, - {0x1f0205df, 0x4f, 0}, - {0x00001120, 0x50, 0}, - {0x4f190803, 0x51, 0}, - {0x00000000, 0x52, 0}, - {0x00000040, 0x53, 0}, - {0x00100050, 0x54, 0}, - {0x00cd1000, 0x55, 0}, - {0x00010fab, 0x56, 0}, - {0x03f0fc3f, 0x58, 0}, - {0x02005014, 0x59, 0}, - {0x01405014, 0x5a, 0}, - {0x00014284, 0x5b, 0}, - {0x00000320, 0x5c, 0}, - {0x14130e05, 0x5d, 0}, - {0x4321c963, 0x5f, 0}, - {0x624668f8, 0x60, 0}, - {0xccc08888, 0x61, 0}, - {0x13212111, 0x62, 0}, - {0x21100000, 0x63, 0}, - {0x624668f8, 0x64, 0}, - {0xccc08888, 0x65, 0}, - {0x13212111, 0x66, 0}, - {0x21100000, 0x67, 0}, - {0x624668f8, 0x68, 0}, - {0xccc08888, 0x69, 0}, - {0x0, 0x0, 0} -}; -#endif - -void dtmb_all_reset(void) -{ - int temp_data = 0; - - if (is_meson_txl_cpu()) { - dtmb_write_reg(DTMB_FRONT_AFIFO_ADC, 0x1f); - /*modified bu xiaotong*/ - dtmb_write_reg(DTMB_CHE_TPS_CONFIG, 0xc00000); - dtmb_write_reg(DTMB_CHE_EQ_CONFIG, 0x1a027719); - dtmb_write_reg(DTMB_FRONT_AGC_CONFIG1, 0x101a7); - dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x131a31); - /*detect 64qam 420 595 problems*/ - dtmb_write_reg(DTMB_FRONT_19_CONFIG, 0x300); - dtmb_write_reg(DTMB_FRONT_4d_CONFIG, 0x12ffbe0); - /*fix fsm b bug*/ - dtmb_write_reg(DTMB_FRONT_DEBUG_CFG, 0x5680000); - /*fix agc problem,skip warm_up status*/ - dtmb_write_reg(DTMB_FRONT_46_CONFIG, 0x1a000f0f); - dtmb_write_reg(DTMB_FRONT_ST_FREQ, 0xf2400000); - } else { - dtmb_write_reg(DTMB_FRONT_AGC_CONFIG1, 0x10127); - dtmb_write_reg(DTMB_CHE_IBDFE_CONFIG6, 0x943228cc); - dtmb_write_reg(DTMB_CHE_IBDFE_CONFIG7, 0xc09aa8cd); - dtmb_write_reg(DTMB_CHE_FD_TD_COEFF, 0x0); - dtmb_write_reg(DTMB_CHE_EQ_CONFIG, 0x9dc59); - /*0x2 is auto,0x406 is invert spectrum*/ - if (dtmb_spectrum == 0) - dtmb_write_reg(DTMB_TOP_CTRL_TPS, 0x406); - else if (dtmb_spectrum == 1) - dtmb_write_reg(DTMB_TOP_CTRL_TPS, 0x402); - else - dtmb_write_reg(DTMB_TOP_CTRL_TPS, 0x2); - - pr_dbg("dtmb_spectrum is %d\n", dtmb_spectrum); - dtmb_write_reg(DTMB_TOP_CTRL_FEC, 0x41444400); - dtmb_write_reg(DTMB_TOP_CTRL_INTLV_TIME, 0x180300); - dtmb_write_reg(DTMB_FRONT_DDC_BYPASS, 0x662ca0); - dtmb_write_reg(DTMB_FRONT_AFIFO_ADC, 0x29); - dtmb_write_reg(DTMB_FRONT_DC_HOLD, 0xa1066); - /*cci para*/ - dtmb_write_reg(DTMB_CHE_M_CCI_THR_CONFIG3, 0x80201f6); - dtmb_write_reg(DTMB_CHE_M_CCI_THR_CONFIG2, 0x3f20080); - dtmb_write_reg(DTMB_CHE_TPS_CONFIG, 0xc00000); - dtmb_write_reg(DTMB_TOP_CTRL_AGC, 0x3); - dtmb_write_reg(DTMB_TOP_CTRL_TS_SFO_CFO, 0x20403006); - dtmb_write_reg(DTMB_FRONT_AGC_CONFIG2, 0x7200a16); - dtmb_write_reg(DTMB_FRONT_DEBUG_CFG, 0x1e00000); - dtmb_write_reg(DTMB_TOP_CTRL_ENABLE, 0x7fffff); - /*close ts3 timing loop*/ - dtmb_write_reg(DTMB_TOP_CTRL_DAGC_CCI, 0x305); - /*dektec card issue,close f case snr drop*/ - dtmb_write_reg(DTMB_CHE_MC_SC_TIMING_POWTHR, 0xc06100a); - if (demod_enable_performance) { - dtmb_write_reg(DTMB_CHE_IBDFE_CONFIG1, 0x4040002); - temp_data = dtmb_read_reg(DTMB_CHE_FD_TD_COEFF); - temp_data = (temp_data & ~0x3fff)|(0x241f & 0x3fff); - temp_data = temp_data | (1<<21); - /*Set freeze_mode and reset coeff*/ - dtmb_write_reg(DTMB_CHE_FD_TD_COEFF, temp_data); - temp_data = temp_data & ~(1<<21); - /*Set freeze_mode and reset coeff*/ - dtmb_write_reg(DTMB_CHE_FD_TD_COEFF, temp_data); - } - } -} - -void dtmb_initial(struct aml_demod_sta *demod_sta) -{ -/* dtmb_write_reg(0x049, memstart); //only for init */ - dtmb_spectrum = 1; - dtmb_spectrum = demod_sta->spectrum; - dtmb_register_reset(); - dtmb_all_reset(); -#if 0 - int i; - - for (i = 0; list_dtmb_v1[i].adr != 0; i++) { - if (list_dtmb_v1[i].rw) - apb_read_reg(DTMB_BASE + ((list_dtmb_v1[i].adr) << 2)); - /* msleep(20); */ - else - apb_write_reg(DTMB_BASE + ((list_dtmb_v1[i].adr) << 2), - list_dtmb_v1[i].dat); - /* msleep(20); */ - } -#endif -} - -int check_dtmb_fec_lock(void) -{ - int fec_lock, snr, status; - - fec_lock = (dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR) >> 14) & 0x1; - snr = dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR) & 0x3fff; - if (fec_lock && (snr > 4)) - status = 1; - else - status = 0; - return status; -} - -int check_dtmb_mobile_det(void) -{ - int mobile_det = 0; - - mobile_det = (dtmb_read_reg(DTMB_TOP_CTRL_SYS_OFDM_CNT) >> 8) & 0x7ffff; - return mobile_det; - -} - - -int dtmb_information(void) -{ - int tps, snr, fec_lock, fec_bch_add, fec_ldpc_unc_acc, fec_ldpc_it_avg, - tmp, che_snr; - struct aml_fe_dev *dev; - - dev = NULL; - tps = dtmb_read_reg(DTMB_TOP_CTRL_CHE_WORKCNT); - tmp = dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR); - if (is_meson_txl_cpu()) - che_snr = tmp & 0x3fff; - else - che_snr = tmp & 0xfff; - snr = che_snr; - snr = convert_snr(snr); - /* if (che_snr >= 8192) */ - /* che_snr = che_snr - 16384;*/ - /* snr = che_snr / 32;*/ - /* snr = 10*log10(snr)-6; */ - fec_lock = (dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR) >> 14) & 0x1; - fec_bch_add = dtmb_read_reg(DTMB_TOP_FEC_BCH_ACC); - fec_ldpc_unc_acc = dtmb_read_reg(DTMB_TOP_FEC_LDPC_UNC_ACC); - fec_ldpc_it_avg = dtmb_read_reg(DTMB_TOP_FEC_LDPC_IT_AVG); - pr_dbg("¡ŸFSM ¡¿: %x %x %x %x\n", - dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0), - dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE1), - dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE2), - dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE3)); - pr_dbg - ("¡ŸAGC ¡¿: agc_power %d,agc_if_gain %d,agc_rf_gain %d,", - (-(((dtmb_read_reg(DTMB_TOP_FRONT_AGC) >> 22) & 0x3ff) / 16)), - ((dtmb_read_reg(DTMB_TOP_FRONT_AGC)) & 0x3ff), - ((dtmb_read_reg(DTMB_TOP_FRONT_AGC) >> 11) & 0x7ff)); - pr_dbg - ("dagc_power %3d,dagc_gain %3d mobi_det_power %d\n", - ((dtmb_read_reg(DTMB_TOP_FRONT_DAGC) >> 0) & 0xff), - ((dtmb_read_reg(DTMB_TOP_FRONT_DAGC) >> 8) & 0xfff), - (dtmb_read_reg(DTMB_TOP_CTRL_SYS_OFDM_CNT) >> 8) & 0x7ffff); - pr_dbg - ("¡ŸTPS ¡¿ SC or MC %2d,f_r %2d qam_nr %2d ", - (dtmb_read_reg(DTMB_TOP_CHE_OBS_STATE1) >> 1) & 0x1, - (tps >> 22) & 0x1, (tps >> 21) & 0x1); - pr_dbg - ("intlv %2d,cr %2d constl %2d\n", - (tps >> 20) & 0x1, - (tps >> 18) & 0x3, (tps >> 16) & 0x3); - - pr_dbg - ("[dtmb] snr is %d,fec_lock is %d,fec_bch_add is %d,", - snr, fec_lock, fec_bch_add); - pr_dbg - ("fec_ldpc_unc_acc is %d ,fec_ldpc_it_avg is %d\n", - fec_ldpc_unc_acc, - fec_ldpc_it_avg / 256); - pr_dbg - ("------------------------------------------------------------\n"); - - tuner_get_ch_power(dev); - - return 0; -} - -int dtmb_check_cci(void) -{ - int cci_det = 0; - - cci_det = - ((dtmb_read_reg(DTMB_TOP_SYNC_CCI_NF2_POSITION) >> 22) - & 0x3); - if (cci_det > 0) { - pr_dbg("find cci\n"); - dtmb_write_reg(DTMB_CHE_CCIDET_CONFIG, 0x20210290); - dtmb_write_reg(DTMB_CHE_M_CCI_THR_CONFIG3, 0x20081f6); - dtmb_write_reg(DTMB_CHE_M_CCI_THR_CONFIG2, 0x3f08020); - } - return cci_det; -} - -int dtmb_bch_check(void) -{ - int fec_bch_add, i; - - fec_bch_add = dtmb_read_reg(DTMB_TOP_FEC_BCH_ACC); - pr_dbg("[debug]fec lock,fec_bch_add is %d\n", fec_bch_add); - msleep(100); - if (((dtmb_read_reg(DTMB_TOP_FEC_BCH_ACC))-fec_bch_add) >= 50) { - pr_dbg("[debug]fec lock,but bch add ,need reset,wait not to reset\n"); - dtmb_reset(); - for (i = 0; i < 30; i++) { - msleep(100); - if (check_dtmb_fec_lock() == 1) { - pr_dbg("[debug]fec lock,but bch add ,need reset,now is lock\n"); - return 0; - } - } - } - return 0; -} - -int dtmb_constell_check(void) -{ - int constell; - - constell = dtmb_read_reg(DTMB_TOP_CTRL_CHE_WORKCNT)>>16 & 0x3; - if (constell == 0)/*4qam*/ - dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x133221); - else if (constell == 1)/*16qam*/ - dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x132821); - else if (constell == 2)/*32qam*/ - dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x131e21); - else if (constell == 3)/*64qam*/ - dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x131a31); - - return 0; -} - - -int dtmb_check_fsm(void) -{ - int tmp, fsm_status, i, has_singnal; - - tmp = dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0); - fsm_status = tmp&0xffffffff; - has_singnal = 0; - pr_dbg("[rsj1] fsm_status is %x\n", fsm_status); - for (i = 0 ; i < 8 ; i++) { - if (((fsm_status >> (i*4)) & 0xf) > 3) { - /*has signal*/ - /* pr_dbg("has signal\n");*/ - has_singnal = 1; - } - } - return has_singnal; - -} - -int patch_ts3(int delay1_us, int delay2_us) -{ - if (((dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0)&0xf) == 0x7)&1) { - dtmb_write_reg(DTMB_TOP_CTRL_FSM, 0x300f); - dtmb_write_reg(DTMB_TOP_CTRL_FSM, 0x310f); - msleep(delay1_us); - dtmb_write_reg(DTMB_TOP_CTRL_ENABLE, 0xffdfff); - dtmb_write_reg(DTMB_TOP_CTRL_ENABLE, 0xffffff); - dtmb_write_reg(DTMB_TOP_CTRL_FSM, 0x3110); - dtmb_write_reg(DTMB_TOP_CTRL_FSM, 0x3010); - dtmb_write_reg(DTMB_TOP_CTRL_FSM, 0x3000); - return 1; - } else - return 0; -} - - -int read_cfo_all(void) -{ - int icfo_all, fcfo_all; - - icfo_all = dtmb_read_reg(DTMB_TOP_CTRL_ICFO_ALL) & 0xfffff; - fcfo_all = dtmb_read_reg(DTMB_TOP_CTRL_FCFO_ALL) & 0x3fff; - if (icfo_all > (1 << 19)) - icfo_all = icfo_all - (1 << 20); - if (fcfo_all > (1 << 13)) - fcfo_all = fcfo_all - (1 << 14); - - return (int)(icfo_all*4+fcfo_all); - -} - - -int dtmb_v3_soft_sync(int cfo_init) -{ - -/* int cfo_all;*/ -/* int cfo_setting;*/ - - if (cfo_init == 0) { - cfo_init = patch_ts3(11, 0); - #if 0 - if (cfo_init == 1) { - cfo_all = read_cfo_all(); - cfo_setting = dtmb_read_reg(DTMB_FRONT_DDC_BYPASS); - dtmb_write_reg(DTMB_FRONT_DDC_BYPASS, - cfo_setting+cfo_all); - dtmb_write_reg(DTMB_TOP_CTRL_LOOP, 0x3); - dtmb_reset(); - } - #endif - } - return cfo_init; - -} - -int dtmb_check_status_gxtv(struct dvb_frontend *fe) -{ - int local_state; - int time_cnt;/* cci_det, src_config;*/ - int cfo_init, count; - - dtmb_information(); - time_cnt = 0; - local_state = 0; - cfo_init = 0; - if (check_dtmb_fec_lock() != 1) { - dtmb_register_reset(); - dtmb_all_reset(); - count = 15; - while ((count) && - ((dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0)&0xf) < 0x6)) { - msleep(20); - count--; - } - - count = demod_sync_count; - while ((count) && (cfo_init == 0)) { - - cfo_init = dtmb_v3_soft_sync(cfo_init); - - msleep(demod_sync_delay_time); - count--; - } - if ((cfo_init == 0) && - ((dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0)&0xf) <= 7)) { - pr_dbg("over 400ms,status is %x, need reset\n", - (dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0)&0xf)); - return 0; - } - while ((time_cnt < 10) && (check_dtmb_fec_lock() != 1)) { - msleep(demod_timeout); - time_cnt++; - local_state = AMLOGIC_DTMB_STEP3; - dtmb_information(); - dtmb_check_cci(); - if (time_cnt > 8) - pr_dbg - ("* local_state = %d\n", local_state); - } - if (time_cnt >= 10 && (check_dtmb_fec_lock() != 1)) { - local_state = AMLOGIC_DTMB_STEP4; - time_cnt = 0; - pr_dbg - ("*all reset,timeout is %d\n", demod_timeout); - } - } else { - dtmb_check_cci(); - dtmb_bch_check(); - #if 0 - cci_det = dtmb_check_cci(); - if ((check_dtmb_mobile_det() <= demod_mobile_power) - && (cci_det == 0)) { - /* open */ - src_config = (dtmb_read_reg(DTMB_FRONT_SRC_CONFIG1)); - dtmb_write_reg(DTMB_FRONT_SRC_CONFIG1, - src_config & (~(0x1 << 28))); - } else { - /* close */ - src_config = (dtmb_read_reg(DTMB_FRONT_SRC_CONFIG1)); - dtmb_write_reg(DTMB_FRONT_SRC_CONFIG1, - src_config | (0x1 << 28)); - } - #endif - } - if (check_dtmb_fec_lock() == 1) - dtmb_write_reg(DTMB_TOP_CTRL_LOOP, 0xf); - return 0; -} - - -int dtmb_check_status_txl(struct dvb_frontend *fe) -{ - int time_cnt; - - time_cnt = 0; - dtmb_information(); - if (check_dtmb_fec_lock() != 1) { - while ((time_cnt < 10) && (check_dtmb_fec_lock() != 1)) { - msleep(demod_timeout); - time_cnt++; - dtmb_information(); - if (((dtmb_read_reg(DTMB_TOP_CTRL_CHE_WORKCNT) - >> 21) & 0x1) == 0x1) { - pr_dbg("4qam-nr,need set spectrum\n"); - if (dtmb_spectrum == 1) { - dtmb_write_reg - (DTMB_TOP_CTRL_TPS, 0x1010406); - } else if (dtmb_spectrum == 0) { - dtmb_write_reg - (DTMB_TOP_CTRL_TPS, 0x1010402); - } else { - dtmb_write_reg - (DTMB_TOP_CTRL_TPS, 0x1010002); - } - } - if (time_cnt > 8) - pr_dbg - ("* time_cnt = %d\n", time_cnt); - } - if (time_cnt >= 10 && (check_dtmb_fec_lock() != 1)) { - time_cnt = 0; - dtmb_register_reset(); - dtmb_all_reset(); - if (dtmb_spectrum == 0) - dtmb_spectrum = 1; - else - dtmb_spectrum = 0; - pr_dbg - ("*all reset,timeout is %d\n", demod_timeout); - } - } else { - dtmb_bch_check(); - dtmb_constell_check(); - } - return 0; -} - - -void dtmb_reset(void) -{ - union DTMB_TOP_CTRL_SW_RST_BITS sw_rst; - - sw_rst.b.ctrl_sw_rst = 1; - sw_rst.b.ctrl_sw_rst_noreg = 1; - dtmb_write_reg(DTMB_TOP_CTRL_SW_RST, sw_rst.d32); - sw_rst.b.ctrl_sw_rst = 0; - sw_rst.b.ctrl_sw_rst_noreg = 0; - dtmb_write_reg(DTMB_TOP_CTRL_SW_RST, sw_rst.d32); -} - -void dtmb_register_reset(void) -{ - union DTMB_TOP_CTRL_SW_RST_BITS sw_rst; - - sw_rst.b.ctrl_sw_rst = 1; - dtmb_write_reg(DTMB_TOP_CTRL_SW_RST, sw_rst.d32); - sw_rst.b.ctrl_sw_rst = 0; - dtmb_write_reg(DTMB_TOP_CTRL_SW_RST, sw_rst.d32); -} - -int dtmb_set_ch(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c, - struct aml_demod_dtmb *demod_dtmb) -{ - int ret = 0; - u8 demod_mode; - u8 bw, sr, ifreq, agc_mode; - u32 ch_freq; - - bw = demod_dtmb->bw; - sr = demod_dtmb->sr; - ifreq = demod_dtmb->ifreq; - agc_mode = demod_dtmb->agc_mode; - ch_freq = demod_dtmb->ch_freq; - demod_mode = demod_dtmb->dat0; - demod_sta->ch_mode = demod_dtmb->mode; /* TODO */ - demod_sta->agc_mode = agc_mode; - demod_sta->ch_freq = ch_freq; - demod_sta->dvb_mode = demod_mode; - demod_sta->ch_bw = (8 - bw) * 1000; - dtmb_initial(demod_sta); - pr_dbg("DTMB mode\n"); - return ret; -} - -int dvbt_set_ch(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c, - struct aml_demod_dvbt *demod_dvbt) -{ - int ret = 0; - u8_t demod_mode = 1; - u8_t bw, sr, ifreq, agc_mode; - u32_t ch_freq; - - bw = demod_dvbt->bw; - sr = demod_dvbt->sr; - ifreq = demod_dvbt->ifreq; - agc_mode = demod_dvbt->agc_mode; - ch_freq = demod_dvbt->ch_freq; - demod_mode = demod_dvbt->dat0; - if (ch_freq < 1000 || ch_freq > 900000000) { - /* pr_dbg("Error: Invalid Channel Freq option %d\n", - *ch_freq); - */ - ch_freq = 474000; - ret = -1; - } - - if (demod_mode < 0 || demod_mode > 4) { - /* pr_dbg("Error: Invalid demod mode option %d\n", - *demod_mode); - */ - demod_mode = 1; - ret = -1; - } - - /* demod_sta->dvb_mode = 1; */ - demod_sta->ch_mode = 0; /* TODO */ - demod_sta->agc_mode = agc_mode; - demod_sta->ch_freq = ch_freq; - demod_sta->dvb_mode = demod_mode; - /* if (demod_i2c->tuner == 1) - * demod_sta->ch_if = 36130; - * else if (demod_i2c->tuner == 2) - * demod_sta->ch_if = 4570; - * else if (demod_i2c->tuner == 3) - * demod_sta->ch_if = 4000;// It is nouse.(alan) - * else if (demod_i2c->tuner == 7) - * demod_sta->ch_if = 5000;//silab 5000kHz IF - */ - - demod_sta->ch_bw = (8 - bw) * 1000; - demod_sta->symb_rate = 0; /* TODO */ - -/* bw=0; */ - demod_mode = 1; - /* for si2176 IF:5M sr 28.57 */ - sr = 4; - ifreq = 4; - if (bw == BANDWIDTH_AUTO) - demod_mode = 2; - ofdm_initial(bw, - /* 00:8M 01:7M 10:6M 11:5M */ - sr, - /* 00:45M 01:20.8333M 10:20.7M 11:28.57 100:24m */ - ifreq, - /* 000:36.13M 001:-5.5M 010:4.57M 011:4M 100:5M */ - demod_mode - 1, - /* 00:DVBT,01:ISDBT */ - 1 - /* 0: Unsigned, 1:TC */ - ); - pr_dbg("DVBT/ISDBT mode\n"); - - return ret; -} - -int demod_set_sys(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c, - struct aml_demod_sys *demod_sys) -{ -/* int adc_clk; */ -/* demod_sta->tmp=Adc_mode; */ - unsigned char dvb_mode; - int clk_adc, clk_dem; - int gpioDV_2; - int gpiW_2; - - dvb_mode = demod_sta->dvb_mode; - clk_adc = demod_sys->adc_clk; - clk_dem = demod_sys->demod_clk; - pr_dbg - ("demod_set_sys,clk_adc is %d,clk_demod is %d\n", - clk_adc, clk_dem); - mutex_init(&mp); - clocks_set_sys_defaults(dvb_mode); - /* open dtv adc pinmux */ - if (is_meson_txl_cpu()) { - gpioDV_2 = demod_read_demod_reg(0xc8834400 + (0x2e << 2)); - pr_dbg("[R840]set adc pinmux,gpioDV_2 %x\n", gpioDV_2); - gpioDV_2 = gpioDV_2 | (0x1 << 22); - gpioDV_2 = gpioDV_2 & ~(0x3 << 19); - gpioDV_2 = gpioDV_2 & ~(0x1 << 23); - gpioDV_2 = gpioDV_2 & ~(0x1 << 31); - demod_set_demod_reg(gpioDV_2, 0xc8834400 + (0x2e << 2)); - pr_dbg("[R840]set adc pinmux,gpioDV_2 %x\n", gpioDV_2); - } else { - gpiW_2 = demod_read_demod_reg(0xc88344c4); - gpiW_2 = gpiW_2 | (0x1 << 25); - gpiW_2 = gpiW_2 & ~(0xd << 24); - demod_set_demod_reg(gpiW_2, 0xc88344c4); - pr_dbg("[R840]set adc pinmux,gpiW_2 %x\n", gpiW_2); - } - /* set adc clk */ - demod_set_adc_core_clk(clk_adc, clk_dem, dvb_mode); - /* init for dtmb */ - if (dvb_mode == Gxtv_Dtmb) { - /* open arbit */ - /* demod_set_demod_reg(0x8, DEMOD_REG4);*/ - } - demod_sta->adc_freq = clk_adc; - demod_sta->clk_freq = clk_dem; - return 0; -} - -void demod_set_reg(struct aml_demod_reg *demod_reg) -{ - switch (demod_reg->mode) { - case 0: - demod_reg->addr = demod_reg->addr + QAM_BASE; - break; - case 1: - case 2: - demod_reg->addr = DTMB_TOP_ADDR(demod_reg->addr); - break; - case 3: - /* demod_reg->addr=ATSC_BASE; */ - break; - case 4: - demod_reg->addr = demod_reg->addr * 4 + DEMOD_CFG_BASE; - break; - case 5: - demod_reg->addr = demod_reg->addr + DEMOD_BASE; - break; - case 6: - /* demod_reg->addr=demod_reg->addr*4+DEMOD_CFG_BASE; */ - break; - case 11: - demod_reg->addr = demod_reg->addr; - break; - case 10: - /* demod_reg->addr=(u32_t)phys_to_virt(demod_reg->addr); */ - break; - } - - if (demod_reg->mode == 3) - atsc_write_reg(demod_reg->addr, demod_reg->val); - else if (demod_reg->mode == 11) - demod_set_cbus_reg(demod_reg->val, demod_reg->addr); - else if (demod_reg->mode == 10) - apb_write_reg_collect(demod_reg->addr, demod_reg->val); - /* demod_reg->val_high = apb_read_reg_high(demod_reg->addr); */ - else - demod_set_demod_reg(demod_reg->val, demod_reg->addr); -} - -void demod_get_reg(struct aml_demod_reg *demod_reg) -{ - if (demod_reg->mode == 0) { - demod_reg->addr = demod_reg->addr + QAM_BASE; - } else if ((demod_reg->mode == 1) || (demod_reg->mode == 2)) { - demod_reg->addr = DTMB_TOP_ADDR(demod_reg->addr); - } else if (demod_reg->mode == 3) { - /* demod_reg->addr=demod_reg->addr+ATSC_BASE; */ - } else if (demod_reg->mode == 4) { - demod_reg->addr = demod_reg->addr * 4 + DEMOD_CFG_BASE; - } else if (demod_reg->mode == 5) { - demod_reg->addr = demod_reg->addr + DEMOD_BASE; - } else if (demod_reg->mode == 6) { - /* demod_reg->addr=demod_reg->addr*4+DEMOD_CFG_BASE; */ - } else if (demod_reg->mode == 11) { - demod_reg->addr = demod_reg->addr; - } else if (demod_reg->mode == 10) { - /* printk("demod_reg->addr is %x\n",demod_reg->addr); */ - /* test=(unsigned long)phys_to_virt(test); */ -/* demod_reg->addr=(unsigned long)phys_to_virt(demod_reg->addr); */ -/* printk("demod_reg->addr is %lx %x\n",test,demod_reg->addr); */ - } - - if (demod_reg->mode == 3) { - demod_reg->val = atsc_read_reg(demod_reg->addr); - /* apb_write_reg(ATSC_BASE+4, (demod_reg->addr&0xffff)<<8); */ - /* demod_reg->val = apb_read_reg(ATSC_BASE)&0xff; */ - } else if (demod_reg->mode == 6) { - demod_reg->val = atsc_read_iqr_reg(); - /* apb_write_reg(ATSC_BASE+4, (demod_reg->addr&0xffff)<<8); */ - /* demod_reg->val = apb_read_reg(ATSC_BASE)&0xff; */ - } else if (demod_reg->mode == 11) { - demod_reg->val = demod_read_cbus_reg(demod_reg->addr); - } else if (demod_reg->mode == 10) { - demod_reg->val = apb_read_reg_collect(demod_reg->addr); - /* demod_reg->val_high = apb_read_reg_high(demod_reg->addr);*/ - } else { - demod_reg->val = demod_read_demod_reg(demod_reg->addr); - } -} - -void apb_write_reg_collect(unsigned int addr, unsigned int data) -{ - writel(data, ((void __iomem *)(phys_to_virt(addr)))); -/* *(volatile unsigned int*)addr = data; */ -} - -unsigned long apb_read_reg_collect(unsigned long addr) -{ - unsigned long tmp; -/* void __iomem *vaddr; - * vaddr = ioremap(((unsigned long)phys_to_virt(addr)), 0x4); - * tmp = readl(vaddr); - * iounmap(vaddr); - */ - tmp = readl((void __iomem *)(phys_to_virt(addr))); -/*tmp = *(volatile unsigned long *)((unsigned long)phys_to_virt(addr));*/ -/* printk("[all][read]%lx,data is %lx\n",addr,tmp); */ - return tmp & 0xffffffff; -} - - - -void apb_write_reg(unsigned int addr, unsigned int data) -{ - demod_set_demod_reg(data, addr); -} - -unsigned long apb_read_reg_high(unsigned long addr) -{ - unsigned long tmp; - - tmp = 0; - return (tmp >> 32) & 0xffffffff; -} - -unsigned long apb_read_reg(unsigned long addr) -{ - return demod_read_demod_reg(addr); -} - -void apb_write_regb(unsigned long addr, int index, unsigned long data) -{ - /*to achieve write func*/ -} - -void enable_qam_int(int idx) -{ - unsigned long mask; - - mask = apb_read_reg(QAM_BASE + 0xd0); - mask |= (1 << idx); - apb_write_reg(QAM_BASE + 0xd0, mask); -} - -void disable_qam_int(int idx) -{ - unsigned long mask; - - mask = apb_read_reg(QAM_BASE + 0xd0); - mask &= ~(1 << idx); - apb_write_reg(QAM_BASE + 0xd0, mask); -} - -char *qam_int_name[] = { " ADC", - " Symbol", - " RS", - " In_Sync0", - " In_Sync1", - " In_Sync2", - " In_Sync3", - " In_Sync4", - "Out_Sync0", - "Out_Sync1", - "Out_Sync2", - "Out_Sync3", - "Out_Sync4", - "In_SyncCo", - "OutSyncCo", - " In_Dagc", - " Out_Dagc", - " Eq_Mode", - "RS_Uncorr" -}; - -#define OFDM_INT_STS 0 -#define OFDM_INT_EN 0 - -void enable_ofdm_int(int ofdm_irq) -{ - -} - -void disable_ofdm_int(int ofdm_irq) -{ - -} - -char *ofdm_int_name[] = { "PFS_FCFO", - "PFS_ICFO", - " CS_FCFO", - " PFS_SFO", - " PFS_TPS", - " SP", - " CCI", - " Symbol", - " In_Sync", - "Out_Sync", - "FSM Stat" -}; - -unsigned long read_ofdm_int(void) -{ - - return 0; -} - -#define PHS_LOOP_OPEN - -void qam_read_all_regs(void) -{ - -} - -void ini_icfo_pn_index(int mode) -{ /* 00:DVBT,01:ISDBT */ - if (mode == 0) { - apb_write_reg(DVBT_BASE + 0x3f8, 0x00000031); - apb_write_reg(DVBT_BASE + 0x3fc, 0x00030000); - apb_write_reg(DVBT_BASE + 0x3f8, 0x00000032); - apb_write_reg(DVBT_BASE + 0x3fc, 0x00057036); - apb_write_reg(DVBT_BASE + 0x3f8, 0x00000033); - apb_write_reg(DVBT_BASE + 0x3fc, 0x0009c08d); - apb_write_reg(DVBT_BASE + 0x3f8, 0x00000034); - apb_write_reg(DVBT_BASE + 0x3fc, 0x000c90c0); - apb_write_reg(DVBT_BASE + 0x3f8, 0x00000035); - apb_write_reg(DVBT_BASE + 0x3fc, 0x001170ff); - apb_write_reg(DVBT_BASE + 0x3f8, 0x00000036); - apb_write_reg(DVBT_BASE + 0x3fc, 0x0014d11a); - } else if (mode == 1) { - apb_write_reg(DVBT_BASE + 0x3f8, 0x00000031); - apb_write_reg(DVBT_BASE + 0x3fc, 0x00085046); - apb_write_reg(DVBT_BASE + 0x3f8, 0x00000032); - apb_write_reg(DVBT_BASE + 0x3fc, 0x0019a0e9); - apb_write_reg(DVBT_BASE + 0x3f8, 0x00000033); - apb_write_reg(DVBT_BASE + 0x3fc, 0x0024b1dc); - apb_write_reg(DVBT_BASE + 0x3f8, 0x00000034); - apb_write_reg(DVBT_BASE + 0x3fc, 0x003b3313); - apb_write_reg(DVBT_BASE + 0x3f8, 0x00000035); - apb_write_reg(DVBT_BASE + 0x3fc, 0x0048d409); - apb_write_reg(DVBT_BASE + 0x3f8, 0x00000036); - apb_write_reg(DVBT_BASE + 0x3fc, 0x00527509); - } -} - -static int coef[] = { - 0xf900, 0xfe00, 0x0000, 0x0000, 0x0100, 0x0100, 0x0000, 0x0000, - 0xfd00, 0xf700, 0x0000, 0x0000, 0x4c00, 0x0000, 0x0000, 0x0000, - 0x2200, 0x0c00, 0x0000, 0x0000, 0xf700, 0xf700, 0x0000, 0x0000, - 0x0300, 0x0900, 0x0000, 0x0000, 0x0600, 0x0600, 0x0000, 0x0000, - 0xfc00, 0xf300, 0x0000, 0x0000, 0x2e00, 0x0000, 0x0000, 0x0000, - 0x3900, 0x1300, 0x0000, 0x0000, 0xfa00, 0xfa00, 0x0000, 0x0000, - 0x0100, 0x0200, 0x0000, 0x0000, 0xf600, 0x0000, 0x0000, 0x0000, - 0x0700, 0x0700, 0x0000, 0x0000, 0xfe00, 0xfb00, 0x0000, 0x0000, - 0x0900, 0x0000, 0x0000, 0x0000, 0x3200, 0x1100, 0x0000, 0x0000, - 0x0400, 0x0400, 0x0000, 0x0000, 0xfe00, 0xfb00, 0x0000, 0x0000, - 0x0e00, 0x0000, 0x0000, 0x0000, 0xfb00, 0xfb00, 0x0000, 0x0000, - 0x0100, 0x0200, 0x0000, 0x0000, 0xf400, 0x0000, 0x0000, 0x0000, - 0x3900, 0x1300, 0x0000, 0x0000, 0x1700, 0x1700, 0x0000, 0x0000, - 0xfc00, 0xf300, 0x0000, 0x0000, 0x0c00, 0x0000, 0x0000, 0x0000, - 0x0300, 0x0900, 0x0000, 0x0000, 0xee00, 0x0000, 0x0000, 0x0000, - 0x2200, 0x0c00, 0x0000, 0x0000, 0x2600, 0x2600, 0x0000, 0x0000, - 0xfd00, 0xf700, 0x0000, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, - 0xf900, 0xfe00, 0x0000, 0x0000, 0x0400, 0x0b00, 0x0000, 0x0000, - 0xf900, 0x0000, 0x0000, 0x0000, 0x0700, 0x0200, 0x0000, 0x0000, - 0x2100, 0x2100, 0x0000, 0x0000, 0x0200, 0x0700, 0x0000, 0x0000, - 0xf900, 0x0000, 0x0000, 0x0000, 0x0b00, 0x0400, 0x0000, 0x0000, - 0xfe00, 0xf900, 0x0000, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, - 0xf700, 0xfd00, 0x0000, 0x0000, 0x2600, 0x2600, 0x0000, 0x0000, - 0x0c00, 0x2200, 0x0000, 0x0000, 0xee00, 0x0000, 0x0000, 0x0000, - 0x0900, 0x0300, 0x0000, 0x0000, 0x0c00, 0x0000, 0x0000, 0x0000, - 0xf300, 0xfc00, 0x0000, 0x0000, 0x1700, 0x1700, 0x0000, 0x0000, - 0x1300, 0x3900, 0x0000, 0x0000, 0xf400, 0x0000, 0x0000, 0x0000, - 0x0200, 0x0100, 0x0000, 0x0000, 0xfb00, 0xfb00, 0x0000, 0x0000, - 0x0e00, 0x0000, 0x0000, 0x0000, 0xfb00, 0xfe00, 0x0000, 0x0000, - 0x0400, 0x0400, 0x0000, 0x0000, 0x1100, 0x3200, 0x0000, 0x0000, - 0x0900, 0x0000, 0x0000, 0x0000, 0xfb00, 0xfe00, 0x0000, 0x0000, - 0x0700, 0x0700, 0x0000, 0x0000, 0xf600, 0x0000, 0x0000, 0x0000, - 0x0200, 0x0100, 0x0000, 0x0000, 0xfa00, 0xfa00, 0x0000, 0x0000, - 0x1300, 0x3900, 0x0000, 0x0000, 0x2e00, 0x0000, 0x0000, 0x0000, - 0xf300, 0xfc00, 0x0000, 0x0000, 0x0600, 0x0600, 0x0000, 0x0000, - 0x0900, 0x0300, 0x0000, 0x0000, 0xf700, 0xf700, 0x0000, 0x0000, - 0x0c00, 0x2200, 0x0000, 0x0000, 0x4c00, 0x0000, 0x0000, 0x0000, - 0xf700, 0xfd00, 0x0000, 0x0000, 0x0100, 0x0100, 0x0000, 0x0000, - 0xfe00, 0xf900, 0x0000, 0x0000, 0x0b00, 0x0400, 0x0000, 0x0000, - 0xfc00, 0xfc00, 0x0000, 0x0000, 0x0200, 0x0700, 0x0000, 0x0000, - 0x4200, 0x0000, 0x0000, 0x0000, 0x0700, 0x0200, 0x0000, 0x0000, - 0xfc00, 0xfc00, 0x0000, 0x0000, 0x0400, 0x0b00, 0x0000, 0x0000 -}; - -void tfd_filter_coff_ini(void) -{ - int i = 0; - - for (i = 0; i < 336; i++) { - apb_write_reg(DVBT_BASE + 0x99 * 4, (i << 16) | coef[i]); - apb_write_reg(DVBT_BASE + 0x03 * 4, (1 << 12)); - } -} - -void ofdm_initial(int bandwidth, - /* 00:8M 01:7M 10:6M 11:5M */ - int samplerate, - /* 00:45M 01:20.8333M 10:20.7M 11:28.57 100: 24.00 */ - int IF, - /* 000:36.13M 001:-5.5M 010:4.57M 011:4M 100:5M */ - int mode, - /* 00:DVBT,01:ISDBT */ - int tc_mode - /* 0: Unsigned, 1:TC */ - ) -{ -#if 0 - int tmp; - int ch_if; - int adc_freq; - - pr_dbg - ("[ofdm_initial]bandwidth is %d,samplerate is %d", - bandwidth, samplerate); - pr_dbg - ("IF is %d, mode is %d,tc_mode is %d\n", - IF, mode, tc_mode); - switch (IF) { - case 0: - ch_if = 36130; - break; - case 1: - ch_if = -5500; - break; - case 2: - ch_if = 4570; - break; - case 3: - ch_if = 4000; - break; - case 4: - ch_if = 5000; - break; - default: - ch_if = 4000; - break; - } - switch (samplerate) { - case 0: - adc_freq = 45000; - break; - case 1: - adc_freq = 20833; - break; - case 2: - adc_freq = 20700; - break; - case 3: - adc_freq = 28571; - break; - case 4: - adc_freq = 24000; - break; - default: - adc_freq = 28571; - break; - } - - apb_write_reg(DVBT_BASE + (0x02 << 2), 0x00800000); - /* SW reset bit[23] ; write anything to zero */ - apb_write_reg(DVBT_BASE + (0x00 << 2), 0x00000000); - - apb_write_reg(DVBT_BASE + (0xe << 2), 0xffff); - /* enable interrupt */ - - if (mode == 0) { /* DVBT */ - switch (samplerate) { - case 0: - apb_write_reg(DVBT_BASE + (0x08 << 2), 0x00005a00); - break; /* 45MHz */ - case 1: - apb_write_reg(DVBT_BASE + (0x08 << 2), 0x000029aa); - break; /* 20.833 */ - case 2: - apb_write_reg(DVBT_BASE + (0x08 << 2), 0x00002966); - break; /* 20.7 SAMPLERATE*512 */ - case 3: - apb_write_reg(DVBT_BASE + (0x08 << 2), 0x00003924); - break; /* 28.571 */ - case 4: - apb_write_reg(DVBT_BASE + (0x08 << 2), 0x00003000); - break; /* 24 */ - default: - apb_write_reg(DVBT_BASE + (0x08 << 2), 0x00003924); - break; /* 28.571 */ - } - } else { /* ISDBT */ - switch (samplerate) { - case 0: - apb_write_reg(DVBT_BASE + (0x08 << 2), 0x0000580d); - break; /* 45MHz */ - case 1: - apb_write_reg(DVBT_BASE + (0x08 << 2), 0x0000290d); - break; /* 20.833 = 56/7 * 20.8333 / (512/63)*512 */ - case 2: - apb_write_reg(DVBT_BASE + (0x08 << 2), 0x000028da); - break; /* 20.7 */ - case 3: - apb_write_reg(DVBT_BASE + (0x08 << 2), 0x0000383F); - break; /* 28.571 3863 */ - case 4: - apb_write_reg(DVBT_BASE + (0x08 << 2), 0x00002F40); - break; /* 24 */ - default: - apb_write_reg(DVBT_BASE + (0x08 << 2), 0x00003863); - break; /* 28.571 */ - } - } -/* memstart=0x93900000; */ - pr_dbg("memstart is %x\n", memstart); - apb_write_reg(DVBT_BASE + (0x10 << 2), memstart); - /* 0x8f300000 */ - - apb_write_reg(DVBT_BASE + (0x14 << 2), 0xe81c4ff6); - /* AGC_TARGET 0xf0121385 */ - - switch (samplerate) { - case 0: - apb_write_reg(DVBT_BASE + (0x15 << 2), 0x018c2df2); - break; - case 1: - apb_write_reg(DVBT_BASE + (0x15 << 2), 0x0185bdf2); - break; - case 2: - apb_write_reg(DVBT_BASE + (0x15 << 2), 0x0185bdf2); - break; - case 3: - apb_write_reg(DVBT_BASE + (0x15 << 2), 0x0187bdf2); - break; - case 4: - apb_write_reg(DVBT_BASE + (0x15 << 2), 0x0187bdf2); - break; - default: - apb_write_reg(DVBT_BASE + (0x15 << 2), 0x0187bdf2); - break; - } - if (tc_mode == 1) - apb_write_regb(DVBT_BASE + (0x15 << 2), 11, 0); - /* For TC mode. Notice, For ADC input is Unsigned, - *For Capture Data, It is TC. - */ - apb_write_regb(DVBT_BASE + (0x15 << 2), 26, 1); - /* [19:0] = [I , Q], I is high, Q is low. This bit is swap I/Q. */ - - apb_write_reg(DVBT_BASE + (0x16 << 2), 0x00047f80); - /* AGC_IFGAIN_CTRL */ - apb_write_reg(DVBT_BASE + (0x17 << 2), 0x00027f80); - /* AGC_RFGAIN_CTRL */ - apb_write_reg(DVBT_BASE + (0x18 << 2), 0x00000190); - /* AGC_IFGAIN_ACCUM */ - apb_write_reg(DVBT_BASE + (0x19 << 2), 0x00000190); - /* AGC_RFGAIN_ACCUM */ - if (ch_if < 0) - ch_if += adc_freq; - if (ch_if > adc_freq) - ch_if -= adc_freq; - - tmp = ch_if * (1 << 15) / adc_freq; - apb_write_reg(DVBT_BASE + (0x20 << 2), tmp); - - apb_write_reg(DVBT_BASE + (0x21 << 2), 0x001ff000); - /* DDC CS_FCFO_ADJ_CTRL */ - apb_write_reg(DVBT_BASE + (0x22 << 2), 0x00000000); - /* DDC ICFO_ADJ_CTRL */ - apb_write_reg(DVBT_BASE + (0x23 << 2), 0x00004000); - /* DDC TRACK_FCFO_ADJ_CTRL */ - - apb_write_reg(DVBT_BASE + (0x27 << 2), (1 << 23) - | (3 << 19) | (3 << 15) | (1000 << 4) | 9); - /* {8'd0,1'd1,4'd3,4'd3,11'd50,4'd9});//FSM_1 */ - apb_write_reg(DVBT_BASE + (0x28 << 2), (100 << 13) | 1000); - /* {8'd0,11'd40,13'd50});//FSM_2 */ - apb_write_reg(DVBT_BASE + (0x29 << 2), (31 << 20) | (1 << 16) | - (24 << 9) | (3 << 6) | 20); - /* {5'd0,7'd127,1'd0,3'd0,7'd24,3'd5,6'd20}); */ - - if (mode == 0) { /* DVBT */ - if (bandwidth == 0) { /* 8M */ - switch (samplerate) { - case 0: - ini_acf_iireq_src_45m_8m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x004ebf2e); - break; /* 45M */ - case 1: - ini_acf_iireq_src_207m_8m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x00247551); - break; /* 20.833M */ - case 2: - ini_acf_iireq_src_207m_8m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x00243999); - break; /* 20.7M */ - case 3: - ini_acf_iireq_src_2857m_8m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x0031ffcd); - break; /* 28.57M */ - case 4: - ini_acf_iireq_src_24m_8m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x002A0000); - break; /* 24M */ - default: - ini_acf_iireq_src_2857m_8m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x0031ffcd); - break; /* 28.57M */ - } - } else if (bandwidth == 1) { /* 7M */ - switch (samplerate) { - case 0: - ini_acf_iireq_src_45m_7m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x0059ff10); - break; /* 45M */ - case 1: - ini_acf_iireq_src_207m_7m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x0029aaa6); - break; /* 20.833M */ - case 2: - ini_acf_iireq_src_207m_7m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x00296665); - break; /* 20.7M */ - case 3: - ini_acf_iireq_src_2857m_7m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x00392491); - break; /* 28.57M */ - case 4: - ini_acf_iireq_src_24m_7m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x00300000); - break; /* 24M */ - default: - ini_acf_iireq_src_2857m_7m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x00392491); - break; /* 28.57M */ - } - } else if (bandwidth == 2) { /* 6M */ - switch (samplerate) { - case 0: - ini_acf_iireq_src_45m_6m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x00690000); - break; /* 45M */ - case 1: - ini_acf_iireq_src_207m_6m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x00309c3e); - break; /* 20.833M */ - case 2: - ini_acf_iireq_src_207m_6m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x002eaaaa); - break; /* 20.7M */ - case 3: - ini_acf_iireq_src_2857m_6m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x0042AA69); - break; /* 28.57M */ - case 4: - ini_acf_iireq_src_24m_6m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x00380000); - break; /* 24M */ - default: - ini_acf_iireq_src_2857m_6m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x0042AA69); - break; /* 28.57M */ - } - } else { /* 5M */ - switch (samplerate) { - case 0: - ini_acf_iireq_src_45m_5m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x007dfbe0); - break; /* 45M */ - case 1: - ini_acf_iireq_src_207m_5m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x003a554f); - break; /* 20.833M */ - case 2: - ini_acf_iireq_src_207m_5m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x0039f5c0); - break; /* 20.7M */ - case 3: - ini_acf_iireq_src_2857m_5m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x004FFFFE); - break; /* 28.57M */ - case 4: - ini_acf_iireq_src_24m_5m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x00433333); - break; /* 24M */ - default: - ini_acf_iireq_src_2857m_5m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), - 0x004FFFFE); - break; /* 28.57M */ - } - } - } else { /* ISDBT */ - switch (samplerate) { - case 0: - ini_acf_iireq_src_45m_6m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), 0x00589800); - break; - -/* 45M - * SampleRate/(symbolRate)*2^20, - * symbolRate = 512/63 for isdbt - */ - case 1: - ini_acf_iireq_src_207m_6m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), 0x002903d4); - break; /* 20.833M */ - case 2: - ini_acf_iireq_src_207m_6m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), 0x00280ccc); - break; /* 20.7M */ - case 3: - ini_acf_iireq_src_2857m_6m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), 0x00383fc8); - break; /* 28.57M */ - case 4: - ini_acf_iireq_src_24m_6m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), 0x002F4000); - break; /* 24M */ - default: - ini_acf_iireq_src_2857m_6m(); - apb_write_reg(DVBT_BASE + (0x44 << 2), 0x00383fc8); - break; /* 28.57M */ - } - } - - if (mode == 0) /* DVBT */ - apb_write_reg(DVBT_BASE + (0x02 << 2), - (bandwidth << 20) | 0x10002); - else /* ISDBT */ - apb_write_reg(DVBT_BASE + (0x02 << 2), (1 << 20) | 0x1001a); - /* {0x000,2'h1,20'h1_001a}); // For ISDBT , bandwidth should be 1, */ - - apb_write_reg(DVBT_BASE + (0x45 << 2), 0x00000000); - /* SRC SFO_ADJ_CTRL */ - apb_write_reg(DVBT_BASE + (0x46 << 2), 0x02004000); - /* SRC SFO_ADJ_CTRL */ - apb_write_reg(DVBT_BASE + (0x48 << 2), 0x000c0287); - /* DAGC_CTRL1 */ - apb_write_reg(DVBT_BASE + (0x49 << 2), 0x00000005); - /* DAGC_CTRL2 */ - apb_write_reg(DVBT_BASE + (0x4c << 2), 0x00000bbf); - /* CCI_RP */ - apb_write_reg(DVBT_BASE + (0x4d << 2), 0x00000376); - /* CCI_RPSQ */ - apb_write_reg(DVBT_BASE + (0x4e << 2), 0x0f0f1d09); - /* CCI_CTRL */ - apb_write_reg(DVBT_BASE + (0x4f << 2), 0x00000000); - /* CCI DET_INDX1 */ - apb_write_reg(DVBT_BASE + (0x50 << 2), 0x00000000); - /* CCI DET_INDX2 */ - apb_write_reg(DVBT_BASE + (0x51 << 2), 0x00000000); - /* CCI_NOTCH1_A1 */ - apb_write_reg(DVBT_BASE + (0x52 << 2), 0x00000000); - /* CCI_NOTCH1_A2 */ - apb_write_reg(DVBT_BASE + (0x53 << 2), 0x00000000); - /* CCI_NOTCH1_B1 */ - apb_write_reg(DVBT_BASE + (0x54 << 2), 0x00000000); - /* CCI_NOTCH2_A1 */ - apb_write_reg(DVBT_BASE + (0x55 << 2), 0x00000000); - /* CCI_NOTCH2_A2 */ - apb_write_reg(DVBT_BASE + (0x56 << 2), 0x00000000); - /* CCI_NOTCH2_B1 */ - apb_write_reg(DVBT_BASE + (0x58 << 2), 0x00000885); - /* MODE_DETECT_CTRL // 582 */ - if (mode == 0) /* DVBT */ - apb_write_reg(DVBT_BASE + (0x5c << 2), 0x00001011); /* */ - else - apb_write_reg(DVBT_BASE + (0x5c << 2), 0x00000753); - /* ICFO_EST_CTRL ISDBT ICFO thres = 2 */ - - apb_write_reg(DVBT_BASE + (0x5f << 2), 0x0ffffe10); - /* TPS_FCFO_CTRL */ - apb_write_reg(DVBT_BASE + (0x61 << 2), 0x0000006c); - /* FWDT ctrl */ - apb_write_reg(DVBT_BASE + (0x68 << 2), 0x128c3929); - apb_write_reg(DVBT_BASE + (0x69 << 2), 0x91017f2d); - /* 0x1a8 */ - apb_write_reg(DVBT_BASE + (0x6b << 2), 0x00442211); - /* 0x1a8 */ - apb_write_reg(DVBT_BASE + (0x6c << 2), 0x01fc400a); - /* 0x */ - apb_write_reg(DVBT_BASE + (0x6d << 2), 0x0030303f); - /* 0x */ - apb_write_reg(DVBT_BASE + (0x73 << 2), 0xffffffff); - /* CCI0_PILOT_UPDATE_CTRL */ - apb_write_reg(DVBT_BASE + (0x74 << 2), 0xffffffff); - /* CCI0_DATA_UPDATE_CTRL */ - apb_write_reg(DVBT_BASE + (0x75 << 2), 0xffffffff); - /* CCI1_PILOT_UPDATE_CTRL */ - apb_write_reg(DVBT_BASE + (0x76 << 2), 0xffffffff); - /* CCI1_DATA_UPDATE_CTRL */ - - tmp = mode == 0 ? 0x000001a2 : 0x00000da2; - apb_write_reg(DVBT_BASE + (0x78 << 2), tmp); /* FEC_CTR */ - - apb_write_reg(DVBT_BASE + (0x7d << 2), 0x0000009d); - apb_write_reg(DVBT_BASE + (0x7e << 2), 0x00004000); - apb_write_reg(DVBT_BASE + (0x7f << 2), 0x00008000); - - apb_write_reg(DVBT_BASE + ((0x8b + 0) << 2), 0x20002000); - apb_write_reg(DVBT_BASE + ((0x8b + 1) << 2), 0x20002000); - apb_write_reg(DVBT_BASE + ((0x8b + 2) << 2), 0x20002000); - apb_write_reg(DVBT_BASE + ((0x8b + 3) << 2), 0x20002000); - apb_write_reg(DVBT_BASE + ((0x8b + 4) << 2), 0x20002000); - apb_write_reg(DVBT_BASE + ((0x8b + 5) << 2), 0x20002000); - apb_write_reg(DVBT_BASE + ((0x8b + 6) << 2), 0x20002000); - apb_write_reg(DVBT_BASE + ((0x8b + 7) << 2), 0x20002000); - - apb_write_reg(DVBT_BASE + (0x93 << 2), 0x31); - apb_write_reg(DVBT_BASE + (0x94 << 2), 0x00); - apb_write_reg(DVBT_BASE + (0x95 << 2), 0x7f1); - apb_write_reg(DVBT_BASE + (0x96 << 2), 0x20); - - apb_write_reg(DVBT_BASE + (0x98 << 2), 0x03f9115a); - apb_write_reg(DVBT_BASE + (0x9b << 2), 0x000005df); - - apb_write_reg(DVBT_BASE + (0x9c << 2), 0x00100000); - /* TestBus write valid, 0 is system clk valid */ - apb_write_reg(DVBT_BASE + (0x9d << 2), 0x01000000); - /* DDR Start address */ - apb_write_reg(DVBT_BASE + (0x9e << 2), 0x02000000); - /* DDR End address */ - - apb_write_regb(DVBT_BASE + (0x9b << 2), 7, 0); - /* Enable Testbus dump to DDR */ - apb_write_regb(DVBT_BASE + (0x9b << 2), 8, 0); - /* Run Testbus dump to DDR */ - - apb_write_reg(DVBT_BASE + (0xd6 << 2), 0x00000003); - /* apb_write_reg(DVBT_BASE+(0xd7<<2), 0x00000008); */ - apb_write_reg(DVBT_BASE + (0xd8 << 2), 0x00000120); - apb_write_reg(DVBT_BASE + (0xd9 << 2), 0x01010101); - - ini_icfo_pn_index(mode); - tfd_filter_coff_ini(); - - calculate_cordic_para(); - msleep(20); - /* delay_us(1); */ - - apb_write_reg(DVBT_BASE + (0x02 << 2), - apb_read_reg(DVBT_BASE + (0x02 << 2)) | (1 << 0)); - apb_write_reg(DVBT_BASE + (0x02 << 2), - apb_read_reg(DVBT_BASE + (0x02 << 2)) | (1 << 24)); -#endif -/* dvbt_check_status(); */ -} - -void calculate_cordic_para(void) -{ - apb_write_reg(DVBT_BASE + 0x0c, 0x00000040); -} - -char *ofdm_fsm_name[] = { " IDLE", - " AGC", - " CCI", - " ACQ", - " SYNC", - "TRACKING", - " TIMING", - " SP_SYNC", - " TPS_DEC", - "FEC_LOCK", - "FEC_LOST" -}; - -void check_fsm_state(void) -{ - unsigned long tmp; - - tmp = apb_read_reg(DVBT_BASE + 0xa8); - /* printk(">>>>>>>>>>>>>>>>>>>>>>>>> OFDM FSM From %d - *to %d\n", tmp>>4&0xf, tmp&0xf); - */ - - if ((tmp & 0xf) == 3) { - apb_write_regb(DVBT_BASE + (0x9b << 2), 8, 1); - /* Stop dump testbus; */ - apb_write_regb(DVBT_BASE + (0x0f << 2), 0, 1); - tmp = apb_read_reg(DVBT_BASE + (0x9f << 2)); - /* printk(">>>>>>>>>>>>>>>>>>>>>>>>> STOP DUMP DATA To DDR : - *End Addr %d,Is it overflow?%d\n", tmp>>1, tmp&0x1); - */ - } -} - -void ofdm_read_all_regs(void) -{ - int i; - unsigned long tmp; - - for (i = 0; i < 0xff; i++) - tmp = apb_read_reg(DVBT_BASE + 0x00 + i * 4); - /* printk("OFDM Reg (0x%x) is 0x%x\n", i, tmp); */ - -} - -static int dvbt_get_status(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c) -{ - return apb_read_reg(DVBT_BASE + 0x0) >> 12 & 1; -} - -static int dvbt_get_ber(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c) -{ -/* pr_dbg("[RSJ]per is %u\n",apb_read_reg(DVBT_BASE+(0xbf<<2))); */ - return apb_read_reg(DVBT_BASE + (0xbf << 2)); -} - -static int dvbt_get_snr(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c) -{ -/* pr_dbg("2snr is %u\n",((apb_read_reg(DVBT_BASE+(0x0a<<2)))>>20)&0x3ff); */ - return ((apb_read_reg(DVBT_BASE + (0x0a << 2))) >> 20) & 0x3ff; - /*dBm: bit0~bit2=decimal */ -} - -static int dvbt_get_strength(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c) -{ -/* int dbm = dvbt_get_ch_power(demod_sta, demod_i2c); */ -/* return dbm; */ - return 0; -} - -static int dvbt_get_ucblocks(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c) -{ - return 0; -/* return dvbt_get_per(); */ -} - -struct demod_status_ops *dvbt_get_status_ops(void) -{ - static struct demod_status_ops ops = { - .get_status = dvbt_get_status, - .get_ber = dvbt_get_ber, - .get_snr = dvbt_get_snr, - .get_strength = dvbt_get_strength, - .get_ucblocks = dvbt_get_ucblocks, - }; - - return &ops; -} - -int app_apb_read_reg(int addr) -{ - addr = DTMB_TOP_ADDR(addr); - return (int)demod_read_demod_reg(addr); -} - -int app_apb_write_reg(int addr, int data) -{ - addr = DTMB_TOP_ADDR(addr); - demod_set_demod_reg(data, addr); - return 0; -} - -void monitor_isdbt(void) -{ - int SNR; - int SNR_SP = 500; - int SNR_TPS = 0; - int SNR_CP = 0; - int timeStamp = 0; - int SFO_residual = 0; - int SFO_esti = 0; - int FCFO_esti = 0; - int FCFO_residual = 0; - int AGC_Gain = 0; - int RF_AGC = 0; - int Signal_power = 0; - int FECFlag = 0; - int EQ_seg_ratio = 0; - int tps_0 = 0; - int tps_1 = 0; - int tps_2 = 0; - - int time_stamp; - int SFO; - int FCFO; - int timing_adj; - int RS_CorrectNum; - - int cnt; - int tmpAGCGain; - - tmpAGCGain = 0; - cnt = 0; - -/* app_apb_write_reg(0x8, app_apb_read_reg(0x8) & ~(1 << 17)); - * // TPS symbol index update : active high - */ - time_stamp = app_apb_read_reg(0x07) & 0xffff; - SNR = app_apb_read_reg(0x0a); - FECFlag = (app_apb_read_reg(0x00) >> 11) & 0x3; - SFO = app_apb_read_reg(0x47) & 0xfff; - SFO_esti = app_apb_read_reg(0x60) & 0xfff; - FCFO_esti = (app_apb_read_reg(0x60) >> 11) & 0xfff; - FCFO = (app_apb_read_reg(0x26)) & 0xffffff; - RF_AGC = app_apb_read_reg(0x0c) & 0x1fff; - timing_adj = app_apb_read_reg(0x6f) & 0x1fff; - RS_CorrectNum = app_apb_read_reg(0xc1) & 0xfffff; - Signal_power = (app_apb_read_reg(0x1b)) & 0x1ff; - EQ_seg_ratio = app_apb_read_reg(0x6e) & 0x3ffff; - tps_0 = app_apb_read_reg(0x64); - tps_1 = app_apb_read_reg(0x65); - tps_2 = app_apb_read_reg(0x66) & 0xf; - - timeStamp = (time_stamp >> 8) * 68 + (time_stamp & 0x7f); - SFO_residual = (SFO > 0x7ff) ? (SFO - 0x1000) : SFO; - FCFO_residual = (FCFO > 0x7fffff) ? (FCFO - 0x1000000) : FCFO; - /* RF_AGC = (RF_AGC>0x3ff)? (RF_AGC - 0x800): RF_AGC; */ - FCFO_esti = (FCFO_esti > 0x7ff) ? (FCFO_esti - 0x1000) : FCFO_esti; - SNR_CP = (SNR) & 0x3ff; - SNR_TPS = (SNR >> 10) & 0x3ff; - SNR_SP = (SNR >> 20) & 0x3ff; - SNR_SP = (SNR_SP > 0x1ff) ? SNR_SP - 0x400 : SNR_SP; - SNR_TPS = (SNR_TPS > 0x1ff) ? SNR_TPS - 0x400 : SNR_TPS; - SNR_CP = (SNR_CP > 0x1ff) ? SNR_CP - 0x400 : SNR_CP; - AGC_Gain = tmpAGCGain >> 4; - tmpAGCGain = (AGC_Gain > 0x3ff) ? AGC_Gain - 0x800 : AGC_Gain; - timing_adj = (timing_adj > 0xfff) ? timing_adj - 0x2000 : timing_adj; - EQ_seg_ratio = - (EQ_seg_ratio > 0x1ffff) ? EQ_seg_ratio - 0x40000 : EQ_seg_ratio; - - pr_dbg - ("T %4x SP %3d TPS %3d CP %3d EQS %8x RSC %4d", - app_apb_read_reg(0xbf) - , SNR_SP, SNR_TPS, SNR_CP -/* ,EQ_seg_ratio */ - , app_apb_read_reg(0x62) - , RS_CorrectNum); - pr_dbg - ("SFO %4d FCFO %4d Vit %4x Timing %3d SigP %3x", - SFO_residual, FCFO_residual, RF_AGC, timing_adj, - Signal_power); - pr_dbg - ("FEC %x RSErr %8x ReSyn %x tps %03x%08x", - FECFlag, app_apb_read_reg(0x0b) - , (app_apb_read_reg(0xc0) >> 20) & 0xff, - app_apb_read_reg(0x05) & 0xfff, app_apb_read_reg(0x04) - ); - pr_dbg("\n"); -} - -int find_2(int data, int *table, int len) -{ - int end; - int index; - int start; - int cnt = 0; - - start = 0; - end = len; - /* printf("data is %d\n",data); */ - while ((len > 1) && (cnt < 10)) { - cnt++; - index = (len / 2); - if (data > table[start + index]) { - start = start + index; - len = len - index - 1; - } - if (data < table[start + index]) { - len = index + 1; - } else if (data == table[start + index]) { - start = start + index; - break; - } - } - return start; -} - -int read_atsc_all_reg(void) -{ - return 0; -#if 0 - int i, j, k; - - j = 4; - unsigned long data; - - pr_dbg("system agc is:"); /* system agc */ - for (i = 0xc00; i <= 0xc0c; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - j = 4; - for (i = 0xc80; i <= 0xc87; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - pr_dbg("\n vsb control is:"); /*vsb control */ - j = 4; - for (i = 0x900; i <= 0x905; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - j = 4; - for (i = 0x908; i <= 0x912; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - j = 4; - for (i = 0x917; i <= 0x91b; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - j = 4; - for (i = 0x980; i <= 0x992; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - pr_dbg("\n vsb demod is:"); /*vsb demod */ - j = 4; - for (i = 0x700; i <= 0x711; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - j = 4; - for (i = 0x716; i <= 0x720; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - j = 4; - for (i = 0x722; i <= 0x724; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - j = 4; - for (i = 0x726; i <= 0x72c; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - j = 4; - for (i = 0x730; i <= 0x732; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - j = 4; - for (i = 0x735; i <= 0x751; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - j = 4; - for (i = 0x780; i <= 0x795; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - j = 4; - for (i = 0x752; i <= 0x755; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - pr_dbg("\n vsb equalizer is:"); /*vsb equalizer */ - j = 4; - for (i = 0x501; i <= 0x5ff; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - pr_dbg("\n vsb fec is:"); /*vsb fec */ - j = 4; - for (i = 0x601; i <= 0x601; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - j = 4; - for (i = 0x682; i <= 0x685; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - pr_dbg("\n qam demod is:"); /*qam demod */ - j = 4; - for (i = 0x1; i <= 0x1a; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - j = 4; - for (i = 0x25; i <= 0x28; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - j = 4; - for (i = 0x101; i <= 0x10b; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - j = 4; - for (i = 0x206; i <= 0x207; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - pr_dbg("\n qam equalize is:"); /*qam equalize */ - j = 4; - for (i = 0x200; i <= 0x23d; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - j = 4; - for (i = 0x260; i <= 0x275; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - pr_dbg("\n qam fec is:"); /*qam fec */ - j = 4; - for (i = 0x400; i <= 0x418; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - pr_dbg("\n system mpeg formatter is:"); /*system mpeg formatter */ - j = 4; - for (i = 0xf00; i <= 0xf09; i++) { - data = atsc_read_reg(i); - if (j == 4) { - pr_dbg("\n[addr:0x%x]", i); - j = 0; - } - pr_dbg("%02x ", data); - j++; - } - pr_dbg("\n\n"); - return 0; -#endif -} - -int check_atsc_fsm_status(void) -{ - int SNR; - int atsc_snr = 0; - int SNR_dB; - int SNR_table[56] = { 0, 7, 9, 11, 14, - 17, - 22, - 27, 34, 43, 54, - 68, 86, 108, 136, 171, - 215, - 271, 341, - 429, 540, - 566, 592, 620, 649, 680, - 712, - 746, 781, - 818, 856, - 896, 939, 983, 1029, 1078, - 1182, - 1237, - 1237, 1296, 1357, - 1708, 2150, 2707, 3408, 4291, - 5402, - 6800, - 8561, 10778, 13568, - 16312, 17081, 18081, 19081, 65536 - }; - int SNR_dB_table[56] = { 360, 350, 340, 330, 320, 310, 300, - 290, - 280, - 270, 260, - 250, 240, 230, 220, 210, 200, 190, - 180, - 170, - 160, - 158, 156, 154, 152, 150, 148, 146, - 144, - 142, - 140, - 138, 136, 134, 132, 130, 128, 126, - 124, - 122, - 120, - 110, 100, 90, 80, 70, 60, 50, - 40, - 30, - 20, - 12, 10, 4, 2, 0 - }; - - int tmp[3]; - int cr; - int ck; - int SM; - int tni; - int ber; - int per; - - int cnt; - - cnt = 0; - ber = 0; - per = 0; - -/* g_demod_mode = 2; */ - tni = atsc_read_reg((0x08) >> 16); -/* g_demod_mode = 4; */ - tmp[0] = atsc_read_reg(0x0511); - tmp[1] = atsc_read_reg(0x0512); - SNR = (tmp[0] << 8) + tmp[1]; - SNR_dB = SNR_dB_table[find_2(SNR, SNR_table, 56)]; - - tmp[0] = atsc_read_reg(0x0780); - tmp[1] = atsc_read_reg(0x0781); - tmp[2] = atsc_read_reg(0x0782); - cr = tmp[0] + (tmp[1] << 8) + (tmp[2] << 16); - tmp[0] = atsc_read_reg(0x0786); - tmp[1] = atsc_read_reg(0x0787); - tmp[2] = atsc_read_reg(0x0788); - ck = (tmp[0] << 16) + (tmp[1] << 8) + tmp[2]; - ck = (ck > 8388608) ? ck - 16777216 : ck; - SM = atsc_read_reg(0x0980); -/* ber per */ - atsc_write_reg(0x0601, atsc_read_reg(0x0601) & (~(1 << 3))); - atsc_write_reg(0x0601, atsc_read_reg(0x0601) | (1 << 3)); - ber = atsc_read_reg(0x0683) + (atsc_read_reg(0x0682) << 8); - per = atsc_read_reg(0x0685) + (atsc_read_reg(0x0684) << 8); - -/* read_atsc_all_reg(); */ - - pr_dbg - ("INT %x SNR %x SNRdB %d.%d FSM %x cr %d ck %d", - tni, SNR, (SNR_dB / 10) - , (SNR_dB - (SNR_dB / 10) * 10) - , SM, cr, ck); - pr_dbg - ("ber is %d, per is %d\n", - ber, per); - - atsc_snr = (SNR_dB / 10); - return atsc_snr; - - /* unsigned long sm,snr1,snr2,snr; - * static int fec_lock_cnt = 0; - * - * delay_us(10000); - * sm = atsc_read_reg(0x0980); - * snr1 = atsc_read_reg(0x0511)&0xff; - * snr2 = atsc_read_reg(0x0512)&0xff; - * snr = (snr1 << 8) + snr2; - * - * printk(">>>>>>>>>>>>>>>>>>>>>>>>> - OFDM FSM %x SNR %x\n", sm&0xff, snr); - * - * if (sm == 0x79) stimulus_finish_pass(); - */ -} diff --git a/drivers/stream_input/tv_frontend/dtv_demod/dvbc_func.c b/drivers/stream_input/tv_frontend/dtv_demod/dvbc_func.c deleted file mode 100644 index cf2ea81..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/dvbc_func.c +++ b/dev/null @@ -1,1331 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#include -#include -#include -#include -#include "demod_func.h" -#include - -static int debug_amldvbc = 1; -#define dprintk(a ...) do { if (debug_amldvbc) printk(a); } while (0) - -static struct task_struct *cci_task; -int cciflag; -struct timer_list mytimer; - -static void dvbc_cci_timer(unsigned long data) -{ -#if 0 - int count; - int maxCCI_p, re, im, j, i, times, maxCCI, sum, sum1, reg_0xf0, tmp1, - tmp, tmp2, reg_0xa8, reg_0xac; - int reg_0xa8_t, reg_0xac_t; - - count = 100; - if ((((apb_read_reg(QAM_BASE + 0x18)) & 0x1) == 1)) { - dprintk("[cci]lock "); - if (cciflag == 0) { - apb_write_reg(QAM_BASE + 0xa8, 0); - - cciflag = 0; - } - dprintk("\n"); - mdelay(500); - mod_timer(&mytimer, jiffies + 2 * HZ); - return; - } - if (cciflag == 1) { - dprintk("[cci]cciflag is 1,wait 20\n"); - mdelay(20000); - } - times = 300; - tmp = 0x2be2be3; - /*0x2ae4772; IF = 6M, fs = 35M, dec2hex(round(8*IF/fs*2^25)) */ - tmp2 = 0x2000; - tmp1 = 8; - reg_0xa8 = 0xc0000000; /* bypass CCI */ - reg_0xac = 0xc0000000; /* bypass CCI */ - - maxCCI = 0; - maxCCI_p = 0; - for (i = 0; i < times; i++) { - /*reg_0xa8 = app_apb_read_reg(0xa8); */ - reg_0xa8_t = reg_0xa8 + tmp + i * tmp2; - apb_write_reg(QAM_BASE + 0xa8, reg_0xa8_t); - reg_0xac_t = reg_0xac + tmp - i * tmp2; - apb_write_reg(QAM_BASE + 0xac, reg_0xac_t); - sum = 0; - sum1 = 0; - for (j = 0; j < tmp1; j++) { - /* msleep(20); */ - /* mdelay(20); */ - reg_0xf0 = apb_read_reg(QAM_BASE + 0xf0); - re = (reg_0xf0 >> 24) & 0xff; - im = (reg_0xf0 >> 16) & 0xff; - if (re > 127) - /*re = re - 256; */ - re = 256 - re; - if (im > 127) - /*im = im - 256; */ - im = 256 - im; - - sum += re + im; - re = (reg_0xf0 >> 8) & 0xff; - im = (reg_0xf0 >> 0) & 0xff; - if (re > 127) - /*re = re - 256; */ - re = 256 - re; - if (im > 127) - /*im = im - 256; */ - im = 256 - im; - - sum1 += re + im; - } - sum = sum / tmp1; - sum1 = sum1 / tmp1; - if (sum1 > sum) { - sum = sum1; - reg_0xa8_t = reg_0xac_t; - } - if (sum > maxCCI) { - maxCCI = sum; - if (maxCCI > 24) - maxCCI_p = reg_0xa8_t & 0x7fffffff; - } - if ((sum < 24) && (maxCCI_p > 0)) - break; /* stop CCI detect. */ - } - - if (maxCCI_p > 0) { - apb_write_reg(QAM_BASE + 0xa8, maxCCI_p & 0x7fffffff); - /* enable CCI */ - apb_write_reg(QAM_BASE + 0xac, maxCCI_p & 0x7fffffff); - /* enable CCI */ - /* if(dvbc.mode == 4) // 256QAM */ - apb_write_reg(QAM_BASE + 0x54, 0xa25705fa); - /**/ cciflag = 1; - mdelay(1000); - } else { - dprintk - ("[cci] ------------ find NO CCI -------------------\n"); - cciflag = 0; - } - - dprintk("[cci][%s]--------------------------\n", __func__); - mod_timer(&mytimer, jiffies + 2 * HZ); - return; -/* }*/ -#endif -} - -int dvbc_timer_init(void) -{ - dprintk("%s\n", __func__); - setup_timer(&mytimer, dvbc_cci_timer, (unsigned long)"Hello, world!"); - mytimer.expires = jiffies + 2 * HZ; - add_timer(&mytimer); - return 0; -} - -void dvbc_timer_exit(void) -{ - dprintk("%s\n", __func__); - del_timer(&mytimer); -} - -int dvbc_cci_task(void *data) -{ - int count; - int maxCCI_p, re, im, j, i, times, maxCCI, sum, sum1, reg_0xf0, tmp1, - tmp, tmp2, reg_0xa8, reg_0xac; - int reg_0xa8_t, reg_0xac_t; - - count = 100; - while (1) { - msleep(200); - if ((((apb_read_reg(QAM_BASE + 0x18)) & 0x1) == 1)) { - dprintk("[cci]lock "); - if (cciflag == 0) { - apb_write_reg(QAM_BASE + 0xa8, 0); - apb_write_reg(QAM_BASE + 0xac, 0); - dprintk("no cci "); - cciflag = 0; - } - dprintk("\n"); - msleep(500); - continue; - } - - if (cciflag == 1) { - dprintk("[cci]cciflag is 1,wait 20\n"); - msleep(20000); - } - times = 300; - tmp = 0x2be2be3; - /*0x2ae4772; IF = 6M,fs = 35M, dec2hex(round(8*IF/fs*2^25)) */ - tmp2 = 0x2000; - tmp1 = 8; - reg_0xa8 = 0xc0000000; /* bypass CCI */ - reg_0xac = 0xc0000000; /* bypass CCI */ - - maxCCI = 0; - maxCCI_p = 0; - for (i = 0; i < times; i++) { - /*reg_0xa8 = app_apb_read_reg(0xa8); */ - reg_0xa8_t = reg_0xa8 + tmp + i * tmp2; - apb_write_reg(QAM_BASE + 0xa8, reg_0xa8_t); - reg_0xac_t = reg_0xac + tmp - i * tmp2; - apb_write_reg(QAM_BASE + 0xac, reg_0xac_t); - sum = 0; - sum1 = 0; - for (j = 0; j < tmp1; j++) { - /* msleep(1); */ - reg_0xf0 = apb_read_reg(QAM_BASE + 0xf0); - re = (reg_0xf0 >> 24) & 0xff; - im = (reg_0xf0 >> 16) & 0xff; - if (re > 127) - /*re = re - 256; */ - re = 256 - re; - if (im > 127) - /*im = im - 256; */ - im = 256 - im; - - sum += re + im; - - re = (reg_0xf0 >> 8) & 0xff; - im = (reg_0xf0 >> 0) & 0xff; - if (re > 127) - /*re = re - 256; */ - re = 256 - re; - if (im > 127) - /*im = im - 256; */ - im = 256 - im; - - sum1 += re + im; - } - sum = sum / tmp1; - sum1 = sum1 / tmp1; - if (sum1 > sum) { - sum = sum1; - reg_0xa8_t = reg_0xac_t; - } - if (sum > maxCCI) { - maxCCI = sum; - if (maxCCI > 24) - maxCCI_p = reg_0xa8_t & 0x7fffffff; - } - - if ((sum < 24) && (maxCCI_p > 0)) - break; /* stop CCI detect. */ - } - - if (maxCCI_p > 0) { - apb_write_reg(QAM_BASE + 0xa8, maxCCI_p & 0x7fffffff); - /* enable CCI */ - apb_write_reg(QAM_BASE + 0xac, maxCCI_p & 0x7fffffff); - /* enable CCI */ - /* if(dvbc.mode == 4) // 256QAM */ - apb_write_reg(QAM_BASE + 0x54, 0xa25705fa); - /**/ cciflag = 1; - msleep(1000); - } else { - cciflag = 0; - } - - dprintk("[cci][%s]--------------------------\n", __func__); - } - return 0; -} - -int dvbc_get_cci_task(void) -{ - if (cci_task) - return 0; - else - return 1; -} - -void dvbc_create_cci_task(void) -{ - int ret; - - /*apb_write_reg(QAM_BASE+0xa8, 0x42b2ebe3); // enable CCI */ - /* apb_write_reg(QAM_BASE+0xac, 0x42b2ebe3); // enable CCI */ -/* if(dvbc.mode == 4) // 256QAM*/ - /* apb_write_reg(QAM_BASE+0x54, 0xa25705fa); // */ - ret = 0; - cci_task = kthread_create(dvbc_cci_task, NULL, "cci_task"); - if (ret != 0) { - dprintk("[%s]Create cci kthread error!\n", __func__); - cci_task = NULL; - return; - } - wake_up_process(cci_task); - dprintk("[%s]Create cci kthread and wake up!\n", __func__); -} - -void dvbc_kill_cci_task(void) -{ - if (cci_task) { - kthread_stop(cci_task); - cci_task = NULL; - dprintk("[%s]kill cci kthread !\n", __func__); - } -} - -u32 dvbc_set_qam_mode(unsigned char mode) -{ - dprintk("auto change mode ,now mode is %d\n", mode); - apb_write_reg(QAM_BASE + 0x008, (mode & 7)); - /* qam mode */ - switch (mode) { - case 0: /* 16 QAM */ - apb_write_reg(QAM_BASE + 0x054, 0x23460224); - /* EQ_FIR_CTL, */ - apb_write_reg(QAM_BASE + 0x068, 0x00c000c0); - /* EQ_CRTH_SNR */ - apb_write_reg(QAM_BASE + 0x074, 0x50001a0); - /* EQ_TH_LMS 40db 13db */ - apb_write_reg(QAM_BASE + 0x07c, 0x003001e9); - /* EQ_NORM and EQ_TH_MMA */ - /*apb_write_reg(QAM_BASE+0x080, 0x000be1ff); - * // EQ_TH_SMMA0 - */ - apb_write_reg(QAM_BASE + 0x080, 0x000e01fe); - /* EQ_TH_SMMA0 */ - apb_write_reg(QAM_BASE + 0x084, 0x00000000); - /* EQ_TH_SMMA1 */ - apb_write_reg(QAM_BASE + 0x088, 0x00000000); - /* EQ_TH_SMMA2 */ - apb_write_reg(QAM_BASE + 0x08c, 0x00000000); - /* EQ_TH_SMMA3 */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2b); - * // AGC_CTRL ALPS tuner - */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292b); - * // Pilips Tuner - */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292d); - * // Pilips Tuner - */ - apb_write_reg(QAM_BASE + 0x094, 0x7f80092d); - /* Pilips Tuner */ - apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f66); - /* by raymond 20121213 */ - break; - - case 1: /* 32 QAM */ - apb_write_reg(QAM_BASE + 0x054, 0x24560506); - /* EQ_FIR_CTL, */ - apb_write_reg(QAM_BASE + 0x068, 0x00c000c0); - /* EQ_CRTH_SNR */ - /*apb_write_reg(QAM_BASE+0x074, 0x5000260); - * // EQ_TH_LMS 40db 19db - */ - apb_write_reg(QAM_BASE + 0x074, 0x50001f0); - /* EQ_TH_LMS 40db 17.5db */ - apb_write_reg(QAM_BASE + 0x07c, 0x00500102); - /* EQ_TH_MMA 0x000001cc */ - apb_write_reg(QAM_BASE + 0x080, 0x00077140); - /* EQ_TH_SMMA0 */ - apb_write_reg(QAM_BASE + 0x084, 0x001fb000); - /* EQ_TH_SMMA1 */ - apb_write_reg(QAM_BASE + 0x088, 0x00000000); - /* EQ_TH_SMMA2 */ - apb_write_reg(QAM_BASE + 0x08c, 0x00000000); - /* EQ_TH_SMMA3 */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2b); - * // AGC_CTRL ALPS tuner - */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292b); - * // Pilips Tuner - */ - apb_write_reg(QAM_BASE + 0x094, 0x7f80092b); - /* Pilips Tuner */ - apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f66); - /* by raymond 20121213 */ - break; - - case 2: /* 64 QAM */ - /*apb_write_reg(QAM_BASE+0x054, 0x2256033a); - * // EQ_FIR_CTL, - */ - apb_write_reg(QAM_BASE + 0x054, 0x2336043a); - /* EQ_FIR_CTL, by raymond */ - apb_write_reg(QAM_BASE + 0x068, 0x00c000c0); - /* EQ_CRTH_SNR */ - /*apb_write_reg(QAM_BASE+0x074, 0x5000260); - * // EQ_TH_LMS 40db 19db - */ - apb_write_reg(QAM_BASE + 0x074, 0x5000230); - /* EQ_TH_LMS 40db 17.5db */ - apb_write_reg(QAM_BASE + 0x07c, 0x007001bd); - /* EQ_TH_MMA */ - apb_write_reg(QAM_BASE + 0x080, 0x000580ed); - /* EQ_TH_SMMA0 */ - apb_write_reg(QAM_BASE + 0x084, 0x001771fb); - /* EQ_TH_SMMA1 */ - apb_write_reg(QAM_BASE + 0x088, 0x00000000); - /* EQ_TH_SMMA2 */ - apb_write_reg(QAM_BASE + 0x08c, 0x00000000); - /* EQ_TH_SMMA3 */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2c); - * // AGC_CTRL ALPS tuner - */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292c); - * // Pilips & maxlinear Tuner - */ - apb_write_reg(QAM_BASE + 0x094, 0x7f802b3d); - /* Pilips Tuner & maxlinear Tuner */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f802b3a); - * // Pilips Tuner & maxlinear Tuner - */ - apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f66); - /* by raymond 20121213 */ - break; - - case 3: /* 128 QAM */ - /*apb_write_reg(QAM_BASE+0x054, 0x2557046a); - * // EQ_FIR_CTL, - */ - apb_write_reg(QAM_BASE + 0x054, 0x2437067a); - /* EQ_FIR_CTL, by raymond 20121213 */ - apb_write_reg(QAM_BASE + 0x068, 0x00c000d0); - /* EQ_CRTH_SNR */ - /* apb_write_reg(QAM_BASE+0x074, 0x02440240); - * // EQ_TH_LMS 18.5db 18db - */ - /* apb_write_reg(QAM_BASE+0x074, 0x04000400); - * // EQ_TH_LMS 22db 22.5db - */ - apb_write_reg(QAM_BASE + 0x074, 0x5000260); - /* EQ_TH_LMS 40db 19db */ - /*apb_write_reg(QAM_BASE+0x07c, 0x00b000f2); - * // EQ_TH_MMA0x000000b2 - */ - apb_write_reg(QAM_BASE + 0x07c, 0x00b00132); - /* EQ_TH_MMA0x000000b2 by raymond 20121213 */ - apb_write_reg(QAM_BASE + 0x080, 0x0003a09d); - /* EQ_TH_SMMA0 */ - apb_write_reg(QAM_BASE + 0x084, 0x000f8150); - /* EQ_TH_SMMA1 */ - apb_write_reg(QAM_BASE + 0x088, 0x001a51f8); - /* EQ_TH_SMMA2 */ - apb_write_reg(QAM_BASE + 0x08c, 0x00000000); - /* EQ_TH_SMMA3 */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2c); - * // AGC_CTRL ALPS tuner - */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292c); - * // Pilips Tuner - */ - apb_write_reg(QAM_BASE + 0x094, 0x7f80092c); - /* Pilips Tuner */ - apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f66); - /* by raymond 20121213 */ - break; - - case 4: /* 256 QAM */ - /*apb_write_reg(QAM_BASE+0x054, 0xa2580588); - * // EQ_FIR_CTL, - */ - apb_write_reg(QAM_BASE + 0x054, 0xa25905f9); - /* EQ_FIR_CTL, by raymond 20121213 */ - apb_write_reg(QAM_BASE + 0x068, 0x01e00220); - /* EQ_CRTH_SNR */ - /*apb_write_reg(QAM_BASE+0x074, 0x50002a0); - * // EQ_TH_LMS 40db 19db - */ - apb_write_reg(QAM_BASE + 0x074, 0x5000270); - /* EQ_TH_LMS 40db 19db by raymond 201211213 */ - apb_write_reg(QAM_BASE + 0x07c, 0x00f001a5); - /* EQ_TH_MMA */ - apb_write_reg(QAM_BASE + 0x080, 0x0002c077); - /* EQ_TH_SMMA0 */ - apb_write_reg(QAM_BASE + 0x084, 0x000bc0fe); - /* EQ_TH_SMMA1 */ - apb_write_reg(QAM_BASE + 0x088, 0x0013f17e); - /* EQ_TH_SMMA2 */ - apb_write_reg(QAM_BASE + 0x08c, 0x01bc01f9); - /* EQ_TH_SMMA3 */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2c); - * // AGC_CTRL ALPS tuner - */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292c); - * // Pilips Tuner - */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292d); - * // Maxlinear Tuner - */ - apb_write_reg(QAM_BASE + 0x094, 0x7f80092d); - /* Maxlinear Tuner */ - apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f67); - /* by raymond 20121213, when adc=35M,sys=70M, - * its better than 0x61f2f66 - */ - break; - default: /*64qam */ - /*apb_write_reg(QAM_BASE+0x054, 0x2256033a); - * // EQ_FIR_CTL, - */ - apb_write_reg(QAM_BASE + 0x054, 0x2336043a); - /* EQ_FIR_CTL, by raymond */ - apb_write_reg(QAM_BASE + 0x068, 0x00c000c0); - /* EQ_CRTH_SNR */ - /*apb_write_reg(QAM_BASE+0x074, 0x5000260); - * // EQ_TH_LMS 40db 19db - */ - apb_write_reg(QAM_BASE + 0x074, 0x5000230); - /* EQ_TH_LMS 40db 17.5db */ - apb_write_reg(QAM_BASE + 0x07c, 0x007001bd); - /* EQ_TH_MMA */ - apb_write_reg(QAM_BASE + 0x080, 0x000580ed); - /* EQ_TH_SMMA0 */ - apb_write_reg(QAM_BASE + 0x084, 0x001771fb); - /* EQ_TH_SMMA1 */ - apb_write_reg(QAM_BASE + 0x088, 0x00000000); - /* EQ_TH_SMMA2 */ - apb_write_reg(QAM_BASE + 0x08c, 0x00000000); - /* EQ_TH_SMMA3 */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2c); - * // AGC_CTRL ALPS tuner - */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292c); - * // Pilips & maxlinear Tuner - */ - apb_write_reg(QAM_BASE + 0x094, 0x7f802b3d); - /* Pilips Tuner & maxlinear Tuner */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f802b3a); - * // Pilips Tuner & maxlinear Tuner - */ - apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f66); - /* by raymond 20121213 */ - break; - } - return 0; -} - -u32 dvbc_get_status(void) -{ -/* dprintk("c4 is %x\n",apb_read_reg(QAM_BASE+0xc4));*/ - return apb_read_reg(QAM_BASE + 0xc4) & 0xf; -} -EXPORT_SYMBOL(dvbc_get_status); - -static u32 dvbc_get_ch_power(void) -{ - u32 tmp; - u32 ad_power; - u32 agc_gain; - u32 ch_power; - - tmp = apb_read_reg(QAM_BASE + 0x09c); - - ad_power = (tmp >> 22) & 0x1ff; - agc_gain = (tmp >> 0) & 0x7ff; - - ad_power = ad_power >> 4; - /* ch_power = lookuptable(agc_gain) + ad_power; TODO */ - ch_power = (ad_power & 0xffff) + ((agc_gain & 0xffff) << 16); - - return ch_power; -} - -static u32 dvbc_get_snr(void) -{ - u32 tmp, snr; - - tmp = apb_read_reg(QAM_BASE + 0x14) & 0xfff; - snr = tmp * 100 / 32; /* * 1e2 */ - - return snr; -} - -static u32 dvbc_get_ber(void) -{ - u32 rs_ber; - u32 rs_packet_len; - - rs_packet_len = apb_read_reg(QAM_BASE + 0x10) & 0xffff; - rs_ber = apb_read_reg(QAM_BASE + 0x14) >> 12 & 0xfffff; - - /* rs_ber = rs_ber / 204.0 / 8.0 / rs_packet_len; */ - if (rs_packet_len == 0) - rs_ber = 1000000; - else - rs_ber = rs_ber * 613 / rs_packet_len; /* 1e-6 */ - - return rs_ber; -} - -static u32 dvbc_get_per(void) -{ - u32 rs_per; - u32 rs_packet_len; - u32 acc_rs_per_times; - - rs_packet_len = apb_read_reg(QAM_BASE + 0x10) & 0xffff; - rs_per = apb_read_reg(QAM_BASE + 0x18) >> 16 & 0xffff; - - acc_rs_per_times = apb_read_reg(QAM_BASE + 0xcc) & 0xffff; - /*rs_per = rs_per / rs_packet_len; */ - - if (rs_packet_len == 0) - rs_per = 10000; - else - rs_per = 10000 * rs_per / rs_packet_len; /* 1e-4 */ - - /*return rs_per; */ - return acc_rs_per_times; -} - -static u32 dvbc_get_symb_rate(void) -{ - u32 tmp; - u32 adc_freq; - u32 symb_rate; - - adc_freq = apb_read_reg(QAM_BASE + 0x34) >> 16 & 0xffff; - tmp = apb_read_reg(QAM_BASE + 0xb8); - - if ((tmp >> 15) == 0) - symb_rate = 0; - else - symb_rate = 10 * (adc_freq << 12) / (tmp >> 15); - /* 1e4 */ - - return symb_rate; -} - -static int dvbc_get_freq_off(void) -{ - int tmp; - int symb_rate; - int freq_off; - - symb_rate = dvbc_get_symb_rate(); - tmp = apb_read_reg(QAM_BASE + 0xe0) & 0x3fffffff; - if (tmp >> 29 & 1) - tmp -= (1 << 30); - - freq_off = ((tmp >> 16) * 25 * (symb_rate >> 10)) >> 3; - - return freq_off; -} - -static void dvbc_set_test_bus(u8 sel) -{ - u32 tmp; - - tmp = apb_read_reg(QAM_BASE + 0x08); - tmp &= ~(0x1f << 4); - tmp |= ((sel & 0x1f) << 4) | (1 << 3); - apb_write_reg(QAM_BASE + 0x08, tmp); -} - -void dvbc_get_test_out(u8 sel, u32 len, u32 *buf) -{ - int i, cnt; - - dvbc_set_test_bus(sel); - - for (i = 0, cnt = 0; i < len - 4 && cnt < 1000000; i++) { - buf[i] = apb_read_reg(QAM_BASE + 0xb0); - if (buf[i] >> 11 & 1) { - buf[i++] = apb_read_reg(QAM_BASE + 0xb0); - buf[i++] = apb_read_reg(QAM_BASE + 0xb0); - buf[i++] = apb_read_reg(QAM_BASE + 0xb0); - buf[i++] = apb_read_reg(QAM_BASE + 0xb0); - } else { - i--; - } - - cnt++; - } -} - -#if 0 -static void dvbc_sw_reset(int addr, int idx) -{ - u32 tmp; - - tmp = apb_read_reg(QAM_BASE + addr); - - tmp &= ~(1 << idx); - apb_write_reg(QAM_BASE + addr, tmp); - - udelay(1); - - tmp |= (1 << idx); - apb_write_reg(QAM_BASE + addr, tmp); -} - -static void dvbc_reset(void) -{ - dvbc_sw_reset(0x04, 0); -} - -static void dvbc_eq_reset(void) -{ - dvbc_sw_reset(0x50, 3); -} - -static void dvbc_eq_smma_reset(void) -{ - dvbc_sw_reset(0xe8, 0); -} -#endif -static void dvbc_reg_initial(struct aml_demod_sta *demod_sta) -{ - u32 clk_freq; - u32 adc_freq; - u8 tuner; - u8 ch_mode; - u8 agc_mode; - u32 ch_freq; - u16 ch_if; - u16 ch_bw; - u16 symb_rate; - u32 phs_cfg; - int afifo_ctr; - int max_frq_off, tmp; - - clk_freq = demod_sta->clk_freq; /* kHz */ - adc_freq = demod_sta->adc_freq; /* kHz */ -/* adc_freq = 25414;*/ - tuner = demod_sta->tuner; - ch_mode = demod_sta->ch_mode; - agc_mode = demod_sta->agc_mode; - ch_freq = demod_sta->ch_freq; /* kHz */ - ch_if = demod_sta->ch_if; /* kHz */ - ch_bw = demod_sta->ch_bw; /* kHz */ - symb_rate = demod_sta->symb_rate; /* k/sec */ - dprintk("ch_if is %d, %d, %d, %d, %d\n", - ch_if, ch_mode, ch_freq, ch_bw, symb_rate); -/* ch_mode=4;*/ -/* apb_write_reg(DEMOD_CFG_BASE,0x00000007);*/ - /* disable irq */ - apb_write_reg(QAM_BASE + 0xd0, 0); - - /* reset */ - /*dvbc_reset(); */ - apb_write_reg(QAM_BASE + 0x4, apb_read_reg(QAM_BASE + 0x4) & ~(1 << 4)); - /* disable fsm_en */ - apb_write_reg(QAM_BASE + 0x4, apb_read_reg(QAM_BASE + 0x4) & ~(1 << 0)); - /* Sw disable demod */ - apb_write_reg(QAM_BASE + 0x4, apb_read_reg(QAM_BASE + 0x4) | (1 << 0)); - /* Sw enable demod */ - - apb_write_reg(QAM_BASE + 0x000, 0x00000000); - /* QAM_STATUS */ - apb_write_reg(QAM_BASE + 0x004, 0x00000f00); - /* QAM_GCTL0 */ - apb_write_reg(QAM_BASE + 0x008, (ch_mode & 7)); - /* qam mode */ - - switch (ch_mode) { - case 0: /* 16 QAM */ - apb_write_reg(QAM_BASE + 0x054, 0x23460224); - /* EQ_FIR_CTL, */ - apb_write_reg(QAM_BASE + 0x068, 0x00c000c0); - /* EQ_CRTH_SNR */ - apb_write_reg(QAM_BASE + 0x074, 0x50001a0); - /* EQ_TH_LMS 40db 13db */ - apb_write_reg(QAM_BASE + 0x07c, 0x003001e9); - /* EQ_NORM and EQ_TH_MMA */ - /*apb_write_reg(QAM_BASE+0x080, 0x000be1ff); - * // EQ_TH_SMMA0 - */ - apb_write_reg(QAM_BASE + 0x080, 0x000e01fe); - /* EQ_TH_SMMA0 */ - apb_write_reg(QAM_BASE + 0x084, 0x00000000); - /* EQ_TH_SMMA1 */ - apb_write_reg(QAM_BASE + 0x088, 0x00000000); - /* EQ_TH_SMMA2 */ - apb_write_reg(QAM_BASE + 0x08c, 0x00000000); - /* EQ_TH_SMMA3 */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2b); - * // AGC_CTRL ALPS tuner - */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292b); - * // Pilips Tuner - */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292d); - * // Pilips Tuner - */ - apb_write_reg(QAM_BASE + 0x094, 0x7f80092d); - /* Pilips Tuner */ - apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f67); - /* by raymond 20121213 */ - break; - - case 1: /* 32 QAM */ - apb_write_reg(QAM_BASE + 0x054, 0x24560506); - /* EQ_FIR_CTL, */ - apb_write_reg(QAM_BASE + 0x068, 0x00c000c0); - /* EQ_CRTH_SNR */ - /*apb_write_reg(QAM_BASE+0x074, 0x5000260); - * // EQ_TH_LMS 40db 19db - */ - apb_write_reg(QAM_BASE + 0x074, 0x50001f0); - /* EQ_TH_LMS 40db 17.5db */ - apb_write_reg(QAM_BASE + 0x07c, 0x00500102); - /* EQ_TH_MMA 0x000001cc */ - apb_write_reg(QAM_BASE + 0x080, 0x00077140); - /* EQ_TH_SMMA0 */ - apb_write_reg(QAM_BASE + 0x084, 0x001fb000); - /* EQ_TH_SMMA1 */ - apb_write_reg(QAM_BASE + 0x088, 0x00000000); - /* EQ_TH_SMMA2 */ - apb_write_reg(QAM_BASE + 0x08c, 0x00000000); - /* EQ_TH_SMMA3 */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2b); - * // AGC_CTRL ALPS tuner - */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292b); - * // Pilips Tuner - */ - apb_write_reg(QAM_BASE + 0x094, 0x7f80092b); - /* Pilips Tuner */ - apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f67); - /* by raymond 20121213 */ - break; - - case 2: /* 64 QAM */ - /*apb_write_reg(QAM_BASE+0x054, 0x2256033a); - * // EQ_FIR_CTL, - */ - apb_write_reg(QAM_BASE + 0x054, 0x2336043a); - /* EQ_FIR_CTL, by raymond */ - apb_write_reg(QAM_BASE + 0x068, 0x00c000c0); - /* EQ_CRTH_SNR */ - /*apb_write_reg(QAM_BASE+0x074, 0x5000260); - * // EQ_TH_LMS 40db 19db - */ - apb_write_reg(QAM_BASE + 0x074, 0x5000230); - /* EQ_TH_LMS 40db 17.5db */ - apb_write_reg(QAM_BASE + 0x07c, 0x007001bd); - /* EQ_TH_MMA */ - apb_write_reg(QAM_BASE + 0x080, 0x000580ed); - /* EQ_TH_SMMA0 */ - apb_write_reg(QAM_BASE + 0x084, 0x001771fb); - /* EQ_TH_SMMA1 */ - apb_write_reg(QAM_BASE + 0x088, 0x00000000); - /* EQ_TH_SMMA2 */ - apb_write_reg(QAM_BASE + 0x08c, 0x00000000); - /* EQ_TH_SMMA3 */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2c); - * // AGC_CTRL ALPS tuner - */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292c); - * // Pilips & maxlinear Tuner - */ - apb_write_reg(QAM_BASE + 0x094, 0x7f802b3d); - /* Pilips Tuner & maxlinear Tuner */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f802b3a); - * // Pilips Tuner & maxlinear Tuner - */ - apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f67); - /* by raymond 20121213 */ - break; - - case 3: /* 128 QAM */ - /*apb_write_reg(QAM_BASE+0x054, 0x2557046a); - * // EQ_FIR_CTL, - */ - apb_write_reg(QAM_BASE + 0x054, 0x2437067a); - /* EQ_FIR_CTL, by raymond 20121213 */ - apb_write_reg(QAM_BASE + 0x068, 0x00c000d0); - /* EQ_CRTH_SNR */ - /* apb_write_reg(QAM_BASE+0x074, 0x02440240); - * // EQ_TH_LMS 18.5db 18db - */ - /* apb_write_reg(QAM_BASE+0x074, 0x04000400); - * // EQ_TH_LMS 22db 22.5db - */ - apb_write_reg(QAM_BASE + 0x074, 0x5000260); - /* EQ_TH_LMS 40db 19db */ - /*apb_write_reg(QAM_BASE+0x07c, 0x00b000f2); - * // EQ_TH_MMA0x000000b2 - */ - apb_write_reg(QAM_BASE + 0x07c, 0x00b00132); - /* EQ_TH_MMA0x000000b2 by raymond 20121213 */ - apb_write_reg(QAM_BASE + 0x080, 0x0003a09d); - /* EQ_TH_SMMA0 */ - apb_write_reg(QAM_BASE + 0x084, 0x000f8150); - /* EQ_TH_SMMA1 */ - apb_write_reg(QAM_BASE + 0x088, 0x001a51f8); - /* EQ_TH_SMMA2 */ - apb_write_reg(QAM_BASE + 0x08c, 0x00000000); - /* EQ_TH_SMMA3 */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2c); - * // AGC_CTRL ALPS tuner - */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292c); - * // Pilips Tuner - */ - apb_write_reg(QAM_BASE + 0x094, 0x7f80092c); - /* Pilips Tuner */ - apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f67); - /* by raymond 20121213 */ - break; - - case 4: /* 256 QAM */ - /*apb_write_reg(QAM_BASE+0x054, 0xa2580588); - * // EQ_FIR_CTL, - */ - apb_write_reg(QAM_BASE + 0x054, 0xa25905f9); - /* EQ_FIR_CTL, by raymond 20121213 */ - apb_write_reg(QAM_BASE + 0x068, 0x01e00220); - /* EQ_CRTH_SNR */ - /*apb_write_reg(QAM_BASE+0x074, 0x50002a0); - * // EQ_TH_LMS 40db 19db - */ - apb_write_reg(QAM_BASE + 0x074, 0x5000270); - /* EQ_TH_LMS 40db 19db by raymond 201211213 */ - apb_write_reg(QAM_BASE + 0x07c, 0x00f001a5); - /* EQ_TH_MMA */ - apb_write_reg(QAM_BASE + 0x080, 0x0002c077); - /* EQ_TH_SMMA0 */ - apb_write_reg(QAM_BASE + 0x084, 0x000bc0fe); - /* EQ_TH_SMMA1 */ - apb_write_reg(QAM_BASE + 0x088, 0x0013f17e); - /* EQ_TH_SMMA2 */ - apb_write_reg(QAM_BASE + 0x08c, 0x01bc01f9); - /* EQ_TH_SMMA3 */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2c); - * // AGC_CTRL ALPS tuner - */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292c); - * // Pilips Tuner - */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292d); - * // Maxlinear Tuner - */ - apb_write_reg(QAM_BASE + 0x094, 0x7f80092d); - /* Maxlinear Tuner */ - apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f67); - /* by raymond 20121213, when adc=35M,sys=70M, - * its better than 0x61f2f66 - */ - break; - default: /*64qam */ - /*apb_write_reg(QAM_BASE+0x054, 0x2256033a); - * // EQ_FIR_CTL, - */ - apb_write_reg(QAM_BASE + 0x054, 0x2336043a); - /* EQ_FIR_CTL, by raymond */ - apb_write_reg(QAM_BASE + 0x068, 0x00c000c0); - /* EQ_CRTH_SNR */ - /* EQ_TH_LMS 40db 19db */ - apb_write_reg(QAM_BASE + 0x074, 0x5000230); - /* EQ_TH_LMS 40db 17.5db */ - apb_write_reg(QAM_BASE + 0x07c, 0x007001bd); - /* EQ_TH_MMA */ - apb_write_reg(QAM_BASE + 0x080, 0x000580ed); - /* EQ_TH_SMMA0 */ - apb_write_reg(QAM_BASE + 0x084, 0x001771fb); - /* EQ_TH_SMMA1 */ - apb_write_reg(QAM_BASE + 0x088, 0x00000000); - /* EQ_TH_SMMA2 */ - apb_write_reg(QAM_BASE + 0x08c, 0x00000000); - /* EQ_TH_SMMA3 */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f800d2c); - * // AGC_CTRL ALPS tuner - */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292c); - * // Pilips & maxlinear Tuner - */ - apb_write_reg(QAM_BASE + 0x094, 0x7f802b3d); - /* Pilips Tuner & maxlinear Tuner */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f802b3a); - * // Pilips Tuner & maxlinear Tuner - */ - apb_write_reg(QAM_BASE + 0x0c0, 0x061f2f67); - /* by raymond 20121213 */ - break; - } - - /*apb_write_reg(QAM_BASE+0x00c, 0xfffffffe); - * // adc_cnt, symb_cnt - */ - apb_write_reg(QAM_BASE + 0x00c, 0xffff8ffe); - /* adc_cnt, symb_cnt by raymond 20121213 */ - if (clk_freq == 0) - afifo_ctr = 0; - else - afifo_ctr = (adc_freq * 256 / clk_freq) + 2; - if (afifo_ctr > 255) - afifo_ctr = 255; - apb_write_reg(QAM_BASE + 0x010, (afifo_ctr << 16) | 8000); - /* afifo, rs_cnt_cfg */ - - /*apb_write_reg(QAM_BASE+0x020, 0x21353e54); - * // PHS_reset & TIM_CTRO_ACCURATE sw_tim_select=0 - */ - /*apb_write_reg(QAM_BASE+0x020, 0x21b53e54); - * //modified by qiancheng - */ - apb_write_reg(QAM_BASE + 0x020, 0x61b53e54); - /*modified by qiancheng by raymond 20121208 0x63b53e54 for cci */ - /* apb_write_reg(QAM_BASE+0x020, 0x6192bfe2); - * //modifed by ligg 20130613 auto symb_rate scan - */ - if (adc_freq == 0) - phs_cfg = 0; - else - phs_cfg = (1 << 31) / adc_freq * ch_if / (1 << 8); - /* 8*fo/fs*2^20 fo=36.125, fs = 28.57114, = 21d775 */ - /* dprintk("phs_cfg = %x\n", phs_cfg); */ - apb_write_reg(QAM_BASE + 0x024, 0x4c000000 | (phs_cfg & 0x7fffff)); - /* PHS_OFFSET, IF offset, */ - - if (adc_freq == 0) { - max_frq_off = 0; - } else { - max_frq_off = (1 << 29) / symb_rate; - /* max_frq_off = (400KHz * 2^29) / - * (AD=28571 * symbol_rate=6875) - */ - tmp = 40000000 / adc_freq; - max_frq_off = tmp * max_frq_off; - } - dprintk("max_frq_off is %x,\n", max_frq_off); - apb_write_reg(QAM_BASE + 0x02c, max_frq_off & 0x3fffffff); - /* max frequency offset, by raymond 20121208 */ - - /*apb_write_reg(QAM_BASE+0x030, 0x011bf400); - * // TIM_CTL0 start speed is 0, when know symbol rate - */ - apb_write_reg(QAM_BASE + 0x030, 0x245cf451); - /*MODIFIED BY QIANCHENG */ -/* apb_write_reg(QAM_BASE+0x030, 0x245bf451); - * //modified by ligg 20130613 --auto symb_rate scan - */ - apb_write_reg(QAM_BASE + 0x034, - ((adc_freq & 0xffff) << 16) | (symb_rate & 0xffff)); - - apb_write_reg(QAM_BASE + 0x038, 0x00400000); - /* TIM_SWEEP_RANGE 16000 */ - -/************* hw state machine config **********/ - apb_write_reg(QAM_BASE + 0x040, 0x003c); -/* configure symbol rate step step 0*/ - - /* modified 0x44 0x48 */ - apb_write_reg(QAM_BASE + 0x044, (symb_rate & 0xffff) * 256); - /* blind search, configure max symbol_rate for 7218 fb=3.6M */ - /*apb_write_reg(QAM_BASE+0x048, 3600*256); - * // configure min symbol_rate fb = 6.95M - */ - apb_write_reg(QAM_BASE + 0x048, 3400 * 256); - /* configure min symbol_rate fb = 6.95M */ - - /*apb_write_reg(QAM_BASE+0x0c0, 0xffffff68); // threshold */ - /*apb_write_reg(QAM_BASE+0x0c0, 0xffffff6f); // threshold */ - /*apb_write_reg(QAM_BASE+0x0c0, 0xfffffd68); // threshold */ - /*apb_write_reg(QAM_BASE+0x0c0, 0xffffff68); // threshold */ - /*apb_write_reg(QAM_BASE+0x0c0, 0xffffff68); // threshold */ - /*apb_write_reg(QAM_BASE+0x0c0, 0xffff2f67); - * // threshold for skyworth - */ - /* apb_write_reg(QAM_BASE+0x0c0, 0x061f2f67); // by raymond 20121208 */ - /* apb_write_reg(QAM_BASE+0x0c0, 0x061f2f66); - * // by raymond 20121213, remove it to every constellation - */ -/************* hw state machine config **********/ - - apb_write_reg(QAM_BASE + 0x04c, 0x00008800); /* reserved */ - - /*apb_write_reg(QAM_BASE+0x050, 0x00000002); // EQ_CTL0 */ - apb_write_reg(QAM_BASE + 0x050, 0x01472002); - /* EQ_CTL0 by raymond 20121208 */ - - /*apb_write_reg(QAM_BASE+0x058, 0xff550e1e); // EQ_FIR_INITPOS */ - apb_write_reg(QAM_BASE + 0x058, 0xff100e1e); - /* EQ_FIR_INITPOS for skyworth */ - - apb_write_reg(QAM_BASE + 0x05c, 0x019a0000); /* EQ_FIR_INITVAL0 */ - apb_write_reg(QAM_BASE + 0x060, 0x019a0000); /* EQ_FIR_INITVAL1 */ - - /*apb_write_reg(QAM_BASE+0x064, 0x01101128); // EQ_CRTH_TIMES */ - apb_write_reg(QAM_BASE + 0x064, 0x010a1128); - /* EQ_CRTH_TIMES for skyworth */ - apb_write_reg(QAM_BASE + 0x06c, 0x00041a05); /* EQ_CRTH_PPM */ - - apb_write_reg(QAM_BASE + 0x070, 0xffb9aa01); /* EQ_CRLP */ - - /*apb_write_reg(QAM_BASE+0x090, 0x00020bd5); // agc control */ - apb_write_reg(QAM_BASE + 0x090, 0x00000bd5); /* agc control */ - - /* agc control */ - /* apb_write_reg(QAM_BASE+0x094, 0x7f800d2c);// AGC_CTRL ALPS tuner */ - /* apb_write_reg(QAM_BASE+0x094, 0x7f80292c); // Pilips Tuner */ - if ((agc_mode & 1) == 0) - /* freeze if agc */ - apb_write_reg(QAM_BASE + 0x094, - apb_read_reg(QAM_BASE + 0x94) | (0x1 << 10)); - if ((agc_mode & 2) == 0) { - /* IF control */ - /*freeze rf agc */ - apb_write_reg(QAM_BASE + 0x094, - apb_read_reg(QAM_BASE + 0x94) | (0x1 << 13)); - } - /*Maxlinear Tuner */ - /*apb_write_reg(QAM_BASE+0x094, 0x7f80292d); */ - apb_write_reg(QAM_BASE + 0x098, 0x9fcc8190); - /* AGC_IFGAIN_CTRL */ - /*apb_write_reg(QAM_BASE+0x0a0, 0x0e028c00); - * // AGC_RFGAIN_CTRL 0x0e020800 - */ - /*apb_write_reg(QAM_BASE+0x0a0, 0x0e03cc00); - * // AGC_RFGAIN_CTRL 0x0e020800 - */ - /*apb_write_reg(QAM_BASE+0x0a0, 0x0e028700); - * // AGC_RFGAIN_CTRL 0x0e020800 now - */ - /*apb_write_reg(QAM_BASE+0x0a0, 0x0e03cd00); - * // AGC_RFGAIN_CTRL 0x0e020800 - */ - /*apb_write_reg(QAM_BASE+0x0a0, 0x0603cd11); - * // AGC_RFGAIN_CTRL 0x0e020800 by raymond, - * if Adjcent channel test, maybe it need change.20121208 ad invert - */ - apb_write_reg(QAM_BASE + 0x0a0, 0x0603cd10); - /* AGC_RFGAIN_CTRL 0x0e020800 by raymond, - * if Adjcent channel test, maybe it need change. - * 20121208 ad invert,20130221, suit for two path channel. - */ - - apb_write_reg(QAM_BASE + 0x004, apb_read_reg(QAM_BASE + 0x004) | 0x33); - /* IMQ, QAM Enable */ - - /* start hardware machine */ - /*dvbc_sw_reset(0x004, 4); */ - apb_write_reg(QAM_BASE + 0x4, apb_read_reg(QAM_BASE + 0x4) | (1 << 4)); - apb_write_reg(QAM_BASE + 0x0e8, - (apb_read_reg(QAM_BASE + 0x0e8) | (1 << 2))); - - /* clear irq status */ - apb_read_reg(QAM_BASE + 0xd4); - - /* enable irq */ - apb_write_reg(QAM_BASE + 0xd0, 0x7fff << 3); - -/*auto track*/ - /* dvbc_set_auto_symtrack(); */ -} - -u32 dvbc_set_auto_symtrack(void) -{ - apb_write_reg(QAM_BASE + 0x030, 0x245bf45c); /*open track */ - apb_write_reg(QAM_BASE + 0x020, 0x61b2bf5c); - apb_write_reg(QAM_BASE + 0x044, (7000 & 0xffff) * 256); - apb_write_reg(QAM_BASE + 0x038, 0x00220000); - apb_write_reg(QAM_BASE + 0x4, apb_read_reg(QAM_BASE + 0x4) & ~(1 << 0)); - /* Sw disable demod */ - apb_write_reg(QAM_BASE + 0x4, apb_read_reg(QAM_BASE + 0x4) | (1 << 0)); - /* Sw enable demod */ - return 0; -} - -int dvbc_set_ch(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c, - struct aml_demod_dvbc *demod_dvbc) -{ - int ret = 0; - u16 symb_rate; - u8 mode; - u32 ch_freq; - - dprintk("f=%d, s=%d, q=%d\n", - demod_dvbc->ch_freq, demod_dvbc->symb_rate, demod_dvbc->mode); - demod_i2c->tuner = 7; - mode = demod_dvbc->mode; - symb_rate = demod_dvbc->symb_rate; - ch_freq = demod_dvbc->ch_freq; - if (mode > 4) { - dprintk("Error: Invalid QAM mode option %d\n", mode); - mode = 2; - ret = -1; - } - - if (symb_rate < 1000 || symb_rate > 7000) { - dprintk("Error: Invalid Symbol Rate option %d\n", symb_rate); - symb_rate = 6875; - ret = -1; - } - - if (ch_freq < 1000 || ch_freq > 900000) { - dprintk("Error: Invalid Channel Freq option %d\n", ch_freq); - ch_freq = 474000; - ret = -1; - } - /* if (ret != 0) return ret; */ - demod_sta->dvb_mode = 0; - demod_sta->ch_mode = mode; - /* 0:16, 1:32, 2:64, 3:128, 4:256 */ - demod_sta->agc_mode = 1; - /* 0:NULL, 1:IF, 2:RF, 3:both */ - demod_sta->ch_freq = ch_freq; - demod_sta->tuner = demod_i2c->tuner; - - if (demod_i2c->tuner == 1) - demod_sta->ch_if = 36130; /* TODO DCT tuner */ - else if (demod_i2c->tuner == 2) - demod_sta->ch_if = 4570; /* TODO Maxlinear tuner */ - else if (demod_i2c->tuner == 7) - /* demod_sta->ch_if = 5000; // TODO Si2176 tuner */ - - demod_sta->ch_bw = 8000; /* TODO */ - if (demod_sta->ch_if == 0) - demod_sta->ch_if = 5000; - demod_sta->symb_rate = symb_rate; - dvbc_reg_initial(demod_sta); - - return ret; -} - -int dvbc_status(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c, - struct aml_demod_sts *demod_sts) -{ - struct aml_fe_dev *dev; - -/* int ftmp, tmp; */ - dev = NULL; - demod_sts->ch_sts = apb_read_reg(QAM_BASE + 0x18); - demod_sts->ch_pow = dvbc_get_ch_power(); - demod_sts->ch_snr = dvbc_get_snr(); - demod_sts->ch_ber = dvbc_get_ber(); - demod_sts->ch_per = dvbc_get_per(); - demod_sts->symb_rate = dvbc_get_symb_rate(); - demod_sts->freq_off = dvbc_get_freq_off(); - /*demod_sts->dat0 = apb_read_reg(QAM_BASE+0x28); */ -/* demod_sts->dat0 = tuner_get_ch_power(demod_i2c);*/ - demod_sts->dat1 = tuner_get_ch_power(dev); -#if 0 - - ftmp = demod_sts->ch_sts; - dprintk("[dvbc debug] ch_sts is %x\n", ftmp); - ftmp = demod_sts->ch_snr; - ftmp /= 100; - dprintk("snr %d dB ", ftmp); - ftmp = demod_sts->ch_ber; - dprintk("ber %.d ", ftmp); - tmp = demod_sts->ch_per; - dprintk("per %d ", tmp); - ftmp = demod_sts->symb_rate; - dprintk("srate %.d ", ftmp); - ftmp = demod_sts->freq_off; - dprintk("freqoff %.d kHz ", ftmp); - tmp = demod_sts->dat1; - dprintk("strength %ddb 0xe0 status is %lu ,b4 status is %lu", tmp, - (apb_read_reg(QAM_BASE + 0xe0) & 0xffff), - (apb_read_reg(QAM_BASE + 0xb4) & 0xffff)); - dprintk("dagc_gain is %lu ", apb_read_reg(QAM_BASE + 0xa4) & 0x7f); - tmp = demod_sts->ch_pow; - dprintk("power is %ddb\n", (tmp & 0xffff)); - -#endif - - return 0; -} - -void dvbc_enable_irq(int dvbc_irq) -{ - u32 mask; - - /* clear status */ - apb_read_reg(QAM_BASE + 0xd4); - /* enable irq */ - mask = apb_read_reg(QAM_BASE + 0xd0); - mask |= (1 << dvbc_irq); - apb_write_reg(QAM_BASE + 0xd0, mask); -} - -void dvbc_disable_irq(int dvbc_irq) -{ - u32 mask; - - /* disable irq */ - mask = apb_read_reg(QAM_BASE + 0xd0); - mask &= ~(1 << dvbc_irq); - apb_write_reg(QAM_BASE + 0xd0, mask); - /* clear status */ - apb_read_reg(QAM_BASE + 0xd4); -} - -char *dvbc_irq_name[] = { - " ADC", - " Symbol", - " RS", - " In_Sync0", - " In_Sync1", - " In_Sync2", - " In_Sync3", - " In_Sync4", - "Out_Sync0", - "Out_Sync1", - "Out_Sync2", - "Out_Sync3", - "Out_Sync4", - "In_SyncCo", - "OutSyncCo", - " In_Dagc", - " Out_Dagc", - " Eq_Mode", - "RS_Uncorr" -}; - -void dvbc_isr(struct aml_demod_sta *demod_sta) -{ - u32 stat, mask; - int dvbc_irq; - - stat = apb_read_reg(QAM_BASE + 0xd4); - mask = apb_read_reg(QAM_BASE + 0xd0); - stat &= mask; - - for (dvbc_irq = 0; dvbc_irq < 20; dvbc_irq++) { - if (stat >> dvbc_irq & 1) { - if (demod_sta->debug) - dprintk("irq: dvbc %2d %s %8x\n", - dvbc_irq, dvbc_irq_name[dvbc_irq], - stat); - /* dvbc_disable_irq(dvbc_irq); */ - } - } -} - -int dvbc_isr_islock(void) -{ -#define IN_SYNC4_MASK (0x80) - - u32 stat, mask; - - stat = apb_read_reg(QAM_BASE + 0xd4); - apb_write_reg(QAM_BASE + 0xd4, 0); - mask = apb_read_reg(QAM_BASE + 0xd0); - stat &= mask; - - return (stat & IN_SYNC4_MASK) == IN_SYNC4_MASK; -} diff --git a/drivers/stream_input/tv_frontend/dtv_demod/dvbt_func.c b/drivers/stream_input/tv_frontend/dtv_demod/dvbt_func.c deleted file mode 100644 index 7654aae..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/dvbt_func.c +++ b/dev/null @@ -1,2188 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#include -#include -#include -#include -#include "demod_func.h" - -static int debug_amldvbt; - -module_param(debug_amldvbt, int, 0644); -MODULE_PARM_DESC(debug_amldvbt, "turn on debugging (default: 0)"); -#define dprintk(args ...) do { if (debug_amldvbt) printk(args); } while (0) - -static int tuner_type = 3; - -static void set_ACF_coef(int ADsample, int bandwidth) -{ - if (ADsample == 45) { - /* Set ACF and IIREQ */ - if (bandwidth == 0) { - /*8M Hz */ - apb_write_reg(2, 0x2c, 0x255); /* ACF_STAGE1_A1 */ - apb_write_reg(2, 0x2d, 0x0B5); /* ACF_STAGE1_A2 */ - apb_write_reg(2, 0x2e, 0x091); /* ACF_STAGE1_B1 */ - apb_write_reg(2, 0x2f, 0x02E); /* ACF_STAGE1_GAIN */ - apb_write_reg(2, 0x30, 0x253); /* ACF_STAGE2_A1 */ - apb_write_reg(2, 0x31, 0x0CB); /* ACF_STAGE2_A2 */ - apb_write_reg(2, 0x32, 0x2CD); /* ACF_STAGE2_B1 */ - apb_write_reg(2, 0x33, 0x07C); /* ACF_STAGE2_GAIN */ - apb_write_reg(2, 0x34, 0x250); /* ACF_STAGE3_A1 */ - apb_write_reg(2, 0x35, 0x0E4); /* ACF_STAGE3_A2 */ - apb_write_reg(2, 0x36, 0x276); /* ACF_STAGE3_B1 */ - apb_write_reg(2, 0x37, 0x05D); /* ACF_STAGE3_GAIN */ - apb_write_reg(2, 0x38, 0x24D); /* ACF_STAGE4_A1 */ - apb_write_reg(2, 0x39, 0x0F3); /* ACF_STAGE4_A2 */ - apb_write_reg(2, 0x3a, 0x25E); /* ACF_STAGE4_B1 */ - apb_write_reg(2, 0x3b, 0x05A); /* ACF_STAGE4_GAIN */ - apb_write_reg(2, 0x3c, 0x24A); /* ACF_STAGE5_A1 */ - apb_write_reg(2, 0x3d, 0x0FD); /* ACF_STAGE5_A2 */ - apb_write_reg(2, 0x3e, 0x256); /* ACF_STAGE5_B1 */ - apb_write_reg(2, 0x3f, 0x04B); /* ACF_STAGE5_GAIN */ - - apb_write_reg(2, 0xfe, 0x000); - apb_write_reg(2, 0xff, 0x003effff); - apb_write_reg(2, 0xfe, 0x001); - apb_write_reg(2, 0xff, 0x003cefbe); - apb_write_reg(2, 0xfe, 0x002); - apb_write_reg(2, 0xff, 0x003adf7c); - apb_write_reg(2, 0xfe, 0x003); - apb_write_reg(2, 0xff, 0x0038bf39); - apb_write_reg(2, 0xfe, 0x004); - apb_write_reg(2, 0xff, 0x003696f5); - apb_write_reg(2, 0xfe, 0x005); - apb_write_reg(2, 0xff, 0x003466b0); - apb_write_reg(2, 0xfe, 0x006); - apb_write_reg(2, 0xff, 0x00322e69); - apb_write_reg(2, 0xfe, 0x007); - apb_write_reg(2, 0xff, 0x002fee21); - apb_write_reg(2, 0xfe, 0x008); - apb_write_reg(2, 0xff, 0x002dadd9); - apb_write_reg(2, 0xfe, 0x009); - apb_write_reg(2, 0xff, 0x002b6d91); - apb_write_reg(2, 0xfe, 0x00a); - apb_write_reg(2, 0xff, 0x00291d48); - apb_write_reg(2, 0xfe, 0x00b); - apb_write_reg(2, 0xff, 0x0026ccfe); - apb_write_reg(2, 0xfe, 0x00c); - apb_write_reg(2, 0xff, 0x00245cb2); - apb_write_reg(2, 0xfe, 0x00d); - apb_write_reg(2, 0xff, 0x0021d463); - apb_write_reg(2, 0xfe, 0x00e); - apb_write_reg(2, 0xff, 0x001f2410); - apb_write_reg(2, 0xfe, 0x00f); - apb_write_reg(2, 0xff, 0x001c3bb6); - apb_write_reg(2, 0xfe, 0x010); - apb_write_reg(2, 0xff, 0x00192b57); - apb_write_reg(2, 0xfe, 0x011); - apb_write_reg(2, 0xff, 0x0015e2f1); - apb_write_reg(2, 0xfe, 0x012); - apb_write_reg(2, 0xff, 0x00127285); - apb_write_reg(2, 0xfe, 0x013); - apb_write_reg(2, 0xff, 0x000eca14); - apb_write_reg(2, 0xfe, 0x014); - apb_write_reg(2, 0xff, 0x000ac99b); - apb_write_reg(2, 0xfe, 0x015); - apb_write_reg(2, 0xff, 0x00063913); - apb_write_reg(2, 0xfe, 0x016); - apb_write_reg(2, 0xff, 0x0000c073); - apb_write_reg(2, 0xfe, 0x017); - apb_write_reg(2, 0xff, 0x003a3fb4); - apb_write_reg(2, 0xfe, 0x018); - apb_write_reg(2, 0xff, 0x00347ecf); - apb_write_reg(2, 0xfe, 0x019); - apb_write_reg(2, 0xff, 0x002ff649); - apb_write_reg(2, 0xfe, 0x01a); - apb_write_reg(2, 0xff, 0x002a8dab); - apb_write_reg(2, 0xfe, 0x01b); - apb_write_reg(2, 0xff, 0x002444f0); - apb_write_reg(2, 0xfe, 0x01c); - apb_write_reg(2, 0xff, 0x001d0c1b); - apb_write_reg(2, 0xfe, 0x01d); - apb_write_reg(2, 0xff, 0x000fc300); - apb_write_reg(2, 0xfe, 0x01e); - apb_write_reg(2, 0xff, 0x000118ce); - apb_write_reg(2, 0xfe, 0x01f); - apb_write_reg(2, 0xff, 0x003c17c3); - apb_write_reg(2, 0xfe, 0x020); - apb_write_reg(2, 0xff, 0x00000751); - } else if (bandwidth == 1) { - /* 7Mhz */ - apb_write_reg(2, 0x2c, 0x24B); /* ACF_STAGE1_A1 */ - apb_write_reg(2, 0x2d, 0x0BD); /* ACF_STAGE1_A2 */ - apb_write_reg(2, 0x2e, 0x04B); /* ACF_STAGE1_B1 */ - apb_write_reg(2, 0x2f, 0x03E); /* ACF_STAGE1_GAIN */ - apb_write_reg(2, 0x30, 0x246); /* ACF_STAGE2_A1 */ - apb_write_reg(2, 0x31, 0x0D1); /* ACF_STAGE2_A2 */ - apb_write_reg(2, 0x32, 0x2A2); /* ACF_STAGE2_B1 */ - apb_write_reg(2, 0x33, 0x07C); /* ACF_STAGE2_GAIN */ - apb_write_reg(2, 0x34, 0x241); /* ACF_STAGE3_A1 */ - apb_write_reg(2, 0x35, 0x0E7); /* ACF_STAGE3_A2 */ - apb_write_reg(2, 0x36, 0x25B); /* ACF_STAGE3_B1 */ - apb_write_reg(2, 0x37, 0x05D); /* ACF_STAGE3_GAIN */ - apb_write_reg(2, 0x38, 0x23D); /* ACF_STAGE4_A1 */ - apb_write_reg(2, 0x39, 0x0F5); /* ACF_STAGE4_A2 */ - apb_write_reg(2, 0x3a, 0x248); /* ACF_STAGE4_B1 */ - apb_write_reg(2, 0x3b, 0x05A); /* ACF_STAGE4_GAIN */ - apb_write_reg(2, 0x3c, 0x23A); /* ACF_STAGE5_A1 */ - apb_write_reg(2, 0x3d, 0x0FD); /* ACF_STAGE5_A2 */ - apb_write_reg(2, 0x3e, 0x242); /* ACF_STAGE5_B1 */ - apb_write_reg(2, 0x3f, 0x04B); /* ACF_STAGE5_GAIN */ - apb_write_reg(2, 0xfe, 0x000); - apb_write_reg(2, 0xff, 0x003f07ff); - apb_write_reg(2, 0xfe, 0x001); - apb_write_reg(2, 0xff, 0x003cffbf); - apb_write_reg(2, 0xfe, 0x002); - apb_write_reg(2, 0xff, 0x003aef7e); - apb_write_reg(2, 0xfe, 0x003); - apb_write_reg(2, 0xff, 0x0038d73c); - apb_write_reg(2, 0xfe, 0x004); - apb_write_reg(2, 0xff, 0x0036b6f9); - apb_write_reg(2, 0xfe, 0x005); - apb_write_reg(2, 0xff, 0x003486b3); - apb_write_reg(2, 0xfe, 0x006); - apb_write_reg(2, 0xff, 0x00324e6d); - apb_write_reg(2, 0xfe, 0x007); - apb_write_reg(2, 0xff, 0x00300e25); - apb_write_reg(2, 0xfe, 0x008); - apb_write_reg(2, 0xff, 0x002dcddd); - apb_write_reg(2, 0xfe, 0x009); - apb_write_reg(2, 0xff, 0x002b8594); - apb_write_reg(2, 0xfe, 0x00a); - apb_write_reg(2, 0xff, 0x00292d4b); - apb_write_reg(2, 0xfe, 0x00b); - apb_write_reg(2, 0xff, 0x0026d500); - apb_write_reg(2, 0xfe, 0x00c); - apb_write_reg(2, 0xff, 0x00245cb3); - apb_write_reg(2, 0xfe, 0x00d); - apb_write_reg(2, 0xff, 0x0021cc62); - apb_write_reg(2, 0xfe, 0x00e); - apb_write_reg(2, 0xff, 0x001f0c0d); - apb_write_reg(2, 0xfe, 0x00f); - apb_write_reg(2, 0xff, 0x001c1bb3); - apb_write_reg(2, 0xfe, 0x010); - apb_write_reg(2, 0xff, 0x0018fb52); - apb_write_reg(2, 0xfe, 0x011); - apb_write_reg(2, 0xff, 0x0015b2eb); - apb_write_reg(2, 0xfe, 0x012); - apb_write_reg(2, 0xff, 0x00123a7f); - apb_write_reg(2, 0xfe, 0x013); - apb_write_reg(2, 0xff, 0x000e9a0e); - apb_write_reg(2, 0xfe, 0x014); - apb_write_reg(2, 0xff, 0x000a9995); - apb_write_reg(2, 0xfe, 0x015); - apb_write_reg(2, 0xff, 0x0006090d); - apb_write_reg(2, 0xfe, 0x016); - apb_write_reg(2, 0xff, 0x0000a06e); - apb_write_reg(2, 0xfe, 0x017); - apb_write_reg(2, 0xff, 0x003a57b3); - apb_write_reg(2, 0xfe, 0x018); - apb_write_reg(2, 0xff, 0x0034ded8); - apb_write_reg(2, 0xfe, 0x019); - apb_write_reg(2, 0xff, 0x00309659); - apb_write_reg(2, 0xfe, 0x01a); - apb_write_reg(2, 0xff, 0x002b75c4); - apb_write_reg(2, 0xfe, 0x01b); - apb_write_reg(2, 0xff, 0x0025350e); - apb_write_reg(2, 0xfe, 0x01c); - apb_write_reg(2, 0xff, 0x001dec37); - apb_write_reg(2, 0xfe, 0x01d); - apb_write_reg(2, 0xff, 0x00126b28); - apb_write_reg(2, 0xfe, 0x01e); - apb_write_reg(2, 0xff, 0x00031130); - apb_write_reg(2, 0xfe, 0x01f); - apb_write_reg(2, 0xff, 0x003cffec); - apb_write_reg(2, 0xfe, 0x020); - apb_write_reg(2, 0xff, 0x00000767); - } else if (bandwidth == 2) { - /* 6MHz */ - apb_write_reg(2, 0x2c, 0x240); /* ACF_STAGE1_A1 */ - apb_write_reg(2, 0x2d, 0x0C6); /* ACF_STAGE1_A2 */ - apb_write_reg(2, 0x2e, 0x3F9); /* ACF_STAGE1_B1 */ - apb_write_reg(2, 0x2f, 0x03E); /* ACF_STAGE1_GAIN */ - apb_write_reg(2, 0x30, 0x23A); /* ACF_STAGE2_A1 */ - apb_write_reg(2, 0x31, 0x0D7); /* ACF_STAGE2_A2 */ - apb_write_reg(2, 0x32, 0x27B); /* ACF_STAGE2_B1 */ - apb_write_reg(2, 0x33, 0x07C); /* ACF_STAGE2_GAIN */ - apb_write_reg(2, 0x34, 0x233); /* ACF_STAGE3_A1 */ - apb_write_reg(2, 0x35, 0x0EA); /* ACF_STAGE3_A2 */ - apb_write_reg(2, 0x36, 0x244); /* ACF_STAGE3_B1 */ - apb_write_reg(2, 0x37, 0x05D); /* ACF_STAGE3_GAIN */ - apb_write_reg(2, 0x38, 0x22F); /* ACF_STAGE4_A1 */ - apb_write_reg(2, 0x39, 0x0F6); /* ACF_STAGE4_A2 */ - apb_write_reg(2, 0x3a, 0x235); /* ACF_STAGE4_B1 */ - apb_write_reg(2, 0x3b, 0x05A); /* ACF_STAGE4_GAIN */ - apb_write_reg(2, 0x3c, 0x22B); /* ACF_STAGE5_A1 */ - apb_write_reg(2, 0x3d, 0x0FD); /* ACF_STAGE5_A2 */ - apb_write_reg(2, 0x3e, 0x231); /* ACF_STAGE5_B1 */ - apb_write_reg(2, 0x3f, 0x04B); /* ACF_STAGE5_GAIN */ - apb_write_reg(2, 0xfe, 0x000); - apb_write_reg(2, 0xff, 0x003f07ff); - apb_write_reg(2, 0xfe, 0x001); - apb_write_reg(2, 0xff, 0x003cffbf); - apb_write_reg(2, 0xfe, 0x002); - apb_write_reg(2, 0xff, 0x003aef7e); - apb_write_reg(2, 0xfe, 0x003); - apb_write_reg(2, 0xff, 0x0038d73c); - apb_write_reg(2, 0xfe, 0x004); - apb_write_reg(2, 0xff, 0x0036b6f8); - apb_write_reg(2, 0xfe, 0x005); - apb_write_reg(2, 0xff, 0x003486b3); - apb_write_reg(2, 0xfe, 0x006); - apb_write_reg(2, 0xff, 0x0032466c); - apb_write_reg(2, 0xfe, 0x007); - apb_write_reg(2, 0xff, 0x002ffe24); - apb_write_reg(2, 0xfe, 0x008); - apb_write_reg(2, 0xff, 0x002dadda); - apb_write_reg(2, 0xfe, 0x009); - apb_write_reg(2, 0xff, 0x002b5d90); - apb_write_reg(2, 0xfe, 0x00a); - apb_write_reg(2, 0xff, 0x0028fd45); - apb_write_reg(2, 0xfe, 0x00b); - apb_write_reg(2, 0xff, 0x002694f9); - apb_write_reg(2, 0xfe, 0x00c); - apb_write_reg(2, 0xff, 0x002414ab); - apb_write_reg(2, 0xfe, 0x00d); - apb_write_reg(2, 0xff, 0x00217458); - apb_write_reg(2, 0xfe, 0x00e); - apb_write_reg(2, 0xff, 0x001ea402); - apb_write_reg(2, 0xfe, 0x00f); - apb_write_reg(2, 0xff, 0x001ba3a5); - apb_write_reg(2, 0xfe, 0x010); - apb_write_reg(2, 0xff, 0x00187342); - apb_write_reg(2, 0xfe, 0x011); - apb_write_reg(2, 0xff, 0x00151ad9); - apb_write_reg(2, 0xfe, 0x012); - apb_write_reg(2, 0xff, 0x0011926b); - apb_write_reg(2, 0xfe, 0x013); - apb_write_reg(2, 0xff, 0x000dc9f6); - apb_write_reg(2, 0xfe, 0x014); - apb_write_reg(2, 0xff, 0x0009a178); - apb_write_reg(2, 0xfe, 0x015); - apb_write_reg(2, 0xff, 0x0004d8eb); - apb_write_reg(2, 0xfe, 0x016); - apb_write_reg(2, 0xff, 0x003f4045); - apb_write_reg(2, 0xfe, 0x017); - apb_write_reg(2, 0xff, 0x0038e785); - apb_write_reg(2, 0xfe, 0x018); - apb_write_reg(2, 0xff, 0x00337eab); - apb_write_reg(2, 0xfe, 0x019); - apb_write_reg(2, 0xff, 0x002f3e2d); - apb_write_reg(2, 0xfe, 0x01a); - apb_write_reg(2, 0xff, 0x002a1599); - apb_write_reg(2, 0xfe, 0x01b); - apb_write_reg(2, 0xff, 0x0023ace1); - apb_write_reg(2, 0xfe, 0x01c); - apb_write_reg(2, 0xff, 0x001b33fb); - apb_write_reg(2, 0xfe, 0x01d); - apb_write_reg(2, 0xff, 0x000cd29c); - apb_write_reg(2, 0xfe, 0x01e); - apb_write_reg(2, 0xff, 0x0001c0c1); - apb_write_reg(2, 0xfe, 0x01f); - apb_write_reg(2, 0xff, 0x003cefde); - apb_write_reg(2, 0xfe, 0x020); - apb_write_reg(2, 0xff, 0x0000076a); - } else { - /* 5MHz */ - apb_write_reg(2, 0x2c, 0x236); /* ACF_STAGE1_A1 */ - apb_write_reg(2, 0x2d, 0x0CE); /* ACF_STAGE1_A2 */ - apb_write_reg(2, 0x2e, 0x39A); /* ACF_STAGE1_B1 */ - apb_write_reg(2, 0x2f, 0x03E); /* ACF_STAGE1_GAIN */ - apb_write_reg(2, 0x30, 0x22F); /* ACF_STAGE2_A1 */ - apb_write_reg(2, 0x31, 0x0DE); /* ACF_STAGE2_A2 */ - apb_write_reg(2, 0x32, 0x257); /* ACF_STAGE2_B1 */ - apb_write_reg(2, 0x33, 0x07C); /* ACF_STAGE2_GAIN */ - apb_write_reg(2, 0x34, 0x227); /* ACF_STAGE3_A1 */ - apb_write_reg(2, 0x35, 0x0EE); /* ACF_STAGE3_A2 */ - apb_write_reg(2, 0x36, 0x230); /* ACF_STAGE3_B1 */ - apb_write_reg(2, 0x37, 0x05D); /* ACF_STAGE3_GAIN */ - apb_write_reg(2, 0x38, 0x222); /* ACF_STAGE4_A1 */ - apb_write_reg(2, 0x39, 0x0F8); /* ACF_STAGE4_A2 */ - apb_write_reg(2, 0x3a, 0x225); /* ACF_STAGE4_B1 */ - apb_write_reg(2, 0x3b, 0x05A); /* ACF_STAGE4_GAIN */ - apb_write_reg(2, 0x3c, 0x21E); /* ACF_STAGE5_A1 */ - apb_write_reg(2, 0x3d, 0x0FE); /* ACF_STAGE5_A2 */ - apb_write_reg(2, 0x3e, 0x222); /* ACF_STAGE5_B1 */ - apb_write_reg(2, 0x3f, 0x04B); /* ACF_STAGE5_GAIN */ - apb_write_reg(2, 0xfe, 0x000); - apb_write_reg(2, 0xff, 0x003effff); - apb_write_reg(2, 0xfe, 0x001); - apb_write_reg(2, 0xff, 0x003ce7bd); - apb_write_reg(2, 0xfe, 0x002); - apb_write_reg(2, 0xff, 0x003ac77a); - apb_write_reg(2, 0xfe, 0x003); - apb_write_reg(2, 0xff, 0x0038a737); - apb_write_reg(2, 0xfe, 0x004); - apb_write_reg(2, 0xff, 0x00367ef2); - apb_write_reg(2, 0xfe, 0x005); - apb_write_reg(2, 0xff, 0x00344eac); - apb_write_reg(2, 0xfe, 0x006); - apb_write_reg(2, 0xff, 0x00321e66); - apb_write_reg(2, 0xfe, 0x007); - apb_write_reg(2, 0xff, 0x002fee20); - apb_write_reg(2, 0xfe, 0x008); - apb_write_reg(2, 0xff, 0x002dbdda); - apb_write_reg(2, 0xfe, 0x009); - apb_write_reg(2, 0xff, 0x002b8d94); - apb_write_reg(2, 0xfe, 0x00a); - apb_write_reg(2, 0xff, 0x00295d4e); - apb_write_reg(2, 0xfe, 0x00b); - apb_write_reg(2, 0xff, 0x00272508); - apb_write_reg(2, 0xfe, 0x00c); - apb_write_reg(2, 0xff, 0x0024dcc0); - apb_write_reg(2, 0xfe, 0x00d); - apb_write_reg(2, 0xff, 0x00227475); - apb_write_reg(2, 0xfe, 0x00e); - apb_write_reg(2, 0xff, 0x001fe426); - apb_write_reg(2, 0xfe, 0x00f); - apb_write_reg(2, 0xff, 0x001d1bd1); - apb_write_reg(2, 0xfe, 0x010); - apb_write_reg(2, 0xff, 0x001a2374); - apb_write_reg(2, 0xfe, 0x011); - apb_write_reg(2, 0xff, 0x0016e311); - apb_write_reg(2, 0xfe, 0x012); - apb_write_reg(2, 0xff, 0x00136aa6); - apb_write_reg(2, 0xfe, 0x013); - apb_write_reg(2, 0xff, 0x000fba33); - apb_write_reg(2, 0xfe, 0x014); - apb_write_reg(2, 0xff, 0x000ba9b8); - apb_write_reg(2, 0xfe, 0x015); - apb_write_reg(2, 0xff, 0x0007092e); - apb_write_reg(2, 0xfe, 0x016); - apb_write_reg(2, 0xff, 0x0001988e); - apb_write_reg(2, 0xfe, 0x017); - apb_write_reg(2, 0xff, 0x003b37d0); - apb_write_reg(2, 0xfe, 0x018); - apb_write_reg(2, 0xff, 0x0035aef3); - apb_write_reg(2, 0xfe, 0x019); - apb_write_reg(2, 0xff, 0x00316673); - apb_write_reg(2, 0xfe, 0x01a); - apb_write_reg(2, 0xff, 0x002c45de); - apb_write_reg(2, 0xfe, 0x01b); - apb_write_reg(2, 0xff, 0x0025e527); - apb_write_reg(2, 0xfe, 0x01c); - apb_write_reg(2, 0xff, 0x001da444); - apb_write_reg(2, 0xfe, 0x01d); - apb_write_reg(2, 0xff, 0x000deaea); - apb_write_reg(2, 0xfe, 0x01e); - apb_write_reg(2, 0xff, 0x000178bf); - apb_write_reg(2, 0xfe, 0x01f); - apb_write_reg(2, 0xff, 0x003cb7d6); - apb_write_reg(2, 0xfe, 0x020); - apb_write_reg(2, 0xff, 0x00000765); - } - } else if (ADsample == 28) { - /* 28.5714 MHz Set ACF */ - if (bandwidth == 0) { - /*8M Hz */ - apb_write_reg(2, 0x2c, 0x2DB); /* ACF_STAGE1_A1 */ - apb_write_reg(2, 0x2d, 0x05B); /* ACF_STAGE1_A2 */ - apb_write_reg(2, 0x2e, 0x163); /* ACF_STAGE1_B1 */ - apb_write_reg(2, 0x2f, 0x00E); /* ACF_STAGE1_GAIN */ - apb_write_reg(2, 0x30, 0x2D5); /* ACF_STAGE2_A1 */ - apb_write_reg(2, 0x31, 0x08B); /* ACF_STAGE2_A2 */ - apb_write_reg(2, 0x32, 0x3BC); /* ACF_STAGE2_B1 */ - apb_write_reg(2, 0x33, 0x06D); /* ACF_STAGE2_GAIN */ - apb_write_reg(2, 0x34, 0x2CF); /* ACF_STAGE3_A1 */ - apb_write_reg(2, 0x35, 0x0BF); /* ACF_STAGE3_A2 */ - apb_write_reg(2, 0x36, 0x321); /* ACF_STAGE3_B1 */ - apb_write_reg(2, 0x37, 0x008); /* ACF_STAGE3_GAIN */ - apb_write_reg(2, 0x38, 0x2C9); /* ACF_STAGE4_A1 */ - apb_write_reg(2, 0x39, 0x0E3); /* ACF_STAGE4_A2 */ - apb_write_reg(2, 0x3a, 0x2EE); /* ACF_STAGE4_B1 */ - apb_write_reg(2, 0x3b, 0x058); /* ACF_STAGE4_GAIN */ - apb_write_reg(2, 0x3c, 0x2C3); /* ACF_STAGE5_A1 */ - apb_write_reg(2, 0x3d, 0x0F8); /* ACF_STAGE5_A2 */ - apb_write_reg(2, 0x3e, 0x2DD); /* ACF_STAGE5_B1 */ - apb_write_reg(2, 0x3f, 0x04D); /* ACF_STAGE5_GAIN */ - - apb_write_reg(2, 0xfe, 0x000); - apb_write_reg(2, 0xff, 0x003ef7ff); - apb_write_reg(2, 0xfe, 0x001); - apb_write_reg(2, 0xff, 0x003d37c0); - apb_write_reg(2, 0xfe, 0x002); - apb_write_reg(2, 0xff, 0x003c3f94); - apb_write_reg(2, 0xfe, 0x003); - apb_write_reg(2, 0xff, 0x003b0f78); - apb_write_reg(2, 0xfe, 0x004); - apb_write_reg(2, 0xff, 0x0038c73f); - apb_write_reg(2, 0xfe, 0x005); - apb_write_reg(2, 0xff, 0x00369ef1); - apb_write_reg(2, 0xfe, 0x006); - apb_write_reg(2, 0xff, 0x003576be); - apb_write_reg(2, 0xfe, 0x007); - apb_write_reg(2, 0xff, 0x0033b698); - apb_write_reg(2, 0xfe, 0x008); - apb_write_reg(2, 0xff, 0x0031164d); - apb_write_reg(2, 0xfe, 0x009); - apb_write_reg(2, 0xff, 0x002f1dfd); - apb_write_reg(2, 0xfe, 0x00a); - apb_write_reg(2, 0xff, 0x002de5cf); - apb_write_reg(2, 0xfe, 0x00b); - apb_write_reg(2, 0xff, 0x002c15a2); - apb_write_reg(2, 0xfe, 0x00c); - apb_write_reg(2, 0xff, 0x0029f560); - apb_write_reg(2, 0xfe, 0x00d); - apb_write_reg(2, 0xff, 0x0027bd1b); - apb_write_reg(2, 0xfe, 0x00e); - apb_write_reg(2, 0xff, 0x00252ccf); - apb_write_reg(2, 0xfe, 0x00f); - apb_write_reg(2, 0xff, 0x0022bc7c); - apb_write_reg(2, 0xfe, 0x010); - apb_write_reg(2, 0xff, 0x00207c34); - apb_write_reg(2, 0xfe, 0x011); - apb_write_reg(2, 0xff, 0x001da3e5); - apb_write_reg(2, 0xfe, 0x012); - apb_write_reg(2, 0xff, 0x001a9b83); - apb_write_reg(2, 0xfe, 0x013); - apb_write_reg(2, 0xff, 0x0017db27); - apb_write_reg(2, 0xfe, 0x014); - apb_write_reg(2, 0xff, 0x001432c6); - apb_write_reg(2, 0xfe, 0x015); - apb_write_reg(2, 0xff, 0x000fa23e); - apb_write_reg(2, 0xfe, 0x016); - apb_write_reg(2, 0xff, 0x000b91af); - apb_write_reg(2, 0xfe, 0x017); - apb_write_reg(2, 0xff, 0x00077136); - apb_write_reg(2, 0xfe, 0x018); - apb_write_reg(2, 0xff, 0x0002c090); - apb_write_reg(2, 0xfe, 0x019); - apb_write_reg(2, 0xff, 0x003ec01a); - apb_write_reg(2, 0xfe, 0x01a); - apb_write_reg(2, 0xff, 0x003a3f92); - apb_write_reg(2, 0xfe, 0x01b); - apb_write_reg(2, 0xff, 0x00354efa); - apb_write_reg(2, 0xfe, 0x01c); - apb_write_reg(2, 0xff, 0x002fee54); - apb_write_reg(2, 0xfe, 0x01d); - apb_write_reg(2, 0xff, 0x002a35a3); - apb_write_reg(2, 0xfe, 0x01e); - apb_write_reg(2, 0xff, 0x0023f4e4); - apb_write_reg(2, 0xfe, 0x01f); - apb_write_reg(2, 0xff, 0x001cdc12); - apb_write_reg(2, 0xfe, 0x020); - apb_write_reg(2, 0xff, 0x00000316); - } else if (bandwidth == 1) { - apb_write_reg(2, 0x2c, 0x2C2); /* ACF_STAGE1_A1 */ - apb_write_reg(2, 0x2d, 0x069); /* ACF_STAGE1_A2 */ - apb_write_reg(2, 0x2e, 0x134); /* ACF_STAGE1_B1 */ - apb_write_reg(2, 0x2f, 0x00E); /* ACF_STAGE1_GAIN */ - apb_write_reg(2, 0x30, 0x2B7); /* ACF_STAGE2_A1 */ - apb_write_reg(2, 0x31, 0x095); /* ACF_STAGE2_A2 */ - apb_write_reg(2, 0x32, 0x36F); /* ACF_STAGE2_B1 */ - apb_write_reg(2, 0x33, 0x06D); /* ACF_STAGE2_GAIN */ - apb_write_reg(2, 0x34, 0x2AA); /* ACF_STAGE3_A1 */ - apb_write_reg(2, 0x35, 0x0C6); /* ACF_STAGE3_A2 */ - apb_write_reg(2, 0x36, 0x2E5); /* ACF_STAGE3_B1 */ - apb_write_reg(2, 0x37, 0x008); /* ACF_STAGE3_GAIN */ - apb_write_reg(2, 0x38, 0x2A1); /* ACF_STAGE4_A1 */ - apb_write_reg(2, 0x39, 0x0E6); /* ACF_STAGE4_A2 */ - apb_write_reg(2, 0x3a, 0x2BA); /* ACF_STAGE4_B1 */ - apb_write_reg(2, 0x3b, 0x058); /* ACF_STAGE4_GAIN */ - apb_write_reg(2, 0x3c, 0x299); /* ACF_STAGE5_A1 */ - apb_write_reg(2, 0x3d, 0x0F9); /* ACF_STAGE5_A2 */ - apb_write_reg(2, 0x3e, 0x2AC); /* ACF_STAGE5_B1 */ - apb_write_reg(2, 0x3f, 0x04D); /* ACF_STAGE5_GAIN */ - - apb_write_reg(2, 0xfe, 0x000); - apb_write_reg(2, 0xff, 0x003ee7ff); - apb_write_reg(2, 0xfe, 0x001); - apb_write_reg(2, 0xff, 0x003d1fbc); - apb_write_reg(2, 0xfe, 0x002); - apb_write_reg(2, 0xff, 0x003bf790); - apb_write_reg(2, 0xfe, 0x003); - apb_write_reg(2, 0xff, 0x003a876a); - apb_write_reg(2, 0xfe, 0x004); - apb_write_reg(2, 0xff, 0x00388f31); - apb_write_reg(2, 0xfe, 0x005); - apb_write_reg(2, 0xff, 0x0036c6f3); - apb_write_reg(2, 0xfe, 0x006); - apb_write_reg(2, 0xff, 0x003536bf); - apb_write_reg(2, 0xfe, 0x007); - apb_write_reg(2, 0xff, 0x00334689); - apb_write_reg(2, 0xfe, 0x008); - apb_write_reg(2, 0xff, 0x00310644); - apb_write_reg(2, 0xfe, 0x009); - apb_write_reg(2, 0xff, 0x002ef5fd); - apb_write_reg(2, 0xfe, 0x00a); - apb_write_reg(2, 0xff, 0x002d45c2); - apb_write_reg(2, 0xfe, 0x00b); - apb_write_reg(2, 0xff, 0x002b7d8c); - apb_write_reg(2, 0xfe, 0x00c); - apb_write_reg(2, 0xff, 0x00298550); - apb_write_reg(2, 0xfe, 0x00d); - apb_write_reg(2, 0xff, 0x00278510); - apb_write_reg(2, 0xfe, 0x00e); - apb_write_reg(2, 0xff, 0x00252ccc); - apb_write_reg(2, 0xfe, 0x00f); - apb_write_reg(2, 0xff, 0x0022847c); - apb_write_reg(2, 0xfe, 0x010); - apb_write_reg(2, 0xff, 0x00201427); - apb_write_reg(2, 0xfe, 0x011); - apb_write_reg(2, 0xff, 0x001e03e0); - apb_write_reg(2, 0xfe, 0x012); - apb_write_reg(2, 0xff, 0x001b6b9b); - apb_write_reg(2, 0xfe, 0x013); - apb_write_reg(2, 0xff, 0x0017c336); - apb_write_reg(2, 0xfe, 0x014); - apb_write_reg(2, 0xff, 0x0013e2b8); - apb_write_reg(2, 0xfe, 0x015); - apb_write_reg(2, 0xff, 0x0010b246); - apb_write_reg(2, 0xfe, 0x016); - apb_write_reg(2, 0xff, 0x000d81e8); - apb_write_reg(2, 0xfe, 0x017); - apb_write_reg(2, 0xff, 0x00084966); - apb_write_reg(2, 0xfe, 0x018); - apb_write_reg(2, 0xff, 0x0003089c); - apb_write_reg(2, 0xfe, 0x019); - apb_write_reg(2, 0xff, 0x003f0022); - apb_write_reg(2, 0xfe, 0x01a); - apb_write_reg(2, 0xff, 0x003aaf9c); - apb_write_reg(2, 0xfe, 0x01b); - apb_write_reg(2, 0xff, 0x00360f0c); - apb_write_reg(2, 0xfe, 0x01c); - apb_write_reg(2, 0xff, 0x00312e74); - apb_write_reg(2, 0xfe, 0x01d); - apb_write_reg(2, 0xff, 0x002c05d3); - apb_write_reg(2, 0xfe, 0x01e); - apb_write_reg(2, 0xff, 0x00268d2a); - apb_write_reg(2, 0xfe, 0x01f); - apb_write_reg(2, 0xff, 0x0020bc76); - apb_write_reg(2, 0xfe, 0x020); - apb_write_reg(2, 0xff, 0x000003b3); - } else if (bandwidth == 2) { - /* 6MHz */ - apb_write_reg(2, 0x2c, 0x2A9); /* ACF_STAGE1_A1 */ - apb_write_reg(2, 0x2d, 0x078); /* ACF_STAGE1_A2 */ - apb_write_reg(2, 0x2e, 0x0F4); /* ACF_STAGE1_B1 */ - apb_write_reg(2, 0x2f, 0x01E); /* ACF_STAGE1_GAIN */ - apb_write_reg(2, 0x30, 0x299); /* ACF_STAGE2_A1 */ - apb_write_reg(2, 0x31, 0x0A1); /* ACF_STAGE2_A2 */ - apb_write_reg(2, 0x32, 0x321); /* ACF_STAGE2_B1 */ - apb_write_reg(2, 0x33, 0x078); /* ACF_STAGE2_GAIN */ - apb_write_reg(2, 0x34, 0x288); /* ACF_STAGE3_A1 */ - apb_write_reg(2, 0x35, 0x0CD); /* ACF_STAGE3_A2 */ - apb_write_reg(2, 0x36, 0x2AE); /* ACF_STAGE3_B1 */ - apb_write_reg(2, 0x37, 0x05F); /* ACF_STAGE3_GAIN */ - apb_write_reg(2, 0x38, 0x27C); /* ACF_STAGE4_A1 */ - apb_write_reg(2, 0x39, 0x0E9); /* ACF_STAGE4_A2 */ - apb_write_reg(2, 0x3a, 0x28B); /* ACF_STAGE4_B1 */ - apb_write_reg(2, 0x3b, 0x058); /* ACF_STAGE4_GAIN */ - apb_write_reg(2, 0x3c, 0x273); /* ACF_STAGE5_A1 */ - apb_write_reg(2, 0x3d, 0x0FA); /* ACF_STAGE5_A2 */ - apb_write_reg(2, 0x3e, 0x281); /* ACF_STAGE5_B1 */ - apb_write_reg(2, 0x3f, 0x04D); /* ACF_STAGE5_GAIN */ - - apb_write_reg(2, 0xfe, 0x000); - apb_write_reg(2, 0xff, 0x003f17ff); - apb_write_reg(2, 0xfe, 0x001); - apb_write_reg(2, 0xff, 0x003d3fc4); - apb_write_reg(2, 0xfe, 0x002); - apb_write_reg(2, 0xff, 0x003b7f8a); - apb_write_reg(2, 0xfe, 0x003); - apb_write_reg(2, 0xff, 0x0039df55); - apb_write_reg(2, 0xfe, 0x004); - apb_write_reg(2, 0xff, 0x00381720); - apb_write_reg(2, 0xfe, 0x005); - apb_write_reg(2, 0xff, 0x00360ee2); - apb_write_reg(2, 0xfe, 0x006); - apb_write_reg(2, 0xff, 0x00342ea1); - apb_write_reg(2, 0xfe, 0x007); - apb_write_reg(2, 0xff, 0x0032ee6e); - apb_write_reg(2, 0xfe, 0x008); - apb_write_reg(2, 0xff, 0x0031e64e); - apb_write_reg(2, 0xfe, 0x009); - apb_write_reg(2, 0xff, 0x00300e22); - apb_write_reg(2, 0xfe, 0x00a); - apb_write_reg(2, 0xff, 0x002daddc); - apb_write_reg(2, 0xfe, 0x00b); - apb_write_reg(2, 0xff, 0x002b758f); - apb_write_reg(2, 0xfe, 0x00c); - apb_write_reg(2, 0xff, 0x0029ad51); - apb_write_reg(2, 0xfe, 0x00d); - apb_write_reg(2, 0xff, 0x0027ad18); - apb_write_reg(2, 0xfe, 0x00e); - apb_write_reg(2, 0xff, 0x00250ccd); - apb_write_reg(2, 0xfe, 0x00f); - apb_write_reg(2, 0xff, 0x00227476); - apb_write_reg(2, 0xfe, 0x010); - apb_write_reg(2, 0xff, 0x00204c2a); - apb_write_reg(2, 0xfe, 0x011); - apb_write_reg(2, 0xff, 0x001de3e6); - apb_write_reg(2, 0xfe, 0x012); - apb_write_reg(2, 0xff, 0x001a838a); - apb_write_reg(2, 0xfe, 0x013); - apb_write_reg(2, 0xff, 0x0016ab12); - apb_write_reg(2, 0xfe, 0x014); - apb_write_reg(2, 0xff, 0x00137a9d); - apb_write_reg(2, 0xfe, 0x015); - apb_write_reg(2, 0xff, 0x00113a4a); - apb_write_reg(2, 0xfe, 0x016); - apb_write_reg(2, 0xff, 0x000db1f8); - apb_write_reg(2, 0xfe, 0x017); - apb_write_reg(2, 0xff, 0x0007c15f); - apb_write_reg(2, 0xfe, 0x018); - apb_write_reg(2, 0xff, 0x00022883); - apb_write_reg(2, 0xfe, 0x019); - apb_write_reg(2, 0xff, 0x003df803); - apb_write_reg(2, 0xfe, 0x01a); - apb_write_reg(2, 0xff, 0x00398f79); - apb_write_reg(2, 0xfe, 0x01b); - apb_write_reg(2, 0xff, 0x0034d6e6); - apb_write_reg(2, 0xfe, 0x01c); - apb_write_reg(2, 0xff, 0x002fd64b); - apb_write_reg(2, 0xfe, 0x01d); - apb_write_reg(2, 0xff, 0x002a8da7); - apb_write_reg(2, 0xfe, 0x01e); - apb_write_reg(2, 0xff, 0x002504fa); - apb_write_reg(2, 0xfe, 0x01f); - apb_write_reg(2, 0xff, 0x001f2443); - apb_write_reg(2, 0xfe, 0x020); - apb_write_reg(2, 0xff, 0x00000382); - } else { - apb_write_reg(2, 0x2c, 0x28F); /* ACF_STAGE1_A1 */ - apb_write_reg(2, 0x2d, 0x088); /* ACF_STAGE1_A2 */ - apb_write_reg(2, 0x2e, 0x09E); /* ACF_STAGE1_B1 */ - apb_write_reg(2, 0x2f, 0x01E); /* ACF_STAGE1_GAIN */ - apb_write_reg(2, 0x30, 0x27C); /* ACF_STAGE2_A1 */ - apb_write_reg(2, 0x31, 0x0AD); /* ACF_STAGE2_A2 */ - apb_write_reg(2, 0x32, 0x2D6); /* ACF_STAGE2_B1 */ - apb_write_reg(2, 0x33, 0x078); /* ACF_STAGE2_GAIN */ - apb_write_reg(2, 0x34, 0x268); /* ACF_STAGE3_A1 */ - apb_write_reg(2, 0x35, 0x0D4); /* ACF_STAGE3_A2 */ - apb_write_reg(2, 0x36, 0x27C); /* ACF_STAGE3_B1 */ - apb_write_reg(2, 0x37, 0x05F); /* ACF_STAGE3_GAIN */ - apb_write_reg(2, 0x38, 0x25B); /* ACF_STAGE4_A1 */ - apb_write_reg(2, 0x39, 0x0ED); /* ACF_STAGE4_A2 */ - apb_write_reg(2, 0x3a, 0x262); /* ACF_STAGE4_B1 */ - apb_write_reg(2, 0x3b, 0x058); /* ACF_STAGE4_GAIN */ - apb_write_reg(2, 0x3c, 0x252); /* ACF_STAGE5_A1 */ - apb_write_reg(2, 0x3d, 0x0FB); /* ACF_STAGE5_A2 */ - apb_write_reg(2, 0x3e, 0x25A); /* ACF_STAGE5_B1 */ - apb_write_reg(2, 0x3f, 0x04D); /* ACF_STAGE5_GAIN */ - - apb_write_reg(2, 0xfe, 0x000); - apb_write_reg(2, 0xff, 0x003f17ff); - apb_write_reg(2, 0xfe, 0x001); - apb_write_reg(2, 0xff, 0x003d4fc5); - apb_write_reg(2, 0xfe, 0x002); - apb_write_reg(2, 0xff, 0x003baf8e); - apb_write_reg(2, 0xfe, 0x003); - apb_write_reg(2, 0xff, 0x003a3f5d); - apb_write_reg(2, 0xfe, 0x004); - apb_write_reg(2, 0xff, 0x0038df32); - apb_write_reg(2, 0xfe, 0x005); - apb_write_reg(2, 0xff, 0x00374703); - apb_write_reg(2, 0xfe, 0x006); - apb_write_reg(2, 0xff, 0x00354ec9); - apb_write_reg(2, 0xfe, 0x007); - apb_write_reg(2, 0xff, 0x00333e88); - apb_write_reg(2, 0xfe, 0x008); - apb_write_reg(2, 0xff, 0x00314e47); - apb_write_reg(2, 0xfe, 0x009); - apb_write_reg(2, 0xff, 0x002f860c); - apb_write_reg(2, 0xfe, 0x00a); - apb_write_reg(2, 0xff, 0x002d9dd2); - apb_write_reg(2, 0xfe, 0x00b); - apb_write_reg(2, 0xff, 0x002b5590); - apb_write_reg(2, 0xfe, 0x00c); - apb_write_reg(2, 0xff, 0x0028cd42); - apb_write_reg(2, 0xfe, 0x00d); - apb_write_reg(2, 0xff, 0x00266cf2); - apb_write_reg(2, 0xfe, 0x00e); - apb_write_reg(2, 0xff, 0x00245cab); - apb_write_reg(2, 0xfe, 0x00f); - apb_write_reg(2, 0xff, 0x00225c6b); - apb_write_reg(2, 0xfe, 0x010); - apb_write_reg(2, 0xff, 0x00200427); - apb_write_reg(2, 0xfe, 0x011); - apb_write_reg(2, 0xff, 0x001d4bd5); - apb_write_reg(2, 0xfe, 0x012); - apb_write_reg(2, 0xff, 0x001a9b7d); - apb_write_reg(2, 0xfe, 0x013); - apb_write_reg(2, 0xff, 0x00183b2b); - apb_write_reg(2, 0xfe, 0x014); - apb_write_reg(2, 0xff, 0x0015b2e1); - apb_write_reg(2, 0xfe, 0x015); - apb_write_reg(2, 0xff, 0x00122a83); - apb_write_reg(2, 0xfe, 0x016); - apb_write_reg(2, 0xff, 0x000d49fc); - apb_write_reg(2, 0xfe, 0x017); - apb_write_reg(2, 0xff, 0x0007594e); - apb_write_reg(2, 0xfe, 0x018); - apb_write_reg(2, 0xff, 0x00024080); - apb_write_reg(2, 0xfe, 0x019); - apb_write_reg(2, 0xff, 0x003e980e); - apb_write_reg(2, 0xfe, 0x01a); - apb_write_reg(2, 0xff, 0x003ab796); - apb_write_reg(2, 0xfe, 0x01b); - apb_write_reg(2, 0xff, 0x00368f15); - apb_write_reg(2, 0xfe, 0x01c); - apb_write_reg(2, 0xff, 0x00320e8a); - apb_write_reg(2, 0xfe, 0x01d); - apb_write_reg(2, 0xff, 0x002d25f4); - apb_write_reg(2, 0xfe, 0x01e); - apb_write_reg(2, 0xff, 0x0027ad4f); - apb_write_reg(2, 0xfe, 0x01f); - apb_write_reg(2, 0xff, 0x00219496); - apb_write_reg(2, 0xfe, 0x020); - apb_write_reg(2, 0xff, 0x000003c9); - } - } else { - /* 20.7 MHz Set ACF */ - if (bandwidth == 0) { - /*8M Hz */ - apb_write_reg(2, 0x2c, 0x318); /* ACF_STAGE1_A1 */ - apb_write_reg(2, 0x2d, 0x03E); /* ACF_STAGE1_A2 */ - apb_write_reg(2, 0x2e, 0x1AE); /* ACF_STAGE1_B1 */ - apb_write_reg(2, 0x2f, 0x00E); /* ACF_STAGE1_GAIN */ - apb_write_reg(2, 0x30, 0x326); /* ACF_STAGE2_A1 */ - apb_write_reg(2, 0x31, 0x074); /* ACF_STAGE2_A2 */ - apb_write_reg(2, 0x32, 0x074); /* ACF_STAGE2_B1 */ - apb_write_reg(2, 0x33, 0x06F); /* ACF_STAGE2_GAIN */ - apb_write_reg(2, 0x34, 0x336); /* ACF_STAGE3_A1 */ - apb_write_reg(2, 0x35, 0x0B1); /* ACF_STAGE3_A2 */ - apb_write_reg(2, 0x36, 0x3C9); /* ACF_STAGE3_B1 */ - apb_write_reg(2, 0x37, 0x008); /* ACF_STAGE3_GAIN */ - apb_write_reg(2, 0x38, 0x33F); /* ACF_STAGE4_A1 */ - apb_write_reg(2, 0x39, 0x0DC); /* ACF_STAGE4_A2 */ - apb_write_reg(2, 0x3a, 0x384); /* ACF_STAGE4_B1 */ - apb_write_reg(2, 0x3b, 0x05A); /* ACF_STAGE4_GAIN */ - apb_write_reg(2, 0x3c, 0x340); /* ACF_STAGE5_A1 */ - apb_write_reg(2, 0x3d, 0x0F6); /* ACF_STAGE5_A2 */ - apb_write_reg(2, 0x3e, 0x36D); /* ACF_STAGE5_B1 */ - apb_write_reg(2, 0x3f, 0x04B); /* ACF_STAGE5_GAIN */ - - apb_write_reg(2, 0xfe, 0x000); - apb_write_reg(2, 0xff, 0x003f37ff); - apb_write_reg(2, 0xfe, 0x001); - apb_write_reg(2, 0xff, 0x003d97cc); - apb_write_reg(2, 0xfe, 0x002); - apb_write_reg(2, 0xff, 0x003bf798); - apb_write_reg(2, 0xfe, 0x003); - apb_write_reg(2, 0xff, 0x003a4f64); - apb_write_reg(2, 0xfe, 0x004); - apb_write_reg(2, 0xff, 0x0038a72f); - apb_write_reg(2, 0xfe, 0x005); - apb_write_reg(2, 0xff, 0x0036f6f9); - apb_write_reg(2, 0xfe, 0x006); - apb_write_reg(2, 0xff, 0x003546c3); - apb_write_reg(2, 0xfe, 0x007); - apb_write_reg(2, 0xff, 0x0033868c); - apb_write_reg(2, 0xfe, 0x008); - apb_write_reg(2, 0xff, 0x0031be54); - apb_write_reg(2, 0xfe, 0x009); - apb_write_reg(2, 0xff, 0x002fe61a); - apb_write_reg(2, 0xfe, 0x00a); - apb_write_reg(2, 0xff, 0x002e05df); - apb_write_reg(2, 0xfe, 0x00b); - apb_write_reg(2, 0xff, 0x002c15a2); - apb_write_reg(2, 0xfe, 0x00c); - apb_write_reg(2, 0xff, 0x002a1562); - apb_write_reg(2, 0xfe, 0x00d); - apb_write_reg(2, 0xff, 0x0027f520); - apb_write_reg(2, 0xfe, 0x00e); - apb_write_reg(2, 0xff, 0x0025c4dc); - apb_write_reg(2, 0xfe, 0x00f); - apb_write_reg(2, 0xff, 0x00236c93); - apb_write_reg(2, 0xfe, 0x010); - apb_write_reg(2, 0xff, 0x0020f446); - apb_write_reg(2, 0xfe, 0x011); - apb_write_reg(2, 0xff, 0x001e4bf4); - apb_write_reg(2, 0xfe, 0x012); - apb_write_reg(2, 0xff, 0x001b739d); - apb_write_reg(2, 0xfe, 0x013); - apb_write_reg(2, 0xff, 0x00185b3d); - apb_write_reg(2, 0xfe, 0x014); - apb_write_reg(2, 0xff, 0x0014ead5); - apb_write_reg(2, 0xfe, 0x015); - apb_write_reg(2, 0xff, 0x00111a62); - apb_write_reg(2, 0xfe, 0x016); - apb_write_reg(2, 0xff, 0x000cb9df); - apb_write_reg(2, 0xfe, 0x017); - apb_write_reg(2, 0xff, 0x00079148); - apb_write_reg(2, 0xfe, 0x018); - apb_write_reg(2, 0xff, 0x00030093); - apb_write_reg(2, 0xfe, 0x019); - apb_write_reg(2, 0xff, 0x003f802a); - apb_write_reg(2, 0xfe, 0x01a); - apb_write_reg(2, 0xff, 0x003b77b2); - apb_write_reg(2, 0xfe, 0x01b); - apb_write_reg(2, 0xff, 0x0036a725); - apb_write_reg(2, 0xfe, 0x01c); - apb_write_reg(2, 0xff, 0x0030ae7b); - apb_write_reg(2, 0xfe, 0x01d); - apb_write_reg(2, 0xff, 0x00285d9f); - apb_write_reg(2, 0xfe, 0x01e); - apb_write_reg(2, 0xff, 0x001abc46); - apb_write_reg(2, 0xfe, 0x01f); - apb_write_reg(2, 0xff, 0x000f8a85); - apb_write_reg(2, 0xfe, 0x020); - apb_write_reg(2, 0xff, 0x00000187); - } else if (bandwidth == 1) { - apb_write_reg(2, 0x2c, 0x2F9); /* ACF_STAGE1_A1 */ - apb_write_reg(2, 0x2d, 0x04C); /* ACF_STAGE1_A2 */ - apb_write_reg(2, 0x2e, 0x18E); /* ACF_STAGE1_B1 */ - apb_write_reg(2, 0x2f, 0x00E); /* ACF_STAGE1_GAIN */ - apb_write_reg(2, 0x30, 0x2FD); /* ACF_STAGE2_A1 */ - apb_write_reg(2, 0x31, 0x07F); /* ACF_STAGE2_A2 */ - apb_write_reg(2, 0x32, 0x01A); /* ACF_STAGE2_B1 */ - apb_write_reg(2, 0x33, 0x06D); /* ACF_STAGE2_GAIN */ - apb_write_reg(2, 0x34, 0x300); /* ACF_STAGE3_A1 */ - apb_write_reg(2, 0x35, 0x0B8); /* ACF_STAGE3_A2 */ - apb_write_reg(2, 0x36, 0x372); /* ACF_STAGE3_B1 */ - apb_write_reg(2, 0x37, 0x05F); /* ACF_STAGE3_GAIN */ - apb_write_reg(2, 0x38, 0x301); /* ACF_STAGE4_A1 */ - apb_write_reg(2, 0x39, 0x0DF); /* ACF_STAGE4_A2 */ - apb_write_reg(2, 0x3a, 0x335); /* ACF_STAGE4_B1 */ - apb_write_reg(2, 0x3b, 0x05A); /* ACF_STAGE4_GAIN */ - apb_write_reg(2, 0x3c, 0x2FE); /* ACF_STAGE5_A1 */ - apb_write_reg(2, 0x3d, 0x0F7); /* ACF_STAGE5_A2 */ - apb_write_reg(2, 0x3e, 0x320); /* ACF_STAGE5_B1 */ - apb_write_reg(2, 0x3f, 0x04B); /* ACF_STAGE5_GAIN */ - - apb_write_reg(2, 0xfe, 0x000); - apb_write_reg(2, 0xff, 0x003f37ff); - apb_write_reg(2, 0xfe, 0x001); - apb_write_reg(2, 0xff, 0x003d8fcc); - apb_write_reg(2, 0xfe, 0x002); - apb_write_reg(2, 0xff, 0x003bef97); - apb_write_reg(2, 0xfe, 0x003); - apb_write_reg(2, 0xff, 0x003a4762); - apb_write_reg(2, 0xfe, 0x004); - apb_write_reg(2, 0xff, 0x0038972d); - apb_write_reg(2, 0xfe, 0x005); - apb_write_reg(2, 0xff, 0x0036e6f7); - apb_write_reg(2, 0xfe, 0x006); - apb_write_reg(2, 0xff, 0x00352ec1); - apb_write_reg(2, 0xfe, 0x007); - apb_write_reg(2, 0xff, 0x00336e89); - apb_write_reg(2, 0xfe, 0x008); - apb_write_reg(2, 0xff, 0x00319e50); - apb_write_reg(2, 0xfe, 0x009); - apb_write_reg(2, 0xff, 0x002fce16); - apb_write_reg(2, 0xfe, 0x00a); - apb_write_reg(2, 0xff, 0x002de5db); - apb_write_reg(2, 0xfe, 0x00b); - apb_write_reg(2, 0xff, 0x002bf59d); - apb_write_reg(2, 0xfe, 0x00c); - apb_write_reg(2, 0xff, 0x0029ed5e); - apb_write_reg(2, 0xfe, 0x00d); - apb_write_reg(2, 0xff, 0x0027d51c); - apb_write_reg(2, 0xfe, 0x00e); - apb_write_reg(2, 0xff, 0x00259cd7); - apb_write_reg(2, 0xfe, 0x00f); - apb_write_reg(2, 0xff, 0x0023448e); - apb_write_reg(2, 0xfe, 0x010); - apb_write_reg(2, 0xff, 0x0020cc41); - apb_write_reg(2, 0xfe, 0x011); - apb_write_reg(2, 0xff, 0x001e23ef); - apb_write_reg(2, 0xfe, 0x012); - apb_write_reg(2, 0xff, 0x001b4b98); - apb_write_reg(2, 0xfe, 0x013); - apb_write_reg(2, 0xff, 0x00183339); - apb_write_reg(2, 0xfe, 0x014); - apb_write_reg(2, 0xff, 0x0014cad1); - apb_write_reg(2, 0xfe, 0x015); - apb_write_reg(2, 0xff, 0x0010fa5e); - apb_write_reg(2, 0xfe, 0x016); - apb_write_reg(2, 0xff, 0x000c99dc); - apb_write_reg(2, 0xfe, 0x017); - apb_write_reg(2, 0xff, 0x00078145); - apb_write_reg(2, 0xfe, 0x018); - apb_write_reg(2, 0xff, 0x0002f892); - apb_write_reg(2, 0xfe, 0x019); - apb_write_reg(2, 0xff, 0x003f802a); - apb_write_reg(2, 0xfe, 0x01a); - apb_write_reg(2, 0xff, 0x003b8fb3); - apb_write_reg(2, 0xfe, 0x01b); - apb_write_reg(2, 0xff, 0x0036d729); - apb_write_reg(2, 0xfe, 0x01c); - apb_write_reg(2, 0xff, 0x00310682); - apb_write_reg(2, 0xfe, 0x01d); - apb_write_reg(2, 0xff, 0x00290dae); - apb_write_reg(2, 0xfe, 0x01e); - apb_write_reg(2, 0xff, 0x001c0c67); - apb_write_reg(2, 0xfe, 0x01f); - apb_write_reg(2, 0xff, 0x0010a2ad); - apb_write_reg(2, 0xfe, 0x020); - apb_write_reg(2, 0xff, 0x000001a8); - } else if (bandwidth == 2) { - /* 6MHz */ - apb_write_reg(2, 0x2c, 0x2D9); /* ACF_STAGE1_A1 */ - apb_write_reg(2, 0x2d, 0x05C); /* ACF_STAGE1_A2 */ - apb_write_reg(2, 0x2e, 0x161); /* ACF_STAGE1_B1 */ - apb_write_reg(2, 0x2f, 0x00E); /* ACF_STAGE1_GAIN */ - apb_write_reg(2, 0x30, 0x2D4); /* ACF_STAGE2_A1 */ - apb_write_reg(2, 0x31, 0x08B); /* ACF_STAGE2_A2 */ - apb_write_reg(2, 0x32, 0x3B8); /* ACF_STAGE2_B1 */ - apb_write_reg(2, 0x33, 0x06B); /* ACF_STAGE2_GAIN */ - apb_write_reg(2, 0x34, 0x2CD); /* ACF_STAGE3_A1 */ - apb_write_reg(2, 0x35, 0x0C0); /* ACF_STAGE3_A2 */ - apb_write_reg(2, 0x36, 0x31E); /* ACF_STAGE3_B1 */ - apb_write_reg(2, 0x37, 0x05F); /* ACF_STAGE3_GAIN */ - apb_write_reg(2, 0x38, 0x2C7); /* ACF_STAGE4_A1 */ - apb_write_reg(2, 0x39, 0x0E3); /* ACF_STAGE4_A2 */ - apb_write_reg(2, 0x3a, 0x2EB); /* ACF_STAGE4_B1 */ - apb_write_reg(2, 0x3b, 0x05A); /* ACF_STAGE4_GAIN */ - apb_write_reg(2, 0x3c, 0x2C1); /* ACF_STAGE5_A1 */ - apb_write_reg(2, 0x3d, 0x0F8); /* ACF_STAGE5_A2 */ - apb_write_reg(2, 0x3e, 0x2DA); /* ACF_STAGE5_B1 */ - apb_write_reg(2, 0x3f, 0x04B); /* ACF_STAGE5_GAIN */ - apb_write_reg(2, 0xfe, 0x000); - apb_write_reg(2, 0xff, 0x003f2fff); - apb_write_reg(2, 0xfe, 0x001); - apb_write_reg(2, 0xff, 0x003d87cb); - apb_write_reg(2, 0xfe, 0x002); - apb_write_reg(2, 0xff, 0x003bdf96); - apb_write_reg(2, 0xfe, 0x003); - apb_write_reg(2, 0xff, 0x003a2f60); - apb_write_reg(2, 0xfe, 0x004); - apb_write_reg(2, 0xff, 0x00387f2a); - apb_write_reg(2, 0xfe, 0x005); - apb_write_reg(2, 0xff, 0x0036c6f4); - apb_write_reg(2, 0xfe, 0x006); - apb_write_reg(2, 0xff, 0x00350ebd); - apb_write_reg(2, 0xfe, 0x007); - apb_write_reg(2, 0xff, 0x00334684); - apb_write_reg(2, 0xfe, 0x008); - apb_write_reg(2, 0xff, 0x0031764b); - apb_write_reg(2, 0xfe, 0x009); - apb_write_reg(2, 0xff, 0x002f9e11); - apb_write_reg(2, 0xfe, 0x00a); - apb_write_reg(2, 0xff, 0x002db5d4); - apb_write_reg(2, 0xfe, 0x00b); - apb_write_reg(2, 0xff, 0x002bbd97); - apb_write_reg(2, 0xfe, 0x00c); - apb_write_reg(2, 0xff, 0x0029b557); - apb_write_reg(2, 0xfe, 0x00d); - apb_write_reg(2, 0xff, 0x00279515); - apb_write_reg(2, 0xfe, 0x00e); - apb_write_reg(2, 0xff, 0x00255ccf); - apb_write_reg(2, 0xfe, 0x00f); - apb_write_reg(2, 0xff, 0x00230c87); - apb_write_reg(2, 0xfe, 0x010); - apb_write_reg(2, 0xff, 0x0020943a); - apb_write_reg(2, 0xfe, 0x011); - apb_write_reg(2, 0xff, 0x001debe8); - apb_write_reg(2, 0xfe, 0x012); - apb_write_reg(2, 0xff, 0x001b1b91); - apb_write_reg(2, 0xfe, 0x013); - apb_write_reg(2, 0xff, 0x00180b33); - apb_write_reg(2, 0xfe, 0x014); - apb_write_reg(2, 0xff, 0x0014aacc); - apb_write_reg(2, 0xfe, 0x015); - apb_write_reg(2, 0xff, 0x0010e25a); - apb_write_reg(2, 0xfe, 0x016); - apb_write_reg(2, 0xff, 0x000c91da); - apb_write_reg(2, 0xfe, 0x017); - apb_write_reg(2, 0xff, 0x00078945); - apb_write_reg(2, 0xfe, 0x018); - apb_write_reg(2, 0xff, 0x00031895); - apb_write_reg(2, 0xfe, 0x019); - apb_write_reg(2, 0xff, 0x003fa82e); - apb_write_reg(2, 0xfe, 0x01a); - apb_write_reg(2, 0xff, 0x003bbfb8); - apb_write_reg(2, 0xfe, 0x01b); - apb_write_reg(2, 0xff, 0x00371730); - apb_write_reg(2, 0xfe, 0x01c); - apb_write_reg(2, 0xff, 0x0031668c); - apb_write_reg(2, 0xfe, 0x01d); - apb_write_reg(2, 0xff, 0x00299dbc); - apb_write_reg(2, 0xfe, 0x01e); - apb_write_reg(2, 0xff, 0x001d1480); - apb_write_reg(2, 0xfe, 0x01f); - apb_write_reg(2, 0xff, 0x00119acf); - apb_write_reg(2, 0xfe, 0x020); - apb_write_reg(2, 0xff, 0x000001c4); - } else { - apb_write_reg(2, 0x2c, 0x2B9); /* ACF_STAGE1_A1 */ - apb_write_reg(2, 0x2d, 0x06E); /* ACF_STAGE1_A2 */ - apb_write_reg(2, 0x2e, 0x11E); /* ACF_STAGE1_B1 */ - apb_write_reg(2, 0x2f, 0x01E); /* ACF_STAGE1_GAIN */ - apb_write_reg(2, 0x30, 0x2AB); /* ACF_STAGE2_A1 */ - apb_write_reg(2, 0x31, 0x099); /* ACF_STAGE2_A2 */ - apb_write_reg(2, 0x32, 0x351); /* ACF_STAGE2_B1 */ - apb_write_reg(2, 0x33, 0x06B); /* ACF_STAGE2_GAIN */ - apb_write_reg(2, 0x34, 0x29D); /* ACF_STAGE3_A1 */ - apb_write_reg(2, 0x35, 0x0C8); /* ACF_STAGE3_A2 */ - apb_write_reg(2, 0x36, 0x2D0); /* ACF_STAGE3_B1 */ - apb_write_reg(2, 0x37, 0x05F); /* ACF_STAGE3_GAIN */ - apb_write_reg(2, 0x38, 0x292); /* ACF_STAGE4_A1 */ - apb_write_reg(2, 0x39, 0x0E7); /* ACF_STAGE4_A2 */ - apb_write_reg(2, 0x3a, 0x2A8); /* ACF_STAGE4_B1 */ - apb_write_reg(2, 0x3b, 0x05A); /* ACF_STAGE4_GAIN */ - apb_write_reg(2, 0x3c, 0x28A); /* ACF_STAGE5_A1 */ - apb_write_reg(2, 0x3d, 0x0F9); /* ACF_STAGE5_A2 */ - apb_write_reg(2, 0x3e, 0x29B); /* ACF_STAGE5_B1 */ - apb_write_reg(2, 0x3f, 0x04B); /* ACF_STAGE5_GAIN */ - - apb_write_reg(2, 0xfe, 0x000); - apb_write_reg(2, 0xff, 0x003f2fff); - apb_write_reg(2, 0xfe, 0x001); - apb_write_reg(2, 0xff, 0x003d7fca); - apb_write_reg(2, 0xfe, 0x002); - apb_write_reg(2, 0xff, 0x003bcf94); - apb_write_reg(2, 0xfe, 0x003); - apb_write_reg(2, 0xff, 0x003a1f5e); - apb_write_reg(2, 0xfe, 0x004); - apb_write_reg(2, 0xff, 0x00386727); - apb_write_reg(2, 0xfe, 0x005); - apb_write_reg(2, 0xff, 0x0036a6f0); - apb_write_reg(2, 0xfe, 0x006); - apb_write_reg(2, 0xff, 0x0034e6b8); - apb_write_reg(2, 0xfe, 0x007); - apb_write_reg(2, 0xff, 0x0033167f); - apb_write_reg(2, 0xfe, 0x008); - apb_write_reg(2, 0xff, 0x00314645); - apb_write_reg(2, 0xfe, 0x009); - apb_write_reg(2, 0xff, 0x002f660a); - apb_write_reg(2, 0xfe, 0x00a); - apb_write_reg(2, 0xff, 0x002d75cd); - apb_write_reg(2, 0xfe, 0x00b); - apb_write_reg(2, 0xff, 0x002b758e); - apb_write_reg(2, 0xfe, 0x00c); - apb_write_reg(2, 0xff, 0x0029654e); - apb_write_reg(2, 0xfe, 0x00d); - apb_write_reg(2, 0xff, 0x0027450a); - apb_write_reg(2, 0xfe, 0x00e); - apb_write_reg(2, 0xff, 0x002504c4); - apb_write_reg(2, 0xfe, 0x00f); - apb_write_reg(2, 0xff, 0x0022a47b); - apb_write_reg(2, 0xfe, 0x010); - apb_write_reg(2, 0xff, 0x0020242d); - apb_write_reg(2, 0xfe, 0x011); - apb_write_reg(2, 0xff, 0x001d7bdb); - apb_write_reg(2, 0xfe, 0x012); - apb_write_reg(2, 0xff, 0x001aa383); - apb_write_reg(2, 0xfe, 0x013); - apb_write_reg(2, 0xff, 0x00178b24); - apb_write_reg(2, 0xfe, 0x014); - apb_write_reg(2, 0xff, 0x00142abd); - apb_write_reg(2, 0xfe, 0x015); - apb_write_reg(2, 0xff, 0x0010624a); - apb_write_reg(2, 0xfe, 0x016); - apb_write_reg(2, 0xff, 0x000c11ca); - apb_write_reg(2, 0xfe, 0x017); - apb_write_reg(2, 0xff, 0x00070935); - apb_write_reg(2, 0xfe, 0x018); - apb_write_reg(2, 0xff, 0x00029885); - apb_write_reg(2, 0xfe, 0x019); - apb_write_reg(2, 0xff, 0x003f281e); - apb_write_reg(2, 0xfe, 0x01a); - apb_write_reg(2, 0xff, 0x003b3fa9); - apb_write_reg(2, 0xfe, 0x01b); - apb_write_reg(2, 0xff, 0x00369720); - apb_write_reg(2, 0xfe, 0x01c); - apb_write_reg(2, 0xff, 0x0030ce7b); - apb_write_reg(2, 0xfe, 0x01d); - apb_write_reg(2, 0xff, 0x0028dda7); - apb_write_reg(2, 0xfe, 0x01e); - apb_write_reg(2, 0xff, 0x001c6464); - apb_write_reg(2, 0xfe, 0x01f); - apb_write_reg(2, 0xff, 0x0011b2c7); - apb_write_reg(2, 0xfe, 0x020); - apb_write_reg(2, 0xff, 0x000001cb); - } - } -} - -static void dvbt_reg_initial(struct aml_demod_sta *demod_sta) -{ - u32 clk_freq; - u32 adc_freq; - u8 ch_mode; - u8 agc_mode; - u32 ch_freq; - u16 ch_if; - u16 ch_bw; - u16 symb_rate; - - u8 bw; - u8 sr; - u8 ifreq; - u32 tmp; - - clk_freq = demod_sta->clk_freq; /* kHz */ - adc_freq = demod_sta->adc_freq; /* kHz */ - ch_mode = demod_sta->ch_mode; - agc_mode = demod_sta->agc_mode; - ch_freq = demod_sta->ch_freq; /* kHz */ - ch_if = demod_sta->ch_if; /* kHz */ - ch_bw = demod_sta->ch_bw; /* kHz */ - symb_rate = demod_sta->symb_rate; /* k/sec */ - - bw = 8 - ch_bw / 1000; - sr = adc_freq > 40000 ? 3 : adc_freq > 24000 ? 2 : - adc_freq > 20770 ? 1 : 0; - ifreq = ch_if > 35000 ? 0 : 1; - - /*//////////////////////////////////// */ - /* bw == 0 : 8M */ - /* 1 : 7M */ - /* 2 : 6M */ - /* 3 : 5M */ - /* sr == 0 : 20.7M */ - /* 1 : 20.8333M */ - /* 2 : 28.5714M */ - /* 3 : 45M */ - /* ifreq == 0: 36.13MHz */ - /* 1: 4.57MHz */ - /* agc_mode == 0: single AGC */ - /* 1: dual AGC */ - /*//////////////////////////////////// */ - apb_write_reg(2, 0x02, 0x00800000); - /* SW reset bit[23] ; write anything to zero */ - apb_write_reg(2, 0x00, 0x00000000); - - switch (sr) { - case 0: - apb_write_reg(2, 0x08, 0x00002966); - break; - case 1: - apb_write_reg(2, 0x08, 0x00002999); - break; - case 2: - apb_write_reg(2, 0x08, 0x00003924); - break; - case 3: - apb_write_reg(2, 0x08, 0x00005a00); - break; /*sample_rate /*45M */ - default: - break; - } - - apb_write_reg(2, 0x0d, 0x00000000); - apb_write_reg(2, 0x0e, 0x00000000); - dvbt_enable_irq(8); - - apb_write_reg(2, 0x11, 0x00100002); /* FSM [15:0] TIMER_FEC_LOST */ - apb_write_reg(2, 0x12, 0x02100201); /* FSM */ - apb_write_reg(2, 0x14, 0xe81c4ff6); /* AGC_TARGET 0xf0121385 */ - apb_write_reg(2, 0x15, 0x02050ca6); /* AGC_CTRL */ - - switch (sr) { - case 0: - apb_write_reg(2, 0x15, apb_read_reg(2, 0x15) | (0x5b << 12)); - break; - case 1: - apb_write_reg(2, 0x15, apb_read_reg(2, 0x15) | (0x5b << 12)); - break; - case 2: - apb_write_reg(2, 0x15, apb_read_reg(2, 0x15) | (0x7b << 12)); - break; - case 3: - apb_write_reg(2, 0x15, apb_read_reg(2, 0x15) | (0xc2 << 12)); - break; /* sample_rate /*45M */ - default: - break; - } - - if (agc_mode == 0) - apb_write_reg(2, 0x16, 0x67f80); /* AGC_IFGAIN_CTRL */ - else if (agc_mode == 1) - apb_write_reg(2, 0x16, 0x07f80); /* AGC_IFGAIN_CTRL */ - - apb_write_reg(2, 0x17, 0x07f80); /* AGC_RFGAIN_CTRL */ - apb_write_reg(2, 0x18, 0x00000000); /* AGC_IFGAIN_ACCUM */ - apb_write_reg(2, 0x19, 0x00000000); /* AGC_RFGAIN_ACCUM */ - - if (ifreq == 0) { - switch (sr) { - case 0: - apb_write_reg(2, 0x20, 0x00002096); - break; - /* DDC NORM_PHASE 36.13M IF For 20.7M sample rate */ - case 1: - apb_write_reg(2, 0x20, 0x000021a9); - break; - /* DDC NORM_PHASE 36.13M IF For 20.8333M sample rate*/ - case 2: - apb_write_reg(2, 0x20, 0x000021dc); - break; - /* DDC NORM_PHASE 36.13M IF For 28.57142M sample rate*/ - case 3: - apb_write_reg(2, 0x20, 0x000066e2); - break; - /* DDC NORM_PHASE 36.13M IF For 45M sample rate */ - default: - break; - } - } else if (ifreq == 1) { - switch (sr) { - case 0: - apb_write_reg(2, 0x20, 0x00001c42); - break; - /* DDC NORM_PHASE 4.57M IF For 20.7M sample rate */ - case 1: - apb_write_reg(2, 0x20, 0x00001c1f); - break; - /* DDC NORM_PHASE 4.57M IF For 20.8333M sample rate */ - case 2: - apb_write_reg(2, 0x20, 0x00001479); - break; - /* DDC NORM_PHASE 4.57M IF For 28.57142M sample rate*/ - case 3: - apb_write_reg(2, 0x20, 0x0000d00); - break; - /* DDC NORM_PHASE 4.57M IF For 45M sample rate */ - default: - break; - } - } - */tmp = ch_if * (1 << 15)/adc_freq; - tmp &= 0x3fff; - apb_write_reg(2, 0x20, tmp); - if (demod_sta->debug) - dprintk("IF: %d kHz ADC: %d kHz DDC: %04x\n", ch_if, adc_freq, - tmp); - - apb_write_reg(2, 0x21, 0x001ff000); /* DDC CS_FCFO_ADJ_CTRL */ - apb_write_reg(2, 0x22, 0x00000000); /* DDC ICFO_ADJ_CTRL */ - apb_write_reg(2, 0x23, 0x00004000); /* DDC TRACK_FCFO_ADJ_CTRL */ - apb_write_reg(2, 0x27, 0x00a98200); - /*[23] agc state mode [22:19] icfo_time_limit ;[18:15] tps_time_limit ; - * [14:4] cs_cfo_thres ; [3:0] fsm_state_d; - */ - /* 1 010,1 001,1 - * 000,0010,0000, xxxx - */ - apb_write_reg(2, 0x28, 0x04028032); - /* [31:24] cs_Q_thres; [23:13] sfo_thres; FSM [12:0] fcfo_thres;; */ - /* 0000,0100, 0000,0010,100 0,0000,0011,0010 */ - apb_write_reg(2, 0x29, 0x0051117F); - /*apb_write_reg(2, 0x29, 0x00010f7F); */ - /* [18:16] fec_rs_sh_ctrl ;[15:9] fsm_total_timer; - * [8:6] modeDet_time_limit; FSM [5:0] sfo_time_limit; ; - */ - /* 01, () 0000,111 1,01 11,1111 */ - - /* SRC NORM_INRATE */ - switch (bw) { - case 0: - tmp = (1 << 14) * adc_freq / 125 / 8 * 7; - break; - case 1: - tmp = (1 << 14) * adc_freq / 125; - break; - case 2: - tmp = (1 << 14) * adc_freq / 125 / 6 * 7; - break; - case 3: - tmp = (1 << 14) * adc_freq / 125 / 5 * 7; - break; - default: - tmp = (1 << 14) * adc_freq / 125 / 8 * 7; - break; - } - - apb_write_reg(2, 0x44, tmp & 0x7fffff); - - apb_write_reg(2, 0x45, 0x00000000); /* SRC SRC_PHASE_INI */ - apb_write_reg(2, 0x46, 0x02004000); - /* SRC SFO_ADJ_CTRL SFO limit 0x100!! */ - apb_write_reg(2, 0x48, 0xc0287); /* DAGC_CTRL */ - apb_write_reg(2, 0x49, 0x00000005); /* DAGC_CTRL1 */ - apb_write_reg(2, 0x4c, 0x00000bbf); /* CCI_RP */ - apb_write_reg(2, 0x4d, 0x00000376); /* CCI_RPSQ */ - apb_write_reg(2, 0x4e, 0x00202109); /* CCI_CTRL */ - apb_write_reg(2, 0x52, 0x00000000); /* CCI_NOTCH1_A2 */ - apb_write_reg(2, 0x53, 0x00000000); /* CCI_NOTCH1_B1 */ - apb_write_reg(2, 0x54, 0x00c00000); /* CCI_NOTCH2_A1 */ - apb_write_reg(2, 0x55, 0x00000000); /* CCI_NOTCH2_A2 */ - apb_write_reg(2, 0x56, 0x00000000); /* CCI_NOTCH2_B1 */ - apb_write_reg(2, 0x57, 0x00000000); /* CCI_NOTCH2_B1 */ - apb_write_reg(2, 0x58, 0x00000886); /* MODE_DETECT_CTRL */ - apb_write_reg(2, 0x5c, 0x00001011); /* ICFO_EST_CTRL */ - apb_write_reg(2, 0x5f, 0x00010503); /* TPS_FCFO_CTRL */ - apb_write_reg(2, 0x61, 0x00000003); /* DE_PN_CTRL */ - apb_write_reg(2, 0x61, apb_read_reg(2, 0x61) | (1 << 2)); - /* DE_PN_CTRL SP sync close , Use TPS only ; */ - apb_write_reg(2, 0x68, 0x004060c0); /* CHAN_EST_CTRL0 */ - apb_write_reg(2, 0x68, apb_read_reg(2, 0x68) & ~(1 << 7)); - /* SNR report filter; */ - /*apb_write_reg(2, 0x68, apb_read_reg(2, 0x68) &~(1<<13)); // - * Timing Adjust Shutdown; - */ - apb_write_reg(2, 0x69, 0x148c3812); /* CHAN_EST_CTRL1 */ - /*apb_write_reg(2, 0x69, apb_read_reg(2, 0x69) | (1<<10)); // - * Disable FD data update - */ - /*apb_write_reg(2, 0x69, apb_read_reg(2, 0x69) | (1<<9)); // - * set FD coeff - */ - /*apb_write_reg(2, 0x69, apb_read_reg(2, 0x69) | (1<<8)); // - * set TD coeff - */ - apb_write_reg(2, 0x6a, 0x9101012d); /* CHAN_EST_CTRL2 */ - apb_write_reg(2, 0x6b, 0x00442211); /* CHAN_EST_CTRL2 */ - apb_write_reg(2, 0x6c, 0x01fc040a); /* CHAN_EST_CTRL3 */ - apb_write_reg(2, 0x6d, 0x0030303f); /* SET SNR THRESHOLD */ - apb_write_reg(2, 0x73, 0xffffffff); /* CCI0_PILOT_UPDATE_CTRL */ - apb_write_reg(2, 0x74, 0xffffffff); /* CCI0_DATA_UPDATE_CTRL */ - apb_write_reg(2, 0x75, 0xffffffff); /* CCI1_PILOT_UPDATE_CTRL */ - apb_write_reg(2, 0x76, 0xffffffff); /* CCI1_DATA_UPDATE_CTRL */ - - /* Set ACF and ACFEQ coeffecient */ - switch (sr) { - case 0: - set_ACF_coef(21, bw); - break; - case 1: - set_ACF_coef(21, bw); - break; - case 2: - set_ACF_coef(28, bw); - break; - case 3: - set_ACF_coef(45, bw); - break; - default: - break; - } - - apb_write_reg(2, 0x78, 0x000001a2); - /* FEC_CTRL parallel mode ; [27:24] is TS clk/valid/sync/error */ - apb_write_reg(2, 0x7d, 0x0000009d); - apb_write_reg(2, 0xd6, 0x00000003); - apb_write_reg(2, 0xd7, 0x00000008); - apb_write_reg(2, 0xd8, 0x00000120); - apb_write_reg(2, 0xd9, 0x01010101); - apb_write_reg(2, 0x04, 0x00000000); - /* TPS Current, QPSK, none Hierarchy, HP, LP 1/2 */ - - tmp = (1 << 25) | ((bw & 3) << 20) | (1 << 16) | (1 << 1); - apb_write_reg(2, 0x02, tmp); - apb_write_reg(2, 0x03, (1 << 6)); /* Cordic parameter Calc */ - - udelay(1); - - tmp = apb_read_reg(2, 0x02); - tmp |= (1 << 24) | 1; /* FSM, Demod enable. */ - apb_write_reg(2, 0x02, tmp); -} - -int dvbt_set_ch(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c, - struct aml_demod_dvbt *demod_dvbt) -{ - int ret = 0; - u8 bw, sr, ifreq, agc_mode; - u32 ch_freq; - - bw = demod_dvbt->bw; - sr = demod_dvbt->sr; - ifreq = demod_dvbt->ifreq; - agc_mode = demod_dvbt->agc_mode; - ch_freq = demod_dvbt->ch_freq; - - /* Set registers */ - /*//////////////////////////////////// */ - /* bw == 0 : 8M */ - /* 1 : 7M */ - /* 2 : 6M */ - /* 3 : 5M */ - /* sr == 0 : 20.7M */ - /* 1 : 20.8333M */ - /* 2 : 28.5714M */ - /* 3 : 45M */ - /* ifreq == 0: 36.13MHz */ - /* 1: 4.57MHz */ - /* agc_mode == 0: single AGC */ - /* 1: dual AGC */ - /*//////////////////////////////////// */ - if (bw > 3) { - dprintk("Error: Invalid Bandwidth option %d\n", bw); - bw = 0; - ret = -1; - } - - if (sr > 3) { - dprintk("Error: Invalid Sampling Freq option %d\n", sr); - sr = 2; - ret = -1; - } - - if (ifreq > 1) { - dprintk("Error: Invalid IFreq option %d\n", ifreq); - ifreq = 0; - ret = -1; - } - - if (agc_mode > 3) { - dprintk("Error: Invalid AGC mode option %d\n", agc_mode); - agc_mode = 0; - ret = -1; - } - /* if (ret != 0) return ret; */ - - /* Set DVB-T */ - (*DEMOD_REG0) |= 1; - - demod_sta->dvb_mode = 1; - demod_sta->ch_mode = 0; /* TODO */ - demod_sta->agc_mode = agc_mode; - demod_sta->ch_freq = ch_freq; - if (demod_i2c->tuner == 1) - demod_sta->ch_if = 36130; - else if (demod_i2c->tuner == 2) - demod_sta->ch_if = 4570; - - demod_sta->ch_bw = (8 - bw) * 1000; - demod_sta->symb_rate = 0; /* TODO */ - - /* Set Tuner */ - if (ch_freq < 1000 || ch_freq > 900000) { - dprintk - ( - "Error: Invalid Channel Freq option %d, Skip Set tuner\n", - ch_freq); - /*ch_freq = 474000; */ - ret = -1; - } else { - /* tuner_set_ch(demod_sta, demod_i2c); */ - } - - if ((ch_freq % 100) == 2) - dprintk("Input frequency is XXX002, Skip initial demod\n"); - else - dvbt_reg_initial(demod_sta); - - dvbt_enable_irq(7); /* open symbolhead int */ - - tuner_type = demod_i2c->tuner; - - return ret; -} - -static int dvbt_get_ch_power(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c) -{ - u32 ad_power; - - ad_power = - agc_power_to_dbm((apb_read_reg(2, 0x1c) & 0x7ff), - apb_read_reg(2, 0x1b) & 0x1ff, 0, - demod_i2c->tuner); - return ad_power; -} - -int dvbt_sfo(void) -{ - int sfo; - - sfo = apb_read_reg(2, 0x47) & 0xfff; - sfo = (sfo > 0x7ff) ? (sfo - 0x1000) : sfo; - return sfo; -} - -int dvbt_fcfo(void) -{ - int fcfo; - - fcfo = (apb_read_reg(2, 0x26)) & 0xffffff; - fcfo = (fcfo > 0x7fffff) ? (fcfo - 0x1000000) : fcfo; - return fcfo; -} - -static int dvbt_total_packet_error(void) -{ - return apb_read_reg(2, 0xbf); -} - -static int dvbt_super_frame_counter(void) -{ - return apb_read_reg(2, 0xc0) & 0xfffff; -} - -static int dvbt_packet_correct_in_sframe(void) -{ - return apb_read_reg(2, 0xc1) & 0xfffff; -} - -/*static int dvbt_resync_counter(void) - * {return((apb_read_reg(2, 0xc0)>>20)&0xff);} - */ -static int dvbt_packets_per_sframe(void) -{ - u32 tmp; - int hier_mode; - int constel; - int hp_code_rate; - int lp_code_rate; - int hier_sel; - int code_rate; - int ret; - - tmp = apb_read_reg(2, 0x06); - constel = tmp >> 13 & 3; - hier_mode = tmp >> 10 & 7; - hp_code_rate = tmp >> 7 & 7; - lp_code_rate = tmp >> 4 & 7; - - if (hier_mode == 0) { - code_rate = hp_code_rate; - } else { - tmp = apb_read_reg(2, 0x78); - hier_sel = tmp >> 9 & 1; - if (hier_sel == 0) { - constel = 0; /* QPSK; */ - code_rate = hp_code_rate; - } else { - constel = constel == 2 ? 1 : 0; - code_rate = lp_code_rate; - } - } - - switch (code_rate) { - case 0: - ret = (constel == 0) ? 1008 : (constel == 1) ? 2016 : 3024; - break; - case 1: - ret = (constel == 0) ? 1344 : (constel == 1) ? 2688 : 4032; - break; - case 2: - ret = (constel == 0) ? 1512 : (constel == 1) ? 3024 : 4536; - break; - case 3: - ret = (constel == 0) ? 1680 : (constel == 1) ? 3360 : 5040; - break; - case 4: - ret = (constel == 0) ? 1764 : (constel == 1) ? 3528 : 5292; - break; - default: - ret = (constel == 0) ? 1008 : (constel == 1) ? 2016 : 3024; - break; - } - return ret; -} - -static int dvbt_get_per(void) -{ - int packets_per_sframe; - int error; - int per; - - packets_per_sframe = dvbt_packets_per_sframe(); - error = packets_per_sframe - dvbt_packet_correct_in_sframe(); - per = 1000 * error / packets_per_sframe; - - return per; -} - -static void dvbt_set_test_bus(u8 sel) -{ - u32 tmp; - - tmp = apb_read_reg(2, 0x7f); - tmp &= ~(0x1f); - tmp |= ((1 << 15) | (1 << 5) | (sel & 0x1f)); - apb_write_reg(2, 0x7f, tmp); -} - -/* - * void dvbt_get_test_out(u8 sel, u32 len, u32 *buf) - * { - * int i; - * - * dvbt_set_test_bus(sel); - * - * for (i=0; i> 10) & 0x1) { - buf[i++] = apb_read_reg(2, 0x13); - buf[i++] = apb_read_reg(2, 0x13); - buf[i++] = apb_read_reg(2, 0x13); - buf[i++] = apb_read_reg(2, 0x13); - buf[i++] = apb_read_reg(2, 0x13); - buf[i++] = apb_read_reg(2, 0x13); - buf[i++] = apb_read_reg(2, 0x13); - buf[i++] = apb_read_reg(2, 0x13); - } else { - i--; - } - - cnt++; - } -} - -static int dvbt_get_avg_per(void) -{ - int packets_per_sframe; - static int err_last; - static int err_now; - static int rsnum_now; - static int rsnum_last; - int per; - - packets_per_sframe = dvbt_packets_per_sframe(); - rsnum_last = rsnum_now; - rsnum_now = dvbt_super_frame_counter(); - err_last = err_now; - err_now = dvbt_total_packet_error(); - if (rsnum_now != rsnum_last) - per = 1000 * (err_now - err_last) / - ((rsnum_now - rsnum_last) * packets_per_sframe); - else - per = 123; - - return per; -} - -int dvbt_status(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c, - struct aml_demod_sts *demod_sts) -{ - /* if parameters are needed to calc, pass the struct to func. */ - /* all small funcs like read_snr() should be static. */ - - demod_sts->ch_snr = apb_read_reg(2, 0x0a); - demod_sts->ch_per = dvbt_get_per(); - demod_sts->ch_pow = dvbt_get_ch_power(demod_sta, demod_i2c); - demod_sts->ch_ber = apb_read_reg(2, 0x0b); - demod_sts->ch_sts = apb_read_reg(2, 0); - demod_sts->dat0 = dvbt_get_avg_per(); - demod_sts->dat1 = apb_read_reg(2, 0x06); - return 0; -} - -static int dvbt_get_status(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c) -{ - return apb_read_reg(2, 0x0) >> 12 & 1; -} - -static int dvbt_ber(void); - -static int dvbt_get_ber(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c) -{ - return dvbt_ber(); /*unit: 1e-7 */ -} - -static int dvbt_get_snr(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c) -{ - return apb_read_reg(2, 0x0a) & 0x3ff; /*dBm: bit0~bit2=decimal */ -} - -static int dvbt_get_strength(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c) -{ - int dbm = dvbt_get_ch_power(demod_sta, demod_i2c); - - return dbm; -} - -static int dvbt_get_ucblocks(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c) -{ - return dvbt_get_per(); -} - -struct demod_status_ops *dvbt_get_status_ops(void) -{ - static struct demod_status_ops ops = { - .get_status = dvbt_get_status, - .get_ber = dvbt_get_ber, - .get_snr = dvbt_get_snr, - .get_strength = dvbt_get_strength, - .get_ucblocks = dvbt_get_ucblocks, - }; - - return &ops; -} - -void dvbt_enable_irq(int dvbt_irq) -{ - /* clear status & enable irq */ - (*OFDM_INT_STS) &= ~(1 << dvbt_irq); - (*OFDM_INT_EN) |= (1 << dvbt_irq); -} - -void dvbt_disable_irq(int dvbt_irq) -{ - /* disable irq & clear status */ - (*OFDM_INT_EN) &= ~(1 << dvbt_irq); - (*OFDM_INT_STS) &= ~(1 << dvbt_irq); -} - -char *dvbt_irq_name[] = { - "PFS_FCFO", - "PFS_ICFO", - " CS_FCFO", - " PFS_SFO", - " PFS_TPS", - " SP", - " CCI", - " Symbol", - " In_Sync", - "Out_Sync", - "FSM Stat" -}; - -void dvbt_isr(struct aml_demod_sta *demod_sta) -{ - u32 stat, mask; - int dvbt_irq; - - stat = (*OFDM_INT_STS); - mask = (*OFDM_INT_EN); - stat &= mask; - - for (dvbt_irq = 0; dvbt_irq < 11; dvbt_irq++) { - if (stat >> dvbt_irq & 1) { - if (demod_sta->debug) - dprintk("irq: aml_demod dvbt %2d %s %8x %8x\n", - dvbt_irq, dvbt_irq_name[dvbt_irq], stat, - mask); - /* dvbt_disable_irq(dvbt_irq); */ - } - } - /* clear status */ - (*OFDM_INT_STS) = 0; -} - -static int demod_monitor_ave(void); -int dvbt_isr_islock(void) -{ -#define IN_SYNC_MASK (0x100) - - u32 stat, mask; - - stat = (*OFDM_INT_STS); - *OFDM_INT_STS = stat & (~IN_SYNC_MASK); - - mask = (*OFDM_INT_EN); - stat &= mask; - - return (stat & IN_SYNC_MASK) == IN_SYNC_MASK; -} - -int dvbt_isr_monitor(void) -{ -#define SYM_HEAD_MASK (0x80) - u32 stat, mask; - - stat = (*OFDM_INT_STS); - *OFDM_INT_STS = stat & (~SYM_HEAD_MASK); - - mask = (*OFDM_INT_EN); - stat &= mask; - /* symbol_head int */ - if ((stat & SYM_HEAD_MASK) == SYM_HEAD_MASK) - demod_monitor_ave(); - return 0; -} - -int dvbt_isr_cancel(void) -{ - *OFDM_INT_STS = 0; - *OFDM_INT_EN = 0; - return 0; -} - -static int demod_monitor_instant(void) -{ - int SNR; - int SNR_SP = 500; - int SNR_TPS = 0; - int SNR_CP = 0; - int SFO_residual = 0; - int SFO_esti = 0; - int FCFO_esti = 0; - int FCFO_residual = 0; - int AGC_Gain = 0; - int be_vit_error = 0; - int Signal_power = 0; - int FECFlag = 0; - int EQ_seg_ratio = 0; - int tps_0 = 0; - int tps_1 = 0; - int tps_2 = 0; - int cci_blank = 0; - - int SFO; - int FCFO; - int timing_adj; - int RS_CorrectNum; - int RS_Error_sum; - int resync_times; - int tps_summary; - - int tps_window; - int tps_guard; - int tps_constell; - int tps_Hier_none; - int tps_Hier_alpha; - int tps_HP_cr; - int tps_LP_cr; - - int tmpAGCGain; - - /* Read Registers */ - SNR = apb_read_reg(2, 0x0a); - FECFlag = (apb_read_reg(2, 0x00) >> 11) & 0x3; - SFO = apb_read_reg(2, 0x47) & 0xfff; - SFO_esti = apb_read_reg(2, 0x60) & 0xfff; - FCFO_esti = (apb_read_reg(2, 0x60) >> 11) & 0xfff; - FCFO = (apb_read_reg(2, 0x26)) & 0xffffff; - be_vit_error = apb_read_reg(2, 0x0c) & 0x1fff; - timing_adj = apb_read_reg(2, 0x6f) & 0x1fff; - RS_CorrectNum = apb_read_reg(2, 0xc1) & 0xfffff; - Signal_power = (apb_read_reg(2, 0x1b)) & 0x1ff; - EQ_seg_ratio = apb_read_reg(2, 0x6e) & 0x3ffff; - tps_0 = apb_read_reg(2, 0x64); - tps_1 = apb_read_reg(2, 0x65); - tps_2 = apb_read_reg(2, 0x66) & 0xf; - tps_summary = apb_read_reg(2, 0x04) & 0x7fff; - cci_blank = (apb_read_reg(2, 0x66) >> 16); - RS_Error_sum = apb_read_reg(2, 0xbf) & 0x3ffff; - resync_times = (apb_read_reg(2, 0xc0) >> 20) & 0xff; - AGC_Gain = apb_read_reg(2, 0x1c) & 0x7ff; - - /* Calc */ - SFO_residual = (SFO > 0x7ff) ? (SFO - 0x1000) : SFO; - FCFO_residual = (FCFO > 0x7fffff) ? (FCFO - 0x1000000) : FCFO; - FCFO_esti = (FCFO_esti > 0x7ff) ? (FCFO_esti - 0x1000) : FCFO_esti; - SNR_CP = (SNR) & 0x3ff; - SNR_TPS = (SNR >> 10) & 0x3ff; - SNR_SP = (SNR >> 20) & 0x3ff; - SNR_SP = (SNR_SP > 0x1ff) ? SNR_SP - 0x400 : SNR_SP; - SNR_TPS = (SNR_TPS > 0x1ff) ? SNR_TPS - 0x400 : SNR_TPS; - SNR_CP = (SNR_CP > 0x1ff) ? SNR_CP - 0x400 : SNR_CP; - tmpAGCGain = AGC_Gain; - timing_adj = (timing_adj > 0xfff) ? timing_adj - 0x2000 : timing_adj; - - tps_window = (tps_summary & 0x3); - tps_guard = ((tps_summary >> 2) & 0x3); - tps_constell = ((tps_summary >> 13) & 0x3); - tps_Hier_none = (((tps_summary >> 10) & 0x7) == 0) ? 1 : 0; - tps_Hier_alpha = (tps_summary >> 11) & 0x3; - tps_Hier_alpha = (tps_Hier_alpha == 3) ? 4 : tps_Hier_alpha; - tps_LP_cr = (tps_summary >> 4) & 0x7; - tps_HP_cr = (tps_summary >> 7) & 0x7; - - dprintk("\n\n"); - switch (tps_window) { - case 0: - dprintk("2K "); - break; - case 1: - dprintk("8K "); - break; - case 2: - dprintk("4K "); - break; - default: - dprintk("UnWin "); - break; - } - switch (tps_guard) { - case 0: - dprintk("1/32 "); - break; - case 1: - dprintk("1/16 "); - break; - case 2: - dprintk("1/ 8 "); - break; - case 3: - dprintk("1/ 4 "); - break; - default: - dprintk("UnGuard "); - break; - } - switch (tps_constell) { - case 0: - dprintk(" QPSK "); - break; - case 1: - dprintk("16QAM "); - break; - case 2: - dprintk("64QAM "); - break; - default: - dprintk("UnConstl "); - break; - } - switch (tps_Hier_none) { - case 0: - dprintk("Hiera "); - break; - case 1: - dprintk("non-H "); - break; - default: - dprintk("UnHier "); - break; - } - dprintk("%d ", tps_Hier_alpha); - dprintk("HP "); - switch (tps_HP_cr) { - case 0: - dprintk("1/2 "); - break; - case 1: - dprintk("2/3 "); - break; - case 2: - dprintk("3/4 "); - break; - case 3: - dprintk("5/6 "); - break; - case 4: - dprintk("7/8 "); - break; - default: - dprintk("UnHCr "); - break; - } - dprintk("LP "); - switch (tps_LP_cr) { - case 0: - dprintk("1/2 "); - break; - case 1: - dprintk("2/3 "); - break; - case 2: - dprintk("3/4 "); - break; - case 3: - dprintk("5/6 "); - break; - case 4: - dprintk("7/8 "); - break; - default: - dprintk("UnLCr "); - break; - } - dprintk("\n"); - dprintk("P %4x ", RS_Error_sum); - dprintk("SP %2d ", SNR_SP); - dprintk("TPS %2d ", SNR_TPS); - dprintk("CP %2d ", SNR_CP); - dprintk("EQS %2x ", EQ_seg_ratio); - dprintk("RSC %4d ", RS_CorrectNum); - dprintk("SFO %3d ", SFO_residual); - dprintk("FCFO %4d ", FCFO_residual); - dprintk("Vit %3x ", be_vit_error); - dprintk("Timing %3d ", timing_adj); - dprintk("SigP %3x ", Signal_power); - dprintk("AGC %d ", tmpAGCGain); - dprintk("SigP %d ", - agc_power_to_dbm(tmpAGCGain, Signal_power, 0, tuner_type)); - dprintk("FEC %x ", FECFlag); - dprintk("ReSyn %x ", resync_times); - dprintk("cciB %x", cci_blank); - - dprintk("\n"); - - return 0; -} - -int serial_div(int a, int b) -{ - int c; - int cnt; - int b_buf; - - if (b == 0) - return 0x7fffffff; - if (a == 0) - return 0; - - c = 0; - cnt = 0; - - a = (a < 0) ? -1 * a : a; - b = (b < 0) ? -1 * b : b; - - b_buf = b; - - while (a >= b) { - b = b << 1; - cnt++; - } - while (b > b_buf) { - b = b >> 1; - c = c << 1; - if (a > b) { - c = c + 1; - a = a - b; - } - } - return c; -} - -static int ave0, bit_unit_L; - -static int dvbt_ber(void) -{ - int BER_e_n7 = serial_div(ave0 * 40, bit_unit_L); - - return BER_e_n7; -} - -static int demod_monitor_ave(void) -{ - static int i; - static int ave[3] = { 0, 0, 0 }; - - ave[0] = ave[0] + (apb_read_reg(2, 0x0b) & 0x7ff); - ave[1] = ave[1] + (apb_read_reg(2, 0x0a) & 0x3ff); - ave[2] = ave[2] + (apb_read_reg(2, 0x0c) & 0x1fff); - - i++; - - if (i >= 8192) { - int tps_mode; - int tps_constell; - int r_t; - int mode_L; - int const_L; - int SNR_Int; - int SNR_fra; - - if (debug_amldvbt) - demod_monitor_instant(); - - r_t = apb_read_reg(2, 0x04); - tps_mode = r_t & 0x3; - tps_constell = (r_t >> 13) & 0x3; - mode_L = (tps_mode == 0) ? 1 : (tps_mode == 1) ? 4 : 2; - const_L = (tps_constell == 0) ? 2 : (tps_constell == 1) ? 4 : 6; - bit_unit_L = 189 * mode_L * const_L; - SNR_Int = (ave[1] >> 16); - switch ((ave[1] >> 13) & 0x7) { - case 0: - SNR_fra = 0; - break; - case 1: - SNR_fra = 125; - break; - case 2: - SNR_fra = 250; - break; - case 3: - SNR_fra = 375; - break; - case 4: - SNR_fra = 500; - break; - case 5: - SNR_fra = 625; - break; - case 6: - SNR_fra = 750; - break; - case 7: - SNR_fra = 875; - break; - default: - SNR_fra = 0; - break; - } - - ave0 = ave[0]; - - if (debug_amldvbt) - dprintk("RSBi %d Thresh %d SNR %d.%d Vit %x\n\n", - (ave[0] >> 3) * 5, (bit_unit_L * 8), SNR_Int, - SNR_fra, (ave[2] >> 13)); - i = 0; - ave[0] = ave[1] = ave[2] = 0; - } - - return i; -} - -int dvbt_switch_to_HP(void) -{ - apb_write_reg(2, 0x78, apb_read_reg(2, 0x78) & ~(1 << 9)); - return 0; -} - -int dvbt_switch_to_LP(void) -{ - apb_write_reg(2, 0x78, apb_read_reg(2, 0x78) | (1 << 9)); - return 0; -} - -int dvbt_shutdown(void) -{ - apb_write_reg(2, 0x02, 0x00800000); - /* SW reset bit[23] ; write anything to zero */ - apb_write_reg(2, 0x00, 0x00000000); - return 0; -} - -int dvbt_get_params(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *adap, int *code_rate_HP, - /* high priority stream code rate */ - int *code_rate_LP, /* low priority stream code rate */ - int *constellation, /* modulation type (see above) */ - int *transmission_mode, - int *guard_interval, int *hierarchy_information) -{ - int tps_summary, tps_window, tps_guard, tps_constell, tps_Hier_none; - int tps_Hier_alpha, tps_LP_cr, tps_HP_cr; - - tps_summary = apb_read_reg(2, 0x04) & 0x7fff; - tps_window = (tps_summary & 0x3); - tps_guard = ((tps_summary >> 2) & 0x3); - tps_constell = ((tps_summary >> 13) & 0x3); - tps_Hier_none = (((tps_summary >> 10) & 0x7) == 0) ? 1 : 0; - tps_Hier_alpha = (tps_summary >> 11) & 0x3; - tps_Hier_alpha = (tps_Hier_alpha == 3) ? 4 : tps_Hier_alpha; - tps_LP_cr = (tps_summary >> 4) & 0x7; - tps_HP_cr = (tps_summary >> 7) & 0x7; - if (code_rate_HP) - *code_rate_HP = tps_HP_cr; /*1/2:2/3:3/4:5/6:7/8 */ - if (code_rate_LP) - *code_rate_LP = tps_LP_cr; /*1/2:2/3:3/4:5/6:7/8 */ - if (constellation) - *constellation = tps_constell; /*QPSK/16QAM/64QAM */ - if (transmission_mode) - *transmission_mode = tps_window; /*2K/8K/4K */ - if (guard_interval) - *guard_interval = tps_guard; /*1/32:1/16:1/8:1/4 */ - if (hierarchy_information) - *hierarchy_information = tps_Hier_alpha; /*1/2/4 */ - return 0; -} diff --git a/drivers/stream_input/tv_frontend/dtv_demod/i2c_func.c b/drivers/stream_input/tv_frontend/dtv_demod/i2c_func.c deleted file mode 100644 index 68b214e..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/i2c_func.c +++ b/dev/null @@ -1,42 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#include -#include -#include -#include -#include "demod_func.h" - -int am_demod_i2c_xfer(struct aml_demod_i2c *adap, struct i2c_msg msgs[], - int num) -{ - int ret = 0; - - if (adap->scl_oe) { - /* ret = aml_i2c_sw_bit_xfer(adap, msgs, num);*/ - } else { - if (adap->i2c_priv) - ret = i2c_transfer((struct i2c_adapter *)adap->i2c_priv, - msgs, num); - else - ; - /* printk("i2c error, no valid i2c\n");*/ - } - return ret; -} diff --git a/drivers/stream_input/tv_frontend/dtv_demod/include/acf_filter_coefficient.h b/drivers/stream_input/tv_frontend/dtv_demod/include/acf_filter_coefficient.h deleted file mode 100644 index 5744885..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/include/acf_filter_coefficient.h +++ b/dev/null @@ -1,414 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -void program_acf(int acf1[20], int acf2[33]) -{ - int i; - - for (i = 0; i < 20; i++) - apb_write_reg(DVBT_BASE + (0x2c + i) * 4, acf1[i]); - for (i = 0; i < 33; i++) { - apb_write_reg(DVBT_BASE + 0xfe * 4, i); - apb_write_reg(DVBT_BASE + 0xff * 4, acf2[i]); - } -} - -void ini_acf_iireq_src_45m_8m(void) -{ - int acf1[] = { 0x294, 0x085, 0x076, 0x01e, - 0x27c, 0x0af, 0x2bf, 0x06d, - 0x265, 0x0d8, 0x270, 0x05e, - 0x257, 0x0ef, 0x25b, 0x04b, - 0x24f, 0x0fc, 0x254, 0x04d - }; - int acf2[] = { 0x3f3fff, 0x3da7cd, 0x3c0f9b, 0x3a7768, 0x38df35, - 0x373f01, - 0x3596cd, 0x33ee98, 0x323e62, 0x307e2b, 0x2eb5f3, - 0x2ce5b9, - 0x2b057e, 0x290d41, 0x26fd00, 0x24dcbd, 0x229477, - 0x202c2c, - 0x1d93dc, 0x1ac386, 0x17b328, 0x144ac1, 0x106a4d, - 0x0be1c8, - 0x07e129, 0x04d0cc, 0x015064, 0x3d47ec, 0x38675e, - 0x326eb1, - 0x326e4d, 0x326e4d, 0x00064d - }; - - program_acf(acf1, acf2); -} - -void ini_acf_iireq_src_45m_7m(void) -{ - int acf1[] = { 0x283, 0x091, 0x02f, 0x01e, - 0x26a, 0x0b8, 0x296, 0x06d, - 0x253, 0x0dc, 0x257, 0x05e, - 0x245, 0x0f1, 0x246, 0x04b, - 0x23d, 0x0fc, 0x241, 0x04d - }; - int acf2[] = { 0x3f3fff, 0x3dafce, 0x3c1f9c, 0x3a8769, 0x38ef37, - 0x374f03, - 0x35aecf, 0x34069b, 0x325665, 0x30962e, 0x2ecdf6, - 0x2cfdbc, - 0x2b1581, 0x291d43, 0x271503, 0x24e4bf, 0x229c78, - 0x202c2d, - 0x1d8bdc, 0x1ab384, 0x179325, 0x141abc, 0x102a46, - 0x0b81be, - 0x07711c, 0x0448bd, 0x00b052, 0x3c7fd6, 0x374740, - 0x308684, - 0x308610, 0x308610, 0x000610 - }; - - program_acf(acf1, acf2); -} - -void ini_acf_iireq_src_45m_6m(void) -{ - int acf1[] = { 0x272, 0x09e, 0x3dc, 0x01e, - 0x259, 0x0c0, 0x272, 0x06d, - 0x242, 0x0e1, 0x240, 0x05e, - 0x235, 0x0f3, 0x234, 0x04b, - 0x22e, 0x0fd, 0x230, 0x04d - }; - int acf2[] = { 0x3f47ff, 0x3dbfcf, 0x3c379e, 0x3aa76d, 0x391f3c, - 0x378709, - 0x35e6d6, 0x343ea2, 0x328e6d, 0x30d636, 0x2f0dfe, - 0x2d35c4, - 0x2b4d88, 0x294d49, 0x273d08, 0x2504c4, 0x22b47c, - 0x203c2f, - 0x1d9bde, 0x1ac386, 0x17a327, 0x1432bf, 0x104249, - 0x0ba9c2, - 0x07a922, 0x0490c5, 0x01185c, 0x3d0fe5, 0x383f58, - 0x3286af, - 0x328650, 0x328650, 0x000650 - }; - - program_acf(acf1, acf2); -} - -void ini_acf_iireq_src_45m_5m(void) -{ - int acf1[] = { 0x260, 0x0ab, 0x37e, 0x02e, - 0x249, 0x0ca, 0x251, 0x06d, - 0x233, 0x0e6, 0x22d, 0x05e, - 0x227, 0x0f5, 0x224, 0x04b, - 0x220, 0x0fd, 0x221, 0x04d - }; - int acf2[] = { 0x3f3fff, 0x3db7cf, 0x3c279d, 0x3a9f6c, 0x39073a, - 0x377707, - 0x35d6d4, 0x3436a0, 0x328e6b, 0x30d636, 0x2f15ff, - 0x2d4dc6, - 0x2b758c, 0x29854f, 0x278511, 0x256ccf, 0x232c89, - 0x20cc3f, - 0x1e33f0, 0x1b6b9b, 0x185b3d, 0x14e2d5, 0x10f260, - 0x0c51d7, - 0x082934, 0x04f8d4, 0x014066, 0x3ccfe4, 0x372f46, - 0x2f5673, - 0x2f55ea, 0x2f55ea, 0x0005ea - }; - - program_acf(acf1, acf2); -} - -void ini_acf_iireq_src_2857m_8m(void) -{ - int acf1[] = { 0x2df, 0x059, 0x144, 0x00e, - 0x2d3, 0x08f, 0x38d, 0x06f, - 0x2c6, 0x0c5, 0x302, 0x05e, - 0x2be, 0x0e7, 0x2d6, 0x04b, - 0x2b7, 0x0f9, 0x2c8, 0x04d - }; - int acf2[] = { 0x3f3fff, 0x3dbfcf, 0x3c379e, 0x3aaf6d, 0x391f3c, - 0x37870a, - 0x35eed7, 0x344ea3, 0x32a66f, 0x30f639, 0x2f3602, - 0x2d65c9, - 0x2b858e, 0x299552, 0x278d12, 0x2564cf, 0x231c88, - 0x20b43d, - 0x1e13ec, 0x1b3395, 0x181336, 0x1492cc, 0x109254, - 0x0be1cb, - 0x07c127, 0x0498c7, 0x00f85b, 0x3cbfde, 0x377747, - 0x309e88, - 0x309e13, 0x309e13, 0x000613 - }; - - program_acf(acf1, acf2); -} - -void ini_acf_iireq_src_2857m_7m(void) -{ - int acf1[] = { 0x2c6, 0x067, 0x10f, 0x01e, - 0x2b4, 0x099, 0x344, 0x06f, - 0x2a2, 0x0cb, 0x2cb, 0x05e, - 0x297, 0x0ea, 0x2a7, 0x04b, - 0x28f, 0x0fa, 0x29c, 0x04d - }; - int acf2[] = { 0x3f3fff, 0x3dbfcf, 0x3c379e, 0x3aa76d, 0x39173b, - 0x378709, - 0x35e6d6, 0x3446a2, 0x329e6d, 0x30e637, 0x2f2600, - 0x2d4dc7, - 0x2b6d8c, 0x297d4e, 0x276d0e, 0x2544cb, 0x22fc84, - 0x208438, - 0x1de3e7, 0x1b0b90, 0x17eb30, 0x146ac7, 0x107250, - 0x0bc9c6, - 0x07b124, 0x0490c5, 0x00f85b, 0x3cc7df, 0x37974a, - 0x30ce8d, - 0x30ce19, 0x30ce19, 0x000619 - }; - - program_acf(acf1, acf2); -} - -void ini_acf_iireq_src_2857m_6m(void) -{ - int acf1[] = { 0x2ac, 0x076, 0x0c9, 0x01e, - 0x297, 0x0a4, 0x2fd, 0x06d, - 0x281, 0x0d2, 0x299, 0x05e, - 0x274, 0x0ed, 0x27d, 0x04b, - 0x26c, 0x0fb, 0x274, 0x04d - }; - int acf2[] = { 0x3f3fff, 0x3db7cf, 0x3c279d, 0x3a976b, 0x390739, - 0x376f07, - 0x35ced3, 0x342e9f, 0x327e6a, 0x30c634, 0x2f05fc, - 0x2d35c4, - 0x2b5d89, 0x29654c, 0x275d0c, 0x253cca, 0x22fc83, - 0x209439, - 0x1dfbe9, 0x1b2b93, 0x181b35, 0x14b2ce, 0x10ca5a, - 0x0c41d4, - 0x084935, 0x0538d9, 0x01c071, 0x3db7fa, 0x38bf6b, - 0x327eb9, - 0x327e4f, 0x327e4f, 0x00064f - }; - - program_acf(acf1, acf2); -} - -void ini_acf_iireq_src_2857m_5m(void) -{ - int acf1[] = { 0x292, 0x087, 0x06e, 0x01e, - 0x27a, 0x0b0, 0x2b9, 0x06d, - 0x262, 0x0d8, 0x26d, 0x05e, - 0x254, 0x0f0, 0x258, 0x04b, - 0x24c, 0x0fc, 0x252, 0x04d - }; - int acf2[] = { 0x3f3fff, 0x3db7ce, 0x3c279d, 0x3a976b, 0x38ff38, - 0x376706, - 0x35c6d2, 0x341e9d, 0x326e68, 0x30ae31, 0x2eedf9, - 0x2d15c0, - 0x2b2d84, 0x293546, 0x272506, 0x24fcc2, 0x22ac7b, - 0x203c2f, - 0x1d9bde, 0x1ac386, 0x17a327, 0x1422be, 0x103247, - 0x0b91bf, - 0x07891e, 0x0470c1, 0x00e858, 0x3ccfde, 0x37bf4d, - 0x313e96, - 0x313e27, 0x313e27, 0x000627 - }; - - program_acf(acf1, acf2); -} - -void ini_acf_iireq_src_24m_8m(void) -{ - int acf1[] = { 0x303, 0x048, 0x17e, 0x00e, - 0x302, 0x081, 0x3f8, 0x00a, - 0x300, 0x0bd, 0x35b, 0x05e, - 0x2fe, 0x0e3, 0x325, 0x04b, - 0x2fb, 0x0f8, 0x313, 0x04d - }; - int acf2[] = { 0x3f47ff, 0x3dc7d0, 0x3c3fa0, 0x3abf6f, 0x392f3e, - 0x37a70d, - 0x360eda, 0x346ea7, 0x32c673, 0x31163d, 0x2f5606, - 0x2d8dce, - 0x2bad93, 0x29bd56, 0x27b517, 0x258cd4, 0x23448d, - 0x20cc41, - 0x1e2bf0, 0x1b4b98, 0x182338, 0x149ace, 0x109255, - 0x0bd1ca, - 0x07a123, 0x0468c2, 0x00b054, 0x3c5fd4, 0x37073a, - 0x302e79, - 0x302e05, 0x302e05, 0x000605 - }; - - program_acf(acf1, acf2); -} - -void ini_acf_iireq_src_24m_7m(void) -{ - int acf1[] = { 0x2e7, 0x055, 0x153, 0x00e, - 0x2dd, 0x08b, 0x3a5, 0x06f, - 0x2d2, 0x0c4, 0x315, 0x05e, - 0x2cb, 0x0e6, 0x2e7, 0x04b, - 0x2c5, 0x0f9, 0x2d8, 0x04d - }; - int acf2[] = { 0x3f3fff, 0x3dbfcf, 0x3c379e, 0x3aaf6d, 0x391f3c, - 0x37870a, - 0x35eed7, 0x344ea3, 0x32a66f, 0x30ee39, 0x2f2e02, - 0x2d65c9, - 0x2b858e, 0x298d51, 0x278511, 0x255cce, 0x231487, - 0x20a43c, - 0x1e0beb, 0x1b3394, 0x181335, 0x1492cb, 0x109254, - 0x0be1ca, - 0x07b925, 0x0480c5, 0x00d858, 0x3c87d8, 0x373740, - 0x305e80, - 0x305e0b, 0x305e0b, 0x00060b - }; - - program_acf(acf1, acf2); -} - -void ini_acf_iireq_src_24m_6m(void) -{ - int acf1[] = { 0x2c9, 0x065, 0x118, 0x01e, - 0x2b9, 0x097, 0x34f, 0x06f, - 0x2a7, 0x0ca, 0x2d3, 0x05e, - 0x29c, 0x0e9, 0x2ae, 0x04b, - 0x295, 0x0fa, 0x2a2, 0x04d - }; - int acf2[] = { 0x3f3fff, 0x3db7cf, 0x3c2f9d, 0x3a9f6c, 0x390f3a, - 0x377707, - 0x35d6d4, 0x342ea0, 0x32866b, 0x30ce34, 0x2f05fd, - 0x2d35c3, - 0x2b5588, 0x295d4b, 0x27550b, 0x252cc8, 0x22dc80, - 0x206c35, - 0x1dcbe4, 0x1af38c, 0x17cb2d, 0x144ac3, 0x104a4b, - 0x0b99c1, - 0x07791d, 0x0448be, 0x00b052, 0x3c6fd4, 0x37473f, - 0x30c686, - 0x30c618, 0x30c618, 0x000618 - }; - - program_acf(acf1, acf2); -} - -void ini_acf_iireq_src_24m_5m(void) -{ - int acf1[] = { 0x2ab, 0x077, 0x0c6, 0x01e, - 0x295, 0x0a5, 0x2fa, 0x06d, - 0x27f, 0x0d2, 0x297, 0x05e, - 0x272, 0x0ed, 0x27b, 0x04b, - 0x26a, 0x0fb, 0x272, 0x04d - }; - int acf2[] = { 0x3f3fff, 0x3db7cf, 0x3c2f9e, 0x3aa76c, 0x39173b, - 0x377f08, - 0x35ded5, 0x343ea1, 0x328e6c, 0x30de36, 0x2f15ff, - 0x2d45c6, - 0x2b658a, 0x29754d, 0x27650d, 0x253cca, 0x22f483, - 0x208438, - 0x1de3e7, 0x1b0b90, 0x17eb30, 0x1472c7, 0x107a51, - 0x0bd9c8, - 0x07c927, 0x04a8c9, 0x01205f, 0x3cf7e4, 0x37e752, - 0x31669a, - 0x31662c, 0x31662c, 0x00062c - }; - - program_acf(acf1, acf2); -} - -void ini_acf_iireq_src_207m_8m(void) -{ - int acf1[] = { 0x327, 0x039, 0x1a5, 0x07b, - 0x332, 0x076, 0x05c, 0x06e, - 0x33e, 0x0b6, 0x3b8, 0x05e, - 0x344, 0x0e0, 0x37a, 0x04b, - 0x345, 0x0f7, 0x365, 0x04d - }; - int acf2[] = { 0x3f47ff, 0x3dcfd1, 0x3c57a1, 0x3ad772, 0x394f42, - 0x37c711, - 0x3636df, 0x34a6ad, 0x32fe7a, 0x315645, 0x2f9e0f, - 0x2dd5d7, - 0x2bfd9d, 0x2a0d61, 0x280d21, 0x25e4df, 0x239c98, - 0x212c4d, - 0x1e8bfc, 0x1baba4, 0x188344, 0x14fad9, 0x10ea61, - 0x0c29d4, - 0x07e92d, 0x04a8cb, 0x00f05c, 0x3c87da, 0x371f3e, - 0x30267a, - 0x302604, 0x302604, 0x000604 - }; - - program_acf(acf1, acf2); -} - -void ini_acf_iireq_src_207m_7m(void) -{ - int acf1[] = { 0x307, 0x046, 0x182, 0x00e, - 0x306, 0x080, 0x002, 0x00a, - 0x306, 0x0bd, 0x364, 0x05e, - 0x304, 0x0e3, 0x32d, 0x04b, - 0x301, 0x0f8, 0x31b, 0x04d - }; - int acf2[] = { 0x3f47ff, 0x3dc7d0, 0x3c47a0, 0x3abf6f, 0x39373f, - 0x37a70d, - 0x3616db, 0x3476a8, 0x32d674, 0x31263f, 0x2f6608, - 0x2d9dd0, - 0x2bbd96, 0x29d559, 0x27cd19, 0x25a4d7, 0x235c90, - 0x20ec45, - 0x1e53f4, 0x1b739d, 0x18533d, 0x14d2d4, 0x10d25c, - 0x0c19d1, - 0x07e12c, 0x04a8ca, 0x00f05c, 0x3c8fdb, 0x372740, - 0x302e7c, - 0x302e05, 0x302e05, 0x000605 - }; - - program_acf(acf1, acf2); -} - -void ini_acf_iireq_src_207m_6m(void) -{ - int acf1[] = { 0x2e6, 0x056, 0x151, 0x00e, - 0x2db, 0x08c, 0x3a1, 0x06f, - 0x2d0, 0x0c4, 0x312, 0x05e, - 0x2c9, 0x0e6, 0x2e4, 0x04b, - 0x2c3, 0x0f9, 0x2d6, 0x04d - }; - int acf2[] = { 0x3f47ff, 0x3dbfd0, 0x3c3f9f, 0x3ab76e, 0x39273d, - 0x37970b, - 0x35fed9, 0x345ea5, 0x32b671, 0x31063b, 0x2f4604, - 0x2d75cb, - 0x2b9590, 0x29a553, 0x279513, 0x256cd0, 0x232489, - 0x20b43d, - 0x1e0bec, 0x1b3395, 0x180b35, 0x148acb, 0x108253, - 0x0bd1c8, - 0x07a123, 0x0470c2, 0x00c055, 0x3c77d6, 0x372f3e, - 0x306e80, - 0x306e0d, 0x306e0d, 0x00060d - }; - - program_acf(acf1, acf2); -} - -void ini_acf_iireq_src_207m_5m(void) -{ - int acf1[] = { 0x2c3, 0x068, 0x109, 0x01e, - 0x2b1, 0x09a, 0x33d, 0x06f, - 0x29f, 0x0cc, 0x2c6, 0x05e, - 0x293, 0x0ea, 0x2a3, 0x04b, - 0x28c, 0x0fa, 0x298, 0x04d - }; - int acf2[] = { 0x3f3fff, 0x3db7ce, 0x3c279d, 0x3a976b, 0x38ff38, - 0x376706, - 0x35c6d2, 0x341e9e, 0x327669, 0x30be32, 0x2ef5fb, - 0x2d25c1, - 0x2b4586, 0x295549, 0x274509, 0x251cc6, 0x22dc80, - 0x206c34, - 0x1dcbe4, 0x1afb8d, 0x17db2e, 0x1462c5, 0x106a4f, - 0x0bc9c6, - 0x07b124, 0x0488c5, 0x00e859, 0x3cafdc, 0x377f47, - 0x30ee8c, - 0x30ee1d, 0x30ee1d, 0x00061d - }; - - program_acf(acf1, acf2); -} diff --git a/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_che.h b/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_che.h deleted file mode 100644 index 4b23132..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_che.h +++ b/dev/null @@ -1,77 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#ifndef __ADDR_DTMB_CHE_H__ -#define __ADDR_DTMB_CHE_H__ - -#include "addr_dtmb_top.h" - -#define DTMB_CHE_ADDR(x) (DTMB_DEMOD_BASE + (x << 2)) - -#define DTMB_CHE_TE_HREB_SNR DTMB_CHE_ADDR(0x8d) -#define DTMB_CHE_MC_SC_TIMING_POWTHR DTMB_CHE_ADDR(0x8e) -#define DTMB_CHE_MC_SC_PROTECT_GD DTMB_CHE_ADDR(0x8f) -#define DTMB_CHE_TIMING_LIMIT DTMB_CHE_ADDR(0x90) -#define DTMB_CHE_TPS_CONFIG DTMB_CHE_ADDR(0x91) -#define DTMB_CHE_FD_TD_STEPSIZE DTMB_CHE_ADDR(0x92) -#define DTMB_CHE_QSTEP_SET DTMB_CHE_ADDR(0x93) -#define DTMB_CHE_SEG_CONFIG DTMB_CHE_ADDR(0x94) -#define DTMB_CHE_FD_TD_LEAKSIZE_CONFIG1 DTMB_CHE_ADDR(0x95) -#define DTMB_CHE_FD_TD_LEAKSIZE_CONFIG2 DTMB_CHE_ADDR(0x96) -#define DTMB_CHE_FD_TD_COEFF DTMB_CHE_ADDR(0x97) -#define DTMB_CHE_M_CCI_THR_CONFIG1 DTMB_CHE_ADDR(0x98) -#define DTMB_CHE_M_CCI_THR_CONFIG2 DTMB_CHE_ADDR(0x99) -#define DTMB_CHE_M_CCI_THR_CONFIG3 DTMB_CHE_ADDR(0x9a) -#define DTMB_CHE_CCIDET_CONFIG DTMB_CHE_ADDR(0x9b) -#define DTMB_CHE_IBDFE_CONFIG1 DTMB_CHE_ADDR(0x9d) -#define DTMB_CHE_IBDFE_CONFIG2 DTMB_CHE_ADDR(0x9e) -#define DTMB_CHE_IBDFE_CONFIG3 DTMB_CHE_ADDR(0x9f) -#define DTMB_CHE_TD_COEFF DTMB_CHE_ADDR(0xa0) -#define DTMB_CHE_FD_TD_STEPSIZE_ADJ DTMB_CHE_ADDR(0xa1) -#define DTMB_CHE_FD_COEFF_FRZ DTMB_CHE_ADDR(0xa2) -#define DTMB_CHE_FD_COEFF DTMB_CHE_ADDR(0xa3) -#define DTMB_CHE_FD_LEAKSIZE DTMB_CHE_ADDR(0xa4) -#define DTMB_CHE_IBDFE_CONFIG4 DTMB_CHE_ADDR(0xa5) -#define DTMB_CHE_IBDFE_CONFIG5 DTMB_CHE_ADDR(0xa6) -#define DTMB_CHE_IBDFE_CONFIG6 DTMB_CHE_ADDR(0xa7) -#define DTMB_CHE_IBDFE_CONFIG7 DTMB_CHE_ADDR(0xa8) -#define DTMB_CHE_DCM_SC_MC_GD_LEN DTMB_CHE_ADDR(0xa9) -#define DTMB_CHE_EQMC_PICK_THR DTMB_CHE_ADDR(0xaa) -#define DTMB_CHE_EQMC_THRESHOLD DTMB_CHE_ADDR(0xab) -#define DTMB_CHE_EQSC_PICK_THR DTMB_CHE_ADDR(0xad) -#define DTMB_CHE_EQSC_THRESHOLD DTMB_CHE_ADDR(0xae) -#define DTMB_CHE_PROTECT_GD_TPS DTMB_CHE_ADDR(0xaf) -#define DTMB_CHE_FD_TD_STEPSIZE_THR1 DTMB_CHE_ADDR(0xb0) -#define DTMB_CHE_TDFD_SWITCH_SYM1 DTMB_CHE_ADDR(0xb1) -#define DTMB_CHE_TDFD_SWITCH_SYM2 DTMB_CHE_ADDR(0xb2) -#define DTMB_CHE_EQ_CONFIG DTMB_CHE_ADDR(0xb3) -#define DTMB_CHE_EQSC_SNR_IMP_THR1 DTMB_CHE_ADDR(0xb4) -#define DTMB_CHE_EQSC_SNR_IMP_THR2 DTMB_CHE_ADDR(0xb5) -#define DTMB_CHE_EQMC_SNR_IMP_THR1 DTMB_CHE_ADDR(0xb6) -#define DTMB_CHE_EQMC_SNR_IMP_THR2 DTMB_CHE_ADDR(0xb7) -#define DTMB_CHE_EQSC_SNR_DROP_THR DTMB_CHE_ADDR(0xb8) -#define DTMB_CHE_EQMC_SNR_DROP_THR DTMB_CHE_ADDR(0xb9) -#define DTMB_CHE_M_CCI_THR DTMB_CHE_ADDR(0xba) -#define DTMB_CHE_TPS_MC DTMB_CHE_ADDR(0xbb) -#define DTMB_CHE_TPS_SC DTMB_CHE_ADDR(0xbc) -#define DTMB_CHE_CHE_SET_FSM DTMB_CHE_ADDR(0xbd) -#define DTMB_CHE_ZERO_NUM_THR DTMB_CHE_ADDR(0xbe) -#define DTMB_CHE_TIMING_READY DTMB_CHE_ADDR(0xbf) - -#endif diff --git a/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_che_bit.h b/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_che_bit.h deleted file mode 100644 index d81c477..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_che_bit.h +++ b/dev/null @@ -1,266 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#ifndef __ADDR_DTMB_CHE_BIT_H__ -#define __ADDR_DTMB_CHE_BIT_H__ - -struct DTMB_CHE_TE_HREB_SNR_BITS { - unsigned int te_hreb_snr:21, reserved0:11; -}; -struct DTMB_CHE_MC_SC_TIMING_POWTHR_BITS { - unsigned int mc_timing_powthr1:5, - reserved1:3, - mc_timing_powthr0:5, - reserved2:2, - sc_timing_powthr1:5, reserved3:4, sc_timing_powthr0:5, reserved4:3; -}; -struct DTMB_CHE_MC_SC_PROTECT_GD_BITS { - unsigned int h_valid:2, - reserved5:2, - dist:3, - reserved6:1, - ma_size:3, - reserved7:1, - mc_protect_gd:5, reserved8:3, sc_protect_gd:5, reserved9:7; -}; -struct DTMB_CHE_TIMING_LIMIT_BITS { - unsigned int ncoh_thd:3, - reserved10:1, - coh_thd:3, - reserved11:1, - strong_loc_thd:8, reserved12:4, timing_limit:5, reserved13:7; -}; -struct DTMB_CHE_TPS_CONFIG_BITS { - unsigned int tps_pst_num:5, - reserved14:3, - tps_pre_num:5, reserved15:3, chi_power_thr:8, reserved16:8; -}; -struct DTMB_CHE_FD_TD_STEPSIZE_BITS { - unsigned int fd_stepsize_thr03:5, - fd_stepsize_thr02:5, - fd_stepsize_thr01:5, - td_stepsize_thr03:5, - td_stepsize_thr02:5, td_stepsize_thr01:5, reserved17:2; -}; -struct DTMB_CHE_QSTEP_SET_BITS { - unsigned int factor_stable_thres:10, - reserved18:2, qstep_set:13, qstep_set_val:1, reserved19:6; -}; -struct DTMB_CHE_SEG_CONFIG_BITS { - unsigned int seg_bypass:1, - seg_num_1seg_log2:3, - seg_alpha:3, - seg_read_val:1, seg_read_addr:12, noise_input_shift:4, reserved20:8; -}; -struct DTMB_CHE_FD_TD_LEAKSIZE_CONFIG1_BITS { - unsigned int fd_leaksize_thr03:5, - fd_leaksize_thr02:5, - fd_leaksize_thr01:5, - td_leaksize_thr03:5, - td_leaksize_thr02:5, td_leaksize_thr01:5, reserved21:2; -}; -struct DTMB_CHE_FD_TD_LEAKSIZE_CONFIG2_BITS { - unsigned int fd_leaksize_thr13:5, - fd_leaksize_thr12:5, - fd_leaksize_thr11:5, - td_leaksize_thr13:5, - td_leaksize_thr12:5, td_leaksize_thr11:5, reserved22:2; -}; -struct DTMB_CHE_FD_TD_COEFF_BITS { - unsigned int td_coeff_frz:14, - reserved23:2, - td_coeff_addr:4, - td_coeff_init:1, - td_coeff_rst:1, - fd_coeff_init:1, - fd_coeff_done:1, - fd_coeff_rst:1, td_coeff_done:1, fd_coeff_addr:5, reserved24:1; -}; -struct DTMB_CHE_M_CCI_THR_CONFIG1_BITS { - unsigned int m_cci_thr_mc1:10, - m_cci_thr_mc2:10, m_cci_thr_mc3:10, reserved25:2; -}; -struct DTMB_CHE_M_CCI_THR_CONFIG2_BITS { - unsigned int m_cci_thr_sc2:10, - m_cci_thr_sc3:10, m_cci_thr_mc0:10, reserved26:2; -}; -struct DTMB_CHE_M_CCI_THR_CONFIG3_BITS { - unsigned int m_cci_thr_ma:10, - m_cci_thr_sc0:10, m_cci_thr_sc1:10, reserved27:2; -}; -struct DTMB_CHE_CCIDET_CONFIG_BITS { - unsigned int ccidet_dly:7, - ccidet_malpha:3, - ccidet_sc_mask_rng:5, - ccidet_mc_mask_rng:5, - ccidet_masize:4, - ccidect_sat_sft:3, - ccicnt_out_sel:2, tune_mask:1, m_cci_bypass:1, reserved28:1; -}; -struct DTMB_CHE_IBDFE_CONFIG1_BITS { - unsigned int ibdfe_cci_just_thr:13, - reserved29:3, - ibdfe_dmsg_point:5, reserved30:3, ibdfe_dmsg_alp:3, reserved31:5; -}; -struct DTMB_CHE_IBDFE_CONFIG2_BITS { - unsigned int ibdfe_rou_rat_1:10, - reserved32:6, ibdfe_rou_rat_0:10, reserved33:6; -}; -struct DTMB_CHE_IBDFE_CONFIG3_BITS { - unsigned int ibdfe_rou_rat_3:10, - reserved34:6, ibdfe_rou_rat_2:10, reserved35:6; -}; -struct DTMB_CHE_TD_COEFF_BITS { - unsigned int td_coeff:24, reserved36:8; -}; -struct DTMB_CHE_FD_TD_STEPSIZE_ADJ_BITS { - unsigned int fd_stepsize_adj:3, td_stepsize_adj:3, reserved37:26; -}; -struct DTMB_CHE_FD_COEFF_BITS { - unsigned int fd_coeff:24, reserved38:8; -}; -struct DTMB_CHE_FD_LEAKSIZE_BITS { - unsigned int fd_leaksize:18, reserved39:14; -}; -struct DTMB_CHE_IBDFE_CONFIG4_BITS { - unsigned int ibdfe_fdbk_iter:4, - ibdfe_eqout_iter:4, - eq_dist_thr_tps:4, - eq_soft_slicer_en:1, - reserved40:3, - gd_len:5, ibdfe_blank_y:1, reserved41:1, ibdfe_dmsg_start_cnt:9; -}; -struct DTMB_CHE_IBDFE_CONFIG5_BITS { - unsigned int ibdfe_init_snr:12, - reserved42:4, eq_init_snr:12, reserved43:4; -}; -struct DTMB_CHE_IBDFE_CONFIG6_BITS { - unsigned int ibdfe_const_thr3:4, - ibdfe_const_thr2:4, - ibdfe_const_thr1:4, - ibdfe_const_thr0:4, - ibdfe_threshold3:4, - ibdfe_threshold2:4, ibdfe_threshold1:4, ibdfe_threshold0:4; -}; -struct DTMB_CHE_IBDFE_CONFIG7_BITS { - unsigned int ibdfe_pick_thr3:8, - ibdfe_pick_thr2:8, ibdfe_pick_thr1:8, ibdfe_pick_thr0:8; -}; -struct DTMB_CHE_DCM_SC_MC_GD_LEN_BITS { - unsigned int dcm_mc_gd_len:6, - reserved44:2, dcm_sc_gd_len:6, reserved45:2, eq_dsnr_slc2drm:16; -}; -struct DTMB_CHE_EQMC_PICK_THR_BITS { - unsigned int eqmc_pick_thr3:8, - eqmc_pick_thr2:8, eqmc_pick_thr1:8, eqmc_pick_thr0:8; -}; -struct DTMB_CHE_EQMC_THRESHOLD_BITS { - unsigned int eqmc_const_thr3:4, - eqmc_const_thr2:4, - eqmc_const_thr1:4, - eqmc_const_thr0:4, - eqmc_threshold3:4, - eqmc_threshold2:4, eqmc_threshold1:4, eqmc_threshold0:4; -}; -struct DTMB_CHE_EQSC_PICK_THR_BITS { - unsigned int eqsc_pick_thr3:8, - eqsc_pick_thr2:8, eqsc_pick_thr1:8, eqsc_pick_thr0:8; -}; -struct DTMB_CHE_EQSC_THRESHOLD_BITS { - unsigned int eqsc_const_thr3:4, - eqsc_const_thr2:4, - eqsc_const_thr1:4, - eqsc_const_thr0:4, - eqsc_threshold3:4, - eqsc_threshold2:4, eqsc_threshold1:4, eqsc_threshold0:4; -}; -struct DTMB_CHE_PROTECT_GD_TPS_BITS { - unsigned int pow_norm:10, - ncoh_thd_tps:3, - coh_thd_tps:3, thr_max:10, protect_gd_tps:5, reserved46:1; -}; -struct DTMB_CHE_FD_TD_STEPSIZE_THR1_BITS { - unsigned int fd_stepsize_thr13:5, - fd_stepsize_thr12:5, - fd_stepsize_thr11:5, - td_stepsize_thr13:5, - td_stepsize_thr12:5, td_stepsize_thr11:5, reserved47:2; -}; -struct DTMB_CHE_TDFD_SWITCH_SYM1_BITS { - unsigned int tdfd_switch_sym00:16, tdfd_switch_sym01:16; -}; -struct DTMB_CHE_TDFD_SWITCH_SYM2_BITS { - unsigned int tdfd_switch_sym10:16, tdfd_switch_sym11:16; -}; -struct DTMB_CHE_EQ_CONFIG_BITS { - unsigned int eq_dsnr_h2drm:6, - eq_cmp_en:1, - eq_imp_setzero_en:1, - dcm_sc_bypass:1, - dcm_mc_bypass:1, - dcm_sc_h_limit:4, - dcm_mc_h_limit:4, - eqsnr_imp_alp:3, eqsnr_avg_alp:3, dcm_alpha:2, reserved48:6; -}; -struct DTMB_CHE_EQSC_SNR_IMP_THR1_BITS { - unsigned int eqsc_snr_imp_thr1:12, eqsc_snr_imp_thr0:12, reserved49:8; -}; -struct DTMB_CHE_EQSC_SNR_IMP_THR2_BITS { - unsigned int eqsc_snr_imp_thr3:12, eqsc_snr_imp_thr2:12, reserved50:8; -}; -struct DTMB_CHE_EQMC_SNR_IMP_THR1_BITS { - unsigned int eqmc_snr_imp_thr1:12, eqmc_snr_imp_thr0:12, reserved51:8; -}; -struct DTMB_CHE_EQMC_SNR_IMP_THR2_BITS { - unsigned int eqmc_snr_imp_thr3:12, eqmc_snr_imp_thr2:12, reserved52:8; -}; -struct DTMB_CHE_EQSC_SNR_DROP_THR_BITS { - unsigned int eqsc_snr_drop_thr3:8, - eqsc_snr_drop_thr2:8, eqsc_snr_drop_thr1:8, eqsc_snr_drop_thr0:8; -}; -struct DTMB_CHE_EQMC_SNR_DROP_THR_BITS { - unsigned int eqmc_snr_drop_thr3:8, - eqmc_snr_drop_thr2:8, eqmc_snr_drop_thr1:8, eqmc_snr_drop_thr0:8; -}; -struct DTMB_CHE_M_CCI_THR_BITS { - unsigned int ccidet_mask_rng_tps:5, - m_cci_thr_tps:10, m_cci_thr_ma_tps:10, reserved53:7; -}; -struct DTMB_CHE_TPS_MC_BITS { - unsigned int tps_mc_run_tim_limit:10, - tps_mc_suc_limit:7, tps_mc_q_thr:7, tps_mc_alpha:3, reserved54:5; -}; -struct DTMB_CHE_TPS_SC_BITS { - unsigned int tps_sc_run_tim_limit:10, - tps_sc_suc_limit:7, tps_sc_q_thr:7, tps_sc_alpha:3, reserved55:5; -}; -struct DTMB_CHE_CHE_SET_FSM_BITS { - unsigned int che_open_loop_len:12, - reserved56:4, - che_set_fsm_st:3, reserved57:1, che_set_fsm_en:1, reserved58:11; -}; -struct DTMB_CHE_ZERO_NUM_THR_BITS { - unsigned int null_frame_thr:16, zero_num_thr:12, reserved59:4; -}; -struct DTMB_CHE_TIMING_READY_BITS { - unsigned int timing_offset:11, - reserved60:5, timing_ready:1, reserved61:15; -}; - -#endif diff --git a/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_front.h b/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_front.h deleted file mode 100644 index bf2f524..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_front.h +++ b/dev/null @@ -1,70 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#ifndef __ADDR_DTMB_FRONT_H__ -#define __ADDR_DTMB_FRONT_H__ - -#include "addr_dtmb_top.h" - -#define DTMB_FRONT_ADDR(x) (DTMB_DEMOD_BASE + (x << 2)) - -#define DTMB_FRONT_AFIFO_ADC DTMB_FRONT_ADDR(0x20) -#define DTMB_FRONT_AGC_CONFIG1 DTMB_FRONT_ADDR(0x21) -#define DTMB_FRONT_AGC_CONFIG2 DTMB_FRONT_ADDR(0x22) -#define DTMB_FRONT_AGC_CONFIG3 DTMB_FRONT_ADDR(0x23) -#define DTMB_FRONT_AGC_CONFIG4 DTMB_FRONT_ADDR(0x24) -#define DTMB_FRONT_DDC_BYPASS DTMB_FRONT_ADDR(0x25) -#define DTMB_FRONT_DC_HOLD DTMB_FRONT_ADDR(0x28) -#define DTMB_FRONT_DAGC_TARGET_POWER DTMB_FRONT_ADDR(0x29) -#define DTMB_FRONT_ACF_BYPASS DTMB_FRONT_ADDR(0x2a) -#define DTMB_FRONT_COEF_SET1 DTMB_FRONT_ADDR(0x2b) -#define DTMB_FRONT_COEF_SET2 DTMB_FRONT_ADDR(0x2c) -#define DTMB_FRONT_COEF_SET3 DTMB_FRONT_ADDR(0x2d) -#define DTMB_FRONT_COEF_SET4 DTMB_FRONT_ADDR(0x2e) -#define DTMB_FRONT_COEF_SET5 DTMB_FRONT_ADDR(0x2f) -#define DTMB_FRONT_COEF_SET6 DTMB_FRONT_ADDR(0x30) -#define DTMB_FRONT_COEF_SET7 DTMB_FRONT_ADDR(0x31) -#define DTMB_FRONT_COEF_SET8 DTMB_FRONT_ADDR(0x32) -#define DTMB_FRONT_COEF_SET9 DTMB_FRONT_ADDR(0x33) -#define DTMB_FRONT_COEF_SET10 DTMB_FRONT_ADDR(0x34) -#define DTMB_FRONT_COEF_SET11 DTMB_FRONT_ADDR(0x35) -#define DTMB_FRONT_COEF_SET12 DTMB_FRONT_ADDR(0x36) -#define DTMB_FRONT_COEF_SET13 DTMB_FRONT_ADDR(0x37) -#define DTMB_FRONT_COEF_SET14 DTMB_FRONT_ADDR(0x38) -#define DTMB_FRONT_COEF_SET15 DTMB_FRONT_ADDR(0x39) -#define DTMB_FRONT_COEF_SET16 DTMB_FRONT_ADDR(0x3a) -#define DTMB_FRONT_COEF_SET17 DTMB_FRONT_ADDR(0x3b) -#define DTMB_FRONT_COEF_SET18 DTMB_FRONT_ADDR(0x3c) -#define DTMB_FRONT_COEF_SET19 DTMB_FRONT_ADDR(0x3d) -#define DTMB_FRONT_SRC_CONFIG1 DTMB_FRONT_ADDR(0x3e) -#define DTMB_FRONT_SRC_CONFIG2 DTMB_FRONT_ADDR(0x3f) -#define DTMB_FRONT_SFIFO_OUT_LEN DTMB_FRONT_ADDR(0x40) -#define DTMB_FRONT_DAGC_GAIN DTMB_FRONT_ADDR(0x41) -#define DTMB_FRONT_IQIB_STEP DTMB_FRONT_ADDR(0x42) -#define DTMB_FRONT_IQIB_CONFIG DTMB_FRONT_ADDR(0x43) -#define DTMB_FRONT_ST_CONFIG DTMB_FRONT_ADDR(0x44) -#define DTMB_FRONT_ST_FREQ DTMB_FRONT_ADDR(0x45) -#define DTMB_FRONT_46_CONFIG DTMB_FRONT_ADDR(0x46) -#define DTMB_FRONT_47_CONFIG DTMB_FRONT_ADDR(0x47) -#define DTMB_FRONT_DEBUG_CFG DTMB_FRONT_ADDR(0x48) -#define DTMB_FRONT_MEM_ADDR DTMB_FRONT_ADDR(0x49) -#define DTMB_FRONT_19_CONFIG DTMB_FRONT_ADDR(0x19) -#define DTMB_FRONT_4d_CONFIG DTMB_FRONT_ADDR(0x4d) - -#endif diff --git a/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_front_bit.h b/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_front_bit.h deleted file mode 100644 index ec74d23..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_front_bit.h +++ b/dev/null @@ -1,331 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#ifndef __ADDR_DTMB_FRONT_BIT_H__ -#define __ADDR_DTMB_FRONT_BIT_H__ - -union DTMB_FRONT_AFIFO_ADC_BITS { - unsigned int d32; - struct { - unsigned int afifo_nco_rate:8, - afifo_data_format:1, - afifo_bypass:1, - adc_sample:6, - adc_IQ:1, - reserved0:15; - } b; -}; -struct DTMB_FRONT_AGC_CONFIG1_BITS { - unsigned int agc_target:4, - agc_cal_intv:2, - reserved1:2, - agc_gain_step2:6, - reserved2:2, - agc_gain_step1:6, - reserved3:2, - agc_a_filter_coef2:3, - reserved4:1, - agc_a_filter_coef1:3, - reserved5:1; -}; -struct DTMB_FRONT_AGC_CONFIG2_BITS { - unsigned int agc_imp_thresh:4, - agc_imp_en:1, - agc_iq_exchange:1, - reserved6:2, - agc_clip_ratio:5, - reserved7:3, - agc_signal_clip_thr:6, - reserved8:2, - agc_sd_rate:7, - reserved9:1; -}; -struct DTMB_FRONT_AGC_CONFIG3_BITS { - unsigned int agc_rffb_value:11, - reserved10:1, - agc_iffb_value:11, - reserved11:1, - agc_gain_step_rf:1, - agc_rfgain_freeze:1, - agc_tuning_slope:1, - agc_rffb_set:1, - agc_gain_step_if:1, - agc_ifgain_freeze:1, - agc_if_only:1, - agc_iffb_set:1; -}; -struct DTMB_FRONT_AGC_CONFIG4_BITS { - unsigned int agc_rffb_gain_sat_i:8, - agc_rffb_gain_sat:8, - agc_iffb_gain_sat_i:8, - agc_iffb_gain_sat:8; -}; -struct DTMB_FRONT_DDC_BYPASS_BITS { - unsigned int ddc_phase:25, - reserved12:3, - ddc_bypass:1, - reserved13:3; -}; -struct DTMB_FRONT_DC_HOLD_BITS { - unsigned int dc_hold:1, - dc_alpha:3, - mobi_det_accu_len:3, - reserved14:1, - mobi_det_observe_len:3, - reserved15:1, - channel_static_th:4, - channel_portable_th:4, - dc_bypass:1, - reserved16:3, - dc_len:3, - reserved17:5; -}; -struct DTMB_FRONT_DAGC_TARGET_POWER_BITS { - unsigned int dagc_target_power_l:8, - dagc_target_power_h:8, - dagc_target_power_ler:8, - dagc_target_power_her:8; -}; -struct DTMB_FRONT_ACF_BYPASS_BITS { - unsigned int coef65:11, - reserved18:1, - coef66:11, - reserved19:1, - acf_bypass:1, - reserved20:7; -}; -struct DTMB_FRONT_COEF_SET1_BITS { - unsigned int coef63:11, - reserved21:1, - coef64:11, - reserved22:9; -}; -struct DTMB_FRONT_COEF_SET2_BITS { - unsigned int coef62:10, - reserved23:22; -}; -struct DTMB_FRONT_COEF_SET3_BITS { - unsigned int coef60:10, - reserved24:2, - coef61:10, - reserved25:10; -}; -struct DTMB_FRONT_COEF_SET4_BITS { - unsigned int coef59:9, - reserved26:23; -}; -struct DTMB_FRONT_COEF_SET5_BITS { - unsigned int coef57:9, - reserved27:3, - coef58:9, - reserved28:11; -}; -struct DTMB_FRONT_COEF_SET6_BITS { - unsigned int coef54:8, - coef55:8, - coef56:8, - reserved29:8; -}; -struct DTMB_FRONT_COEF_SET7_BITS { - unsigned int coef53:7, - reserved30:25; -}; -struct DTMB_FRONT_COEF_SET8_BITS { - unsigned int coef49:7, - reserved31:1, - coef50:7, - reserved32:1, - coef51:7, - reserved33:1, - coef52:7, - reserved34:1; -}; -struct DTMB_FRONT_COEF_SET9_BITS { - unsigned int coef45:7, - reserved35:1, - coef46:7, - reserved36:1, - coef47:7, - reserved37:1, - coef48:7, - reserved38:1; -}; -struct DTMB_FRONT_COEF_SET10_BITS { - unsigned int coef42:6, - reserved39:2, - coef43:6, - reserved40:2, - coef44:6, - reserved41:10; -}; -struct DTMB_FRONT_COEF_SET11_BITS { - unsigned int coef38:6, - reserved42:2, - coef39:6, - reserved43:2, - coef40:6, - reserved44:2, - coef41:6, - reserved45:2; -}; -struct DTMB_FRONT_COEF_SET12_BITS { - unsigned int coef34:6, - reserved46:2, - coef35:6, - reserved47:2, - coef36:6, - reserved48:2, - coef37:6, - reserved49:2; -}; -struct DTMB_FRONT_COEF_SET13_BITS { - unsigned int coef30:6, - reserved50:2, - coef31:6, - reserved51:2, - coef32:6, - reserved52:2, - coef33:6, - reserved53:2; -}; -struct DTMB_FRONT_COEF_SET14_BITS { - unsigned int coef27:5, - reserved54:3, - coef28:5, - reserved55:3, - coef29:5, - reserved56:11; -}; -struct DTMB_FRONT_COEF_SET15_BITS { - unsigned int coef23:5, - reserved57:3, - coef24:5, - reserved58:3, - coef25:5, - reserved59:3, - coef26:5, - reserved60:3; -}; -struct DTMB_FRONT_COEF_SET16_BITS { - unsigned int coef19:5, - reserved61:3, - coef20:5, - reserved62:3, - coef21:5, - reserved63:3, - coef22:5, - reserved64:3; -}; -struct DTMB_FRONT_COEF_SET17_BITS { - unsigned int coef15:5, - reserved65:3, - coef16:5, - reserved66:3, - coef17:5, - reserved67:3, - coef18:5, - reserved68:3; -}; -struct DTMB_FRONT_COEF_SET18_BITS { - unsigned int coef08:4, - coef09:4, - coef10:4, - coef11:4, - coef12:4, - coef13:4, - coef14:4, - reserved69:4; -}; -struct DTMB_FRONT_COEF_SET19_BITS { - unsigned int coef00:4, - coef01:4, - coef02:4, - coef03:4, - coef04:4, - coef05:4, - coef06:4, - coef07:4; -}; -struct DTMB_FRONT_SRC_CONFIG1_BITS { - unsigned int src_norm_inrate:24, - src_tim_shr:4, - src_ted_disable:1, - reserved70:3; -}; -struct DTMB_FRONT_SRC_CONFIG2_BITS { - unsigned int src_stable_timeout:4, - src_seg_len:3, - reserved71:1, - src_ted_beta:3, - reserved72:1, - src_time_err_thr:4, - src_time_mu1:5, - reserved73:3, - src_time_mu2:5, - reserved74:3; -}; -struct DTMB_FRONT_SFIFO_OUT_LEN_BITS { - unsigned int sfifo_out_len:4, - reserved75:28; -}; -struct DTMB_FRONT_DAGC_GAIN_BITS { - unsigned int dagc_bypass:1, - dagc_power_alpha:2, - dagc_bw:3, - dagc_gain_ctrl:12, - dagc_gain_step_er:6, - dagc_gain_step:6, - reserved76:2; -}; -struct DTMB_FRONT_IQIB_STEP_BITS { - unsigned int iqib_step_b:2, - iqib_step_a:2, - iqib_period:3, - reserved77:1, - iqib_bypass:1, - reserved78:23; -}; -struct DTMB_FRONT_IQIB_CONFIG_BITS { - unsigned int iqib_set_b:12, - iqib_set_a:10, - reserved79:2, - iqib_set_val:1, - iqib_hold:1, - reserved80:6; -}; -struct DTMB_FRONT_ST_CONFIG_BITS { - unsigned int st_enable:1, - reserved81:3, - st_dc_len:3, - reserved82:1, - st_alpha:3, - reserved83:1, - st_Q_thrsh:8, - st_dist:3, - reserved84:1, - st_len:5, - reserved85:3; -}; -struct DTMB_FRONT_ST_FREQ_BITS { - unsigned int st_freq_v:1, - st_freq_i:19, - reserved86:12; -}; - -#endif diff --git a/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_sync.h b/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_sync.h deleted file mode 100644 index 0607b19..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_sync.h +++ b/dev/null @@ -1,53 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#ifndef __ADDR_DTMB_SYNC_H__ -#define __ADDR_DTMB_SYNC_H__ - -#include "addr_dtmb_top.h" -#define DTMB_SYNC_ADDR(x) (DTMB_DEMOD_BASE + (x << 2)) - -#define DTMB_SYNC_TS_CFO_PN_VALUE DTMB_SYNC_ADDR(0x57) -#define DTMB_SYNC_TS_CFO_ERR_LIMIT DTMB_SYNC_ADDR(0x58) -#define DTMB_SYNC_TS_CFO_PN_MODIFY DTMB_SYNC_ADDR(0x59) -#define DTMB_SYNC_TS_GAIN DTMB_SYNC_ADDR(0x5a) -#define DTMB_SYNC_FE_CONFIG DTMB_SYNC_ADDR(0x5b) -#define DTMB_SYNC_PNPHASE_OFFSET DTMB_SYNC_ADDR(0x5c) -#define DTMB_SYNC_PNPHASE_CONFIG DTMB_SYNC_ADDR(0x5d) -#define DTMB_SYNC_SFO_SFO_PN0_MODIFY DTMB_SYNC_ADDR(0x5e) -#define DTMB_SYNC_SFO_SFO_PN1_MODIFY DTMB_SYNC_ADDR(0x5f) -#define DTMB_SYNC_SFO_SFO_PN2_MODIFY DTMB_SYNC_ADDR(0x60) -#define DTMB_SYNC_SFO_CONFIG DTMB_SYNC_ADDR(0x61) -#define DTMB_SYNC_FEC_CFG DTMB_SYNC_ADDR(0x67) -#define DTMB_SYNC_FEC_DEBUG_CFG DTMB_SYNC_ADDR(0x68) -#define DTMB_SYNC_DATA_DDR_ADR DTMB_SYNC_ADDR(0x69) -#define DTMB_SYNC_DEBUG_DDR_ADR DTMB_SYNC_ADDR(0x6a) -#define DTMB_SYNC_FEC_SIM_CFG1 DTMB_SYNC_ADDR(0x6b) -#define DTMB_SYNC_FEC_SIM_CFG2 DTMB_SYNC_ADDR(0x6c) -#define DTMB_SYNC_TRACK_CFO_MAX DTMB_SYNC_ADDR(0x6d) -#define DTMB_SYNC_CCI_DAGC_CONFIG1 DTMB_SYNC_ADDR(0x6e) -#define DTMB_SYNC_CCI_DAGC_CONFIG2 DTMB_SYNC_ADDR(0x6f) -#define DTMB_SYNC_CCI_RP DTMB_SYNC_ADDR(0x70) -#define DTMB_SYNC_CCI_DET_THRES DTMB_SYNC_ADDR(0x71) -#define DTMB_SYNC_CCI_NOTCH1_CONFIG1 DTMB_SYNC_ADDR(0x72) -#define DTMB_SYNC_CCI_NOTCH1_CONFIG2 DTMB_SYNC_ADDR(0x73) -#define DTMB_SYNC_CCI_NOTCH2_CONFIG1 DTMB_SYNC_ADDR(0x74) -#define DTMB_SYNC_CCI_NOTCH2_CONFIG2 DTMB_SYNC_ADDR(0x75) - -#endif diff --git a/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_sync_bit.h b/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_sync_bit.h deleted file mode 100644 index 0aebdd1..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_sync_bit.h +++ b/dev/null @@ -1,110 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#ifndef __ADDR_DTMB_SYNC_BIT_H__ -#define __ADDR_DTMB_SYNC_BIT_H__ - -struct DTMB_SYNC_TS_CFO_PN_VALUE_BITS { - unsigned int ts_cfo_pn1_value:16, ts_cfo_pn0_value:16; -}; -struct DTMB_SYNC_TS_CFO_ERR_LIMIT_BITS { - unsigned int ts_cfo_err_limit:16, ts_cfo_pn2_value:16; -}; -struct DTMB_SYNC_TS_CFO_PN_MODIFY_BITS { - unsigned int ts_cfo_pn1_modify:16, ts_cfo_pn0_modify:16; -}; -struct DTMB_SYNC_TS_GAIN_BITS { - unsigned int ts_gain:2, - reserved0:2, - ts_sat_shift:3, - reserved1:1, - ts_fixpn_en:1, - ts_fixpn:2, reserved2:1, ts_cfo_cut:4, ts_cfo_pn2_modify:16; -}; -struct DTMB_SYNC_FE_CONFIG_BITS { - unsigned int fe_lock_len:4, - fe_sat_shift:3, reserved3:1, fe_cut:4, reserved4:4, fe_modify:16; -}; -struct DTMB_SYNC_PNPHASE_OFFSET_BITS { - unsigned int pnphase_offset2:4, - pnphase_offset1:4, pnphase_offset0:4, reserved5:20; -}; -struct DTMB_SYNC_PNPHASE_CONFIG_BITS { - unsigned int pnphase_gain:2, - reserved6:2, - pnphase_sat_shift:4, pnphase_cut:4, reserved7:4, pnphase_modify:16; -}; -struct DTMB_SYNC_SFO_SFO_PN0_MODIFY_BITS { - unsigned int sfo_cfo_pn0_modify:16, sfo_sfo_pn0_modify:16; -}; -struct DTMB_SYNC_SFO_SFO_PN1_MODIFY_BITS { - unsigned int sfo_cfo_pn1_modify:16, sfo_sfo_pn1_modify:16; -}; -struct DTMB_SYNC_SFO_SFO_PN2_MODIFY_BITS { - unsigned int sfo_cfo_pn2_modify:16, sfo_sfo_pn2_modify:16; -}; -struct DTMB_SYNC_SFO_CONFIG_BITS { - unsigned int sfo_sat_shift:4, - sfo_gain:2, - reserved8:2, - sfo_dist:2, - reserved9:2, - sfo_cfo_cut:4, sfo_sfo_cut:4, sfo_cci_th:4, reserved10:8; -}; -struct DTMB_SYNC_TRACK_CFO_MAX_BITS { - unsigned int track_cfo_max:8, - track_sfo_max:8, track_max_en:1, ctrl_fe_to_th:4, reserved11:11; -}; -struct DTMB_SYNC_CCI_DAGC_CONFIG1_BITS { - unsigned int cci_dagc_bypass:1, - cci_dagc_power_alpha:2, - cci_dagc_bw:3, - cci_dagc_gain_ctrl:12, - cci_dagc_gain_step_er:6, cci_dagc_gain_step:6, reserved12:2; -}; -struct DTMB_SYNC_CCI_DAGC_CONFIG2_BITS { - unsigned int cci_dagc_target_power_l:8, - cci_dagc_target_power_h:8, - cci_dagc_target_power_ler:8, cci_dagc_target_power_her:8; -}; -struct DTMB_SYNC_CCI_RP_BITS { - unsigned int cci_rpsq_n:10, reserved13:2, cci_rp_n:13, reserved14:7; -}; -struct DTMB_SYNC_CCI_DET_THRES_BITS { - unsigned int cci_avr_times:5, - reserved15:3, cci_det_thres:3, reserved16:21; -}; -struct DTMB_SYNC_CCI_NOTCH1_CONFIG1_BITS { - unsigned int cci_notch1_a1:10, - reserved17:2, cci_notch1_en:1, reserved18:19; -}; -struct DTMB_SYNC_CCI_NOTCH1_CONFIG2_BITS { - unsigned int cci_notch1_b1:10, - reserved19:2, cci_notch1_a2:10, reserved20:10; -}; -struct DTMB_SYNC_CCI_NOTCH2_CONFIG1_BITS { - unsigned int cci_notch2_a1:10, - reserved21:2, cci_notch2_en:1, reserved22:3, cci_mpthres:16; -}; -struct DTMB_SYNC_CCI_NOTCH2_CONFIG2_BITS { - unsigned int cci_notch2_b1:10, - reserved23:2, cci_notch2_a2:10, reserved24:10; -}; - -#endif diff --git a/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_top.h b/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_top.h deleted file mode 100644 index c12d26f..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_top.h +++ b/dev/null @@ -1,90 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#ifndef __ADDR_DTMB_TOP_H__ -#define __ADDR_DTMB_TOP_H__ - -#include "addr_dtmb_top_bit.h" -#include "addr_dtmb_sync.h" -#include "addr_dtmb_sync_bit.h" -#include "addr_dtmb_che.h" -#include "addr_dtmb_che_bit.h" -#include "addr_dtmb_front.h" -#include "addr_dtmb_front_bit.h" - -#define DTMB_DEMOD_BASE DEMOD_REG_ADDR(0x0) -#define DTMB_TOP_ADDR(x) (DTMB_DEMOD_BASE + (x << 2)) - -#define DTMB_TOP_CTRL_SW_RST DTMB_TOP_ADDR(0x1) -#define DTMB_TOP_TESTBUS DTMB_TOP_ADDR(0x2) -#define DTMB_TOP_TB DTMB_TOP_ADDR(0x3) -#define DTMB_TOP_TB_V DTMB_TOP_ADDR(0x4) -#define DTMB_TOP_TB_ADDR_BEGIN DTMB_TOP_ADDR(0x5) -#define DTMB_TOP_TB_ADDR_END DTMB_TOP_ADDR(0x6) -#define DTMB_TOP_CTRL_ENABLE DTMB_TOP_ADDR(0x7) -#define DTMB_TOP_CTRL_LOOP DTMB_TOP_ADDR(0x8) -#define DTMB_TOP_CTRL_FSM DTMB_TOP_ADDR(0x9) -#define DTMB_TOP_CTRL_AGC DTMB_TOP_ADDR(0xa) -#define DTMB_TOP_CTRL_TS_SFO_CFO DTMB_TOP_ADDR(0xb) -#define DTMB_TOP_CTRL_FEC DTMB_TOP_ADDR(0xc) -#define DTMB_TOP_CTRL_INTLV_TIME DTMB_TOP_ADDR(0xd) -#define DTMB_TOP_CTRL_DAGC_CCI DTMB_TOP_ADDR(0xe) -#define DTMB_TOP_CTRL_TPS DTMB_TOP_ADDR(0xf) -#define DTMB_TOP_TPS_BIT DTMB_TOP_ADDR(0x10) -#define DTMB_TOP_CCI_FLG DTMB_TOP_ADDR(0xc7) -#define DTMB_TOP_TESTBUS_OUT DTMB_TOP_ADDR(0xc8) -#define DTMB_TOP_TBUS_DC_ADDR DTMB_TOP_ADDR(0xc9) -#define DTMB_TOP_FRONT_IQIB_CHECK DTMB_TOP_ADDR(0xca) -#define DTMB_TOP_SYNC_TS DTMB_TOP_ADDR(0xcb) -#define DTMB_TOP_SYNC_PNPHASE DTMB_TOP_ADDR(0xcd) -#define DTMB_TOP_CTRL_DDC_ICFO DTMB_TOP_ADDR(0xd2) -#define DTMB_TOP_CTRL_DDC_FCFO DTMB_TOP_ADDR(0xd3) -#define DTMB_TOP_CTRL_FSM_STATE0 DTMB_TOP_ADDR(0xd4) -#define DTMB_TOP_CTRL_FSM_STATE1 DTMB_TOP_ADDR(0xd5) -#define DTMB_TOP_CTRL_FSM_STATE2 DTMB_TOP_ADDR(0xd6) -#define DTMB_TOP_CTRL_FSM_STATE3 DTMB_TOP_ADDR(0xd7) -#define DTMB_TOP_CTRL_TS2 DTMB_TOP_ADDR(0xd8) -#define DTMB_TOP_FRONT_AGC DTMB_TOP_ADDR(0xd9) -#define DTMB_TOP_FRONT_DAGC DTMB_TOP_ADDR(0xda) -#define DTMB_TOP_FEC_TIME_STS DTMB_TOP_ADDR(0xdb) -#define DTMB_TOP_FEC_LDPC_STS DTMB_TOP_ADDR(0xdc) -#define DTMB_TOP_FEC_LDPC_IT_AVG DTMB_TOP_ADDR(0xdd) -#define DTMB_TOP_FEC_LDPC_UNC_ACC DTMB_TOP_ADDR(0xde) -#define DTMB_TOP_FEC_BCH_ACC DTMB_TOP_ADDR(0xdf) -#define DTMB_TOP_CTRL_ICFO_ALL DTMB_TOP_ADDR(0xe0) -#define DTMB_TOP_CTRL_FCFO_ALL DTMB_TOP_ADDR(0xe1) -#define DTMB_TOP_CTRL_SFO_ALL DTMB_TOP_ADDR(0xe2) -#define DTMB_TOP_FEC_LOCK_SNR DTMB_TOP_ADDR(0xe3) -#define DTMB_TOP_CHE_SEG_FACTOR DTMB_TOP_ADDR(0xe4) -#define DTMB_TOP_CTRL_CHE_WORKCNT DTMB_TOP_ADDR(0xe5) -#define DTMB_TOP_CHE_OBS_STATE1 DTMB_TOP_ADDR(0xe6) -#define DTMB_TOP_CHE_OBS_STATE2 DTMB_TOP_ADDR(0xe7) -#define DTMB_TOP_CHE_OBS_STATE3 DTMB_TOP_ADDR(0xe8) -#define DTMB_TOP_CHE_OBS_STATE4 DTMB_TOP_ADDR(0xe9) -#define DTMB_TOP_CHE_OBS_STATE5 DTMB_TOP_ADDR(0xea) -#define DTMB_TOP_SYNC_CCI_NF1 DTMB_TOP_ADDR(0xee) -#define DTMB_TOP_SYNC_CCI_NF2 DTMB_TOP_ADDR(0xef) -#define DTMB_TOP_SYNC_CCI_NF2_POSITION DTMB_TOP_ADDR(0xf0) -#define DTMB_TOP_CTRL_SYS_OFDM_CNT DTMB_TOP_ADDR(0xf1) -#define DTMB_TOP_CTRL_TPS_Q_FINAL DTMB_TOP_ADDR(0xf2) -#define DTMB_TOP_FRONT_DC DTMB_TOP_ADDR(0xf3) -#define DTMB_TOP_CHE_DEBUG DTMB_TOP_ADDR(0xf6) -#define DTMB_TOP_CTRL_TOTPS_READY_CNT DTMB_TOP_ADDR(0xff) - -#endif diff --git a/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_top_bit.h b/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_top_bit.h deleted file mode 100644 index 63233c4..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_top_bit.h +++ b/dev/null @@ -1,178 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#ifndef __ADDR_DTMB_TOP_BIT_H__ -#define __ADDR_DTMB_TOP_BIT_H__ - -union DTMB_TOP_CTRL_SW_RST_BITS { - unsigned int d32; - struct { - unsigned int ctrl_sw_rst:1, ctrl_sw_rst_noreg:1, reserved0:30; - } b; -}; -struct DTMB_TOP_TESTBUS_BITS { - unsigned int testbus_addr:16, testbus_en:1, reserved1:15; -}; -struct DTMB_TOP_TB_BITS { - unsigned int tb_act_width:5, - reserved2:3, - tb_dc_mk:3, - reserved3:1, tb_capture_stop:1, tb_self_test:1, reserved4:18; -}; -struct DTMB_TOP_CTRL_ENABLE_BITS { - unsigned int ctrl_enable:24, reserved5:8; -}; -struct DTMB_TOP_CTRL_LOOP_BITS { - unsigned int ctrl_src_pnphase_loop:1, - ctrl_src_sfo_loop:1, - ctrl_ddc_fcfo_loop:1, ctrl_ddc_icfo_loop:1, reserved6:28; -}; -struct DTMB_TOP_CTRL_FSM_BITS { - unsigned int ctrl_fsm_state:5, - reserved7:3, - ctrl_fsm_v:1, reserved8:3, ctrl_reset_state:4, reserved9:16; -}; -struct DTMB_TOP_CTRL_AGC_BITS { - unsigned int ctrl_fast_agc:1, - ctrl_agc_bypass:1, - ts_cfo_bypass:1, sfo_strong0_bypass:1, reserved10:28; -}; -struct DTMB_TOP_CTRL_TS_SFO_CFO_BITS { - unsigned int ctrl_ts_q:10, - reserved11:2, - ctrl_pnphase_q:7, reserved12:1, ctrl_sfo_q:4, ctrl_cfo_q:8; -}; -struct DTMB_TOP_CTRL_FEC_BITS { - unsigned int reserved13:8, - ctrl_ts_to_th:4, - ctrl_pnphase_to_th:4, - ctrl_sfo_to_th:4, - ctrl_fe_to_th:4, ctrl_che_to_th:4, ctrl_fec_to_th:4; -}; -struct DTMB_TOP_CTRL_INTLV_TIME_BITS { - unsigned int ctrl_intlv720_time:12, ctrl_intlv240_time:12, reserved14:8; -}; -struct DTMB_TOP_CTRL_DAGC_CCI_BITS { - unsigned int dagc_mode:2, - cci_dagc_mode:2, - cci_bypass:1, - fe_bypass:1, - reserved15:1, - new_sync1:1, new_sync2:1, fec_inzero_check:1, reserved16:22; -}; -struct DTMB_TOP_CTRL_TPS_BITS { - unsigned int sfo_gain:2, - freq_reverse:1, - qam4_nr:1, - intlv_mode:1, - code_rate:2, - constell:2, - tps_carrier_mode:1, - freq_reverse_known:1, tps_known:1, ctrl_tps_to_th:4, reserved17:16; -}; -struct DTMB_TOP_CCI_FLG_BITS { - unsigned int cci_flg_cnt:8, m_cci_ready:1, reserved18:23; -}; -struct DTMB_TOP_FRONT_IQIB_CHECK_BITS { - unsigned int front_iqib_check_b:12, - front_iqib_check_a:10, reserved19:10; -}; -struct DTMB_TOP_SYNC_TS_BITS { - unsigned int sync_ts_idx:2, sync_ts_pos:13, sync_ts_q:10, reserved20:7; -}; -struct DTMB_TOP_SYNC_PNPHASE_BITS { - unsigned int sync_pnphase_max_q_idx:2, - sync_pnphase:8, sync_pnphase_max_q:7, reserved21:15; -}; -struct DTMB_TOP_CTRL_DDC_ICFO_BITS { - unsigned int ctrl_ddc_icfo:20, reserved22:12; -}; -struct DTMB_TOP_CTRL_DDC_FCFO_BITS { - unsigned int ctrl_src_sfo:17, ctrl_ddc_fcfo:14, reserved23:1; -}; -struct DTMB_TOP_CTRL_TS2_BITS { - unsigned int ctrl_ts2_workcnt:8, - ctrl_pnphase_workcnt:8, ctrl_sfo_workcnt:8, sync_fe_workcnt:8; -}; -struct DTMB_TOP_FRONT_AGC_BITS { - unsigned int front_agc_if_gain:11, - front_agc_rf_gain:11, front_agc_power:10; -}; -struct DTMB_TOP_FRONT_DAGC_BITS { - unsigned int front_dagc_power:8, front_dagc_gain:12, reserved24:12; -}; -struct DTMB_TOP_FEC_LDPC_IT_AVG_BITS { - unsigned int fec_ldpc_it_avg:16, fec_ldpc_per_rpt:13, reserved25:3; -}; -struct DTMB_TOP_CTRL_ICFO_ALL_BITS { - unsigned int ctrl_icfo_all:20, reserved26:12; -}; -struct DTMB_TOP_CTRL_FCFO_ALL_BITS { - unsigned int ctrl_fcfo_all:20, reserved27:12; -}; -struct DTMB_TOP_CTRL_SFO_ALL_BITS { - unsigned int ctrl_sfo_all:25, reserved28:7; -}; -struct DTMB_TOP_FEC_LOCK_SNR_BITS { - unsigned int che_snr:14, - fec_lock:1, reserved29:1, che_snr_average:14, reserved30:2; -}; -struct DTMB_TOP_CHE_SEG_FACTOR_BITS { - unsigned int che_seg_factor:14, reserved31:18; -}; -struct DTMB_TOP_CTRL_CHE_WORKCNT_BITS { - unsigned int ctrl_che_workcnt:8, - ctrl_fec_workcnt:8, - ctrl_constell:2, - ctrl_code_rate:2, - ctrl_intlv_mode:1, - ctrl_qam4_nr:1, ctrl_freq_reverse:1, reserved32:9; -}; -struct DTMB_TOP_SYNC_CCI_NF1_BITS { - unsigned int sync_cci_nf1_b1:10, - sync_cci_nf1_a2:10, sync_cci_nf1_a1:10, reserved33:2; -}; -struct DTMB_TOP_SYNC_CCI_NF2_BITS { - unsigned int sync_cci_nf2_b1:10, - sync_cci_nf2_a2:10, sync_cci_nf2_a1:10, reserved34:2; -}; -struct DTMB_TOP_SYNC_CCI_NF2_POSITION_BITS { - unsigned int sync_cci_nf2_position:11, - sync_cci_nf1_position:11, - sync_cci_nf2_det:1, sync_cci_nf1_det:1, reserved35:8; -}; -struct DTMB_TOP_CTRL_SYS_OFDM_CNT_BITS { - unsigned int ctrl_sys_ofdm_cnt:8, - mobi_det_power_var:19, - reserved36:1, ctrl_che_working_state:2, reserved37:2; -}; -struct DTMB_TOP_CTRL_TPS_Q_FINAL_BITS { - unsigned int ctrl_tps_q_final:7, ctrl_tps_suc_cnt:7, reserved38:18; -}; -struct DTMB_TOP_FRONT_DC_BITS { - unsigned int front_dc_q:10, front_dc_i:10, reserved39:12; -}; -struct DTMB_TOP_CTRL_TOTPS_READY_CNT_BITS { - unsigned int ctrl_dead_lock_det:1, - ctrl_dead_lock:1, - reserved40:2, - ctrl_dead_cnt:4, reserved41:8, ctrl_totps_ready_cnt:16; -}; - -#endif diff --git a/drivers/stream_input/tv_frontend/dtv_demod/include/aml_dtv_demod_reg.h b/drivers/stream_input/tv_frontend/dtv_demod/include/aml_dtv_demod_reg.h deleted file mode 100644 index 4f49fa7..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/include/aml_dtv_demod_reg.h +++ b/dev/null @@ -1,28 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#ifndef _DTV_REG_H_ -#define _DTV_REG_H_ - -#include - -#define DTV_WRITE_CBUS_REG(_r, _v) aml_write_cbus(_r, _v) -#define DTV_READ_CBUS_REG(_r) aml_read_cbus(_r) - -#endif /* */ diff --git a/drivers/stream_input/tv_frontend/dtv_demod/include/amlfrontend.h b/drivers/stream_input/tv_frontend/dtv_demod/include/amlfrontend.h deleted file mode 100644 index 5df7b1c..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/include/amlfrontend.h +++ b/dev/null @@ -1,86 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ - -/***************************************************************** - ** - ** Copyright (C) 2010 Amlogic,Inc. - ** All rights reserved - ** Filename : amlfrontend.h - ** - ** comment: - ** Driver for aml demodulator - ** - **************************************************************** - */ - -#ifndef _AMLFRONTEND_H -#define _AMLFRONTEND_H - -struct amlfe_config { - int fe_mode; - int i2c_id; - int tuner_type; - int tuner_addr; -}; -enum Gxtv_Demod_Tuner_If { - Si2176_5M_If = 5, - Si2176_6M_If = 6 -}; -/* 0 -DVBC, 1-DVBT, ISDBT, 2-ATSC */ -enum Gxtv_Demod_Dvb_Mode { - Gxtv_Dvbc = 0, - Gxtv_Dvbt_Isdbt = 1, - Gxtv_Atsc = 2, - Gxtv_Dtmb = 3, -}; -#define Adc_Clk_35M 35714 /* adc clk dvbc */ -#define Demod_Clk_71M 71428 /* demod clk */ - -#define Adc_Clk_24M 24000 -#define Demod_Clk_72M 72000 -#define Demod_Clk_60M 60000 - -#define Adc_Clk_28M 28571 /* dvbt,isdbt */ -#define Demod_Clk_66M 66666 - -#define Adc_Clk_26M 26000 /* atsc air */ -#define Demod_Clk_78M 78000 /* */ - -#define Adc_Clk_25_2M 25200 /* atsc cable */ -#define Demod_Clk_75M 75600 /* */ - -#define Adc_Clk_25M 25000 /* dtmb */ -#define Demod_Clk_100M 100000 /* */ -#define Demod_Clk_180M 180000 /* */ -#define Demod_Clk_200M 200000 /* */ -#define Demod_Clk_225M 225000 - -#define Adc_Clk_27M 27777 /* atsc */ -#define Demod_Clk_83M 83333 /* */ - -enum M6_Demod_Pll_Mode { - Cry_mode = 0, - Adc_mode = 1 -}; - -int M6_Demod_Dtmb_Init(struct aml_fe_dev *dev); -int convert_snr(int in_snr); - -#endif diff --git a/drivers/stream_input/tv_frontend/dtv_demod/include/demod_func.h b/drivers/stream_input/tv_frontend/dtv_demod/include/demod_func.h deleted file mode 100644 index 4c9d281..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/include/demod_func.h +++ b/dev/null @@ -1,626 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#ifdef DEMOD_FUNC_H -#else -#define DEMOD_FUNC_H - -#include -/* #include */ -/*#include - * #include - #include -*/ -#include -#include "aml_fe.h" -#include "amlfrontend.h" -#include "addr_dtmb_top.h" -#include "c_stb_define.h" -#include "c_stb_regs_define.h" -#include - -/* #define G9_TV */ -#define GX_TV -#define safe_addr - -#define PWR_ON 1 -#define PWR_OFF 0 - -#define dtmb_mobile_mode - - -/* void __iomem *meson_reg_demod_map[1024]; */ - -#define IO_CBUS_PHY_BASE (0xc0800000) - -#ifdef safe_addr -#define IO_DEMOD_BASE (0xc8844000) -#define IO_AOBUS_BASE (0xc8100000) -#define IO_HIU_BASE (0xc883c000) -#else -#define IO_DEMOD_BASE (0xda844000) -#define IO_AOBUS_BASE (0xda100000) -#define IO_HIU_BASE (0xda83c000) -#endif - -#define DEMOD_REG_OFFSET(reg) (reg & 0xfffff) -#define DEMOD_REG_ADDR(reg) (IO_DEMOD_BASE + DEMOD_REG_OFFSET(reg)) - -#define DEMOD_CBUS_REG_OFFSET(reg) (reg << 2) -#define DEMOD_CBUS_REG_ADDR(reg) (IO_CBUS_PHY_BASE + \ - DEMOD_CBUS_REG_OFFSET(reg)) - -#define DEMOD_AOBUS_REG_OFFSET(reg) ((reg)) -#define DEMOD_AOBUS_REG_ADDR(reg) (IO_AOBUS_BASE + \ - DEMOD_AOBUS_REG_OFFSET(reg)) - -/* #define DEMOD_BASE APB_REG_ADDR(0x20000) */ -#define DEMOD_BASE DEMOD_REG_ADDR(0x0) /* 0xc8020000 */ - -/* #define DEMOD_BASE 0xc8020000 */ -#define DTMB_BASE (DEMOD_BASE + 0x000) -#define DVBT_BASE (DEMOD_BASE + 0x000) -#define ISDBT_BASE (DEMOD_BASE + 0x000) -#define QAM_BASE (DEMOD_BASE + 0x400) -#define ATSC_BASE (DEMOD_BASE + 0x800) -#define DEMOD_CFG_BASE (DEMOD_BASE + 0xC00) - -/* #ifdef TXL_TV */ -#define TXLTV_ADC_RESET_VALUE 0xca6a2110 /* 0xce7a2110 */ -#define TXLTV_ADC_REG1_VALUE 0x5d414260 -#define TXLTV_ADC_REG2_VALUE 0x5ba00384 /* 0x34e0bf81 */ -#define TXLTV_ADC_REG2_VALUE_CRY 0x34e0bf81 -#define TXLTV_ADC_REG3_VALUE 0x4a6a2110 /* 0x4e7a2110 */ -#define TXLTV_ADC_REG4_VALUE 0x02913004 -#define TXLTV_ADC_REG4_CRY_VALUE 0x301 -#define TXLTV_ADC_REG7_VALUE 0x00102038 -#define TXLTV_ADC_REG8_VALUE 0x00000406 -#define TXLTV_ADC_REG9_VALUE 0x00082183 -#define TXLTV_ADC_REGA_VALUE 0x80480240 -#define TXLTV_ADC_REGB_VALUE 0x22000442 -#define TXLTV_ADC_REGC_VALUE 0x00034a00 -#define TXLTV_ADC_REGD_VALUE 0x00005000 -#define TXLTV_ADC_REGE_VALUE 0x00000200 - - -/* DADC DPLL */ -#define ADC_REG1 (IO_HIU_BASE + (0xaa << 2)) -#define ADC_REG2 (IO_HIU_BASE + (0xab << 2)) -#define ADC_REG3 (IO_HIU_BASE + (0xac << 2)) -#define ADC_REG4 (IO_HIU_BASE + (0xad << 2)) - -#define ADC_REG5 (IO_HIU_BASE + (0x73 << 2)) -#define ADC_REG6 (IO_HIU_BASE + (0x74 << 2)) - -#define ADC_REGB (IO_HIU_BASE + (0xaf << 2)) -#define ADC_REGC (IO_HIU_BASE + (0x9e << 2)) -#define ADC_REGD (IO_HIU_BASE + (0x9f << 2)) - -/* DADC REG */ -#define ADC_REG7 (IO_HIU_BASE + (0x27 << 2)) -#define ADC_REG8 (IO_HIU_BASE + (0x28 << 2)) -#define ADC_REG9 (IO_HIU_BASE + (0x2a << 2)) -#define ADC_REGA (IO_HIU_BASE + (0x2b << 2)) -#define ADC_REGE (IO_HIU_BASE + (0xbd << 2)) - -/* #endif */ - - -/* #ifdef GX_TV */ - -#define ADC_RESET_VALUE 0x8a2a2110 /* 0xce7a2110 */ -#define ADC_REG1_VALUE 0x00100228 -#define ADC_REG2_VALUE 0x34e0bf80 /* 0x34e0bf81 */ -#define ADC_REG2_VALUE_CRY 0x34e0bf81 -#define ADC_REG3_VALUE 0x0a2a2110 /* 0x4e7a2110 */ -#define ADC_REG4_VALUE 0x02933800 -#define ADC_REG4_CRY_VALUE 0x301 -#define ADC_REG7_VALUE 0x01411036 -#define ADC_REG8_VALUE 0x00000000 -#define ADC_REG9_VALUE 0x00430036 -#define ADC_REGA_VALUE 0x80480240 -#if 0 -/* DADC DPLL */ -#define ADC_REG1 (IO_HIU_BASE + (0xaa << 2)) -#define ADC_REG2 (IO_HIU_BASE + (0xab << 2)) -#define ADC_REG3 (IO_HIU_BASE + (0xac << 2)) -#define ADC_REG4 (IO_HIU_BASE + (0xad << 2)) - -#define ADC_REG5 (IO_HIU_BASE + (0x73 << 2)) -#define ADC_REG6 (IO_HIU_BASE + (0x74 << 2)) - -/* DADC REG */ -#define ADC_REG7 (IO_HIU_BASE + (0x27 << 2)) -#define ADC_REG8 (IO_HIU_BASE + (0x28 << 2)) -#define ADC_REG9 (IO_HIU_BASE + (0x2a << 2)) -#define ADC_REGA (IO_HIU_BASE + (0x2b << 2)) -#endif -/* #endif */ - -#ifdef G9_TV - -#define ADC_RESET_VALUE 0x8a2a2110 /* 0xce7a2110 */ -#define ADC_REG1_VALUE 0x00100228 -#define ADC_REG2_VALUE 0x34e0bf80 /* 0x34e0bf81 */ -#define ADC_REG2_VALUE_CRY 0x34e0bf81 -#define ADC_REG3_VALUE 0x0a2a2110 /* 0x4e7a2110 */ -#define ADC_REG4_VALUE 0x02933800 -#define ADC_REG4_CRY_VALUE 0x301 -#define ADC_REG7_VALUE 0x01411036 -#define ADC_REG8_VALUE 0x00000000 -#define ADC_REG9_VALUE 0x00430036 -#define ADC_REGA_VALUE 0x80480240 - -/* DADC DPLL */ -#define ADC_REG1 0x10aa -#define ADC_REG2 0x10ab -#define ADC_REG3 0x10ac -#define ADC_REG4 0x10ad - -#define ADC_REG5 0x1073 -#define ADC_REG6 0x1074 - -/* DADC REG */ -#define ADC_REG7 0x1027 -#define ADC_REG8 0x1028 -#define ADC_REG9 0x102a -#define ADC_REGA 0x102b -#endif - -#ifdef M6_TV -#define ADC_REG1_VALUE 0x003b0232 -#define ADC_REG2_VALUE 0x814d3928 -#define ADC_REG3_VALUE 0x6b425012 -#define ADC_REG4_VALUE 0x101 -#define ADC_REG4_CRY_VALUE 0x301 -#define ADC_REG5_VALUE 0x70b -#define ADC_REG6_VALUE 0x713 - -#define ADC_REG1 0x10aa -#define ADC_REG2 0x10ab -#define ADC_REG3 0x10ac -#define ADC_REG4 0x10ad -#define ADC_REG5 0x1073 -#define ADC_REG6 0x1074 -#endif - -#define DEMOD_REG1_VALUE 0x0000d007 -#define DEMOD_REG2_VALUE 0x2e805400 -#define DEMOD_REG3_VALUE 0x201 - -#define DEMOD_REG1 (DEMOD_BASE + 0xc00) -#define DEMOD_REG2 (DEMOD_BASE + 0xc04) -#define DEMOD_REG3 (DEMOD_BASE + 0xc08) -#define DEMOD_REG4 (DEMOD_BASE + 0xc0c) - -/* #define Wr(addr, data) WRITE_CBUS_REG(addr, data)*/ -/* #define Rd(addr) READ_CBUS_REG(addr) */ - -/*#define Wr(addr, data) *(volatile unsigned long *)(addr) = (data)*/ -/*#define Rd(addr) *(volatile unsigned long *)(addr)*/ - -enum { - enable_mobile, - disable_mobile -}; - -enum { - OPEN_TIME_EQ, - CLOSE_TIME_EQ -}; - -enum { - AMLOGIC_DTMB_STEP0, - AMLOGIC_DTMB_STEP1, - AMLOGIC_DTMB_STEP2, - AMLOGIC_DTMB_STEP3, - AMLOGIC_DTMB_STEP4, - AMLOGIC_DTMB_STEP5, /* time eq */ - AMLOGIC_DTMB_STEP6, /* set normal mode sc */ - AMLOGIC_DTMB_STEP7, - AMLOGIC_DTMB_STEP8, /* set time eq mode */ - AMLOGIC_DTMB_STEP9, /* reset */ - AMLOGIC_DTMB_STEP10, /* set normal mode mc */ - AMLOGIC_DTMB_STEP11, -}; - -enum { - DTMB_IDLE = 0, - DTMB_AGC_READY = 1, - DTMB_TS1_READY = 2, - DTMB_TS2_READY = 3, - DTMB_FE_READY = 4, - DTMB_PNPHASE_READY = 5, - DTMB_SFO_INIT_READY = 6, - DTMB_TS3_READY = 7, - DTMB_PM_INIT_READY = 8, - DTMB_CHE_INIT_READY = 9, - DTMB_FEC_READY = 10 -}; - -/* i2c functions */ -/* int aml_i2c_sw_test_bus(struct aml_demod_i2c *adap, char *name); */ -int am_demod_i2c_xfer(struct aml_demod_i2c *adap, struct i2c_msg *msgs, - int num); -int init_tuner_fj2207(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *adap); -int set_tuner_fj2207(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *adap); - -int get_fj2207_ch_power(void); -int tuner_get_ch_power(struct aml_fe_dev *adap); -int tda18273_tuner_set_frequnecy(unsigned int dwFrequency, - unsigned int dwStandard); -int dtmb_get_power_strength(int agc_gain); - - -int tuner_set_ch(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c); - -/* dvbt */ -int dvbt_set_ch(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c, - struct aml_demod_dvbt *demod_dvbt); - -struct demod_status_ops { - int (*get_status)(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c); - int (*get_ber)(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c); - int (*get_snr)(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c); - int (*get_strength)(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c); - int (*get_ucblocks)(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c); -}; - -struct demod_status_ops *dvbt_get_status_ops(void); - -/* dvbc */ - -int dvbc_set_ch(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c, - struct aml_demod_dvbc *demod_dvbc); -int dvbc_status(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c, - struct aml_demod_sts *demod_sts); -int dvbc_isr_islock(void); -void dvbc_isr(struct aml_demod_sta *demod_sta); -u32 dvbc_set_qam_mode(unsigned char mode); -u32 dvbc_get_status(void); -u32 dvbc_set_auto_symtrack(void); -int dvbc_timer_init(void); -void dvbc_timer_exit(void); -int dvbc_cci_task(void *data); -int dvbc_get_cci_task(void); -void dvbc_create_cci_task(void); -void dvbc_kill_cci_task(void); - -/* atsc */ - -int atsc_set_ch(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c, - struct aml_demod_atsc *demod_atsc); -int check_atsc_fsm_status(void); - -void atsc_write_reg(int reg_addr, int reg_data); - -unsigned long atsc_read_reg(int reg_addr); - -unsigned long atsc_read_iqr_reg(void); - -int atsc_qam_set(fe_modulation_t mode); - -void qam_initial(int qam_id); - -/* dtmb */ - -int dtmb_set_ch(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c, - struct aml_demod_dtmb *demod_atsc); - -void dtmb_reset(void); - -int dtmb_check_status_gxtv(struct dvb_frontend *fe); -int dtmb_check_status_txl(struct dvb_frontend *fe); - - -void dtmb_write_reg(int reg_addr, int reg_data); -int dtmb_read_reg(int reg_addr); -void dtmb_register_reset(void); - -/* demod functions */ -unsigned long apb_read_reg_collect(unsigned long addr); -void apb_write_reg_collect(unsigned int addr, unsigned int data); -void apb_write_reg(unsigned int reg, unsigned int val); -unsigned long apb_read_reg_high(unsigned long addr); -unsigned long apb_read_reg(unsigned long reg); -int app_apb_write_reg(int addr, int data); -int app_apb_read_reg(int addr); - -void demod_set_cbus_reg(unsigned int data, unsigned int addr); -unsigned int demod_read_cbus_reg(unsigned int addr); -void demod_set_demod_reg(unsigned int data, unsigned int addr); -unsigned int demod_read_demod_reg(unsigned int addr); - -/* extern int clk_measure(char index); */ - -void ofdm_initial(int bandwidth, - /* 00:8M 01:7M 10:6M 11:5M */ - int samplerate, - /* 00:45M 01:20.8333M 10:20.7M 11:28.57 */ - int IF, - /* 000:36.13M 001:-5.5M 010:4.57M 011:4M 100:5M */ - int mode, - /* 00:DVBT,01:ISDBT */ - int tc_mode - /* 0: Unsigned, 1:TC */); - -void monitor_isdbt(void); -void demod_set_reg(struct aml_demod_reg *demod_reg); -void demod_get_reg(struct aml_demod_reg *demod_reg); - -/* void demod_calc_clk(struct aml_demod_sta *demod_sta); */ -int demod_set_sys(struct aml_demod_sta *demod_sta, - struct aml_demod_i2c *demod_i2c, - struct aml_demod_sys *demod_sys); -/* int demod_get_sys(struct aml_demod_i2c *demod_i2c, */ -/* struct aml_demod_sys *demod_sys); */ -/* int dvbt_set_ch(struct aml_demod_sta *demod_sta, */ -/* struct aml_demod_i2c *demod_i2c, */ -/* struct aml_demod_dvbt *demod_dvbt); */ -/* int tuner_set_ch (struct aml_demod_sta *demod_sta, */ -/* struct aml_demod_i2c *demod_i2c); */ - -/* typedef char int8_t; */ -/* typedef short int int16_t; */ -/* typedef int int32_t; */ -/* typedef long int64_t; */ -/*typedef unsigned char uint8_t; - * typedef unsigned short int uint16_t; - * typedef unsigned int uint32_t; - * typedef unsigned long uint64_t; - */ - -/*typedef unsigned char u8_t; - * typedef signed char s8_t; - * typedef unsigned short u16_t; - * typedef signed short s16_t; - * typedef unsigned int u32_t; - * typedef signed int s32_t; - * typedef unsigned long u64_t; - * typedef signed long s64_t; - */ - -/* #define extadc */ - -/* for g9tv */ -void adc_dpll_setup(int clk_a, int clk_b, int clk_sys); -void demod_power_switch(int pwr_cntl); - -union adc_pll_cntl { - /** raw register data */ - uint32_t d32; - /** register bits */ - struct { - unsigned pll_m:9; - unsigned pll_n:5; - unsigned pll_od0:2; - unsigned pll_od1:2; - unsigned pll_od2:2; - unsigned pll_xd0:6; - unsigned pll_xd1:6; - } b; -}; - -union adc_pll_cntl2 { - /** raw register data */ - uint32_t d32; - /** register bits */ - struct { - unsigned output_mux_ctrl:4; - unsigned div2_ctrl:1; - unsigned b_polar_control:1; - unsigned a_polar_control:1; - unsigned gate_ctrl:6; - unsigned tdc_buf:8; - unsigned lm_s:6; - unsigned lm_w:4; - unsigned reserved:1; - } b; -}; - -union adc_pll_cntl3 { - /** raw register data */ - uint32_t d32; - /** register bits */ - struct { - unsigned afc_dsel_in:1; - unsigned afc_dsel_bypass:1; - unsigned dco_sdmck_sel:2; - unsigned dc_vc_in:2; - unsigned dco_m_en:1; - unsigned dpfd_lmode:1; - unsigned filter_acq1:11; - unsigned enable:1; - unsigned filter_acq2:11; - unsigned reset:1; - } b; -}; - -union adc_pll_cntl4 { - /** raw register data */ - uint32_t d32; - /** register bits */ - struct { - unsigned reve:12; - unsigned tdc_en:1; - unsigned dco_sdm_en:1; - unsigned dco_iup:2; - unsigned pvt_fix_en:1; - unsigned iir_bypass_n:1; - unsigned pll_od3:2; - unsigned filter_pvt1:4; - unsigned filter_pvt2:4; - unsigned reserved:4; - } b; -}; - -/* ///////////////////////////////////////////////////////////////// */ - -union demod_dig_clk { - /** raw register data */ - uint32_t d32; - /** register bits */ - struct { - unsigned demod_clk_div:7; - unsigned reserved0:1; - unsigned demod_clk_en:1; - unsigned demod_clk_sel:2; - unsigned reserved1:5; - unsigned adc_extclk_div:7; /* 34 */ - unsigned use_adc_extclk:1; /* 1 */ - unsigned adc_extclk_en:1; /* 1 */ - unsigned adc_extclk_sel:3; /* 1 */ - unsigned reserved2:4; - } b; -}; - -union demod_adc_clk { - /** raw register data */ - uint32_t d32; - /** register bits */ - struct { - unsigned pll_m:9; - unsigned pll_n:5; - unsigned pll_od:2; - unsigned pll_xd:5; - unsigned reserved0:3; - unsigned pll_ss_clk:4; - unsigned pll_ss_en:1; - unsigned reset:1; - unsigned pll_pd:1; - unsigned reserved1:1; - } b; -}; - -union demod_cfg0 { - /** raw register data */ - uint32_t d32; - /** register bits */ - struct { - unsigned mode:4; - unsigned ts_sel:4; - unsigned test_bus_clk:1; - unsigned adc_ext:1; - unsigned adc_rvs:1; - unsigned adc_swap:1; - unsigned adc_format:1; - unsigned adc_regout:1; - unsigned adc_regsel:1; - unsigned adc_regadj:5; - unsigned adc_value:10; - unsigned adc_test:1; - unsigned ddr_sel:1; - } b; -}; - -union demod_cfg1 { - /** raw register data */ - uint32_t d32; - /** register bits */ - struct { - unsigned reserved:8; - unsigned ref_top:2; - unsigned ref_bot:2; - unsigned cml_xs:2; - unsigned cml_1s:2; - unsigned vdda_sel:2; - unsigned bias_sel_sha:2; - unsigned bias_sel_mdac2:2; - unsigned bias_sel_mdac1:2; - unsigned fast_chg:1; - unsigned rin_sel:3; - unsigned en_ext_vbg:1; - unsigned en_cmlgen_res:1; - unsigned en_ext_vdd12:1; - unsigned en_ext_ref:1; - } b; -}; - -union demod_cfg2 { - /** raw register data */ - uint32_t d32; - /** register bits */ - struct { - unsigned en_adc:1; - unsigned biasgen_ibipt_sel:2; - unsigned biasgen_ibic_sel:2; - unsigned biasgen_rsv:4; - unsigned biasgen_en:1; - unsigned biasgen_bias_sel_adc:2; - unsigned biasgen_bias_sel_cml1:2; - unsigned biasgen_bias_sel_ref_op:2; - unsigned clk_phase_sel:1; - unsigned reserved:15; - } b; -}; - -union demod_cfg3 { - /** raw register data */ - uint32_t d32; - /** register bits */ - struct { - unsigned dc_arb_mask:3; - unsigned dc_arb_enable:1; - unsigned reserved:28; - } b; -}; - -struct atsc_cfg { - int adr; - int dat; - int rw; -}; - -struct agc_power_tab { - char name[128]; - int level; - int ncalcE; - int *calcE; -}; - -struct dtmb_cfg { - int dat; - int adr; - int rw; -}; - -void dtvpll_lock_init(void); -void dtvpll_init_flag(int on); -void demod_set_irq_mask(void); -void demod_clr_irq_stat(void); -void demod_set_adc_core_clk(int adc_clk, int sys_clk, int dvb_mode); -void demod_set_adc_core_clk_fix(int clk_adc, int clk_dem); -void calculate_cordic_para(void); -void ofdm_read_all_regs(void); -extern int aml_fe_analog_set_frontend(struct dvb_frontend *fe); - -#endif diff --git a/drivers/stream_input/tv_frontend/dtv_demod/tuner_func.c b/drivers/stream_input/tv_frontend/dtv_demod/tuner_func.c deleted file mode 100644 index f4c1a38..0000000 --- a/drivers/stream_input/tv_frontend/dtv_demod/tuner_func.c +++ b/dev/null @@ -1,189 +0,0 @@ -/* -* Copyright (C) 2017 Amlogic, Inc. All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* 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., -* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* Description: -*/ -#include -#include -#include -#include "demod_func.h" -#include "../aml_fe.h" - -int tuner_get_ch_power(struct aml_fe_dev *adap) -{ - int strength = 0; - int agc_if_gain; - - struct dvb_frontend *dvbfe; - - dvbfe = get_si2177_tuner(); - if (dvbfe != NULL) - if (dvbfe->ops.tuner_ops.get_strength) - strength = dvbfe->ops.tuner_ops.get_strength(dvbfe); - if (strength <= -56) { - agc_if_gain = - ((dtmb_read_reg(DTMB_TOP_FRONT_AGC))&0x3ff); - strength = dtmb_get_power_strength(agc_if_gain); - } - - return strength; -} - -struct dvb_tuner_info *tuner_get_info(int type, int mode) -{ - /*type : 0-NULL, 1-DCT7070, 2-Maxliner, 3-FJ2207, 4-TD1316 */ - /*mode: 0-DVBC 1-DVBT */ - static struct dvb_tuner_info tinfo_null = { }; - - static struct dvb_tuner_info tinfo_MXL5003S[2] = { - [1] = { /*DVBT*/ .name = "Maxliner", - .frequency_min = 44000000, - .frequency_max = 885000000, } - }; - static struct dvb_tuner_info tinfo_FJ2207[2] = { - [0] = { /*DVBC*/ .name = "FJ2207", - .frequency_min = 54000000, - .frequency_max = 870000000, }, - [1] = { /*DVBT*/ .name = "FJ2207", - .frequency_min = 174000000, - .frequency_max = 864000000, }, - }; - static struct dvb_tuner_info tinfo_DCT7070[2] = { - [0] = { /*DVBC*/ .name = "DCT7070", - .frequency_min = 51000000, - .frequency_max = 860000000, } - }; - static struct dvb_tuner_info tinfo_TD1316[2] = { - [1] = { /*DVBT*/ .name = "TD1316", - .frequency_min = 51000000, - .frequency_max = 858000000, } - }; - static struct dvb_tuner_info tinfo_SI2176[2] = { - [0] = { /*DVBC*/ - /*#error please add SI2176 code*/ - .name = "SI2176", - .frequency_min = 51000000, - .frequency_max = 860000000, - } - }; - - struct dvb_tuner_info *tinfo[] = { - &tinfo_null, - tinfo_DCT7070, - tinfo_MXL5003S, - tinfo_FJ2207, - tinfo_TD1316, - tinfo_SI2176 - }; - - if ((type < 0) || (type > 4) || (mode < 0) || (mode > 1)) - return tinfo[0]; - - return &tinfo[type][mode]; -} - -struct agc_power_tab *tuner_get_agc_power_table(int type) -{ - /*type : 0-NULL, 1-DCT7070, 2-Maxliner, 3-FJ2207, 4-TD1316 */ - static int calcE_FJ2207[31] = { - 87, 118, 138, 154, 172, 197, 245, - 273, 292, 312, 327, 354, 406, 430, - 448, 464, 481, 505, 558, 583, 599, - 616, 632, 653, 698, 725, 745, 762, - 779, 801, 831 }; - static int calcE_Maxliner[79] = { - 543, 552, 562, 575, 586, 596, 608, - 618, 627, 635, 645, 653, 662, 668, - 678, 689, 696, 705, 715, 725, 733, - 742, 752, 763, 769, 778, 789, 800, - 807, 816, 826, 836, 844, 854, 864, - 874, 884, 894, 904, 913, 923, 932, - 942, 951, 961, 970, 980, 990, 1000, - 1012, 1022, 1031, 1040, 1049, 1059, - 1069, 1079, 1088, 1098, 1107, 1115, - 1123, 1132, 1140, 1148, 1157, 1165, - 1173, 1179, 1186, 1192, 1198, 1203, - 1208, 1208, 1214, 1217, 1218, 1220 }; - - static struct agc_power_tab power_tab[] = { - [0] = { "null", 0, 0, NULL }, - [1] = { - .name = "DCT7070", - .level = 0, - .ncalcE = 0, - .calcE = NULL, - }, - [2] = { - .name = "Maxlear", - .level = -22, - .ncalcE = sizeof(calcE_Maxliner) / sizeof(int), - .calcE = calcE_Maxliner, - }, - [3] = { - .name = "FJ2207", - .level = -62, - .ncalcE = sizeof(calcE_FJ2207) / sizeof(int), - .calcE = calcE_FJ2207, - }, - [4] = { - .name = "TD1316", - .level = 0, - .ncalcE = 0, - .calcE = NULL, - }, - }; - - if (type >= 2 && type <= 3) - return &power_tab[type]; - else - return &power_tab[3]; -}; - -int agc_power_to_dbm(int agc_gain, int ad_power, int offset, int tuner) -{ - struct agc_power_tab *ptab = tuner_get_agc_power_table(tuner); - int est_rf_power; - int j; - - for (j = 0; j < ptab->ncalcE; j++) - if (agc_gain <= ptab->calcE[j]) - break; - - est_rf_power = ptab->level - j - (ad_power >> 4) + 12 + offset; - - return est_rf_power; -} - -int dtmb_get_power_strength(int agc_gain) -{ - int strength; - int j; - static int calcE_R840[13] = { - 1010, 969, 890, 840, 800, - 760, 720, 680, 670, 660, - 510, 440, 368}; - for (j = 0; j < sizeof(calcE_R840)/sizeof(int); j++) - if (agc_gain >= calcE_R840[j]) - break; - if (agc_gain >= 440) - strength = -90+j*3; - else - strength = -56; - return strength; -} - - diff --git a/firmware/video_ucode.bin b/firmware/video_ucode.bin index cf1c3b9..5bdf4c2 100644 --- a/firmware/video_ucode.bin +++ b/firmware/video_ucode.bin @@ -1,420 +1,29 @@ -ŒžŒöÉöšþ€ej€BeàùŽ=Š4¯µŠ&È8+Žß˜TtªW‘GÞIߎ$Ym IÊo¯A‰1aËØŋ°£ÈEÎ×±åv¬å Ä -±Ä5qaÊ8Þ÷џ3kYÁÝ{s™40-·Ôam’œÛ2lÔ@?Bgþò’ÑÇXŽŠ ’RŒñÅꚬץ,h=~H\&ɕ¥.Rc”·ê(ŸÜvéd-É\”\uq¹ÕŸŒéI`³¬|ÚóTVÁwŽöùFäA«‡”ßT²!HÁ³±È·Ç³¹»à­Š~<Èá ŒWîÉÓß4+ï~J’ÜnKCAP - +A±VwfYÈ-E4Œ(djO8 ±ˆDÃCÂÏ·É®B:i&¹ͱFŠÑ»g¢Ÿéµ [ß2¢ä3õ º„€¢wfÍ þtQFŸšåú`F§w^—›ÖšaQënœ#üµù$×;©,‚ ¢Ÿåð×éßZcc% +MLµœžéŒšTóÉozÓ/Ù²§Ž'¹ ]3·üxZÊ£”#‡ålãvÐNùåü7‰‰ŠŠÅœÎÇ¥§žŸá8 £œÉSöMdì"A±qDúj<®ž³øèF˜ï⋺x=jñH‰)÷ÎÒʂÅ9 + € @¡ I€` -@y ‰€` -@ y $ - -Ç  - @! - -² -ÇC€Àd -)LÄâ  - - -ñ%€€ö ò%€ò -€ -G€‡ÀG€GÀ% & & & ÇÀr€ ! €@¡ - GÀ  - ¢ -Ç - -@o -@€Í?¡  - - -Ê - -/G¡ -Ê€JÀ -ÉFa - - -€ŠÀÈ; -€  - -Gd -Ê€JÀ - €  À  -¬ -Q -?€ -R P - - -Ë?€ˆ€ NI HB€ À  -Àþ Ë@GA€ǀ¢ -G€È€r@ @> HÀH - -‰€É -€ -Ào -G€‡À#LB0 €o - - ÇA ÈR LI - -% ‡Š -H€¡ -À` - -‰ - -É -@® ÉÀË?€ˆ€ NI HB€ À  -Àþ Ë@ˆ - -ÐI -À  -Ç  -  - -¢€ - € - -LJ£€ - À· - -L -Š€ -  €   -LÊ?! - -LJ§À - J§€ ʧ€ - €‚Àq -,¥ -ˆ@€À£ -Êl¡ -Ší¡ -Šl¢ -Êëâ -À÷x  -x ‡À -@À -Ä €‚À€ÀŠ -ÀÁÀÀÀqÀÀÀ - -€ -À‡ -€G -ÀÀÀ‡ -ÀÇ -À1@€@u ‡ - -€\ ˆ -ÀÇ -È -È -H - - - - -ÀÁÀÀÀqÀÀ!ÀGÀ` -€x Z -À@x š -€ -À‡ -€G -ÀÀÀ‡ -ÀÇ -Àq€€] š -@Ÿ # GÀÀÀÈ -€\ šÀ  -È -Àˆ -ÀÇ -È -È -H -€òÀÇ À¥ - -€  -ÇñÇ@ÇñGÀG -€  -ÇñÇ@Çñ‡À‡ -€  -ÇñÇ@Çñ@ x ÇÀ -€ À¢ -ÇñÇ€€È1@ @€H‚ -€ À¢ -ÇñÇ€€È1@ @€H‚ -€ À¢ -ÇñÇ€€È1 -GA€ÇÀ` -@x €ÀÀ‡ -€G - - - -  € ÀÀx ÀÀÀÀ -IÀ€“ #  - €ˆÀˆ€ÈÀˆ€À€HÀˆÀÀx  €È!€ˆÀÈ#€ÈÀÀ(€HÀˆÀH5€ÈÀÇÀa - € À@x À¢ -‰€ - -QLFLˆ€AI€H‚ -‚p "@ȁ -CLˆ‚@ -@Lˆ‚@ÈÀ ÀÀ˜ -H -a   - - -Œ - €G€¡ - -É - - -x Ç@‡À  -I€É€ÉÀ €x  - -‡ - - -H -ˆ -È - -€ÇA ÈQ@ -G - €ZÀ` -É@È -È Ù@  -I@@x @‰€É@ -²  -°  -± É -@x ‡€ÇÀˆÀ… - -‡€‡Àa H -€  -@¡ -Ç -m€­`€@Š - @a -J - - - -x - -€Èñ@ -a Ö GL€ˆL€Èa H - - -€x -@d - -Y€Ja  -Èd - -Y€ -a -@€ˆ‚ -YÀ@x -ü¢ „b -Y€ -a H‚ -¬ -Q R P PC ó€L€ï - -¬@ - - LÀ -Àþ J -È€ r€ -ò€ -ÉÀ -GB€ -  - -@x -G -‡ -Ç@ -@x - ÇsÀ ‡s€  -  -LÇ! €o - -H - - -  -‚ǁ €£ -€V -GLÃ@€Hâ - -€ €ÂÀ‚ -€1€À= ‚ - -€x -CtÂ€‚ -.GL®K€.Hâ - -€'~ - -Pî -P€À£ -À!x  - - -/Ç£ -P€d@Ñ€Q€QÀà  -¢RÀ  -À¢Á¢@À -B€RÀ¢ -@€@x A€ÑÀc -€ N’ €Ž -Q@ÑÀ‘€Q@ -b¡RÀ  -`¡a¡Ò€€¢ -€ N’ D€ €€Ý ÒÀ -‘€@§ -Q@QÀ& ‘ÀЀÐÀ  - - -x ü/Ç  -„ - t ’ €4‚ T -  - -‘€Àü -B¡Á  -@¡A¡€À /Ç  -ßßÀô P€”@P’€‘‘ÀP4@€€a -ÐÁ Ð -ß -ˆ -ŽIˆ| -Ž I z Ê -"p  ˆ ‚À"h Š €Ê Ê€ - € -bp -À  -@ÿ @ I € ɐ€  À ɐÀ  -SIŠ - À  -@þ I@ -I À  - -€o -I@ -=LŠ¢€ʀï -ŽI - € É€‰bp -Ž  - À -Ž :Lb - L L 8L€ -    8  - /€Ëÿ¿$ -€€€‹@Š -! Ša " ça # Ž €Λ -Ç?€‡À -‡€Ç?a Ç  ÇÁA‡ÀPCÇñ€G€ï - -‡ -Àó -À€€ȁ -¬ - -Q -?€ -RÀí P#LGÀï -Ç€Èq@ - -Â. Š - -Â. Š - -Â. Š - -ˆ -­`€Z - -Â. Š -€  -ÀLx -‰€ À` - -‰€ À  - -À x ˆ€@Ç€€é Ç@ €Hbd 0 H€@Ç€€ç Ç@H €Hbd 0 €ˆ€r@ÇñG@Ç€€r@ÇñÇ@G’R  €Hbd 0 €ˆ€ÀÑ ‰€€Hbd 0 Ç€€ -Œ€ -Ç€Ç@ˆ€@€x  - -Ç€Ç@ˆ€ - -Ç€Ç@H€@Àx  -Ç€Ç@H€ -Ç@Ç -Ç@ˆ€À` - -@ -Ç@Ç -Ç@ˆ€À` - -@ - -Àx €ˆ€ -€x €€Ç@ # - À¡ - - - À¡ -I - -@ˆ€@Œ€¡ -L@¡ - -I@‰€I@Œ€¡ -L@¡ -I - ‘ @x ’  ‘ ’ “ ” € -Z€  - -ˆXØш‡ -ˆPÈH ‘ȈÐ -ˆXØ -HØ -*ÅI*€d -*AL+CL«Êh jê@ -j - - - -À -2Í ³ ! ±,€ -Àx 3Á - - - € @¡ -I€` -€=y ‰€` -À9y È# -€†x -Ç  - @U +@Ly ‰€` +€Hy ÆIȀ` +€•x È# +Àˆx +Ç  + ÀŸ " - + ÇC€€d )LÄâ  -ñ%€ +ñ%€@Ò ò%€ € G€‡ÀG€GÀˆ>€ % & & & ÇC€ÀŠ D€@f &LÀo - - + +  GÀ   ¢ Ç @@ -439,22 +48,21 @@ Gd ¬ Q ?€ -R P€X +R P C.  - + Ë?€ˆ€ NI HB€ À  Àþ Ë@GA€ÇÀŠ -G€È€‚A @g HÀH +G€È€‚A À± HÀH D€@b ÇC€À¡  -ˆÀ - - Š - -‰€É +ˆÀ + + +‰€É € Ào G€‡À#LB0 €o @@ -466,54 +74,60 @@ H€€ Àc ÇC€À¡ -G +G š@c &LÀo -G -‰ - +G +‰ + &LÀo ZÀ` -Ç +Ç É -@š ÉÀË?€ˆ€ NI HB€ À  + Àþ Ë@ˆ - - ÀÎ + +  ¢€  € LJ£€ - €Ð + À D€€a @a - -ÐI + +J€ À  Ç  L Š€ -  €  €‚Àq +  €  ÆIÈÀa + +ÔI±€€E Š + +Êì  +Š­  +@x @; ì€ -ˆ@€À£ +ÁIÀ£ Êl¡ Ší¡ Šl¢ Êëâ -Ày  -x ‡À + +x ‡À @À -Ä €‚À€ÀŠ +Ä €‚À€ÀŠ  ǀȀ¢@ ‡’€ D€Àa ÇC€@¡ - + ÀÁÀÀÀqÀÀÀ € @@ -521,8 +135,8 @@ x ‡À €G ÀÀÀ‡ ÀÇ -À1@€ -@ê # GÀÀÀˆ +À1@€@' ‡ +À) # GÀÀÀˆ €\ ˆ ÀÇ È @@ -531,12 +145,12 @@ H   - +  ǀȀ¢@ ‡’€ D€Àa ÇC€@¡ - + ÀÁÀÀÀqÀÀ!ÀGÀ` €x Z À@x š @@ -545,8 +159,8 @@ H €G ÀÀÀ‡ ÀÇ -Àq€€’ š -ÀÎ # GÀÀÀÈ +Àq€À  š +@ # GÀÀÀÈ €\ šÀ  È Àˆ @@ -572,31 +186,31 @@ GA€ÇÀ` @x €ÀÀ‡ €G  - +  € ÀÀx ÀÀÀÀ -IÀ +IÀ€ã #   €ˆÀˆ€ÈÀˆ€À€HÀˆÀÀx  €È!€ˆÀÈ#€ÈÀÀ(€HÀˆÀH5€ÈÀÇÀa  € À@x À¢ -‰€€— #  +‰€ I@À   QLFLˆ€AI€H‚ ‚p "@ȁ CLˆ‚@ -@Lˆ‚@ÈÀ À@§ +@Lˆ‚@ÈÀ ÀÀæ H -a  ÀÊ +a  Àö  Œ €G€¡ -É +É  ID€ €` -€×~ €§x - + +@x I€É€‹€Ë@‹ Š Ç @@ -605,32 +219,33 @@ I€É€‹€Ë@‹  @a G -H - -‡ - +H + +‡ + €¢ Ë@ -€ˆ² -ÀË€ˆ@Ê¢ - -€ÇA ÈQ@ -G +€ˆ² +À +\€ +¢ +@¢ +€ÇA Èa@ +G  €ZÀ` É@È È Ù@  -I@@x @‰€É@ - ˆ +I@@x @‰€É@ ²  °  ± É @x ‡€ÇÀˆÀ… - + ‡€‡Àa H €  @¡ -Ç --€-p€ +Ç +­€-s€@é @a J @@ -640,7 +255,7 @@ x €Èñ@ a Ö GL€ˆL€Èa H - + €x @d @@ -666,13 +281,13 @@ Q R P PC ó€L€ï ‡’€ D€Àa ÇC€@¡ - -J - + +J + Àõ J È€ b€ @x ’@È€ R€ -ÉÀ +ÉÀ GB€   @@ -683,26 +298,52 @@ G ÇC€À` @x ÇsÀ ‡s€  - @¯ + €ê LÇ! €o - + H -  -‚ǁ €£ -À{ - -GLÃ@€Hâ - -€ €ÂÀ -€1€€` ‚ +  +LÀ  + +Ç À¥ +€µ + +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +À + + “ ±Ä€€± ‡ +€ €ÂÀF€ €FÀ +ÆIC +L€¡ +@x GLÃ@€ˆå + + +F€Âÿ¿Âÿÿƒ0 +€  €x -CtÂ€‚ -.GL®K€.Hâ - -Àò} +CtÂ€‚ +.GL®K€.å + + +ÀŠ} P€À£ À!x  @@ -780,7 +421,7 @@ RÀí P#LGÀï Â. Š ˆ --p€Z +-s€Z Â. Š €  @@ -834,33 +475,44 @@ H - + *ÅI*€d *AL+CL«Êh jê@ j - -À -2Í ³ ! ±,€ + +(vÀiÀi +ivÀjÀª +ªvÀkÀë +ëvÀlÀ, ,wÀmÀm mwÀnÀ® ®wÀoÀï ïwÀ +A +A@n€)ªv€ˆ +A€n€* ëv€È +AÀn€+°,w€ A +€x 3ÓI³@& +Àx 3ÓI3‚% +2Í ò?€2 Àx 3Á - - - + + + + € @¡ I€` -€ y ‰€` -€ y $ - -Ç  - À +Ày ‰€` +Ày ÆIȀ` +€ux $ +@lx +Ç  + Ài  -² +² ÇC€Àd )LÄâ  -ñ%€ +ñ%€Àx ò%€ò € G€‡ÀG€GÀ% & & & ÇÀr€ ! €@¡  GÀ  @@ -887,14 +539,14 @@ Gd ¬ Q ?€ -R P€* +R P€u  Ë?€ˆ€ NI HB€ À  Àþ Ë@GA€ǀ¢ -G€È€r@ À; HÀH - -‰€É +G€È€r@ À† HÀH + +‰€É € Ào G€‡À#LB0 €o @@ -905,23 +557,25 @@ G€‡À#LB0 €o H€¡ À` -‰ - +‰ + É -@® ÉÀË?€ˆ€ NI HB€ À  + Àþ Ë@ˆ - -ÐI + +J€ À  -Ç  - €³ +Ç  + @ü + ¢€  € LJ£€ - @µ - +  +L@a + L Š€   €   @@ -929,409 +583,23 @@ H€¡ LJ§À  J§€ ʧ€ - €‚Àq -,¥ -ˆ@€À£ -Êl¡ -Ší¡ -Šl¢ -Êëâ - -x ‡À -@À -Ä €‚À€ÀŠ -ÀÁÀÀÀqÀÀÀ - -€ -À‡ -€G -ÀÀÀ‡ -ÀÇ -À1@€Àr ‡ -€Ó # GÀÀÀˆ -€\ ˆ -ÀÇ -È -È -H - - - - -ÀÁÀÀÀqÀÀ!ÀGÀ` -€x Z -À@x š -€ -À‡ -€G -ÀÀÀ‡ -ÀÇ -Àq€ -À» # GÀÀÀÈ -€\ šÀ  -È -Àˆ -ÀÇ -È -È -H -€òÀÇ À¥ - -€  -ÇñÇ@ÇñGÀG -€  -ÇñÇ@Çñ‡À‡ -€  -ÇñÇ@Çñ@ x ÇÀ -€ À¢ -ÇñÇ€€È1@ @€H‚ -€ À¢ -ÇñÇ€€È1@ @€H‚ -€ À¢ -ÇñÇ€€È1 -GA€ÇÀ` -@x €ÀÀ‡ -€G - - - -  € ÀÀx ÀÀÀÀ -IÀ - €ˆÀˆ€ÈÀˆ€À€HÀˆÀÀx  €È!€ˆÀÈ#€ÈÀÀ(€HÀˆÀH5€ÈÀÇÀa - € À@x À¢ -‰€€„ #  - -QLFLˆ€AI€H‚ -‚p "@ȁ -CLˆ‚@ -@Lˆ‚@ÈÀ À@– -H -a  @ž - -Œ - €G€¡ - -É - - -x Ç@‡À  -I€É€ÉÀ €x  - -‡ - - -H -ˆ -È - -€ÇA ÈQ@ -G - €ZÀ` -É@È -È Ù@  -I@@x @‰€É@ -²  -°  -± É -@x ‡€ÇÀˆÀ… - -‡€‡Àa H -€  -@¡ -Ç -m€­`€@§ - @a -J - - - -x - -€Èñ@ -a Ö GL€ˆL€Èa H - - -€x -@d - -Y€Ja  -Èd - -Y€ -a -@€ˆ‚ -YÀ@x -ü¢ „b -Y€ -a H‚ -¬ -Q R P PC ó€L€ï - -¬@ - - LÀ -Àþ J -È€ r€ -ò€ -ÉÀ -GB€ -  - -@x -G -‡ -Ç@ -@x - ÇsÀ ‡s€  - @± -LÇ! €o - -H - - -  -‚ǁ €£ -ÀU - -GLÃ@€Hâ - -€ €ÂÀ‚ -€1€ - -€x -CtÂ€‚ -.GL®K€.Hâ - -@(~ - -P€À£ -À!x  - - -/Ç£ -P€d@Ñ€Q€QÀà  -¢RÀ  -À¢Á¢@À -B€RÀ¢ -@€@x A€ÑÀc -€ N’ €Ž -Q@ÑÀ‘€Q@ -b¡RÀ  -`¡a¡Ò€€¢ -€ N’ D€ €€Þ ÒÀ -‘€@§ -Q@QÀ& ‘ÀЀÐÀ  - - -x ü/Ç  -„ - t ’ €4‚ T -  - -‘€Àü -B¡Á  -@¡A¡€À /Ç  -ßßÀô P€”@P’€‘‘ÀP4@€€a -ÐÁ Ð -ß -ˆ -ŽIˆ| -Ž IÊ -"p  ˆ ‚À"h Š €Ê Ê€ - € -bp -À  -@ÿ @ I € ɐ€  À ɐÀ  -SIŠ - À  -@þ I@ -I À  + ÆIÈÀa -€o -I@ -=LŠ¢€ʀï -ŽI - € É€‰bp -Ž  - À -Ž :Lb - L L 8L€ -    8  - /€Ëÿ¿$ -€€€‹@Š -! Ša " ça # Ž €Λ -Ç?€‡À -‡€Ç?a Ç  ÇÁA‡ÀPCÇñ€G€ï - -‡ -Àó -À€€ȁ -¬ - -Q -?€ -RÀí P#LGÀï -Ç€Èq@ - -Â. Š - -Â. Š - -Â. Š - -ˆ -­`€Z - -Â. Š -€  -ÀLx -‰€ À` - -‰€ À  - -À x ˆ€@Ç€€é Ç@ €Hbd 0 H€@Ç€€ç Ç@H €Hbd 0 €ˆ€r@ÇñG@Ç€€r@ÇñÇ@G’R  €Hbd 0 €ˆ€ÀÑ ‰€€Hbd 0 Ç€€ -Œ€ -Ç€Ç@ˆ€@€x  - -Ç€Ç@ˆ€ - -Ç€Ç@H€@Àx  -Ç€Ç@H€ -Ç@Ç -Ç@ˆ€À` - -@ -Ç@Ç -Ç@ˆ€À` - -@ - -Àx €ˆ€ -€x €€Ç@ # - À¡ - - - À¡ -I - -@ˆ€@Œ€¡ -L@¡ - -I@‰€I@Œ€¡ -L@¡ -I - ‘ @x ’  ‘ ’ “ ” € -Z€  - -ˆXØш‡ -ˆPÈH ‘ȈÐ -ˆXØ -HØ -*ÅI*€d -*AL+CL«Êh jê@ -j - - - -À -2Í ³ ! ±,€ -Àx 3Á - - - - € @¡ -I€` -€ y ‰€` -€ y $ - -Ç  - À - -² -ÇC€Àd -)LÄâ  - - -ñ%€ -€ -G€‡ÀG€GÀ% & & & ÇÀr€ ! €@¡ - GÀ  - ¢ -Ç - -@o -@€Í?¡  - - -Ê - -/G¡ -Ê€JÀ -ÉFa - - -€ŠÀÈ; -€  - -Gd -Ê€JÀ - €  À  -¬ -Q -?€ -R P€* - - -Ë?€ˆ€ NI HB€ À  -Àþ Ë@GA€ǀ¢ -G€È€r@ À; HÀH - -‰€É -€ -Ào -G€‡À#LB0 €o - - ÇA ÈR LI - -% ‡Š -H€¡ -À` - -‰ - -É -@® ÉÀË?€ˆ€ NI HB€ À  -Àþ Ë@ˆ - -ÐI -À  -Ç  - €³ - -¢€ - € - -LJ£€ - @µ - -L -Š€ -  €   -LÊ?! - -LJ§À - J§€ ʧ€ - €‚Àq +ÔI±€ + +Êì  +Š­  +@x @! ,¥ -ˆ@€À£ +ÁIÀ£ Êl¡ Ší¡ Šl¢ Êëâ - -x ‡À +@üx  +x ‡À @À -Ä €‚À€ÀŠ +Ä €‚À€ÀŠ ÀÁÀÀÀqÀÀÀ € @@ -1339,8 +607,8 @@ x ‡À €G ÀÀÀ‡ ÀÇ -À1@€Àr ‡ -€Ó # GÀÀÀˆ +À1@€ + €\ ˆ ÀÇ È @@ -1349,7 +617,7 @@ H   - + ÀÁÀÀÀqÀÀ!ÀGÀ` €x Z À@x š @@ -1358,8 +626,8 @@ H €G ÀÀÀ‡ ÀÇ -Àq€ -À» # GÀÀÀÈ +Àq€@Ô š +@û # GÀÀÀÈ €\ šÀ  È Àˆ @@ -1385,53 +653,54 @@ GA€ÇÀ` @x €ÀÀ‡ €G  - +  € ÀÀx ÀÀÀÀ -IÀ +IÀ€Ð #   €ˆÀˆ€ÈÀˆ€À€HÀˆÀÀx  €È!€ˆÀÈ#€ÈÀÀ(€HÀˆÀH5€ÈÀÇÀa  € À@x À¢ -‰€€„ #  +‰€  QLFLˆ€AI€H‚ ‚p "@ȁ CLˆ‚@ -@Lˆ‚@ÈÀ À@– +@Lˆ‚@ÈÀ ÀÀÕ H -a  @ž +a  €ã  Œ €G€¡ -É - - -x Ç@‡À  -I€É€ÉÀ €x  - -‡ - - -H -ˆ -È - -€ÇA ÈQ@ -G +É + +@ x +I€É€€Ç@É1 + +‡ + +À¢ +Ë@ +€ˆ² +À +\€ +¢ +@¢ +€ÇA Èa@ +G  €ZÀ` É@È È Ù@  -I@@x @‰€É@ +I@@x @‰€É@ ²  °  ± É @x ‡€ÇÀˆÀ… - + ‡€‡Àa H €  @¡ -Ç -m€­`€@§ +Ç +퀭c€€à @a J @@ -1441,7 +710,7 @@ x €Èñ@ a Ö GL€ˆL€Èa H - + €x @d @@ -1465,7 +734,7 @@ Q R P PC ó€L€ï Àþ J È€ r€ ò€ -ÉÀ +ÉÀ GB€   @@ -1475,26 +744,52 @@ G Ç@ @x ÇsÀ ‡s€  - @± + €ê LÇ! €o - + H -  -‚ǁ €£ -ÀU - -GLÃ@€Hâ - -€ €ÂÀ‚ -€1€ +  +LÀ  + +Ç À¥ +€ + +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +À + + “ ±Ä€€Ž ‡ +€ €ÂÀ‚ +ÆIC +L€¡ +@x GLÃ@€ˆå + + +F€Âÿ¿Âÿÿƒ0 +€  €x -CtÂ€‚ -.GL®K€.Hâ - -@(~ +CtÂ€‚ +.GL®K€.å + + +ÀÛ} P€À£ À!x  @@ -1572,7 +867,7 @@ RÀí P#LGÀï Â. Š ˆ -­`€Z +­c€Z Â. Š €  @@ -1618,33 +913,44 @@ Z€  ˆXØш‡ ˆPÈH ‘ȈÐ ˆXØ -HØ +HØ *ÅI*€d *AL+CL«Êh jê@ j - -À -2Í ³ ! ±,€ + +(vÀiÀi +ivÀjÀª +ªvÀkÀë +ëvÀlÀ, ,wÀmÀm mwÀnÀ® ®wÀoÀï ïwÀ +A +A@n€)ªv€ˆ +A€n€* ëv€È +AÀn€+°,w€ A +€x 3ÓI³@& +Àx 3ÓI3‚% +2Í ò?€2 Àx 3Á - - - + + + + € @¡ I€` -€ y ‰€` -€y $ - -Ç  - € +Ày ‰€` +Ày ÆIȀ` +€ux $ +@lx +Ç  + €f  -² +² ÇC€Àd )LÄâ  -ñ%€Àð ò%€ò +ñ%€€u ò%€ò € G€‡ÀG€GÀ% & & & ÇÀr€ ! €@¡  GÀ  @@ -1671,14 +977,14 @@ Gd ¬ Q ?€ -R P@' +R P@r  Ë?€ˆ€ NI HB€ À  Àþ Ë@GA€ǀ¢ -G€È€r@ €8 HÀH - -‰€É +G€È€r@ €ƒ HÀH + +‰€É € Ào G€‡À#LB0 €o @@ -1689,36 +995,43 @@ G€‡À#LB0 €o H€¡ À` -‰ - +‰ + É -@® ÉÀË?€ˆ€ NI HB€ À  + Àþ Ë@ˆ - -ÐI + +J€ À  -Ç  - @° +Ç  +  ¢€  € LJ£€ -  - + Àú +L@a + L Š€ -  €  €‚Àq +  €  ÆIÈÀa + +ÔI±€À Š + +Êì  +Š­  +@x @! ,¥ -ˆ@€À£ +ÁIÀ£ Êl¡ Ší¡ Šl¢ Êëâ - -x ‡À +@üx  +x ‡À @À -Ä €‚À€ÀŠ +Ä €‚À€ÀŠ ÀÁÀÀÀqÀÀÀ € @@ -1726,8 +1039,8 @@ x ‡À €G ÀÀÀ‡ ÀÇ -À1@€€q ‡ -@Ò # GÀÀÀˆ +À1@€Àê ‡ +À # GÀÀÀˆ €\ ˆ ÀÇ È @@ -1736,7 +1049,7 @@ H   - + ÀÁÀÀÀqÀÀ!ÀGÀ` €x Z À@x š @@ -1745,8 +1058,8 @@ H €G ÀÀÀ‡ ÀÇ -Àq€ÀY š -€º # GÀÀÀÈ +Àq€ + €\ šÀ  È Àˆ @@ -1772,53 +1085,54 @@ GA€ÇÀ` @x €ÀÀ‡ €G  - +  € ÀÀx ÀÀÀÀ -IÀÀ # @ +IÀ@Ï # ÀÏ  €ˆÀˆ€ÈÀˆ€À€HÀˆÀÀx  €È!€ˆÀÈ#€ÈÀÀ(€HÀˆÀH5€ÈÀÇÀa  € À@x À¢ -‰€@ƒ # Àƒ +‰€À # @à  QLFLˆ€AI€H‚ ‚p "@ȁ CLˆ‚@ -@Lˆ‚@ÈÀ À +@Lˆ‚@ÈÀ À€Ô H -a   +a  @â  Œ €G€¡ -É - - -x Ç@‡À  -I€É€ÉÀ €x  - -‡ - - -H -ˆ -È - -€ÇA ÈQ@ -G +É + +@ x +I€É€€Ç@É1 + +‡ + +À¢ +Ë@ +€ˆ² +À +\€ +¢ +@¢ +€ÇA Èa@ +G  €ZÀ` É@È È Ù@  -I@@x @‰€É@ +I@@x @‰€É@ ²  °  ± É @x ‡€ÇÀˆÀ… - + ‡€‡Àa H €  @¡ -Ç -m€­`€ +Ç +퀭c€@ß @a J @@ -1828,7 +1142,7 @@ x €Èñ@ a Ö GL€ˆL€Èa H - + €x @d @@ -1852,7 +1166,7 @@ Q R P PC ó€L€ï Àþ J È€ r€ ò€Àx ’@È€ R€ -ÉÀ +ÉÀ GB€   @@ -1862,26 +1176,53 @@ G Ç@ @x ÇsÀ ‡s€  -  + @é LÇ! €o - + H -  -‚ǁ €£ -ÀU - -GLÃ@€Hâ - -€ €ÂÀ‚ -€1€ +  +LÀ  + +Ç À¥ +€ + +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +À + + “ ±Ä€€Ž ‡ +€ €ÂÀ‚ +ÆIC +L€¡ +@x GLÃ@€ˆå + + + +F€Âÿ¿Âÿÿƒ0 +€  €x -CtÂ€‚ -.GL®K€.Hâ - -€+~ +CtÂ€‚ +.GL®K€.å + + + P€À£ À!x  @@ -1959,7 +1300,7 @@ RÀí P#LGÀï Â. Š ˆ -­`€Z +­c€Z Â. Š €  @@ -2005,33 +1346,44 @@ Z€  ˆXØш‡ ˆPÈH ‘ȈÐ ˆXØ -HØ +HØ *ÅI*€d *AL+CL«Êh jê@ j - -À -2Í ³ ! ±,€ + +(vÀiÀi +ivÀjÀª +ªvÀkÀë +ëvÀlÀ, ,wÀmÀm mwÀnÀ® ®wÀoÀï ïwÀ +A +A@n€)ªv€ˆ +A€n€* ëv€È +AÀn€+°,w€ A +€x 3ÓI³@& +Àx 3ÓI3‚% +2Í ò?€2 Àx 3Á - - - + + + + € @¡ I€` -@y ‰€` -@ y $ - -Ç  - @! +€y ‰€` +€y ÆIȀ` +€ux $ +@lx +Ç  + @l  -² +² ÇC€Àd )LÄâ  -ñ%€€ö ò%€ò +ñ%€@{ ò%€ò € G€‡ÀG€GÀ% & & & ÇÀr€ ! €@¡  GÀ  @@ -2058,14 +1410,14 @@ Gd ¬ Q ?€ -R P +R P  Ë?€ˆ€ NI HB€ À  Àþ Ë@GA€ǀ¢ -G€È€r@ @> HÀH - -‰€É +G€È€r@ @‰ HÀH + +‰€É € Ào G€‡À#LB0 €o @@ -2076,23 +1428,24 @@ G€‡À#LB0 €o H€¡ À` -‰ - +‰ + É -@® ÉÀË?€ˆ€ NI HB€ À  + Àþ Ë@ˆ - -ÐI + +J€ À  -Ç  -  +Ç  + Àþ ¢€  € LJ£€ - À· - + € +L@a + L Š€   €   @@ -2100,17 +1453,23 @@ H€¡ LJ§À  J§€ ʧ€ - €‚Àq + ÆIÈÀa + +ÔI±€€  Š + +Êì  +Š­  +@x ,¥ -ˆ@€À£ +ÁIÀ£ Êl¡ Ší¡ Šl¢ Êëâ -À÷x  -x ‡À + +x ‡À @À -Ä €‚À€ÀŠ +Ä €‚À€ÀŠ ÀÁÀÀÀqÀÀÀ € @@ -2118,8 +1477,8 @@ x ‡À €G ÀÀÀ‡ ÀÇ -À1@€@u ‡ - +À1@€€î ‡ +€ # GÀÀÀˆ €\ ˆ ÀÇ È @@ -2128,7 +1487,7 @@ H   - + ÀÁÀÀÀqÀÀ!ÀGÀ` €x Z À@x š @@ -2137,8 +1496,8 @@ H €G ÀÀÀ‡ ÀÇ -Àq€€] š -@Ÿ # GÀÀÀÈ +Àq€ÀÖ š +Àý # GÀÀÀÈ €\ šÀ  È Àˆ @@ -2164,54 +1523,55 @@ GA€ÇÀ` @x €ÀÀ‡ €G  - +  € ÀÀx ÀÀÀÀ -IÀ€“ #  +IÀ  €ˆÀˆ€ÈÀˆ€À€HÀˆÀÀx  €È!€ˆÀÈ#€ÈÀÀ(€HÀˆÀH5€ÈÀÇÀa  € À@x À¢ -‰€ +‰€€Æ #   QLFLˆ€AI€H‚ ‚p "@ȁ CLˆ‚@ -@Lˆ‚@ÈÀ ÀÀ˜ +@Lˆ‚@ÈÀ À@Ø H -a   +a  @å   Œ €G€¡ -É - - -x Ç@‡À  -I€É€ÉÀ €x  - -‡ - - -H -ˆ -È - -€ÇA ÈQ@ -G +É + +@ x +I€É€€Ç@É1 + +‡ + +À¢ +Ë@ +€ˆ² +À +\€ +¢ +@¢ +€ÇA Èa@ +G  €ZÀ` É@È È Ù@  -I@@x @‰€É@ +I@@x @‰€É@ ²  °  ± É @x ‡€ÇÀˆÀ… - + ‡€‡Àa H €  @¡ -Ç -m€­`€@Š +Ç +퀭c€€ß @a J @@ -2221,7 +1581,7 @@ x €Èñ@ a Ö GL€ˆL€Èa H - + €x @d @@ -2245,7 +1605,7 @@ Q R P PC ó€L€ï Àþ J È€ r€ ò€ -ÉÀ +ÉÀ GB€   @@ -2255,25 +1615,53 @@ G Ç@ @x ÇsÀ ‡s€  -  + @ë LÇ! €o - + H -  -‚ǁ €£ -€V -GLÃ@€Hâ - -€ €ÂÀ‚ -€1€À= ‚ +  +LÀ  + +Ç À¥ +@ + +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +Š +À + + “ ±Ä€@ ‡ +€ €ÂÀ‚ +ÆIC +L€¡ +@x GLÃ@€ˆå + + + +F€Âÿ¿Âÿÿƒ0 +€  €x -CtÂ€‚ -.GL®K€.Hâ - -€'~ +CtÂ€‚ +.GL®K€.å + + + Pî P€À£ @@ -2352,7 +1740,7 @@ RÀí P#LGÀï Â. Š ˆ -­`€Z +­c€Z Â. Š €  @@ -2398,18 +1786,27 @@ Z€  ˆXØш‡ ˆPÈH ‘ȈÐ ˆXØ -HØ +HØ *ÅI*€d *AL+CL«Êh jê@ j - -À -2Í ³ ! ±,€ + +(vÀiÀi +ivÀjÀª +ªvÀkÀë +ëvÀlÀ, ,wÀmÀm mwÀnÀ® ®wÀoÀï ïwÀ +A +A@n€)ªv€ˆ +A€n€* ëv€È +AÀn€+°,w€ A +€x 3ÓI³@& +Àx 3ÓI3‚% +2Í ò?€2 Àx 3Á - - + +  @x ȀŠ @@ -2423,7 +1820,7 @@ H ÈÿƒH @p 6 €Õ -@ÿ +@ÿ  % Àx @@ -2434,7 +1831,7 @@ H H È€ x -@ÿ +@ÿ € @¡ I€` €ûx ‰€` @@ -2923,7 +2320,7 @@ HCP €HCX À"@I‡r€ C C @ ‘I‡r€ C C 3€ -C C B LˆCH +C C B LˆCH € @¡ I€` €ûx ‰€` @@ -3411,495 +2808,7 @@ HCP €HCX À"@I‡r€ C C @ ‘I‡r€ C C 3€ -C C B LˆCH - € @¡ -I€` -€ûx ‰€` -Àìx " -@}x - -À)LÇ G@c -G€Ð" - - À  -‡)€ÈÀ` -Ç -€À` -€+y -& & &  -H@o @ -À - -À J -À Š - - -¢@ÇA€ɑ -G -G -G - -È - -! `% Éÿƒ#LB0  -Ç! I -& €÷ & H€€b - - -# -H - - - -& & & Àå & ‡ - -H -!  -H - -Ç! È -& ÀÎx -H - -€ - - - - -GIŠ‚  -ÂO -I@ -I À  - -€o -I@ -=LŠ¢€ʀï -ŽI - € É€‰Rp -Ž  - À -Ž P$ - - -¢€ - € - -LJ£€ - €õ - - - € ”€  ÀÀȁ -ȁ -ȁ -ȁ -ȁ -ÀÀ¢h -ÀÀG‚@ÀÀG‚@ ÒM -ÀÀb£ -€ö G -‡ -Šƒ¯ - -ì -Ja - - -b - - -€x - - -x -À ÀáÀÇ - -‡ -À ÀÀ - - - -€ÀÀÀAÀGÀ  - -ú€Jú€ÀÀ@¡ - -À - -@ÀÀ€¢ - - -ÀÀjx -QLFLÈ€A‰€H‚ -‚p ¢@ȁ -CLˆ‚@ -@Lˆ‚@ÀHÀG€Ç -À`x Çñ -@]x ò - -a   -€Fx Ç€@b - € -€Sx -È€@¡ -Èÿ¿9 €x 8  - -Ȉ -@(x -‡ -€ x Ç@‡À  -I€É€ÉÀ -x ÈI@¡ -Ç€r€ÇÀ - -H -ˆ -È -Ç€G€  -  -€ÇA ÈQ@ -G -É@H -ȁß@‰ -I@@x ‰@‰€É@‡ -²  -°  -± É€IÀ  -É - €` - - - - €¡ - -G - €  -À¡ -É€ À` -Ç - €¡ -G€G€b -m6€ -m\€‡À  --m€íN€LǁÁ @3 -„À G€À` - -À x Ç"€À  - -€ÀÀG.ÀÀ¶ -€ x -È €r@È€"€ -ÇÀÀÀ -À· -%€GÀ  -‡ - -€x À H - - - - -Àx -€$Â` -€«~ -* Ij@ï -ꠂ ê Â š)€(À` -*AÑ꧂ * * I* ‚ * * Â *¥‚ j¥‚ ª¥‚ è €èÀ  -) -š€é€) - - - - -€Fx - €a - -J* J* è€h - -* )šÂJ Š - ÚÀ)À  - - À` -€:x - -Ç€GÀ  -@x -x -Ï! Ç1 -" €¢ -Ï! ÒÀÇ1 -Ï! Ç1 -Ï! Ç1 -€€@€ -@x *€H*€ €À& -À -x -@€€€ˆ -Q -€H€ €@ -Q -Q -Q -GÀ¡ -Ç$€G@¢ -L -L - - -Ç€G@£ -G€‡À  -H - -\ PPCÇñ€G€ï - -ðJ’@È"  -À` - - -K! @Ž -À` - - -K! @Ž - -@x -`­ Ç - ¯  -À„ˆÀ -I -@  - - ® Ç - - -šêÿŸ( ( -€GÀ Ç - -À x –€À¢ -–@–ÀÖ€–@#L - -–¡¡WÀ  -–€¡ ¡À×ÿƒ×@@! NU  - -Ö€€¡ -–@V -ÀÀ@c -ÀÀÀc -€ÀÀ -G€€x ‡€ - -‡ -2@ -Áb -I€‡ €G‚p Ç €G‚` NGÀï -G  -€x ‹ €ËÀ  Àÿ Ë2@É €ÉÀ  Àÿ I2@ @a -É€ À  -€ -x I€‡ €G‚p Ç €G‚` K"\ GX  NIÀï À€ -É -É -I -É -@¢ -Çx -Çx - -À¢ -Çx - €° -À¡ -K - - -Çx - €° - À°ˆB@‡r -Ç%€" Ç! Ç1@‡F! Ç -‡ -H - -À x  -Ç€€  -Àx ‡"€À  -H"€ÀÀ€¢ -#€ -"€ -G - -G€‡€a -‡ - - -Ç"€ -À  - -G€‡@c -G€€¢ - -Ä` @ÿ  -@x -€ˆ,À -È1 ‡€c -ÈA  -H - À` - - - -@x )€€¢ - - -H - --€À  - - @¢ -ˆ€È&ÀH&€H   - -G€G@c - -€ˆ,À - - @b - -GÀÀÀÀ -`€  -€Rx )€€¢ - - -H - -€ - - -ˆ -H -G€GÀ¢ -ˆ - -ˆ -ÀÀ€e -ˆ -È -H - -ˆ -È - - -ˆ -H -È - -ˆ -È - - - - -‡€` -À x   -@x @x - -x ! Àe J -‡ - -È€ - - -€ - -ÀÀ@b -ˆ -È -H - -ˆ -H - -‡ -Àò - - - - -G$€ - - -G - - -€, -  -ˆ€‰,€I‚ -  -H$€€a -È €È - - -` - À  - - -` - -  - -  -` -À  - -` -  - -I - - -Ç - -H - -H -GÀ  -ˆ -È€ˆ€ˆ(ÀÇ#€@£ - -ǂ¢ - -H&€ȁ -Gt€ GtÀ -(»I(Ê *SIª - - - - - - -+ @x ,‘ + € -`À  - -HØH€@f -ˆ€@¢ -‡ÀŠ -Ј -ˆˆG@€ -ˆÐHPˆ€x Ȉ‡À¢ -ÈHH -ˆÐˆˆ€ -HØ%€HÀ¡ -HPˆGÀ¢ -ˆÈHH -ˆÐHPˆ€ -@€Š - -HC@ €Çr€ -HCH €C€ -HCP €HCX À"@I‡r€ -C -C 3€ -C C @ ‘I‡r€ -C -C 3€ -C C B LˆCH +C C B LˆCH € @¡ I€` €ûx ‰€` @@ -4387,495 +3296,7 @@ HCP €HCX À"@I‡r€ C C @ ‘I‡r€ C C 3€ -C C B LˆCH - € @¡ -I€` -€ûx ‰€` -Àìx " -@}x - -À)LÇ G@c -G€Ð" - - À  -‡)€ÈÀ` -Ç -€À` -€+y -& & &  -H@o @ -À - -À J -À Š - - -¢@ÇA€ɑ -G -G -G - -È - -! `% Éÿƒ#LB0  -Ç! I -& €÷ & H€€b - - -# -H - - - -& & & Àå & ‡ - -H -!  -H - -Ç! È -& ÀÎx -H - -€ - - - - -GIŠ‚  -ÂO -I@ -I À  - -€o -I@ -=LŠ¢€ʀï -ŽI - € É€‰Rp -Ž  - À -Ž P$ - - -¢€ - € - -LJ£€ - €õ - - - € ”€  ÀÀȁ -ȁ -ȁ -ȁ -ȁ -ÀÀ¢h -ÀÀG‚@ÀÀG‚@ ÒM -ÀÀb£ -€ö G -‡ -Šƒ¯ - -ì -Ja - - -b - - -€x - - -x -À ÀáÀÇ - -‡ -À ÀÀ - - - -€ÀÀÀAÀGÀ  - -ú€Jú€ÀÀ@¡ - -À - -@ÀÀ€¢ - - -ÀÀjx -QLFLÈ€A‰€H‚ -‚p ¢@ȁ -CLˆ‚@ -@Lˆ‚@ÀHÀG€Ç -À`x Çñ -@]x ò - -a   -€Fx Ç€@b - € -€Sx -È€@¡ -Èÿ¿9 €x 8  - -Ȉ -@(x -‡ -€ x Ç@‡À  -I€É€ÉÀ -x ÈI@¡ -Ç€r€ÇÀ - -H -ˆ -È -Ç€G€  -  -€ÇA ÈQ@ -G -É@H -ȁß@‰ -I@@x ‰@‰€É@‡ -²  -°  -± É€IÀ  -É - €` - - - - €¡ - -G - €  -À¡ -É€ À` -Ç - €¡ -G€G€b -m6€ -m\€‡À  --m€íN€LǁÁ @3 -„À G€À` - -À x Ç"€À  - -€ÀÀG.ÀÀ¶ -€ x -È €r@È€"€ -ÇÀÀÀ -À· -%€GÀ  -‡ - -€x À H - - - - -Àx -€$Â` -€«~ -* Ij@ï -ꠂ ê Â š)€(À` -*AÑ꧂ * * I* ‚ * * Â *¥‚ j¥‚ ª¥‚ è €èÀ  -) -š€é€) - - - - -€Fx - €a - -J* J* è€h - -* )šÂJ Š - ÚÀ)À  - - À` -€:x - -Ç€GÀ  -@x -x -Ï! Ç1 -" €¢ -Ï! ÒÀÇ1 -Ï! Ç1 -Ï! Ç1 -€€@€ -@x *€H*€ €À& -À -x -@€€€ˆ -Q -€H€ €@ -Q -Q -Q -GÀ¡ -Ç$€G@¢ -L -L - - -Ç€G@£ -G€‡À  -H - -\ PPCÇñ€G€ï - -ðJ’@È"  -À` - - -K! @Ž -À` - - -K! @Ž - -@x -`­ Ç - ¯  -À„ˆÀ -I -@  - - ® Ç - - -šêÿŸ( ( -€GÀ Ç - -À x –€À¢ -–@–ÀÖ€–@#L - -–¡¡WÀ  -–€¡ ¡À×ÿƒ×@@! NU  - -Ö€€¡ -–@V -ÀÀ@c -ÀÀÀc -€ÀÀ -G€€x ‡€ - -‡ -2@ -Áb -I€‡ €G‚p Ç €G‚` NGÀï -G  -€x ‹ €ËÀ  Àÿ Ë2@É €ÉÀ  Àÿ I2@ @a -É€ À  -€ -x I€‡ €G‚p Ç €G‚` K"\ GX  NIÀï À€ -É -É -I -É -@¢ -Çx -Çx - -À¢ -Çx - €° -À¡ -K - - -Çx - €° - À°ˆB@‡r -Ç%€" Ç! Ç1@‡F! Ç -‡ -H - -À x  -Ç€€  -Àx ‡"€À  -H"€ÀÀ€¢ -#€ -"€ -G - -G€‡€a -‡ - - -Ç"€ -À  - -G€‡@c -G€€¢ - -Ä` @ÿ  -@x -€ˆ,À -È1 ‡€c -ÈA  -H - À` - - - -@x )€€¢ - - -H - --€À  - - @¢ -ˆ€È&ÀH&€H   - -G€G@c - -€ˆ,À - - @b - -GÀÀÀÀ -`€  -€Rx )€€¢ - - -H - -€ - - -ˆ -H -G€GÀ¢ -ˆ - -ˆ -ÀÀ€e -ˆ -È -H - -ˆ -È - - -ˆ -H -È - -ˆ -È - - - - -‡€` -À x   -@x @x - -x ! Àe J -‡ - -È€ - - -€ - -ÀÀ@b -ˆ -È -H - -ˆ -H - -‡ -Àò - - - - -G$€ - - -G - - -€, -  -ˆ€‰,€I‚ -  -H$€€a -È €È - - -` - À  - - -` - -  - -  -` -À  - -` -  - -I - - -Ç - -H - -H -GÀ  -ˆ -È€ˆ€ˆ(ÀÇ#€@£ - -ǂ¢ - -H&€ȁ -Gt€ GtÀ -(»I(Ê *SIª - - - - - - -+ @x ,‘ + € -`À  - -HØH€@f -ˆ€@¢ -‡ÀŠ -Ј -ˆˆG@€ -ˆÐHPˆ€x Ȉ‡À¢ -ÈHH -ˆÐˆˆ€ -HØ%€HÀ¡ -HPˆGÀ¢ -ˆÈHH -ˆÐHPˆ€ -@€Š - -HC@ €Çr€ -HCH €C€ -HCP €HCX À"@I‡r€ -C -C 3€ -C C @ ‘I‡r€ -C -C 3€ -C C B LˆCH +C C B LˆCH ÈIÀð v¢ Gö  @@ -4968,7 +3389,7 @@ U T%H @IDÁï T%H @IDÁï T%H @IDÁï -U +U ÈI@õ v¢ Gö  @@ -5070,7 +3491,7 @@ U T%H @IDÁï T%H @IDÁï T%H @IDÁï -U +U ÈIÀó v¢ @@ -5165,7 +3586,7 @@ U T%H @IDÁï T%H @IDÁï T%H @IDÁï -U +U ÈI@ø v¢ @@ -5269,15 +3690,8 @@ U T%H @IDÁï T%H @IDÁï T%H @IDÁï -U - - - - - - - - +U + € x B<¡  £ @@ -5287,14 +3701,13 @@ C Ã#€ -€Â0€ ›€à - + ɑÀ @}z IÀ -GLÊÿ - -ˆ +GLÊÿ + -@Rx  - +ÀRx  +€Tx ‚à Àý € @@ -5308,7 +3721,7 @@ GLÊÿ GIŠ‚ È,€ ÂO -I@ +I@ I À  €o @@ -5337,7 +3750,7 @@ J  € LJ£€ - ª € + ª €À™ k   @x €R @@ -5347,8 +3760,8 @@ J @x J€ Áe ˆ€B€ €Àa -Àx H -€€: +@ x H +€ H ÀÇñ ÀG£ G@£ ‡Á` @@ -5357,9 +3770,9 @@ G@£ x x }‚G‚` -@x +@x €x QL -FL @LBLȂ@‚ +FL @LBLȂ@‚ G @@ -5368,17 +3781,17 @@ G - +  -Ó t - +Ó t + -  +  ÉIJÀ ÄIʁ À - + LÊ¥€ @@ -5392,15 +3805,15 @@ G € -GÀ +GÀ -GÀ€€I +GÀ€€I ÂI Àd  €Â` - - + + Õ)€ÙIÅ ”$€”@¥ ”  @@ -5443,18 +3856,23 @@ U@%ÀÕ$€U@Àx Õ$À&€Ö)€• Àý Êÿƒ Š@@x -N N N@ -  +N N NN@ +  À  @ÿ @Èÿƒ II24 ÉA"  - Iɐ€ ɐÀ Àý @ I € ‰€  À ‰À  + Iɐ€ ɐÀ Àý @ I € ‰€  À ‰À  + +€ÿ Éÿƒ»I SIÇ À  - -Ç +@þ I@ +œIò + @o +Ç@ +I -K -K +K +K <€ À` € x J @@ -5479,36 +3897,37 @@ G€4€ Š,€Š@ I Ç,À@Ȅ@ -ÀÇ,€€¡ -Ç@Ç  Àÿ ÇÁA+ÀÇ,€‡À-€ÇÀ -€ +Ç@Ç  Àÿ ÇÁA+ÀÇ,€‡À-€ÇÀ +@ + # <À€  # ÇAª €ª GÀª ÇÀÈ;€H É-À% <€€  -@ ÏIÉÀ +€ ÏIÉÀ ‡À¢ -@  €H¢ +€  €H¢ H€@a ‡€  -À H - + + È;€I - + -GÀǑ@Ê¡ +GÀǑ@Ê¡ -GÀH;€È¡@Ê¡ - +GÀH;€È¡@Ê¡ + -GÀ @€ @° +GÀ @€ @°@À ÀŒ -GÀ €  °€Å +GÀ €  °ÀŸ -GÀ @€ À° +GÀ @€ À°@Œ -GÀ À€€Á @°È €È€ +GÀ À€Àº @°È €È€ ÏIÊÀå Ê;€ Bå €JÁ€ @@ -5517,49 +3936,49 @@ J€‡ J9€ @b Ê;€ -Âá +Âá É - + ‡!€Ç€ˆs€À‡sÀÇt€GÀ €Ç@b - + Gu€ÀÇu€GÀ - + €Ç@b - -x + +x  -À×~  - - +€Ñ~  + +ÀÎ~ ª Ào - +  H $€ɀ¢ -Š@Š€I‡p€ Çp€  QIÇs€ Q Ê#ÀG)€É!D G)À‡ƒc -É +Š@Š€I‡p€ Çp€  QIÇs€ Q Ê#ÀG)€É!D G)À‡ƒd +É šP‚Ú‚È;€È! ‡€¡ ‡ - - - - - + + + + +À±~  - + G,€ÇÂ" Ç,€@a -QI†À À +QI†À À ­ Q ?€ R - + ÈŒo @@ -5573,8 +3992,7 @@ R €x ,Á Àø *ÖI - - Ëò@ c@ÇrÀ + G#€ ‡#€ ÀqÀ@) ‡#€‡q€ Çs€  @@ -5637,17 +4055,17 @@ G$€‡)À Ê -(€ +(€ % & &   GÀ   ¢ SÀ& -@\ +@d À¡ Š*€ À  ‰$€ @o -É&€I@€b É&À@x €ˆ*€ €H"P ! & ‡%À‡À  Ç +É&€I@€j É&À@x €ˆ*€ €H"P ! & ‡%À‡À  Ç Ç Ê,€‡£ @@ -5674,566 +4092,14 @@ R P  -€L@ã L+€Ì" €¢ Ë@ #\ Àa L+ÀLÀ - €° À° - -€x Ç,€Ç -ÉI - € -É Ç,€DŽP -€Ʉ@ € @¡ -I@ À` - ÀÀø~ I,€‰D €€‡b -@x --€JÀ -Š - +€-€GÀ% -É! - --€JÀ+ -‡ -€x  -É! - +€É -€’€Ëÿ¿! - - -€€€‹@Š - ãa  $a    '   -    N,€Ž€ -Ç?€G)€‡Ã¡ -Ç,€Ç@Ç  Àÿ ÇÁA+À -+€Ç?a Ç  ÇÁA+ÀPCÇñ€G€ï - -‡ -€ó Š+À€€ȁ -@x -I€ -x - Àx £À# Ì@d -L€ C@ “ÀÀ  S - €x ³À# Ì -L€ C@ “À€  S @x ³ÀC C@ “ÀS - - - - -L€ C@ “ÀÀþ S - ³À‡ €‡€¢ - -  ‚ ‰C@$€Ç -À - -ÊߏÊÿüNˆ‚€‡ LJ’À -J2€ Àx ˆ†€ Š -Š@Ȇ€ - -‡‚0 -À` -Š - -€v~ - À€j # LJ @t~  - - - - ¡ -r€€  -@c~ G@Q -þ I -“ - -€ -€x H@ÀÀB H@ -Q -Q - -Q - -GÀÀÁG@Q -‡@ À - ˆ/ÀÀÀÀ¡ -‡B - ˆ/À‡/€G@Q - -ˆ€ÀÀ€' # G@Q - -Ç;€p€ Ç;À - -GÀС@Ê¡ - -G@€@!x Ñ - - -G -!ÀI@‰ -R ‰B@ˆÂh - H -H:À  ÈB G)ÀÍ  -Ç@!€ÈD #À‡ -G -G -Ç ÀG -GB G -G -@õ} -€x Q - -Ç;€Gp€ Ç;À - -GÀБ@Ê¡ - - ;ÀR` G)€"j ! É Ç(ÀÉ! )ÀI - - -€ €‰Á  ̀̀ @€ - -ÌÏ  -‰Aa Ìa -€÷ à€ ‹ - @G€É1€ -N -£ -É¡ I - - -€ €‰Á  ̀̀ @£ -G -ÌÏ  -‰Aa Ìa -@÷ à€ ‹ - @ÉÁ  - - - -@x  € - - - -H€ƒ - -t€@d # ÇsÀRP @c # tÀR` G)€"j ! Ç - - - -B @\ # BH €[ # BP B À€@ À És€؀@ À t€Àx -Çs€ - -B €R # BH ÀQ # BP B À€@  - €H€¢‚ - - ဉ -a  -G@GA® -I -I - -‡ €‡@¢ - €ÀD # "@ -Àx ‡ €ˆ€B€ -ö€€ - -GÀ À€@ @ €? #  - -G"@ À; # @= - -€ x -B<¡ - £ -@ý  -?À -C -Ã#€ --€Â0€ -›€à - -ɑÀ -GLÊÿ - -ˆ - -@Rx  - -€ - - - - -) À - - J@À -  J„ -. 8  - -GIŠ‚ È,€ -ÂO -I@ -I À  - -€o -I@ -=LŠ¢€ʀï -ŽI - € É€‰bp -Ž  - À -Ž 4ÈI -­ -Q R P PC ó€L€ï - -­@JŠ -A -A - Ê&À -%ÀÊ€ -(À -\€ -! p! Š - -J - -¢€ - € - -LJ£€ - ª € - -   -@x €R -ÉÀa -ˆ€¢A -€ -@x J€ Áe -ˆ€B€ -€Àa -Àx H -€À9 - H ÀÇñ ÀG£ -G@£ -‡Á` -€ x ǂÇÁ` -À -x - -x }‚G‚` -@x - QL -FL @LBLȂ@‚ - -G - - -Ç€Èq@ - - - - -  -Ó t - - - -  -ÉIJÀ -ÄIʁ -À - - - -ÉB@Ȃ - - - - - - -€ - -GÀ - -GÀ€€I -ÂI -Àd - -€Â` - - -”$€”@¥ -”  -@.x - - -W(€¥ -Ô*€e@-€U€UÀà  - \€! €x U@-€UÀà  -¢VÀ  -À¢Á¢ -@ÀÔ€TeP W| NÔB  -”E”E@ -B€VÀ¢ -@€@x A€Հe -Ô&€ N– ”EŽ -ÀÀÔ€TeP W| NÔB  -U@%ÀÕ$€U@Àx Õ$À&€Ö)€• -b±VÀ  -`±a±V0€À¢ -Ô&€ N– ”U€ 'À”€@Õ ”$À -Àó Õ&€U - -Õ$€€` - - - -… - u V,€”¥‚ ”E -@ - -• -B¡Á  -@¡A¡€À Ç  -Àò ”&€•@@ -ÔAÁ Ô -Àý Êÿƒ - -Š@@x -N N N@ -  -À  -@ÿ @Èÿƒ II24 ÉA" - - Iɐ€ ɐÀ Àý @ I € ‰€  À ‰À  - -€ÿ Éÿƒ»I SIÇ - À  -@þ I@ -I - -K -K -<€ -À` -€ x J -€  -€ x ÏIǀ! -<€À  -J - -Àx J -€x J -G2€ -H"€ -À - -‡€È€2€ -€x J -€Ç3@ -G€4€ -€ -@x ‡.ÀI,€J)€ -Ã` -Š,€Š@ -I -Ç,À@Ȅ@ -ÀÇ,€€¡ -Ç@Ç  Àÿ ÇÁA+ÀÇ,€‡À-€ÇÀ -€  -€ª -GÀª -ÇÀÈ;€H É-À% -<€€  -@ ÏIÉÀ -‡À¢ -@  €H¢ -H€@a -‡€  -À H - -È;€I - - - - -GÀǑ@Ê¡ - -GÀH;€È¡@Ê¡ - - -GÀ @€ @° -ÀŒ -GÀ €  °€È - -GÀ @€ À° - -GÀ À€€Ä @°È €È€ -ÏIÊÀå Ê;€ -Bå - €JÁ€ -J€‡ -Š -J9€ -@b -Ê;€ -Âá -É - - -‡!€Ç€ˆs€À‡sÀÇt€GÀ -€Ç@b - -Gu€ÀÇu€GÀ - -€Ç@b - -x - - -ÀÚ~  - - -Ào - - -H - $€ɀ¢ -Š@Š€I‡p€ Çp€  QIÇs€ Q Ê#ÀG)€É!D G)À‡ƒd -É -šP‚Ú‚È;€È! ‡€¡ -‡ - - - - - - - - -G,€ÇÂ" Ç,€@a -QI†À À -­ - -Q -?€ -R - - -ÈŒo - - -Ë@‡ - GÀ  - ¢ - -À -+× ì -! ê*€ -€x ,Á -Àø -*ÖI - - G#€ -‡#€ - ÀqÀ@) ‡#€‡q€ Çs€  - ÇsÀ ‡s€ - ˆ'€ -LÇ! €o -!*€! -G)€ €‡ƒ¡ -É)À‰€É)À€Wx  @Ix €‡ƒ¡ -É)À‰€É)À@%x  À x -G)€ €‡ƒ¡ -É)À‰€É)ÀÀOx  €Ax €‡ƒ¡ -É)À‰€É)À€x   -G$€‡)À - - -Š$€ -@o -Ê -€  - -' €x   'LI! & ' ( ) ˆ)€ a '   'LI!      H$€ a '   CIÀï #€ÇÀx % Èÿƒ> ?LÇ> @¯ -#LGB0 À  -@î -@ -*€ - -ÊÀ  - @o -I@Ê -(€‡(À#LB0 €o - - ÇA ÈR K€ À  -(À@x GBŠ -% ‡BŠ -Gƒ¥ -HÀ¡ -‡ƒ¥ -À` -Àx -‰ - -É -À&x I*À‡  -S@ï ËÿƒÈ&€ NI HB€ À  -Àþ Ë@ˆ - NË @o - @ NË @n -‹$€ Àm - -G$€‡)À - -'    -' €x   'LI! & ' ˆ)€ a '   'LI!   H$€ a '  #€ÇÃ% Š$€ -Ào -Ê -!L"L%'L e! Ç,€€a -*€ -Š$€ʀ  - - -Ê -(€ -% & & & ÇÀr€ ! G%€@¡ - GÀ  - ¢ -SÀ& -€Z -À¡ -Š*€ -À  -‰$€ @o -É&€I@À` É&À@x €ˆ*€ €H"P ! & ‡%À‡À  Ç -Ç - -Ê,€‡£ -Ê --€Àx ‹òB - -G¡ - --€JÀ -ÉFa - - -€ -+ÀˆD - - -Ç  -@x - €  À  -­ -Q -?€ -R P  - -€L@ã L+€Ì" €¢ -Ë@ #\ Àa -L+ÀLÀ - €° À°@. + €° À° €x Ç,€Ç ÉI  € É Ç,€DŽP -€Ʉ@ € @¡ I@ À` - À + ÀÀÿ~ I,€‰D €€‡b @x -€JÀ Š @@ -6242,9 +4108,9 @@ I@ À` -€JÀ+ ‡ -€x  +€x  É! - +€É + +€É ‡ €‡@a x @@ -6266,7 +4132,7 @@ x +€Ç?a Ç  ÇÁA+ÀPCÇñ€G€ï  ‡ -€ó Š+À€€ȁ +€ó Š+À€€ȁ ÊߏÊÿüNˆ‚€‡ LJ’À J2€ Àx ˆ†€ Š Š@Ȇ€ @@ -6274,39 +4140,39 @@ J2€ Àx ˆ†€ Š ‡‚0 À` Š - -€v~ - À€j # LJ @t~  - + +@w~ + ÀÀj # LJ +  - +  ¡ r€€  -@c~ G@Q -þ I -“ +€c~ ‡ +þ I +“ -€ +€@E # G@Hÿ Q €x H@ÀÀB H@ Q Q Q - +@5 # À4 # ÀÀG@Q GÀÀÁG@Q -‡@ +‡@ À ˆ/ÀÀÀÀ¡ -‡B @‰ +‡B ˆ/À‡/€G@Q -ˆ€ÀÀ€' # G@Q +ˆ€ÀÀÀ' # G@Q Ç;€p€ Ç;À -GÀС@Ê¡ +GÀС@Ê¡ G@€@!x Ñ - +  G !ÀI@‰ @@ -6318,19 +4184,19 @@ G G Ç ÀG GB G -G -@õ} +G + €x Q - + Ç;€Gp€ Ç;À -GÀБ@Ê¡ +GÀБ@Ê¡  - ;ÀR` G)€"j ! É Ç(ÀÉ! )ÀI - + ;ÀR` G)€"j ! É Ç(ÀÉ! )ÀI + € €‰Á  ̀̀ @€ - + ÌÏ  ‰Aa Ìa €÷ à€ ‹ @@ -6341,45 +4207,52 @@ GÀБ@Ê¡  € €‰Á  ̀̀ @£ -G +G ÌÏ  ‰Aa Ìa @÷ à€ ‹ - @ÉÁ  - + @ÉÁ  + - + @x  € - + - + H€ƒ -t€@d # ÇsÀRP @c # tÀR` G)€"j ! Ç - - +t€€d # ÇsÀRP €c # tÀR` G)€"j ! Ç + +  -B @\ # BH €[ # BP B À€@ À És€؀@ À t€Àx -Çs€ - -B €R # BH ÀQ # BP B À€@  +B €\ # BH À[ # BP B À€@ @! És€؀@ @  t€Àx +Çs€@W # ÇsÀRP G)€"j ! Ç + +B ÀR # BH  €H€¢‚ ဉ -a  +a  G@GA® -I -I +I +I  ‡ €‡@¢ - €ÀD # "@ + € @x ‡ €ˆ€"@ ö€ -GÀ À€À @  - -G"@ @< # À= - +GÀ À€ + +G"@ €< #  + + + + + + + + € x B<¡  £ @@ -6389,14 +4262,13 @@ C Ã#€ -€Â0€ ›€à - + ɑÀ @}z IÀ -GLÊÿ - -ˆ +GLÊÿ + -@Rx  - +ÀRx  +€Tx ‚à Àý € @@ -6410,7 +4282,7 @@ GLÊÿ GIŠ‚ È,€ ÂO -I@ +I@ I À  €o @@ -6439,7 +4311,7 @@ J  € LJ£€ - ª € + ª €   @x €R @@ -6449,8 +4321,8 @@ J @x J€ Áe ˆ€B€ €Àa -Àx H -€€: +@ x H +€ H ÀÇñ ÀG£ G@£ ‡Á` @@ -6459,9 +4331,9 @@ G@£ x x }‚G‚` -@x +@x €x @üx QL -FL @LBLȂ@‚ +FL @LBLȂ@‚ G @@ -6470,17 +4342,17 @@ G - +  -Ó t - +Ó t + -  +  ÉIJÀ ÄIʁ À - + LÊ¥€ @@ -6494,15 +4366,15 @@ G € -GÀ +GÀ -GÀ€€I +GÀ€€I ÂI Àd  €Â` - - + + Õ)€ÙIÅ ”$€”@¥ ”  @@ -6545,18 +4417,21 @@ U@%ÀÕ$€U@Àx Õ$À&€Ö)€• Àý Êÿƒ Š@@x -N N N@ -  +N N NN@ +  À  @ÿ @Èÿƒ II24 ÉA"  Iɐ€ ɐÀ Àý @ I € ‰€  À ‰À  À  - -Ç + +œIò + @o +Ç@ +Ç -K -K +K +K <€ À` € x J @@ -6581,36 +4456,36 @@ G€4€ Š,€Š@ I Ç,À@Ȅ@ -ÀÇ,€€¡ -Ç@Ç  Àÿ ÇÁA+ÀÇ,€‡À-€ÇÀ -€ +Ç@Ç  Àÿ ÇÁA+ÀÇ,€‡À-€ÇÀ + €ª GÀª ÇÀÈ;€H É-À% <€€  -@ ÏIÉÀ +@ ÏIÉÀ ‡À¢ -@  €H¢ +@  €H¢ H€@a ‡€  -À H - +À H + È;€I - + -GÀǑ@Ê¡ +GÀǑ@Ê¡ -GÀH;€È¡@Ê¡ - +GÀH;€È¡@Ê¡ + -GÀ @€ @° +GÀ @€ @° ÀŒ -GÀ €  °€Å +GÀ €  °€Á -GÀ @€ À° +GÀ @€ À° -GÀ À€€Á @°È €È€ +GÀ À€€œ @°È €È€ ÏIÊÀå Ê;€ Bå €JÁ€ @@ -6619,25 +4494,25 @@ J€‡ J9€ @b Ê;€ -Âá +Âá É - + ‡!€Ç€ˆs€À‡sÀÇt€GÀ €Ç@b - + Gu€ÀÇu€GÀ - + €Ç@b - + x  -À×~  - - +@Ô~  + +€Ñ~ ª Ào - +  H $€ɀ¢ @@ -6645,23 +4520,23 @@ H É šP‚Ú‚È;€È! ‡€¡ ‡ - - - - - + + + + +€µ~  - + G,€ÇÂ" Ç,€@a -QI†À À +QI†À À ­ Q ?€ R - + ÈŒo @@ -6676,7 +4551,7 @@ R Àø *ÖI - Ëò@ c@ÇrÀ + Ëò@ c@ÇrÀ G#€ ‡#€ ÀqÀ@) ‡#€‡q€ Çs€  @@ -6739,17 +4614,17 @@ G$€‡)À Ê -(€ +(€ % & &   GÀ   ¢ SÀ& -@\ +€` À¡ Š*€ À  ‰$€ @o -É&€I@€b É&À@x €ˆ*€ €H"P ! & ‡%À‡À  Ç +É&€I@Àf É&À@x €ˆ*€ €H"P ! & ‡%À‡À  Ç Ç Ê,€‡£ @@ -6776,14 +4651,14 @@ R P  -€L@ã L+€Ì" €¢ Ë@ #\ Àa L+ÀLÀ - €° À° + €° À°@4 -€x Ç,€Ç +€x Ç,€Ç ÉI  € É Ç,€DŽP -€Ʉ@ € @¡ I@ À` - ÀÀø~ I,€‰D €€‡b + À @x -€JÀ Š @@ -6792,9 +4667,9 @@ I@ À` -€JÀ+ ‡ -€x  +€x  É! - +€É + +€É €’€Ëÿ¿! @@ -6807,18 +4682,18 @@ I@ À`  ‡ €ó Š+À€€ȁ -@x -I€ -x +@x +I€@ S +x Àx £À# Ì@d -L€ C@ “ÀÀ  S +L€ C@ “À €x ³À# Ì -L€ C@ “À€  S @x ³ÀC C@ “ÀS - - +L€ C@ “ÀÀ  S @x ³ÀC C@ “ÀS + @  GS @x ³ÀC C@ “ÀS @  GS ³À €f + -L€ C@ “ÀÀþ S +L€ C@ “À ³À‡ €‡€¢   ‚ ‰C@$€Ç @@ -6831,36 +4706,36 @@ J2€ Àx ˆ†€ Š ‡‚0 À` Š - -€v~ - À€j # LJ @t~  - + +@w~ + ÀÀj # LJ +  - +  ¡ r€€  -@c~ G@Q -þ I -“ +€c~ ‡ +þ I +“ -€ +€@E # G@Hÿ Q €x H@ÀÀB H@ Q Q Q - +@5 # À4 # ÀÀG@Q GÀÀÁG@Q ‡@ À ˆ/ÀÀÀÀ¡ ‡B ˆ/À‡/€G@Q -ˆ€ÀÀ€' # G@Q +ˆ€ÀÀÀ' # G@Q Ç;€p€ Ç;À -GÀС@Ê¡ +GÀС@Ê¡ G@€@!x Ñ  @@ -6875,19 +4750,19 @@ G G Ç ÀG GB G -G -@õ} +G + €x Q - + Ç;€Gp€ Ç;À -GÀБ@Ê¡ +GÀБ@Ê¡  - ;ÀR` G)€"j ! É Ç(ÀÉ! )ÀI - + ;ÀR` G)€"j ! É Ç(ÀÉ! )ÀI + € €‰Á  ̀̀ @€ - + ÌÏ  ‰Aa Ìa €÷ à€ ‹ @@ -6898,46 +4773,45 @@ GÀБ@Ê¡  € €‰Á  ̀̀ @£ -G +G ÌÏ  ‰Aa Ìa @÷ à€ ‹ - @ÉÁ  - + @ÉÁ  + - + @x  € - + - + H€ƒ -t€@d # ÇsÀRP @c # tÀR` G)€"j ! Ç - - +t€€d # ÇsÀRP €c # tÀR` G)€"j ! Ç + +  -B @\ # BH €[ # BP B À€@ À És€؀@ À t€Àx -Çs€ - -B €R # BH ÀQ # BP B À€@  +B €\ # BH À[ # BP B À€@ € És€؀@ € t€Àx +Çs€@W # ÇsÀRP G)€"j ! Ç + +B ÀR # BH  €H€¢‚ ဉ -a  +a  G@GA® -I -I +I +I  ‡ €‡@¢ - €ÀD # "@ + € Àx ‡ €ˆ€B€ ö€€ -GÀ À€@ @ €? #  - -G"@ À; # @= -gxm_h264_multi.bin - +GÀ À€€ @ À? # @A + +G"@ + € x B<¡  £ @@ -6947,14 +4821,13 @@ C Ã#€ -€Â0€ ›€à - + ɑÀ -GLÊÿ - -ˆ +GLÊÿ + -@Rx  - +ÀRx  +€Tx ‚à Àý € @@ -6968,7 +4841,7 @@ GLÊÿ GIŠ‚ È,€ ÂO -I@ +I@ I À  €o @@ -6997,7 +4870,7 @@ J  € LJ£€ - ª €À k + ª €€“ k   @x €R @@ -7007,8 +4880,8 @@ J @x J€ Áe ˆ€B€ €Àa -Àx H -€€: +@ x H +€@: H ÀÇñ ÀG£ G@£ ‡Á` @@ -7017,9 +4890,9 @@ G@£ x x }‚G‚` -@x +@x €x Àøx QL -FL @LBLȂ@‚ +FL @LBLȂ@‚ G @@ -7028,21 +4901,19 @@ G - +  -Ó t - +Ó t + -  +  ÉIJÀ ÄIʁ À - + - -LÊ¥€ - % + ÉB@Ȃ @@ -7052,14 +4923,14 @@ G € -GÀ +GÀ -GÀ€€I +GÀ€€I ÂI Àd  €Â` - + ”$€”@¥ ”  @@ -7100,7 +4971,7 @@ U@%ÀÕ$€U@Àx Õ$À&€Ö)€• Š@@x N N N@ -  +  À  @ÿ @Èÿƒ II24 ÉA"  @@ -7108,11 +4979,14 @@ U@%ÀÕ$€U@Àx Õ$À&€Ö)€• €ÿ Éÿƒ»I SIÇ À  -@þ I@ -I +@þ I@ +œIò + @o +Ç@ +I -K -K +K +K <€ À` € x J @@ -7137,36 +5011,36 @@ G€4€ Š,€Š@ I Ç,À@Ȅ@ -ÀÇ,€€¡ -Ç@Ç  Àÿ ÇÁA+ÀÇ,€‡À-€ÇÀ -À +Ç@Ç  Àÿ ÇÁA+ÀÇ,€‡À-€ÇÀ +€ €ª GÀª ÇÀÈ;€H É-À% <€€  -€ ÏIÉÀ +À ÏIÉÀ ‡À¢ -€  €H¢ +À  €H¢ H€@a ‡€  - - +@ H + È;€I - + -GÀǑ@Ê¡ +GÀǑ@Ê¡ -GÀH;€È¡@Ê¡ - +GÀH;€È¡@Ê¡ + -GÀ @€ @°@É +GÀ @€ @°€Æ ÀŒ -GÀ €  °ÀÇ +GÀ €  ° -GÀ @€ À°@Å +GÀ @€ À°€Â -GÀ À€Àà @°È €È€ +GÀ À€ ÏIÊÀå Ê;€ Bå €JÁ€ @@ -7175,25 +5049,25 @@ J€‡ J9€ @b Ê;€ -Âá +Âá É - + ‡!€Ç€ˆs€À‡sÀÇt€GÀ €Ç@b - + Gu€ÀÇu€GÀ - + €Ç@b - + x  - - -@×~ ª +À×~  + + Ào - +  H $€ɀ¢ @@ -7201,23 +5075,23 @@ H É šP‚Ú‚È;€È! ‡€¡ ‡ - - - - -@º~  + + + + + - + G,€ÇÂ" Ç,€@a -QI†À À +QI†À À ­ Q ?€ R - + ÈŒo @@ -7231,7 +5105,7 @@ R €x ,Á Àø *ÖI - + G#€ ‡#€ ÀqÀ@) ‡#€‡q€ Çs€  @@ -7294,17 +5168,17 @@ G$€‡)À Ê -(€ +(€ % & & & ÇÀr€ ! G%€@¡  GÀ   ¢ SÀ& -@[ +@^ À¡ Š*€ À  ‰$€ @o -É&€I@€a É&À@x €ˆ*€ €H"P ! & ‡%À‡À  Ç +É&€I@€d É&À@x €ˆ*€ €H"P ! & ‡%À‡À  Ç Ç Ê,€‡£ @@ -7331,14 +5205,14 @@ R P  -€L@ã L+€Ì" €¢ Ë@ #\ Àa L+ÀLÀ - €° À° + €° À° -€x Ç,€Ç +€x Ç,€Ç ÉI  € É Ç,€DŽP -€Ʉ@ € @¡ I@ À` - ÀÀö~ I,€‰D €€‡b + ÀÀù~ I,€‰D €€‡b @x -€JÀ Š @@ -7347,9 +5221,9 @@ I@ À` -€JÀ+ ‡ -€x  +€x  É! - +€É + +€É ‡ €‡@a x @@ -7379,36 +5253,36 @@ J2€ Àx ˆ†€ Š ‡‚0 À` Š - -€v~ - À€j # LJ @t~  - + +@w~ + ÀÀj # LJ +  - +  ¡ r€€  -@c~ G@Q -þ I -“ +€c~ ‡ +þ I +“ -€ +€@E # G@Hÿ Q €x H@ÀÀB H@ Q Q Q - +@5 # À4 # ÀÀG@Q GÀÀÁG@Q ‡@ ˆ/ÀÀÀÀ¡ ‡B @‰ ˆ/À‡/€G@Q -ˆ€ÀÀ€' # G@Q +ˆ€ÀÀÀ' # G@Q Ç;€p€ Ç;À -GÀС@Ê¡ +GÀС@Ê¡ G@€@!x Ñ  @@ -7423,19 +5297,19 @@ G G Ç ÀG GB G -G -@õ} +G + €x Q - + Ç;€Gp€ Ç;À -GÀБ@Ê¡ +GÀБ@Ê¡  - ;ÀR` G)€"j ! É Ç(ÀÉ! )ÀI - + ;ÀR` G)€"j ! É Ç(ÀÉ! )ÀI + € €‰Á  ̀̀ @€ - + ÌÏ  ‰Aa Ìa €÷ à€ ‹ @@ -7446,49 +5320,45 @@ GÀБ@Ê¡  € €‰Á  ̀̀ @£ -G +G ÌÏ  ‰Aa Ìa @÷ à€ ‹ @ÉÁ  - + - + @x  € - + - + H€ƒ -t€@d # ÇsÀRP @c # tÀR` G)€"j ! Ç - - +t€€d # ÇsÀRP €c # tÀR` G)€"j ! Ç + +  -B @\ # BH €[ # BP B À€@ € És€؀@ € t€Àx -Çs€ - -B €R # BH ÀQ # BP B À€@ À És€@IGrÀ @ G €À§ +B €\ # BH À[ # BP B À€@  +Çs€@W # ÇsÀRP G)€"j ! Ç + +B ÀR # BH  €H€¢‚ ဉ -a  +a  G@GA® -I -I +I +I  ‡ €‡@¢ - €ÀD # "@ + € @x ‡ €ˆ€"@ ö€ -GÀ À€À @  - -G"@ @< # À= - - - -tl1_h264_multi.bin - +GÀ À€ + +G"@ €< #  + € x B<¡  £ @@ -7498,14 +5368,13 @@ C Ã#€ -€Â0€ ›€à - + ɑÀ -GLÊÿ - -ˆ +GLÊÿ + -@Rx  - +ÀRx  +€Tx ‚à Àý € @@ -7519,7 +5388,7 @@ GLÊÿ GIŠ‚ È,€ ÂO -I@ +I@ I À  €o @@ -7548,7 +5417,7 @@ J  € LJ£€ - ª €À k + ª €@” k   @x €R @@ -7558,8 +5427,8 @@ J @x J€ Áe ˆ€B€ €Àa -Àx H -€€: +@ x H +€ H ÀÇñ ÀG£ G@£ ‡Á` @@ -7568,9 +5437,9 @@ G@£ x x }‚G‚` -@x +@x €x €ùx QL -FL @LBLȂ@‚ +FL @LBLȂ@‚ G @@ -7579,17 +5448,17 @@ G - +  -Ó t - +Ó t + -  +  ÉIJÀ ÄIʁ À - + LÊ¥€ @@ -7603,15 +5472,15 @@ G € -GÀ +GÀ -GÀ€€I +GÀ€€I ÂI Àd  €Â` - - + + ”$€”@¥ ”  @.x @@ -7651,7 +5520,7 @@ U@%ÀÕ$€U@Àx Õ$À&€Ö)€• Š@@x N N N@ -  +  À  @ÿ @Èÿƒ II24 ÉA"  @@ -7659,11 +5528,14 @@ U@%ÀÕ$€U@Àx Õ$À&€Ö)€• €ÿ Éÿƒ»I SIÇ À  -@þ I@ -I +@þ I@ +œIò + @o +Ç@ +I -K -K +K +K <€ À` € x J @@ -7688,36 +5560,36 @@ G€4€ Š,€Š@ I Ç,À@Ȅ@ -ÀÇ,€€¡ -Ç@Ç  Àÿ ÇÁA+ÀÇ,€‡À-€ÇÀ -À +Ç@Ç  Àÿ ÇÁA+ÀÇ,€‡À-€ÇÀ +À €ª GÀª ÇÀÈ;€H É-À% <€€  -€ ÏIÉÀ + ‡À¢ -€  €H¢ + H€@a ‡€  - - +€ H + È;€I - + -GÀǑ@Ê¡ +GÀǑ@Ê¡ -GÀH;€È¡@Ê¡ - +GÀH;€È¡@Ê¡ + -GÀ @€ @°@É +GÀ @€ @°ÀÅ ÀŒ -GÀ €  °ÀÇ +GÀ €  °@Ä -GÀ @€ À°@Å +GÀ @€ À°ÀÁ -GÀ À€Àà @°È €È€ +GÀ À€@À @°È €È€ ÏIÊÀå Ê;€ Bå €JÁ€ @@ -7726,25 +5598,25 @@ J€‡ J9€ @b Ê;€ -Âá +Âá É - + ‡!€Ç€ˆs€À‡sÀÇt€GÀ €Ç@b - + Gu€ÀÇu€GÀ - + €Ç@b - + x  - - -@×~ ª + + +@Ô~ ª Ào - +  H $€ɀ¢ @@ -7752,23 +5624,23 @@ H É šP‚Ú‚È;€È! ‡€¡ ‡ - - - - -@º~  + + + + +@·~  - + G,€ÇÂ" Ç,€@a -QI†À À +QI†À À ­ Q ?€ R - + ÈŒo @@ -7782,7 +5654,7 @@ R €x ,Á Àø *ÖI - + G#€ ‡#€ ÀqÀ@) ‡#€‡q€ Çs€  @@ -7845,17 +5717,17 @@ G$€‡)À Ê -(€ +(€ % & & & ÇÀr€ ! G%€@¡  GÀ   ¢ SÀ& -@[ + À¡ Š*€ À  ‰$€ @o -É&€I@€a É&À@x €ˆ*€ €H"P ! & ‡%À‡À  Ç +É&€I@@e É&À@x €ˆ*€ €H"P ! & ‡%À‡À  Ç Ç Ê,€‡£ @@ -7882,14 +5754,14 @@ R P  -€L@ã L+€Ì" €¢ Ë@ #\ Àa L+ÀLÀ - €° À° + €° À°À2 -€x Ç,€Ç +€x Ç,€Ç ÉI  € É Ç,€DŽP -€Ʉ@ € @¡ I@ À` - ÀÀö~ I,€‰D €€‡b + À€ú~ I,€‰D €€‡b @x -€JÀ Š @@ -7898,9 +5770,9 @@ I@ À` -€JÀ+ ‡ -€x  +€x  É! - +€É + +€É ‡ €‡@a x @@ -7930,36 +5802,36 @@ J2€ Àx ˆ†€ Š ‡‚0 À` Š - -€v~ - À€j # LJ @t~  - + +@w~ + ÀÀj # LJ +  - +  ¡ r€€  -@c~ G@Q -þ I -“ +€c~ ‡ +þ I +“ -€ +€@E # G@Hÿ Q €x H@ÀÀB H@ Q Q Q - +@5 # À4 # ÀÀG@Q GÀÀÁG@Q ‡@ ˆ/ÀÀÀÀ¡ ‡B @‰ ˆ/À‡/€G@Q -ˆ€ÀÀ€' # G@Q +ˆ€ÀÀÀ' # G@Q Ç;€p€ Ç;À -GÀС@Ê¡ +GÀС@Ê¡ G@€@!x Ñ  @@ -7974,19 +5846,19 @@ G G Ç ÀG GB G -G -@õ} +G + €x Q - + Ç;€Gp€ Ç;À -GÀБ@Ê¡ +GÀБ@Ê¡  - ;ÀR` G)€"j ! É Ç(ÀÉ! )ÀI - + ;ÀR` G)€"j ! É Ç(ÀÉ! )ÀI + € €‰Á  ̀̀ @€ - + ÌÏ  ‰Aa Ìa €÷ à€ ‹ @@ -7997,442 +5869,47 @@ GÀБ@Ê¡  € €‰Á  ̀̀ @£ -G +G ÌÏ  ‰Aa Ìa @÷ à€ ‹ - @ÉÁ  - + @ÉÁ  + - + @x  € - + - + H€ƒ -t€@d # ÇsÀRP @c # tÀR` G)€"j ! Ç - - +t€€d # ÇsÀRP €c # tÀR` G)€"j ! Ç + +  -B @\ # BH €[ # BP B À€@ € És€؀@ € t€Àx -Çs€ - -B €R # BH ÀQ # BP B À€@ À És€@IGrÀ @ G €À§ +B €\ # BH À[ # BP B À€@ À És€؀@ À t€Àx +Çs€@W # ÇsÀRP G)€"j ! Ç + +B ÀR # BH  €H€¢‚ ဉ -a  +a  G@GA® -I -I +I +I  ‡ €‡@¢ - €ÀD # "@ + € @x ‡ €ˆ€"@ ö€ -GÀ À€À @  - -G"@ @< # À= - ÄI ð! - `xI@á C Äà - €‰€ €ú À‰À À € @¡ -I€ -€.x ‰€ -€(x È -@x - - -@ö € ˆ€€` - -È€À` -ˆ -G€€o -€‡À‡À  Ç -À~x - -‚ -6L‚ ˆËk - -ÀÀ‡K¡ -ÀÀ‡Ë  -ÀÀ@yx ‡Ti -ˆQ“ÀÁ"N - - €  - -Ç - -€rx ‰€a -@¡ -Ç@Ê @qx -À  -@ÿ ž@Þÿƒ II24 ÉA" - - Iɐ€ ɐÀ Àý ž@ I € ‰€  À ‰À ÉÿƒSIH@! - -@ÿ I@ -‡ -Àx Ç@‡À  -I€É€ɀâ -É¡Ç -ÀIGÀ# - -ÁI‡ -H -ÂIA" -ˆ -ÃI‚! -È -Ç€‡ -G €ÇA ÈQ@ -G -²  -°  -± Ç€G - -‘ Äš -H(ŒH(Œ € BL ÂÀQ IGv€ v€  P  -G€HL€ȁP GLÀ €G Àˆ€ ÀÈAÀ -Èq@ -À À¢ Èq@I -À G€Ào - -Å ü¿ò -QI€ Q  -@ÀIò -À€È -ÀÈH€À  -H -ˆ -G€@x GMÀ‡€GÀà -)LÄà Àx -€Èq@Ç€ -€€È -À€Ã -€À¡ -G@¡ - ’‡À  - -Àd - -H - - -G €ȁ€ À` - - - - , ( (LGÀ/ -Ç€ - -‡€Ào -‡€€£ -G€G - -Ày - -"&  - - - -Þ¿. @n -ÀI -‘   -Ç@À  # €` €d ‡À€` - -ˆ€ˆÀ€ÀT  -€‡€ÇÀÇ€‡€¢ - -  -‡ -ÈÿƒÈÁH & ( G€ˆ€À` -GMÀÇ€GÀ(LG@. -Ç€C¢ GÀ( (LGÀ/ -Ç€GÀ -@ - -@ÇAa -ˆ€ˆÀÀx €Ç - -€ -€‡B¡ -¡ -G  - - ÈBa -G€Ç -À? - -"&  -G€€ -GÁ£ -‡‚` -@x €; -@x À,  -€ -x - -€ -€G € - -Ê -ǀ¡ -‡€€2@ Œ€ €€  Ð - EEÐ@î -G‚  -ǀ` -€ x - -€Š€ €@ …ÐÀ…ÀƒÀ…ƒÀŠ -€Ç€ - -Ê - -€ÀG€GÀ‡€‡ÀÇ€Àè ÇÀ €À  - -€Š€ €Œ€@î -€‹€ €@ê -‡BX J -‡BP  -‡BH J - -(`xh@á (C(Äà -(€( -H€H†á -G@¡ -R - -Àx ΀ -Ž@ÎÀŽ€Ž@ŽÀ -€@¡ -â OÀ  -à á Í€ÍÀ¡ -M€ NÍC@ -€@ x ÀL€ÏÀM -á OÀ  -â à € -Ž€À  -@è Ž@΀ €Mƒ@Ó -Àx M€Mó‡M@ NÀŽNÀNNÀŽNÀNŽÀŽÎÀNÎQÀŽÎUÀNÎYÀŽÀ -€ €¡ -M@¢ -B¢ -͂  -@Ix €x -Í€€Ž - Á OÀ  -   À ÍÀ - Á OÀ  -   À ÍÀM@  -O€OÀà -Àx -MC@ â Ž - Á` -@ñ -€ x € €P3@ @$ -€x -́¡ -   -@x -ƒ  €@ NMӀ Í€M3@M@ ÔX ²IMƒ tr Í€M# -€¡ - -G@b -Ç€À¡ -I€GB -É - -Ç€ - -Çÿ¿@ - -!LÇÿ¿@ -‡€"LÉ€ @¡ - -£ -J‚£ -Ê@£ -ÊA¡ -Š  -@x Ê€Š€o -Šr€‡ - €@x ÊJ JM€ŠÂ` - -€ -€ -Š€ -€@" - -€ -€@ -Š€ -€@ -€@ -x ÌV JM€ŠÂ` - -€ -€@ -Š€ -€ - -€ -€€ -Š€ -€€ - €ÊJ JY€Š" Ê!L ŠM€J" É!\ @ - - -JÀ - -c -@x KÁ` -JAb -€x ‹Á  -ˁ  -‹Â` - -¡ -JÁ  - -Š - - -p€Ir€IB -É¡ -‰Á  -I€ @ x É - ,€IB -ɱ@ -Á  - € € @ -I€I€ @ -À -x ,€IB ‰‚  -ɱ@ -Á  - € € @ -I€I€ @ -€ ,€‰‚€ C Œ€ €¥ -Ì€ -Ì € C Œ‚  -ÌA -‹€¡ -†€‹€€‰2@  - -@Ç} - -Õ€@¡ -•€ @ x -x €Ä hx•! VÀ• –Àhx•! ÖÀ• ÀT -Õ€U@ÕÀ†•Àe8hxqxU… -T€Õ€ÀqxU…€•5@ - -€o8…Q `8 - -†–Àe8hx•% VÀÀ¢ -–€¢ -ր` -Àx Ö€hx–%@À - - €UÀ¢ - -@!~ - -H€ -(€G@€ -,€‡À£ -<€Ç@£ -P€Á¢ -X€GA¢ - €‡Á¡ -°€ -ˆ‚ - €G@Š - !€‡À¥ - $€Ç@¥ - <€Á€ - H€GA€ - x€Ç@@ÀGrÀÇ1€À¢ - -€G@¢ - Z€‡À¡ - € -‰’ -G€b@ -‡€GB@ - -@x #€ã -€x ŠI -Àx Š‰ -¥€$ -$Y@€€“@¢ -å€$ -$)@å€SÀ -d - -Çÿ¿H -@ó -Èÿ¿p r  -r  -Ç€‰“€ ŒÀÀ ŒÁÀ Èÿ ’€ -¢€‡Àâ -‡ - -¢€Ç€H€  -‡€ - -¢€ s  -q  u IL€I‚ -@€I@H‚P U SIˆÀï -¿I‚ UIǁ ‚O - -K<€K4€ T Àß - -‡€  - -!`xa@á !C!Äà - -À£ -Á - -‚ -„ ÌI  -A§ -ħ - - €Â¥ -I €‰€Ä -€Ê -„A¢ - -Di -Š - - - -GÀ` -… -€x  B €  ÌI D` - -E€‚€G@¢ -ŀ‡€¢ -E‚Ł€x - -E‚‚‚GÀ¡ -łƒ‡ -Eƒ‚ƒѐ "€ KÀ` -@ˆ"À „Á` - -GÀ` -… - -E„‚„GÀ¡ -ń…‡ -E…‚…Ņ "€ Š   -E†‚†GÀ¡ -ņ‡‡ -E‡‚‡Ґ "€ Ç +GÀ À€ + +G"@ €< #  + + + ÄI ð! `xI@á C Äà €‰€ €ú À‰À À € @¡ @@ -8830,1149 +6307,7 @@ E„‚„GÀ¡ E…‚…Ņ "€ Š   E†‚†GÀ¡ ņ‡‡ -E‡‚‡Ґ "€ Ç - ÄI ð! - `xI@á C Äà - €‰€ €ú À‰À À € @¡ -I€ - - -@x - - -@ö @’ ˆ€€` -€Rx L€ÇÀ€ -È€À` -ˆ -G€€o -€‡À‡À  Ç - -‚ -6L‚ ˆKl - -ÀÀ‡K¡ -ÀÀ‡Ë  -ÀÀ -ˆQ“ÀÁBN - - €  - -Ç - -@ˆx ‰€a -@¡ -Ç@Ê  -À  -@ÿ ž@Þÿƒ II24 ÉA" - - Iɐ€ ɐÀ Àý ž@ I € ‰€  À ‰À ÉÿƒSIH@! - -@ÿ I@ -‡ -Àx Ç@‡À  -I€É€ɀâ -É¡Ç -ÀIGÀ# - -ÁI‡ -H -ÂIA" -ˆ -ÃI‚! -È -Ç€‡ -G €ÇA ÈQ@ -G -²  -°  -± Ç€G - -‘ „  -G€HL€ȁP GLÀ €G Àˆ€ ÀÈAÀ -Èq@ -À €Š Èq@I -À G€Ào - -Å ü¿ò -@ÀIò -À€È -À -H -ˆ -G€€x GMÀ‡€GÀà -)LÄà -€Èq@Ç€ -€€È -À -€À¡ -G@¡ - ’‡À  - -ÀF - -ˆÀ ˆ€  €@a - -G €ȁ€ À` - - -À¡ -B J@¡ -B ŠÀ  -B B -K,€@x ÈBX IÀ` -€x ÇBP ‰À` -À - , ( (LGÀ/ -Ç€ - -‡€Ào -‡€€£ -G€G - -€d - -"&  - - - -Þ¿. -ÀI -‘  % -GMÀÇ€GÀ -@¥ -ˆ€GÀ€ -ˆ -È - -ˆ€G@¢ -È€‡À¡ -€Ç@¡ -H€Á  - - -ˆ€ˆÀ€À;  -€‡€ÇÀÇ€‡€¢ - -  - - -@ÇAa -ˆ€ˆÀÀx €Ç - -€ -€‡B¡ -¡ -G  - - ÈBa -G€Ç - - -"&  -G€€ -@x @  -€ -x - -€ -€G € - -Ê -ǀ¡ -‡€€2@ Œ€ € -G‚  -ǀ` -€ x - -€Š€ €Àÿ -€Ç€ - -Ê - -€ÀG€GÀ‡€‡ÀÇ€Àè ÇÀ €À  - -€Š€ €Œ€Àì -€‹€ €Àè -‡BX J -‡BP  -‡BH J - -(`xh@á (C(Äà -(€( -Àx ΀ -Ž@ÎÀŽ€Ž@ŽÀ -€@¡ -â OÀ  -à á Í€ÍÀ¡ -M€ NÍC@ -€@ x ÀL€ÏÀM -á OÀ  -â à € -Ž€À  -@è Ž@΀ €Mƒ@Ó -Àx M€Mó‡M@ NÀŽNÀNNÀŽNÀNŽÀŽÎÀNÎQÀŽÎUÀNÎYÀŽÀ -€ €¡ -M@¢ -B¢ -͂  -@Ix €x -Í€€Ž - Á OÀ  -   À ÍÀ - Á OÀ  -   À ÍÀM@  -O€OÀà -Àx -MC@ â Ž - Á` -@ñ -€ x € €P3@ @$ -€x -́¡ -   -@x -ƒ  €@ NMӀ Í€M3@M@ ÔX ²IMƒ tr Í€M# -€¡ - -G@b -Ç€À¡ -I€GB -É - -Ç€ - -‡€ÇA@N€ȁ -Çÿ¿@ - -!LÇÿ¿@ -‡€"LÉ€ @¡ - -£ -J‚£ -Ê@£ -ÊA¡ -Š  -@x Ê€Š€o -Šr€‡ - €@x ÊJ JM€ŠÂ` - -€ -€ -Š€ -€@" - -€ -€@ -Š€ -€@ -€@ -x ÌV JM€ŠÂ` - -€ -€@ -Š€ -€ - -€ -€€ -Š€ -€€ - €ÊJ JY€Š" Ê!L ŠM€J" É!\ @ - - -JÀ - -c -@x KÁ` -JAb -€x ‹Á  -ˁ  -‹Â` - -¡ -JÁ  - -Š - - -p€Ir€IB -É¡ -‰Á  -I€ @ x É - -Àá} - -Õ€@¡ -•€ @ x -x €Ä hx•! VÀ• –Àhx•! ÖÀ• ÀT -Õ€U@ÕÀ†•Àe8hxqxU… -T€Õ€ÀqxU…€•5@ - -€o8…Q `8 - -†–Àe8hx•% VÀÀ¢ -–€¢ -ր` -Àx Ö€hx–%@À - - €UÀ¢ - -€O~ -ˆÀ ˆ€ ÀÀÊ -@x #€ã -€x ŠI -Àx Š‰ -¥€$ -$Y@€€“@¢ -å€$ -$)@å€SÀ -d - À‡" Ê!@ ‡" Ê!D ‡MÀH€ˆ§ - -Çÿ¿H -Àò -Èÿ¿p r  -r €] ˆB - -Ç€‰“€ ŒÀÀ ŒÁÀ ŒÂÀ Èÿ ’€ -¢€‡ -‡ - -¢€Ç€H€  -‡€@£ - -¢€ s  -q LÂÀ È€À  - ÂÀ € u H€RJ RT v ˆ€É€I@ -@€I@ˆ -‹€Ë€@H‚P U SIˆÀï -¿I‚ UIǁ ‚O - -‚@ -H‚P SIˆÀï - -‡€  - -!`xa@á !C!Äà - -À£ -Á - -‚ -„ ÌI  -A§ -ħ - - €Â¥ -I €‰€Ä -€Ê -„A¢ - -Di -Š - - - -GÀ` -… -€x  B €  ÌI D` - -E€‚€G@¢ -ŀ‡€¢ -E‚Ł€x - -E‚‚‚GÀ¡ -łƒ‡ -Eƒ‚ƒѐ "€ @ˆ"À „Á` - -GÀ` -… - -„À¥ -E„‚„G -ń…‡@€ -E…‚…Ņ@x -E€‚€GÀ¡ -ŀ‡ -E‚Ł -†À¥ -E†‚†G -ņ‡‡@€ -E‡‚‡Ґ@x -E‚‚‚GÀ¡ -łƒ‡ -Eƒ‚ƒѐ@ -À` - ÄI ð! - `xI@á C Äà - €‰€ €ú À‰À À € @¡ -I€ - - -@x - - -@ö @’ ˆ€€` -€Rx L€ÇÀ€ -È€À` -ˆ -G€€o -€‡À‡À  Ç - -‚ -6L‚ ˆKl - -ÀÀ‡K¡ -ÀÀ‡Ë  -ÀÀ -ˆQ“ÀÁBN - - €  - -Ç - -@ˆx ‰€a -@¡ -Ç@Ê  -À  -@ÿ ž@Þÿƒ II24 ÉA" - - Iɐ€ ɐÀ Àý ž@ I € ‰€  À ‰À ÉÿƒSIH@! - -@ÿ I@ -‡ -Àx Ç@‡À  -I€É€ɀâ -É¡Ç -ÀIGÀ# - -ÁI‡ -H -ÂIA" -ˆ -ÃI‚! -È -Ç€‡ -G €ÇA ÈQ@ -G -²  -°  -± Ç€G - -‘ „  -G€HL€ȁP GLÀ €G Àˆ€ ÀÈAÀ -Èq@ -À  -À G€Ào - -Å ü¿ò -@ÀIò -À€È -À -H -ˆ -G€€x GMÀ‡€GÀà -)LÄà -€Èq@Ç€ -€€È -À -€À¡ -G@¡ - ’‡À  - -@F - -ˆÀ ˆ€  €@a - -G €ȁ€ À` - - -À¡ -B J@¡ -B ŠÀ  -B B -K,€@x ÈBX IÀ` -€x ÇBP ‰À` -À - , ( (LGÀ/ -Ç€ - -‡€Ào -‡€€£ -G€G - -€d - -"&  - - - -Þ¿. -ÀI -‘  % -GMÀÇ€GÀ -@¥ -ˆ€GÀ€ -ˆ -È - -ˆ€G@¢ -È€‡À¡ -€Ç@¡ -H€Á  - - -ˆ€ˆÀ€@;  -€‡€ÇÀÇ€‡€¢ - -  -€é - -@ÇAa -ˆ€ˆÀÀx €Ç - -€ -€‡B¡ -¡ -G  - - ÈBa -G€Ç - - -"&  -G€€ -@x À  -€ -x - -€ -€G € - -Ê -ǀ¡ -‡€€2@ Œ€ €€ - Ð€É -G‚  -ǀ` -€ x - -€Š€ €@ÿ -€Ç€ - -Ê - -€ÀG€GÀ‡€‡ÀÇ€Àè ÇÀ €À  - -€Š€ €Œ€@ì -€‹€ €@è -‡BX J -‡BP  -‡BH J - -(`xh@á (C(Äà -(€( -Àx ΀ -Ž@ÎÀŽ€Ž@ŽÀ -€@¡ -â OÀ  -à á Í€ÍÀ¡ -M€ NÍC@ -€@ x ÀL€ÏÀM -á OÀ  -â à € -Ž€À  -@è Ž@΀ €Mƒ@Ó -Àx M€Mó‡M@ NÀŽNÀNNÀŽNÀNŽÀŽÎÀNÎQÀŽÎUÀNÎYÀŽÀ -€ €¡ -M@¢ -B¢ -͂  -@Ix €x -Í€€Ž - Á OÀ  -   À ÍÀ - Á OÀ  -   À ÍÀM@  -O€OÀà -Àx -MC@ â Ž - Á` -@ñ -€ x € €P3@ @$ -€x -́¡ -   -@x -ƒ  €@ NMӀ Í€M3@M@ ÔX ²IMƒ tr Í€M# -€¡ - -G@b -Ç€À¡ -I€GB -É - -Ç€ - -Çÿ¿@ - -!LÇÿ¿@ -‡€"LÉ€ @¡ - -£ -J‚£ -Ê@£ -ÊA¡ -Š  -@x Ê€Š€o -Šr€‡ - €@x ÊJ JM€ŠÂ` - -€ -€ -Š€ -€@" - -€ -€@ -Š€ -€@ -€@ -x ÌV JM€ŠÂ` - -€ -€@ -Š€ -€ - -€ -€€ -Š€ -€€ - €ÊJ JY€Š" Ê!L ŠM€J" É!\ @ - - -JÀ - -c -@x KÁ` -JAb -€x ‹Á  -ˁ  -‹Â` - -¡ -JÁ  - -Š - - -p€Ir€IB -É¡ -‰Á  -I€ @ x É - -@â} - -Õ€@¡ -•€ @ x -x €Ä hx•! VÀ• –Àhx•! ÖÀ• ÀT -Õ€U@ÕÀ†•Àe8hxqxU… -T€Õ€ÀqxU…€•5@ - -€o8…Q `8 - -†–Àe8hx•% VÀÀ¢ -–€¢ -ր` -Àx Ö€hx–%@À - - €UÀ¢ - - -ˆÀ ˆ€ À@Ë -@x #€ã -€x ŠI -Àx Š‰ -¥€$ -$Y@€€“@¢ -å€$ -$)@å€SÀ -d - À‡" Ê!@ ‡" Ê!D ‡MÀH€ˆ§ - -Çÿ¿H -Àò -Èÿ¿p r  -r €] ˆB - -Ç€‰“€ ŒÀÀ ŒÁÀ ŒÂÀ Èÿ ’€ -¢€‡ -‡ - -¢€Ç€H€  -‡€@£ - -¢€ s  -q LÂÀ È€À  - ÂÀ € u H€RJ RT v ˆ€É€I@ -@€I@ˆ -‹€Ë€@H‚P U SIˆÀï -¿I‚ UIǁ ‚O - -‚@ -H‚P SIˆÀï - -‡€  - -!`xa@á !C!Äà - -À£ -Á - -‚ -„ ÌI  -A§ -ħ - - €Â¥ -I €‰€Ä -€Ê -„A¢ - -Di -Š - - - -GÀ` -… -€x  B €  ÌI D` - -E€‚€G@¢ -ŀ‡€¢ -E‚Ł€x - -E‚‚‚GÀ¡ -łƒ‡ -Eƒ‚ƒѐ "€ @ˆ"À „Á` - -GÀ` -… - -„À¥ -E„‚„G -ń…‡@€ -E…‚…Ņ@x -E€‚€GÀ¡ -ŀ‡ -E‚Ł -†À¥ -E†‚†G -ņ‡‡@€ -E‡‚‡Ґ@x -E‚‚‚GÀ¡ -łƒ‡ -Eƒ‚ƒѐ@ -À` - ÄI ð! - `xI@á C Äà - €‰€ €ú À‰À À € @¡ -I€ -€.x ‰€ -€(x È -@x - - -@ö € ˆ€€` - -È€À` -ˆ -G€€o -€‡À‡À  Ç -À~x - -‚ -6L‚ ˆËk - -ÀÀ‡K¡ -ÀÀ‡Ë  -ÀÀ@yx ‡Ti -ˆQ“ÀÁ"N - - €  - -Ç - -€rx ‰€a -@¡ -Ç@Ê @qx -À  -@ÿ ž@Þÿƒ II24 ÉA" - - Iɐ€ ɐÀ Àý ž@ I € ‰€  À ‰À ÉÿƒSIH@! - -@ÿ I@ -‡ -Àx Ç@‡À  -I€É€ɀâ -É¡Ç -ÀIGÀ# - -ÁI‡ -H -ÂIA" -ˆ -ÃI‚! -È -Ç€‡ -G €ÇA ÈQ@ -G -²  -°  -± Ç€G - -‘ Äš -H(ŒH(Œ € BL ÂÀQ IGv€ v€  P  -G€HL€ȁP GLÀ €G Àˆ€ ÀÈAÀ -Èq@ -À @£ Èq@I -À G€Ào - -Å ü¿ò -QI€ Q  -@ÀIò -À€È -ÀÈH€À  -H -ˆ -G€@x GMÀ‡€GÀà -)LÄà Àx -€Èq@Ç€ -€€È -À -€À¡ -G@¡ - ’‡À  - -@e - -H - - -G €ȁ€ À` - - - - , ( (LGÀ/ -Ç€ - -‡€Ào -‡€€£ -G€G - -Ày - -"&  - - - -Þ¿. @n -ÀI -‘   -Ç@À  # €` €d ‡À€` - -ˆ€ˆÀ€@U  -€‡€ÇÀÇ€‡€¢ - -  -‡ -ÈÿƒÈÁH & ( G€ˆ€À` -GMÀÇ€GÀ(LG@. -Ç€C¢ GÀ( (LGÀ/ -Ç€GÀ -À - -@ÇAa -ˆ€ˆÀÀx €Ç - -€ -€‡B¡ -¡ -G  - - ÈBa -G€Ç -À? - -"&  -G€€ -GÁ£ -‡‚` -@x €; -@x @-  -€ -x - -€ -€G € - -Ê -ǀ¡ -‡€€2@ Œ€ € -G‚  -ǀ` -€ x - -€Š€ €À …ÐÀ…ÀƒÀ…ƒÀŠ -€Ç€ - -Ê - -€ÀG€GÀ‡€‡ÀÇ€Àè ÇÀ €À  - -€Š€ €Œ€Àî -€‹€ €Àê -‡BX J -‡BP  -‡BH J - -(`xh@á (C(Äà -(€( -H€H†á -G@¡ -R - -Àx ΀ -Ž@ÎÀŽ€Ž@ŽÀ -€@¡ -â OÀ  -à á Í€ÍÀ¡ -M€ NÍC@ -€@ x ÀL€ÏÀM -á OÀ  -â à € -Ž€À  -@è Ž@΀ €Mƒ@Ó -Àx M€Mó‡M@ NÀŽNÀNNÀŽNÀNŽÀŽÎÀNÎQÀŽÎUÀNÎYÀŽÀ -€ €¡ -M@¢ -B¢ -͂  -@Ix €x -Í€€Ž - Á OÀ  -   À ÍÀ - Á OÀ  -   À ÍÀM@  -O€OÀà -Àx -MC@ â Ž - Á` -@ñ -€ x € €P3@ @$ -€x -́¡ -   -@x -ƒ  €@ NMӀ Í€M3@M@ ÔX ²IMƒ tr Í€M# -€¡ - -G@b -Ç€À¡ -I€GB -É - -Ç€ - -‡€ÇA@N€ȁ -Çÿ¿@ - -!LÇÿ¿@ -‡€"LÉ€ @¡ - -£ -J‚£ -Ê@£ -ÊA¡ -Š  -@x Ê€Š€o -Šr€‡ - €@x ÊJ JM€ŠÂ` - -€ -€ -Š€ -€@" - -€ -€@ -Š€ -€@ -€@ -x ÌV JM€ŠÂ` - -€ -€@ -Š€ -€ - -€ -€€ -Š€ -€€ - €ÊJ JY€Š" Ê!L ŠM€J" É!\ @ - - -JÀ - -c -@x KÁ` -JAb -€x ‹Á  -ˁ  -‹Â` - -¡ -JÁ  - -Š - - -p€Ir€IB -É¡ -‰Á  -I€ @ x É - ,€IB -ɱ@ -Á  - € € @ -I€I€ @ -À -x ,€IB ‰‚  -ɱ@ -Á  - € € @ -I€I€ @ -€ ,€‰‚€ C Œ€ €¥ -Ì€ -Ì € C Œ‚  -ÌA -‹€¡ -†€‹€€‰2@  - -ÀÆ} - -Õ€@¡ -•€ @ x -x €Ä hx•! VÀ• –Àhx•! ÖÀ• ÀT -Õ€U@ÕÀ†•Àe8hxqxU… -T€Õ€ÀqxU…€•5@ - -€o8…Q `8 - -†–Àe8hx•% VÀÀ¢ -–€¢ -ր` -Àx Ö€hx–%@À - - €UÀ¢ - -À ~ - -H€ -(€G@€ -,€‡À£ -<€Ç@£ -P€Á¢ -X€GA¢ - €‡Á¡ -°€ -ˆ‚ - €G@Š - !€‡À¥ - $€Ç@¥ - <€Á€ - H€GA€ - x€Ç@@ÀGrÀÇ1€À¢ - -€G@¢ - Z€‡À¡ - € -‰’ -G€b@ -‡€GB@ - -@x #€ã -€x ŠI -Àx Š‰ -¥€$ -$Y@€€“@¢ -å€$ -$)@å€SÀ -d - -Çÿ¿H -@ó -Èÿ¿p r  -r  -Ç€‰“€ ŒÀÀ ŒÁÀ Èÿ ’€ -¢€‡Àâ -‡ - -¢€Ç€H€  -‡€ - -¢€ s  -q  u IL€I‚ -@€I@H‚P U SIˆÀï -¿I‚ UIǁ ‚O - -K<€K4€ T Àß - -‡€  - -!`xa@á !C!Äà - -À£ -Á - -‚ -„ ÌI  -A§ -ħ - - €Â¥ -I €‰€Ä -€Ê -„A¢ - -Di -Š - - - -GÀ` -… -€x  B €  ÌI D` - -E€‚€G@¢ -ŀ‡€¢ -E‚Ł€x - -E‚‚‚GÀ¡ -łƒ‡ -Eƒ‚ƒѐ "€ KÀ` -@ˆ"À „Á` - -GÀ` -… - -E„‚„GÀ¡ -ń…‡ -E…‚…Ņ "€ Š   -E†‚†GÀ¡ -ņ‡‡ -E‡‚‡Ґ "€ Ç +E‡‚‡Ґ "€ Ç ÄI ð! `iI@á C Äà €‰€ €ú À‰À À € @¡ @@ -10344,7 +6679,7 @@ E‡‚‡Ґ@x E‚‚‚GÀ¡ łƒ‡ Eƒ‚ƒѐ@ -À` +À` ÄI ð! `xI@á C Äà €‰€ €ú À‰À À € @¡ @@ -10716,7 +7051,7 @@ E‡‚‡Ґ@x E‚‚‚GÀ¡ łƒ‡ Eƒ‚ƒѐ@ -À` +À` ÄI ð! `iI@á C Äà €‰€ €ú À‰À À € @¡ @@ -11114,7 +7449,7 @@ E„‚„GÀ¡ E…‚…Ņ "€ Š   E†‚†GÀ¡ ņ‡‡ -E‡‚‡Ґ "€ Ç +E‡‚‡Ґ "€ Ç ÄI ð! `xI@á C Äà €‰€ €ú À‰À À € @¡ @@ -11486,7 +7821,7 @@ E‡‚‡Ґ@x E‚‚‚GÀ¡ łƒ‡ Eƒ‚ƒѐ@ -À` +À` ÄI ð! `xI@á C Äà €‰€ €ú À‰À À € @¡ @@ -11884,7 +8219,7 @@ E„‚„GÀ¡ E…‚…Ņ "€ Š   E†‚†GÀ¡ ņ‡‡ -E‡‚‡Ґ "€ Ç +E‡‚‡Ґ "€ Ç €ê @4x @@ -12065,7 +8400,7 @@ nì£ €Jò` É€ -€JÂ`  +€JÂ`  @@ -12263,600 +8598,493 @@ nì£ €Jò` É€ -€JÂ`  -À - - - - -ÀG -% - -@:LÇa - - - - -€y -Ç€Ào -È€Àc -È€HCc -€ÇÀ€É€IÀ -€x -*L6Lǁ ÈQ ;LH2  -Çñ€H -L À` - -Ç@@ÿ I -À -x -Ç€‡À   - -@x  €À  -È -2 - -( G€GÀCGÀï -€¯ - +€o + + + + +€ú + +!€n +­À- Aˆ-;: ìÀ-+6 ,À«À! +Àg +«€§ +ëC§ +k¥ +¬€,€¢ +l€, +í€lۂm@% +,‹€-€lۂm@$ +ë` + +«Š ++` + +ï€@ + + +m +€o + +‹o + @¢ -‰‚P Ê@Ë -€x À -‚À - -ÀÀGÀGÀ  - - - - -ÀHÀÀÀÇ`ÀãW @Ux -€x -€ -H€H - -€ÿ  - -*L 6LŠ Š‚@˂€‹‚@ -Š@K€K€¡ -I - - -ɬ -ˆ€B r@€@x r@€Ž - -ˆ€ €Gr -ÀÉ€Gr -È€ˆÀ  -È€ -GÀ` - - -G€ÀŠ -b ˆ€  -€¢ - -Ç€Ào -€ÇÀ€I€ €¢ -H - - - -€G@H -Çÿ¿Ç?ÀÁI‚ ȑ€ -ÂI‚ Èa€ -ÁI ÂI - - - - - - - -À - - -€ -J -€ -Àx G€GÀˆ€ÈP ! @$ NÈ€È -ˆ@¥ -" ‡€€¢ -€N" H€ÈD È€2P @x ! Àx A!  -G€ÀÀGÀ¡ -‡€ÀÀG -Ç€ÀÀ€GÀÀ` - -‡€@€ - -€ÀÀ@¡ -HÇ! " - È - -I -€x F! €x -@á - -Íÿ¿Nã - €ˆ €r - - Ç! ‡òŠR€GâIb€‰a ÇIGa Ç Çñ -a   - - -€€À‰"B @x Š@@À Ào -Š -@ -ۆ€[@á GLÛ€   Àa~ Ü€Û €׀ - -š -@e - -( -! (@šŠ‚( hQ˜ -( -* -kÚ -냚 -+B£ - -* -* -š - -! ( 銂( ( -@$ ("Lh -! ( 銂( hЈšŠÂ0D €x ( °D *k€é -Q -* -* -k¡ -p -* - -! h€Â (‹‚(„‚ m€-^ ( ( -@$ ("L( ( -! h€Â (‹‚(„‚ í€-^ ( (XŒšŠÂ0D ( (†šŠÂ0D ( ( -$ /"L/ / -! h€Â (‹‚(„‚ ­€-^ ( ( -P$ ("L( ( -! h€Â (‹‚(„‚ -€-^ ( h؎šŠÂ0D (  $ $("L./(€ - - -š -! ( 銂( @$ ("Lh -! ( 銂( hО0D @x ( * -Q €x +kA¡ -k¡ -p -šŽ0D ( ) ìÿŸ( -! h€Â (‹‚(„‚ ­€-^ ( @$ ("L( ( -! h€Â (‹‚(„‚ ( (XŒ0D ( (¶0D ( ( -! h€Â (‹‚(„‚ ­€m€-^ ( P$ ("L( ( -! h€Â (‹‚(„‚ 胂 ( hØŸ0D (  $ $("L./(( -@#x ÙIUÅ - -@ x –€À¡ -–@–ÀÖ€–@Àx ÖÀ €•€U…@•U–5 -`¡–a¡À×ÿŸ×@À¡ - -U@ -Ö€€¡ -–@V - - -ÖE —ÀNNNà$ " N - -x Õ€Ad -V €U - -ÖE × - -G€ÇÀ  -Gƒ© -c -€Ç -N N NÀ  - -   -@ -ÀÀ€È€ÀÀÀ!À -GÀ  - -ÊߏÊÿþNˆ‚€‡‚ ŠÀ  Lȃ€ JBÀ -‡‚ -À` -Š -, - *CëÿŸ(I(Ìï -,J@($ š€šŠÂ,*F ( ) ("L(h ! ( 튂( ( -,J@š‚ ($ ("Lh ! ( 튂( ìÀ© , -("Lh ! ( 튂(  -À - - - - -ÀG -% - -@:LÇa - - - - -@y -Ç€Ào -È€Àc -È€HCc -€ÇÀ€É€IÀ -€x -*L6Lǁ ÈQ ;LH2  -Çñ€H -L À` - -Ç@@ÿ I -À -x -Ç€‡À   - -@x  €À  -È -2 - -( G€GÀCGÀï -€¯ - ‰À À  + +ÉÀ A…HR6 I +À A A…HR6 I +À A…HR6 I +ÀˆR4 Š +ˆÃ( NÀ A…HR6 "€" + AH> NÂH IÀ" +I@ +À@i +€Àh +€ AH> € + AH> + A„HB8 M + +‰À A‡HB8 I" + + +À A…HB8 ‰B@ 6 ÈÀ@¡ +ˆÀ A‚"< ˆ"N +À A> @a +‰ +‰ +‰ +€ +Ð +È + Aƒ2:  + A +€ˆ€ˆ(À AH> H—€ P H—À @a +Š +‚@ H—ÀËÀ À ƒP Œ—ÀJ€J@# + +Kƒa + @a +I +K€ +Äâ + Aˑ€  €ɒ@H‚€H À + + +ÀÊ ÀI ÀÉ À +É +À +È€@¡ +ˆ€À` +@$ Ë €@x + +I +ˆ@¡ +J +I + À AH> À€H" ‰ + AH> I À À¡ +€H" ‰ + AH> ‰ À +@x ˆ€@¢ +I€ AÉ¡€ + +€J¢@ˆ‚€È ÀÈ €È@¡ +I + AÉ¡€ + +€J¢@ˆ’€IÀÉ€È €Àa +È €@¡ +ˆ + AƒH2: ‰ÀÈ€À¥ + AH> À€ +J€ `€H + +Ë€Ȳ€KÀ! +‚€ €Ȳ€KÀ +€  K +€Šü M +@0x H €@a +É?€ AˆH‚0 ÉÀÉÿ` + €@d +È €À£ +ˆ€@£ + €M&€‰€ AÉ¡€ + +€J¢@ˆ‚€H@ þ M +€À€ +K€Š€Ë€J A É€‰’@H‚€ÈÀˆ +À ÀH + AH> IÀ €¡ + € AƒH2: I’ + +€ ¡ + + +2€ + € €ŠòŠr€Ëò +²@K2@ €ÿ  +²@K2@ €ÿ  +²@K2@ €ÿ  +²@K2@ €ÿ  + AH> +€ €¢ + € AH! ‰ +€x À0` Hƒ€ H € + + + Aˆ> À x +À €€  +@Ð  +É?€ AˆH‚0 ÉÀÈ €À£ +ˆ€@£ + €M&€‰€ AÉ¡€ + +€J¢@ˆ‚€H@ þ M + +Î"À A†Hb4 #ÀL#€ + +É€ AÉ¡€ + +€J¢@ˆ‚€ÈÒF @MC€Ì$a K3p @û  +€ÀŠ + + AH> +  + + + € A‚H"< ‰%À AH> É%ÀÈ €€b + +ˆ€ + AH> &ÀH€ + + AH> I +€ x J€‰€Jr@  A> À  +Àþ Š +@€‹²@KÀʀɀJ2@ J¢@ + +Àþ Š +ÀH +€Àa P€ +P€‹²@@ +x ‹ÀÊ€L€N +@€‹²@KÀ + +‰€Š +‰“@€ÿ  +€@[ P€ +P€‹²@‹À +ˆ€H + - -À` -Š -X „€ ȃ€  -, ÀÀÇÀÉ - -ǀȀÈq@ˆ€BD ˆÀH€H@d - -Àx - - -‰€@À À €£ -HA£ -È¢ - - -€ȃ€ X  - -Àx ! G€G£ -Ç€‡À‡€GÀ€‡À€ÇÀ€$LÇÃï € x 0! $LÇÃï È€@$ NÈ -ˆ@¥ -" ‡€€¢ -€N" H€ÈD È€2P @x ! Àx A!  -@ -É€‰À` @ + +ÀÀx ŠÀH @¡ - + +€¡ +‰À@™ H€À˜ ˆ€€Ðà H_€È€I€H’P ]ˆ€HrP ˆ€Hr` ɗ€ [É€H€HrP €Hr` ˆ€Hrp ɗ€ \Ëÿƒ AH> @€ + + +Àx ‰Àˆ€ÈÁa +I +ÉÀ AH> À AH> IÀH€€` +€x + + +‰r@LÀ A‡Hr2 ‰r@  AH> À¡ +‰^ LÀ A‡Hr2 ‰rP I“€L‚ +@ AH> À¡ +‰r@LÀ A‡Hr2 ‰r@  AH> À¡ +‰^ LÀ A‡Hr2 ‰rP I•€L‚ +@ AH> +ÉJ ÀLÀ AƒH2: É2D  AH> +ÉB ÀLÀ AH> +É@ ÀLÀÌ2l Ë·€ Ìa F€ê  +É@ A‚I"< É"B € + AI> +ÉF Aƒ‰"< I: Ê"H ÉL ‹ÀH +ˆ€@£ +H€Àb +Î"€ +Œ€@] +€ +Àa +ÉÀ +Èÿƒ GÈÂh €@ +x HÀ AŒHb4 ˆb( JbP ÉÀ @¢ + +IÀ Aˆ> JB + +IÀÀN ‹€@N Ë€ÀM €@M K€ÀL ‹€È +€ ÀŠ +H€@f + A„H"< I2 + +H€ +H€‚` + +Àx À Aˆ> € À  +Àx Š +@¡ + AH> J¢ +ä€ã€J +$@ã€$@Ê"L À Ï! + + AH> c +€ +©€JÀ` +©€JÀ` +"À€ + + + + +ˆ€€€ + lA À¯ + + AH> ÉR ËÀ + €Àa +€ˆ@! + AH> À AH> IÀ €@d + AB €o + + + +@x H €À` +ˆ €@§ + AI> ÉÀ + ~ @A +I + AƒH2: + +K8€L ⁠a L D H" I€a +€€ ˲€ I €É2P €À € @b +˳€ ˳À Ë + +‹ ÀÀ2 + +#€Š2 + +#€Š2 +#€ +2 J2 + +,ÊÿŸÊ(ÀÎ(€Ï(€ +‚@ ‚P € +x Š*ÀŠ*€‚P € x Š*Àb +P² +J€Ò@Š€Š@Q + +Àx @ÌÀ` + +3@ + +#€ +4 J2 +‰„É„ ,2€ .A2@ ’€Iò„ ’ + +È€ €H’ + +€J¢@ˆ‚€ˆÀ AÉ¡€ + +€J¢@ˆ‚€ÈÀˆ€€d +À +Ì€Àx  +!€HÀà + + +:J€ +Å! +O! I +Þ ‰ + +€ +! +R@"@ ‚ +aA‹a +aŠ€ +À£ +Ê€@€ +€¡ +^ +€ À` -Š - -HÀ€z Ç€Ào - - NË €¯ - - - -GIŠ‚  -ÂO -I@ -I À  - + +Aˆ€ÈÁ` +Ê£€ Š£€ ‰"D ÈA£ + + `AIÀï + + + + €o -I@ -ŽI - € É€‰Rp -Ž  - À -Ž  ôI`ÀÿO -Àõ - -¢€ - € - -LJ£€ - €õ - -‡­` -À6x Gì` -G -G -‡ÀÀÁÅ ÀÀ - - -À^ -€Ç€GÀ ÃIGa à ÀÀÀÑÀ@À -a  ÀÀÀ -€G - -‡ - -ÀÀ€` -Àx ‡À - -Ç@€‚À -@¢ -‰‚P Ê@Ë -€x À -ÁÀ9 -€ IGÀï € -Ç@€‚À -@¢ -‰‚P Ê@Ë -€x À -‚À - -ÀÀGÀGÀ  - - - - -ÀHÀÀÀÇ`ÀãW -€x -€ -H€H - -€ÿ  - -*L 6LŠ Š‚@˂€‹‚@ -Š@K€K€¡ -I - - -ɬ -ˆ€B r@€@x r@€Ž - -ˆ€ €Gr -ÀÉ€Gr -È€ˆÀ  -È€ -GÀ` - - -G€ÀŠ -b ˆ€  -€¢ - -Ç€Ào -€ÇÀ€I€ €¢ -H - - -À  - -€G@H -Çÿ¿Ç?ÀÁI‚ ȑ€ -ÂI‚ Èa€ -ÁI ÂI - - - - - - - -À - - -€ -J -€ -Àx G€GÀˆ€ÈP ! @$ NÈ€È -ˆ@¥ -" ‡€€¢ -€N" H€ÈD È€2P @x ! Àx A!  -G€ÀÀGÀ¡ -‡€ÀÀG -Ç€ÀÀ€GÀÀ` - -‡€@€ - -€ÀÀ@¡ -HÇ! " - È - -I -€x F! €x -@á - -Íÿ¿Nã - €ˆ €r - - Ç! ‡òŠR€GâIb€‰a ÇIGa Ç Çñ -a   + +’ + € a È€À  + +pA +! É¢@H +a È €Ê€ +¢ +a È€@ €I@ a  BÈ €À  +ˆ€€H2@ È,€2 +€Jò` É€ +€JÂ`  +I +I + + € !€‰’ +…€ …À € Àa +ȅ€ É€I" À` + +€J r Š€J t J v I€ | € ~  € + € € a  #F‰“€ # € I Y AI" €o + + €À` +ˆ€@b + È@ _É€ÉÀ ` `AIÀï _A€hˆ€ € a # €I  €HB  €HD ˆ€HF €HP H€HRR H €@¡ +H\ Aˆ…€ € + H^ H€H"` È€" H"d H€Hh È€Hj € Hn È%€Hp €Hr ˆ €Ht H%€Hv €Hx ˆ€Hz Xˆ€r +| ‰ +~ YÈ€Z€Ðà H_€È€I€H’P ]ˆ€HrP ˆ€Hr` ‰—€ ɗ€ [É€H€HrP €Hr` ˆ€Hrp ɗ€ \È€Àd + €@d + +LF€€ LH +ˆ!€^HÂX _Bx !i"j-€ˆ‡€ ȇ€ $o€€€¬  + + +Ïñ€ €À` +ÈN ð€ ŸðÁ Oó€ +$@ +Ë@Ê‚ +ò€ Í€Mҁ + +ñ€ + €Êò€ + +‹ €OóÀ Oñ€ Ë@ÊR€ +I +ñ€ ]Ё Ïð€ ^AÂ/ +À¡ + +À + d cgρÀ ^A H!€ +ˆ€€¡ +È€ €H2@ + + + + + € !€J¢ + ÀŠ!ÀH!€@ +!€J¢@ +!ÀÀ@òHž¯ +€É€HR@  +-€ +  +€ +! + ’ + N  A‡Hr2 s@  AH> €¡ + ^  A‡Hr2 sP + +H!€€x + +©€ŠC +¢@Jˆ` À + + +¢@Šˆ` À + +©€ŠC +¢@Jˆ` À + + +¢@Šˆ` À + + + +ÍC# + A„ˆC8 NCH @ +À +Œ" @¢ + +Œ" @¢ + + A%`‰aC €¡ + A&`‰a A‚H"< #d + Aa +N@¡ + + AÎÀ` + +a +<€‰’@Ha Ç +ý +ý +š€‰r +#Á - -€€À‰"B @x Š@@À Ào -Š -@ -ۆ€[@á GLÛ€   Àa~ Ü€Û €׀ - -š -@e - -( -! (@šŠ‚( hQ˜ -( -* -kÚ -냚 -+B£ - -* -* -š - -! ( 銂( ( -@$ ("Lh -! ( 銂( hЈšŠÂ0D €x ( °D *k€é -Q -* -* -k¡ -p -* - -! h€Â (‹‚(„‚ m€-^ ( ( -@$ ("L( ( -! h€Â (‹‚(„‚ í€-^ ( (XŒšŠÂ0D ( (†šŠÂ0D ( ( -$ /"L/ / -! h€Â (‹‚(„‚ ­€-^ ( ( -P$ ("L( ( -! h€Â (‹‚(„‚ -€-^ ( h؎šŠÂ0D (  $ $("L./(€ - - -š -! ( 銂( @$ ("Lh -! ( 銂( hО0D @x ( * -Q €x +kA¡ -k¡ -p -šŽ0D ( ) ìÿŸ( -! h€Â (‹‚(„‚ ­€-^ ( @$ ("L( ( -! h€Â (‹‚(„‚ ( (XŒ0D ( (¶0D ( ( -! h€Â (‹‚(„‚ ­€m€-^ ( P$ ("L( ( -! h€Â (‹‚(„‚ 胂 ( hØŸ0D (  $ $("L./(( -@#x ÙIUÅ - -@ x –€À¡ -–@–ÀÖ€–@Àx ÖÀ €•€U…@•U–5 -`¡–a¡À×ÿŸ×@À¡ - -U@ -Ö€€¡ -–@V - - -ÖE —ÀNNNà$ " N - -x Õ€Ad -V €U - -ÖE × - -G€ÇÀ  -Gƒ© -c -€Ç -N N NÀ  - -   -@ -ÀÀ€È€ÀÀÀ!À -GÀ  - -ÊߏÊÿþNˆ‚€‡‚ ŠÀ  Lȃ€ JBÀ -‡‚ -À` -Š -, - *CëÿŸ(I(Ìï -,J@($ š€šŠÂ,*F ( ) ("L(h ! ( 튂( ( -,J@š‚ ($ ("Lh ! ( 튂( ìÀ© , -("Lh ! ( 튂(  +C@ “ + + €‰B€ + + €‰B€ +@ô À @@ -13153,7 +9381,7 @@ GÀ   *CëÿŸ(I(Ìï ,J@($ š€šŠÂ,*F ( ) ("L(h ! ( 튂( ( ,J@š‚ ($ ("Lh ! ( 튂( ìÀ© , -("Lh ! ( 튂(  +("Lh ! ( 튂(  À @@ -13449,26 +9677,26 @@ GÀ   *CëÿŸ(I(Ìï ,J@($ š€šŠÂ,*F ( ) ("L(h ! ( 튂( ( ,J@š‚ ($ ("Lh ! ( 튂( ìÀ© , -("Lh ! ( 튂(  +("Lh ! ( 튂(  À - + - + -À:x +À:x G€ @a @x -@äx +Àæx Ç€À  ,  € - +  -À÷ +@ú Ç€À Ã! @@ -13481,41 +9709,43 @@ JÀÀæ  GÀ$ €À` -ˆ +ˆ  @I - + €o -I@ŽIp€ v€ Gv€ ‡v€ Gw€ Ž pÀ vÀ GvÀ ‡vÀ GwÀ Ž  +I@ŽIp€ v€ Gv€ ‡v€ Gw€ Ž pÀ vÀ GvÀ ‡vÀ GwÀ Ž  -€ï +€ï -‚k@ûW ª€ÀW Ç - +‚k@ûW ª€@Z Ç + Àö r€ -H - +H + @I É€ € ÉÀˆ`À €ÿ G€ À` -€x + É€ € ÉÀG`ÀH€R@ ‡`€ˆ€"@ - -‡€È + +‡€È ’ bÀ  2 x€ -B€  - €¡ +B€  + €¡ + +  € - + € - + ÇA§ ‡ Ç@a @@ -13558,8 +9788,8 @@ I@Èÿƒ»IÇÁ >€À  @x -É  - +É €( + €x QL FLBL @L‡r@ǁ Éÿ¿É?ÀÂI‚ H‚ @@ -13575,7 +9805,7 @@ H2X - + @@ -13594,7 +9824,7 @@ H2X  I ÇA@_€`ÀË -…€T@á GL€   @°~  +…€T@á GL€   À­~  U @@ -13635,26 +9865,26 @@ D@À @€ @x HR& ‰b@I"@J¢@Hb ‰’ - + À - + - + -À:x +À:x G€ @a @x - +€éx Ç€À  ,  € - +  -@û +Àý Ç€À Ã! @@ -13667,41 +9897,43 @@ JÀÀæ  GÀ$ €À` -ˆ +ˆ  @I - + €o -I@ŽIp€ v€ Gv€ ‡v€ Gw€ Ž pÀ vÀ GvÀ ‡vÀ GwÀ Ž  +I@ŽIp€ v€ Gv€ ‡v€ Gw€ Ž pÀ vÀ GvÀ ‡vÀ GwÀ Ž  -€ï +€ï -‚k@ûW ª€@[ Ç - +‚k@ûW ª€À] Ç + Àö r€ -H - +H + @I É€ € ÉÀˆ`À €ÿ G€ À` -@ x +À¢x É€ € ÉÀG`ÀH€R@ ‡`€ˆ€"@ - -‡€È + +‡€È ’ bÀ  2 x€ -B€  - €¡ +B€  + €¡ + +  € - + € - + ÇA§ ‡ Ç@a @@ -13744,8 +9976,8 @@ I@Èÿƒ»IÇÁ >€À  @x -É  - +É €( + €x QL FLBL @L‡r@ǁ Éÿ¿É?ÀÂI‚ H‚ @@ -13763,7 +9995,7 @@ H2X - + @@ -13782,7 +10014,7 @@ H2X  I ÇA@_€`ÀË -…€T@á GL€   À¬~  +…€T@á GL€   @ª~  U @@ -13823,700 +10055,7 @@ D@À @€ @x HR& ‰b@I"@J¢@Hb ‰’ - -À - - - - - - -À:x -G€ @a - -@x -@äx -Ç€À - -,  - € - - -À÷ -Ç€À -Ã! - - -JÀÀæ  -ÇÀ - -, ! - - GÀ$ -€À` - -ˆ - -@I - -€o -I@ŽIp€ v€ Gv€ ‡v€ Gw€ Ž pÀ vÀ GvÀ ‡vÀ GwÀ Ž  - -€ï - -‚k@ûW ª€ÀW Ç - -Àö -r€ -H - -@I -É€ € ÉÀˆ`À -€ÿ -G€ À` -€x -É€ € ÉÀG`ÀH€R@ -‡`€ˆ€"@ - -‡€È -’ bÀ - -2 x€ -B€  - €¡ - -€ - - -€ - -ÇA§ -‡ -Ç@a - - - - - -£ -Š€JÀ` - -ˆ -‰ - À@ÀIÀˆ€ ^ G \ G Z É€ÉÀ  -I - - - -ËI -¢ -QGb€ɑ@I2 -QHbÀIb  P PCIò€I€ï Àb -@î -QË€ RIc  P PCIò€I€ï G €ˆ €B  - -€G€ LI ÉB Hb€Bx „€ Ó Ç€€Èa Ò t - - - -@^ - -GIǁ ˆa€À  -‚O -I@Èÿƒ»IÇÁ -À  - - - -@ x Ç€ª - ->€À  -@x -É  - -€x QL FLBL -@L‡r@ǁ -Éÿ¿É?ÀÂI‚ H‚ -ÃI‚ HR - ÂI   ÃI€x ‘  ÃI   ²I ‘ ‡À €€ - -L -H2X -  - - - - - - - - - - - -AL"CL¢Çh ޘ@ -Þ - -€ÀÈ€ÈÀ  -ˆ - - -‡€È - -ˆ -@x € Àa - -I -ÇA@_€`ÀË -…€T@á GL€   @°~  -U - - -ÈA@ - - - - - - -Çs€ ‡s€ E€Ë€ËÀg -ƒ -…€a - - -Œ€L@a - -„ -„ -E@a -@ -Œ€L - -D -GIǁ  -I@ -   ‡! †À¥ -<€Ȁa -E<€ÇB€ - -ÇB - - =€È -E=€„=€Å=€  E D’€L>€L€¡ -Çb - -D@À @€ - -@x HR& ‰b@I"@J¢@Hb ‰’ - - -À - - - - - - -À:x -G€ @a - -@x - -Ç€À - -,  - € - - -@û -Ç€À -Ã! - - -JÀÀæ  -ÇÀ - -, ! - - GÀ$ -€À` - -ˆ - -@I - -€o -I@ŽIp€ v€ Gv€ ‡v€ Gw€ Ž pÀ vÀ GvÀ ‡vÀ GwÀ Ž  - -€ï - -‚k@ûW ª€@[ Ç - -Àö -r€ -H - -@I -É€ € ÉÀˆ`À -€ÿ -G€ À` -@ x -É€ € ÉÀG`ÀH€R@ -‡`€ˆ€"@ - -‡€È -’ bÀ - -2 x€ -B€  - €¡ - -€ - - -€ - -ÇA§ -‡ -Ç@a - - - - - -£ -Š€JÀ` - -ˆ -‰ - À@ÀIÀˆ€ ^ G \ G Z É€ÉÀ  -I - - - -ËI -¢ -QGb€ɑ@I2 -QHbÀIb  P PCIò€I€ï Àb -@î -QË€ RIc  P PCIò€I€ï G €ˆ €B  - -€G€ LI ÉB Hb€Bx „€ Ó Ç€€Èa Ò t - - - -Àa - -GIǁ ˆa€À  -‚O -I@Èÿƒ»IÇÁ -À  - - - -@ x Ç€ª - ->€À  -@x -É  - -€x QL FLBL -@L‡r@ǁ -Éÿ¿É?ÀÂI‚ H‚ -ÃI‚ HR - ÂI   ÃI€x ‘  ÃI   ²I ‘ ‡À €€ - -L -H2X -  IHÀï -À  - - - - - - - - - - - - -AL"CL¢Çh ޘ@ -Þ - -€ÀÈ€ÈÀ  -ˆ - - -‡€È - -ˆ -@x € Àa - -I -ÇA@_€`ÀË -…€T@á GL€   À¬~  -U - - -ÈA@ - - - - - - -Çs€ ‡s€ E€Ë€ËÀg -ƒ -…€a - - -Œ€L@a - -„ -„ -E@a -@ -Œ€L - -D -GIǁ  -I@ -   ‡! †À¥ -<€Ȁa -E<€ÇB€ - -ÇB - - =€È -E=€„=€Å=€  E D’€L>€L€¡ -Çb - -D@À @€ - -@x HR& ‰b@I"@J¢@Hb ‰’ - - -Âß]I6d127c5 -€ y -ÀG@, -% -I€` - - -@”x -@:LÇa - - - - -@-y -Ç€Ào -È€Àc -È€HCc -€ÇÀ€É€IÀ -€x -*L6Lǁ ÈQ ;LH2  -Çñ€H -L À` - -Ç@@ÿ I -À -x À2y Ç€Ào -Ç€‡À   - -@x  €À  -È -2 - -( G€GÀCGÀï -€¯ -€ % & & & ÇC€ÀŠ D€@f &LÀo - - + +  GÀ   ¢ Ç @@ -18484,19 +12754,19 @@ Gd ¬ Q ?€ -R P +R PÀ8 C.  - + Ë?€ˆ€ NI HB€ À  Àþ Ë@GA€ÇÀŠ -G€È€‚A €C HÀH +G€È€‚A @H HÀH D€@b ÇC€À¡  -ˆÀ - +ˆÀ + ‰€É € Ào @@ -18525,14 +12795,14 @@ ZÀ` É @  ÉÀË?€ˆ€ NI HB€ À  Àþ Ë@ˆ - -  + + Àµ ¢€  € LJ£€ - À² + €· D€€a @a @@ -18549,10 +12819,10 @@ ZÀ` Šl¢ Êëâ -€ -x ‡À +Ày  +x ‡À @À -Ä €‚À€ÀŠ +Ä €‚À€ÀŠ  ǀȀ¢@ ‡’€ D€Àa @@ -18566,7 +12836,7 @@ x ‡À ÀÀÀ‡ ÀÇ ÀA€ -@Í # GÀÀÀˆ + €\ ˆ ÀÇ È @@ -18575,7 +12845,7 @@ H   - +  ǀȀ¢@ ‡’€ D€Àa @@ -18590,7 +12860,7 @@ H ÀÀÀ‡ ÀÇ ÀA€ -@³ # GÀÀÀÈ + €\ šÀ  È Àˆ @@ -18616,32 +12886,32 @@ GA€ÇÀ` @x €ÀÀ‡ €G  - +  € ÀÀx ÀÀÀÀ -IÀ€ˆ #  +IÀ@ # À  €ˆÀˆ€ÈÀˆ€À€HÀˆÀÀx  €È!€ˆÀÈ#€ÈÀÀ(€HÀˆÀH5€ÈÀÇÀa  € À@x À¢ -‰€ +‰€À€ # @ I@À   QLFLˆ€AI€H‚ ‚p "@ȁ CLˆ‚@ -@Lˆ‚@ÈÀ ÀÀ‹ +@Lˆ‚@ÈÀ À€ H -a  @· +a    Œ €G€¡ -É +É  ID€ €` -@á~ +@á~ @¢x ‡ -@x Ç@‡À  + I€É€‹€Ë@‹ Š Ç @@ -18650,15 +12920,26 @@ I€É€‹€Ë@‹  @a G -H - -€¢ -Ë@ -€ˆ² -ÀË€ˆ@Ê¢ +H +Ç +ÉÇ + +@€J +AJÀ' +ˆ +È +ÑI +" +È +B‚JÀ„$ +€ŠÂ‚ÊÀˆ# +H€ +CƒJÀ" +ˆ€ŠÃƒÊÀ ! +ȀŠG  €ÇA ÈQ@ -G +G  €ZÀ` É@È È Ù@  @@ -18672,7 +12953,7 @@ I@@x @‰€É@ €  @¡ Ç -m€mi€€˜ +m€mi€ @a J @@ -18682,7 +12963,7 @@ x €Èñ@ a Ö GL€ˆL€Èa H - + €x @d @@ -18708,13 +12989,13 @@ Q R P PC ó€L€ï ‡’€ D€Àa ÇC€@¡ - + J - + €ö J È€ b€ €x ’@È€ R€ -ÉÀ +ÉÀ GB€   @@ -18725,21 +13006,21 @@ G ÇC€À` @x ÇsÀ ‡s€  - €š +  LÇ! €o - + H -  -€š +  + € €ÂÀ €  Àx CtÂ€‚ - +@~ P€À£ À!x  @@ -18875,22 +13156,21 @@ H *AL+CL«Êh jê@ j - -Âß]I6d127c5 + € @¡ I€` -@ûx ‰€` +@üx ‰€` -Ç  - @î +Ç  + Àõ ‚ -@ty Ç€Ào +À{y Ç€Ào ÇC€Àc )LÄâ  - +€wy € G€‡ÀG€GÀ% & & & ÇÀr€ ! €@¡  GÀ  @@ -18917,12 +13197,12 @@ Gd ¬ Q ?€ -R P€û +R P  Ë?€ˆ€ NI HB€ À  Àþ Ë@GA€ǀ¢ -G€È€r@ €  HÀH +G€È€r@ ‰€É € Ào @@ -18942,15 +13222,15 @@ H€¡ ÐI À  -Ç  - À‹ +Ç  + @“ ¢€  € LJ£€ - € - +  + L Š€   €  €‚À @@ -18961,10 +13241,10 @@ H€¡ Šl¢ Êëâ -Àêx  -x ‡À +@òx  +x ‡À @À -Ä €‚À€ÀŠ +Ä €‚À€ÀŠ ÀÁÀÀÀqÀÀÀ € @@ -18973,7 +13253,7 @@ x ‡À ÀÀÀ‡ ÀÇ ÀA€ -@¯ # GÀÀÀˆ +À¶ # GÀÀÀˆ €\ ˆ ÀÇ È @@ -18982,7 +13262,7 @@ H   - + ÀÁÀÀÀqÀÀ!ÀGÀ` €x Z À@x š @@ -18992,7 +13272,7 @@ H ÀÀÀ‡ ÀÇ ÀA€ - +€  # GÀÀÀÈ €\ šÀ  È Àˆ @@ -19018,38 +13298,49 @@ GA€ÇÀ` @x €ÀÀ‡ €G  - +  € ÀÀx ÀÀÀÀ -IÀ@n # Àn +IÀÀu # @v  €ˆÀˆ€ÈÀˆ€À€HÀˆÀÀx  €È!€ˆÀÈ#€ÈÀÀ(€HÀˆÀH5€ÈÀÇÀa  € À@x À¢ -‰€Àa # @b +‰€@i # Ài  QLFLˆ€AI€H‚ ‚p "@ȁ CLˆ‚@ -@Lˆ‚@ÈÀ À€s +@Lˆ‚@ÈÀ À H -a   +a  €Š  Œ €G€¡ -É +É  ‡ - -I€É€ÉÀç + +x Ç@‡À  +I€É€ÑIÀ  +Ç ÉÇ - - -H -ˆ -È + +@€J +AJÀ' +ˆ +È +ÑI +" +È +B‚JÀ„$ +€ŠÂ‚ÊÀˆ# +H€ +CƒJÀ" +ˆ€ŠÃƒÊÀ ! +ȀŠG  €ÇA ÈQ@ -G +G  €ZÀ` É@È È Ù@  @@ -19073,7 +13364,7 @@ x €Èñ@ a Ö GL€ˆL€Èa H - + €x @d @@ -19113,7 +13404,7 @@ LÇ! €o H -  +  Àµ € €ÂÀ @@ -19121,7 +13412,7 @@ H  Àx CtÂ€‚ -ÀY~ +@R~ P€À£ À!x  @@ -19249,388 +13540,7 @@ HØ *AL+CL«Êh jê@ j - -Âß]I6d127c5 - € @¡ -I€` - -Àóx È# - -Ç  -  -‚ - -ÇC€Àc -)LÄâ  - - -Àsy -€ -G€‡ÀG€GÀ% & & & ÇÀr€ ! €@¡ - GÀ  - ¢ -Ç - -@o -@€Í?¡  - - -Ê - -/G¡ -Ê€JÀ -ÉFa - - -€ŠÀÈ; -€  - -Gd -Ê€JÀ - €  À  -¬ -Q -?€ -R P@ - - -Ë?€ˆ€ NI HB€ À  -Àþ Ë@GA€ǀ¢ -G€È€r@ @ HÀH -‰€É -€ -Ào -G€‡À#LB0 €o - - ÇA ÈR LI - -% ‡Š -H€¡ -À` - -‰ - -É -ÀŽ ÉÀË?€ˆ€ NI HB€ À  -Àþ Ë@ˆ - -ÐI -À  -Ç  - €‘ - -¢€ - € - -LJ£€ - @“ - -L -Š€ -  €   -LÊ?! - -LJ§À - J§€ ʧ€ - €‚À -¬¥ -ÁI€€ -Ê,¢ -Š­¢ - -Šl¢ -Êëâ -€ìx  -x ‡À -@À -Ä €‚À€ÀŠ -ÀÁÀÀÀqÀÀÀ - -€ -À‡ -€G -ÀÀÀ‡ -ÀÇ -ÀA€ - -€\ ˆ -ÀÇ -È -È -H - - - - -ÀÁÀÀÀqÀÀ!ÀGÀ` -€x Z -À@x š -€ -À‡ -€G -ÀÀÀ‡ -ÀÇ -ÀA€ -Àœ # GÀÀÀÈ -€\ šÀ  -È -Àˆ -ÀÇ -È -È -H -€òÀÇ À¥ - -€  -ÇñÇ@ÇñGÀG -€  -ÇñÇ@Çñ‡À‡ -€  -ÇñÇ@Çñ@ x ÇÀ -€ À¢ -ÇñÇ€€È1@ @€H‚ -€ À¢ -ÇñÇ€€È1@ @€H‚ -€ À¢ -ÇñÇ€€È1 -GA€ÇÀ` -@x €ÀÀ‡ -€G - - - -  € ÀÀx ÀÀÀÀ -IÀ - €ˆÀˆ€ÈÀˆ€À€HÀˆÀÀx  €È!€ˆÀÈ#€ÈÀÀ(€HÀˆÀH5€ÈÀÇÀa - € À@x À¢ -‰€€e #  - -QLFLˆ€AI€H‚ -‚p "@ȁ -CLˆ‚@ -@Lˆ‚@ÈÀ À@w -H -a   - - -Œ - €G€¡ - -É - -‡ - -I€É€ÉÀç -ÉÇ - - -H -ˆ -È - -€ÇA ÈQ@ -G - €ZÀ` -É@È -È Ù@  -I@@x @‰€É@ -²  -°  -± É -@x ‡€ÇÀˆÀ… - -‡€‡Àa H -€  -@¡ -Ç -퀭W€ÀŒ - @a -J - - - -x - -€Èñ@ -a Ö GL€ˆL€Èa H - - -€x -@d - -Y€Ja  -Èd - -Y€ -a -@€ˆ‚ -YÀ@x -ü¢ „b -Y€ -a H‚ -¬ -Q R P PC ó€L€ï - -¬@ - - LÀ - -È€ b€ - -ÉÀ -GB€ -  - -@x -G -‡ -Ç@ -@x - ÇsÀ ‡s€  - €™ -LÇ! €o - -H - - -  -€Ž -€ €ÂÀ -€ - -Àx -CtÂ€‚ -ÀU~ - -Pî -P€À£ -À!x  - - -/Ç£ -P€d@Ñ€Q€QÀà  -¢RÀ  -À¢Á¢@À -B€RÀ¢ -@€@x A€ÑÀc -€ N’ €Ž -Q@ÑÀ‘€Q@ -b¡RÀ  -`¡a¡Ò€€¢ -€ N’ D€ €€Ý ÒÀ -‘€@§ -Q@QÀ& ‘ÀЀÐÀ  - - -x ü/Ç  -„ - t ’ €4‚ T -  - -‘€Àü -B¡Á  -@¡A¡€À /Ç  -ßßÀô P€”@P’€‘‘ÀP4@€€a -ÐÁ Ð -ß -ˆ -ŽIˆ| -Ž I z Ê -"p  ˆ ‚À"h Š €Ê Ê€ - € -bp -À  -@ÿ @ I € ɐ€  À ɐÀ  -SIŠ - À  -@þ I@ -I À  - -€o -I@ -=LŠ¢€ʀï -ŽI - € É€‰bp -Ž  - À -Ž :Lb - L L 8L€ -    8  - /€Ëÿ¿$ -€€€‹@Š -! Ša " ça # Ž €Λ -Ç?€‡À -‡€Ç?a Ç  ÇÁA‡ÀPCÇñ€G€ï - -‡ -Àó -À€€ȁ -¬ - -Q -?€ -RÀí P#LGÀï -Ç€Èq@ - -Â. Š - -Â. Š - -Â. Š - -ˆ -­W€Z - -Â. Š -€  -ÀLx -‰€ À` - -‰€ À  - -À x ˆ€@Ç€€é Ç@ €Hbd 0 H€@Ç€€ç Ç@H €Hbd 0 €ˆ€r@ÇñG@Ç€€r@ÇñÇ@G’R  €Hbd 0 €ˆ€ÀÑ ‰€€Hbd 0 Ç€€ -Œ€ -Ç€Ç@ˆ€@€x  - -Ç€Ç@ˆ€ - -Ç€Ç@H€@Àx  -Ç€Ç@H€ -Ç@Ç -Ç@ˆ€À` - -@ -Ç@Ç -Ç@ˆ€À` - -@ - -Àx €ˆ€ -€x €€Ç@ # - À¡ - - - À¡ -I - -@ˆ€@Œ€¡ -L@¡ - -I@‰€I@Œ€¡ -L@¡ -I - ‘ @x ’  ‘ ’ “ ” € -Z€  - -ˆXØш‡ -ˆPÈH ‘ȈÐ -ˆXØ -HØ -*AL+CL«Êh jê@ -j - - -Âß]I6d127c5 + 3À  €ý  @@ -20176,10 +14086,10 @@ HsÀ À@R # LJ @U~    - +  ¡ r€€  -@D~ G@Q +ÀC~ ‡ þ I “ €6~ @@ -20460,8 +14370,7 @@ q €±À  @¡ À  €i - -Âß]I6d127c5 + 3À  €ý  @@ -21008,10 +14917,10 @@ HsÀ À@R # LJ @U~    - +  ¡ r€€  -@D~ G@Q +ÀC~ ‡ þ I “ €6~ @@ -21292,656 +15201,7 @@ q €±À  @¡ À  €i - - -@þ ÁÀ` - - -Àx -Àû Á` - - -  -€ -À - -€ - - - -Àä -E€FQ@ - - - - - -Æ1 †1 -˜N† €  -ÆO -N†! À  -ÆÁN - - - - -€ - - -A@€A`€ - - - -@€`€AðƒA0@ - - -CLŠ€ -˜¯  - - - - ÉÀòÀˆ¡ -Å  -€x -IÀ  -I - b€ - -H -H -ˆ` - -ȃ¡ -‚` -@Fx @î €^x - - -Àˆ -À  - -ÀÀŠ -À -À€¥ - - €H À@Ÿ -É À -’ -’ - - - - -’ -È@ - À -ÈB @ - ÀÏÀ - -‰€ -ËIJ¢À -Ë  ÒIHrR @› -À» -FLH€A €Ȃ -€¢ - -È€HÀ€ŽÀ - -ÌIJ¢À -Ì  ÒIH’@ €z -Q - - -!€€` - -Àš -H -HÀˆ -‰€ À¡ -É¿¡ -ˆ€ÉÿŸH2@ -À† -b€ -H’@ €p -b€ -HrR @d - - -€H€  -Ê - -É€J2€ - - -I€H2€ - -€@e -H -€€@a -‰€H2€ - - -@7 -€H€` - - -H¢ -€HÁ  -À x -ˆ€ -È€À) -B€ Š - € €ŠÁ  ̀̀ @€ - -ÍÏ  -ŠAa Ía -€÷ ð€ Ì -M@H€ -2€ - - € €ŠÁ  ̀̀ €£ -ˆ -ÍÏ  -ŠAa Ía - -M@ÊÁ  -€A - Ò -À? -¢ -¡ -M@a -€x -€ ‚@ -Ȁ€ ȀÀ ) Ž € - - -È€HÀ@â - - - - - -€J - - - - -€@ - -@€‰’ -`€€ -€@ - -@€‰’ -`€€ - -€‰’ -8€€ - -€‰’ -8€ -R -ÎIJ¢ -Q P PCIò€I€ï - - -X -I -K@É€ɂp ‰ -€ɂ` Á È - -À ÂIKÀË! ‹À@H -ˆ€€b - -@X - ‚  㠋€ À  -Ë -¢@Èÿ¿ -¢ - ‚ -H -@? -€ x €I¢ -É€ €¡ - - - - - # E -…"@ €  #  - -1 €ß~ Ê H  - - -ˆ €@£ -È€À  -ȐHÉÿ¿Hr€ -I€H €ÈH@I -@Ù -€á -€€J€“€À³ - B €ü # EBH Àû # EBP B À€@  - - - - €€ô # E"@ ! @æ -À„ -ˆ €@£ -È€À  -ȐHÉÿ¿Hr€ -I€H €ÈH@I -@Å -€Í -ˆ€À£ -ˆ €@£ -È€À  -ˆÉÿ¿Hr€ -‰€H €ÈH@I -H€ѕ€H@ˆ€HÀÀœ -H€ѕ€H@ˆ€HÀ€Ã -€€J€“€ - - B @Û # EBH €Ú # EBP B À€@ À! Š€؀@ À  Ê€ÀÝ -I@€I`€ -€H@Êÿ I‚ -€H€  -€€ -ʀ£ -Ë€ˀ¢ -KÀ  -É -É -K -€ -H@€H`€  - & - -Í€ €@x K@Œ@Š -N -C Œ@Š - -€ -H@€H`€ €  -@x -N -C Œ@Š - -€ - -È -€  - -I€ -㏠Š -ÈIÎ> €¡ -΃  -Ï@ƒP È Î€ - - -Ž€@b -ÈI΃ Àm -΃ -Ñÿ¿ÄÀQ€’€Ra Ñ -ÖI×I@ - -O€Àb -€ -ÏÿŸä€ -Àx ä€ -’ÀÿŸÀx ÀÏÿŸd€ -Ð À  - -ЀPÀ  - -€P€ - - -K„ - - -O -@l - - ÀÀ €ý Œ@L" IÀl -  À  -Ž - - @€ `€J -2 -£@M - @€ `€J -Š - -Ž -8 -€€ €@ˆb€  - €Šˆb@  - -Žó‡ - - - -Ó@Ó@ - @€ `€€ËÔÀ -ˆÂ@ Àí  -Ë#€ô -K#€Ô - - @€ `€H‚ -ÖI×I@ - -…á -E -À - - @€ `€J - á Š2@Ê¢ -I -È -£@Ìÿ¿ -£ -Õ€€U… -Q -Òÿ¿@ -@€`€€ # Å@€ -@¯ -Eã - -À -€ -À -URAU@2@ APÈ€Ô€Ô - - - - á Š2@Ê€ -5€ -€ý  - î Š2@Ê€ -5 - -URAU@PõŒ €ó PA@ #  - - - -àà €þ  -€` -€P -ՁÀOÀ“ÀÔ€Ô -Õ$À x R -x ÒÏ €P - -€$`À - - -€€‰ -€ ’ - @€ `€J - -Š - -Ž - @€ `€3@Îâ -ÌÀÀ ŒÀÀ ÀÀ Œ@Ž@Œ -È -£@Ìÿ¿ -£ - @€ `€J - - -Š - -Ž -€ö - @€ `€3@Îâ - Ѐ @Q - - -€þ -L -L - -@‰ € D É€ @ *À - - -CLŠ€ -˜¯  - - -Òî Ëÿƒ À­ -Ë@NH2 - -$ - -€¡ -HÀ` -€x - -À  - -H€ˆ€  -ÀIx €yx ˆ€  - - - - -ÎI‰’ - -I -Ê€ʀ¢ -Ë@Ë€Iˆ€€ Ȁ€  QIȃ€ Q Ë&ÀÈ € -"D È Àˆc -Ê -B@ Q IH„€  H€ˆÀ  -䆁dN€ -ˆ€ -  - ȃÀ ˆƒ€ À° -  %€ -L" €o -[(€ -È € -€ˆƒ¡ - -(ÀŠ€ -(À -€ˆƒ¡ - -(ÀŠ€ -(À -È € -€ˆƒ¡ - -(ÀŠ€ -(À -€ˆƒ¡ - -(ÀŠ€ -(À -ˆ(€È(À -Ë'€ @o -Ë - -'LŠ!  ! " # É(€Ja '   -'LŠ!     ‰(€Ja '   -CJÀï *€Ã@ x % LLLL'L Ÿ! H!€€c -I(€ - -€o -Š@Ë -)€ÊQ J!€ʂp L*€&€ˆ)À#LHB0 €o -H - B R À  -&À@x HBŠ -% ˆBŠ -Hƒ¥ -IÀ¡ -ˆƒ¥ -À` -Àx -Š -'ÀÌ'€ Ào - -'À& & &  '€‰ -Ê -@%x -'À%‡  -U@ï Ìÿƒ‰'€ - NŠ ‰B€ À  -Àþ @‰ - N  @o -M@ N  @n -Ì'€ Àm - -'À -ˆ(€È(À - -'LŠ!  ! É(€Ja '   -'LŠ!   ‰(€Ja '  *€Ã% Ë'€ Ào -Ë -)€ÊQ J!€ʂp @x LL'L Ÿ! H!€€a -I(€ -À  -Ë'€ @o -Ë -)€ÊQ J!€ʂp &€ˆ)À#LHB0 €o -B &Àˆ¡ -% & & & À‚€ ! ˆ#€@¡ -  HÀ  - ¢ -CJÀï ÀÊ €Šƒf -U@& -‹)€ À¡ -K'€ -Ê'€ -@o -Š'€Š@@m -€‰"P -! & ‰ - - - -I -K!€%‡£ -  -%G¡ -‹!€KÀ -ÊFa -Î - ‡d - #€KÀ - €  À  - -H!€ - €JI €€%‡b -@ -x -Ë -x @  -Ê"€ˆ!€HÀ' - -" -‹!€KÀ+ -È -€x  - -Ç` €€ À€ - -" -" -Ê"€ - -¢ -a I - - -=L¢€Ȁï  -%€e€Ìÿ¿ - ]a  ža    '   -    €O© -È?€È"À -È"€È?a Ç  ÂAÈ"ÀPCò€H€ï - -ˆ -ÎI‰’ -@ó K#À€€ ’ - -ÎI‹² - - @ˆ -  HÀ  - ¢ -€‰"P -! & J -æ'€ŠÀ€ -À*x ' -VÀ -@x š%€šÀê -i)€%G¥ -Š"€Ši@š!€(€' -Š (\€(! Àx –ŠY@š!€' -'¢hÀ  -'À¢'Á¢) -'@Àæ€æiP é| '& -'zB'zBf&€š&€š a Š™@æiæ9@'è#€(@£ -'B€hÀ¢ -'@€@x 'A€çÀd -Š'€( N( - &jŽ -'ÀÀæ€æiP é| ' -ç@ç%À§%€ç@À x §%Àg$€§$Àf&€š&€š a Š™@æi((€'zg$Àæ9@'è#€(@¡ -'b¡hÀ  -'`¡'a¡è)€(€¢ -Š'€( N( - &J€ š$€ -€ô §'€ç -' -§%€' -ç@g€" §%À&'€æÀ  - -VÀ -–‰ - –y ( €&j‚ &: -–  -VÀ -'$€@ü -&B¡'Á  -&@¡&A¡&€À %Ç  -–– -æa &æ -– -NŠ J€ï - - -JGà -  - I - € Ê € -  - À Ê À -  - -D  - -E  - IJ - À  -@ÿ I@ - I - € Ê € -  - À Ê À -  - -À  -@ÿ Š@ -ÊߏÊÿüNˆ‚€‡ LJ’À -J2€ Àx ˆ†€ Š -Š@Ȇ€ - -‡‚0 -À` -Š + @þ ÁÀ` @@ -22590,7 +15850,7 @@ J2€ Àx ˆ†€ Š ‡‚0 À` -Š +Š @þ ÁÀ` @@ -23239,657 +16499,7 @@ J2€ Àx ˆ†€ Š ‡‚0 À` -Š - -@þ ÁÀ` - - -Àx -Àû Á` - - -  -€ -À - -€ - - - -Àä -E€FQ@ - - - - - -Æ1 †1 -˜N† €  -ÆO -N†! À  -ÆÁN - - - - -€ - - -A@€A`€ - - - -@€`€AðƒA0@ - - -CLŠ€ -˜¯  - - - - ÉÀòÀˆ¡ -Å  -€x -IÀ  -I - b€ - -H -H -ˆ` - -ȃ¡ -‚` -@Fx @î €^x - - -Àˆ -À  - -ÀÀŠ -À -À€¥ - - €H À@Ÿ -É À -’ -’ - - - - -’ -È@ - À -ÈB @ - ÀÏÀ - -‰€ -ËIJ¢À -Ë  ÒIHrR @› -À» -FLH€A €Ȃ -€¢ - -È€HÀ€ŽÀ - -ÌIJ¢À -Ì  ÒIH’@ €z -Q - - -!€€` - -Àš -H -HÀˆ -‰€ À¡ -É¿¡ -ˆ€ÉÿŸH2@ -À† -b€ -H’@ €p -b€ -HrR @d - - -€H€  -Ê - -É€J2€ - - -I€H2€ - -€@e -H -€€@a -‰€H2€ - - -@7 -€H€` - - -H¢ -€HÁ  -À x -ˆ€ -È€À) -B€ Š - € €ŠÁ  ̀̀ @€ - -ÍÏ  -ŠAa Ía -€÷ ð€ Ì -M@H€ -2€ - - € €ŠÁ  ̀̀ €£ -ˆ -ÍÏ  -ŠAa Ía - -M@ÊÁ  -€A - Ò -À? -¢ -¡ -M@a -€x -€ ‚@ -Ȁ€ ȀÀ ) Ž € - - -È€HÀ@â - - - - - -€J - - - - -€@ - -@€‰’ -`€€ -€@ - -@€‰’ -`€€ - -€‰’ -8€€ - -€‰’ -8€ -R -ÎIJ¢ -Q P PCIò€I€ï - - -X -I -K@É€ɂp ‰ -€ɂ` Á È - -À ÂIKÀË! ‹À@H -ˆ€€b - -@X - ‚  㠋€ À  -Ë -¢@Èÿ¿ -¢ - ‚ -H -@? -€ x €I¢ -É€ €¡ - - - - - # E -…"@ €  #  - -1 €ß~ Ê H  - - -ˆ €@£ -È€À  -ȐHÉÿ¿Hr€ -I€H €ÈH@I -@Ù -€á -€€J€“€À³ - B €ü # EBH Àû # EBP B À€@  - - - - €€ô # E"@ ! @æ -À„ -ˆ €@£ -È€À  -ȐHÉÿ¿Hr€ -I€H €ÈH@I -@Å -€Í -ˆ€À£ -ˆ €@£ -È€À  -ˆÉÿ¿Hr€ -‰€H €ÈH@I -H€ѕ€H@ˆ€HÀÀœ -H€ѕ€H@ˆ€HÀ€Ã -€€J€“€ - - B @Û # EBH €Ú # EBP B À€@ À! Š€؀@ À  Ê€ÀÝ -I@€I`€ -€H@Êÿ I‚ -€H€  -€€ -ʀ£ -Ë€ˀ¢ -KÀ  -É -É -K -€ -H@€H`€  - & - -Í€ €@x K@Œ@Š -N -C Œ@Š - -€ -H@€H`€ €  -@x -N -C Œ@Š - -€ - -È -€  - -I€ -㏠Š -ÈIÎ> €¡ -΃  -Ï@ƒP È Î€ - - -Ž€@b -ÈI΃ Àm -΃ -Ñÿ¿ÄÀQ€’€Ra Ñ -ÖI×I@ - -O€Àb -€ -ÏÿŸä€ -Àx ä€ -’ÀÿŸÀx ÀÏÿŸd€ -Ð À  - -ЀPÀ  - -€P€ - - -K„ - - -O -@l - - ÀÀ €ý Œ@L" IÀl -  À  -Ž - - @€ `€J -2 -£@M - @€ `€J -Š - -Ž -8 -€€ €@ˆb€  - €Šˆb@  - -Žó‡ - - - -Ó@Ó@ - @€ `€€ËÔÀ -ˆÂ@ Àí  -Ë#€ô -K#€Ô - - @€ `€H‚ -ÖI×I@ - -…á -E -À - - @€ `€J - á Š2@Ê¢ -I -È -£@Ìÿ¿ -£ -Õ€€U… -Q -Òÿ¿@ -@€`€€ # Å@€ -@¯ -Eã - -À -€ -À -URAU@2@ APÈ€Ô€Ô - - - - á Š2@Ê€ -5€ -€ý  - î Š2@Ê€ -5 - -URAU@PõŒ €ó PA@ #  - - - -àà €þ  -€` -€P -ՁÀOÀ“ÀÔ€Ô -Õ$À x R -x ÒÏ €P - -€$`À - - -€€‰ -€ ’ - @€ `€J - -Š - -Ž - @€ `€3@Îâ -ÌÀÀ ŒÀÀ ÀÀ Œ@Ž@Œ -È -£@Ìÿ¿ -£ - @€ `€J - - -Š - -Ž -€ö - @€ `€3@Îâ - Ѐ @Q - - -€þ -L -L - -@‰ € D É€ @ *À - - -CLŠ€ -˜¯  - - -Òî Ëÿƒ À­ -Ë@NH2 - -$ - -€¡ -HÀ` -€x - -À  - -H€ˆ€  -@Hx -€1x €ix - -ÎI‰’ - -I -Ê€ʀ¢ -Ë@Ë€Iˆ€€ Ȁ€  QIȃ€ Q Ë&ÀÈ € -"D È Àˆƒc -Ê -B@ - -Òy Q IH„€  H€ˆÀ  -d…äL€ -ˆ€ -  - ȃÀ ˆƒ€ À° -  %€ -L" €o -[(€ -È € -€ˆƒ¡ - -(ÀŠ€ -(À -€ˆƒ¡ - -(ÀŠ€ -(À -È € -€ˆƒ¡ - -(ÀŠ€ -(À -€ˆƒ¡ - -(ÀŠ€ -(À -ˆ(€È(À -Ë'€ @o -Ë - -'LŠ!  ! " # É(€Ja '   -'LŠ!     ‰(€Ja '   -CJÀï *€Ã@ x % LLLL'L Ÿ! H!€€c -I(€ - -€o -Š@Ë -)€ÊQ J!€ʂp L*€&€ˆ)À#LHB0 €o -H - B R À  -&À@x HBŠ -% ˆBŠ -Hƒ¥ -IÀ¡ -ˆƒ¥ -À` -Àx -Š -'ÀÌ'€ Ào - -'À& & &  '€‰ -Ê -@%x -'À%‡  -U@ï Ìÿƒ‰'€ - NŠ ‰B€ À  -Àþ @‰ - N  @o -M@ N  @n -Ì'€ Àm - -'À -ˆ(€È(À - -'LŠ!  ! É(€Ja '   -'LŠ!   ‰(€Ja '  *€Ã% Ë'€ Ào -Ë -)€ÊQ J!€ʂp @x LL'L Ÿ! H!€€a -I(€ -À  -Ë'€ @o -Ë -)€ÊQ J!€ʂp &€ˆ)À#LHB0 €o -B &Àˆ¡ -% & & & À‚€ ! ˆ#€@¡ -  HÀ  - ¢ -CJÀï ÀÊ €Šƒf -U@& -‹)€ À¡ -K'€ -Ê'€ -@o -Š'€Š@@m -€‰"P -! & ‰ - - - -I -K!€%‡£ -  -%G¡ -‹!€KÀ -ÊFa -Î - ‡d - #€KÀ - €  À  - -H!€ - €JI €€%‡b -@ -x -Ë -x @  -Ê"€ˆ!€HÀ' - -" -‹!€KÀ+ -È -€x  - -Ç` €€ À€ - -" -" -Ê"€ - -¢ -a I - - -=L¢€Ȁï  -%€e€Ìÿ¿ - ]a  ža    '   -    €O© -È?€È"À -È"€È?a Ç  ÂAÈ"ÀPCò€H€ï - -ˆ -ÎI‰’ -@ó K#À€€ ’ - -ÎI‹² - - @ˆ -  HÀ  - ¢ -€‰"P -! & J -æ'€ŠÀ€ -À*x ' -VÀ -@x š%€šÀê -i)€%G¥ -Š"€Ši@š!€(€' -Š (\€(! Àx –ŠY@š!€' -'¢hÀ  -'À¢'Á¢) -'@Àæ€æiP é| '& -'zB'zBf&€š&€š a Š™@æiæ9@'è#€(@£ -'B€hÀ¢ -'@€@x 'A€çÀd -Š'€( N( - &jŽ -'ÀÀæ€æiP é| ' -ç@ç%À§%€ç@À x §%Àg$€§$Àf&€š&€š a Š™@æi((€'zg$Àæ9@'è#€(@¡ -'b¡hÀ  -'`¡'a¡è)€(€¢ -Š'€( N( - &J€ š$€ -€ô §'€ç -' -§%€' -ç@g€" §%À&'€æÀ  - -VÀ -–‰ - –y ( €&j‚ &: -–  -VÀ -'$€@ü -&B¡'Á  -&@¡&A¡&€À %Ç  -–– -æa &æ -– -NŠ J€ï - - -JGà -  - I - € Ê € -  - À Ê À -  - -D  - -E  - IJ - À  -@ÿ I@ - I - € Ê € -  - À Ê À -  - -À  -@ÿ Š@ -ÊߏÊÿüNˆ‚€‡ LJ’À -J2€ Àx ˆ†€ Š -Š@Ȇ€ - -‡‚0 -À` -Š -Âß]I6d127c5 +Š @x @þ ÁÀ` @x @@ -24536,7 +17146,7 @@ J2€ Àx ˆ†€ Š ‡‚0 À` -Š +Š €– €x @‡x þÀ @@ -24565,54 +17175,54 @@ H@Š À@JÃo - + -@x +@x A¡ € Î €x @x À - - - -H€€.Àˆ.À À  -ˆ€!€H.ÀÈ.À€x ߀H&€É€Hb€ -'€€ h&€@]x ÿÀ - -I#€ À  - + + + +H€€/Àˆ/À À  +ˆ€"€H/ÀÈ/À€x ߀H'€É€Hb€ +'€€ h'€@]x ÿÀ + +I$€ À  + #Fˆ‚€ #-FH€€ - - - + + Œ À` -Œ +Œ €ÿ   -Eˆ‡€ E € "` I € "d ˆ-€É-€ ¢` -€ BX I-€ Bx Š-€ˆ.€ˆ‚ -/€I/€‰¢` '(€ +Eˆ‡€ E € "` I € "d ˆ.€É.€ ¢` .€ BX I.€ Bx Š.€ˆ/€ˆ‚ +0€I0€‰¢` '(€ - - - /€Š-€‰"€ + + + 0€Š.€‰"€ @x É@H Ê@   -I/€H -Ì@ Ë@@ +I0€H +Ì@ Ë@@  - “@K² + “@K² H€01DH¢ HR €n - -/€@a -I#€ À  + +0€@a +I$€ À  @† @@ -24620,51 +17230,51 @@ I#€ À  À~ -€ +€ @a - €@ + €@ Î> €~ Ž@Àþ M@ €Ò@LÀ J Î> €~ Ž@Àþ M@ €Ò@LÀL Àà - + "Ab !H! ÀZ -_ñÁ I#€ €€ +_ñÁ I$€ €€ @ x É© + -@ñ +@ñ ×@ - + ¡ À Àr À -À -‰.€H2€ - - -€x -x ‰.ÀI -! +À +‰/€H2€ + + +€x +x ‰/ÀI +! À -! -J Jˆ +! +J Jˆ @x ¢BX HÀ` €x ¢BP ˆÀ` À -! +! JH H@¡ JH ˆÀ  JH JH A‡1 - + À x IÀ¡ ‰@¢ ɀŠ @@ -24678,26 +17288,26 @@ JH JH ÉA§ ` Àx -!Àˆ"€J@‰’ +"Àˆ"€J@‰’ @È@ ² @H3€ @Ê€  @È@ ² @È"@I -@ +@ À€K À€K - + À€‹  À€‹ -À€K +À€K 3@€À   -À€‹ +À€‹ 3@€À   @@ -24706,53 +17316,53 @@ JH JH Š€I@J¢@ B` H€€ I € "| €¡ Š€I@J¢@ -Bh H€€ %G‰€ @ B D ‰ € "H  G € "@ I € "H "P  D € @ I€ B  D € "@ I € "D   -€HHÀ0€ˆHÀÈ€I€I@H‚ÀÈHÀˆ€IÀÈ€HIÀ€‰I€ € - +Bh H€€ %G‰€ @ B D ‰ € "H  G € "@ I € "H "P  D € @ I€ B  D € "@ I € "D   +€HIÀ1€ˆIÀÈ€I€I@H‚ÀÈIÀˆ€JÀÈ€HJÀ€‰J€ € + H€ € HÀ -#€I€ HÀ -ˆ#€‰€ HÀ -È#€ɐ€ HÀ -$€ ‘€ HÀ -H+€I‘€ HÀ -ˆ+€‰‘€ HÀ -(€ɑ€ HÀ -H(€ ’€ HÀ -H,€I’€ HÀ - -R€È0€  +$€I€ HÀ +ˆ$€‰€ HÀ +È$€ɐ€ HÀ +%€ ‘€ HÀ +H,€I‘€ HÀ +ˆ,€‰‘€ HÀ +)€ɑ€ HÀ +H)€ ’€ HÀ +H-€I’€ HÀ + +T€È1€  ‰2@ @þ I - -Š -® ˆ‚ + +Š +® ˆ‚ €ï -@ - 0ÀÀ +@ + 1ÀÀ - 0€I€ 0À + 1€I€ 1À €J¢@ɑ€  A ˆ‚€H@M @ - -I/€Š€‰2@ Ê-€‰Â@ + +I0€Š€‰2@ Ê.€‰Â@ @ €n F‰> Àm - +  -/€^a Ѐ ’ -J;€ˆ +0€^a Ѐ ’ +J<€ˆ b I@@õ %A#ú€$AdIA #€ï ã@#€€äA €€$ €@M - - + + @3x Š€ã€$@‚#™À $ @@ -24770,14 +17380,14 @@ $ð‚£9#I €÷ $$€f $"€€x - -%>€å€` + +%?€å€` À x %` -@)x %>€£ ! d€Ÿ&é€ +@)x %?€£ ! d€Ÿ&é€ d %  @x -$$€$$€$ +$$€$$€$ $A$> $ @@ -24785,14 +17395,14 @@ $A$> $ äcÀ d€! - + åQ f9@ @ x e<€&Êa d)eÀà x ¥€æIa deÀ @ x å€$Ò@€@æ $) ä€a -ã€#:À Á@c‚@ Á +ã€#;À Á@c‚@ Á cÀ% fH£ Š£ @@ -24808,7 +17418,7 @@ e å %Œ` - + £i2 $$€$$€$ d € @@ -24821,17 +17431,17 @@ d € ä ä€fÅ $€$<€@ - + - -h€‰r + +j€‰r #Á -C@ “ - -`€‰B€ -@ö -`€‰B€ +C@ “ + +b€‰B€ +@ö +b€‰B€ Àô À (Ñ @@ -24971,45 +17581,45 @@ J s@J€H€ˆB€ JÀ€ï s@ A‡H> IÀH< ‰ÀH26 ÉÀH4 ÀH2 IÀ€S ‰€ - -Àª + +Àª € -x ÀF ‰€H€ÀÀE É€ˆ€!À AH> IÀ @¡ - +x ÀF ‰€H€ÀÀE É€ˆ€"À AH> IÀ @¡ + - -É#À $ÀI$À@x ‰$À A‚H> É#ÀH< €a - $ÀÀ9 I$€@9 ‰$€ AH> €b + +É$À %ÀI%À@x ‰%À A‚H> É$ÀH< €a + %ÀÀ9 I%€@9 ‰%€ AH> €b ˆ€€¢ €À  - + -€*} ÿÀ - - ?€ À¡ +€*} ÿÀ + + @€ À¡ É€Hr‚ ÀÉÿ  - + € ÀÀÀ s@ s@ À € À€ž s@J€H€ˆB€ JÀ€° -s@È%€ -‰&À@x I&ÀH€@¡ - -€J¢@ɑ€ ˆ‚€H&Àˆ&€À  +s@È&€ +‰'À@x I'ÀH€@¡ + +€J¢@ɑ€ ˆ‚€H'Àˆ'€À  ÀNx -ȁ€ À É&€ˆ€@¡ -I +ȁ€ À É'€ˆ€@¡ +I a - -€J¢@ɑ€ ˆ‚€H'À AH> @a - @€€â ΀ + +€J¢@ɑ€ ˆ‚€H(À AH> @a + A€€â ΀ @ x Š€ @¡ @@ -25017,55 +17627,59 @@ I ˆ€HÀ¥ ˆ€ˆÀ! I €A! ‰ €Â É € !€ A@x  A‰ €IB €J¢@ɑ€ ˆ‚€ AH>  AH> À  @÷ I - -(À + +)À A AH> €b -‰€‰bT ‰(À À` - - - -É/€IÀ Àþ +‰€‰bT ‰)À À` + + + +É0€IÀ Àþ A‰l - )ÀI€ @¡ - + *ÀI€ @¡ + @a -I +I À  -É(€‰(€I - +É)€‰)€I + €I€{DH2@ - - -+€ˆ‚ - - $€‰+ÀI$€É+À‰$€Àx ,À AH> €a -‰+À€É É+€ - -H(€@a -ˆ+€À  -@x -H#€€` -@x ÀÁ ‰,€‹,€ @£ + + +,€ˆ‚ + + %€‰,ÀI%€É,À‰%€Àx -À AH> €a +‰,À€É É,€ + +H)€@a +ˆ,€À  +@x +H$€€` +@x ÀÁ ‰-€‹-€ @£ ÀÀ I € £@ÌÁ€  A ˆ‚€H -Ë@H%€ +Ë@H&€ @œ I BHÀ/ - + -:€â I&€ À` -É&€‰ - +;€â I'€ À` +É'€‰ + +È&€ + BIB ‰A¡ +J€IÁ  +Ê€J€I'€‰’@BH‚ Á  -ÀC +À= €œ €x ÀŒx þÀ @@ -25094,59 +17708,59 @@ H@Š À@JÃo - + -@x +@x A¡ € Î €x  N @x À -€Nx - - -H€€.Àˆ.À À  -ˆ€!€H.ÀÈ.À€x ߀H&€É€Hb€ -'€€ h&€Àbx ÿÀ - -I#€ À  - +€Nx + + +H€€/Àˆ/À À  +ˆ€"€H/ÀÈ/À€x ߀H'€É€Hb€ +'€€ h'€Àbx ÿÀ + +I$€ À  + È€@c -@ˆ†€  - +@ˆ†€  + Œ À` -Œ +Œ I€ À IÀ L FÀ  -ɗ€ ɗÀ ˆ€É€ a ˆ-€É-€ a ˆ.€É.€ a +ɗ€ ɗÀ ˆ€É€ a ˆ.€É.€ a ˆ/€É/€ a €ÿ ER   -E € "` I € "d ˆ-€É-€ ¢` É€ ~ Š.€É.€‰¢` +E € "` I € "d ˆ.€É.€ ¢` É€ ~ Š/€É/€‰¢` ȇÀ -/€I/€‰¢` '(€€ê  +0€I0€‰¢` '(€€ê  - - - /€Š-€‰"€ + + + 0€Š.€‰"€ @x É@H Ê@   -I/€H -Ì@ Ë@@ +I0€H +Ì@ Ë@@  - “@K² + “@K² H€01DH¢ HR €n - -/€@a -I#€ À  + +0€@a +I$€ À  @Ž @@ -25154,9 +17768,9 @@ I#€ À  À† -€ +€ @a - €@ + €@ Î> €~ Ž@Àþ M@ €Ò@LÀ J Î> €~ Ž@Àþ M@ €Ò@LÀL @@ -25169,42 +17783,42 @@ H À  -@9 +@9 "Ab !H! ÀZ -_ñÁ I#€ €€ +_ñÁ I$€ €€ @ x É© + -@ñ +@ñ ×@ - + ¡ À @u À -À -‰.€H2€ - - -€x -x ‰.ÀI -! +À +‰/€H2€ + + +€x +x ‰/ÀI +! À -! -J Jˆ +! +J Jˆ @x ¢BX HÀ` €x ¢BP ˆÀ` À -! +! JH H@¡ JH ˆÀ  JH JH A‡1 - + À x IÀ¡ ‰@¢ ɀŠ @@ -25218,25 +17832,25 @@ JH JH ÉA§ ` Àx -!Àˆ"€J@‰’ +"Àˆ"€J@‰’ @È@ ² @H3€ @Ê€  @È@ ² @È"@I -@ +@ À€K À€K - + À€‹ À€‹ -À€K +À€K 3@€À   -À€‹ +À€‹ 3@€À   @@ -25245,51 +17859,51 @@ JH JH Š€I@J¢@ B` H€€ I € "| €¡ Š€I@J¢@ -Bh H€€ %G‰€ @ B D ‰ € "H  G € "@ I € "H "P  D € @ I€ B  D € "@ I € "D   -€HHÀ0€ˆHÀÈ€I€I@H‚ÀÈHÀˆ€IÀÈ€HIÀ€‰I€ € - +Bh H€€ %G‰€ @ B D ‰ € "H  G € "@ I € "H "P  D € @ I€ B  D € "@ I € "D   +€HIÀ1€ˆIÀÈ€I€I@H‚ÀÈIÀˆ€JÀÈ€HJÀ€‰J€ € + H€ € HÀ -#€I€ HÀ -ˆ#€‰€ HÀ -È#€ɐ€ HÀ -$€ ‘€ HÀ -H+€I‘€ HÀ -ˆ+€‰‘€ HÀ -(€ɑ€ HÀ -H(€ ’€ HÀ -H,€I’€ HÀ - -R€È0€  +$€I€ HÀ +ˆ$€‰€ HÀ +È$€ɐ€ HÀ +%€ ‘€ HÀ +H,€I‘€ HÀ +ˆ,€‰‘€ HÀ +)€ɑ€ HÀ +H)€ ’€ HÀ +H-€I’€ HÀ + +T€È1€  ‰2@ @þ I - -Š -® ˆ‚ + +Š +® ˆ‚ €ï -@ - 0ÀÀ +@ + 1ÀÀ - 0€I€ 0À + 1€I€ 1À €J¢@ɑ€  A ˆ‚€H@M @ - +  -/€^a Ѐ ’ +0€^a Ѐ ’ $@¢ £Y@æhB&iÀ - + -J;€ˆ +J<€ˆ b I@€ô %A#ú€$AdIA #€ï ã@#€€äA €€$ € - - + + Š€ã€$@‚#™À $ @@ -25308,14 +17922,14 @@ $ð‚£9#I €÷ $$€f $"€€x - -%>€å€` + +%?€å€` À x %` -@)x %>€£ ! d€Ÿ&é€ +@)x %?€£ ! d€Ÿ&é€ d %  @x -$$€$$€$ +$$€$$€$ $A$> $ @@ -25323,14 +17937,14 @@ $A$> $ äcÀ d€! - + åQ f9@ @ x e<€&Êa d)eÀà x ¥€æIa deÀ @ x å€$Ò@€@æ $) ä€a -ã€#:À Á@c‚@ Á +ã€#;À Á@c‚@ Á cÀ% fH£ Š£ @@ -25346,7 +17960,7 @@ e å %Œ` - + £i2 $$€$$€$ d € @@ -25359,17 +17973,17 @@ d € ä ä€fÅ $€$<€@ - + - -h€‰r + +j€‰r #Á -C@ “ - -`€‰B€ -@ö -`€‰B€ +C@ “ + +b€‰B€ +@ö +b€‰B€ Àô À (Ñ @@ -25512,45 +18126,45 @@ J s@J€H€ˆB€ JÀ€ë s@ A‡H> IÀH< ‰ÀH26 ÉÀH4 ÀH2 IÀ€O ‰€ - -ÀŠ + +ÀŠ € -x -@© +x +@© - -É#À $ÀI$À@x ‰$À A‚H> É#ÀH< €a - $À + +É$À %ÀI%À@x ‰%À A‚H> É$ÀH< €a + %À ˆ€€¢ €À  - + @Ï s@À(} ÿÀ -À%} ÿÀ - - ?€ À¡ +À%} ÿÀ + + @€ À¡ É€Hr‚ ÀÉÿ  - + € À s@À! s@ À € ÀÀ³ s@J€H€ˆB€ JÀÀ« -s@È%€ -‰&À@x I&ÀH€@¡ - -€J¢@ɑ€ ˆ‚€H&Àˆ&€À  +s@È&€ +‰'À@x I'ÀH€@¡ + +€J¢@ɑ€ ˆ‚€H'Àˆ'€À  ÀLx -ȁ€  -I +ȁ€  +I a - -€J¢@ɑ€ ˆ‚€H'À AH> @a - @€@à ΀ + +€J¢@ɑ€ ˆ‚€H(À AH> @a + A€@à ΀ @ x Š€ @¡ @@ -25558,53 +18172,53 @@ I ˆ€HÀ¥ ˆ€ˆÀ! I €A! ‰ €Â É € !€ A@x  A‰ €IB €J¢@ɑ€ ˆ‚€ AH>  AH> À  €ò I - -(À + +)À A AH> €b -‰€‰bT ‰(À À` - -@æ É(€É(€I - -É/€IÀ €ú +‰€‰bT ‰)À À` + +@æ É)€É)€I + +É0€IÀ €ú A‰l - )ÀI€ @¡ - + *ÀI€ @¡ + @a -I +I À  -É(€‰(€I - +É)€‰)€I + €I€ { - -@Ï É*€ÀÎ +€ AH€Ê*€ˆ‚ -+€ˆ‚ - - $€‰+ÀI$€É+À‰$€Àx ,À AH> €a -‰+ÀÀÆ É+€@Æ ,€ˆ#€@£ - -H(€@a -ˆ+€À  -@x -H#€€` -@x + +@Ï É+€ÀÎ ,€ AH€Ê+€ˆ‚ +,€ˆ‚ + + %€‰,ÀI%€É,À‰%€Àx -À AH> €a +‰,ÀÀÆ É,€@Æ -€ˆ$€@£ + +H)€@a +ˆ,€À  +@x +H$€€` +@x € £@ÌÁ€  A ˆ‚€H -Ë@H%€ +Ë@H&€ €º I F> €o - + -:€â I&€ À` -É&€‰ - +;€â I'€ À` +É'€‰ + Á  -À@ +À@  @ €x @@ -25634,56 +18248,56 @@ H@Š À@JÃo - + -@x +@x A¡ @÷ Î €x @x À -@Jx - - -H€€.Àˆ.À À  -ˆ€!€H.ÀÈ.À€x ߀H&€É€Hb€ -'€@÷ h&€€Vx ÿÀ - -I#€ À  - - +@Jx + + +H€€/Àˆ/À À  +ˆ€"€H/ÀÈ/À€x ߀H'€É€Hb€ +'€@÷ h'€€Vx ÿÀ + +I$€ À  + + Œ À` -Œ +Œ I€ À IÀ L FÀ  -ɗ€ ɗÀ ˆ€É€ a ˆ-€É-€ a ˆ.€É.€ a +ɗ€ ɗÀ ˆ€É€ a ˆ.€É.€ a ˆ/€É/€ a €ÿ ER   -E € "` I € "d ˆ-€É-€ ¢` É€ ~ Š.€É.€‰¢` +E € "` I € "d ˆ.€É.€ ¢` É€ ~ Š/€É/€‰¢` ȇÀ -/€I/€‰¢` '(€€Õ  +0€I0€‰¢` '(€€Õ  - - - /€Š-€‰"€ + + + 0€Š.€‰"€ @x É@H Ê@   -I/€H -Ì@ Ë@@ +I0€H +Ì@ Ë@@  - “@K² + “@K² H€01DH¢ HR €n - -/€@a -I#€ À  + +0€@a +I$€ À  @† @@ -25691,51 +18305,51 @@ I#€ À  À~ -€ +€ @a - €@ + €@ Î> €~ Ž@Àþ M@ €Ò@LÀ J Î> €~ Ž@Àþ M@ €Ò@LÀL Àà - + "Ab !H! ÀZ -_ñÁ I#€ €€ +_ñÁ I$€ €€ @ x É© + -@ñ +@ñ ×@ - + ¡ À @h À -À -‰.€H2€ - - -€x -x ‰.ÀI -! +À +‰/€H2€ + + +€x +x ‰/ÀI +! À -! -J Jˆ +! +J Jˆ @x ¢BX HÀ` €x ¢BP ˆÀ` À -! +! JH H@¡ JH ˆÀ  JH JH A‡1 - + À x IÀ¡ ‰@¢ ɀŠ @@ -25749,25 +18363,25 @@ JH JH ÉA§ ` Àx -!Àˆ"€J@‰’ +"Àˆ"€J@‰’ @È@ ² @H3€ @Ê€  @È@ ² @È"@I -@ +@ À€K À€K - + À€‹ À€‹ -À€K +À€K 3@€À   -À€‹ +À€‹ 3@€À   @@ -25776,38 +18390,38 @@ JH JH Š€I@J¢@ B` H€€ I € "| €¡ Š€I@J¢@ -Bh H€€ %G‰€ @ B D ‰ € "H  G € "@ I € "H "P  D € @ I€ B  D € "@ I € "D   -€HHÀ0€ˆHÀÈ€I€I@H‚ÀÈHÀˆ€IÀÈ€HIÀ€‰I€ € - +Bh H€€ %G‰€ @ B D ‰ € "H  G € "@ I € "H "P  D € @ I€ B  D € "@ I € "D   +€HIÀ1€ˆIÀÈ€I€I@H‚ÀÈIÀˆ€JÀÈ€HJÀ€‰J€ € + H€ € HÀ -#€I€ HÀ -ˆ#€‰€ HÀ -È#€ɐ€ HÀ -$€ ‘€ HÀ -H+€I‘€ HÀ -ˆ+€‰‘€ HÀ -(€ɑ€ HÀ -H(€ ’€ HÀ -H,€I’€ HÀ - -R€È0€  +$€I€ HÀ +ˆ$€‰€ HÀ +È$€ɐ€ HÀ +%€ ‘€ HÀ +H,€I‘€ HÀ +ˆ,€‰‘€ HÀ +)€ɑ€ HÀ +H)€ ’€ HÀ +H-€I’€ HÀ + +T€È1€  ‰2@ @þ I - -Š -® ˆ‚ + +Š +® ˆ‚ €ï -@ - 0ÀÀ +@ + 1ÀÀ - 0€I€ 0À + 1€I€ 1À €J¢@ɑ€  A ˆ‚€H@M @ - +  -/€^a Ѐ ’ +0€^a Ѐ ’ $@¢ £Y@æhB&iÀ @@ -25816,8 +18430,8 @@ $@¢ ã@#€€äA €€$ € - - + + Š€ã€$@‚#™À $ @@ -25836,14 +18450,14 @@ $ð‚£9#I €÷ $$€f $"€€x - -%>€å€` + +%?€å€` À x %` -@)x %>€£ ! d€Ÿ&é€ +@)x %?€£ ! d€Ÿ&é€ d %  @x -$$€$$€$ +$$€$$€$ $A$> $ @@ -25851,14 +18465,14 @@ $A$> $ äcÀ d€! - + åQ f9@ @ x e<€&Êa d)eÀà x ¥€æIa deÀ @ x å€$Ò@€@æ $) ä€a -ã€#:À Á@c‚@ Á +ã€#;À Á@c‚@ Á cÀ% fH£ Š£ @@ -25874,7 +18488,7 @@ e å %Œ` - + £i2 $$€$$€$ d € @@ -25887,17 +18501,17 @@ d € ä ä€fÅ $€$<€@ - + - -h€‰r + +j€‰r #Á -C@ “ - -`€‰B€ -@ö -`€‰B€ +C@ “ + +b€‰B€ +@ö +b€‰B€ Àô À (Ñ @@ -26039,45 +18653,45 @@ J s@J€H€ˆB€ JÀ€ø s@ A‡H> IÀH< ‰ÀH26 ÉÀH4 ÀH2 IÀ€\ ‰€ - -À³ + +À³ € -x -@¶ +x +@¶ - -É#À $ÀI$À@x ‰$À A‚H> É#ÀH< €a - $À + +É$À %ÀI%À@x ‰%À A‚H> É$ÀH< €a + %À ˆ€€¢ €À  - + @Ü s@À5} ÿÀ -À2} ÿÀ - - ?€ À¡ +À2} ÿÀ + + @€ À¡ É€Hr‚ ÀÉÿ  - + € À s@À! s@ À € ÀÀÀ s@J€H€ˆB€ JÀÀž -s@È%€ -‰&À@x I&ÀH€@¡ - -€J¢@ɑ€ ˆ‚€H&Àˆ&€À  +s@È&€ +‰'À@x I'ÀH€@¡ + +€J¢@ɑ€ ˆ‚€H'Àˆ'€À  ÀLx -ȁ€  -I +ȁ€  +I a - -€J¢@ɑ€ ˆ‚€H'À AH> @a - @€@à ΀ + +€J¢@ɑ€ ˆ‚€H(À AH> @a + A€@à ΀ @ x Š€ @¡ @@ -26085,53 +18699,53 @@ I ˆ€HÀ¥ ˆ€ˆÀ! I €A! ‰ €Â É € !€ A@x  A‰ €IB €J¢@ɑ€ ˆ‚€ AH>  AH> À  €ÿ I - -(À + +)À A AH> €b -‰€‰bT ‰(À À` - -@ó É(€É(€I - -É/€IÀ € +‰€‰bT ‰)À À` + +@ó É)€É)€I + +É0€IÀ € A‰l - )ÀI€ @¡ - + *ÀI€ @¡ + @a -I +I À  -É(€‰(€I - +É)€‰)€I + €I€ { - -@Ü É*€ÀÛ +€ AH€Ê*€ˆ‚ -+€ˆ‚ - - $€‰+ÀI$€É+À‰$€Àx ,À AH> €a -‰+ÀÀÓ É+€@Ó ,€ˆ#€@£ - -H(€@a -ˆ+€À  -@x -H#€€` -@x + +@Ü É+€ÀÛ ,€ AH€Ê+€ˆ‚ +,€ˆ‚ + + %€‰,ÀI%€É,À‰%€Àx -À AH> €a +‰,ÀÀÓ É,€@Ó -€ˆ$€@£ + +H)€@a +ˆ,€À  +@x +H$€€` +@x € £@ÌÁ€  A ˆ‚€H -Ë@H%€ +Ë@H&€ €Ç I F> €o - + -:€â I&€ À` -É&€‰ - +;€â I'€ À` +É'€‰ + Á  -À@ +À@ À €x €x þÀ @@ -26160,54 +18774,54 @@ H@Š À@JÃo - +   -@x +@x A¡ €õ Î €x @x À -@Kx - - -H€€.Àˆ.À À  -ˆ€!€H.ÀÈ.À€x ߀H&€É€Hb€ -'€€õ h&€€Wx ÿÀ - -I#€ À  - - - +@Kx + + +H€€/Àˆ/À À  +ˆ€"€H/ÀÈ/À€x ߀H'€É€Hb€ +'€€õ h'€€Wx ÿÀ + +I$€ À  + + + Œ À` -Œ +Œ €ÿ   -Eˆ‡€ E € "` I € "d ˆ-€É-€ ¢` -€ BX I-€ Bx Š-€ˆ.€ˆ‚ -/€I/€‰¢` '(€ÀÒ  +Eˆ‡€ E € "` I € "d ˆ.€É.€ ¢` .€ BX I.€ Bx Š.€ˆ/€ˆ‚ +0€I0€‰¢` '(€ÀÒ  - - - /€Š-€‰"€ + + + 0€Š.€‰"€ @x É@H Ê@   -I/€H -Ì@ Ë@@ +I0€H +Ì@ Ë@@  - “@K² + “@K² H€01DH¢ HR €n - -/€@a -I#€ À  + +0€@a +I$€ À  @† @@ -26215,51 +18829,51 @@ I#€ À  À~ -€ +€ @a - €@ + €@ Î> €~ Ž@Àþ M@ €Ò@LÀ J Î> €~ Ž@Àþ M@ €Ò@LÀL Àà - + "Ab !H! ÀZ -_ñÁ I#€ €€ +_ñÁ I$€ €€ @ x É© + -@ñ +@ñ ×@ - + ¡ À €e À -À -‰.€H2€ - - -€x -x ‰.ÀI -! +À +‰/€H2€ + + +€x +x ‰/ÀI +! À -! -J Jˆ +! +J Jˆ @x ¢BX HÀ` €x ¢BP ˆÀ` À -! +! JH H@¡ JH ˆÀ  JH JH A‡1 - + À x IÀ¡ ‰@¢ ɀŠ @@ -26273,25 +18887,25 @@ JH JH ÉA§ ` Àx -!Àˆ"€J@‰’ +"Àˆ"€J@‰’ @È@ ² @H3€ @Ê€  @È@ ² @È"@I -@ +@ À€K À€K - + À€‹ À€‹ -À€K +À€K 3@€À   -À€‹ +À€‹ 3@€À   @@ -26300,51 +18914,51 @@ JH JH Š€I@J¢@ B` H€€ I € "| €¡ Š€I@J¢@ -Bh H€€ %G‰€ @ B D ‰ € "H  G € "@ I € "H "P  D € @ I€ B  D € "@ I € "D   -€HHÀ0€ˆHÀÈ€I€I@H‚ÀÈHÀˆ€IÀÈ€HIÀ€‰I€ € - +Bh H€€ %G‰€ @ B D ‰ € "H  G € "@ I € "H "P  D € @ I€ B  D € "@ I € "D   +€HIÀ1€ˆIÀÈ€I€I@H‚ÀÈIÀˆ€JÀÈ€HJÀ€‰J€ € + H€ € HÀ -#€I€ HÀ -ˆ#€‰€ HÀ -È#€ɐ€ HÀ -$€ ‘€ HÀ -H+€I‘€ HÀ -ˆ+€‰‘€ HÀ -(€ɑ€ HÀ -H(€ ’€ HÀ -H,€I’€ HÀ - -R€È0€  +$€I€ HÀ +ˆ$€‰€ HÀ +È$€ɐ€ HÀ +%€ ‘€ HÀ +H,€I‘€ HÀ +ˆ,€‰‘€ HÀ +)€ɑ€ HÀ +H)€ ’€ HÀ +H-€I’€ HÀ + +T€È1€  ‰2@ @þ I - -Š -® ˆ‚ + +Š +® ˆ‚ €ï -@ - 0ÀÀ +@ + 1ÀÀ - 0€I€ 0À + 1€I€ 1À €J¢@ɑ€  A ˆ‚€H@M @ - -I/€Š€‰2@ Ê-€‰¢@ + +I0€Š€‰2@ Ê.€‰¢@ F‰> @n - +  -/€^a Ѐ ’ +0€^a Ѐ ’ %A#ú€$AdIA #€ï ã@#€€äA €€$ €@M - - + + @3x Š€ã€$@‚#™À $ @@ -26362,14 +18976,14 @@ $ð‚£9#I €÷ $$€f $"€€x - -%>€å€` + +%?€å€` À x %` -@)x %>€£ ! d€Ÿ&é€ +@)x %?€£ ! d€Ÿ&é€ d %  @x -$$€$$€$ +$$€$$€$ $A$> $ @@ -26377,14 +18991,14 @@ $A$> $ äcÀ d€! - + åQ f9@ @ x e<€&Êa d)eÀà x ¥€æIa deÀ @ x å€$Ò@€@æ $) ä€a -ã€#:À Á@c‚@ Á +ã€#;À Á@c‚@ Á cÀ% fH£ Š£ @@ -26400,7 +19014,7 @@ e å %Œ` - + £i2 $$€$$€$ d € @@ -26413,17 +19027,17 @@ d € ä ä€fÅ $€$<€@ - + - -h€‰r + +j€‰r #Á -C@ “ - -`€‰B€ -@ö -`€‰B€ +C@ “ + +b€‰B€ +@ö +b€‰B€ Àô À (Ñ @@ -26563,45 +19177,45 @@ J s@J€H€ˆB€ JÀÀü s@ A‡H> IÀH< ‰ÀH26 ÉÀH4 ÀH2 IÀÀ` ‰€ - - + + € -x -@» +x +@» - -É#À $ÀI$À@x ‰$À A‚H> É#ÀH< €a - $À + +É$À %ÀI%À@x ‰%À A‚H> É$ÀH< €a + %À ˆ€€¢ €À  - + @á s@À:} ÿÀ -À7} ÿÀ - - ?€ À¡ +À7} ÿÀ + + @€ À¡ É€Hr‚ ÀÉÿ  - + € À s@ s@ À € ÀÀÅ s@J€H€ˆB€ JÀÀœ -s@È%€ -‰&À@x I&ÀH€@¡ - -€J¢@ɑ€ ˆ‚€H&Àˆ&€À  +s@È&€ +‰'À@x I'ÀH€@¡ + +€J¢@ɑ€ ˆ‚€H'Àˆ'€À  ÀNx -ȁ€  -I +ȁ€  +I a - -€J¢@ɑ€ ˆ‚€H'À AH> @a - @€€â ΀ + +€J¢@ɑ€ ˆ‚€H(À AH> @a + A€€â ΀ @ x Š€ @¡ @@ -26609,55 +19223,59 @@ I ˆ€HÀ¥ ˆ€ˆÀ! I €A! ‰ €Â É € !€ A@x  A‰ €IB €J¢@ɑ€ ˆ‚€ AH>  AH> À  € I - -(À + +)À A AH> €b -‰€‰bT ‰(À À` - -@ø É(€É(€I - -É/€IÀ +‰€‰bT ‰)À À` + +@ø É)€É)€I + +É0€IÀ A‰l - )ÀI€ @¡ - + *ÀI€ @¡ + @a -I +I À  -É(€‰(€I - +É)€‰)€I + €I€{DH2@ - -@ß É*€ÀÞ +€ AH€Ê*€ˆ‚ -+€ˆ‚ - - $€‰+ÀI$€É+À‰$€Àx ,À AH> €a -‰+ÀÀÖ É+€@Ö ,€ˆ#€@£ - -H(€@a -ˆ+€À  -@x -H#€€` -@x + +@ß É+€ÀÞ ,€ AH€Ê+€ˆ‚ +,€ˆ‚ + + %€‰,ÀI%€É,À‰%€Àx -À AH> €a +‰,ÀÀÖ É,€@Ö -€ˆ$€@£ + +H)€@a +ˆ,€À  +@x +H$€€` +@x € £@ÌÁ€  A ˆ‚€H -Ë@H%€ +Ë@H&€ €Ê I BHÀ/ - + -:€â I&€ À` -É&€‰ - +;€â I'€ À` +É'€‰ + +È&€ + BIB ‰A¡ +J€IÁ  +Ê€J€I'€‰’@BH‚ Á  -ÀC +À= €– €x @‡x þÀ @@ -26686,54 +19304,54 @@ H@Š À@JÃo - + -@x +@x A¡ € Î €x @x À - - - -H€€.Àˆ.À À  -ˆ€!€H.ÀÈ.À€x ߀H&€É€Hb€ -'€€ h&€@]x ÿÀ - -I#€ À  - + + + +H€€/Àˆ/À À  +ˆ€"€H/ÀÈ/À€x ߀H'€É€Hb€ +'€€ h'€@]x ÿÀ + +I$€ À  + #Fˆ‚€ #-FH€€ - - - + + Œ À` -Œ +Œ €ÿ   -Eˆ‡€ E € "` I € "d ˆ-€É-€ ¢` -€ bT I-€ bt Š-€ˆ.€ˆ‚ -/€I/€‰¢` '(€ +Eˆ‡€ E € "` I € "d ˆ.€É.€ ¢` .€ bT I.€ bt Š.€ˆ/€ˆ‚ +0€I0€‰¢` '(€ - - - /€Š-€‰"€ + + + 0€Š.€‰"€ @x É@H Ê@   -I/€H -Ì@ Ë@@ +I0€H +Ì@ Ë@@  - “@K² + “@K² H€01DH¢ HR €n - -/€@a -I#€ À  + +0€@a +I$€ À  @† @@ -26741,51 +19359,51 @@ I#€ À  À~ -€ +€ @a - €@ + €@ Î> €~ Ž@Àþ M@ €Ò@LÀ J Î> €~ Ž@Àþ M@ €Ò@LÀL Àà - + "Ab !H! ÀZ -_ñÁ I#€ €€ +_ñÁ I$€ €€ @ x É© + -@ñ +@ñ ×@ - + ¡ À Àr À -À -‰.€H2€ - - -€x -x ‰.ÀI -! +À +‰/€H2€ + + +€x +x ‰/ÀI +! À -! -J Jˆ +! +J Jˆ @x ¢BX HÀ` €x ¢BP ˆÀ` À -! +! JH H@¡ JH ˆÀ  JH JH A‡1 - + À x IÀ¡ ‰@¢ ɀŠ @@ -26799,26 +19417,26 @@ JH JH ÉA§ ` Àx -!Àˆ"€J@‰’ +"Àˆ"€J@‰’ @È@ ² @H3€ @Ê€  @È@ ² @È"@I -@ +@ À€K À€K - + À€‹  À€‹ -À€K +À€K 3@€À   -À€‹ +À€‹ 3@€À   @@ -26827,53 +19445,53 @@ JH JH Š€I@J¢@ B` H€€ I € "| €¡ Š€I@J¢@ -Bh H€€ %G‰€ @ B D ‰ € "H  G € "@ I € "H "P  D € @ I€ B  D € "@ I € "D   -€HHÀ0€ˆHÀÈ€I€I@H‚ÀÈHÀˆ€IÀÈ€HIÀ€‰I€ € - +Bh H€€ %G‰€ @ B D ‰ € "H  G € "@ I € "H "P  D € @ I€ B  D € "@ I € "D   +€HIÀ1€ˆIÀÈ€I€I@H‚ÀÈIÀˆ€JÀÈ€HJÀ€‰J€ € + H€ € HÀ -#€I€ HÀ -ˆ#€‰€ HÀ -È#€ɐ€ HÀ -$€ ‘€ HÀ -H+€I‘€ HÀ -ˆ+€‰‘€ HÀ -(€ɑ€ HÀ -H(€ ’€ HÀ -H,€I’€ HÀ - -R€È0€  +$€I€ HÀ +ˆ$€‰€ HÀ +È$€ɐ€ HÀ +%€ ‘€ HÀ +H,€I‘€ HÀ +ˆ,€‰‘€ HÀ +)€ɑ€ HÀ +H)€ ’€ HÀ +H-€I’€ HÀ + +T€È1€  ‰2@ @þ I - -Š -® ˆ‚ + +Š +® ˆ‚ €ï -@ - 0ÀÀ +@ + 1ÀÀ - 0€I€ 0À + 1€I€ 1À €J¢@ɑ€  A ˆ‚€H@M @ - -I/€Š€‰2@ Ê-€‰Â@ + +I0€Š€‰2@ Ê.€‰Â@ @ €n F‰> Àm - +  -/€^a Ѐ ’ -J;€ˆ +0€^a Ѐ ’ +J<€ˆ b I@@õ %A#ú€$AdIA #€ï ã@#€€äA €€$ €@M - - + + @3x Š€ã€$@‚#™À $ @@ -26891,14 +19509,14 @@ $ð‚£9#I €÷ $$€f $"€€x - -%>€å€` + +%?€å€` À x %` -@)x %>€£ ! d€Ÿ&é€ +@)x %?€£ ! d€Ÿ&é€ d %  @x -$$€$$€$ +$$€$$€$ $A$> $ @@ -26906,14 +19524,14 @@ $A$> $ äcÀ d€! - + åQ f9@ @ x e<€&Êa d)eÀà x ¥€æIa deÀ @ x å€$Ò@€@æ $) ä€a -ã€#:À Á@c‚@ Á +ã€#;À Á@c‚@ Á cÀ% fH£ Š£ @@ -26929,7 +19547,7 @@ e å %Œ` - + £i2 $$€$$€$ d € @@ -26942,17 +19560,17 @@ d € ä ä€fÅ $€$<€@ - + - -h€‰r + +j€‰r #Á -C@ “ - -`€‰B€ -@ö -`€‰B€ +C@ “ + +b€‰B€ +@ö +b€‰B€ Àô À (Ñ @@ -27092,45 +19710,45 @@ J s@J€H€ˆB€ JÀ€ï s@ A‡H> IÀH< ‰ÀH26 ÉÀH4 ÀH2 IÀ€S ‰€ - -Àª + +Àª € -x ÀF ‰€H€ÀÀE É€ˆ€!À AH> IÀ @¡ - +x ÀF ‰€H€ÀÀE É€ˆ€"À AH> IÀ @¡ + - -É#À $ÀI$À@x ‰$À A‚H> É#ÀH< €a - $ÀÀ9 I$€@9 ‰$€ AH> €b + +É$À %ÀI%À@x ‰%À A‚H> É$ÀH< €a + %ÀÀ9 I%€@9 ‰%€ AH> €b ˆ€€¢ €À  - + -€*} ÿÀ - - ?€ À¡ +€*} ÿÀ + + @€ À¡ É€Hr‚ ÀÉÿ  - + € ÀÀÀ s@ s@ À € À€ž s@J€H€ˆB€ JÀ€° -s@È%€ -‰&À@x I&ÀH€@¡ - -€J¢@ɑ€ ˆ‚€H&Àˆ&€À  +s@È&€ +‰'À@x I'ÀH€@¡ + +€J¢@ɑ€ ˆ‚€H'Àˆ'€À  ÀNx -ȁ€ À É&€ˆ€@¡ -I +ȁ€ À É'€ˆ€@¡ +I a - -€J¢@ɑ€ ˆ‚€H'À AH> @a - @€€â ΀ + +€J¢@ɑ€ ˆ‚€H(À AH> @a + A€€â ΀ @ x Š€ @¡ @@ -27138,55 +19756,59 @@ I ˆ€HÀ¥ ˆ€ˆÀ! I €A! ‰ €Â É € !€ A@x  A‰ €IB €J¢@ɑ€ ˆ‚€ AH>  AH> À  @÷ I - -(À + +)À A AH> €b -‰€‰bT ‰(À À` - - - -É/€IÀ Àþ +‰€‰bT ‰)À À` + + + +É0€IÀ Àþ A‰l - )ÀI€ @¡ - + *ÀI€ @¡ + @a -I +I À  -É(€‰(€I - +É)€‰)€I + €I€{DH2@ - - -+€ˆ‚ - - $€‰+ÀI$€É+À‰$€Àx ,À AH> €a -‰+À€É É+€ - -H(€@a -ˆ+€À  -@x -H#€€` -@x ÀÁ ‰,€‹,€ @£ + + +,€ˆ‚ + + %€‰,ÀI%€É,À‰%€Àx -À AH> €a +‰,À€É É,€ + +H)€@a +ˆ,€À  +@x +H$€€` +@x ÀÁ ‰-€‹-€ @£ ÀÀ I € £@ÌÁ€  A ˆ‚€H -Ë@H%€ +Ë@H&€ @œ I BHÀ/ - + -:€â I&€ À` -É&€‰ - +;€â I'€ À` +É'€‰ + +È&€ + BIB ‰A¡ +J€IÁ  +Ê€J€I'€‰’@BH‚ Á  -ÀC +À= €– €x @‡x þÀ @@ -27215,54 +19837,54 @@ H@Š À@JÃo - + -@x +@x A¡ € Î €x @x À - - - -H€€.Àˆ.À À  -ˆ€!€H.ÀÈ.À€x ߀H&€É€Hb€ -'€€ h&€@]x ÿÀ - -I#€ À  - + + + +H€€/Àˆ/À À  +ˆ€"€H/ÀÈ/À€x ߀H'€É€Hb€ +'€€ h'€@]x ÿÀ + +I$€ À  + #Fˆ‚€ #-FH€€ - - - + + Œ À` -Œ +Œ €ÿ   -Eˆ‡€ E € "` I € "d ˆ-€É-€ ¢` -€ BX I-€ Bx Š-€ˆ.€ˆ‚ -/€I/€‰¢` '(€ +Eˆ‡€ E € "` I € "d ˆ.€É.€ ¢` .€ BX I.€ Bx Š.€ˆ/€ˆ‚ +0€I0€‰¢` '(€ - - - /€Š-€‰"€ + + + 0€Š.€‰"€ @x É@H Ê@   -I/€H -Ì@ Ë@@ +I0€H +Ì@ Ë@@  - “@K² + “@K² H€01DH¢ HR €n - -/€@a -I#€ À  + +0€@a +I$€ À  @† @@ -27270,51 +19892,51 @@ I#€ À  À~ -€ +€ @a - €@ + €@ Î> €~ Ž@Àþ M@ €Ò@LÀ J Î> €~ Ž@Àþ M@ €Ò@LÀL Àà - + "Ab !H! ÀZ -_ñÁ I#€ €€ +_ñÁ I$€ €€ @ x É© + -@ñ +@ñ ×@ - + ¡ À Àr À -À -‰.€H2€ - - -€x -x ‰.ÀI -! +À +‰/€H2€ + + +€x +x ‰/ÀI +! À -! -J Jˆ +! +J Jˆ @x ¢BX HÀ` €x ¢BP ˆÀ` À -! +! JH H@¡ JH ˆÀ  JH JH A‡1 - + À x IÀ¡ ‰@¢ ɀŠ @@ -27328,26 +19950,26 @@ JH JH ÉA§ ` Àx -!Àˆ"€J@‰’ +"Àˆ"€J@‰’ @È@ ² @H3€ @Ê€  @È@ ² @È"@I -@ +@ À€K À€K - + À€‹  À€‹ -À€K +À€K 3@€À   -À€‹ +À€‹ 3@€À   @@ -27356,53 +19978,53 @@ JH JH Š€I@J¢@ B` H€€ I € "| €¡ Š€I@J¢@ -Bh H€€ %G‰€ @ B D ‰ € "H  G € "@ I € "H "P  D € @ I€ B  D € "@ I € "D   -€HHÀ0€ˆHÀÈ€I€I@H‚ÀÈHÀˆ€IÀÈ€HIÀ€‰I€ € - +Bh H€€ %G‰€ @ B D ‰ € "H  G € "@ I € "H "P  D € @ I€ B  D € "@ I € "D   +€HIÀ1€ˆIÀÈ€I€I@H‚ÀÈIÀˆ€JÀÈ€HJÀ€‰J€ € + H€ € HÀ -#€I€ HÀ -ˆ#€‰€ HÀ -È#€ɐ€ HÀ -$€ ‘€ HÀ -H+€I‘€ HÀ -ˆ+€‰‘€ HÀ -(€ɑ€ HÀ -H(€ ’€ HÀ -H,€I’€ HÀ - -R€È0€  +$€I€ HÀ +ˆ$€‰€ HÀ +È$€ɐ€ HÀ +%€ ‘€ HÀ +H,€I‘€ HÀ +ˆ,€‰‘€ HÀ +)€ɑ€ HÀ +H)€ ’€ HÀ +H-€I’€ HÀ + +T€È1€  ‰2@ @þ I - -Š -® ˆ‚ + +Š +® ˆ‚ €ï -@ - 0ÀÀ +@ + 1ÀÀ - 0€I€ 0À + 1€I€ 1À €J¢@ɑ€  A ˆ‚€H@M @ - -I/€Š€‰2@ Ê-€‰Â@ + +I0€Š€‰2@ Ê.€‰Â@ @ €n F‰> Àm - +  -/€^a Ѐ ’ -J;€ˆ +0€^a Ѐ ’ +J<€ˆ b I@@õ %A#ú€$AdIA #€ï ã@#€€äA €€$ €@M - - + + @3x Š€ã€$@‚#™À $ @@ -27420,14 +20042,14 @@ $ð‚£9#I €÷ $$€f $"€€x - -%>€å€` + +%?€å€` À x %` -@)x %>€£ ! d€Ÿ&é€ +@)x %?€£ ! d€Ÿ&é€ d %  @x -$$€$$€$ +$$€$$€$ $A$> $ @@ -27435,14 +20057,14 @@ $A$> $ äcÀ d€! - + åQ f9@ @ x e<€&Êa d)eÀà x ¥€æIa deÀ @ x å€$Ò@€@æ $) ä€a -ã€#:À Á@c‚@ Á +ã€#;À Á@c‚@ Á cÀ% fH£ Š£ @@ -27458,7 +20080,7 @@ e å %Œ` - + £i2 $$€$$€$ d € @@ -27471,17 +20093,17 @@ d € ä ä€fÅ $€$<€@ - + - -h€‰r + +j€‰r #Á -C@ “ - -`€‰B€ -@ö -`€‰B€ +C@ “ + +b€‰B€ +@ö +b€‰B€ Àô À (Ñ @@ -27621,45 +20243,45 @@ J s@J€H€ˆB€ JÀ€ï s@ A‡H> IÀH< ‰ÀH26 ÉÀH4 ÀH2 IÀ€S ‰€ - -Àª + +Àª € -x ÀF ‰€H€ÀÀE É€ˆ€!À AH> IÀ @¡ - +x ÀF ‰€H€ÀÀE É€ˆ€"À AH> IÀ @¡ + - -É#À $ÀI$À@x ‰$À A‚H> É#ÀH< €a - $ÀÀ9 I$€@9 ‰$€ AH> €b + +É$À %ÀI%À@x ‰%À A‚H> É$ÀH< €a + %ÀÀ9 I%€@9 ‰%€ AH> €b ˆ€€¢ €À  - + -€*} ÿÀ - - ?€ À¡ +€*} ÿÀ + + @€ À¡ É€Hr‚ ÀÉÿ  - + € ÀÀÀ s@ s@ À € À€ž s@J€H€ˆB€ JÀ€° -s@È%€ -‰&À@x I&ÀH€@¡ - -€J¢@ɑ€ ˆ‚€H&Àˆ&€À  +s@È&€ +‰'À@x I'ÀH€@¡ + +€J¢@ɑ€ ˆ‚€H'Àˆ'€À  ÀNx -ȁ€ À É&€ˆ€@¡ -I +ȁ€ À É'€ˆ€@¡ +I a - -€J¢@ɑ€ ˆ‚€H'À AH> @a - @€€â ΀ + +€J¢@ɑ€ ˆ‚€H(À AH> @a + A€€â ΀ @ x Š€ @¡ @@ -27667,585 +20289,60 @@ I ˆ€HÀ¥ ˆ€ˆÀ! I €A! ‰ €Â É € !€ A@x  A‰ €IB €J¢@ɑ€ ˆ‚€ AH>  AH> À  @÷ I - -(À + +)À A AH> €b -‰€‰bT ‰(À À` - - - -É/€IÀ Àþ +‰€‰bT ‰)À À` + + + +É0€IÀ Àþ A‰l - )ÀI€ @¡ - + *ÀI€ @¡ + @a -I +I À  -É(€‰(€I - +É)€‰)€I + €I€{DH2@ - - -+€ˆ‚ - - $€‰+ÀI$€É+À‰$€Àx ,À AH> €a -‰+À€É É+€ - -H(€@a -ˆ+€À  -@x -H#€€` -@x ÀÁ ‰,€‹,€ @£ + + +,€ˆ‚ + + %€‰,ÀI%€É,À‰%€Àx -À AH> €a +‰,À€É É,€ + +H)€@a +ˆ,€À  +@x +H$€€` +@x ÀÁ ‰-€‹-€ @£ ÀÀ I € £@ÌÁ€  A ˆ‚€H -Ë@H%€ +Ë@H&€ @œ I BHÀ/ - + -:€â I&€ À` -É&€‰ - +;€â I'€ À` +É'€‰ + +È&€ + BIB ‰A¡ +J€IÁ  +Ê€J€I'€‰’@BH‚ Á  -ÀC -€– -€x -@‡x þÀ - - - - - - -¢ - - - - - -€` -@ -x I€Š -Ib€ - - - - -H -H@Š - -À@JÃo - - - -@x - A¡ -€ Î -€x -@x -À - - - -H€€.Àˆ.À À  -ˆ€!€H.ÀÈ.À€x ߀H&€É€Hb€ -'€€ h&€@]x ÿÀ - -I#€ À  - -#Fˆ‚€ #-FH€€ - - - - -Œ -À` -Œ -€ÿ - - -Eˆ‡€ E € "` I € "d ˆ-€É-€ ¢` -€ BX I-€ Bx Š-€ˆ.€ˆ‚ -/€I/€‰¢` '(€ - - - - - - /€Š-€‰"€ -@x É@H -Ê@ - - -I/€H -Ì@ Ë@@ - - “@K² -H€01DH¢ -HR €n - -/€@a -I#€ À  -@† - - - -À~ - - -€ -@a - €@ -Î> €~ Ž@Àþ M@ €Ò@LÀ -J -Î> €~ Ž@Àþ M@ €Ò@LÀL -Àà - - - -"Ab -!H! -ÀZ -_ñÁ I#€ €€ - -@ x -É© + -@ñ -×@ - -¡ - -À -Àr À - -À -‰.€H2€ - - -€x -x ‰.ÀI -! -À -! -J Jˆ -@x ¢BX HÀ` -€x ¢BP ˆÀ` -À -! -JH H@¡ -JH ˆÀ  -JH JH -A‡1 - - -À x IÀ¡ -‰@¢ -ɀŠ -ÉA§ - ` -Àx -Àˆ"€J@‰’ -À x IÀ¡ -‰@¢ -ɀŠ -ÉA§ - ` -Àx -!Àˆ"€J@‰’ -@È@ ² -@H3€ @Ê€  -@È@ ² -@È"@I -@ -À€K -À€K - -À€‹ - - -À€‹ -À€K - 3@€À  - - - - -À€‹ - 3@€À  - - - -€‰’@ "x  -Š€I@J¢@ -B` H€€ I € "| €¡ -Š€I@J¢@ -Bh H€€ %G‰€ @ B D ‰ € "H  G € "@ I € "H "P  D € @ I€ B  D € "@ I € "D   -€HHÀ0€ˆHÀÈ€I€I@H‚ÀÈHÀˆ€IÀÈ€HIÀ€‰I€ € - -H€ € HÀ -#€I€ HÀ -ˆ#€‰€ HÀ -È#€ɐ€ HÀ -$€ ‘€ HÀ -H+€I‘€ HÀ -ˆ+€‰‘€ HÀ -(€ɑ€ HÀ -H(€ ’€ HÀ -H,€I’€ HÀ - -R€È0€  - - - -‰2@ @þ I - -Š -® ˆ‚ -€ï -@ - 0ÀÀ - - 0€I€ 0À -€J¢@ɑ€  A ˆ‚€H@M - @ - -I/€Š€‰2@ Ê-€‰Â@ -@ -€n - F‰> -Àm - - -/€^a Ѐ ’ -J;€ˆ -b I@@õ -%A#ú€$AdIA -#€ï -ã@#€€äA - -€€$ €@M - - -@3x -Š€ã€$@‚#™À -$ -$ð‚£9#I - - - - - -€ö -§€ÀW - - - -€÷ -$$€f -$"€€x - -%>€å€` -À x %` -@)x %>€£ ! d€Ÿ&é€ -d -%  -@x -$$€$$€$ - - -$A$> $ -#DcÀ/ - -äcÀ -d€! - -åQ f9@ -@ x e<€&Êa -d)eÀà -x ¥€æIa -deÀ -@ x å€$Ò@€@æ $) ä€a -ã€#:À Á@c‚@ Á -cÀ% -fH£ -Š£ -£ -#Á$ -d@¢ -#‚á €À -f…! €x &…  -æc -@ -e -¥ -å -%Œ` - - -£i2 $$€$$€$ -d -€ -ä -ä€f…! $€e¡ -$<€ÀÙ -d€Ÿ&I@ -£i2 €Õ -d -€ -ä -ä€fÅ $€$<€@ - - - -h€‰r -#Á - -C@ “ - -`€‰B€ -@ö -`€‰B€ -Àô -À -(Ñ -! '*€ -À -(@o - - - - - -Êã -€x GKÀ` -À - - -ò@A¢ -C ÏÀ¡ -C @¡ -C OÀ  -C C - -À` -À -À¡ -J -Š@¢ -ʀ¢ - -Á¢ -Àx NCh @x NC@ Àx NCH @x NCP À -K@¡ -À x @ x Àx ‹À¢ €@2 I -ø€ˆù€ˆ‚ -à€K@¡ - -`€À€€ -JB@€Jb@H‚ - -@x É€Nb@ -N@€# I - -È -\ - - Aˆ> - - @b -€û - -€x M@Q -S$S$AL -SŽ - -¢@Š@ AH> -â - -¢ -â - -IÀÁ@ ‚P Á -‰€IòIb€IÀÉ€IòIb€‰À@ -‰€IòIR€IÀÉ€IòIR€‰À  -‰€Iò - -ÀÈÿ  -@| s@ -€JÀ AˆHR0 À AH! IÀ AH! ‰À A„HB8 ‰ÀŒ AˆH‚0 ÉÀ‹€ @Š - - A @¥ -J> - Aˆ A A A„ŒJ< À  - AˆŠ"@@û Ë@ AH> ‹€ À` - - - - - - AH> À  -@Õ I -H€Èÿ  -Àb s@ÀÑ} ÿÀ -€Ï} þÀ - -À€[ s@ -€JÀ€c -s@ AˆHR0 À AH! IÀ AH! ‰À A„Œ AˆH‚0 ÉÀ‹€ @Š - - A @¥ -J> - Aˆ A A A„ŒJ< À  - AˆŠ"@@û Ë@ÀŸ I -ÀÉÿ  -€Q s@€À@Œ I€À» ‰€@» É€ˆ€É€ a # AH> €¢ -ÉÀ€ž € - - - -€À± É € -€€ÿ I - -‰À AH> À  -À^ - - -Ï€€ÿ Ž - - -@ ‰€À¡ - A‰H‚0 H. Àþ @ AƒH> ÉÀH< ÀH:  - -@ s@€†} ÿÀ - - AH! ‰À AH! ÉÀ AH> À  -H<  AH> @£ -Hâ$ IÀH À A…H6 @¡ - -@x ‰ - A‚ À` - - A‚ €` -Àx  AH! ‰À AH! ÉÀ AH! À AH! IÀ AH> - -J -À` -Àx - A> @¢ - AˆH‚0  A‹HR6 H4 HR*  AˆHB8 HB0 - A„HB8  AHR6 HR, HR" -À\} þÀ -ÀÉÿ  -@ -€ˆb€ -À -€ -À€÷ -s@J€H€ˆB€ -JÀ€ï -s@ A‡H> IÀH< ‰ÀH26 ÉÀH4 ÀH2 IÀ€S ‰€ - -Àª -€ -x ÀF ‰€H€ÀÀE É€ˆ€!À AH> IÀ @¡ - - - - - -É#À $ÀI$À@x ‰$À A‚H> É#ÀH< €a - $ÀÀ9 I$€@9 ‰$€ AH> €b -ˆ€€¢ -€À  - - - -€*} ÿÀ - - ?€ À¡ -É€Hr‚ -ÀÉÿ  - -€ -ÀÀÀ -s@ -s@ -À € À€ž s@J€H€ˆB€ -JÀ€° -s@È%€ -‰&À@x I&ÀH€@¡ - -€J¢@ɑ€ ˆ‚€H&Àˆ&€À  -ÀNx -ȁ€ À É&€ˆ€@¡ -I - a - -€J¢@ɑ€ ˆ‚€H'À AH> @a - @€€â ΀ -@ x Š€ -@¡ - -€x ÌâÀ -ˆ€HÀ¥ ˆ€ˆÀ! I €A! ‰ €Â É € !€ A@x  A‰ €IB -€J¢@ɑ€ ˆ‚€ AH>  AH> À  -@÷ I - -(À - -A AH> €b -‰€‰bT ‰(À À` - - - -É/€IÀ Àþ - -A‰l - )ÀI€ @¡ - - @a -I - À  -É(€‰(€I - - €I€{DH2@ - - - - - -+€ˆ‚ - - $€‰+ÀI$€É+À‰$€Àx ,À AH> €a -‰+À€É É+€ - -H(€@a -ˆ+€À  -@x -H#€€` -@x ÀÁ ‰,€‹,€ @£ -ÀÀ I -€ -£@ÌÁ€  A ˆ‚€H -Ë@H%€ -@œ I - -BHÀ/ - - - -:€â I&€ À` -É&€‰ - - Á  -ÀC -y +À= +y ÀŠ À•x þÀ @@ -28274,62 +20371,62 @@ H@Š À@JÃo - + -@x +@x A¡ € Î €x @x - - - -H€€.Àˆ.À À  -ˆ€!€H.ÀÈ.À€x ߀H&€É€Hb€ -'€ - -I#€ À  - + + + +H€€/Àˆ/À À  +ˆ€"€H/ÀÈ/À€x ߀H'€É€Hb€ +'€ + +I$€ À  + È€@c -@ˆ†€  - +@ˆ†€  + Œ À` -Œ +Œ I€ À IÀ L FÀ  -ɗ€ ɗÀ ˆ€É€ a ˆ-€É-€ a ˆ.€É.€ a +ɗ€ ɗÀ ˆ€É€ a ˆ.€É.€ a ˆ/€É/€ a €ÿ ER   ˆ €È  €I €H‚ -ˆ-€É-€ ¢` /€J/€J¢` HR@ -ˆ-€À  -@ +ˆ.€É.€ ¢` 0€J0€J¢` HR@ +ˆ.€À  +@ ȇÀ -/€I/€‰¢` '(€Àë  +0€I0€‰¢` '(€Àë  - - - /€Š-€‰"€ + + + 0€Š.€‰"€ @x É@H Ê@   -I/€H -Ì@ Ë@@ +I0€H +Ì@ Ë@@  - “@K² + “@K² H€01DH¢ HR €n - -/€@a -I#€ À  + +0€@a +I$€ À  € @@ -28337,9 +20434,9 @@ I#€ À  -€ +€ @a - €@ + €@ Î> €~ Ž@Àþ M@ €Ò@LÀ J Î> €~ Ž@Àþ M@ €Ò@LÀL @@ -28352,43 +20449,43 @@ H À  -€: +€: "Ab !H! -_ñÁ I#€ €€ +_ñÁ I$€ €€ €x É© + -@ñ +@ñ ×@@€ - + Á¢ À @u À -À -‰.€H2€ - - -€x -x ‰.ÀI -! +À +‰/€H2€ + + +€x +x ‰/ÀI +! À -! -J Jˆ +! +J Jˆ @x ¢BX HÀ` €x ¢BP ˆÀ` À -! +! JH H@¡ JH ˆÀ  JH JH A‡1 - + À x IÀ¡ ‰@¢ ɀŠ @@ -28402,25 +20499,25 @@ JH JH ÉA§ ` Àx -!Àˆ"€J@‰’ +"Àˆ"€J@‰’ @È@ ² @H3€ @Ê€  @È@ ² @È"@I -@ +@ À€K À€K - + À€‹ À€‹ -À€K +À€K 3@€À   -À€‹ +À€‹ 3@€À   @@ -28429,51 +20526,51 @@ JH JH Š€I@J¢@ B` H€€ I € "| €¡ Š€I@J¢@ -Bh H€€ %G‰€ @ B D ‰ € "H  G € "@ I € "H "P  D € @ I€ B  D € "@ I € "D   -€HHÀ0€ˆHÀÈ€I€I@H‚ÀÈHÀˆ€IÀÈ€HIÀ€‰I€ € - +Bh H€€ %G‰€ @ B D ‰ € "H  G € "@ I € "H "P  D € @ I€ B  D € "@ I € "D   +€HIÀ1€ˆIÀÈ€I€I@H‚ÀÈIÀˆ€JÀÈ€HJÀ€‰J€ € + H€ € HÀ -#€I€ HÀ -ˆ#€‰€ HÀ -È#€ɐ€ HÀ -$€ ‘€ HÀ -H+€I‘€ HÀ -ˆ+€‰‘€ HÀ -(€ɑ€ HÀ -H(€ ’€ HÀ -H,€I’€ HÀ - -R€È0€  +$€I€ HÀ +ˆ$€‰€ HÀ +È$€ɐ€ HÀ +%€ ‘€ HÀ +H,€I‘€ HÀ +ˆ,€‰‘€ HÀ +)€ɑ€ HÀ +H)€ ’€ HÀ +H-€I’€ HÀ + +T€È1€  ‰2@ @þ I - -Š -® ˆ‚ + +Š +® ˆ‚ €ï -@ - 0ÀÀ +@ + 1ÀÀ - 0€I€ 0À + 1€I€ 1À €J¢@ɑ€  A ˆ‚€H@M @ - +  -/€^a Ѐ ’ +0€^a Ѐ ’ $@¢ £Y@æhB&iÀ - + -J;€ˆ +J<€ˆ b I@€ô %A#ú€$AdIA #€ï ã@#€€äA €€$ € - - + + Š€ã€$@‚#™À $ @@ -28492,14 +20589,14 @@ $ð‚£9#I €÷ $$€f $"€€x - -%>€å€` + +%?€å€` À x %` -@)x %>€£ ! d€Ÿ&é€ +@)x %?€£ ! d€Ÿ&é€ d %  @x -$$€$$€$ +$$€$$€$ $A$> $ @@ -28507,14 +20604,14 @@ $A$> $ äcÀ d€! - + åQ f9@ @ x e<€&Êa d)eÀà x ¥€æIa deÀ @ x å€$Ò@€@æ $) ä€a -ã€#:À Á@c‚@ Á +ã€#;À Á@c‚@ Á cÀ% fH£ Š£ @@ -28530,7 +20627,7 @@ e å %Œ` - + £i2 $$€$$€$ d € @@ -28543,17 +20640,17 @@ d € ä ä€fÅ $€$<€@ - + - -h€‰r + +j€‰r #Á -C@ “ - -`€‰B€ -@ö -`€‰B€ +C@ “ + +b€‰B€ +@ö +b€‰B€ Àô À (Ñ @@ -28697,45 +20794,45 @@ J s@J€H€ˆB€ JÀ@E s@ A‡H> IÀH< ‰ÀH26 ÉÀH4 ÀH2 IÀ - -€ + +€ € -x €š ‰€H€À€™ É€ˆ€!À AH> IÀ @¡ - +x €š ‰€H€À€™ É€ˆ€"À AH> IÀ @¡ + - -É#À $ÀI$À@x ‰$À A‚H> É#ÀH< €a - $À€ I$€ + +É$À %ÀI%À@x ‰%À A‚H> É$ÀH< €a + %À€ I%€ ˆ€€¢ €À  - + -@~} ÿÀ - - ?€ À¡ +@~} ÿÀ + + @€ À¡ É€Hr‚ ÀÉÿ  - + € ÀÀ s@Àr s@ À € À€  s@J€H€ˆB€ JÀ€ -s@È%€ -‰&À@x I&ÀH€@¡ - -€J¢@ɑ€ ˆ‚€H&Àˆ&€À  +s@È&€ +‰'À@x I'ÀH€@¡ + +€J¢@ɑ€ ˆ‚€H'Àˆ'€À  ÀLx -ȁ€ €c É&€ˆ€@¡ -I +ȁ€ €c É'€ˆ€@¡ +I a - -€J¢@ɑ€ ˆ‚€H'À AH> @a - @€@1 ΀ + +€J¢@ɑ€ ˆ‚€H(À AH> @a + A€@1 ΀ @ x Š€ @¡ @@ -28743,55 +20840,55 @@ I ˆ€HÀ¥ ˆ€ˆÀ! I €A! ‰ €Â É € !€ A@x  A‰ €IB €J¢@ɑ€ ˆ‚€ AH>  AH> À  - -(À + +)À A AH> €b -‰€‰bT ‰(À À` - -À> É(€É(€I - -É/€IÀ @T +‰€‰bT ‰)À À` + +À> É)€É)€I + +É0€IÀ @T A‰l - )ÀI€ @¡ - + *ÀI€ @¡ + @a -I +I À  -É(€‰(€I - +É)€‰)€I + €I€ { - -À' É*€@' +€ AH€Ê*€ˆ‚ -+€ˆ‚ - - $€‰+ÀI$€É+À‰$€Àx ,À AH> €a -‰+À@ É+€À ,€ˆ#€@£ - -H(€@a -ˆ+€À  -@x -H#€€` -@x € ‰,€‹,€ @£ + +À' É+€@' ,€ AH€Ê+€ˆ‚ +,€ˆ‚ + + %€‰,ÀI%€É,À‰%€Àx -À AH> €a +‰,À@ É,€À -€ˆ$€@£ + +H)€@a +ˆ,€À  +@x +H$€€` +@x € ‰-€‹-€ @£ € I € £@ÌÁ€  A ˆ‚€H -Ë@H%€ +Ë@H&€ F> €o - + -:€â I&€ À` -É&€‰ - +;€â I'€ À` +É'€‰ + Á  -€š +€š âA Ã@‹âÊ - ² + ² @@ -28859,7 +20956,7 @@ H - + +Ö@+@­ @@ -29183,7 +21280,7 @@ a . AîêB+×@+@€ -€Jò`  €J€JÂ`  +€Jò`  €J€JÂ`  +Ö@+@­ @@ -29505,7 +21602,7 @@ a . AîêB+×@+@€ -€Jò`  €J€JÂ`  +€Jò`  €J€JÂ`  +Ö@+@­ @@ -29824,7 +21921,7 @@ a . AîêB+×@+@€ -€Jò`  €J€JÂ`  +€Jò`  €J€JÂ`  +Ö@+@­ @@ -30143,7 +22240,7 @@ a . AîêB+×@+@€ -€Jò`  €J€JÂ`  +€Jò`  €J€JÂ`  +Ö@+@­ @@ -30465,7 +22562,7 @@ a . AîêB+×@+@€ -€Jò`  €J€JÂ`  +€Jò`  €J€JÂ`  +Ö@+@­ @@ -30790,780 +22887,7 @@ a . AîêB+×@+@€ -€Jò`  €J€JÂ`  - -+Ö@+@­ - - - -€ y - -IÀ¡ -‰ -€@¡ -ˆ -€À  -H - AƒH2: ‰ ÀÀ# -h OIÀ  -@÷x - -H€ - €IÀI -‰€ €IÀ AƒH2: ‰ÀÉÁ` - - - AˆH‚0 À AH! I - -J - AH> €` -Àx  AH> -ˆ0 ‡ - -Hb2 - -ˆ0 ‡ - -Hb2 - -ˆ0 ‡ - -Hb2 - -ˆ0 ‡ - -Hb2 - -ˆ0 ‡ - -Hb2 - -ˆ0 ‡ - -Hb2 - -ˆ4 … - -HB6 - -ˆ4 … - -HB6 - -ˆ4 … - -HB6 - -Àˆ€ ’ -ˆ €Àa -È €@a - -€À` - -I -À -ÀOAI -€ n ‰ -€ p É -€ r € t O - -Àþ Š -@¡ - AH> J¢ - ÀH -€À` -È€ÈÀ` - - -A¯€ - -Ê£€ @ x - MAï€ÀÏ - - - -H‚0 - -I - - - -H‚0 - - -H €  - -ˆ€Àa - €@a -H €À` - - -ˆ" Ê - AAAH €o -H J¢ -2X O -b -H¿ÈÀAAAH €o - - -H @¢ -H¿ÈbÀ -"| AAAH @m - -B@ ÊÀ« Š -¿ˆ - -Àx H¿ÀAAAH €o - -H¿ÈÀAAAH €o - - -OAH€H -Oˆ JB@ -ˆ - - -H À¢ - - -H À  -J -ÀOA -"T OŠ -H¿ÀAAAH €o - -H"¿HÀAAAH €o - - -H¿ÀAAAH €o - - - -ÀÀAAAH €o - - - -ˆ ÀÀ _ðÁ  € - € - -9A -€¡ - -9J2@ɗ€ ‰—€ :H€À  -ˆ€ -È € -€À  -€ù - -ˆ€€H2@ È€2 - -€Jò`  €J€JÂ`  -I -I - -OAH€ - -O - -H @  -€ˆ‡€ ȇ€ $H €Àf -ˆ €@f - - - - -€ -À  -@þ -h O€@a - -À  AˆH‚0 À AŒHÂ( IÀ  ‰ ˆb€ -Ê €‰ -Š €J€ OAJb@ OŠ -Ë#À -À - - -€‚H": ‰À` ‰ -2` O€ - -*CAf -#G -€À  -@À -I—À È € - ÀÀ~ -ÀÁ - - €K€Ka AK²@/€€ -À -I€H2€ - -x É€J €Š" -$ -€À  -Àl -A‡1 -@ -À|~ -€ˆ(À €È(Àˆ€+ÀÁ@Q €R  PPCò€H€ï - - -‰2@ @þ I -Š@ F‰> -€o - -‰ -À€ x J„ -- - -É?€ AˆH‚0 ˂@ɂ@ ʀ­ Š -Á` - -- AH> À¿ -É -À - -É?€ AˆH‚0 ˂@ɂ@ Š€­ Š -€ x - - -ÉV  A‡Hb4 ‰b@ ÉbH H2 ‰P ÉT B - -@ AH> €¡ -ÉF  A‚H"< É"B  AH> É@ Ì2l Ë·€ Ìa FÀô  - € -À  -‹€ -Àa -‰€ˆ‚ H -‹’ - -Ê?€‰ -’ -Ë?€É - -’ -Ë?€É -’ -È?€  -€@¡ -È -€À` - - - - -€€¢ -H€ Ë@H’ -Ê€ €I -‰€@x I -Ê€ -@a - €I -€‰b -‰€IB -€@¡ -È -€À` - - - - - - H2@"@H‚ -€€` - -P/€À: -ˆ€H@£ - -H‚0 - - -H‚0 - -H?€É€ "P à -È@ÌbAË·€ Ìa F - -ÀˆòŠb€ -î€+€«».ð‚«[ - -a . AîêB+×@+@€ - - - - -!+ A/€€ - -Àö -Àõ -,Ò@l€! - - -‰o - -ðƒ 00 -À -0Ñ -Àx 1! - - - -€Jò`  €J€JÂ`  - FL € CL R@  -I€` -€ëx ‰€` -€Øx H! -€@x -G€ @a - -@x -€ y -Ç€À - -,  - € - - - -Ç€À -Ã! - - -JÀ -ÇÀ - -, ! - - GÀ$ -€À` - -ˆ - -@I - -GIǁ  -I@ -€o -I@èIH€€ è œIÇQ €ï - -€ê -‚kÀüW Rk@5P ` -ˆ€Èÿš -ˆ€ÒÀ -r€ -H - -@I -É€ € ÉÀˆ`À -€ÿ -G€ À` -@Ãx -É€ € ÉÀG`ÀH€R@ -‡`€ˆ€"@ - -‡€È - -’ bÀ - -2 x€ -B€  -  - -€ - -€ - -ÇA§ -‡ -Ç@a - - - - - -£ -Š€JÀ` - -ˆ -‰ - À@ÀIÀ € ^ G \ G Z É€ÉÀ  -I - - - -ËI -¢@ -QGb€ɑ@I2 -QHbÀIb  P PCIò€I€ï Àb -€î -QË€ RIc  P PCIò€I€ï G €ˆ €B  - -€G€ LI ÉB Hb€Bx „€ Ö Ç€€Èa × t - -€x Ç@‡À  -‰€ €ɀã - - -ɱÇ -€x ‰€Éÿ  - -Éÿƒ À¡ -GIǁ ˆa€€¥ -²O -I@Èÿƒ»IÇÁ -À  - - -@L‡r@ǁ -À` -H - -I -€¡ -@a - - -L -H2X -  -‡ -Àx Ç@‡À  -‰€ €ÉA$ -@c - - - À ÊÀÊ£€ H€ -@€ x - - - - €á€GÀà €x  -H - -€á €& -ˆ -€a -€‚% -È - €á -€„$ -€Š €a €ˆ# -H€J €! €" -ˆ€Ê €¡ € ! -ȀΠG -‡€‡ -‡€ÇA ÈQ@ -G - -@x GH ˆÀ` -€x GP ÈÀ` -Àx GX €Á` -@x G@ HÁ` -€x GH ˆÁ` -À -²  -’ ‡€G -@x Ç€ÀÈÀ ‘I  ‰€IB@HB@ ‰À -‘ À - - - - - - -Àà -Àà -ÀÄI Àà -ÀÅIƒ Àà - -AL"CL¢Çh ÞØ@ -Þ - -(à -Àx (ÀhÀ£ -©ÿ¿š@£ -iÿ¿èÀ¢ -éþ¿(A¢ -éý¿hÁ¡ -éû¿šA¡ -é÷¿èÁ  -éï¿éß¿ -š€(€¡ -( €)CL): -€ÀÈ€ÈÀ  -ˆ - - -‡€È - -ˆ -@x € Àa - -I -ÇA@_€`ÀË -@‹~ -ÈA@ - - - - - - -Çs€ ‡s€ E€Ë€ËÀg -ƒ -…€a - - -Œ€L@a - -„ - -„ -E@a - -Œ€L - -D -   ‡! †À¥ -<€Ȁa -E<€ÇB€ - -ÇB - - =€È -E=€„=€Å=€  E D’€L>€L€¡ -Çb - -D@À @€ - -Àx HR& ‰b@I"@J¢@Hb ‰’ - FL € CL R@  -I€` -€åx ‰€` -€Òx H! - -G€ @a - -@x -€y -Ç€À - -,  - € - - -€+ -Ç€À -Ã! - - -JÀ -ÇÀ - -, ! - - GÀ$ -€À` - -ˆ - -@I - -GIǁ  -I@ -€o -I@ŽIp€ v€ Gv€ ‡v€ Gw€ Ž pÀ vÀ GvÀ ‡vÀ GwÀ Ž  - -‚kÀüW Rk@5P ` -ˆ€Èÿš -ˆ€ÒÀ -r€ -H - -@I -É€ € ÉÀˆ`À -€ÿ -G€ À` -ÀÁx -É€ € ÉÀG`ÀH€R@ -‡`€ˆ€"@ - -‡€È -’ bÀ - -2 x€ -B€  - €€ - -€ - -€ - -ÇA§ -‡ -Ç@a - - - - - -£ -Š€JÀ` - -ˆ -‰ - À@ÀIÀ € ^ G \ G Z É€ÉÀ  -I - - - -ËI -¢@ -QGb€ɑ@I2 -QHbÀIb  P PCIò€I€ï Àb -€î -QË€ RIc  P PCIò€I€ï G €ˆ €B  - -€G€ LI ÉB Hb€Bx „€ Ö Ç€€Èa × t - -€x Ç@‡À  -‰€ €ɀã - - -ɱÇ - - -Éÿƒ À¡ -GIǁ ˆa€ -²O -I@Èÿƒ»IÇÁ -À  - - -@L‡r@ǁ -À` -H - -I -€¡ -@a - - -L -H2X -  -‡ -Àx Ç@‡À  -‰€ €ÉA$ -@c - - - À ÊÀÊ£€ H€ -@€ x - - - - €á€GÀà €x  -H - -€á €& -ˆ -€a -€‚% -È - €á -€„$ -€Š €a €ˆ# -H€J €! €" -ˆ€Ê €¡ € ! -ȀΠG -‡€‡ -‡€ÇA ÈQ@ -G - -@x GH ˆÀ` -€x GP ÈÀ` -Àx GX €Á` -@x G@ HÁ` -€x GH ˆÁ` -À -²  -’ ‡€G -@x Ç€ÀÈÀ ‘I  ‰€IB@HB@ ‰À -‘ À - - - - - - -Àà -Àà -ÀÄI Àà -ÀÅIƒ Àà - -AL"CL¢Çh ÞØ@ -Þ - -(à -Àx (ÀhÀ£ -©ÿ¿š@£ -iÿ¿èÀ¢ -éþ¿(A¢ -éý¿hÁ¡ -éû¿šA¡ -é÷¿èÁ  -éï¿éß¿ -š€(€¡ -( €)CL): -€ÀÈ€ÈÀ  -ˆ - - -‡€È - -ˆ -@x € Àa - -I -ÇA@_€`ÀË -À’~ -ÈA@ - - - - - - -Çs€ ‡s€ E€Ë€ËÀg -ƒ -…€a - - -Œ€L@a - -„ - -„ -E@a - -Œ€L - -D -   ‡! †À¥ -<€Ȁa -E<€ÇB€ - -ÇB - - =€È -E=€„=€Å=€  E D’€L>€L€¡ -Çb - -D@À @€ - -Àx HR& ‰b@I"@J¢@Hb ‰’ +€Jò`  €J€JÂ`  FL € CL R@  I€` €ëx ‰€` @@ -31791,7 +23115,7 @@ E=€„=€Å=€  E D’€L>€L€¡ D@À @€ -Àx HR& ‰b@I"@J¢@Hb ‰’ +Àx HR& ‰b@I"@J¢@Hb ‰’ FL € CL R@  I€` €åx ‰€` @@ -32017,4 +23341,4 @@ E=€„=€Å=€  E D’€L>€L€¡ D@À @€ -Àx HR& ‰b@I"@J¢@Hb ‰’ +Àx HR& ‰b@I"@J¢@Hb ‰’ -- cgit