summaryrefslogtreecommitdiff
Diffstat
-rw-r--r--[-rwxr-xr-x]Media.mk1
-rw-r--r--drivers/amvdec_ports/Makefile1
-rw-r--r--drivers/amvdec_ports/aml_vcodec_adapt.c112
-rw-r--r--drivers/amvdec_ports/aml_vcodec_adapt.h5
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.c992
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.h2
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec_drv.c122
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec_pm.c206
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec_pm.h34
-rw-r--r--drivers/amvdec_ports/aml_vcodec_drv.h188
-rw-r--r--drivers/amvdec_ports/aml_vcodec_util.c34
-rw-r--r--drivers/amvdec_ports/aml_vcodec_util.h90
-rw-r--r--drivers/amvdec_ports/aml_vcodec_vfm.c28
-rw-r--r--drivers/amvdec_ports/decoder/aml_h264_parser.c81
-rw-r--r--drivers/amvdec_ports/decoder/aml_h264_parser.h1
-rw-r--r--drivers/amvdec_ports/decoder/aml_hevc_parser.c133
-rw-r--r--drivers/amvdec_ports/decoder/aml_hevc_parser.h1
-rw-r--r--drivers/amvdec_ports/decoder/aml_mjpeg_parser.c34
-rw-r--r--drivers/amvdec_ports/decoder/aml_mjpeg_parser.h1
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg12_parser.h1
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg4_parser.c178
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg4_parser.h1
-rw-r--r--drivers/amvdec_ports/decoder/aml_vp9_parser.c26
-rw-r--r--drivers/amvdec_ports/decoder/aml_vp9_parser.h1
-rw-r--r--drivers/amvdec_ports/decoder/vdec_h264_if.c223
-rw-r--r--drivers/amvdec_ports/decoder/vdec_hevc_if.c194
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mjpeg_if.c210
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mpeg12_if.c304
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mpeg4_if.c209
-rw-r--r--drivers/amvdec_ports/decoder/vdec_vp9_if.c195
-rw-r--r--drivers/amvdec_ports/vdec_drv_if.c6
-rw-r--r--drivers/amvdec_ports/vdec_drv_if.h21
-rw-r--r--drivers/common/chips/chips.c1
-rw-r--r--drivers/common/chips/decoder_cpu_ver_info.c8
-rw-r--r--drivers/common/chips/decoder_cpu_ver_info.h1
-rw-r--r--drivers/common/firmware/firmware_drv.c9
-rw-r--r--drivers/common/firmware/firmware_type.c1
-rw-r--r--drivers/common/firmware/firmware_type.h1
-rw-r--r--drivers/common/media_clock/clk/clk.c3
-rw-r--r--drivers/common/media_clock/clk/clkg12.c5
-rw-r--r--drivers/frame_provider/decoder/Makefile1
-rw-r--r--drivers/frame_provider/decoder/avs/avs.c60
-rw-r--r--drivers/frame_provider/decoder/avs2/avs2_bufmgr.c12
-rw-r--r--drivers/frame_provider/decoder/avs2/avs2_global.h3
-rw-r--r--drivers/frame_provider/decoder/avs2/vavs2.c115
-rw-r--r--drivers/frame_provider/decoder/avs_multi/Makefile2
-rw-r--r--drivers/frame_provider/decoder/avs_multi/avs_multi.c1633
-rw-r--r--drivers/frame_provider/decoder/avs_multi/avsp_trans_multi.c5065
-rw-r--r--drivers/frame_provider/decoder/h264/vh264.c58
-rw-r--r--drivers/frame_provider/decoder/h264_multi/h264_dpb.c50
-rw-r--r--drivers/frame_provider/decoder/h264_multi/h264_dpb.h34
-rw-r--r--drivers/frame_provider/decoder/h264_multi/vmh264.c1043
-rw-r--r--drivers/frame_provider/decoder/h265/vh265.c707
-rw-r--r--drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c60
-rw-r--r--drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c595
-rw-r--r--drivers/frame_provider/decoder/mpeg4/vmpeg4.c5
-rw-r--r--drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c80
-rw-r--r--drivers/frame_provider/decoder/utils/amvdec.c5
-rw-r--r--drivers/frame_provider/decoder/utils/frame_check.c178
-rw-r--r--drivers/frame_provider/decoder/utils/frame_check.h4
-rw-r--r--drivers/frame_provider/decoder/utils/vdec.c530
-rw-r--r--drivers/frame_provider/decoder/utils/vdec.h18
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_input.c12
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_input.h3
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c92
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h7
-rw-r--r--drivers/frame_provider/decoder/vav1/Makefile2
-rw-r--r--drivers/frame_provider/decoder/vav1/aom_av1_define.h171
-rw-r--r--drivers/frame_provider/decoder/vav1/av1_bufmgr.c3392
-rw-r--r--drivers/frame_provider/decoder/vav1/av1_global.h2310
-rw-r--r--drivers/frame_provider/decoder/vav1/vav1.c9946
-rw-r--r--drivers/frame_provider/decoder/vav1/vav1.h22
-rw-r--r--drivers/frame_provider/decoder/vc1/vvc1.c46
-rw-r--r--drivers/frame_provider/decoder/vp9/vvp9.c449
-rw-r--r--drivers/frame_sink/encoder/h264/encoder.c2
-rw-r--r--drivers/stream_input/Makefile5
-rw-r--r--drivers/stream_input/amports/amstream.c263
-rw-r--r--drivers/stream_input/parser/demux/aml_dvb.h5
-rw-r--r--drivers/stream_input/parser/demux/hw_demux/demod_gt.h62
-rw-r--r--drivers/stream_input/parser/demux/hw_demux/frontend.c293
-rw-r--r--drivers/stream_input/parser/dvb_common.c17
-rw-r--r--drivers/stream_input/parser/dvb_common.h26
-rw-r--r--drivers/stream_input/parser/esparser.c15
-rw-r--r--drivers/stream_input/parser/hw_demux/aml_demod_gt.h87
-rw-r--r--drivers/stream_input/parser/hw_demux/aml_dmx.c270
-rw-r--r--drivers/stream_input/parser/hw_demux/aml_dvb.c445
-rw-r--r--drivers/stream_input/parser/hw_demux/aml_dvb.h32
-rw-r--r--drivers/stream_input/parser/streambuf.c9
-rw-r--r--drivers/stream_input/parser/tsdemux.c14
-rw-r--r--drivers/stream_input/parser/tsdemux.h1
-rw-r--r--drivers/stream_input/tv_frontend/Makefile16
-rw-r--r--drivers/stream_input/tv_frontend/aml_fe.c1372
-rw-r--r--drivers/stream_input/tv_frontend/aml_fe.h213
-rw-r--r--drivers/stream_input/tv_frontend/atv_demod/atvdemod_frontend.c791
-rw-r--r--drivers/stream_input/tv_frontend/atv_demod/atvdemod_func.c2163
-rw-r--r--drivers/stream_input/tv_frontend/atv_demod/atvdemod_func.h323
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/aml_demod.c725
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/amlfrontend.c1402
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/demod_func.c2996
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/dvbc_func.c1331
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/dvbt_func.c2188
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/i2c_func.c42
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/acf_filter_coefficient.h414
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_che.h77
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_che_bit.h266
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_front.h70
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_front_bit.h331
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_sync.h53
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_sync_bit.h110
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_top.h90
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/addr_dtmb_top_bit.h178
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/aml_dtv_demod_reg.h28
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/amlfrontend.h86
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/include/demod_func.h626
-rw-r--r--drivers/stream_input/tv_frontend/dtv_demod/tuner_func.c189
-rw-r--r--firmware/video_ucode.bin14148
116 files changed, 25845 insertions, 36303 deletions
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);
/*