blob: edfa775f5594f3add4590fb1df8b8f22b3803f9c [file] [log] [blame]
/*
* drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.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.
*
*/
/* Standard Linux headers */
#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>
/* Amlogic headers */
#include <linux/amlogic/media/vfm/vframe.h>
/* Local headers */
#include "../tvin_format_table.h"
#include "vdin_drv.h"
#include "vdin_canvas.h"
#include "vdin_ctl.h"
/*the value depending on dts config mem limit
*for skip two vframe case,need +2
*/
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_byte = PAGE_SIZE;
#ifdef DEBUG_SUPPORT
module_param(max_buf_num, uint, 0664);
MODULE_PARM_DESC(max_buf_num, "vdin max buf num.\n");
module_param(min_buf_num, uint, 0664);
MODULE_PARM_DESC(min_buf_num, "vdin min buf num.\n");
module_param(max_buf_width, uint, 0664);
MODULE_PARM_DESC(max_buf_width, "vdin max buf width.\n");
module_param(max_buf_height, uint, 0664);
MODULE_PARM_DESC(max_buf_height, "vdin max buf height.\n");
module_param(dolby_size_byte, uint, 0664);
MODULE_PARM_DESC(dolby_size_byte, "dolby_size_byte.\n");
#endif
const unsigned int vdin_canvas_ids[2][VDIN_CANVAS_MAX_CNT] = {
{
38, 39, 40, 41, 42,
43, 44, 45, 46,
},
{
47, 48, 49, 50, 51,
52, 53, 54, 55,
},
};
/*function:
* 1.set canvas_max_w & canvas_max_h
* 2.set canvas_max_size & canvas_max_num
* 3.set canvas_id & canvas_addr
*/
void vdin_canvas_init(struct vdin_dev_s *devp)
{
int i, canvas_id;
unsigned int canvas_addr;
int canvas_max_w = 0;
int canvas_max_h = VDIN_CANVAS_MAX_HEIGH;
canvas_max_w = VDIN_CANVAS_MAX_WIDTH_HD << 1;
devp->canvas_max_size = PAGE_ALIGN(canvas_max_w*canvas_max_h);
devp->canvas_max_num = devp->mem_size / devp->canvas_max_size;
if (devp->canvas_max_num > VDIN_CANVAS_MAX_CNT)
devp->canvas_max_num = VDIN_CANVAS_MAX_CNT;
devp->mem_start = roundup(devp->mem_start, devp->canvas_align);
pr_info("vdin.%d canvas initial table:\n", devp->index);
for (i = 0; i < devp->canvas_max_num; i++) {
canvas_id = vdin_canvas_ids[devp->index][i];
canvas_addr = devp->mem_start + devp->canvas_max_size * i;
canvas_config(canvas_id, canvas_addr,
canvas_max_w, canvas_max_h,
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
pr_info("\t%d: 0x%x-0x%x %dx%d (%d KB)\n",
canvas_id, canvas_addr,
(canvas_addr + devp->canvas_max_size),
canvas_max_w, canvas_max_h,
(devp->canvas_max_size >> 10));
}
}
/*function:canvas_config when canvas_config_mode=1
* 1.set canvas_w and canvas_h
* 2.set canvas_max_size and canvas_max_num
* 3.when dest_cfmt is TVIN_NV12/TVIN_NV21,
* buf width add canvas_w*canvas_h
*based on parameters:
* format_convert/ source_bitdepth/
* v_active color_depth_mode/ prop.dest_cfmt
*/
void vdin_canvas_start_config(struct vdin_dev_s *devp)
{
int i = 0;
int canvas_id;
unsigned long canvas_addr;
unsigned int chroma_size = 0;
unsigned int canvas_step = 1;
unsigned int canvas_num = VDIN_CANVAS_MAX_CNT;
unsigned int max_buffer_num = max_buf_num;
/* todo: if new add output YUV444 format,this place should add too!!*/
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)) {
if (devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH)
devp->canvas_w = max_buf_width *
VDIN_YUV444_10BIT_PER_PIXEL_BYTE;
else
devp->canvas_w = max_buf_height *
VDIN_YUV444_8BIT_PER_PIXEL_BYTE;
} else if ((devp->prop.dest_cfmt == TVIN_NV12) ||
(devp->prop.dest_cfmt == TVIN_NV21)) {
devp->canvas_w = max_buf_width;
canvas_num = canvas_num/2;
canvas_step = 2;
} else{/*YUV422*/
/* txl new add yuv422 pack mode:canvas_w=h*2*10/8*/
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))
devp->canvas_w = (max_buf_width * 5)/2;
else if ((devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) &&
(devp->color_depth_mode == 0))
devp->canvas_w = max_buf_width *
VDIN_YUV422_10BIT_PER_PIXEL_BYTE;
else
devp->canvas_w = max_buf_width *
VDIN_YUV422_8BIT_PER_PIXEL_BYTE;
}
/*backup before roundup*/
devp->canvas_active_w = devp->canvas_w;
if (devp->force_yuv444_malloc == 1) {
if ((devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) &&
(devp->color_depth_mode != 1))
devp->canvas_w = devp->h_active *
VDIN_YUV444_10BIT_PER_PIXEL_BYTE;
else
devp->canvas_w = devp->h_active *
VDIN_YUV444_8BIT_PER_PIXEL_BYTE;
}
/*canvas_w must ensure divided exact by 256bit(32byte)*/
devp->canvas_w = roundup(devp->canvas_w, devp->canvas_align);
devp->canvas_h = devp->v_active;
if ((devp->prop.dest_cfmt == TVIN_NV12) ||
(devp->prop.dest_cfmt == TVIN_NV21))
chroma_size = devp->canvas_w*devp->canvas_h/2;
devp->canvas_max_size = PAGE_ALIGN(devp->canvas_w*
devp->canvas_h+chroma_size);
devp->canvas_max_num = devp->mem_size / devp->canvas_max_size;
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->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);
#ifdef VDIN_DEBUG
pr_info("vdin%d cnavas start configuration table:\n",
devp->index);
#endif
for (i = 0; i < devp->canvas_max_num; i++) {
canvas_id = vdin_canvas_ids[devp->index][i*canvas_step];
canvas_addr = devp->mem_start +
devp->canvas_max_size * i;
canvas_config(canvas_id, canvas_addr,
devp->canvas_w, devp->canvas_h,
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
if (chroma_size)
canvas_config(canvas_id+1,
canvas_addr +
devp->canvas_w*devp->canvas_h,
devp->canvas_w,
devp->canvas_h/2,
CANVAS_ADDR_NOWRAP,
CANVAS_BLKMODE_LINEAR);
#ifdef VDIN_DEBUG
pr_info("\t%3d: 0x%lx-0x%lx %ux%u\n",
canvas_id, canvas_addr,
canvas_addr + devp->canvas_max_size,
devp->canvas_w, devp->canvas_h);
#endif
}
} else if (devp->cma_config_flag & 0x100) {
#ifdef VDIN_DEBUG
pr_info("vdin%d cnavas start configuration table:\n",
devp->index);
#endif
for (i = 0; i < devp->canvas_max_num; i++) {
devp->vfmem_start[i] =
roundup(devp->vfmem_start[i],
devp->canvas_align);
canvas_id = vdin_canvas_ids[devp->index][i*canvas_step];
canvas_addr = devp->vfmem_start[i];
canvas_config(canvas_id, canvas_addr,
devp->canvas_w, devp->canvas_h,
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
if (chroma_size)
canvas_config(canvas_id+1,
canvas_addr +
devp->canvas_w*devp->canvas_h,
devp->canvas_w,
devp->canvas_h/2,
CANVAS_ADDR_NOWRAP,
CANVAS_BLKMODE_LINEAR);
#ifdef VDIN_DEBUG
pr_info("\t%3d: 0x%lx-0x%lx %ux%u\n",
canvas_id, canvas_addr,
canvas_addr + devp->canvas_max_size,
devp->canvas_w, devp->canvas_h);
#endif
}
}
}
/*
*this function used for configure canvas when canvas_config_mode=2
*base on the input format
*also used for input resalution over 1080p such as camera input 200M,500M
*YUV422-8BIT:1pixel = 2byte;
*YUV422-10BIT:1pixel = 3byte;
*YUV422-10BIT-FULLPACK:1pixel = 2.5byte;
*YUV444-8BIT:1pixel = 3byte;
*YUV444-10BIT:1pixel = 4byte
*/
void vdin_canvas_auto_config(struct vdin_dev_s *devp)
{
int i = 0;
int canvas_id;
unsigned long canvas_addr;
unsigned int chroma_size = 0;
unsigned int canvas_step = 1;
unsigned int canvas_num = VDIN_CANVAS_MAX_CNT;
unsigned int max_buffer_num = max_buf_num;
/* todo: if new add output YUV444 format,this place should add too!!*/
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)) {
if (devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH)
devp->canvas_w = devp->h_active *
VDIN_YUV444_10BIT_PER_PIXEL_BYTE;
else
devp->canvas_w = devp->h_active *
VDIN_YUV444_8BIT_PER_PIXEL_BYTE;
} else if ((devp->prop.dest_cfmt == TVIN_NV12) ||
(devp->prop.dest_cfmt == TVIN_NV21)) {
canvas_num = canvas_num/2;
canvas_step = 2;
devp->canvas_w = devp->h_active;
/* nv21/nv12 only have 8bit mode */
} else {/*YUV422*/
/* txl new add yuv422 pack mode:canvas-w=h*2*10/8*/
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))
devp->canvas_w = (devp->h_active * 5)/2;
else if ((devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) &&
(devp->color_depth_mode == 0))
devp->canvas_w = devp->h_active *
VDIN_YUV422_10BIT_PER_PIXEL_BYTE;
else
devp->canvas_w = devp->h_active *
VDIN_YUV422_8BIT_PER_PIXEL_BYTE;
}
/*backup before roundup*/
devp->canvas_active_w = devp->canvas_w;
if (devp->force_yuv444_malloc == 1) {
if ((devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) &&
(devp->color_depth_mode != 1))
devp->canvas_w = devp->h_active *
VDIN_YUV444_10BIT_PER_PIXEL_BYTE;
else
devp->canvas_w = devp->h_active *
VDIN_YUV444_8BIT_PER_PIXEL_BYTE;
}
/*canvas_w must ensure divided exact by 256bit(32byte)*/
devp->canvas_w = roundup(devp->canvas_w, devp->canvas_align);
devp->canvas_h = devp->v_active;
if ((devp->prop.dest_cfmt == TVIN_NV12) ||
(devp->prop.dest_cfmt == TVIN_NV21))
chroma_size = devp->canvas_w*devp->canvas_h/2;
devp->canvas_max_size = PAGE_ALIGN(devp->canvas_w*
devp->canvas_h+chroma_size);
devp->canvas_max_num = devp->mem_size / devp->canvas_max_size;
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->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);
#ifdef VDIN_DEBUG
pr_info("vdin%d cnavas auto configuration table:\n",
devp->index);
#endif
for (i = 0; i < devp->canvas_max_num; i++) {
canvas_id = vdin_canvas_ids[devp->index][i*canvas_step];
canvas_addr = devp->mem_start +
devp->canvas_max_size * i;
canvas_config(canvas_id, canvas_addr,
devp->canvas_w, devp->canvas_h,
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
if (chroma_size)
canvas_config(canvas_id+1,
canvas_addr +
devp->canvas_w*devp->canvas_h,
devp->canvas_w,
devp->canvas_h/2,
CANVAS_ADDR_NOWRAP,
CANVAS_BLKMODE_LINEAR);
#ifdef VDIN_DEBUG
pr_info("\t%3d: 0x%lx-0x%lx %ux%u\n",
canvas_id, canvas_addr,
canvas_addr + devp->canvas_max_size,
devp->canvas_w, devp->canvas_h);
#endif
}
} else if (devp->cma_config_flag & 0x100) {
#ifdef VDIN_DEBUG
pr_info("vdin%d cnavas auto configuration table:\n",
devp->index);
#endif
for (i = 0; i < devp->canvas_max_num; i++) {
devp->vfmem_start[i] =
roundup(devp->vfmem_start[i],
devp->canvas_align);
canvas_id = vdin_canvas_ids[devp->index][i*canvas_step];
canvas_addr = devp->vfmem_start[i];
canvas_config(canvas_id, canvas_addr,
devp->canvas_w, devp->canvas_h,
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
if (chroma_size)
canvas_config(canvas_id+1,
canvas_addr +
devp->canvas_w*devp->canvas_h,
devp->canvas_w,
devp->canvas_h/2,
CANVAS_ADDR_NOWRAP,
CANVAS_BLKMODE_LINEAR);
#ifdef VDIN_DEBUG
pr_info("\t%3d: 0x%lx-0x%lx %ux%u\n",
canvas_id, canvas_addr,
canvas_addr + devp->canvas_max_size,
devp->canvas_w, devp->canvas_h);
#endif
}
}
}
#ifdef CONFIG_CMA
/* need to be static for pointer use in codec_mm */
static char vdin_name[6];
/* return val:1: fail;0: ok */
unsigned int vdin_cma_alloc(struct vdin_dev_s *devp)
{
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;
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;
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_byte;
devp->vfmem_size = (devp->vfmem_size/PAGE_SIZE + 1)*PAGE_SIZE;
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)
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) {
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);
if (devp->vfmem_start[i] == 0) {
pr_err("\nvdin%d buf[%d]codec alloc fail!!!\n",
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);
}
}
pr_info("vdin%d codec cma alloc ok!\n", devp->index);
devp->mem_size = mem_size;
} 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);
}
} 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 {
devp->cma_mem_alloc = 0;
pr_err("\nvdin%d cma mem undefined2.\n",
devp->index);
return 1;
}
}
devp->cma_mem_alloc = 1;
devp->mem_size = mem_size;
pr_info("vdin%d cma alloc ok!\n", devp->index);
} else {
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 {
devp->cma_mem_alloc = 0;
pr_err("\nvdin%d cma mem undefined2.\n",
devp->index);
return 1;
}
}
return 0;
}
/*this function used for codec cma release
* 1.call codec_mm_free_for_dma() or
* dma_release_from_contiguous() to relase cma;
* 2.reset mem_start & mem_size & cma_mem_alloc to 0;
*/
void vdin_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) {
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);
} else if (devp->cma_config_flag == 0x1) {
codec_mm_free_for_dma(vdin_name, devp->mem_start);
pr_info("vdin%d codec cma release ok!\n", devp->index);
} else if (devp->cma_config_flag == 0x100) {
for (i = 0; i < devp->vfmem_max_cnt; i++)
dma_release_from_contiguous(
&(devp->this_pdev->dev),
devp->vfvenc_pages[i],
devp->vfmem_size >> PAGE_SHIFT);
pr_info("vdin%d 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 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;
}
/*@20170823 new add for the case of csc change after signal stable*/
void vdin_cma_malloc_mode(struct vdin_dev_s *devp)
{
unsigned int h_size, v_size;
h_size = devp->h_active;
v_size = devp->v_active;
if ((h_size <= VDIN_YUV444_MAX_CMA_WIDTH) &&
(v_size <= VDIN_YUV444_MAX_CMA_HEIGH) &&
(devp->cma_mem_mode == 1))
devp->force_yuv444_malloc = 1;
else
devp->force_yuv444_malloc = 0;
}
#endif