From 874fe722a972e908e4ed6b23ce86e7ae90301951 Mon Sep 17 00:00:00 2001 From: Evoke Zhang Date: Sat, 20 Apr 2019 19:19:46 +0800 Subject: [PATCH] vdin: support afbc/non-afbc switch dynamically [1/1] PD#SWPL-7512 Problem: need switch vdin afbc/non-afbc mode sometime Solution: support afbc/non-afbc switch dynamically Verify: x301 Change-Id: I08433938f169a51ed1ed7a23fd99f3ba42e076fe Signed-off-by: Evoke Zhang --- arch/arm/boot/dts/amlogic/tl1_t962x2_x301_1g.dts | 17 +- arch/arm/boot/dts/amlogic/tl1_t962x2_x301_2g.dts | 17 +- arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_1g.dts | 17 +- arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_2g.dts | 17 +- drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c | 462 +++------------ drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h | 7 +- drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.c | 206 ++++++- drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c | 30 +- drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c | 84 ++- drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c | 654 ++++++--------------- drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h | 34 +- drivers/amlogic/media/vin/tvin/vdin/vdin_vf.c | 3 +- include/linux/amlogic/media/vfm/vframe.h | 6 +- include/linux/amlogic/media/vfm/vframe_provider.h | 1 + 14 files changed, 623 insertions(+), 932 deletions(-) diff --git a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301_1g.dts b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301_1g.dts index 1e66516..18ac07e 100644 --- a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301_1g.dts +++ b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301_1g.dts @@ -523,7 +523,7 @@ *if support 4K2K-YUV422-8BIT-WR:3840*2160*2*4 ~= 64M *if support 1080p-YUV422-8BIT-WR:1920*1080*2*4 ~= 16M */ - cma_size = <160>; + cma_size = <180>; interrupts = <0 83 1>; rdma-irq = <2>; clocks = <&clkc CLKID_FCLK_DIV5>, @@ -541,15 +541,14 @@ */ tv_bit_mode = <0x215>; /* afbce_bit_mode: (amlogic frame buff compression encoder) - * bit 0~3: - * 0 -- normal mode, not use afbce - * 1 -- use afbce non-mmu mode - * 2 -- use afbce mmu mode - * bit 4: - * 0 -- afbce compression-lossy disable - * 1 -- afbce compression-lossy enable + * bit0 -- enable afbce + * bit1 -- enable afbce compression-lossy + * bit4 -- afbce for 4k + * bit5 -- afbce for 1080p + * bit6 -- afbce for 720p + * bit7 -- afbce for smaller resolution */ - afbce_bit_mode = <0x1>; + afbce_bit_mode = <0x11>; }; vdin@1 { diff --git a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301_2g.dts b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301_2g.dts index 45e143b..bef9f9f 100644 --- a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301_2g.dts +++ b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301_2g.dts @@ -518,7 +518,7 @@ *if support 4K2K-YUV422-8BIT-WR:3840*2160*2*4 ~= 64M *if support 1080p-YUV422-8BIT-WR:1920*1080*2*4 ~= 16M */ - cma_size = <160>; + cma_size = <180>; interrupts = <0 83 1>; rdma-irq = <2>; clocks = <&clkc CLKID_FCLK_DIV5>, @@ -536,15 +536,14 @@ */ tv_bit_mode = <0x215>; /* afbce_bit_mode: (amlogic frame buff compression encoder) - * bit 0~3: - * 0 -- normal mode, not use afbce - * 1 -- use afbce non-mmu mode - * 2 -- use afbce mmu mode - * bit 4: - * 0 -- afbce compression-lossy disable - * 1 -- afbce compression-lossy enable + * bit0 -- enable afbce + * bit1 -- enable afbce compression-lossy + * bit4 -- afbce for 4k + * bit5 -- afbce for 1080p + * bit6 -- afbce for 720p + * bit7 -- afbce for smaller resolution */ - afbce_bit_mode = <0x1>; + afbce_bit_mode = <0x11>; }; vdin@1 { diff --git a/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_1g.dts b/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_1g.dts index 95e41d0..335a3f3 100644 --- a/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_1g.dts +++ b/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_1g.dts @@ -519,7 +519,7 @@ *if support 4K2K-YUV422-8BIT-WR:3840*2160*2*4 ~= 64M *if support 1080p-YUV422-8BIT-WR:1920*1080*2*4 ~= 16M */ - cma_size = <160>; + cma_size = <180>; interrupts = <0 83 1>; rdma-irq = <2>; clocks = <&clkc CLKID_FCLK_DIV5>, @@ -537,15 +537,14 @@ */ tv_bit_mode = <0x215>; /* afbce_bit_mode: (amlogic frame buff compression encoder) - * bit 0~3: - * 0 -- normal mode, not use afbce - * 1 -- use afbce non-mmu mode - * 2 -- use afbce mmu mode - * bit 4: - * 0 -- afbce compression-lossy disable - * 1 -- afbce compression-lossy enable + * bit0 -- enable afbce + * bit1 -- enable afbce compression-lossy + * bit4 -- afbce for 4k + * bit5 -- afbce for 1080p + * bit6 -- afbce for 720p + * bit7 -- afbce for smaller resolution */ - afbce_bit_mode = <0x1>; + afbce_bit_mode = <0x11>; }; vdin@1 { diff --git a/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_2g.dts b/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_2g.dts index 05788b9..e2f6af2 100644 --- a/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_2g.dts +++ b/arch/arm64/boot/dts/amlogic/tl1_t962x2_x301_2g.dts @@ -513,7 +513,7 @@ *if support 4K2K-YUV422-8BIT-WR:3840*2160*2*4 ~= 64M *if support 1080p-YUV422-8BIT-WR:1920*1080*2*4 ~= 16M */ - cma_size = <160>; + cma_size = <180>; interrupts = <0 83 1>; rdma-irq = <2>; clocks = <&clkc CLKID_FCLK_DIV5>, @@ -531,15 +531,14 @@ */ tv_bit_mode = <0x215>; /* afbce_bit_mode: (amlogic frame buff compression encoder) - * bit 0~3: - * 0 -- normal mode, not use afbce - * 1 -- use afbce non-mmu mode - * 2 -- use afbce mmu mode - * bit 4: - * 0 -- afbce compression-lossy disable - * 1 -- afbce compression-lossy enable + * bit0 -- enable afbce + * bit1 -- enable afbce compression-lossy + * bit4 -- afbce for 4k + * bit5 -- afbce for 1080p + * bit6 -- afbce for 720p + * bit7 -- afbce for smaller resolution */ - afbce_bit_mode = <0x1>; + afbce_bit_mode = <0x11>; }; vdin@1 { diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c index 14dd11f3..1c5c003 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c @@ -57,323 +57,46 @@ #include "vdin_canvas.h" #include "vdin_afbce.h" -static unsigned int max_buf_num = VDIN_CANVAS_MAX_CNT; -static unsigned int min_buf_num = 4; -static unsigned int max_buf_width = VDIN_CANVAS_MAX_WIDTH_HD; -static unsigned int max_buf_height = VDIN_CANVAS_MAX_HEIGH; -/* one frame max metadata size:32x280 bits = 1120bytes(0x460) */ -unsigned int dolby_size_bytes = PAGE_SIZE; - -unsigned int vdin_afbce_cma_alloc(struct vdin_dev_s *devp) +/* fixed config mif by default */ +void vdin_mif_config_init(struct vdin_dev_s *devp) { - char vdin_name[6]; - unsigned int mem_size, h_size, v_size; - int flags = CODEC_MM_FLAGS_CMA_FIRST|CODEC_MM_FLAGS_CMA_CLEAR| - CODEC_MM_FLAGS_DMA; - unsigned int max_buffer_num = min_buf_num; - unsigned int i; - /*head_size:3840*2160*3*9/32*/ - unsigned int afbce_head_size_byte = PAGE_SIZE * 1712; - /*afbce map_table need 218700 byte at most*/ - unsigned int afbce_table_size_byte = PAGE_SIZE * 60;/*0.3M*/ - unsigned int afbce_mem_used; - unsigned int frame_head_size; - unsigned int mmu_used; - unsigned long body_start_paddr; - - if (devp->rdma_enable) - max_buffer_num++; - /*todo: need update if vf_skip_cnt used by other port*/ - if (devp->vfp->skip_vf_num && - (((devp->parm.port >= TVIN_PORT_HDMI0) && - (devp->parm.port <= TVIN_PORT_HDMI7)) || - ((devp->parm.port >= TVIN_PORT_CVBS0) && - (devp->parm.port <= TVIN_PORT_CVBS3)))) - max_buffer_num += devp->vfp->skip_vf_num; - if (max_buffer_num > max_buf_num) - max_buffer_num = max_buf_num; - devp->vfmem_max_cnt = max_buffer_num; - devp->canvas_max_num = max_buffer_num; - - if ((devp->cma_config_en == 0) || - (devp->cma_mem_alloc == 1)) { - pr_info("\nvdin%d %s use_reserved mem or cma already alloced (%d,%d)!!!\n", - devp->index, __func__, devp->cma_config_en, - devp->cma_mem_alloc); - return 0; - } - h_size = devp->h_active; - v_size = devp->v_active; - if (devp->canvas_config_mode == 1) { - h_size = max_buf_width; - v_size = max_buf_height; - } - if ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV444) || - (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_RGB) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_RGB) || - (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_GBR) || - (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_BRG) || - (devp->force_yuv444_malloc == 1)) { - if ((devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) && - (devp->color_depth_mode != 1)) { - h_size = roundup(h_size * - VDIN_YUV444_10BIT_PER_PIXEL_BYTE, - devp->canvas_align); - devp->canvas_alin_w = h_size / - VDIN_YUV444_10BIT_PER_PIXEL_BYTE; - } else { - h_size = roundup(h_size * - VDIN_YUV444_8BIT_PER_PIXEL_BYTE, - devp->canvas_align); - devp->canvas_alin_w = h_size / - VDIN_YUV444_8BIT_PER_PIXEL_BYTE; - } - } else if ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_NV12) || - (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_NV21) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_NV12) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_NV21)) { - h_size = roundup(h_size, devp->canvas_align); - devp->canvas_alin_w = h_size; - /*todo change with canvas alloc!!*/ - /* nv21/nv12 only have 8bit mode */ + if (devp->index == 0) { + W_VCBUS_BIT(VDIN_MISC_CTRL, + 1, VDIN0_MIF_ENABLE_BIT, 1); + W_VCBUS_BIT(VDIN_MISC_CTRL, + 0, VDIN0_OUT_AFBCE_BIT, 1); + W_VCBUS_BIT(VDIN_MISC_CTRL, + 1, VDIN0_OUT_MIF_BIT, 1); } else { - /* txl new add mode yuv422 pack mode:canvas-w=h*2*10/8 - *canvas_w must ensure divided exact by 256bit(32byte - */ - if ((devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) && - ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) || - (devp->format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) || - (devp->format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422)) && - (devp->color_depth_mode == 1)) { - h_size = roundup((h_size * 5)/2, devp->canvas_align); - devp->canvas_alin_w = (h_size * 2) / 5; - } else if ((devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) && - (devp->color_depth_mode == 0)) { - h_size = roundup(h_size * - VDIN_YUV422_10BIT_PER_PIXEL_BYTE, - devp->canvas_align); - devp->canvas_alin_w = h_size / - VDIN_YUV422_10BIT_PER_PIXEL_BYTE; - } else { - h_size = roundup(h_size * - VDIN_YUV422_8BIT_PER_PIXEL_BYTE, - devp->canvas_align); - devp->canvas_alin_w = h_size / - VDIN_YUV422_8BIT_PER_PIXEL_BYTE; - } - } - mem_size = h_size * v_size; - if ((devp->format_convert >= VDIN_FORMAT_CONVERT_YUV_NV12) && - (devp->format_convert <= VDIN_FORMAT_CONVERT_RGB_NV21)) - mem_size = (mem_size * 3)/2; - devp->vfmem_size = PAGE_ALIGN(mem_size) + dolby_size_bytes; - devp->vfmem_size = (devp->vfmem_size/PAGE_SIZE + 1)*PAGE_SIZE; - - mem_size = PAGE_ALIGN(mem_size) * max_buffer_num + - dolby_size_bytes * max_buffer_num; - mem_size = (mem_size/PAGE_SIZE + 1)*PAGE_SIZE; - if (mem_size > devp->cma_mem_size) - mem_size = devp->cma_mem_size; - if (devp->index == 0) - strcpy(vdin_name, "vdin0"); - else if (devp->index == 1) - strcpy(vdin_name, "vdin1"); - - - if (devp->cma_config_flag == 0x101) { - devp->afbce_info->head_paddr = codec_mm_alloc_for_dma( - vdin_name, afbce_head_size_byte/PAGE_SIZE, 0, flags); - devp->afbce_info->table_paddr = codec_mm_alloc_for_dma( - vdin_name, afbce_table_size_byte/PAGE_SIZE, 0, flags); - devp->afbce_info->head_size = afbce_head_size_byte; - devp->afbce_info->table_size = afbce_table_size_byte; - devp->afbce_info->frame_body_size = devp->vfmem_size; - - pr_info("vdin%d head_start = 0x%lx, head_size = 0x%x\n", - devp->index, devp->afbce_info->head_paddr, - devp->afbce_info->head_size); - pr_info("vdin%d table_start = 0x%lx, table_size = 0x%x\n", - devp->index, devp->afbce_info->table_paddr, - devp->afbce_info->table_size); - - /* set fm_body_paddr */ - for (i = 0; i < max_buffer_num; i++) { - devp->afbce_info->fm_body_paddr[i] = - codec_mm_alloc_for_dma(vdin_name, - devp->vfmem_size/PAGE_SIZE, 0, flags); - if (devp->afbce_info->fm_body_paddr[i] == 0) { - pr_err("\nvdin%d-afbce buf[%d]codec alloc fail!!!\n", - devp->index, i); - devp->cma_mem_alloc = 0; - } else { - devp->cma_mem_alloc = 1; - pr_info("vdin%d fm_body_paddr[%d] = 0x%lx, body_size = 0x%x\n", - devp->index, i, - devp->afbce_info->fm_body_paddr[i], - devp->afbce_info->frame_body_size); - } - - if (devp->cma_mem_alloc == 0) - return 1; - } - pr_info("vdin%d-afbce codec cma alloc ok!\n", devp->index); - devp->mem_size = mem_size; - } else if (devp->cma_config_flag == 0) { - devp->venc_pages = dma_alloc_from_contiguous( - &(devp->this_pdev->dev), - devp->cma_mem_size >> PAGE_SHIFT, 0); - if (devp->venc_pages) { - devp->mem_start = - page_to_phys(devp->venc_pages); - devp->mem_size = mem_size; - devp->cma_mem_alloc = 1; - - devp->afbce_info->head_paddr = devp->mem_start; - devp->afbce_info->head_size = 2*SZ_1M;/*2M*/ - devp->afbce_info->table_paddr = - devp->mem_start + devp->afbce_info->head_paddr; - devp->afbce_info->table_size = 2*SZ_1M;/*2M*/ - devp->afbce_info->frame_body_size = devp->vfmem_size; - - body_start_paddr = devp->afbce_info->table_paddr + - devp->afbce_info->table_size; - - pr_info("vdin%d head_start = 0x%lx, head_size = 0x%x\n", - devp->index, devp->afbce_info->head_paddr, - devp->afbce_info->head_size); - pr_info("vdin%d table_start = 0x%lx, table_size = 0x%x\n", - devp->index, devp->afbce_info->table_paddr, - devp->afbce_info->table_size); - - /* set fm_body_paddr */ - for (i = 0; i < max_buffer_num; i++) { - devp->afbce_info->fm_body_paddr[i] = - body_start_paddr + (devp->vfmem_size * i); - - pr_info("vdin%d body[%d]_start = 0x%lx, body_size = 0x%x\n", - devp->index, i, - devp->afbce_info->fm_body_paddr[i], - devp->afbce_info->frame_body_size); - } - - /*check memory over the boundary*/ - afbce_mem_used = - devp->afbce_info->fm_body_paddr[max_buffer_num] - + devp->afbce_info->frame_body_size - - devp->afbce_info->head_paddr; - if (afbce_mem_used > devp->cma_mem_size) { - pr_info("afbce mem: afbce_mem_used(%d) > cma_mem_size(%d)\n", - afbce_mem_used, devp->cma_mem_size); - return 1; - } - devp->cma_mem_alloc = 1; - pr_info("vdin%d cma alloc ok!\n", devp->index); - } else { - devp->cma_mem_alloc = 0; - pr_err("\nvdin%d-afbce cma mem undefined2.\n", - devp->index); - return 1; - } - } - - /* 1 block = 32 * 4 pixle = 128 pixel */ - /* there is a header in one block, a header has 4 bytes */ - /* set fm_head_paddr start */ - frame_head_size = (int)roundup(devp->vfmem_size, 128); - /*h_active * v_active / 128 * 4 = frame_head_size*/ - frame_head_size = PAGE_ALIGN(frame_head_size / 32); - - devp->afbce_info->frame_head_size = frame_head_size; - - for (i = 0; i < max_buffer_num; i++) { - devp->afbce_info->fm_head_paddr[i] = - devp->afbce_info->head_paddr + (frame_head_size*i); - - pr_info("vdin%d fm_head_paddr[%d] = 0x%lx, frame_head_size = 0x%x\n", - devp->index, i, - devp->afbce_info->fm_head_paddr[i], - frame_head_size); + W_VCBUS_BIT(VDIN_MISC_CTRL, + 1, VDIN1_MIF_ENABLE_BIT, 1); + W_VCBUS_BIT(VDIN_MISC_CTRL, + 0, VDIN1_OUT_AFBCE_BIT, 1); + W_VCBUS_BIT(VDIN_MISC_CTRL, + 1, VDIN1_OUT_MIF_BIT, 1); } - /* set fm_head_paddr end */ - - /* set fm_table_paddr start */ - mmu_used = devp->afbce_info->frame_body_size >> 12; - mmu_used = mmu_used * 4; - mmu_used = PAGE_ALIGN(mmu_used); - devp->afbce_info->frame_table_size = mmu_used; - - for (i = 0; i < max_buffer_num; i++) { - devp->afbce_info->fm_table_paddr[i] = - devp->afbce_info->table_paddr + (mmu_used*i); - - pr_info("vdin%d fm_table_paddr[%d]=0x%lx, frame_table_size = 0x%x\n", - devp->index, i, - devp->afbce_info->fm_table_paddr[i], - devp->afbce_info->frame_table_size); - } - /* set fm_table_paddr end */ - - return 0; } -void vdin_afbce_cma_release(struct vdin_dev_s *devp) +/* only support init vdin0 mif/afbce */ +void vdin_write_mif_or_afbce_init(struct vdin_dev_s *devp) { - char vdin_name[6]; - unsigned int i; - - if ((devp->cma_config_en == 0) || - (devp->cma_mem_alloc == 0)) { - pr_err("\nvdin%d %s fail for (%d,%d)!!!\n", - devp->index, __func__, devp->cma_config_en, - devp->cma_mem_alloc); - return; - } - if (devp->index == 0) - strcpy(vdin_name, "vdin0"); - else if (devp->index == 1) - strcpy(vdin_name, "vdin1"); - - if (devp->cma_config_flag == 0x101) { - codec_mm_free_for_dma(vdin_name, devp->afbce_info->head_paddr); - codec_mm_free_for_dma(vdin_name, devp->afbce_info->table_paddr); - for (i = 0; i < devp->vfmem_max_cnt; i++) - codec_mm_free_for_dma(vdin_name, - devp->afbce_info->fm_body_paddr[i]); - pr_info("vdin%d-afbce codec cma release ok!\n", devp->index); - } else if (devp->venc_pages - && devp->cma_mem_size - && (devp->cma_config_flag == 0)) { - dma_release_from_contiguous( - &(devp->this_pdev->dev), - devp->venc_pages, - devp->cma_mem_size >> PAGE_SHIFT); - pr_info("vdin%d-afbce cma release ok!\n", devp->index); - } else { - pr_err("\nvdin%d %s fail for (%d,0x%x,0x%lx)!!!\n", - devp->index, __func__, devp->cma_mem_size, - devp->cma_config_flag, devp->mem_start); - } - devp->mem_start = 0; - devp->mem_size = 0; - devp->cma_mem_alloc = 0; -} + enum vdin_output_mif_e sel; -/*can not use RDMA, because vdin0/1 both use the register */ -void vdin_write_mif_or_afbce(struct vdin_dev_s *devp, - enum vdin_output_mif_e sel) -{ - unsigned int offset = devp->addr_offset; + if (devp->afbce_mode == 0) + sel = VDIN_OUTPUT_TO_MIF; + else + sel = VDIN_OUTPUT_TO_AFBCE; - if (offset == 0) { + if (devp->index == 0) { if (sel == VDIN_OUTPUT_TO_MIF) { + vdin_afbce_hw_disable(); + W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_MIF_ENABLE_BIT, 1); W_VCBUS_BIT(VDIN_MISC_CTRL, - 1, VDIN0_OUT_MIF_BIT, 1); - W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN0_OUT_AFBCE_BIT, 1); + W_VCBUS_BIT(VDIN_MISC_CTRL, + 1, VDIN0_OUT_MIF_BIT, 1); } else if (sel == VDIN_OUTPUT_TO_AFBCE) { W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_MIF_ENABLE_BIT, 1); @@ -381,26 +104,32 @@ void vdin_write_mif_or_afbce(struct vdin_dev_s *devp, 0, VDIN0_OUT_MIF_BIT, 1); W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_OUT_AFBCE_BIT, 1); + + vdin_afbce_hw_enable(); } - } else { - if (sel == VDIN_OUTPUT_TO_MIF) { - W_VCBUS_BIT(VDIN_MISC_CTRL, - 1, VDIN1_MIF_ENABLE_BIT, 1); - W_VCBUS_BIT(VDIN_MISC_CTRL, - 1, VDIN1_OUT_MIF_BIT, 1); - W_VCBUS_BIT(VDIN_MISC_CTRL, - 0, VDIN1_OUT_AFBCE_BIT, 1); - } else if (sel == VDIN_OUTPUT_TO_AFBCE) { - /*sel vdin1 afbce: not support in sw now, - *just reserved interface - */ - W_VCBUS_BIT(VDIN_MISC_CTRL, - 1, VDIN1_MIF_ENABLE_BIT, 1); - W_VCBUS_BIT(VDIN_MISC_CTRL, - 0, VDIN1_OUT_MIF_BIT, 1); - W_VCBUS_BIT(VDIN_MISC_CTRL, - 1, VDIN1_OUT_AFBCE_BIT, 1); - } + } +} + +/* only support config vdin0 mif/afbce dynamically */ +void vdin_write_mif_or_afbce(struct vdin_dev_s *devp, + enum vdin_output_mif_e sel) +{ + + if (devp->index != 0) + return; + + if (sel == VDIN_OUTPUT_TO_MIF) { + rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 0, 8, 1); + rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + 0, VDIN0_OUT_AFBCE_BIT, 1); + rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + 1, VDIN0_OUT_MIF_BIT, 1); + } else if (sel == VDIN_OUTPUT_TO_AFBCE) { + rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + 0, VDIN0_OUT_MIF_BIT, 1); + rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + 1, VDIN0_OUT_AFBCE_BIT, 1); + rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 1, 8, 1); } } /* @@ -419,10 +148,8 @@ void vdin_afbce_update(struct vdin_dev_s *devp) int uncmp_bits; int uncmp_size; - if (devp->index != 0) { - pr_info("cat not use afbce on vdin1 at the moment\n"); + if (!devp->afbce_info) return; - } #ifndef CONFIG_AMLOGIC_MEDIA_RDMA pr_info("##############################################\n"); @@ -477,7 +204,6 @@ void vdin_afbce_update(struct vdin_dev_s *devp) void vdin_afbce_config(struct vdin_dev_s *devp) { - unsigned int offset = devp->addr_offset; int hold_line_num = VDIN_AFBCE_HOLD_LINE_NUM; int lbuf_depth = 256; int lossy_luma_en = 0; @@ -503,10 +229,8 @@ void vdin_afbce_config(struct vdin_dev_s *devp) int enc_win_bgn_v;//input scope int enc_win_end_v;//input scope - if (offset != 0) { - pr_info("cat not use afbce on vdin1 at the moment\n"); + if (!devp->afbce_info) return; - } #ifndef CONFIG_AMLOGIC_MEDIA_RDMA pr_info("##############################################\n"); @@ -549,94 +273,83 @@ void vdin_afbce_config(struct vdin_dev_s *devp) //bit size of uncompression mode uncmp_size = (((((16*uncmp_bits*sblk_num)+7)>>3)+31)/32)<<1; - rdma_write_reg_bits(devp->rdma_handle, - VDIN_WRARB_REQEN_SLV, 0x1, 3, 1);//vpu arb axi_enable - rdma_write_reg_bits(devp->rdma_handle, - VDIN_WRARB_REQEN_SLV, 0x1, 7, 1);//vpu arb axi_enable + W_VCBUS_BIT(VDIN_WRARB_REQEN_SLV, 0x1, 3, 1);//vpu arb axi_enable + W_VCBUS_BIT(VDIN_WRARB_REQEN_SLV, 0x1, 7, 1);//vpu arb axi_enable - rdma_write_reg(devp->rdma_handle, AFBCE_MODE, + W_VCBUS(AFBCE_MODE, (0 & 0x7) << 29 | (0 & 0x3) << 26 | (3 & 0x3) << 24 | (hold_line_num & 0x7f) << 16 | (2 & 0x3) << 14 | (reg_fmt444_comb & 0x1)); - rdma_write_reg_bits(devp->rdma_handle, - AFBCE_QUANT_ENABLE, (lossy_luma_en & 0x1), 0, 1);//loosy - rdma_write_reg_bits(devp->rdma_handle, - AFBCE_QUANT_ENABLE, (lossy_chrm_en & 0x1), 4, 1);//loosy + W_VCBUS_BIT(AFBCE_QUANT_ENABLE, (lossy_luma_en & 0x1), 0, 1);//loosy + W_VCBUS_BIT(AFBCE_QUANT_ENABLE, (lossy_chrm_en & 0x1), 4, 1);//loosy - if (devp->afbce_lossy_en == 1) { - rdma_write_reg(devp->rdma_handle, - AFBCE_QUANT_ENABLE, 0xc11); + if (devp->afbce_flag & VDIN_AFBCE_EN_LOOSY) { + W_VCBUS(AFBCE_QUANT_ENABLE, 0xc11); pr_info("afbce use lossy compression mode\n"); } - rdma_write_reg(devp->rdma_handle, AFBCE_SIZE_IN, + W_VCBUS(AFBCE_SIZE_IN, ((devp->h_active & 0x1fff) << 16) | // hsize_in of afbc input ((devp->v_active & 0x1fff) << 0) // vsize_in of afbc input ); - rdma_write_reg(devp->rdma_handle, AFBCE_BLK_SIZE_IN, + W_VCBUS(AFBCE_BLK_SIZE_IN, ((hblksize_out & 0x1fff) << 16) | // out blk hsize ((vblksize_out & 0x1fff) << 0) // out blk vsize ); //head addr of compressed data - rdma_write_reg(devp->rdma_handle, AFBCE_HEAD_BADDR, + W_VCBUS(AFBCE_HEAD_BADDR, devp->afbce_info->fm_head_paddr[0]); - rdma_write_reg_bits(devp->rdma_handle, - AFBCE_MIF_SIZE, (uncmp_size & 0x1fff), 16, 5);//uncmp_size + W_VCBUS_BIT(AFBCE_MIF_SIZE, (uncmp_size & 0x1fff), 16, 5);//uncmp_size /* how to set reg when we use crop ? */ // scope of hsize_in ,should be a integer multipe of 32 // scope of vsize_in ,should be a integer multipe of 4 - rdma_write_reg(devp->rdma_handle, AFBCE_PIXEL_IN_HOR_SCOPE, + W_VCBUS(AFBCE_PIXEL_IN_HOR_SCOPE, ((enc_win_end_h & 0x1fff) << 16) | ((enc_win_bgn_h & 0x1fff) << 0)); // scope of hsize_in ,should be a integer multipe of 32 // scope of vsize_in ,should be a integer multipe of 4 - rdma_write_reg(devp->rdma_handle, AFBCE_PIXEL_IN_VER_SCOPE, + W_VCBUS(AFBCE_PIXEL_IN_VER_SCOPE, ((enc_win_end_v & 0x1fff) << 16) | ((enc_win_bgn_v & 0x1fff) << 0)); - rdma_write_reg(devp->rdma_handle, - AFBCE_CONV_CTRL, lbuf_depth);//fix 256 + W_VCBUS(AFBCE_CONV_CTRL, lbuf_depth);//fix 256 - rdma_write_reg(devp->rdma_handle, AFBCE_MIF_HOR_SCOPE, + W_VCBUS(AFBCE_MIF_HOR_SCOPE, ((blk_out_bgn_h & 0x3ff) << 16) | // scope of out blk hsize ((blk_out_end_h & 0xfff) << 0) // scope of out blk vsize ); - rdma_write_reg(devp->rdma_handle, AFBCE_MIF_VER_SCOPE, + W_VCBUS(AFBCE_MIF_VER_SCOPE, ((blk_out_bgn_v & 0x3ff) << 16) | // scope of out blk hsize ((blk_out_end_v & 0xfff) << 0) // scope of out blk vsize ); - rdma_write_reg(devp->rdma_handle, AFBCE_FORMAT, + W_VCBUS(AFBCE_FORMAT, (reg_format_mode & 0x3) << 8 | (uncmp_bits & 0xf) << 4 | (uncmp_bits & 0xf)); - rdma_write_reg(devp->rdma_handle, AFBCE_DEFCOLOR_1, + W_VCBUS(AFBCE_DEFCOLOR_1, ((def_color_3 & 0xfff) << 12) | // def_color_a ((def_color_0 & 0xfff) << 0) // def_color_y ); - rdma_write_reg(devp->rdma_handle, AFBCE_DEFCOLOR_2, + W_VCBUS(AFBCE_DEFCOLOR_2, ((def_color_2 & 0xfff) << 12) | // def_color_v ((def_color_1 & 0xfff) << 0) // def_color_u ); - rdma_write_reg_bits(devp->rdma_handle, - AFBCE_MMU_RMIF_CTRL4, devp->afbce_info->table_paddr, 0, 32); - rdma_write_reg_bits(devp->rdma_handle, - AFBCE_MMU_RMIF_SCOPE_X, cur_mmu_used, 0, 12); + W_VCBUS_BIT(AFBCE_MMU_RMIF_CTRL4, devp->afbce_info->table_paddr, 0, 32); + W_VCBUS_BIT(AFBCE_MMU_RMIF_SCOPE_X, cur_mmu_used, 0, 12); - rdma_write_reg_bits(devp->rdma_handle, - AFBCE_ENABLE, 1, 12, 1); //set afbce pulse mode - rdma_write_reg_bits(devp->rdma_handle, - AFBCE_ENABLE, 0, 8, 1);//disable afbce + W_VCBUS_BIT(AFBCE_ENABLE, 1, 12, 1); //set afbce pulse mode + W_VCBUS_BIT(AFBCE_ENABLE, 0, 8, 1);//disable afbce } void vdin_afbce_maptable_init(struct vdin_dev_s *devp) @@ -649,6 +362,9 @@ void vdin_afbce_maptable_init(struct vdin_dev_s *devp) unsigned int size; void *p = NULL; + if (!devp->afbce_info) + return; + size = roundup(devp->afbce_info->frame_body_size, 4096); ptable = devp->afbce_info->fm_table_paddr[0]; @@ -709,6 +425,9 @@ void vdin_afbce_set_next_frame(struct vdin_dev_s *devp, { unsigned char i; + if (!devp->afbce_info) + return; + i = vfe->af_num; vfe->vf.compHeadAddr = devp->afbce_info->fm_head_paddr[i]; vfe->vf.compBodyAddr = devp->afbce_info->fm_body_paddr[i]; @@ -754,9 +473,20 @@ void vdin_afbce_hw_disable(void) W_VCBUS_BIT(AFBCE_ENABLE, 0, 8, 1);//disable afbce } -void vdin_afbce_hw_enable(struct vdin_dev_s *devp) +void vdin_afbce_hw_enable(void) +{ + W_VCBUS_BIT(AFBCE_ENABLE, 1, 8, 1); +} + +void vdin_afbce_hw_disable_rdma(struct vdin_dev_s *devp) +{ + rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 0, 8, 1); +} + +void vdin_afbce_hw_enable_rdma(struct vdin_dev_s *devp) { - //enable afbce + if (devp->afbce_flag & VDIN_AFBCE_EN_LOOSY) + rdma_write_reg(devp->rdma_handle, AFBCE_QUANT_ENABLE, 0xc11); rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 1, 8, 1); } diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h index 08ad76f..0ac61b5 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h @@ -300,10 +300,9 @@ #define AFBCE_MMU_RMIF_RO_STAT 0x41c6 +extern void vdin_write_mif_or_afbce_init(struct vdin_dev_s *devp); extern void vdin_write_mif_or_afbce(struct vdin_dev_s *devp, enum vdin_output_mif_e sel); -extern unsigned int vdin_afbce_cma_alloc(struct vdin_dev_s *devp); -extern void vdin_afbce_cma_release(struct vdin_dev_s *devp); extern void vdin_afbce_update(struct vdin_dev_s *devp); extern void vdin_afbce_config(struct vdin_dev_s *devp); extern void vdin_afbce_maptable_init(struct vdin_dev_s *devp); @@ -312,7 +311,9 @@ extern void vdin_afbce_set_next_frame(struct vdin_dev_s *devp, extern void vdin_afbce_clear_writedown_flag(struct vdin_dev_s *devp); extern int vdin_afbce_read_writedown_flag(void); extern void vdin_afbce_hw_disable(void); -extern void vdin_afbce_hw_enable(struct vdin_dev_s *devp); +extern void vdin_afbce_hw_enable(void); +extern void vdin_afbce_hw_disable_rdma(struct vdin_dev_s *devp); +extern void vdin_afbce_hw_enable_rdma(struct vdin_dev_s *devp); extern void vdin_afbce_soft_reset(void); #endif diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.c index edfa775..0d32bfc 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.c @@ -328,6 +328,10 @@ void vdin_canvas_auto_config(struct vdin_dev_s *devp) devp->canvas_max_num = min(devp->canvas_max_num, canvas_num); devp->canvas_max_num = min(devp->canvas_max_num, max_buffer_num); + if (devp->canvas_max_num < devp->vfmem_max_cnt) { + pr_err("\nvdin%d canvas_max_num %d less than vfmem_max_cnt %d\n", + devp->index, devp->canvas_max_num, devp->vfmem_max_cnt); + } if ((devp->cma_config_en != 1) || !(devp->cma_config_flag & 0x100)) { /*use_reserved_mem or alloc_from_contiguous*/ devp->mem_start = roundup(devp->mem_start, devp->canvas_align); @@ -393,6 +397,7 @@ void vdin_canvas_auto_config(struct vdin_dev_s *devp) /* need to be static for pointer use in codec_mm */ static char vdin_name[6]; /* return val:1: fail;0: ok */ +/* combined canvas and afbce memory */ unsigned int vdin_cma_alloc(struct vdin_dev_s *devp) { unsigned int mem_size, h_size, v_size; @@ -400,6 +405,14 @@ unsigned int vdin_cma_alloc(struct vdin_dev_s *devp) CODEC_MM_FLAGS_DMA; unsigned int max_buffer_num = min_buf_num; unsigned int i; + /*head_size:3840*2160*3*9/32*/ + unsigned int afbce_head_size_byte = PAGE_SIZE * 1712; + /*afbce map_table need 218700 byte at most*/ + unsigned int afbce_table_size_byte = PAGE_SIZE * 60;/*0.3M*/ + unsigned long ref_paddr; + unsigned int mem_used; + unsigned int frame_head_size; + unsigned int mmu_used; if (devp->rdma_enable) max_buffer_num++; @@ -493,14 +506,19 @@ unsigned int vdin_cma_alloc(struct vdin_dev_s *devp) mem_size = PAGE_ALIGN(mem_size) * max_buffer_num + dolby_size_byte * max_buffer_num; mem_size = (mem_size/PAGE_SIZE + 1)*PAGE_SIZE; - if (mem_size > devp->cma_mem_size) + if (mem_size > devp->cma_mem_size) { mem_size = devp->cma_mem_size; + pr_err("\nvdin%d cma_mem_size is not enough!!!\n", devp->index); + devp->cma_mem_alloc = 0; + return 1; + } if (devp->index == 0) strcpy(vdin_name, "vdin0"); else if (devp->index == 1) strcpy(vdin_name, "vdin1"); if (devp->cma_config_flag == 0x101) { + /* canvas or afbce paddr */ for (i = 0; i < max_buffer_num; i++) { devp->vfmem_start[i] = codec_mm_alloc_for_dma(vdin_name, devp->vfmem_size/PAGE_SIZE, 0, flags); @@ -509,70 +527,185 @@ unsigned int vdin_cma_alloc(struct vdin_dev_s *devp) devp->index, i); devp->cma_mem_alloc = 0; return 1; - } else { - devp->cma_mem_alloc = 1; - pr_info("vdin%d buf[%d] mem_start = 0x%lx, mem_size = 0x%x\n", - devp->index, i, - devp->vfmem_start[i], devp->vfmem_size); } + if (devp->afbce_info) { + devp->afbce_info->fm_body_paddr[i] = + devp->vfmem_start[i]; + } + pr_info("vdin%d buf[%d] mem_start = 0x%lx, mem_size = 0x%x\n", + devp->index, i, + devp->vfmem_start[i], devp->vfmem_size); } - pr_info("vdin%d codec cma alloc ok!\n", devp->index); + if (devp->afbce_info) + devp->afbce_info->frame_body_size = devp->vfmem_size; devp->mem_size = mem_size; + + if (devp->afbce_info) { + devp->afbce_info->head_paddr = codec_mm_alloc_for_dma( + vdin_name, afbce_head_size_byte/PAGE_SIZE, + 0, flags); + if (devp->afbce_info->head_paddr == 0) { + pr_err("\nvdin%d header codec alloc fail!!!\n", + devp->index); + devp->cma_mem_alloc = 0; + return 1; + } + devp->afbce_info->table_paddr = codec_mm_alloc_for_dma( + vdin_name, afbce_table_size_byte/PAGE_SIZE, + 0, flags); + if (devp->afbce_info->table_paddr == 0) { + pr_err("\nvdin%d table codec alloc fail!!!\n", + devp->index); + codec_mm_free_for_dma(vdin_name, + devp->afbce_info->head_paddr); + devp->cma_mem_alloc = 0; + return 1; + } + devp->afbce_info->head_size = afbce_head_size_byte; + devp->afbce_info->table_size = afbce_table_size_byte; + + pr_info("vdin%d head_start = 0x%lx, head_size = 0x%x\n", + devp->index, devp->afbce_info->head_paddr, + devp->afbce_info->head_size); + pr_info("vdin%d table_start = 0x%lx, table_size = 0x%x\n", + devp->index, devp->afbce_info->table_paddr, + devp->afbce_info->table_size); + } + + devp->cma_mem_alloc = 1; } else if (devp->cma_config_flag == 0x1) { devp->mem_start = codec_mm_alloc_for_dma(vdin_name, mem_size/PAGE_SIZE, 0, flags); - devp->mem_size = mem_size; if (devp->mem_start == 0) { pr_err("\nvdin%d codec alloc fail!!!\n", devp->index); devp->cma_mem_alloc = 0; return 1; - } else { - devp->cma_mem_alloc = 1; - pr_info("vdin%d mem_start = 0x%lx, mem_size = 0x%x\n", - devp->index, devp->mem_start, devp->mem_size); - pr_info("vdin%d codec cma alloc ok!\n", devp->index); } + devp->mem_size = mem_size; + devp->cma_mem_alloc = 1; + pr_info("vdin%d mem_start = 0x%lx, mem_size = 0x%x\n", + devp->index, devp->mem_start, devp->mem_size); } else if (devp->cma_config_flag == 0x100) { for (i = 0; i < max_buffer_num; i++) { devp->vfvenc_pages[i] = dma_alloc_from_contiguous( &(devp->this_pdev->dev), devp->vfmem_size >> PAGE_SHIFT, 0); - if (devp->vfvenc_pages[i]) { - devp->vfmem_start[i] = - page_to_phys(devp->vfvenc_pages[i]); - pr_info("vdin%d buf[%d]mem_start = 0x%lx, mem_size = 0x%x\n", - devp->index, i, - devp->vfmem_start[i], devp->vfmem_size); - } else { + if (!devp->vfvenc_pages[i]) { devp->cma_mem_alloc = 0; pr_err("\nvdin%d cma mem undefined2.\n", devp->index); return 1; } + devp->vfmem_start[i] = + page_to_phys(devp->vfvenc_pages[i]); + pr_info("vdin%d buf[%d]mem_start = 0x%lx, mem_size = 0x%x\n", + devp->index, i, + devp->vfmem_start[i], devp->vfmem_size); } + devp->mem_size = mem_size; devp->cma_mem_alloc = 1; - devp->mem_size = mem_size; - pr_info("vdin%d cma alloc ok!\n", devp->index); } else { + /* canvas or afbce paddr */ devp->venc_pages = dma_alloc_from_contiguous( &(devp->this_pdev->dev), devp->cma_mem_size >> PAGE_SHIFT, 0); - if (devp->venc_pages) { - devp->mem_start = - page_to_phys(devp->venc_pages); - devp->mem_size = mem_size; - devp->cma_mem_alloc = 1; - pr_info("vdin%d mem_start = 0x%lx, mem_size = 0x%x\n", - devp->index, devp->mem_start, devp->mem_size); - pr_info("vdin%d cma alloc ok!\n", devp->index); - } else { + if (!devp->venc_pages) { devp->cma_mem_alloc = 0; pr_err("\nvdin%d cma mem undefined2.\n", devp->index); return 1; } + devp->mem_start = page_to_phys(devp->venc_pages); + devp->mem_size = mem_size; + + /* set fm_body_paddr */ + if (devp->afbce_info) { + ref_paddr = devp->mem_start; + devp->afbce_info->frame_body_size = devp->vfmem_size; + for (i = 0; i < max_buffer_num; i++) { + ref_paddr = devp->mem_start + + (devp->vfmem_size * i); + devp->afbce_info->fm_body_paddr[i] = ref_paddr; + + pr_info("vdin%d body[%d]_start = 0x%lx, body_size = 0x%x\n", + devp->index, i, + devp->afbce_info->fm_body_paddr[i], + devp->afbce_info->frame_body_size); + } + + /* afbce header & table paddr */ + devp->afbce_info->head_paddr = ref_paddr + + devp->vfmem_size; + devp->afbce_info->head_size = 2 * SZ_1M;/*2M*/ + devp->afbce_info->table_paddr = + devp->afbce_info->head_paddr + + devp->afbce_info->head_size; + devp->afbce_info->table_size = 2 * SZ_1M;/*2M*/ + + pr_info("vdin%d head_start = 0x%lx, head_size = 0x%x\n", + devp->index, devp->afbce_info->head_paddr, + devp->afbce_info->head_size); + pr_info("vdin%d table_start = 0x%lx, table_size = 0x%x\n", + devp->index, devp->afbce_info->table_paddr, + devp->afbce_info->table_size); + + /*check memory over the boundary*/ + mem_used = devp->afbce_info->table_paddr + + devp->afbce_info->table_size - + devp->afbce_info->fm_body_paddr[0]; + if (mem_used > devp->cma_mem_size) { + pr_err("vdin%d error: mem_used(%d) > cma_mem_size(%d)\n", + devp->index, mem_used, + devp->cma_mem_size); + return 1; + } + } + + devp->cma_mem_alloc = 1; + pr_info("vdin%d mem_start = 0x%lx, mem_size = 0x%x\n", + devp->index, devp->mem_start, devp->mem_size); } + + /* set afbce head paddr */ + if (devp->afbce_info) { + /* 1 block = 32 * 4 pixle = 128 pixel */ + /* there is a header in one block, a header has 4 bytes */ + frame_head_size = (int)roundup(devp->vfmem_size, 128); + /*h_active * v_active / 128 * 4 = frame_head_size*/ + frame_head_size = PAGE_ALIGN(frame_head_size / 32); + + devp->afbce_info->frame_head_size = frame_head_size; + + for (i = 0; i < max_buffer_num; i++) { + devp->afbce_info->fm_head_paddr[i] = + devp->afbce_info->head_paddr + + (frame_head_size*i); + + pr_info("vdin%d fm_head_paddr[%d] = 0x%lx, frame_head_size = 0x%x\n", + devp->index, i, + devp->afbce_info->fm_head_paddr[i], + frame_head_size); + } + + /* set afbce table paddr */ + mmu_used = devp->afbce_info->frame_body_size >> 12; + mmu_used = mmu_used * 4; + mmu_used = PAGE_ALIGN(mmu_used); + devp->afbce_info->frame_table_size = mmu_used; + + for (i = 0; i < max_buffer_num; i++) { + devp->afbce_info->fm_table_paddr[i] = + devp->afbce_info->table_paddr + (mmu_used*i); + + pr_info("vdin%d fm_table_paddr[%d]=0x%lx, frame_table_size = 0x%x\n", + devp->index, i, + devp->afbce_info->fm_table_paddr[i], + devp->afbce_info->frame_table_size); + } + } + + pr_info("vdin%d cma alloc ok!\n", devp->index); return 0; } @@ -599,6 +732,17 @@ void vdin_cma_release(struct vdin_dev_s *devp) strcpy(vdin_name, "vdin1"); if (devp->cma_config_flag == 0x101) { + if (devp->afbce_info) { + if (devp->afbce_info->head_paddr) { + codec_mm_free_for_dma(vdin_name, + devp->afbce_info->head_paddr); + } + if (devp->afbce_info->table_paddr) { + codec_mm_free_for_dma(vdin_name, + devp->afbce_info->table_paddr); + } + } + /* canvas or afbce paddr */ for (i = 0; i < devp->vfmem_max_cnt; i++) codec_mm_free_for_dma(vdin_name, devp->vfmem_start[i]); pr_info("vdin%d codec cma release ok!\n", devp->index); diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c index 89820b2..4c67d9c 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c @@ -3936,6 +3936,7 @@ void vdin_dolby_config(struct vdin_dev_s *devp) } } +unsigned int vdin0_afbce_debug_force; int vdin_event_cb(int type, void *data, void *op_arg) { unsigned long flags; @@ -4007,6 +4008,26 @@ int vdin_event_cb(int type, void *data, void *op_arg) pr_info("%s(type 0x%x vf index 0x%x)=>disp_mode %d,req_mode:%d\n", __func__, type, index_disp, req->disp_mode, req->req_mode); + } else if (type & VFRAME_EVENT_RECEIVER_NEED_NO_COMP) { + struct vdin_dev_s *devp = vdin_get_dev(0); + unsigned int *cnt; + + /* use for debug */ + if (vdin0_afbce_debug_force) + return 0; + + cnt = (unsigned int *)data; + if (*cnt) { + devp->afbce_mode = 0; + } else { + if (devp->afbce_valid) + devp->afbce_mode = 1; + } + + if (vdin_ctl_dbg&(1<<1)) + pr_info("%s(type 0x%x vdin%d) afbce_mode: %d, vpp_cnt: %d\n", + __func__, type, devp->index, + devp->afbce_mode, *cnt); } return 0; } @@ -4186,7 +4207,7 @@ u32 vdin_get_curr_field_type(struct vdin_dev_s *devp) if ((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV444) || (format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444)) { type |= VIDTYPE_VIU_444; - if (devp->afbce_mode == 1) + if (devp->afbce_mode_pre) type |= VIDTYPE_COMB_MODE; } else if ((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || (format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422)) @@ -4200,10 +4221,13 @@ u32 vdin_get_curr_field_type(struct vdin_dev_s *devp) } - if (devp->afbce_mode == 1) { + if (devp->afbce_valid) + type |= VIDTYPE_SUPPORT_COMPRESS; + if (devp->afbce_mode_pre) { type |= VIDTYPE_COMPRESS; + type |= VIDTYPE_NO_DW; type |= VIDTYPE_SCATTER; - if (devp->afbce_lossy_en == 1) + if (devp->afbce_flag & VDIN_AFBCE_EN_LOOSY) type |= VIDTYPE_COMPRESS_LOSS; } diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c index cb3065f..c9927f1 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c @@ -32,6 +32,7 @@ #include "vdin_drv.h" #include "vdin_ctl.h" #include "vdin_regs.h" +#include "vdin_afbce.h" /*2018-07-18 add debugfs*/ #include #include @@ -828,7 +829,7 @@ static void vdin_dump_state(struct vdin_dev_s *devp) devp->dv.dv_flag, devp->dv.dv_config, devp->prop.dolby_vision); pr_info("size of struct vdin_dev_s: %d\n", devp->vdin_dev_ssize); - pr_info("afbce_flag: %d\n", devp->afbce_flag); + pr_info("afbce_flag: 0x%x\n", devp->afbce_flag); pr_info("afbce_mode: %d\n", devp->afbce_mode); if (devp->afbce_mode == 1) { for (i = 0; i < devp->vfmem_max_cnt; i++) { @@ -852,17 +853,10 @@ static void vdin_dump_state(struct vdin_dev_s *devp) i, devp->afbce_info->fm_body_paddr[i], devp->afbce_info->frame_body_size); } - if (is_meson_tl1_cpu()) { - pr_info("tl1 preview flag = %d\n", - tl1_vdin1_preview_flag); - } } pr_info("Vdin driver version : %s\n", VDIN_VER); } -/*2018-07-18 add debugfs*/ -struct vdin_dev_s *vdin_get_dev(unsigned int index); - /*same as vdin_dump_state*/ static int seq_file_vdin_state_show(struct seq_file *seq, void *v) { @@ -1772,11 +1766,23 @@ start_chk: unsigned int offset = devp->addr_offset; pr_info("vdin%d addr offset:0x%x regs start----\n", devp->index, offset); - for (reg = VDIN_SCALE_COEF_IDX; reg <= 0x1273; reg++) - pr_info("[0x%x]reg:0x%x-0x%x\n", - (0xd0100000 + ((reg+offset)<<2)), - (reg+offset), rd(offset, reg)); - pr_info("vdin%d regs end----\n", devp->index); + for (reg = VDIN_SCALE_COEF_IDX; reg <= 0x1273; reg++) { + pr_info("0x%04x = 0x%08x\n", + (reg+offset), rd(offset, reg)); + } + pr_info("vdin%d regs end----\n", devp->index); + if (devp->afbce_flag & VDIN_AFBCE_EN) { + pr_info("vdin%d afbce regs start----\n", devp->index); + for (reg = AFBCE_ENABLE; reg <= AFBCE_MMU_RMIF_RO_STAT; + reg++) { + pr_info("0x%04x = 0x%08x\n", + (reg), R_VCBUS(reg)); + } + pr_info("vdin%d afbce regs end----\n", devp->index); + } + reg = VDIN_MISC_CTRL; + pr_info("0x%04x = 0x%08x\n", (reg), R_VCBUS(reg)); + pr_info("\n"); } else if (!strcmp(parm[0], "rgb_xy")) { unsigned int x = 0, y = 0; @@ -2133,15 +2139,15 @@ start_chk: } else { pr_info("skip_frame_debug: %d\n", skip_frame_debug); } - } else if (!strcmp(parm[0], "afbc_drop_cnt")) { + } else if (!strcmp(parm[0], "max_recycle_cnt")) { if (parm[1] != NULL) { if (kstrtouint(parm[1], 10, - &vdin_afbc_force_drop_frame_cnt) == 0) - pr_info("set vdin_afbc_force_drop_frame_cnt: %d\n", - vdin_afbc_force_drop_frame_cnt); + &max_recycle_frame_cnt) == 0) + pr_info("set max_recycle_frame_cnt: %d\n", + max_recycle_frame_cnt); } else { - pr_info("vdin_afbc_force_drop_frame_cnt: %d\n", - vdin_afbc_force_drop_frame_cnt); + pr_info("max_recycle_frame_cnt: %d\n", + max_recycle_frame_cnt); } } else if (!strcmp(parm[0], "max_ignore_cnt")) { if (parm[1] != NULL) { @@ -2152,6 +2158,46 @@ start_chk: pr_info("max_ignore_frame_cnt: %d\n", max_ignore_frame_cnt); } + } else if (!strcmp(parm[0], "afbce_flag")) { + if (parm[1] != NULL) { + if (kstrtouint(parm[1], 16, &devp->afbce_flag) == 0) { + pr_info("set vdin_afbce_flag: 0x%x\n", + devp->afbce_flag); + } + } else { + pr_info("vdin_afbce_flag: 0x%x\n", devp->afbce_flag); + } + } else if (!strcmp(parm[0], "afbce_mode")) { + unsigned int mode = 0, flag = 0; + + if (parm[2] != NULL) { + if ((kstrtouint(parm[1], 10, &mode) == 0) && + (kstrtouint(parm[2], 10, &flag) == 0)) { + vdin0_afbce_debug_force = flag; + if (devp->afbce_flag & VDIN_AFBCE_EN) + devp->afbce_mode = mode; + else + devp->afbce_mode = 0; + if (vdin0_afbce_debug_force) { + pr_info("set force vdin_afbce_mode: %d\n", + devp->afbce_mode); + } else { + pr_info("set vdin_afbce_mode: %d\n", + devp->afbce_mode); + } + } + } else if (parm[1] != NULL) { + if (kstrtouint(parm[1], 10, &mode) == 0) { + if (devp->afbce_flag & VDIN_AFBCE_EN) + devp->afbce_mode = mode; + else + devp->afbce_mode = 0; + pr_info("set vdin_afbce_mode: %d\n", + devp->afbce_mode); + } + } else { + pr_info("vdin_afbce_mode: %d\n", devp->afbce_mode); + } } else { pr_info("unknown command\n"); } diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c index e0b9e63..eaf8a65 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c @@ -80,14 +80,6 @@ static unsigned long mem_start, mem_end; static unsigned int use_reserved_mem; static unsigned int pr_times; -/* afbce related */ -static int afbc_init_flag[VDIN_MAX_DEVS]; -unsigned int tl1_vdin1_preview_flag; -static unsigned int tl1_vdin1_data_readied; -static unsigned int tl1_vdin1_canvas_addr; -static unsigned int tl1_vdin1_height; -static unsigned int tl1_vdin1_width; -spinlock_t tl1_preview_lock; /* * canvas_config_mode * 0: canvas_config in driver probe @@ -97,18 +89,14 @@ spinlock_t tl1_preview_lock; static int canvas_config_mode = 2; static bool work_mode_simple; static int phase_lock_flag; -static int max_ignore_frames[2] = {2, 1}; /*game_mode_switch_frames:min num is 5 by 1080p60hz input test*/ static int game_mode_switch_frames = 10; static int game_mode_phlock_switch_frames = 60; -static int ignore_frames[2] = {0, 0}; static unsigned int dv_work_delby; -static int tl1_vdin1_preview_ready_flag; -static unsigned int vdin_afbc_force_drop_frame = 1; static struct vf_entry *vfe_drop_force; -unsigned int vdin_afbc_force_drop_frame_cnt = 2; +unsigned int max_recycle_frame_cnt; unsigned int max_ignore_frame_cnt = 2; unsigned int skip_frame_debug; @@ -217,18 +205,13 @@ int vdin_open_fe(enum tvin_port_e port, int index, struct vdin_dev_s *devp) devp->frontend = fe; devp->parm.port = port; - /* don't change parm.info for tl1_vdin1_preview, - * for it should follow vdin0 parm.info - */ - if (tl1_vdin1_preview_flag == 0) { - /* for atv snow function */ - if ((port == TVIN_PORT_CVBS3) && - (devp->parm.info.fmt == TVIN_SIG_FMT_NULL)) - devp->parm.info.fmt = TVIN_SIG_FMT_CVBS_NTSC_M; - else - devp->parm.info.fmt = TVIN_SIG_FMT_NULL; - devp->parm.info.status = TVIN_SIG_STATUS_NULL; - } + /* for atv snow function */ + if ((port == TVIN_PORT_CVBS3) && + (devp->parm.info.fmt == TVIN_SIG_FMT_NULL)) + devp->parm.info.fmt = TVIN_SIG_FMT_CVBS_NTSC_M; + else + devp->parm.info.fmt = TVIN_SIG_FMT_NULL; + devp->parm.info.status = TVIN_SIG_STATUS_NULL; /* clear color para*/ memset(&devp->pre_prop, 0, sizeof(devp->pre_prop)); /* clear color para*/ @@ -245,11 +228,8 @@ int vdin_open_fe(enum tvin_port_e port, int index, struct vdin_dev_s *devp) if (devp->msr_clk != NULL) clk_prepare_enable(devp->msr_clk); - if (tl1_vdin1_preview_flag == 0) { - if (devp->frontend->dec_ops && devp->frontend->dec_ops->open) - ret = - devp->frontend->dec_ops->open(devp->frontend, port); - } + if (devp->frontend->dec_ops && devp->frontend->dec_ops->open) + ret = devp->frontend->dec_ops->open(devp->frontend, port); /* check open status */ if (ret) return 1; @@ -372,22 +352,22 @@ static void vdin_vf_init(struct vdin_dev_s *devp) #ifndef VDIN_DYNAMIC_DURATION vf->duration = devp->fmt_info_p->duration; #endif + /* init canvas config */ /*if output fmt is nv21 or nv12 , * use the two continuous canvas for one field */ - if (devp->afbce_mode == 0) { - if ((devp->prop.dest_cfmt == TVIN_NV12) || - (devp->prop.dest_cfmt == TVIN_NV21)) { - chromaid = + if ((devp->prop.dest_cfmt == TVIN_NV12) || + (devp->prop.dest_cfmt == TVIN_NV21)) { + chromaid = (vdin_canvas_ids[index][(vf->index<<1)+1])<<8; - addr = - vdin_canvas_ids[index][vf->index<<1] | - chromaid; - } else - addr = vdin_canvas_ids[index][vf->index]; + addr = vdin_canvas_ids[index][vf->index<<1] | chromaid; + } else { + addr = vdin_canvas_ids[index][vf->index]; + } + vf->canvas0Addr = vf->canvas1Addr = addr; - vf->canvas0Addr = vf->canvas1Addr = addr; - } else if (devp->afbce_mode == 1) { + /* init afbce config */ + if (devp->afbce_info) { vf->compHeadAddr = devp->afbce_info->fm_head_paddr[i]; vf->compBodyAddr = devp->afbce_info->fm_body_paddr[i]; vf->compWidth = devp->h_active; @@ -440,6 +420,34 @@ static void vdin_rdma_irq(void *arg) static struct rdma_op_s vdin_rdma_op[VDIN_MAX_DEVS]; #endif +static void vdin_afbce_mode_init(struct vdin_dev_s *devp) +{ + /* afbce_valid means can switch into afbce mode */ + devp->afbce_valid = 0; + if (devp->afbce_flag & VDIN_AFBCE_EN) { + if ((devp->h_active > 1920) && (devp->v_active > 1080)) { + if (devp->afbce_flag & VDIN_AFBCE_EN_4K) + devp->afbce_valid = 1; + } else if ((devp->h_active > 1280) && (devp->v_active > 720)) { + if (devp->afbce_flag & VDIN_AFBCE_EN_1080P) + devp->afbce_valid = 1; + } else if ((devp->h_active > 720) && (devp->v_active > 576)) { + if (devp->afbce_flag & VDIN_AFBCE_EN_720P) + devp->afbce_valid = 1; + } else { + if (devp->afbce_flag & VDIN_AFBCE_EN_SMALL) + devp->afbce_valid = 1; + } + } + + /* default non-afbce mode + * switch to afbce_mode if need by vpp notify + */ + devp->afbce_mode = 0; + devp->afbce_mode_pre = devp->afbce_mode; + pr_info("vdin%d init afbce_mode: %d\n", devp->index, devp->afbce_mode); +} + /* * 1. config canvas base on canvas_config_mode * 0: canvas_config in driver probe @@ -532,45 +540,29 @@ void vdin_start_dec(struct vdin_dev_s *devp) if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL) vdin_fix_nonstd_vsync(devp); - /*reverse / disable reverse write buffer*/ + /*reverse / disable reverse write buffer*/ vdin_wr_reverse(devp->addr_offset, - devp->parm.h_reverse, - devp->parm.v_reverse); + devp->parm.h_reverse, devp->parm.v_reverse); /* check if need enable afbce */ - if (devp->afbce_flag == 1) { - if ((devp->h_active > 1920) && (devp->v_active > 1080)) - devp->afbce_mode = 1; - else - devp->afbce_mode = 0; - pr_info("vdin%d afbce_mode: %d\n", - devp->index, devp->afbce_mode); - } + vdin_afbce_mode_init(devp); #ifdef CONFIG_CMA vdin_cma_malloc_mode(devp); - if (devp->afbce_mode == 1) { - if (vdin_afbce_cma_alloc(devp)) { - pr_err("\nvdin%d-afbce %s fail for cma alloc fail!!!\n", - devp->index, __func__); - return; - } - } else if (devp->afbce_mode == 0) { - if (vdin_cma_alloc(devp)) { - pr_err("\nvdin%d %s fail for cma alloc fail!!!\n", - devp->index, __func__); - return; - } + if (vdin_cma_alloc(devp)) { + pr_err("\nvdin%d %s fail for cma alloc fail!!!\n", + devp->index, __func__); + return; } #endif /* h_active/v_active will be used by bellow calling */ - if (devp->afbce_mode == 0) { - if (canvas_config_mode == 1) - vdin_canvas_start_config(devp); - else if (canvas_config_mode == 2) - vdin_canvas_auto_config(devp); - } else if (devp->afbce_mode == 1) { + if (canvas_config_mode == 1) + vdin_canvas_start_config(devp); + else if (canvas_config_mode == 2) + vdin_canvas_auto_config(devp); + + if (devp->afbce_info) { vdin_afbce_maptable_init(devp); vdin_afbce_config(devp); } @@ -589,7 +581,7 @@ void vdin_start_dec(struct vdin_dev_s *devp) else devp->duration = devp->fmt_info_p->duration; - devp->vfp->size = devp->canvas_max_num; + devp->vfp->size = devp->vfmem_max_cnt; /* canvas and afbce compatible */ vf_pool_init(devp->vfp, devp->vfp->size); vdin_game_mode_check(devp); vdin_vf_init(devp); @@ -622,11 +614,7 @@ void vdin_start_dec(struct vdin_dev_s *devp) vdin_hw_enable(devp->addr_offset); vdin_set_all_regs(devp); - - if (devp->afbce_mode == 0) - vdin_write_mif_or_afbce(devp, VDIN_OUTPUT_TO_MIF); - else if (devp->afbce_mode == 1) - vdin_write_mif_or_afbce(devp, VDIN_OUTPUT_TO_AFBCE); + vdin_write_mif_or_afbce_init(devp); if (!(devp->parm.flag & TVIN_PARM_FLAG_CAP) && (devp->frontend) && @@ -682,23 +670,8 @@ void vdin_start_dec(struct vdin_dev_s *devp) devp->index, jiffies_to_msecs(jiffies), jiffies_to_msecs(jiffies)-devp->start_time); - if ((devp->afbce_mode == 1) && - (is_meson_tl1_cpu() || is_meson_tm2_cpu())) { - if ((devp->h_active >= 1920) && (devp->v_active >= 1080)) { - tl1_vdin1_preview_flag = 1; - tl1_vdin1_data_readied = 0; - tl1_vdin1_preview_ready_flag = 0; - pr_info("vdin.%d tl1_vdin1_preview state init\n", - devp->index); - } else { - tl1_vdin1_preview_flag = 0; - vdin_afbc_force_drop_frame = - vdin_afbc_force_drop_frame_cnt; - } - vfe_drop_force = NULL; - max_ignore_frames[devp->index] = max_ignore_frame_cnt; - vdin_afbc_force_drop_frame = vdin_afbc_force_drop_frame_cnt; - } + vfe_drop_force = NULL; + devp->recycle_frames = 0; } /* @@ -725,7 +698,6 @@ void vdin_stop_dec(struct vdin_dev_s *devp) #endif disable_irq_nosync(devp->irq); - afbc_init_flag[devp->index] = 0; if (devp->afbce_mode == 1) { while (i++ < afbc_write_down_timeout) { @@ -738,10 +710,6 @@ void vdin_stop_dec(struct vdin_dev_s *devp) devp->index); } } - if (is_meson_tl1_cpu() && (tl1_vdin1_preview_flag == 1)) { - if (devp->index == 1) - tl1_vdin1_preview_flag = 0; - } if (!(devp->parm.flag & TVIN_PARM_FLAG_CAP) && devp->frontend->dec_ops && @@ -779,10 +747,7 @@ void vdin_stop_dec(struct vdin_dev_s *devp) #endif #ifdef CONFIG_CMA - if (devp->afbce_mode == 1) - vdin_afbce_cma_release(devp); - else if (devp->afbce_mode == 0) - vdin_cma_release(devp); + vdin_cma_release(devp); #endif switch_vpu_mem_pd_vmod(devp->addr_offset?VPU_VIU_VDIN1:VPU_VIU_VDIN0, VPU_MEM_POWER_DOWN); @@ -791,7 +756,7 @@ void vdin_stop_dec(struct vdin_dev_s *devp) rdma_clear(devp->rdma_handle); #endif devp->flags &= (~VDIN_FLAG_RDMA_ENABLE); - ignore_frames[devp->index] = 0; + devp->ignore_frames = 0; devp->cycle = 0; /* clear color para*/ @@ -822,11 +787,6 @@ int start_tvin_service(int no, struct vdin_parm_s *para) return -1; } - if (tl1_vdin1_preview_flag == 1) { - pr_err("[vdin]%s vdin%d use for preview, return.\n", - __func__, no); - return -1; - } fmt = devp->parm.info.fmt; if (vdin_dbg_en) { pr_info("**[%s]cfmt:%d;dfmt:%d;dest_hactive:%d;", @@ -1354,31 +1314,16 @@ static void vdin_hist_tgt(struct vdin_dev_s *devp, struct vframe_s *vf) spin_unlock_irqrestore(&devp->hist_lock, flags); } -static bool vdin_skip_frame_check(struct vdin_dev_s *devp) +static bool vdin_recycle_frame_check(struct vdin_dev_s *devp) { - ulong flags = 0; int skip_flag = 0; - spin_lock_irqsave(&tl1_preview_lock, flags); - if (devp->afbce_mode == 0) { - spin_unlock_irqrestore(&tl1_preview_lock, flags); + if (devp->index) return false; - } - if (tl1_vdin1_preview_flag == 1) { - if (tl1_vdin1_preview_ready_flag == 0) { - skip_flag = 1; - } else { - if (vdin_afbc_force_drop_frame > 0) { - vdin_afbc_force_drop_frame--; - skip_flag = 1; - } - } - } else { - if (vdin_afbc_force_drop_frame > 0) { - vdin_afbc_force_drop_frame--; - skip_flag = 1; - } + if (devp->recycle_frames < max_recycle_frame_cnt) { + devp->recycle_frames++; + skip_flag = 1; } if (skip_flag) { @@ -1387,14 +1332,30 @@ static bool vdin_skip_frame_check(struct vdin_dev_s *devp) receiver_vf_put(&vfe_drop_force->vf, devp->vfp); else pr_info("vdin.%d: skip vf get error\n", devp->index); - spin_unlock_irqrestore(&tl1_preview_lock, flags); return true; } - spin_unlock_irqrestore(&tl1_preview_lock, flags); return false; } +static void vdin_afbce_mode_update(struct vdin_dev_s *devp) +{ + /* vdin mif/afbce mode update */ + if (devp->afbce_mode) { + vdin_write_mif_or_afbce(devp, VDIN_OUTPUT_TO_AFBCE); + vdin_afbce_hw_enable_rdma(devp); + } else { + vdin_afbce_hw_disable_rdma(devp); + vdin_write_mif_or_afbce(devp, VDIN_OUTPUT_TO_MIF); + } + + if (vdin_dbg_en) { + pr_info("vdin.%d: change afbce_mode %d->%d\n", + devp->index, devp->afbce_mode_pre, devp->afbce_mode); + } + devp->afbce_mode_pre = devp->afbce_mode; +} + /* *VDIN_FLAG_RDMA_ENABLE=1 * provider_vf_put(devp->last_wr_vfe, devp->vfp); @@ -1403,7 +1364,7 @@ static bool vdin_skip_frame_check(struct vdin_dev_s *devp) */ irqreturn_t vdin_isr(int irq, void *dev_id) { - ulong flags = 0, flags1 = 0; + ulong flags = 0; struct vdin_dev_s *devp = (struct vdin_dev_s *)dev_id; enum tvin_sm_status_e state; @@ -1437,30 +1398,23 @@ irqreturn_t vdin_isr(int irq, void *dev_id) pr_info("vdin.%d: vdin_irq_flag=%d\n", devp->index, devp->vdin_irq_flag); } - goto irq_handled; + return IRQ_HANDLED; } /* ignore fake irq caused by sw reset*/ if (devp->vdin_reset_flag) { devp->vdin_reset_flag = 0; + devp->vdin_irq_flag = 10; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } return IRQ_HANDLED; } vf_drop_cnt = vdin_drop_cnt; offset = devp->addr_offset; - if (devp->afbce_mode == 1) { - if (afbc_init_flag[devp->index] == 0) { - afbc_init_flag[devp->index] = 1; - /*set mem power on*/ - vdin_afbce_hw_enable(devp); - return IRQ_HANDLED; - } else if (afbc_init_flag[devp->index] == 1) { - afbc_init_flag[devp->index] = 2; - return IRQ_HANDLED; - } - } - isr_log(devp->vfp); devp->irq_cnt++; /* debug interrupt interval time @@ -1470,6 +1424,7 @@ irqreturn_t vdin_isr(int irq, void *dev_id) */ spin_lock_irqsave(&devp->isr_lock, flags); + if (devp->afbce_mode == 1) { /* no need reset mif under afbc mode */ devp->vdin_reset_flag = 0; @@ -1492,8 +1447,10 @@ irqreturn_t vdin_isr(int irq, void *dev_id) stamp = vdin_get_meas_vstamp(offset); if (!devp->curr_wr_vfe) { devp->curr_wr_vfe = provider_vf_get(devp->vfp); - devp->curr_wr_vfe->vf.ready_jiffies64 = jiffies_64; - devp->curr_wr_vfe->vf.ready_clock[0] = sched_clock(); + if (devp->curr_wr_vfe) { + devp->curr_wr_vfe->vf.ready_jiffies64 = jiffies_64; + devp->curr_wr_vfe->vf.ready_clock[0] = sched_clock(); + } /*save the first field stamp*/ devp->stamp = stamp; devp->vdin_irq_flag = 3; @@ -1503,6 +1460,7 @@ irqreturn_t vdin_isr(int irq, void *dev_id) } goto irq_handled; } + /* use RDMA and not game mode */ if (devp->last_wr_vfe && (devp->flags&VDIN_FLAG_RDMA_ENABLE) && !(devp->game_mode & VDIN_GAME_MODE_1) && @@ -1525,30 +1483,6 @@ irqreturn_t vdin_isr(int irq, void *dev_id) devp->dv.dv_crc_check = true; if ((devp->dv.dv_crc_check == true) || (!(dv_dbg_mask & DV_CRC_CHECK))) { - spin_lock_irqsave(&tl1_preview_lock, flags1); - if ((devp->index == 0) && - (tl1_vdin1_preview_flag == 1)) { - if (tl1_vdin1_data_readied == 1) { - tl1_vdin1_data_readied = 0; - devp->last_wr_vfe->vf.canvas0Addr = - tl1_vdin1_canvas_addr; - devp->last_wr_vfe->vf.height = - tl1_vdin1_height; - devp->last_wr_vfe->vf.width = - tl1_vdin1_width; - tl1_vdin1_preview_ready_flag = 1; - } else { - tl1_vdin1_preview_ready_flag = 0; - } - } else if ((devp->index == 1) && - (tl1_vdin1_preview_flag == 1)) { - tl1_vdin1_canvas_addr = - devp->last_wr_vfe->vf.canvas0Addr; - tl1_vdin1_height = devp->last_wr_vfe->vf.height; - tl1_vdin1_width = devp->last_wr_vfe->vf.width; - tl1_vdin1_data_readied = 1; - } - spin_unlock_irqrestore(&tl1_preview_lock, flags1); provider_vf_put(devp->last_wr_vfe, devp->vfp); if (time_en) { devp->last_wr_vfe->vf.ready_clock[1] = @@ -1572,36 +1506,30 @@ irqreturn_t vdin_isr(int irq, void *dev_id) vdin_vf_disp_mode_update(devp->last_wr_vfe, devp->vfp); devp->last_wr_vfe = NULL; - if ((devp->index == 1) && (tl1_vdin1_preview_flag == 1)) { - //if (vdin_dbg_en) - //pr_info("vdin1 preview dont notify receiver.\n"); - } else { #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - if (((devp->dv.dolby_input & (1 << devp->index)) || - (devp->dv.dv_flag && is_dolby_vision_enable())) - && (devp->dv.dv_config == true)) - vf_notify_receiver("dv_vdin", - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - else { + if (((devp->dv.dolby_input & (1 << devp->index)) || + (devp->dv.dv_flag && is_dolby_vision_enable())) && + (devp->dv.dv_config == true)) + vf_notify_receiver("dv_vdin", + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + else { #endif - if (vdin_skip_frame_check(devp)) { - devp->vdin_irq_flag = 16; - if (skip_frame_debug) { - pr_info("vdin.%d: vdin_irq_flag=%d\n", - devp->index, - devp->vdin_irq_flag); - } - vdin_drop_cnt++; - } else { - vf_notify_receiver(devp->name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); + if (vdin_recycle_frame_check(devp)) { + devp->vdin_irq_flag = 16; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, + devp->vdin_irq_flag); } -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + vdin_drop_cnt++; + } else { + vf_notify_receiver(devp->name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, + NULL); } -#endif +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION } +#endif } /*check vs is valid base on the time during continuous vs*/ if (vdin_check_cycle(devp) && (!(isr_flag & VDIN_BYPASS_CYC_CHECK)) @@ -1651,8 +1579,7 @@ irqreturn_t vdin_isr(int irq, void *dev_id) if (((devp->parm.flag & TVIN_PARM_FLAG_2D_TO_3D) || (trans_fmt && (trans_fmt != TVIN_TFMT_3D_FP))) && ((last_field_type & VIDTYPE_INTERLACE_BOTTOM) == - VIDTYPE_INTERLACE_BOTTOM) - ) { + VIDTYPE_INTERLACE_BOTTOM)) { devp->vdin_irq_flag = 7; if (skip_frame_debug) { pr_info("vdin.%d: vdin_irq_flag=%d\n", @@ -1664,6 +1591,10 @@ irqreturn_t vdin_isr(int irq, void *dev_id) curr_wr_vfe = devp->curr_wr_vfe; curr_wr_vf = &curr_wr_vfe->vf; + /* change afbce mode */ + if (devp->afbce_mode_pre != devp->afbce_mode) + vdin_afbce_mode_update(devp); + /* change color matrix */ if (devp->csc_cfg != 0) { prop = &devp->prop; @@ -1699,7 +1630,7 @@ irqreturn_t vdin_isr(int irq, void *dev_id) pre_prop->vdin_hdr_Flag = prop->vdin_hdr_Flag; pre_prop->color_fmt_range = prop->color_fmt_range; pre_prop->dest_cfmt = prop->dest_cfmt; - ignore_frames[devp->index] = 0; + devp->ignore_frames = 0; devp->vdin_irq_flag = 20; if (skip_frame_debug) { pr_info("vdin.%d: vdin_irq_flag=%d\n", @@ -1742,13 +1673,13 @@ irqreturn_t vdin_isr(int irq, void *dev_id) curr_wr_vf->phase = sm_ops->get_secam_phase(devp->frontend) ? VFRAME_PHASE_DB : VFRAME_PHASE_DR; - if (ignore_frames[devp->index] < max_ignore_frames[devp->index]) { + if (devp->ignore_frames < max_ignore_frame_cnt) { devp->vdin_irq_flag = 12; if (skip_frame_debug) { pr_info("vdin.%d: vdin_irq_flag=%d\n", devp->index, devp->vdin_irq_flag); } - ignore_frames[devp->index]++; + devp->ignore_frames++; vdin_drop_cnt++; goto irq_handled; } @@ -1762,7 +1693,7 @@ irqreturn_t vdin_isr(int irq, void *dev_id) } vdin_drop_cnt++; if (devp->flags&VDIN_FLAG_RDMA_ENABLE) - ignore_frames[devp->index] = 0; + devp->ignore_frames = 0; goto irq_handled; } @@ -1788,21 +1719,17 @@ irqreturn_t vdin_isr(int irq, void *dev_id) } } - if ((devp->index == 1) && (tl1_vdin1_preview_flag == 1)) { - //if (vdin_dbg_en) - //pr_info("vdin1 preview dont notify receiver.\n"); - } else { #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - if (((devp->dv.dolby_input & (1 << devp->index)) || - (devp->dv.dv_flag && is_dolby_vision_enable())) && - (devp->dv.dv_config == true)) - vdin2nr = vf_notify_receiver("dv_vdin", - VFRAME_EVENT_PROVIDER_QUREY_VDIN2NR, NULL); - else + if (((devp->dv.dolby_input & (1 << devp->index)) || + (devp->dv.dv_flag && is_dolby_vision_enable())) && + (devp->dv.dv_config == true)) + vdin2nr = vf_notify_receiver("dv_vdin", + VFRAME_EVENT_PROVIDER_QUREY_VDIN2NR, NULL); + else #endif - vdin2nr = vf_notify_receiver(devp->name, - VFRAME_EVENT_PROVIDER_QUREY_VDIN2NR, NULL); - } + vdin2nr = vf_notify_receiver(devp->name, + VFRAME_EVENT_PROVIDER_QUREY_VDIN2NR, NULL); + /*if vdin-nr,di must get * vdin current field type which di pre will read */ @@ -1816,8 +1743,7 @@ irqreturn_t vdin_isr(int irq, void *dev_id) */ if (((devp->parm.flag & TVIN_PARM_FLAG_2D_TO_3D) || (curr_wr_vf->trans_fmt)) && - (last_field_type & VIDTYPE_INTERLACE) - ) { + (last_field_type & VIDTYPE_INTERLACE)) { curr_wr_vf->type &= ~VIDTYPE_INTERLACE_TOP; curr_wr_vf->type |= VIDTYPE_PROGRESSIVE; curr_wr_vf->type |= VIDTYPE_PRE_INTERLACE; @@ -1882,32 +1808,6 @@ irqreturn_t vdin_isr(int irq, void *dev_id) if ((devp->dv.dv_crc_check == true) || (!(dv_dbg_mask & DV_CRC_CHECK))) { - spin_lock_irqsave(&tl1_preview_lock, flags1); - if ((devp->index == 0) && - (tl1_vdin1_preview_flag == 1)) { - if (tl1_vdin1_data_readied == 1) { - tl1_vdin1_data_readied = 0; - curr_wr_vfe->vf.canvas0Addr = - tl1_vdin1_canvas_addr; - curr_wr_vfe->vf.height = - tl1_vdin1_height; - curr_wr_vfe->vf.width = - tl1_vdin1_width; - tl1_vdin1_preview_ready_flag = 1; - } else { - tl1_vdin1_preview_ready_flag = 0; - } - } else if ((devp->index == 1) && - (tl1_vdin1_preview_flag == 1)) { - tl1_vdin1_canvas_addr = - curr_wr_vfe->vf.canvas0Addr; - tl1_vdin1_height = - curr_wr_vfe->vf.height; - tl1_vdin1_width = - curr_wr_vfe->vf.width; - tl1_vdin1_data_readied = 1; - } - spin_unlock_irqrestore(&tl1_preview_lock, flags1); provider_vf_put(curr_wr_vfe, devp->vfp); if (vdin_dbg_en) { curr_wr_vfe->vf.ready_clock[1] = sched_clock(); @@ -1962,8 +1862,7 @@ irqreturn_t vdin_isr(int irq, void *dev_id) if ((devp->frame_cnt >= game_mode_switch_frames) && (devp->game_mode & VDIN_GAME_MODE_SWITCH_EN)) { if (vdin_dbg_en) { - pr_info( - "switch game mode (%d-->5), frame_cnt=%d\n", + pr_info("switch game mode (%d-->5), frame_cnt=%d\n", devp->game_mode, devp->frame_cnt); } devp->game_mode = (VDIN_GAME_MODE_0 | VDIN_GAME_MODE_2); @@ -1988,6 +1887,7 @@ irqreturn_t vdin_isr(int irq, void *dev_id) } devp->curr_wr_vfe = next_wr_vfe; + next_wr_vfe->vf.type = vdin_get_curr_field_type(devp); /* debug for video latency */ next_wr_vfe->vf.ready_jiffies64 = jiffies_64; next_wr_vfe->vf.ready_clock[0] = sched_clock(); @@ -1995,71 +1895,16 @@ irqreturn_t vdin_isr(int irq, void *dev_id) if (!(devp->flags&VDIN_FLAG_RDMA_ENABLE) || (devp->game_mode & VDIN_GAME_MODE_1)) { /* not RDMA, or game mode 1 */ - if ((devp->index == 1) && (tl1_vdin1_preview_flag == 1)) { - //if (vdin_dbg_en) - //pr_info("vdin1 preview dont notify receiver.\n"); - } else { #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - if (((devp->dv.dolby_input & (1 << devp->index)) || - (devp->dv.dv_flag && is_dolby_vision_enable())) - && (devp->dv.dv_config == true)) - vf_notify_receiver("dv_vdin", - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - else { -#endif - if (vdin_skip_frame_check(devp)) { - devp->vdin_irq_flag = 17; - if (skip_frame_debug) { - pr_info("vdin.%d: vdin_irq_flag=%d\n", - devp->index, - devp->vdin_irq_flag); - } - vdin_drop_cnt++; - } else { - vf_notify_receiver(devp->name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - } -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - } + if (((devp->dv.dolby_input & (1 << devp->index)) || + (devp->dv.dv_flag && is_dolby_vision_enable())) + && (devp->dv.dv_config == true)) + vf_notify_receiver("dv_vdin", + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + else { #endif - } - } else if (devp->game_mode & VDIN_GAME_MODE_2) { - /* game mode 2 */ - spin_lock_irqsave(&tl1_preview_lock, flags1); - if ((devp->index == 0) && - (tl1_vdin1_preview_flag == 1)) { - if (tl1_vdin1_data_readied == 1) { - tl1_vdin1_data_readied = 0; - next_wr_vfe->vf.canvas0Addr = - tl1_vdin1_canvas_addr; - next_wr_vfe->vf.height = - tl1_vdin1_height; - next_wr_vfe->vf.width = - tl1_vdin1_width; - tl1_vdin1_preview_ready_flag = 1; - } else { - tl1_vdin1_preview_ready_flag = 0; - } - } else if ((devp->index == 1) && - (tl1_vdin1_preview_flag == 1)) { - tl1_vdin1_canvas_addr = - next_wr_vfe->vf.canvas0Addr; - tl1_vdin1_height = - next_wr_vfe->vf.height; - tl1_vdin1_width = - next_wr_vfe->vf.width; - tl1_vdin1_data_readied = 1; - } - spin_unlock_irqrestore(&tl1_preview_lock, flags1); - provider_vf_put(next_wr_vfe, devp->vfp); - if ((devp->index == 1) && (tl1_vdin1_preview_flag == 1)) { - //if (vdin_dbg_en) - //pr_info("vdin1 preview dont notify receiver.\n"); - } else { - if (vdin_skip_frame_check(devp)) { - devp->vdin_irq_flag = 18; + if (vdin_recycle_frame_check(devp)) { + devp->vdin_irq_flag = 17; if (skip_frame_debug) { pr_info("vdin.%d: vdin_irq_flag=%d\n", devp->index, @@ -2070,15 +1915,28 @@ irqreturn_t vdin_isr(int irq, void *dev_id) vf_notify_receiver(devp->name, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - if (vdin_dbg_en) { - next_wr_vfe->vf.ready_clock[1] = - sched_clock(); - pr_info("vdin put latency %lld us.first %lld us\n", - func_div(next_wr_vfe->vf.ready_clock[1], - 1000), - func_div(next_wr_vfe->vf.ready_clock[0], - 1000)); - } + } +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + } +#endif + } else if (devp->game_mode & VDIN_GAME_MODE_2) { + /* game mode 2 */ + provider_vf_put(next_wr_vfe, devp->vfp); + if (vdin_recycle_frame_check(devp)) { + devp->vdin_irq_flag = 18; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } + vdin_drop_cnt++; + } else { + vf_notify_receiver(devp->name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + if (vdin_dbg_en) { + next_wr_vfe->vf.ready_clock[1] = sched_clock(); + pr_info("vdin put latency %lld us.first %lld us\n", + func_div(next_wr_vfe->vf.ready_clock[1], 1000), + func_div(next_wr_vfe->vf.ready_clock[0], 1000)); } } } @@ -2378,7 +2236,6 @@ static int vdin_open(struct inode *inode, struct file *file) static int vdin_release(struct inode *inode, struct file *file) { struct vdin_dev_s *devp = file->private_data; - struct vdin_dev_s *devp_vdin1 = vdin_devp[1]; if (!(devp->flags & VDIN_FLAG_FS_OPENED)) { if (vdin_dbg_en) @@ -2412,28 +2269,6 @@ static int vdin_release(struct inode *inode, struct file *file) file->private_data = NULL; - if (tl1_vdin1_preview_flag == 1) { - tl1_vdin1_preview_flag = 0; - devp_vdin1->flags &= (~VDIN_FLAG_FS_OPENED); - if (devp_vdin1->flags & VDIN_FLAG_DEC_STARTED) { - devp_vdin1->flags |= VDIN_FLAG_DEC_STOP_ISR; - vdin_stop_dec(devp_vdin1); - /* init flag */ - devp_vdin1->flags &= ~VDIN_FLAG_DEC_STOP_ISR; - /* clear the flag of decode started */ - devp_vdin1->flags &= (~VDIN_FLAG_DEC_STARTED); - } - if (devp_vdin1->flags & VDIN_FLAG_DEC_OPENED) { - vdin_close_fe(devp_vdin1); - devp_vdin1->flags &= (~VDIN_FLAG_DEC_OPENED); - } - devp_vdin1->flags &= (~VDIN_FLAG_SNOW_FLAG); - - /* free irq */ - if (devp_vdin1->flags & VDIN_FLAG_ISR_REQ) - free_irq(devp_vdin1->irq, (void *)devp_vdin1); - devp_vdin1->flags &= (~VDIN_FLAG_ISR_REQ); - } /* reset the hardware limit to vertical [0-1079] */ /* WRITE_VCBUS_REG(VPP_PREBLEND_VD1_V_START_END, 0x00000437); */ /*if (vdin_dbg_en)*/ @@ -2458,7 +2293,6 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) long ret = 0; int callmaster_status = 0; struct vdin_dev_s *devp = NULL; - struct vdin_dev_s *devp_vdin1 = NULL; void __user *argp = (void __user *)arg; struct vdin_parm_s param; ulong flags; @@ -2575,71 +2409,6 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) pr_info("TVIN_IOC_START_DEC port %s, decode started ok\n\n", tvin_port_str(devp->parm.port)); mutex_unlock(&devp->fe_lock); - - devp_vdin1 = vdin_devp[1]; - mutex_lock(&devp_vdin1->fe_lock); - if ((tl1_vdin1_preview_flag == 1) && - !(devp_vdin1->flags & VDIN_FLAG_DEC_STARTED)) { - /*msleep(150);*/ - devp_vdin1->flags |= VDIN_FLAG_FS_OPENED; - - devp_vdin1->unstable_flag = false; - devp_vdin1->parm.info.fmt = fmt; - devp_vdin1->parm.port = devp->parm.port; - devp_vdin1->parm.info.status = TVIN_SIG_STATUS_STABLE; - devp_vdin1->fmt_info_p = (struct tvin_format_s *) - tvin_get_fmt_info(fmt); - - if (!(devp_vdin1->flags & VDIN_FLAG_DEC_OPENED)) { - /*init queue*/ - init_waitqueue_head(&devp_vdin1->queue); - - ret = vdin_open_fe(devp_vdin1->parm.port, - 0, devp_vdin1); - if (ret) { - pr_err("TVIN_IOC_OPEN(%d) failed to open port 0x%x\n", - devp_vdin1->index, - devp_vdin1->parm.port); - ret = -EFAULT; - mutex_unlock(&devp_vdin1->fe_lock); - break; - } - } - - devp_vdin1->flags |= VDIN_FLAG_DEC_OPENED; - devp_vdin1->flags |= VDIN_FLAG_FORCE_RECYCLE; - - devp_vdin1->debug.scaler4w = 1280; - devp_vdin1->debug.scaler4h = 720; - /* vdin1 follow vdin0 afbc dest_cfmt */ - devp_vdin1->debug.dest_cfmt = devp->prop.dest_cfmt; - devp_vdin1->flags |= VDIN_FLAG_MANUAL_CONVERSION; - - vdin_start_dec(devp_vdin1); - devp_vdin1->flags |= VDIN_FLAG_DEC_STARTED; - - if (!(devp_vdin1->flags & VDIN_FLAG_ISR_REQ)) { - ret = request_irq(devp_vdin1->irq, vdin_isr, - IRQF_SHARED, - devp_vdin1->irq_name, - (void *)devp_vdin1); - if (ret != 0) { - pr_info("tl1_vdin1_preview request irq error.\n"); - mutex_unlock(&devp_vdin1->fe_lock); - break; - } - devp_vdin1->flags |= VDIN_FLAG_ISR_REQ; - } else { - enable_irq(devp_vdin1->irq); - if (vdin_dbg_en) - pr_info("****[%s]enable_vdin1_irq****\n", - __func__); - } - - pr_info("TVIN_IOC_START_DEC port %s, vdin1 used for preview\n", - tvin_port_str(devp_vdin1->parm.port)); - } - mutex_unlock(&devp_vdin1->fe_lock); break; } case TVIN_IOC_STOP_DEC: { @@ -2667,29 +2436,6 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) pr_info("TVIN_IOC_STOP_DEC(%d) port %s, decode stop ok\n\n", parm->index, tvin_port_str(parm->port)); - if (tl1_vdin1_preview_flag == 1) { - devp_vdin1 = vdin_devp[1]; - msleep(20); - if (!(devp_vdin1->flags & VDIN_FLAG_DEC_STARTED)) { - pr_err("TVIN_IOC_STOP_DEC(%d) decode havn't started\n", - devp_vdin1->index); - ret = -EPERM; - mutex_unlock(&devp->fe_lock); - break; - } - devp_vdin1->flags |= VDIN_FLAG_DEC_STOP_ISR; - vdin_stop_dec(devp_vdin1); - /* init flag */ - devp_vdin1->flags &= ~VDIN_FLAG_DEC_STOP_ISR; - /* devp->flags &= ~VDIN_FLAG_FORCE_UNSTABLE; */ - /* clear the flag of decode started */ - devp_vdin1->flags &= (~VDIN_FLAG_DEC_STARTED); - if (vdin_dbg_en) - pr_info("vdin1 TVIN_IOC_STOP_DEC(%d) port %s stop ok\n\n", - parm->index, - tvin_port_str(parm->port)); - } - mutex_unlock(&devp->fe_lock); reset_tvin_smr(parm->index); break; @@ -2741,24 +2487,6 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) parm->index, tvin_port_str(port)); - if (tl1_vdin1_preview_flag == 1) { - msleep(20); - devp_vdin1 = vdin_devp[1]; - tl1_vdin1_preview_flag = 0; - if (!(devp_vdin1->flags & VDIN_FLAG_DEC_OPENED)) { - pr_err("TVIN_IOC_CLOSE(%d) you have not opened port\n", - devp_vdin1->index); - ret = -EPERM; - mutex_unlock(&devp->fe_lock); - break; - } - vdin_close_fe(devp_vdin1); - devp_vdin1->flags &= (~VDIN_FLAG_DEC_OPENED); - if (vdin_dbg_en) - pr_info("vdin1 TVIN_IOC_CLOSE(%d) port %s closed ok\n\n", - parm->index, - tvin_port_str(port)); - } mutex_unlock(&devp->fe_lock); break; } @@ -3192,7 +2920,6 @@ static int vdin_drv_probe(struct platform_device *pdev) int ret = 0; struct vdin_dev_s *vdevp; struct resource *res; - unsigned int val; unsigned int urgent_en = 0; unsigned int bit_mode = VDIN_WR_COLOR_DEPTH_8BIT; /* const void *name; */ @@ -3319,30 +3046,26 @@ static int vdin_drv_probe(struct platform_device *pdev) else vdevp->color_depth_mode = 0; - /* use for tl1 vdin1 preview */ - spin_lock_init(&tl1_preview_lock); - /*set afbce mode*/ - ret = of_property_read_u32(pdev->dev.of_node, - "afbce_bit_mode", &val); - if (ret) { - vdevp->afbce_flag = 0; - } else { - vdevp->afbce_flag = val & 0xf; - vdevp->afbce_lossy_en = (val>>4)&0xf; - if ((is_meson_tl1_cpu() || is_meson_tm2_cpu()) && - (vdevp->index == 0)) { - /* just use afbce at vdin0 */ - pr_info("afbce flag = %d\n", vdevp->afbce_flag); - pr_info("afbce loosy en = %d\n", vdevp->afbce_lossy_en); + /*set afbce config*/ + vdevp->afbce_flag = 0; + if (vdevp->index == 0) { /* just use afbce at vdin0 */ + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) { vdevp->afbce_info = devm_kzalloc(vdevp->dev, sizeof(struct vdin_afbce_s), GFP_KERNEL); if (!vdevp->afbce_info) goto fail_kzalloc_vdev; - } else { - vdevp->afbce_flag = 0; - pr_info("get afbce from dts, but chip cannot support\n"); + + ret = of_property_read_u32(pdev->dev.of_node, + "afbce_bit_mode", &vdevp->afbce_flag); + if (ret) { + vdevp->afbce_flag = 0; + } else { + pr_info("afbce flag = 0x%x\n", + vdevp->afbce_flag); + } } } + /*vdin urgent en*/ ret = of_property_read_u32(pdev->dev.of_node, "urgent_en", &urgent_en); @@ -3475,6 +3198,7 @@ static int vdin_drv_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&vdevp->dv.dv_dwork, vdin_dv_dwork); INIT_DELAYED_WORK(&vdevp->vlock_dwork, vdin_vlock_dwork); + vdin_mif_config_init(vdevp); /* 2019-0425 add, ensure mif/afbc bit */ vdin_debugfs_init(vdevp);/*2018-07-18 add debugfs*/ pr_info("%s: driver initialized ok\n", __func__); return 0; diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h index 927c8c5..74d809d 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h @@ -45,7 +45,10 @@ #include "vdin_vf.h" #include "vdin_regs.h" -#define VDIN_VER "Ref.2019/03/01" +/* Ref.2019/04/25: tl1 vdin0 afbce dynamically switch support, + * vpp also should support this function + */ +#define VDIN_VER "Ref.2019/04/25" /*the counter of vdin*/ #define VDIN_MAX_DEVS 2 @@ -106,6 +109,13 @@ /*TXL new add*/ #define VDIN_WR_COLOR_DEPTH_10BIT_FULL_PCAK_MODE (1 << 4) +/* vdin afbce flag */ +#define VDIN_AFBCE_EN (1 << 0) +#define VDIN_AFBCE_EN_LOOSY (1 << 1) +#define VDIN_AFBCE_EN_4K (1 << 4) +#define VDIN_AFBCE_EN_1080P (1 << 5) +#define VDIN_AFBCE_EN_720P (1 << 6) +#define VDIN_AFBCE_EN_SMALL (1 << 7) static inline const char *vdin_fmt_convert_str( enum vdin_format_convert_e fmt_cvt) @@ -329,15 +339,26 @@ struct vdin_dev_s { * 1: use afbce non-mmu mode: head/body addr set by code * 2: use afbce mmu mode: head set by code, body addr assigning by hw */ + /*afbce_flag: + *bit[0]: enable afbce + *bit[1]: enable afbce_loosy + *bit[4]: afbce enable for 4k + *bit[5]: afbce enable for 1080p + *bit[6]: afbce enable for 720p + *bit[7]: afbce enable for other small resolution + */ unsigned int afbce_flag; + unsigned int afbce_mode_pre; unsigned int afbce_mode; - unsigned int afbce_lossy_en; + unsigned int afbce_valid; unsigned int canvas_config_mode; bool prehsc_en; bool vshrk_en; bool urgent_en; bool black_bar_enable; bool hist_bar_enable; + unsigned int ignore_frames; + unsigned int recycle_frames; /*use frame rate to cal duraton*/ unsigned int use_frame_rate; unsigned int irq_cnt; @@ -364,12 +385,12 @@ struct vdin_v4l2_param_s { int fps; }; -extern unsigned int tl1_vdin1_preview_flag; -extern unsigned int vdin_afbc_preview_force_drop_frame_cnt; -extern unsigned int vdin_afbc_force_drop_frame_cnt; +extern unsigned int max_recycle_frame_cnt; extern unsigned int max_ignore_frame_cnt; extern unsigned int skip_frame_debug; +extern unsigned int vdin0_afbce_debug_force; + extern struct vframe_provider_s *vf_get_provider_by_name( const char *provider_name); extern bool enable_reset; @@ -409,5 +430,8 @@ extern void vdin_debugfs_exit(struct vdin_dev_s *vdevp); extern bool vlock_get_phlock_flag(void); +extern struct vdin_dev_s *vdin_get_dev(unsigned int index); +extern void vdin_mif_config_init(struct vdin_dev_s *devp); + #endif /* __TVIN_VDIN_DRV_H */ diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_vf.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_vf.c index 012163e..2bdd0e1 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_vf.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_vf.c @@ -1022,8 +1022,7 @@ void vdin_vf_disp_mode_update(struct vf_entry *vfe, struct vf_pool *p) VFRAME_DISP_MODE_SKIP) p->disp_mode[p->disp_index[p->skip_vf_num]] = VFRAME_DISP_MODE_OK; - for (i = p->skip_vf_num - 1; i < VFRAME_DISP_MAX_NUM; i--) - p->disp_mode[p->disp_index[i]] = VFRAME_DISP_MODE_UNKNOWN; + p->disp_mode[p->disp_index[0]] = VFRAME_DISP_MODE_UNKNOWN; } /*skip all from current *disp_index[i]: diff --git a/include/linux/amlogic/media/vfm/vframe.h b/include/linux/amlogic/media/vfm/vframe.h index f29ed1b..dd7c882 100644 --- a/include/linux/amlogic/media/vfm/vframe.h +++ b/include/linux/amlogic/media/vfm/vframe.h @@ -44,9 +44,11 @@ #define VIDTYPE_COMPRESS 0x100000 #define VIDTYPE_PIC 0x200000 #define VIDTYPE_SCATTER 0x400000 -#define VIDTYPE_VD2 0x800000 +#define VIDTYPE_VD2 0x800000 #define VIDTYPE_COMPRESS_LOSS 0x1000000 -#define VIDTYPE_COMB_MODE 0x2000000 +#define VIDTYPE_COMB_MODE 0x2000000 +#define VIDTYPE_NO_DW 0x4000000 +#define VIDTYPE_SUPPORT_COMPRESS 0x8000000 #define DISP_RATIO_FORCECONFIG 0x80000000 #define DISP_RATIO_FORCE_NORMALWIDE 0x40000000 diff --git a/include/linux/amlogic/media/vfm/vframe_provider.h b/include/linux/amlogic/media/vfm/vframe_provider.h index 014f163..f67776e 100644 --- a/include/linux/amlogic/media/vfm/vframe_provider.h +++ b/include/linux/amlogic/media/vfm/vframe_provider.h @@ -40,6 +40,7 @@ struct vframe_states { #define VFRAME_EVENT_RECEIVER_GET_AUX_DATA 0x80 #define VFRAME_EVENT_RECEIVER_DISP_MODE 0x100 #define VFRAME_EVENT_RECEIVER_DOLBY_BYPASS_EL 0x200 +#define VFRAME_EVENT_RECEIVER_NEED_NO_COMP 0x400 /* for VFRAME_EVENT_RECEIVER_GET_AUX_DATA*/ struct provider_aux_req_s { -- 2.7.4