From: shihong.zheng Date: Tue, 16 Jun 2020 13:54:30 +0000 (+0800) Subject: media_modules: sc2 media modules bringup. [1/1] X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=1418c7d85efb873033c3c7a93c9ecb32138a88ff;p=GitHub%2FLineageOS%2FG12%2Fandroid_hardware_amlogic_kernel-modules_media.git media_modules: sc2 media modules bringup. [1/1] PD#SWPL-26369 Problem: sc2 media modules bringup. Solution: support sc2 decoder changes. ucode change id: Ieb122b1 ucode commit id: ff35011e Verify: ptm/pxp Change-Id: Ibda54d1710ef61841ae2a75c10912e796434dac2 Signed-off-by: shihong.zheng --- diff --git a/drivers/common/chips/chips.c b/drivers/common/chips/chips.c index 9cabb1d..d692ca8 100644 --- a/drivers/common/chips/chips.c +++ b/drivers/common/chips/chips.c @@ -77,6 +77,7 @@ static const struct type_name cpu_type_name[] = { {AM_MESON_CPU_MAJOR_ID_SM1, "sm1"}, {AM_MESON_CPU_MAJOR_ID_TL1, "tl1"}, {AM_MESON_CPU_MAJOR_ID_TM2, "tm2"}, + {AM_MESON_CPU_MAJOR_ID_SC2, "sc2"}, {0, NULL}, }; diff --git a/drivers/common/chips/decoder_cpu_ver_info.c b/drivers/common/chips/decoder_cpu_ver_info.c index 894bd74..d74728c 100644 --- a/drivers/common/chips/decoder_cpu_ver_info.c +++ b/drivers/common/chips/decoder_cpu_ver_info.c @@ -61,6 +61,9 @@ static enum AM_MESON_CPU_MAJOR_ID cpu_ver_info[AM_MESON_CPU_MAJOR_ID_MAX - MAJOR AM_MESON_CPU_MAJOR_ID_RES_0x2d, AM_MESON_CPU_MAJOR_ID_TL1, AM_MESON_CPU_MAJOR_ID_TM2, + AM_MESON_CPU_MAJOR_ID_RES_0x30, + AM_MESON_CPU_MAJOR_ID_RES_0x31, + AM_MESON_CPU_MAJOR_ID_SC2, }; static const struct of_device_id cpu_ver_of_match[] = { @@ -107,6 +110,10 @@ static const struct of_device_id cpu_ver_of_match[] = { .compatible = "amlogic, cpu-major-id-tm2", .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_TM2 - MAJOR_ID_START], }, + { + .compatible = "amlogic, cpu-major-id-sc2", + .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_SC2 - MAJOR_ID_START], + }, {}, }; diff --git a/drivers/common/chips/decoder_cpu_ver_info.h b/drivers/common/chips/decoder_cpu_ver_info.h index 83e8274..cd97477 100644 --- a/drivers/common/chips/decoder_cpu_ver_info.h +++ b/drivers/common/chips/decoder_cpu_ver_info.h @@ -48,6 +48,9 @@ enum AM_MESON_CPU_MAJOR_ID AM_MESON_CPU_MAJOR_ID_RES_0x2d, AM_MESON_CPU_MAJOR_ID_TL1 = 0x2e, AM_MESON_CPU_MAJOR_ID_TM2 = 0x2f, + AM_MESON_CPU_MAJOR_ID_RES_0x30, + AM_MESON_CPU_MAJOR_ID_RES_0x31, + AM_MESON_CPU_MAJOR_ID_SC2 = 0x32, AM_MESON_CPU_MAJOR_ID_MAX, }; diff --git a/drivers/common/firmware/firmware_type.c b/drivers/common/firmware/firmware_type.c index ac35859..c232020 100644 --- a/drivers/common/firmware/firmware_type.c +++ b/drivers/common/firmware/firmware_type.c @@ -75,6 +75,7 @@ static const struct cpu_type_s cpu_type[] = { {AM_MESON_CPU_MAJOR_ID_SM1, "sm1"}, {AM_MESON_CPU_MAJOR_ID_TL1, "tl1"}, {AM_MESON_CPU_MAJOR_ID_TM2, "tm2"}, + {AM_MESON_CPU_MAJOR_ID_SC2, "sc2"}, }; const char *get_fw_format_name(unsigned int format) diff --git a/drivers/common/media_clock/clk/clkg12.c b/drivers/common/media_clock/clk/clkg12.c index 22d71a6..237ddc1 100644 --- a/drivers/common/media_clock/clk/clkg12.c +++ b/drivers/common/media_clock/clk/clkg12.c @@ -414,18 +414,24 @@ static struct clk_set_setting clks_for_formats[] = { void set_clock_gate(struct gate_switch_node *nodes, int num) { struct gate_switch_node *node = NULL; + char *hevc_mux_str = NULL; + + if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2) + hevc_mux_str = "clk_hevc_mux"; + else + hevc_mux_str = "clk_hevcf_mux"; do { node = &nodes[num - 1]; - if (IS_ERR_OR_NULL(node)) + if (IS_ERR_OR_NULL(node) || (IS_ERR_OR_NULL(node->clk))) pr_info("get mux clk err.\n"); if (!strcmp(node->name, "clk_vdec_mux")) gclk.vdec_mux_node = node; else if (!strcmp(node->name, "clk_hcodec_mux")) gclk.hcodec_mux_node = node; - else if (!strcmp(node->name, "clk_hevc_mux")) - gclk.hevc_mux_node = node; + else if (!strcmp(node->name, hevc_mux_str)) + gclk.hevc_mux_node = node; else if (!strcmp(node->name, "clk_hevcb_mux")) gclk.hevc_back_mux_node = node; } while(--num); @@ -785,7 +791,8 @@ static int hevc_back_clock_set(int clk) clk = hevcb_frq; } - if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_TXLX) { + if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_TXLX) && + (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2)) { if ((READ_EFUSE_REG(EFUSE_LIC1) >> 28 & 0x1) && clk > 333) { pr_info("The hevcb clock limit to 333MHz.\n"); clk = 333; @@ -1022,6 +1029,7 @@ static int vdec_clock_get(enum vdec_type_e core) AM_MESON_CPU_MAJOR_ID_SM1,\ AM_MESON_CPU_MAJOR_ID_TL1,\ AM_MESON_CPU_MAJOR_ID_TM2,\ + AM_MESON_CPU_MAJOR_ID_SC2,\ 0} #include "clk.h" diff --git a/drivers/common/media_clock/switch/amports_gate.c b/drivers/common/media_clock/switch/amports_gate.c index beaea53..9d5f7b4 100644 --- a/drivers/common/media_clock/switch/amports_gate.c +++ b/drivers/common/media_clock/switch/amports_gate.c @@ -64,6 +64,9 @@ struct gate_switch_node gates[] = { { .name = "asyncfifo", }, + { + .name = "clk_hevcf_mux", + }, }; /* diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c index 9cf5629..0bb416c 100644 --- a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c +++ b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c @@ -47,6 +47,7 @@ #include "../utils/firmware.h" #include "../utils/vdec_v4l2_buffer_ops.h" #include "../utils/config_parser.h" +#include "../../../common/chips/decoder_cpu_ver_info.h" #include #define DRIVER_NAME "ammvdec_mpeg4" @@ -871,8 +872,8 @@ static void vmpeg4_prepare_input(struct vdec_mpeg4_hw_s *hw) /* reset VLD fifo for all vdec */ WRITE_VREG(DOS_SW_RESET0, (1<<5) | (1<<4) | (1<<3)); WRITE_VREG(DOS_SW_RESET0, 0); - - dummy = READ_RESET_REG(RESET0_REGISTER); + if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2) + dummy = READ_RESET_REG(RESET0_REGISTER); WRITE_VREG(POWER_CTL_VLD, 1 << 4); /* diff --git a/drivers/frame_provider/decoder/utils/vdec.c b/drivers/frame_provider/decoder/utils/vdec.c index 327242d..f75d735 100644 --- a/drivers/frame_provider/decoder/utils/vdec.c +++ b/drivers/frame_provider/decoder/utils/vdec.c @@ -78,6 +78,9 @@ #include #endif +#include +#include + static DEFINE_MUTEX(vdec_mutex); #define MC_SIZE (4096 * 4) @@ -135,7 +138,7 @@ static int enable_mvdec_info = 1; int decode_underflow = 0; -int enable_stream_mode_multi_dec; +static int enable_stream_mode_multi_dec; #define CANVAS_MAX_SIZE (AMVDEC_CANVAS_MAX1 - AMVDEC_CANVAS_START_INDEX + 1 + AMVDEC_CANVAS_MAX2 + 1) @@ -279,6 +282,15 @@ void VDEC_PRINT_FUN_LINENO(const char *fun, int line) } EXPORT_SYMBOL(VDEC_PRINT_FUN_LINENO); +bool is_support_no_parser(void) +{ + if ((enable_stream_mode_multi_dec) || + (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)) + return true; + return false; +} +EXPORT_SYMBOL(is_support_no_parser); + unsigned char is_mult_inc(unsigned int type) { unsigned char ret = 0; @@ -657,7 +669,8 @@ static void vdec_disable_DMC(struct vdec_s *vdec) codec_dmcbus_read(DMC_REQ_CTRL) & ~mask); spin_unlock_irqrestore(&vdec_spin_lock, flags); - if (is_cpu_tm2_revb()) { + if (is_cpu_tm2_revb() || + (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)) { while (!(codec_dmcbus_read(TM2_REVB_DMC_CHAN_STS) & mask)) ; @@ -1308,7 +1321,7 @@ static void vdec_sync_input_write(struct vdec_s *vdec) return; if (vdec->input.target == VDEC_INPUT_TARGET_VLD) { - if (enable_stream_mode_multi_dec) { + if (is_support_no_parser()) { if (!vdec->master) { WRITE_VREG(VLD_MEM_VIFIFO_WP, STBUF_READ(&vdec->vbuf, get_wp)); @@ -1321,7 +1334,7 @@ static void vdec_sync_input_write(struct vdec_s *vdec) STBUF_READ(&vdec->vbuf, get_wp)); } } else if (vdec->input.target == VDEC_INPUT_TARGET_HEVC) { - if (enable_stream_mode_multi_dec) { + if (is_support_no_parser()) { if (!vdec->master) { WRITE_VREG(HEVC_STREAM_WR_PTR, STBUF_READ(&vdec->vbuf, get_wp)); @@ -1359,8 +1372,8 @@ int vdec_prepare_input(struct vdec_s *vdec, struct vframe_chunk_s **p) /* reset VLD fifo for all vdec */ WRITE_VREG(DOS_SW_RESET0, (1<<5) | (1<<4) | (1<<3)); WRITE_VREG(DOS_SW_RESET0, 0); - - dummy = READ_RESET_REG(RESET0_REGISTER); + if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2) + dummy = READ_RESET_REG(RESET0_REGISTER); WRITE_VREG(POWER_CTL_VLD, 1 << 4); } else if (input->target == VDEC_INPUT_TARGET_HEVC) { #if 0 @@ -1823,7 +1836,8 @@ void hevc_wait_ddr(void) codec_dmcbus_read(DMC_REQ_CTRL) & ~mask); spin_unlock_irqrestore(&vdec_spin_lock, flags); - if (is_cpu_tm2_revb()) { + if (is_cpu_tm2_revb() || + (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)) { while (!(codec_dmcbus_read(TM2_REVB_DMC_CHAN_STS) & mask)) ; @@ -2199,7 +2213,7 @@ s32 vdec_init(struct vdec_s *vdec, int is_4k) *todo: VFM patch control should be configurable, * for now all stream based input uses default VFM path. */ - if (!enable_stream_mode_multi_dec) { + if (!is_support_no_parser()) { if (vdec_stream_based(vdec) && !vdec_dual(vdec)) { if (vdec_core->vfm_vdec == NULL) { pr_debug("vdec_init set vfm decoder %p\n", vdec); @@ -2236,7 +2250,7 @@ s32 vdec_init(struct vdec_s *vdec, int is_4k) /* todo */ if (!vdec_dual(vdec)) { p->use_vfm_path = - enable_stream_mode_multi_dec ? + (is_support_no_parser()) ? vdec_single(vdec) : vdec_stream_based(vdec); } @@ -2313,7 +2327,7 @@ s32 vdec_init(struct vdec_s *vdec, int is_4k) /* create IONVIDEO instance and connect decoder's * vf_provider interface to it */ - if (!enable_stream_mode_multi_dec) { + if (!is_support_no_parser()) { if (p->type != VDEC_TYPE_FRAME_BLOCK) { r = -ENODEV; pr_err("vdec: Incorrect decoder type\n"); @@ -3468,6 +3482,7 @@ void vdec_power_reset(void) } EXPORT_SYMBOL(vdec_power_reset); + void vdec_poweron(enum vdec_type_e core) { void *decomp_addr = NULL; @@ -3488,6 +3503,34 @@ void vdec_poweron(enum vdec_type_e core) return; } + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2) { + if (core == VDEC_1) + pwr_ctrl_psci_smc(PDID_DOS_VDEC, PWR_ON); + else if (core == VDEC_HEVC) { + pwr_ctrl_psci_smc(PDID_DOS_HEVC, PWR_ON); + + /* wait 10uS */ + udelay(10); + /* hevc soft reset */ + WRITE_VREG(DOS_SW_RESET3, 0xffffffff); + WRITE_VREG(DOS_SW_RESET3, 0); + /* enable hevc clock */ + amports_switch_gate("clk_hevcf_mux", 1); + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) + amports_switch_gate("clk_hevcb_mux", 1); + hevc_clock_hi_enable(); + hevc_back_clock_hi_enable(); + /* power up hevc memories */ + WRITE_VREG(DOS_MEM_PD_HEVC, 0); + /* remove hevc isolation */ + } else if (core == VDEC_HCODEC) + pwr_ctrl_psci_smc(PDID_DOS_HCODEC, PWR_ON); + + mutex_unlock(&vdec_mutex); + + return; + } + if (vdec_on(core)) { mutex_unlock(&vdec_mutex); return; @@ -3752,6 +3795,24 @@ void vdec_poweroff(enum vdec_type_e core) return; } + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2) { + if (core == VDEC_1) + pwr_ctrl_psci_smc(PDID_DOS_VDEC, PWR_OFF); + else if (core == VDEC_HEVC) { + pwr_ctrl_psci_smc(PDID_DOS_HEVC, PWR_OFF); + + /* disable hevc clock */ + hevc_clock_off(); + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) + hevc_back_clock_off(); + } + else if (core == VDEC_HCODEC) + pwr_ctrl_psci_smc(PDID_DOS_HCODEC, PWR_OFF); + + mutex_unlock(&vdec_mutex); + return; + } + is_power_ctrl_ver2 = ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TL1)) ? true : false; @@ -4061,7 +4122,8 @@ void vdec_reset_core(struct vdec_s *vdec) codec_dmcbus_read(DMC_REQ_CTRL) & ~mask); spin_unlock_irqrestore(&vdec_spin_lock, flags); - if (is_cpu_tm2_revb()) { + if (is_cpu_tm2_revb() || + (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)) { while (!(codec_dmcbus_read(TM2_REVB_DMC_CHAN_STS) & mask)) ; @@ -4150,7 +4212,8 @@ void hevc_reset_core(struct vdec_s *vdec) codec_dmcbus_read(DMC_REQ_CTRL) & ~mask); spin_unlock_irqrestore(&vdec_spin_lock, flags); - if (is_cpu_tm2_revb()) { + if (is_cpu_tm2_revb() || + (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)) { while (!(codec_dmcbus_read(TM2_REVB_DMC_CHAN_STS) & mask)) ; @@ -4178,10 +4241,18 @@ void hevc_reset_core(struct vdec_s *vdec) * 19:sao * 24:hevc_afifo */ - WRITE_VREG(DOS_SW_RESET3, + if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2) && + (vdec->format == VFORMAT_AVS2)) { + WRITE_VREG(DOS_SW_RESET3, (1<<3)|(1<<4)|(1<<8)|(1<<11)| - (1<<12)|(1<<13)|(1<<14)|(1<<15)| - (1<<17)|(1<<18)|(1<<19)|(1<<24)); + (1<<12)|(1<<14)|(1<<15)| + (1<<17)|(1<<18)|(1<<19)); + } else { + WRITE_VREG(DOS_SW_RESET3, + (1<<3)|(1<<4)|(1<<8)|(1<<11)| + (1<<12)|(1<<13)|(1<<14)|(1<<15)| + (1<<17)|(1<<18)|(1<<19)|(1<<24)); + } WRITE_VREG(DOS_SW_RESET3, 0); diff --git a/drivers/frame_provider/decoder/utils/vdec.h b/drivers/frame_provider/decoder/utils/vdec.h index 0a526d0..54c5903 100644 --- a/drivers/frame_provider/decoder/utils/vdec.h +++ b/drivers/frame_provider/decoder/utils/vdec.h @@ -468,4 +468,6 @@ int vdec_get_frame_num(struct vdec_s *vdec); int show_stream_buffer_status(char *buf, int (*callback) (struct stream_buf_s *, char *)); +bool is_support_no_parser(void); + #endif /* VDEC_H */ diff --git a/drivers/frame_provider/decoder/vav1/vav1.c b/drivers/frame_provider/decoder/vav1/vav1.c index cba2890..f8b03a3 100644 --- a/drivers/frame_provider/decoder/vav1/vav1.c +++ b/drivers/frame_provider/decoder/vav1/vav1.c @@ -3635,11 +3635,11 @@ struct loopfilter { //LpfSuperblockInfo neighbor_sb_lpf_info; //#endif // LOOP_FILTER_BITMASK }; - +#ifdef DBG_LPF_DBLK_LVL static int32_t myclamp(int32_t value, int32_t low, int32_t high) { return value < low ? low : (value > high ? high : value); } - +#endif /*static int8_t extend_sign_7bits(uint8_t value) { return (((value>>6) & 0x1)<<7) | (value&0x7f); }*/ @@ -3710,10 +3710,13 @@ void av1_loop_filter_frame_init(AV1Decoder* pbi, struct segmentation_lf *seg, struct loopfilter *lf, int32_t pic_width) { BuffInfo_t* buf_spec = pbi->work_space_buf; - int32_t i,dir; + int32_t i; +#ifdef DBG_LPF_DBLK_LVL + int32_t dir; int32_t filt_lvl[MAX_MB_PLANE], filt_lvl_r[MAX_MB_PLANE]; int32_t plane; int32_t seg_id; +#endif // 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 @@ -3730,7 +3733,7 @@ void av1_loop_filter_frame_init(AV1Decoder* pbi, struct segmentation_lf *seg, | (lfi->lfthr[i*2].mblim & 0xff); WRITE_VREG(HEVC_DBLK_CFG9, thr); } - +#ifdef DBG_LPF_DBLK_LVL filt_lvl[0] = lf->filter_level[0]; filt_lvl[1] = lf->filter_level_u; filt_lvl[2] = lf->filter_level_v; @@ -3854,6 +3857,8 @@ void av1_loop_filter_frame_init(AV1Decoder* pbi, struct segmentation_lf *seg, level = 0; WRITE_VREG(HEVC_DBLK_CFGA, level); } +#endif // DBG_LPF_DBLK_LVL + #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); @@ -3896,6 +3901,9 @@ void av1_loop_filter_frame_init(AV1Decoder* pbi, struct segmentation_lf *seg, { uint32_t cdef_data32 = (READ_VREG(HEVC_DBLK_CDEF1) & 0xffffff00); cdef_data32 |= 17; // TODO ERROR :: cdef temp dma address left offset +#ifdef DBG_LPF_CDEF_NO_PIPELINE + cdef_data32 |= (1<<17); // cdef test no pipeline for very small picture +#endif WRITE_VREG(HEVC_DBLK_CDEF1, cdef_data32); } // Picture count @@ -5943,10 +5951,14 @@ static void config_film_grain_reg(struct AV1HW_s *hw, int film_grain_params_ref_ 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); + int j; + AV1_COMMON *const cm = &hw->pbi->common; + + av1_set_next_ref_frame_map(hw->pbi); + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2) + WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x11a0); + else + 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); @@ -6593,7 +6605,10 @@ int av1_continue_decoding(struct AV1HW_s *hw, int obu_type) cm->cur_frame->segment_feature[i] = (0x80000000 | (i << 22)); } } - WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x1010 + (cur_pic_config->index)); + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2) + WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x11b0 + (cur_pic_config->index)); + else + 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 diff --git a/drivers/stream_input/amports/amstream.c b/drivers/stream_input/amports/amstream.c index fbf6517..75a72a5 100644 --- a/drivers/stream_input/amports/amstream.c +++ b/drivers/stream_input/amports/amstream.c @@ -123,8 +123,6 @@ static int def_vstreambuf_sizeM = (DEFAULT_VIDEO_BUFFER_SIZE >> 20); static int slow_input; -extern int enable_stream_mode_multi_dec; - /* #define DATA_DEBUG */ static int use_bufferlevelx10000 = 10000; static int reset_canuse_buferlevel(int level); @@ -907,7 +905,8 @@ static int amstream_port_init(struct port_priv_s *priv) mutex_lock(&amstream_mutex); - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { + if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) && + (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2)) { r = check_efuse_chip(port->vformat); if (r) { pr_info("No support video format %d.\n", port->vformat); @@ -960,7 +959,7 @@ static int amstream_port_init(struct port_priv_s *priv) get_esparser_stbuf_ops(); /* def used stbuf with parser if the feature disable. */ - if (!enable_stream_mode_multi_dec) + if (!is_support_no_parser()) ops = get_esparser_stbuf_ops(); } @@ -1614,7 +1613,7 @@ static int amstream_open(struct inode *inode, struct file *file) } } - if (!enable_stream_mode_multi_dec) { + if (!is_support_no_parser()) { if ((port->flag & PORT_FLAG_IN_USE) && ((port->type & PORT_TYPE_FRAME) == 0)) { mutex_unlock(&amstream_mutex); @@ -1717,6 +1716,7 @@ static int amstream_open(struct inode *inode, struct file *file) } } } + return 0; } @@ -3432,6 +3432,46 @@ static long amstream_do_ioctl_old(struct port_priv_s *priv, */ break; } + case AMSTREAM_IOC_INIT_EX_STBUF: { + struct stream_buffer_metainfo parm; + struct stream_buf_s *vbuf = &priv->vdec->vbuf; + + if (copy_from_user(&parm, (void __user *)arg, + sizeof(struct stream_buffer_metainfo))) { + return -EFAULT; + } + stream_buffer_set_ext_buf(vbuf, parm.stbuf_start, + parm.stbuf_size, parm.stbuf_flag); + break; + } + case AMSTREAM_IOC_WR_STBUF_META: { + struct stream_buffer_metainfo meta; + struct stream_buf_s *vbuf = &priv->vdec->vbuf; + + if (copy_from_user(&meta, (void __user *)arg, + sizeof(struct stream_buffer_metainfo))) { + return -EFAULT; + } + if (!vbuf->ext_buf_addr) + return -ENODEV; + + stream_buffer_meta_write(vbuf, &meta); + break; + } + case AMSTREAM_IOC_GET_STBUF_STATUS: { + struct stream_buffer_status st; + struct stream_buf_s *pbuf = &priv->vdec->vbuf; + + st.stbuf_start = pbuf->ext_buf_addr; + st.stbuf_size = pbuf->buf_size; + st.stbuf_rp = pbuf->ops->get_rp(pbuf); + st.stbuf_wp = pbuf->ops->get_wp(pbuf); + if (copy_to_user((void __user *)arg, &st, + sizeof(struct stream_buffer_status))) { + return -EFAULT; + } + break; + } default: r = -ENOIOCTLCMD; break; diff --git a/drivers/stream_input/amports/stream_buffer_base.c b/drivers/stream_input/amports/stream_buffer_base.c index e6dc5f1..d436441 100644 --- a/drivers/stream_input/amports/stream_buffer_base.c +++ b/drivers/stream_input/amports/stream_buffer_base.c @@ -88,8 +88,10 @@ int stream_buffer_base_init(struct stream_buf_s *stbuf, width = vdec->sys_info->width; height = vdec->sys_info->height; - memcpy(stbuf, get_def_parms(format), - sizeof(*stbuf)); + if (!stbuf->ext_buf_addr) { + memcpy(stbuf, get_def_parms(format), + sizeof(*stbuf)); + } stbuf->id = vdec->id; stbuf->is_hevc = ((format == VFORMAT_HEVC) || @@ -110,13 +112,38 @@ EXPORT_SYMBOL(stream_buffer_base_init); void stream_buffer_set_ext_buf(struct stream_buf_s *stbuf, ulong addr, - u32 size) + u32 size, + u32 flag) { stbuf->ext_buf_addr = addr; stbuf->buf_size = size; + stbuf->is_secure = ((flag & STBUF_META_FLAG_SECURE) != 0); + + /* + pr_debug("%s, addr %lx, size 0x%x, secure %d\n", __func__, + stbuf->ext_buf_addr, stbuf->buf_size, stbuf->is_secure); + */ } EXPORT_SYMBOL(stream_buffer_set_ext_buf); +void stream_buffer_meta_write(struct stream_buf_s *stbuf, + struct stream_buffer_metainfo *meta) +{ + u32 wp; + + if (meta->stbuf_pktaddr + meta->stbuf_pktsize < stbuf->buf_start + stbuf->buf_size) + wp = meta->stbuf_pktaddr + meta->stbuf_pktsize; + else + wp = meta->stbuf_pktaddr + meta->stbuf_pktsize - stbuf->buf_size; + + stbuf->ops->set_wp(stbuf, wp); + /* + pr_debug("%s, update wp 0x%x + sz 0x%x --> 0x%x\n", + __func__, meta->stbuf_pktaddr, meta->stbuf_pktsize, wp); + */ +} +EXPORT_SYMBOL(stream_buffer_meta_write); + ssize_t stream_buffer_write_ex(struct file *file, struct stream_buf_s *stbuf, const char __user *buf, diff --git a/drivers/stream_input/amports/stream_buffer_base.h b/drivers/stream_input/amports/stream_buffer_base.h index e7a107f..3360e64 100644 --- a/drivers/stream_input/amports/stream_buffer_base.h +++ b/drivers/stream_input/amports/stream_buffer_base.h @@ -44,8 +44,9 @@ int stream_buffer_base_init(struct stream_buf_s *stbuf, struct parser_args *pars); void stream_buffer_set_ext_buf(struct stream_buf_s *stbuf, - ulong addr, - u32 size); + ulong addr, + u32 size, + u32 flag); int stream_buffer_write(struct file *file, struct stream_buf_s *stbuf, @@ -58,5 +59,8 @@ ssize_t stream_buffer_write_ex(struct file *file, size_t count, int flags); +void stream_buffer_meta_write(struct stream_buf_s *stbuf, + struct stream_buffer_metainfo *meta); + #endif /* STREAM_BUFFER_INTERFACE_H */ diff --git a/drivers/stream_input/amports/stream_buffer_interface.c b/drivers/stream_input/amports/stream_buffer_interface.c index 71e83d0..e8981ed 100644 --- a/drivers/stream_input/amports/stream_buffer_interface.c +++ b/drivers/stream_input/amports/stream_buffer_interface.c @@ -31,6 +31,7 @@ #include #include #include "../../frame_provider/decoder/utils/vdec.h" +#include "../../common/chips/decoder_cpu_ver_info.h" #include "stream_buffer_base.h" #include "amports_priv.h" #include "thread_rw.h" @@ -88,6 +89,8 @@ static int stream_buffer_init(struct stream_buf_s *stbuf, struct vdec_s *vdec) if (stbuf->ext_buf_addr) { addr = stbuf->ext_buf_addr; size = stbuf->buf_size; + is_secure = stbuf->is_secure; + pages = (size >> PAGE_SHIFT); } else { flags |= CODEC_MM_FLAGS_FOR_VDECODER; if (vdec->port_flag & PORT_FLAG_DRM) { @@ -103,12 +106,11 @@ static int stream_buffer_init(struct stream_buf_s *stbuf, struct vdec_s *vdec) ret = -ENOMEM; goto err; } - - ret = vdec_set_input_buffer(vdec, addr, size); - if (ret) { - pr_err("[%d]: set input buffer err.\n", stbuf->id); - goto err; - } + } + ret = vdec_set_input_buffer(vdec, addr, size); + if (ret) { + pr_err("[%d]: set input buffer err.\n", stbuf->id); + goto err; } atomic_set(&stbuf->payload, 0); @@ -123,16 +125,18 @@ static int stream_buffer_init(struct stream_buf_s *stbuf, struct vdec_s *vdec) stbuf->buf_page_num = pages; stbuf->canusebuf_size = size; - /* init pts server. */ - ret = pts_start(type_to_pts(stbuf->type)); - if (ret < 0) { - pr_err("[%d]: pts server failed\n", stbuf->id); - //goto err;//fixme + if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2) { + /* init pts server. parser register w/r inside */ + ret = pts_start(type_to_pts(stbuf->type)); + if (ret < 0) { + pr_err("[%d]: pts server failed\n", stbuf->id); + //goto err;//fixme + } } - /* init thread write. */ if (!(vdec_get_debug_flags() & 1) && - !codec_mm_video_tvp_enabled()) { + !codec_mm_video_tvp_enabled() && + (!stbuf->ext_buf_addr)) { int block_size = PAGE_SIZE << 4; int buf_num = (2 * SZ_1M) / (PAGE_SIZE << 4); diff --git a/drivers/stream_input/amports/streambuf.c b/drivers/stream_input/amports/streambuf.c index 20aa640..8243f56 100644 --- a/drivers/stream_input/amports/streambuf.c +++ b/drivers/stream_input/amports/streambuf.c @@ -265,10 +265,11 @@ u32 stbuf_space(struct stream_buf_s *buf) size = size - 6 * 1024; } - if ((buf->type == BUF_TYPE_VIDEO) - || (has_hevc_vdec() && buf->type == BUF_TYPE_HEVC)) - size -= READ_PARSER_REG(PARSER_VIDEO_HOLE); - + if (!buf->no_parser) { + if ((buf->type == BUF_TYPE_VIDEO) + || (has_hevc_vdec() && buf->type == BUF_TYPE_HEVC)) + size -= READ_PARSER_REG(PARSER_VIDEO_HOLE); + } return size > 0 ? size : 0; } @@ -432,11 +433,11 @@ void stbuf_release(struct stream_buf_s *buf) int r; buf->first_tstamp = INVALID_PTS; - - r = stbuf_init(buf, NULL);/* reinit buffer */ - if (r < 0) - pr_err("stbuf_release %d, stbuf_init failed\n", __LINE__); - + if (!buf->ext_buf_addr) { + r = stbuf_init(buf, NULL);/* reinit buffer */ + if (r < 0) + pr_err("stbuf_release %d, stbuf_init failed\n", __LINE__); + } if (buf->flag & BUF_FLAG_ALLOC && buf->buf_start) { codec_mm_free_for_dma(MEM_NAME, buf->buf_start); buf->flag &= ~BUF_FLAG_ALLOC; diff --git a/drivers/stream_input/amports/streambuf.h b/drivers/stream_input/amports/streambuf.h index eb6ff8c..1c14a59 100644 --- a/drivers/stream_input/amports/streambuf.h +++ b/drivers/stream_input/amports/streambuf.h @@ -37,6 +37,10 @@ #define FETCHBUF_SIZE (64*1024) #define USER_DATA_SIZE (8*1024) +/* stream_buffer_metainfo stbuf_flag */ +#define STBUF_META_FLAG_SECURE (1 << 0) +#define STBUF_META_FLAG_XXX1 (1 << 1) + struct vdec_s; struct stream_buf_s; @@ -138,6 +142,29 @@ struct drm_info { u32 extpad[7]; } /*drminfo_t */; +struct stream_buffer_metainfo { + union { + u32 stbuf_start; + u32 stbuf_pktaddr; //stbuf_pktaddr + stbuf_pktsize = wp + }; + union { + u32 stbuf_size; + u32 stbuf_pktsize; + }; + u32 stbuf_flag; + u32 stbuf_private; + u32 reserved[16]; +}; + +struct stream_buffer_status { + u32 stbuf_wp; + u32 stbuf_rp; + u32 stbuf_start; + u32 stbuf_size; + u32 reserved[16]; +}; + + #define TYPE_DRMINFO_V2 0x100 #define TYPE_DRMINFO 0x80 #define TYPE_PATTERN 0x40 diff --git a/firmware/video_ucode.bin b/firmware/video_ucode.bin old mode 100755 new mode 100644 index fb22598..ca48cd6 Binary files a/firmware/video_ucode.bin and b/firmware/video_ucode.bin differ