deinterace: add codec mm interface [1/1]

PD#OTT-3688

Problem:
add di when playing encrypted stream(DRM)

Solution:
1. add codec mm interface;
2. set flag_cma '4' in dts for codec mm;

Verify:
verified on u212

Change-Id: If969899e0d5a457a038660c22a1e85dedcfcb40b
Signed-off-by: Jihong Sui <jihong.sui@amlogic.com>
This commit is contained in:
Jihong Sui
2019-06-06 14:19:09 +08:00
committed by Luan Yuan
parent 06efbfe3d7
commit 3d56eaaa7d
3 changed files with 295 additions and 5 deletions

View File

@@ -1917,8 +1917,128 @@ static void config_canvas(struct di_buf_s *di_buf)
#endif
#ifdef CONFIG_CMA
/**********************************************************
* ./include/linux/amlogic/media/codec_mm/codec_mm.h:
* unsigned long codec_mm_alloc_for_dma(const char *owner,
* int page_cnt,
* int align2n,
* int memflags);
* int codec_mm_free_for_dma(const char *owner,
* unsigned long phy_addr);
* void *codec_mm_phys_to_virt(unsigned long phy_addr);
***********************************************************/
#define TVP_MEM_PAGES 0xffff
/**********************************************************
* alloc mm from codec mm
* o: out:
* return:
* true: seccuss
* false: failed
***********************************************************/
static bool mm_codec_alloc(const char *owner, size_t count,
int cma_mode,
struct di_mm_s *o)
{
int flags = 0;
bool istvp = false;
if (codec_mm_video_tvp_enabled()) {
istvp = true;
flags |= CODEC_MM_FLAGS_TVP;
} else {
flags |= CODEC_MM_FLAGS_RESERVED | CODEC_MM_FLAGS_CPU;
}
if (cma_mode == 4 && !istvp)
flags = CODEC_MM_FLAGS_CMA_FIRST |
CODEC_MM_FLAGS_CPU;
o->addr = codec_mm_alloc_for_dma(owner,
count,
0,
flags);
if (o->addr == 0) {
/*failed*/
pr_err("di:%s: failed\n", __func__);
return false;
}
if (istvp)
o->ppage = (struct page *) TVP_MEM_PAGES;
else
o->ppage = codec_mm_phys_to_virt(o->addr);
//pr_info("%s:page:0x%p,add:0x%lx\n", __func__, o->ppage, o->addr);
return true;
}
/**********************************************************
* ./include/linux/dma-contiguous.h:
* struct page *dma_alloc_from_contiguous(struct device *dev,
* size_t count,
* unsigned int order);
* bool dma_release_from_contiguous(struct device *dev,
* struct page *pages,
* int count);
*
***********************************************************/
/**********************************************************
* alloc mm by cma
* o: out:
* return:
* true: seccuss
* false: failed
***********************************************************/
static bool mm_cma_alloc(struct device *dev, size_t count,
struct di_mm_s *o)
{
o->ppage = dma_alloc_from_contiguous(dev, count, 0);
if (o->ppage) {
o->addr = page_to_phys(o->ppage);
return true;
}
pr_err("di:%s: failed\n", __func__);
return false;
}
bool di_mm_alloc(int cma_mode, size_t count, struct di_mm_s *o)
{
bool ret;
if (cma_mode == 3 || cma_mode == 4)
ret = mm_codec_alloc(DEVICE_NAME,
count,
cma_mode,
o);
else
ret = mm_cma_alloc(&(de_devp->pdev->dev), count, o);
return ret;
}
bool di_mm_release(int cma_mode,
struct page *pages,
int count,
unsigned long addr)
{
bool ret = true;
if (cma_mode == 3 || cma_mode == 4)
codec_mm_free_for_dma(DEVICE_NAME, addr);
else
ret = dma_release_from_contiguous(&(de_devp->pdev->dev),
pages,
count);
return ret;
}
/***********************************************************/
static unsigned int di_cma_alloc_total(struct di_dev_s *de_devp)
{
#if 0
de_devp->total_pages =
dma_alloc_from_contiguous(&(de_devp->pdev->dev),
de_devp->mem_size >> PAGE_SHIFT, 0);
@@ -1936,8 +2056,28 @@ static unsigned int di_cma_alloc_total(struct di_dev_s *de_devp)
}
return 0;
#else
/*****************************************************/
struct di_mm_s omm;
bool ret;
ret = di_mm_alloc(de_devp->flag_cma,
de_devp->mem_size >> PAGE_SHIFT,
&omm);
if (!ret) /*failed*/
return 0;
de_devp->total_pages = omm.ppage;
de_devp->mem_start = omm.addr;
if (de_devp->flag_cma != 0 && de_devp->nrds_enable) {
nr_ds_buf_init(de_devp->flag_cma, 0,
&(de_devp->pdev->dev));
}
return 1;
#endif
}
static bool cma_print;
@@ -1947,10 +2087,12 @@ static unsigned int di_cma_alloc(struct di_dev_s *devp)
struct di_buf_s *buf_p = NULL;
int itmp, alloc_cnt = 0;
u8 *tmp;
bool aret;
struct di_mm_s omm;
start_time = jiffies_to_msecs(jiffies);
queue_for_each_entry(buf_p, ptmp, QUEUE_LOCAL_FREE, list) {
#if 0
if (buf_p->pages == NULL) {
buf_p->pages =
dma_alloc_from_contiguous(&(devp->pdev->dev),
@@ -1973,6 +2115,34 @@ static unsigned int di_cma_alloc(struct di_dev_s *devp)
}
}
buf_p->nr_adr = page_to_phys(buf_p->pages);
#else
if (buf_p->pages != NULL) {
pr_err("di:err1:%s:buf[%d] page:0x%p alloced skip\n",
__func__, buf_p->index, buf_p->pages);
continue;
}
aret = di_mm_alloc(devp->flag_cma,
devp->buffer_size >> PAGE_SHIFT,
&omm);
if (!aret) {
buf_p->pages = NULL;
pr_err("di:err2:%s: alloc failed %d fail.\n",
__func__,
buf_p->index);
return 0;
}
buf_p->pages = omm.ppage;
buf_p->nr_adr = omm.addr;
alloc_cnt++;
if (cma_print)
pr_info("DI CMA allocate buf[%d]page:0x%p\n",
buf_p->index, buf_p->pages);
#endif
if (cma_print)
pr_info(" addr 0x%lx ok.\n", buf_p->nr_adr);
if (di_pre_stru.buf_alloc_mode == 0) {
@@ -2009,6 +2179,7 @@ static unsigned int di_cma_alloc(struct di_dev_s *devp)
}
if (post_wr_en && post_wr_support) {
queue_for_each_entry(buf_p, ptmp, QUEUE_POST_FREE, list) {
#if 0
if (buf_p->pages == NULL) {
buf_p->pages =
dma_alloc_from_contiguous(
@@ -2031,6 +2202,35 @@ static unsigned int di_cma_alloc(struct di_dev_s *devp)
buf_p->index, buf_p->pages);
}
buf_p->nr_adr = page_to_phys(buf_p->pages);
#else
if (buf_p->pages != NULL) {
pr_err("di:err3:%s:buf[%d] page:0x%p skip\n",
__func__,
buf_p->index, buf_p->pages);
continue;
}
aret = di_mm_alloc(devp->flag_cma,
devp->post_buffer_size>>PAGE_SHIFT,
&omm);
if (!aret) {
buf_p->pages = NULL;
pr_err("di:err4:%s: alloc failed %d fail.\n",
__func__,
buf_p->index);
return 0;
}
buf_p->pages = omm.ppage;
buf_p->nr_adr = omm.addr;
alloc_cnt++;
if (cma_print)
pr_info("di:%s:pbuf[%d]page:0x%p\n",
__func__,
buf_p->index, buf_p->pages);
#endif
if (cma_print)
pr_info(" addr 0x%lx ok.\n", buf_p->nr_adr);
}
@@ -2051,6 +2251,7 @@ static void di_cma_release(struct di_dev_s *devp)
{
unsigned int i, ii, rels_cnt = 0, start_time, end_time, delta_time;
struct di_buf_s *buf_p, *keep_buf;
bool ret;
keep_buf = di_post_stru.keep_buf;
start_time = jiffies_to_msecs(jiffies);
@@ -2073,7 +2274,7 @@ static void di_cma_release(struct di_dev_s *devp)
di_unmap_phyaddr((u8 *)buf_p->mcinfo_vaddr);
buf_p->bflg_vmap = false;
}
#if 0
if (dma_release_from_contiguous(&(devp->pdev->dev),
buf_p->pages,
devp->buffer_size >> PAGE_SHIFT)) {
@@ -2085,6 +2286,22 @@ static void di_cma_release(struct di_dev_s *devp)
} else {
pr_err("DI CMA release buf[%d] fail.\n", i);
}
#else
ret = di_mm_release(devp->flag_cma, buf_p->pages,
devp->buffer_size >> PAGE_SHIFT,
buf_p->nr_adr);
if (ret) {
buf_p->pages = NULL;
rels_cnt++;
if (cma_print)
pr_info(
"DI release buf[%d] ok.\n", i);
} else {
pr_err("di:err:%s:release buf[%d] fail.\n",
__func__, i);
}
#endif
} else {
if (!IS_ERR_OR_NULL(buf_p->pages) && cma_print) {
pr_info("DI buf[%d] page:0x%p no release.\n",
@@ -2095,6 +2312,7 @@ static void di_cma_release(struct di_dev_s *devp)
if (post_wr_en && post_wr_support) {
for (i = 0; i < di_post_stru.di_post_num; i++) {
buf_p = &(di_buf_post[i]);
#if 0
if (buf_p->pages != NULL) {
if (dma_release_from_contiguous(
&(devp->pdev->dev),
@@ -2111,6 +2329,28 @@ static void di_cma_release(struct di_dev_s *devp)
i);
}
}
#else
if (buf_p->pages == NULL) {
pr_err("di:err2:%s:post buf[%d] is null\n",
__func__, i);
continue;
}
ret = di_mm_release(devp->flag_cma,
buf_p->pages,
devp->post_buffer_size >> PAGE_SHIFT,
buf_p->nr_adr);
if (ret) {
buf_p->pages = NULL;
rels_cnt++;
if (cma_print)
pr_info(
"DI release post buf[%d] ok.\n", i);
} else {
pr_err("di:err:%s:release post buf[%d] fail\n",
__func__, i);
}
#endif
}
}
if (de_devp->nrds_enable) {
@@ -2312,7 +2552,8 @@ static int di_init_buf(int width, int height, unsigned char prog_flag)
}
}
#ifdef CONFIG_CMA
if (de_devp->flag_cma == 1) {
if (de_devp->flag_cma == 1 || (de_devp->flag_cma == 4) ||
(de_devp->flag_cma == 3)) {
pr_dbg("%s:cma alloc req time: %u ms\n",
__func__, jiffies_to_msecs(jiffies));
atomic_set(&de_devp->mem_flag, 0);
@@ -6211,7 +6452,9 @@ static void di_unreg_process_irq(void)
di_pre_stru.unreg_req_flag = 0;
di_pre_stru.unreg_req_flag_irq = 0;
#ifdef CONFIG_CMA
if (de_devp->flag_cma == 1) {
if (de_devp->flag_cma == 1 ||
(de_devp->flag_cma == 3) ||
(de_devp->flag_cma == 4)) {
pr_dbg("%s:cma release req time: %d ms\n",
__func__, jiffies_to_msecs(jiffies));
di_pre_stru.cma_release_req = 1;
@@ -7900,11 +8143,27 @@ static int di_probe(struct platform_device *pdev)
/*di pre h scaling down :sm1 tm2*/
di_devp->h_sc_down_en = pre_hsc_down_en;
pr_info("di:flag_cma=%d\n", di_devp->flag_cma);
if (di_devp->flag_cma >= 1) {
#ifdef CONFIG_CMA
di_devp->pdev = pdev;
di_devp->flags |= DI_MAP_FLAG;
di_devp->mem_size = dma_get_cma_size_int_byte(&pdev->dev);
if (di_devp->flag_cma == 1
|| di_devp->flag_cma == 2)
di_devp->mem_size
= dma_get_cma_size_int_byte(&pdev->dev);
if (di_devp->mem_size <= 0x800000) {
di_devp->mem_size = 0x2800000;
//(flag_cma ? 3) reserved in
//codec mm : cma in codec mm
if (di_devp->flag_cma != 3) {
//no di cma, try use
//cma from codec mm
di_devp->flag_cma = 4;
}
}
pr_info("DI: CMA size 0x%x.\n", di_devp->mem_size);
if (di_devp->flag_cma == 2) {
if (di_cma_alloc_total(di_devp))

View File

@@ -416,6 +416,16 @@ struct di_buf_pool_s {
struct di_buf_s *di_buf_ptr;
unsigned int size;
};
struct di_mm_s {
struct page *ppage;
unsigned long addr;
};
extern bool di_mm_alloc(int cma_mode, size_t count, struct di_mm_s *o);
extern bool di_mm_release(int cma_mode,
struct page *pages,
int count,
unsigned long addr);
unsigned char is_bypass(vframe_t *vf_in);

View File

@@ -28,6 +28,7 @@
#include <linux/amlogic/media/canvas/canvas_mgr.h>
#include "register.h"
#include "nr_downscale.h"
#include "deinterlace.h"
static struct nr_ds_s nrds_dev;
@@ -65,16 +66,29 @@ void nr_ds_buf_init(unsigned int cma_flag, unsigned long mem_start,
struct device *dev)
{
unsigned int i = 0;
bool ret;
struct di_mm_s omm;
if (cma_flag == 0) {
nrds_dev.nrds_addr = mem_start;
} else {
#if 0
nrds_dev.nrds_pages = dma_alloc_from_contiguous(dev,
NR_DS_PAGE_NUM, 0);
if (nrds_dev.nrds_pages)
nrds_dev.nrds_addr = page_to_phys(nrds_dev.nrds_pages);
else
pr_err("DI: alloc nr ds mem error.\n");
#else
ret = di_mm_alloc(cma_flag, NR_DS_PAGE_NUM, &omm);
if (ret) {
nrds_dev.nrds_pages = omm.ppage;
nrds_dev.nrds_addr = omm.addr;
} else {
pr_err("di:err: alloc nr ds mem error.\n");
}
#endif
}
for (i = 0; i < NR_DS_BUF_NUM; i++)
nrds_dev.buf[i] = nrds_dev.nrds_addr + (NR_DS_BUF_SIZE*i);
@@ -90,9 +104,16 @@ void nr_ds_buf_uninit(unsigned int cma_flag, struct device *dev)
nrds_dev.nrds_addr = 0;
} else {
if (nrds_dev.nrds_pages) {
#if 0
dma_release_from_contiguous(dev,
nrds_dev.nrds_pages,
NR_DS_PAGE_NUM);
#else
di_mm_release(cma_flag,
nrds_dev.nrds_pages,
NR_DS_PAGE_NUM,
nrds_dev.nrds_addr);
#endif
nrds_dev.nrds_addr = 0;
nrds_dev.nrds_pages = NULL;
} else