vdin: add afbce function for tl1 [1/1]

PD#172587

Problem:
new added function for tl1

Solution:
add vdin afbce support for tl1

Verify:
verified on PTM

Change-Id: I5e3e2487b6cdbed2d2ca794a6a21ed885e4bf469
Signed-off-by: xuhua zhang <xuhua.zhang@amlogic.com>
This commit is contained in:
xuhua zhang
2018-10-09 17:21:14 +08:00
committed by Jianxin Pan
parent b61002d2d1
commit 831a14c310
13 changed files with 1263 additions and 47 deletions

View File

@@ -14672,3 +14672,8 @@ F: drivers\amlogic\media\vout\lcd\lcd_clk_ctrl.h
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

View File

@@ -88,7 +88,7 @@
// compatible = "shared-dma-pool";
// reusable;
/* 3840x2160x4x4 ~=128 M */
// size = <0x8000000>;
// size = <0xc400000>;
// alignment = <0x400000>;
//};
@@ -313,6 +313,12 @@
* 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 {

View File

@@ -9,3 +9,5 @@ tvin_vdin-objs += vdin_drv.o
tvin_vdin-objs += vdin_ctl.o
tvin_vdin-objs += vdin_sm.o
tvin_vdin-objs += vdin_canvas.o
tvin_vdin-objs += vdin_afbce.o

View File

@@ -0,0 +1,590 @@
/*
* 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);
}

View File

@@ -0,0 +1,313 @@
/*
* 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

View File

@@ -4327,33 +4327,4 @@ void vdin_clk_onoff(struct vdin_dev_s *devp, bool onoff)
}
}
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);
}
}
}

View File

@@ -207,8 +207,7 @@ extern enum tvin_force_color_range_e color_range_force;
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

View File

@@ -263,6 +263,8 @@ static ssize_t vdin_attr_show(struct device *dev,
"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,
@@ -368,6 +370,217 @@ static void vdin_dump_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)
{
@@ -552,6 +765,31 @@ static void vdin_dump_state(struct vdin_dev_s *devp)
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);
}
@@ -1629,6 +1867,16 @@ start_chk:
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");
}

View File

@@ -63,6 +63,7 @@
#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"
@@ -466,17 +467,30 @@ void vdin_start_dec(struct vdin_dev_s *devp)
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))
@@ -523,8 +537,14 @@ void vdin_start_dec(struct vdin_dev_s *devp)
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 &&
@@ -630,7 +650,10 @@ void vdin_stop_dec(struct vdin_dev_s *devp)
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);
@@ -1508,8 +1531,13 @@ irqreturn_t vdin_isr(int irq, void *dev_id)
}
/* 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))
@@ -1700,8 +1728,13 @@ irqreturn_t vdin_v4l2_isr(int irq, void *dev_id)
/* 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,
@@ -2471,6 +2504,25 @@ static int vdin_drv_probe(struct platform_device *pdev)
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);

View File

@@ -161,6 +161,25 @@ struct vdin_dv_s {
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;
@@ -173,6 +192,8 @@ struct vdin_dev_s {
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;
@@ -294,6 +315,12 @@ struct vdin_dev_s {
*/
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;

View File

@@ -717,6 +717,7 @@
/*g12a new add end*/
#define VDIN_WRARB_REQEN_SLV 0x12c1
/* #define VDIN_SCALE_COEF_IDX 0x1200 */
/* #define VDIN_SCALE_COEF 0x1201 */

View File

@@ -387,6 +387,7 @@ int vf_pool_init(struct vf_pool *p, int size)
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);

View File

@@ -106,6 +106,7 @@ struct vf_entry {
enum vf_status_e status;
struct list_head list;
unsigned int flag;
unsigned char af_num;/*afbce num*/
};
struct vf_pool {