F: drivers\amlogic\media\vout\lcd\lcd_debug.h
F: drivers\amlogic\media\vout\lcd\lcd_tcon.c
F: drivers\amlogic\media\vout\lcd\lcd_tcon.h
+
+AMLOGIC VDIN DRIVERS
+M: Xuhua Zhang <xuhua.zhang@amlogic.com>
+F: drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c
+F: drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h
// compatible = "shared-dma-pool";
// reusable;
/* 3840x2160x4x4 ~=128 M */
- // size = <0x8000000>;
+ // size = <0xc400000>;
// alignment = <0x400000>;
//};
* bit9:use 10bit at 4k_50/60hz_10bit
*/
tv_bit_mode = <0x215>;
+ /* afbce_bit_mode: (amlogic frame buff compression encoder)
+ * 0: normal mode, not use afbce
+ * 1: use afbce non-mmu mode
+ * 2: use afbce mmu mode
+ */
+ afbce_bit_mode = <0>;
};
vdin@1 {
tvin_vdin-objs += vdin_ctl.o
tvin_vdin-objs += vdin_sm.o
tvin_vdin-objs += vdin_canvas.o
+tvin_vdin-objs += vdin_afbce.o
+
--- /dev/null
+/*
+ * drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+/******************** READ ME ************************
+ *
+ * at afbce mode, 1 block = 32 * 4 pixel
+ * there is a header in one block.
+ * for example at 1080p,
+ * header nembers = block nembers = 1920 * 1080 / (32 * 4)
+ *
+ * table map(only at non-mmu mode):
+ * afbce data was saved at "body" region,
+ * body region has been divided for every 4K(4096 bytes) and 4K unit,
+ * table map contents is : (body addr >> 12)
+ *
+ * at non-mmu mode(just vdin non-mmu mode):
+ * ------------------------------
+ * header
+ * (can analysis body addr)
+ * ------------------------------
+ * table map
+ * (save body addr)
+ * ------------------------------
+ * body
+ * (save afbce data)
+ * ------------------------------
+ */
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/cma.h>
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/dma-contiguous.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/slab.h>
+#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
+#include "../tvin_global.h"
+#include "../tvin_format_table.h"
+#include "vdin_ctl.h"
+#include "vdin_regs.h"
+#include "vdin_drv.h"
+#include "vdin_vf.h"
+#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)
+{
+ 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_CPU;
+ unsigned int max_buffer_num = min_buf_num;
+ unsigned int i;
+ /*afbce head need 1036800 byte at most*/
+ unsigned int afbce_head_size_byte = PAGE_SIZE * 300;/*1.2M*/
+ /*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 afbce_head_phy_addr;
+ //unsigned long afbce_table_phy_addr;
+ 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 */
+ } 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 = roundup(devp->h_active * devp->v_active, 128);
+ /*h_active * v_active / 128 * 4 = frame_head_size*/
+ frame_head_size = devp->h_active * devp->v_active / 32;
+ frame_head_size = PAGE_ALIGN(frame_head_size);
+
+ 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 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)
+{
+ 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;
+}
+
+void vdin_write_mif_or_afbce(struct vdin_dev_s *devp,
+ enum vdin_output_mif_e sel)
+{
+ unsigned int offset = devp->addr_offset;
+
+ if (offset == 0) {
+ if (sel == VDIN_OUTPUT_TO_MIF) {
+ 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);
+ } else if (sel == VDIN_OUTPUT_TO_AFBCE) {
+ W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_MIF_ENABLE_BIT, 1);
+ W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN0_OUT_MIF_BIT, 1);
+ W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_OUT_AFBCE_BIT, 1);
+ }
+ } 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);
+ }
+ }
+}
+
+static void afbce_wr(uint32_t reg, const uint32_t val)
+{
+ wr(0, reg, val);
+}
+
+void vdin_afbce_config(struct vdin_dev_s *devp)
+{
+ unsigned int offset = devp->addr_offset;
+ int hold_line_num = 4;
+ int lbuf_depth = 256;
+ int lossy_luma_en = 0;
+ int lossy_chrm_en = 0;
+ int cur_mmu_used = 0;
+ int reg_format_mode;//0:444 1:422 2:420
+ int reg_fmt444_comb;
+ int sblk_num;
+ int uncmp_bits;
+ int uncmp_size;
+ int def_color_0 = 0;
+ int def_color_1 = 0;
+ int def_color_2 = 0;
+ int def_color_3 = 0;
+ int hblksize_out = (devp->h_active + 31) >> 5;
+ int vblksize_out = (devp->v_active + 3) >> 2;
+ int blk_out_end_h;//output blk scope
+ int blk_out_bgn_h;//output blk scope
+ int blk_out_end_v;//output blk scope
+ int blk_out_bgn_v;//output blk scope
+ int enc_win_bgn_h;//input scope
+ int enc_win_end_h;//input scope
+ 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");
+ return;
+ }
+
+ enc_win_bgn_h = 0;
+ enc_win_end_h = devp->h_active - 1;
+ enc_win_bgn_v = 0;
+ enc_win_end_v = devp->v_active - 1;
+
+ blk_out_end_h = enc_win_bgn_h >> 5 ;//output blk scope
+ blk_out_bgn_h = (enc_win_end_h+31) >> 5 ;//output blk scope
+ blk_out_end_v = enc_win_bgn_v >> 2 ;//output blk scope
+ blk_out_bgn_v = (enc_win_end_v + 3) >> 2 ;//output blk scope
+
+ if ((devp->prop.dest_cfmt == TVIN_YUV444) && (devp->h_active > 2048))
+ reg_fmt444_comb = 1;
+ else
+ reg_fmt444_comb = 0;
+
+ if ((devp->prop.dest_cfmt == TVIN_NV12) ||
+ (devp->prop.dest_cfmt == TVIN_NV21)) {
+ reg_format_mode = 2;
+ sblk_num = 12;
+ } else if ((devp->prop.dest_cfmt == TVIN_YUV422) ||
+ (devp->prop.dest_cfmt == TVIN_YUYV422) ||
+ (devp->prop.dest_cfmt == TVIN_YVYU422) ||
+ (devp->prop.dest_cfmt == TVIN_UYVY422) ||
+ (devp->prop.dest_cfmt == TVIN_VYUY422)) {
+ reg_format_mode = 1;
+ sblk_num = 16;
+ } else {
+ reg_format_mode = 0;
+ sblk_num = 24;
+ }
+ uncmp_bits = devp->source_bitdepth;
+
+ //bit size of uncompression mode
+ uncmp_size = (((((16*uncmp_bits*sblk_num)+7)>>3)+31)/32)<<1;
+
+ 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
+
+ afbce_wr(AFBCE_MODE,
+ (0 & 0x7) << 29 | (0 & 0x3) << 26 | (3 & 0x3) << 24 |
+ (hold_line_num & 0x7f) << 16 |
+ (2 & 0x3) << 14 | (reg_fmt444_comb & 0x1));
+
+ 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
+
+ afbce_wr(AFBCE_SIZE_IN,
+ ((devp->h_active & 0x1fff) << 16) | // hsize_in of afbc input
+ ((devp->v_active & 0x1fff) << 0) // vsize_in of afbc input
+ );
+
+ afbce_wr(AFBCE_BLK_SIZE_IN,
+ ((hblksize_out & 0x1fff) << 16) | // out blk hsize
+ ((vblksize_out & 0x1fff) << 0) // out blk vsize
+ );
+
+ //head addr of compressed data
+ afbce_wr(AFBCE_HEAD_BADDR, devp->afbce_info->fm_head_paddr[0]);
+
+ 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
+ afbce_wr(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
+ afbce_wr(AFBCE_PIXEL_IN_VER_SCOPE,
+ ((enc_win_end_v & 0x1fff) << 16) |
+ ((enc_win_bgn_v & 0x1fff) << 0));
+
+ afbce_wr(AFBCE_CONV_CTRL, lbuf_depth);//fix 256
+
+ afbce_wr(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
+ );
+
+ afbce_wr(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
+ );
+
+ afbce_wr(AFBCE_FORMAT,
+ (reg_format_mode & 0x3) << 8 |
+ (uncmp_bits & 0xf) << 4 |
+ (uncmp_bits & 0xf));
+
+ afbce_wr(AFBCE_DEFCOLOR_1,
+ ((def_color_3 & 0xfff) << 12) | // def_color_a
+ ((def_color_0 & 0xfff) << 0) // def_color_y
+ );
+
+ afbce_wr(AFBCE_DEFCOLOR_2,
+ ((def_color_2 & 0xfff) << 12) | // def_color_v
+ ((def_color_1 & 0xfff) << 0) // def_color_u
+ );
+
+ //cur_mmu_used += Rd(AFBCE_MMU_NUM); //4k addr have used in every frame;
+
+ 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);
+
+ W_VCBUS_BIT(AFBCE_ENABLE, 1, 8, 1);//enable afbce
+}
+
+void vdin_afbce_maptable_init(struct vdin_dev_s *devp)
+{
+ unsigned int i, j;
+ unsigned int *ptable = NULL;
+ unsigned int *vtable = NULL;
+ unsigned int body;
+ unsigned int size;
+
+ size = roundup(devp->afbce_info->frame_body_size, 4096);
+
+ for (i = 0; i < devp->vfmem_max_cnt; i++) {
+ ptable = (unsigned int *)
+ (devp->afbce_info->fm_table_paddr[i]&0xffffffff);
+ if (devp->cma_config_flag == 0x101)
+ vtable = codec_mm_phys_to_virt((unsigned long)ptable);
+ else if (devp->cma_config_flag == 0)
+ vtable = phys_to_virt((unsigned long)ptable);
+
+ body = devp->afbce_info->fm_body_paddr[i]&0xffffffff;
+ for (j = 0; j < size; j += 4096) {
+ *vtable = ((j + body) >> 12) & 0x000fffff;
+ vtable++;
+ }
+ }
+}
+
+void vdin_afbce_set_next_frame(struct vdin_dev_s *devp,
+ unsigned int rdma_enable, struct vf_entry *vfe)
+{
+ unsigned char i;
+ unsigned int cur_mmu_used;
+
+ i = vfe->af_num;
+ cur_mmu_used = devp->afbce_info->fm_table_paddr[i] / 4;
+
+#ifdef CONFIG_AML_RDMA
+ if (rdma_enable)
+ rdma_write_reg_bits(devp->rdma_handle,
+ AFBCE_HEAD_BADDR, devp->afbce_info->fm_head_paddr[i]);
+ rdma_write_reg(devp->rdma_handle,
+ AFBCE_MMU_RMIF_SCOPE_X, cur_mmu_used, 0, 12);
+ else
+#endif
+ afbce_wr(AFBCE_HEAD_BADDR, devp->afbce_info->fm_head_paddr[i]);
+ W_VCBUS_BIT(AFBCE_MMU_RMIF_SCOPE_X, cur_mmu_used, 0, 12);
+}
+
--- /dev/null
+/*
+ * drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __VDIN_AFBCE_H__
+#define __VDIN_AFBCE_H__
+#include "vdin_drv.h"
+#include "vdin_ctl.h"
+
+#define AFBCE_ENABLE 0x41a0
+//Bit 31:13, reserved
+//Bit 12 , reg_clk_en default = 1,
+//Bit 11:9, reserved
+//Bit 8, enc_enable default = 0
+//Bit 7:1, reserved
+//Bit 0, enc_frm_start default = 0,
+
+#define AFBCE_MODE 0x41a1
+//Bit 31:29, soft_rst default = 0 ,the use as go_field
+//Bit 28, reserved
+//Bit 27:26, rev_mode default = 0 , reverse mode
+//Bit 25:24, mif_urgent default = 3 , info mif and data mif urgent
+//Bit 23, reserved
+//Bit 22:16, hold_line_num default = 4, 0: burst1 1:burst2 2:burst4
+//Bit 15:14, burst_mode default = 1, 0: burst1 1:burst2 2:burst4
+//Bit 13:0, reserved
+
+#define AFBCE_SIZE_IN 0x41a2
+//Bit 31:29, reserved
+//Bit 28:16 hsize_in default = 1920,pic horz size in.unit: pixel
+//Bit 15:13, reserved
+//Bit 12:0, vsize_in default = 1080,pic vert size in.unit: pixel
+
+#define AFBCE_BLK_SIZE_IN 0x41a3
+//Bit 31:29, reserved
+//Bit 28:16 hblk_size default = 60 , pic horz size in.unit: pixel
+//Bit 15:13, reserved
+//Bit 12:0, vblk_size default = 270, pic vert size in.unit: pixel
+
+#define AFBCE_HEAD_BADDR 0x41a4
+//Bit 31:0, head_baddr unsigned, default = 32'h00;
+
+#define AFBCE_MIF_SIZE 0x41a5
+//Bit 31:30, reserved
+//Bit 29:28, ddr_blk_size unsigned, default = 32'h128;
+//Bit 27, reserved
+//Bit 26:24, cmd_blk_size unsigned, default = 32'h128;
+//Bit 23:21, reserved
+//Bit 20:16, uncmp_size unsigned, default = 32'h128;
+//Bit 15:13, reserved
+//Bit 12:0, mmu_page_size unsigned, default = 32'h4096;
+
+#define AFBCE_PIXEL_IN_HOR_SCOPE 0x41a6
+//Bit 31:29, reserved
+//Bit 28:16, enc_win_end_h unsigned, default = 1919
+//Bit 15:13, reserved
+//Bit 12:0, enc_win_bgn_h unsigned, default = 0
+
+#define AFBCE_PIXEL_IN_VER_SCOPE 0x41a7
+//Bit 31:29, reserved
+//Bit 28:16, enc_win_end_v unsigned, default = 1079
+//Bit 15:13, reserved
+//Bit 12:0, enc_win_bgn_v unsigned, default = 0
+
+#define AFBCE_CONV_CTRL 0x41a8
+//Bit 31:12, reserved
+//Bit 11: 0, lbuf_depth default = 256, unit=16 pixel need to set = 2^n
+
+#define AFBCE_MIF_HOR_SCOPE 0x41a9
+//Bit 31:26, reserved
+//Bit 25:16, blk_end_h unsigned, default = 0
+//Bit 15:10, reserved
+//Bit 9:0, blk_bgn_h unsigned, default = 59
+
+#define AFBCE_MIF_VER_SCOPE 0x41aa
+//Bit 31:28, reserved
+//Bit 27:16, blk_end_v unsigned, default = 0
+//Bit 15:12, reserved
+//Bit 11:0, blk_bgn_v unsigned, default = 269
+
+#define AFBCE_STAT1 0x41ab
+//Bit 31, ro_frm_end_pulse1 unsigned, default = 0;frame end status
+//Bit 30:0, ro_dbg_top_info1 unsigned, default = 0;
+
+#define AFBCE_STAT2 0x41ac
+//Bit 31, reserved unsigned, default = 0;frame end status
+//Bit 30:0, ro_dbg_top_info2 unsigned, default = 0
+
+#define AFBCE_FORMAT 0x41ad
+//Bit 31:12 reserved
+//Bit 11 reserved
+//Bit 10 reg_inp_yuv default = 1
+// input is with yuv instead of rgb: 0: rgb, 1:yuv
+//Bit 9 reg_inp_422 default = 0
+// input is with yuv422 instead of 444. 0: yuv444/yuv420; 1:yuv422
+//Bit 8 reg_inp_420 default = 1
+// input is with yuv420 instead of 444. 0: yuv444/yuv422; 1:yuv420
+//Bit 7: 4 reg_bly default = 10 luma bitwidth
+//Bit 3: 0 reg_blc default = 10 chroma bitwidth
+
+#define AFBCE_MODE_EN 0x41ae
+//Bit 31:28 reserved
+//Bit 27:26 reserved
+//Bit 25 reg_adpt_interleave_ymode
+// RW, default = 0 force 0 to disable it: no HW implementation
+//Bit 24 reg_adpt_interleave_cmode
+// RW, default = 0 force 0 to disable it: not HW implementation
+//Bit 23 reg_adpt_yinterleave_luma_ride
+// RW, default = 1 vertical interleave piece luma reorder ride;
+// 0: no reorder ride; 1: w/4 as ride
+//Bit 22 reg_adpt_yinterleave_chrm_ride
+// RW, default = 1 vertical interleave piece chroma reorder ride;
+// 0: no reorder ride; 1: w/2 as ride
+//Bit 21 reg_adpt_xinterleave_luma_ride
+// RW, default = 1 vertical interleave piece luma reorder ride;
+// 0: no reorder ride; 1: w/4 as ride
+//Bit 20 reg_adpt_xinterleave_chrm_ride
+// RW, default = 1 vertical interleave piece chroma reorder ride;
+// 0: no reorder ride; 1: w/2 as ride
+//Bit 19 reserved
+//Bit 18 reg_disable_order_mode_i_6
+// RW, default = 0 disable order mode0~6: each mode with one
+// disable bit: 0: no disable, 1: disable
+//Bit 17 reg_disable_order_mode_i_5
+// RW, default = 0 disable order mode0~6: each mode with one
+// disable bit: 0: no disable, 1: disable
+//Bit 16 reg_disable_order_mode_i_4
+// RW, default = 0 disable order mode0~6: each mode with one
+// disable bit: 0: no disable, 1: disable
+//Bit 15 reg_disable_order_mode_i_3
+// RW, default = 0 disable order mode0~6: each mode with one
+// disable bit: 0: no disable, 1: disable
+//Bit 14 reg_disable_order_mode_i_2
+// RW, default = 0 disable order mode0~6: each mode with one
+// disable bit: 0: no disable, 1: disable
+//Bit 13 reg_disable_order_mode_i_1
+// RW, default = 0 disable order mode0~6: each mode with one
+// disable bit: 0: no disable, 1: disable
+//Bit 12 reg_disable_order_mode_i_0
+// RW, default = 0 disable order mode0~6: each mode with one
+// disable bit: 0: no disable, 1: disable
+//Bit 11 reserved
+//Bit 10 reg_minval_yenc_en
+// RW, default = 0 force disable,
+// final decision to remove this ws 1% performance loss
+//Bit 9 reg_16x4block_enable
+// RW, default = 0 block as mission, but permit 16x4 block
+//Bit 8 reg_uncompress_split_mode
+// RW, default = 0 0: no split; 1: split
+//Bit 7: 6 reserved
+//Bit 5 reg_input_padding_uv128
+// RW, default = 0 input picture 32x4
+// block gap mode: 0: pad uv=0; 1: pad uv=128
+//Bit 4 reg_dwds_padding_uv128
+// RW, default = 0 downsampled image for double write 32x gap mode
+// 0: pad uv=0; 1: pad uv=128
+//Bit 3: 1 reg_force_order_mode_value
+// RW, default = 0 force order mode 0~7
+//Bit 0 reg_force_order_mode_en
+// RW, default = 0 force order mode enable
+// 0: no force; 1: forced to force_value
+
+#define AFBCE_DWSCALAR 0x41af
+//Bit 31: 8 reserved
+//Bit 7: 6 reg_dwscalar_w0
+// RW, default = 3 horizontal 1st step scalar mode
+// 0: 1:1 no scalar; 1: 2:1 data drop (0,2,4, 6)
+// pixel kept; 2: 2:1 data drop (1, 3, 5,7..) pixels kept; 3: avg
+//Bit 5: 4 reg_dwscalar_w1
+// RW, default = 0 horizontal 2nd step scalar mode
+// 0: 1:1 no scalar; 1: 2:1 data drop (0,2,4, 6) pixel kept;
+// 2: 2:1 data drop (1, 3, 5,7..) pixels kept; 3: avg
+//Bit 3: 2 reg_dwscalar_h0
+// RW, default = 2 vertical 1st step scalar mode
+// 0: 1:1 no scalar; 1: 2:1 data drop (0,2,4, 6) pixel kept
+// 2: 2:1 data drop (1, 3, 5,7..) pixels kept; 3: avg
+//Bit 1: 0 reg_dwscalar_h1
+// RW, default = 3 vertical 2nd step scalar mode
+// 0: 1:1 no scalar; 1: 2:1 data drop (0,2,4, 6) pixel kept
+// 2: 2:1 data drop (1, 3, 5,7..) pixels kept; 3: avg
+
+#define AFBCE_DEFCOLOR_1 0x41b0
+//Bit 31:24 reserved
+//Bit 23:12 reg_enc_defalutcolor_3
+// RW, default = 4095 Picture wise default color value in [Y Cb Cr]
+//Bit 11: 0 reg_enc_defalutcolor_0
+// RW, default = 4095 Picture wise default color value in [Y Cb Cr]
+
+#define AFBCE_DEFCOLOR_2 0x41b1
+//Bit 31:24 reserved
+//Bit 23:12 reg_enc_defalutcolor_2
+// RW, default = 2048 wise default color value in [Y Cb Cr]
+//Bit 11: 0 reg_enc_defalutcolor_1
+// RW, default = 2048 wise default color value in [Y Cb Cr]
+
+#define AFBCE_QUANT_ENABLE 0x41b2
+//Bit 31:10 reserved
+//Bit 9: 8 reg_bcleav_ofst
+// RW, default = 0 bcleave ofset to get lower range,
+// especially under lossy, for v1/v2, x=0 is equivalent, default = -1;
+//Bit 7: 5 reserved
+//Bit 4 reg_quant_enable_1
+// RW, default = 0 enable for quant to get some lossy
+//Bit 3: 1 reserved
+//Bit 0 reg_quant_enable_0
+// RW, default = 0 enable for quant to get some lossy
+
+#define AFBCE_IQUANT_LUT_1 0x41b3
+#define AFBCE_IQUANT_LUT_2 0x41b4
+#define AFBCE_IQUANT_LUT_3 0x41b5
+#define AFBCE_IQUANT_LUT_4 0x41b6
+#define AFBCE_RQUANT_LUT_1 0x41b7
+#define AFBCE_RQUANT_LUT_2 0x41b8
+#define AFBCE_RQUANT_LUT_3 0x41b9
+#define AFBCE_RQUANT_LUT_4 0x41ba
+
+#define AFBCE_YUV_FORMAT_CONV_MODE 0x41bb
+//Bit 31: 8 reserved
+//Bit 7 reserved
+//Bit 6: 4 reg_444to422_mode RW, default = 0
+//Bit 3 reserved
+//Bit 2: 0 reg_422to420_mode RW, default = 0
+
+#define AFBCE_DUMMY_DATA 0x41bc
+//Bit 31:30 reserved
+//Bit 29: 0 reg_dummy_data RW, default = 0x00080200
+
+#define AFBCE_CLR_FLAG 0x41bd
+//Bit 31:0 reg_afbce_clr_flag default = 0
+
+#define AFBCE_STA_FLAGT 0x41be
+//Bit 31:0 ro_afbce_sta_flag default = 0
+
+#define AFBCE_MMU_NUM 0x41bf
+//Bit 31:16 reserved
+//Bit 15: 0 ro_frm_mmu_num default = 0
+
+#define AFBCE_MMU_RMIF_CTRL1 0x41c0
+//Bit 31:26 reserved
+//Bit 25:24 reg_sync_sel default = 0, axi canvas id sync with frm rst
+//Bit 23:16 reg_canvas_id default = 0, axi canvas id num
+//Bit 15 reserved
+//Bit 14:12 reg_cmd_intr_len
+// default = 1, interrupt send cmd when how many series axi cmd
+//Bit 11:10 reg_cmd_req_size
+// default = 1, how many room fifo have,
+// then axi send series req, 0=16 1=32 2=24 3=64
+//Bit 9:8 reg_burst_len
+// default = 2, burst type: 0-single 1-bst2 2-bst4
+//Bit 7 reg_swap_64bit
+// default = 0, 64bits of 128bit swap enable
+//Bit 6 reg_little_endian
+// default = 0, big endian enable
+//Bit 5 reg_y_rev default = 0, vertical reverse enable
+//Bit 4 reg_x_rev default = 0, horizontal reverse enable
+//Bit 3 reserved
+//Bit 2:0 reg_pack_mode
+// default = 3, 0:4bit 1:8bit 2:16bit 3:32bit 4:64bit 5:128bit
+
+#define AFBCE_MMU_RMIF_CTRL2 0x41c1
+//Bit 31:30 reg_sw_rst // unsigned , default = 0,
+//Bit 29:24 reserved
+//Bit 23:18 reg_gclk_ctrl
+//Bit 17 reserved
+//Bit 16:0 reg_urgent_ctrl // unsigned , default = 0, urgent control reg
+
+#define AFBCE_MMU_RMIF_CTRL3 0x41c2
+//Bit 31:17 reserved
+//Bit 16 reg_acc_mode // unsigned , default = 1
+//Bit 15:13 reserved
+//Bit 12:0 reg_stride // unsigned , default = 4096
+
+#define AFBCE_MMU_RMIF_CTRL4 0x41c3
+//Bit 31:0 reg_baddr // unsigned , default = 0
+
+#define AFBCE_MMU_RMIF_SCOPE_X 0x41c4
+//Bit 31:29 reserved
+//Bit 28:16 reg_x_end default = 4095, the canvas hor end pixel position
+//Bit 15:13 reserved
+//Bit 12: 0 reg_x_start default = 0, the canvas hor start pixel position
+
+#define AFBCE_MMU_RMIF_SCOPE_Y 0x41c5
+//Bit 31:29 reserved
+//Bit 28:16 reg_y_end default = 0, the canvas ver end pixel position
+//Bit 15:13 reserved
+//Bit 12: 0 reg_y_start default = 0, the canvas ver start pixel positio
+
+#define AFBCE_MMU_RMIF_RO_STAT 0x41c6
+
+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_config(struct vdin_dev_s *devp);
+extern void vdin_afbce_maptable_init(struct vdin_dev_s *devp);
+extern void vdin_afbce_set_next_frame(struct vdin_dev_s *devp,
+unsigned int rdma_enable, struct vf_entry *vfe);
+
+#endif
+
}
}
-void vdin_write_mif_or_afbce(struct vdin_dev_s *devp,
- enum vdin_output_mif_e sel)
-{
- unsigned int offset = devp->addr_offset;
- if (offset == 0) {
- if (sel == VDIN_OUTPUT_TO_MIF) {
- 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);
- } else if (sel == VDIN_OUTPUT_TO_AFBCE) {
- W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_MIF_ENABLE_BIT, 1);
- W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN0_OUT_MIF_BIT, 1);
- W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_OUT_AFBCE_BIT, 1);
- }
- } 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);
- }
- }
-}
extern void vdin_vlock_input_sel(unsigned int type,
enum vframe_source_type_e source_type);
-extern void vdin_write_mif_or_afbce(struct vdin_dev_s *devp,
- enum vdin_output_mif_e sel);
+
#endif
"echo rdma_irq_cnt >/sys/class/vdin/vdinx/attr.\n");
len += sprintf(buf+len,
"echo skip_vf_num 0/1/2 /sys/class/vdin/vdinx/attr.\n");
+ len += sprintf(buf+len,
+ "echo dump_afbce storage/xxx.bin >/sys/class/vdin/vdinx/attr\n");
return len;
}
static void vdin_dump_one_buf_mem(char *path, struct vdin_dev_s *devp,
set_fs(old_fs);
}
+static void vdin_dump_one_afbce_mem(char *path, struct vdin_dev_s *devp,
+ unsigned int buf_num)
+{
+ struct file *filp = NULL;
+ loff_t pos = 0;
+ void *buf_head = NULL;
+ void *buf_table = NULL;
+ void *buf_body = NULL;
+ unsigned char buff[100];
+ mm_segment_t old_fs = get_fs();
+
+ if (buf_num >= devp->canvas_max_num) {
+ pr_info("%s: param error", __func__);
+ return;
+ }
+
+ if ((devp->cma_config_flag & 0x1) &&
+ (devp->cma_mem_alloc == 0)) {
+ pr_info("%s:no cma alloc mem!!!\n", __func__);
+ return;
+ }
+
+ if (devp->cma_config_flag == 0x101) {
+ buf_head = codec_mm_phys_to_virt(
+ devp->afbce_info->fm_head_paddr[buf_num]);
+ buf_table = codec_mm_phys_to_virt(
+ devp->afbce_info->fm_table_paddr[buf_num]);
+ buf_body = codec_mm_phys_to_virt(
+ devp->afbce_info->fm_body_paddr[buf_num]);
+
+ pr_info(".head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n",
+ devp->afbce_info->fm_head_paddr[buf_num],
+ (devp->afbce_info->fm_table_paddr[buf_num]),
+ devp->afbce_info->fm_body_paddr[buf_num]);
+ } else if (devp->cma_config_flag == 0) {
+ buf_head = phys_to_virt(
+ devp->afbce_info->fm_head_paddr[buf_num]);
+ buf_table = phys_to_virt(
+ devp->afbce_info->fm_table_paddr[buf_num]);
+ buf_body = phys_to_virt(
+ devp->afbce_info->fm_body_paddr[buf_num]);
+
+ pr_info("head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n",
+ devp->afbce_info->fm_head_paddr[buf_num],
+ (devp->afbce_info->fm_table_paddr[buf_num]),
+ devp->afbce_info->fm_body_paddr[buf_num]);
+ }
+
+ set_fs(KERNEL_DS);
+
+ /*write header bin*/
+ strcpy(buff, path);
+ strcat(buff, "_1header.bin");
+ filp = filp_open(buff, O_RDWR|O_CREAT, 0666);
+ if (IS_ERR(filp)) {
+ pr_info("create %s header error.\n", buff);
+ return;
+ }
+
+ vfs_write(filp, buf_head, devp->afbce_info->frame_head_size, &pos);
+ pr_info("write buffer %2d of %2u head to %s.\n",
+ buf_num, devp->canvas_max_num, buff);
+ vfs_fsync(filp, 0);
+ filp_close(filp, NULL);
+
+ /*write table bin*/
+ pos = 0;
+ strcpy(buff, path);
+ strcat(buff, "_1table.bin");
+ filp = filp_open(buff, O_RDWR|O_CREAT, 0666);
+ if (IS_ERR(filp)) {
+ pr_info("create %s table error.\n", buff);
+ return;
+ }
+ vfs_write(filp, buf_table, devp->afbce_info->frame_table_size, &pos);
+ pr_info("write buffer %2d of %2u table to %s.\n",
+ buf_num, devp->canvas_max_num, buff);
+ vfs_fsync(filp, 0);
+ filp_close(filp, NULL);
+
+ /*write body bin*/
+ pos = 0;
+ strcpy(buff, path);
+ strcat(buff, "_1body.bin");
+ filp = filp_open(buff, O_RDWR|O_CREAT, 0666);
+ if (IS_ERR(filp)) {
+ pr_info("create %s body error.\n", buff);
+ return;
+ }
+ vfs_write(filp, buf_body, devp->afbce_info->frame_body_size, &pos);
+ pr_info("write buffer %2d of %2u body to %s.\n",
+ buf_num, devp->canvas_max_num, buff);
+ vfs_fsync(filp, 0);
+ filp_close(filp, NULL);
+
+ set_fs(old_fs);
+}
+
+static void vdin_dump_afbce_mem(char *path, struct vdin_dev_s *devp)
+{
+ struct file *filp = NULL;
+ loff_t pos = 0;
+ void *buf_head = NULL;
+ void *buf_table = NULL;
+ void *buf_body = NULL;
+ unsigned char buff[100];
+ unsigned int i;
+ mm_segment_t old_fs = get_fs();
+
+ if ((devp->cma_config_flag & 0x1) &&
+ (devp->cma_mem_alloc == 0)) {
+ pr_info("%s:no cma alloc mem!!!\n", __func__);
+ return;
+ }
+
+ if (devp->cma_config_flag == 0x101) {
+ buf_head = codec_mm_phys_to_virt(
+ devp->afbce_info->head_paddr);
+ buf_table = codec_mm_phys_to_virt(
+ devp->afbce_info->table_paddr);
+ buf_body = codec_mm_phys_to_virt(
+ devp->afbce_info->fm_body_paddr[0]);
+
+ pr_info(".head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n",
+ devp->afbce_info->head_paddr,
+ (devp->afbce_info->table_paddr),
+ devp->afbce_info->fm_body_paddr[0]);
+ } else if (devp->cma_config_flag == 0) {
+ buf_head = phys_to_virt(
+ devp->afbce_info->head_paddr);
+ buf_table = phys_to_virt(
+ devp->afbce_info->table_paddr);
+ buf_body = phys_to_virt(
+ devp->afbce_info->fm_body_paddr[0]);
+
+ pr_info("head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n",
+ devp->afbce_info->head_paddr,
+ (devp->afbce_info->table_paddr),
+ devp->afbce_info->fm_body_paddr[0]);
+ }
+
+ set_fs(KERNEL_DS);
+
+ /* write header bin start */
+ strcpy(buff, path);
+ strcat(buff, "_header.bin");
+ filp = filp_open(buff, O_RDWR|O_CREAT, 0666);
+ if (IS_ERR(filp)) {
+ pr_info("create %s header error.\n", buff);
+ return;
+ }
+
+ for (i = 0; i < devp->vfmem_max_cnt; i++) {
+ vfs_write(filp, buf_head,
+ devp->afbce_info->frame_head_size, &pos);
+ buf_head += devp->afbce_info->frame_head_size;
+ pr_info("write buffer %2d(0x%x bytes) of %2u head to %s.\n",
+ i, devp->afbce_info->frame_head_size,
+ devp->canvas_max_num, buff);
+ }
+ vfs_fsync(filp, 0);
+ filp_close(filp, NULL);
+ /* write header bin end */
+
+ /* write table bin start */
+ pos = 0;
+ strcpy(buff, path);
+ strcat(buff, "_table.bin");
+ filp = filp_open(buff, O_RDWR|O_CREAT, 0666);
+ if (IS_ERR(filp)) {
+ pr_info("create %s table error.\n", buff);
+ return;
+ }
+
+ for (i = 0; i < devp->vfmem_max_cnt; i++) {
+ vfs_write(filp, buf_table,
+ devp->afbce_info->frame_table_size, &pos);
+ buf_table += devp->afbce_info->frame_table_size;
+ pr_info("write buffer %2d(0x%x bytes) of %2u table to %s.\n",
+ i, devp->afbce_info->frame_table_size,
+ devp->canvas_max_num, buff);
+ }
+ vfs_fsync(filp, 0);
+ filp_close(filp, NULL);
+ /* write table bin end */
+
+ /* write body bin start */
+ pos = 0;
+ strcpy(buff, path);
+ strcat(buff, "_body.bin");
+ filp = filp_open(buff, O_RDWR|O_CREAT, 0666);
+ if (IS_ERR(filp)) {
+ pr_info("create %s body error.\n", buff);
+ return;
+ }
+
+ for (i = 0; i < devp->vfmem_max_cnt; i++) {
+ vfs_write(filp, buf_body,
+ devp->afbce_info->frame_body_size, &pos);
+ buf_body += devp->afbce_info->frame_body_size;
+ pr_info("write buffer %2d(0x%x bytes) of %2u body to %s.\n",
+ i, devp->afbce_info->frame_body_size,
+ devp->canvas_max_num, buff);
+ }
+ vfs_fsync(filp, 0);
+ filp_close(filp, NULL);
+ /* write body bin end */
+
+ set_fs(old_fs);
+}
+
static void dump_other_mem(char *path,
unsigned int start, unsigned int offset)
{
pr_info("dv_flag:%d;dv_config:%d,dolby_vision:%d\n",
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);
+
+ if (devp->afbce_mode == 1) {
+ for (i = 0; i < devp->vfmem_max_cnt; i++) {
+ pr_info("head(%d) addr:0x%lx, size:0x%x\n",
+ i, devp->afbce_info->fm_head_paddr[i],
+ devp->afbce_info->frame_head_size);
+ }
+ pr_info("all head size: 0x%x\n",
+ devp->afbce_info->head_size);
+
+ for (i = 0; i < devp->vfmem_max_cnt; i++) {
+ pr_info("table(%d) addr:0x%lx, size:0x%x\n",
+ i, devp->afbce_info->fm_table_paddr[i],
+ devp->afbce_info->frame_table_size);
+ }
+ pr_info("all table size: 0x%x\n",
+ devp->afbce_info->table_size);
+
+ for (i = 0; i < devp->vfmem_max_cnt; i++) {
+ pr_info("body(%d) addr:0x%lx, size:0x%x\n",
+ i, devp->afbce_info->fm_body_paddr[i],
+ devp->afbce_info->frame_body_size);
+ }
+ }
+
pr_info("Vdin driver version : %s\n", VDIN_VER);
}
pr_info("vframe_skip(%d):%d\n\n", devp->index,
devp->vfp->skip_vf_num);
}
+ } else if (!strcmp(parm[0], "dump_afbce")) {
+ if (parm[2] != NULL) {
+ unsigned int buf_num = 0;
+
+ if (kstrtol(parm[2], 10, &val) == 0)
+ buf_num = val;
+ vdin_dump_one_afbce_mem(parm[1], devp, buf_num);
+ } else if (parm[1] != NULL) {
+ vdin_dump_afbce_mem(parm[1], devp);
+ }
} else {
pr_info("unknown command\n");
}
#include "vdin_sm.h"
#include "vdin_vf.h"
#include "vdin_canvas.h"
+#include "vdin_afbce.h"
#define VDIN_DRV_NAME "vdin"
#define VDIN_DEV_NAME "vdin"
devp->parm.v_reverse);
#ifdef CONFIG_CMA
vdin_cma_malloc_mode(devp);
- if (vdin_cma_alloc(devp)) {
- pr_err("\nvdin%d %s fail for cma alloc fail!!!\n",
- devp->index, __func__);
- return;
+ 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;
+ }
}
#endif
/* h_active/v_active will be used by bellow calling */
- if (canvas_config_mode == 1)
- vdin_canvas_start_config(devp);
- else if (canvas_config_mode == 2)
- vdin_canvas_auto_config(devp);
+ 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) {
+ vdin_afbce_maptable_init(devp);
+ vdin_afbce_config(devp);
+ }
#if 0
if ((devp->prop.dest_cfmt == TVIN_NV12) ||
(devp->prop.dest_cfmt == TVIN_NV21))
vdin_hw_enable(devp->addr_offset);
vdin_set_all_regs(devp);
- if (is_meson_tl1_cpu() && (devp->index == 0))
- vdin_write_mif_or_afbce(devp, VDIN_OUTPUT_TO_MIF);
+
+ if (is_meson_tl1_cpu()) {
+ 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);
+ }
+
if (!(devp->parm.flag & TVIN_PARM_FLAG_CAP) &&
(devp->frontend) &&
devp->frontend->dec_ops &&
vf_unreg_provider(&devp->vprov);
devp->dv.dv_config = 0;
#ifdef CONFIG_CMA
- vdin_cma_release(devp);
+ if (devp->afbce_mode == 1)
+ vdin_afbce_cma_release(devp);
+ else if (devp->afbce_mode == 0)
+ vdin_cma_release(devp);
#endif
vdin_dolby_addr_release(devp, devp->vfp->size);
}
/* prepare for next input data */
next_wr_vfe = provider_vf_get(devp->vfp);
- vdin_set_canvas_id(devp, (devp->flags&VDIN_FLAG_RDMA_ENABLE),
- (next_wr_vfe->vf.canvas0Addr&0xff));
+ if (devp->afbce_mode == 0)
+ vdin_set_canvas_id(devp, (devp->flags&VDIN_FLAG_RDMA_ENABLE),
+ (next_wr_vfe->vf.canvas0Addr&0xff));
+ else if (devp->afbce_mode == 1)
+ vdin_afbce_set_next_frame(devp,
+ (devp->flags&VDIN_FLAG_RDMA_ENABLE), next_wr_vfe);
+
/* prepare for chroma canvas*/
if ((devp->prop.dest_cfmt == TVIN_NV12) ||
(devp->prop.dest_cfmt == TVIN_NV21))
/* prepare for next input data */
next_wr_vfe = provider_vf_get(devp->vfp);
- vdin_set_canvas_id(devp, (devp->flags&VDIN_FLAG_RDMA_ENABLE),
- (next_wr_vfe->vf.canvas0Addr&0xff));
+ if (devp->afbce_mode == 0)
+ vdin_set_canvas_id(devp, (devp->flags&VDIN_FLAG_RDMA_ENABLE),
+ (next_wr_vfe->vf.canvas0Addr&0xff));
+ else if (devp->afbce_mode == 1)
+ vdin_afbce_set_next_frame(devp,
+ (devp->flags&VDIN_FLAG_RDMA_ENABLE), next_wr_vfe);
+
if ((devp->prop.dest_cfmt == TVIN_NV12) ||
(devp->prop.dest_cfmt == TVIN_NV21))
vdin_set_chma_canvas_id(devp,
else
vdevp->color_depth_mode = 0;
+ /*set afbce mode*/
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "afbce_bit_mode", &vdevp->afbce_mode);
+ if (ret) {
+ vdevp->afbce_mode = 0;
+ pr_info("no afbce mode found, use normal mode\n");
+ } else {
+ if ((is_meson_tl1_cpu()) && (vdevp->index == 0)) {
+ /* just use afbce at vdin0 */
+ pr_info("afbce mode = %d\n", vdevp->afbce_mode);
+ 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_mode = 0;
+ pr_info("get afbce from dts, but chip cannot support\n");
+ }
+ }
/*vdin urgent en*/
ret = of_property_read_u32(pdev->dev.of_node,
"urgent_en", &urgent_en);
bool dv_config;
bool dv_crc_check;/*0:fail;1:ok*/
};
+
+struct vdin_afbce_s {
+ unsigned int head_size;/*all head size*/
+ unsigned int table_size;/*all table size*/
+ unsigned int frame_head_size;/*1 frame head size*/
+ unsigned int frame_table_size;/*1 frame table size*/
+ unsigned int frame_body_size;/*1 frame body size*/
+ unsigned long head_paddr;
+ unsigned long table_paddr;
+ /*every frame head addr*/
+ unsigned long fm_head_paddr[VDIN_CANVAS_MAX_CNT];
+ /*every frame tab addr*/
+ unsigned long fm_table_paddr[VDIN_CANVAS_MAX_CNT];
+ /*every body head addr*/
+ unsigned long fm_body_paddr[VDIN_CANVAS_MAX_CNT];
+ //unsigned int cur_af;/*current afbce number*/
+ //unsigned int last_af;/*last afbce number*/
+};
+
struct vdin_dev_s {
struct cdev cdev;
struct device *dev;
struct vframe_provider_s vprov;
struct vdin_dv_s dv;
+ struct vdin_afbce_s *afbce_info;
+
/* 0:from gpio A,1:from csi2 , 2:gpio B*/
enum bt_path_e bt_path;
*/
unsigned int game_mode;
unsigned int rdma_enable;
+ /* afbce_mode: (amlogic frame buff compression encoder)
+ * 0: normal mode, not use afbce
+ * 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
+ */
+ unsigned int afbce_mode;
unsigned int canvas_config_mode;
bool prehsc_en;
bool vshrk_en;
/*g12a new add end*/
+#define VDIN_WRARB_REQEN_SLV 0x12c1
/* #define VDIN_SCALE_COEF_IDX 0x1200 */
/* #define VDIN_SCALE_COEF 0x1201 */
log_state = false;
break;
}
+ master->af_num = i;
master->status = VF_STATUS_WL;
master->flag |= VF_FLAG_NORMAL_FRAME;
master->flag &= (~VF_FLAG_FREEZED_FRAME);
enum vf_status_e status;
struct list_head list;
unsigned int flag;
+ unsigned char af_num;/*afbce num*/
};
struct vf_pool {