From 80637ef9c6bb6bd9660c2ac35030a1167cde8044 Mon Sep 17 00:00:00 2001 From: Jihong Sui Date: Thu, 6 Jun 2019 14:19:09 +0800 Subject: [PATCH] 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 --- drivers/amlogic/media/deinterlace/deinterlace.c | 269 ++++++++++++++++++++++- drivers/amlogic/media/deinterlace/deinterlace.h | 10 + drivers/amlogic/media/deinterlace/nr_downscale.c | 21 ++ 3 files changed, 295 insertions(+), 5 deletions(-) diff --git a/drivers/amlogic/media/deinterlace/deinterlace.c b/drivers/amlogic/media/deinterlace/deinterlace.c index c460a31..1dfdad8 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.c +++ b/drivers/amlogic/media/deinterlace/deinterlace.c @@ -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); @@ -6210,7 +6451,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; @@ -7899,11 +8142,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)) diff --git a/drivers/amlogic/media/deinterlace/deinterlace.h b/drivers/amlogic/media/deinterlace/deinterlace.h index 964e203..e0ca3ac 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.h +++ b/drivers/amlogic/media/deinterlace/deinterlace.h @@ -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); diff --git a/drivers/amlogic/media/deinterlace/nr_downscale.c b/drivers/amlogic/media/deinterlace/nr_downscale.c index 66baf44..fe98a66 100644 --- a/drivers/amlogic/media/deinterlace/nr_downscale.c +++ b/drivers/amlogic/media/deinterlace/nr_downscale.c @@ -28,6 +28,7 @@ #include #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 -- 2.7.4