From 53a66f642c2fcd63394042ac17afb4fafba38207 Mon Sep 17 00:00:00 2001 From: Nanxin Qin Date: Mon, 29 Jan 2018 18:06:33 +0800 Subject: [PATCH] media: adds the feature of the amvdec ports are based on v4l2.[1/2] PD#153299: 1. amports has v4l for video decoding implemented upstream. 2. Only the decoding of h264 has been implemented at the moment. 3. the maximun resolution supports 1080p currently. 4. it is nv12 that the canvas data format of the decoder output. 5. the detailed description can be referred to wiki. wiki: Media/The_V4L2_Amvdec_Ports_Instructions Change-Id: Ie19311e1f44ae53b491500be9903f3d82c83b800 Signed-off-by: Nanxin Qin --- arch/arm64/boot/dts/amlogic/mesong12a.dtsi | 6 ++ arch/arm64/boot/dts/amlogic/mesongxl.dtsi | 6 ++ arch/arm64/boot/dts/amlogic/mesongxm.dtsi | 6 ++ arch/arm64/boot/dts/amlogic/mesontxlx.dtsi | 6 ++ drivers/amlogic/media/common/codec_mm/codec_mm.c | 80 +++++++++++++++++++++++- drivers/amlogic/media/common/v4l_util/Kconfig | 2 + include/linux/amlogic/media/codec_mm/codec_mm.h | 7 +++ include/linux/amlogic/media/utils/amstream.h | 1 + include/linux/amlogic/media/vfm/vframe.h | 4 ++ 9 files changed, 117 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi index 9f8f293..0d752d9 100644 --- a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi @@ -1266,6 +1266,12 @@ "mailbox_2"; }; + vcodec_dec { + compatible = "amlogic, vcodec-dec"; + dev_name = "aml-vcodec-dec"; + status = "okay"; + }; + amvenc_avc{ compatible = "amlogic, amvenc_avc"; dev_name = "amvenc_avc"; diff --git a/arch/arm64/boot/dts/amlogic/mesongxl.dtsi b/arch/arm64/boot/dts/amlogic/mesongxl.dtsi index 509953c..05b0e8d 100644 --- a/arch/arm64/boot/dts/amlogic/mesongxl.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesongxl.dtsi @@ -171,6 +171,12 @@ reserve_mem_size = <0x00300000>; }; + vcodec_dec { + compatible = "amlogic, vcodec-dec"; + dev_name = "aml-vcodec-dec"; + status = "okay"; + }; + securitykey { compatible = "aml, securitykey"; storage_query = <0x82000060>; diff --git a/arch/arm64/boot/dts/amlogic/mesongxm.dtsi b/arch/arm64/boot/dts/amlogic/mesongxm.dtsi index 3158626..3cb75c8 100644 --- a/arch/arm64/boot/dts/amlogic/mesongxm.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesongxm.dtsi @@ -288,6 +288,12 @@ reserve_mem_size = <0x00300000>; }; + vcodec_dec { + compatible = "amlogic, vcodec-dec"; + dev_name = "aml-vcodec-dec"; + status = "okay"; + }; + securitykey { compatible = "aml, securitykey"; storage_query = <0x82000060>; diff --git a/arch/arm64/boot/dts/amlogic/mesontxlx.dtsi b/arch/arm64/boot/dts/amlogic/mesontxlx.dtsi index 0d6a78c..f56dc75 100644 --- a/arch/arm64/boot/dts/amlogic/mesontxlx.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesontxlx.dtsi @@ -172,6 +172,12 @@ reserve_mem_size = <0x00300000>; }; + vcodec_dec { + compatible = "amlogic, vcodec-dec"; + dev_name = "aml-vcodec-dec"; + status = "okay"; + }; + securitykey { compatible = "aml, securitykey"; status = "okay"; diff --git a/drivers/amlogic/media/common/codec_mm/codec_mm.c b/drivers/amlogic/media/common/codec_mm/codec_mm.c index e6665d3..5646d85 100644 --- a/drivers/amlogic/media/common/codec_mm/codec_mm.c +++ b/drivers/amlogic/media/common/codec_mm/codec_mm.c @@ -137,6 +137,7 @@ struct codec_mm_mgt_s { int alloced_sys_size; int alloced_for_sc_size; int alloced_for_sc_cnt; + int alloced_from_coherent; int alloc_from_sys_pages_max; int enable_kmalloc_on_nomem; @@ -1352,6 +1353,83 @@ int codec_mm_get_reserved_size(void) } EXPORT_SYMBOL(codec_mm_get_reserved_size); +struct device *v4l_get_dev_from_codec_mm(void) +{ + struct codec_mm_mgt_s *mgt = get_mem_mgt(); + + return mgt->dev; +} +EXPORT_SYMBOL(v4l_get_dev_from_codec_mm); + +struct codec_mm_s *v4l_reqbufs_from_codec_mm(const char *owner, + unsigned int addr, unsigned int size, unsigned int index) +{ + unsigned long flags; + struct codec_mm_mgt_s *mgt = get_mem_mgt(); + struct codec_mm_s *mem = NULL; + int buf_size = PAGE_ALIGN(size); + + mem = kzalloc(sizeof(struct codec_mm_s), GFP_KERNEL); + if (IS_ERR_OR_NULL(mem)) + goto out; + + mem->owner[0] = owner; + mem->mem_handle = NULL; + mem->buffer_size = buf_size; + mem->page_count = buf_size / PAGE_SIZE; + mem->phy_addr = addr; + mem->ins_buffer_id = index; + mem->alloced_jiffies = get_jiffies_64(); + mem->from_flags + = AMPORTS_MEM_FLAGS_FROM_GET_FROM_COHERENT; + + spin_lock_irqsave(&mgt->lock, flags); + + mem->mem_id = mgt->global_memid++; + mgt->alloced_from_coherent += buf_size; + mgt->total_alloced_size += buf_size; + mgt->alloced_cma_size += buf_size; + list_add_tail(&mem->list, &mgt->mem_list); + + spin_unlock_irqrestore(&mgt->lock, flags); + + if (debug_mode & 0x20) + pr_info("%s alloc coherent size %d at %lx from %d.\n", + owner, buf_size, mem->phy_addr, mem->from_flags); +out: + return mem; +} +EXPORT_SYMBOL(v4l_reqbufs_from_codec_mm); + +void v4l_freebufs_back_to_codec_mm(const char *owner, struct codec_mm_s *mem) +{ + unsigned long flags; + struct codec_mm_mgt_s *mgt = get_mem_mgt(); + + if (IS_ERR_OR_NULL(mem)) + return; + + if (!mem->owner[0] || strcmp(owner, mem->owner[0]) || + !mem->buffer_size) + goto out; + + spin_lock_irqsave(&mgt->lock, flags); + + mgt->alloced_from_coherent -= mem->buffer_size; + mgt->total_alloced_size -= mem->buffer_size; + mgt->alloced_cma_size -= mem->buffer_size; + list_del(&mem->list); + + spin_unlock_irqrestore(&mgt->lock, flags); + + if (debug_mode & 0x20) + pr_info("%s free mem size %d at %lx from %d\n", mem->owner[0], + mem->buffer_size, mem->phy_addr, mem->from_flags); +out: + kfree(mem); +} +EXPORT_SYMBOL(v4l_freebufs_back_to_codec_mm); + /* *with_wait: *1: if no mem, do wait and free some cache. @@ -1916,7 +1994,7 @@ static int codec_mm_probe(struct platform_device *pdev) if (r == 0) pr_debug("codec_mm reserved memory probed done\n"); - pr_debug("codec_mm_probe ok\n"); + pr_info("codec_mm_probe ok\n"); codec_mm_scatter_mgt_init(); codec_mm_keeper_mgr_init(); diff --git a/drivers/amlogic/media/common/v4l_util/Kconfig b/drivers/amlogic/media/common/v4l_util/Kconfig index 69324b3..5511b62 100644 --- a/drivers/amlogic/media/common/v4l_util/Kconfig +++ b/drivers/amlogic/media/common/v4l_util/Kconfig @@ -4,6 +4,8 @@ config AMLOGIC_VIDEOBUF_RESOURCE bool "Amlogic V4L UTIL Support" + select VIDEOBUF2_DMA_CONTIG + select V4L2_MEM2MEM_DEV default n help Select to enable V4L UTIL support diff --git a/include/linux/amlogic/media/codec_mm/codec_mm.h b/include/linux/amlogic/media/codec_mm/codec_mm.h index 5de94ec..8f71042 100644 --- a/include/linux/amlogic/media/codec_mm/codec_mm.h +++ b/include/linux/amlogic/media/codec_mm/codec_mm.h @@ -96,6 +96,7 @@ struct codec_mm_s { #define AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA 4 #define AMPORTS_MEM_FLAGS_FROM_GET_FROM_TVP 5 #define AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA_RES 6 +#define AMPORTS_MEM_FLAGS_FROM_GET_FROM_COHERENT 7 int from_flags; /*may can be shared on many user..*/ /*decoder/di/ppmgr,*/ @@ -148,4 +149,10 @@ void *codec_mm_dma_alloc_coherent(const char *owner, int size, dma_addr_t *dma_handle, gfp_t flag, int memflags); void codec_mm_dma_free_coherent(const char *owner, int size, void *cpu_addr, dma_addr_t dma_handle, int memflags); + +struct device *v4l_get_dev_from_codec_mm(void); +struct codec_mm_s *v4l_reqbufs_from_codec_mm(const char *owner, + unsigned int addr, unsigned int size, unsigned int index); +void v4l_freebufs_back_to_codec_mm(const char *owner, struct codec_mm_s *mem); + #endif diff --git a/include/linux/amlogic/media/utils/amstream.h b/include/linux/amlogic/media/utils/amstream.h index f40bdff..34e650b 100644 --- a/include/linux/amlogic/media/utils/amstream.h +++ b/include/linux/amlogic/media/utils/amstream.h @@ -230,6 +230,7 @@ enum FRAME_BASE_VIDEO_PATH { FRAME_BASE_PATH_DI_AMVIDEO, FRAME_BASE_PATH_AMVIDEO, FRAME_BASE_PATH_AMVIDEO2, + FRAME_BASE_PATH_V4L_VIDEO, FRAME_BASE_PATH_MAX }; diff --git a/include/linux/amlogic/media/vfm/vframe.h b/include/linux/amlogic/media/vfm/vframe.h index 9e53f1e48..8403e1a 100644 --- a/include/linux/amlogic/media/vfm/vframe.h +++ b/include/linux/amlogic/media/vfm/vframe.h @@ -75,6 +75,7 @@ #define VFRAME_FLAG_ERROR_RECOVERY 8 #define VFRAME_FLAG_SYNCFRAME 0x10 #define VFRAME_FLAG_GAME_MODE 0x20 +#define VFRAME_FLAG_EMPTY_FRAME_V4L 0x80 enum pixel_aspect_ratio_e { PIXEL_ASPECT_RATIO_1_1, @@ -256,6 +257,7 @@ struct vframe_s { u32 next_vf_pts; u32 disp_pts; u64 disp_pts_us64; + u64 timestamp; u32 flag; u32 canvas0Addr; @@ -346,6 +348,8 @@ struct vframe_s { /*for MMU H265/VP9 compress header*/ void *mem_head_handle; struct vframe_pic_mode_s pic_mode; + + unsigned long v4l_mem_handle; } /*vframe_t */; #if 0 -- 2.7.4