diff --git a/drivers/amlogic/media/video_processor/ionvideo/ionvideo.c b/drivers/amlogic/media/video_processor/ionvideo/ionvideo.c index 8d9bb9b12127..75c16de3ae76 100644 --- a/drivers/amlogic/media/video_processor/ionvideo/ionvideo.c +++ b/drivers/amlogic/media/video_processor/ionvideo/ionvideo.c @@ -1167,6 +1167,7 @@ void ionvideo_release_map(int inst) unsigned long flags; struct ionvideo_dev *dev = NULL; struct list_head *p; + bool need_release_canvas; flags = ionvideo_devlist_lock(); @@ -1179,6 +1180,17 @@ void ionvideo_release_map(int inst) } } + need_release_canvas = true; + list_for_each(p, &ionvideo_devlist) { + dev = list_entry(p, struct ionvideo_dev, ionvideo_devlist); + if (dev->mapped) { + need_release_canvas = false; + break; + } + } + if (need_release_canvas) + ionvideo_free_canvas(); + ionvideo_devlist_unlock(flags); } diff --git a/drivers/amlogic/media/video_processor/ionvideo/ionvideo.h b/drivers/amlogic/media/video_processor/ionvideo/ionvideo.h index f754d2108c98..86ead18a3167 100644 --- a/drivers/amlogic/media/video_processor/ionvideo/ionvideo.h +++ b/drivers/amlogic/media/video_processor/ionvideo/ionvideo.h @@ -48,6 +48,7 @@ #include #include +#include /* Wake up at about 30 fps */ #define WAKE_NUMERATOR 30 @@ -73,8 +74,6 @@ do { \ pr_debug("ppmgr2-dev: " fmt, ## arg); \ } while (0) -#define PPMGR2_CANVAS_INDEX_SRC (PPMGR2_CANVAS_INDEX + 3) - /* v4l2_amlogic_parm must < u8[200] */ struct v4l2_amlogic_parm { u32 signal_type; @@ -317,6 +316,8 @@ struct ionvideo_dev { unsigned int get_ionvideo_debug(void); +void ionvideo_alloc_canvas(void); +void ionvideo_free_canvas(void); int ppmgr2_init(struct ppmgr2_device *ppd); int ppmgr2_canvas_config(struct ppmgr2_device *ppd, int index); int ppmgr2_process(struct vframe_s *vf, struct ppmgr2_device *ppd, int index); diff --git a/drivers/amlogic/media/video_processor/ionvideo/ppmgr2.c b/drivers/amlogic/media/video_processor/ionvideo/ppmgr2.c index 2cd629e44206..c22f07ec432d 100644 --- a/drivers/amlogic/media/video_processor/ionvideo/ppmgr2.c +++ b/drivers/amlogic/media/video_processor/ionvideo/ppmgr2.c @@ -17,6 +17,52 @@ #include "ionvideo.h" +#define IONVIDEO_CANVAS_COUNT 5 +int ionvideo_canvas_id[IONVIDEO_CANVAS_COUNT] = {-1, -1, -1, -1, -1}; + +void ionvideo_alloc_canvas(void) +{ + const char *owner = "ionvideo"; + int i; + + if (ionvideo_canvas_id[0] != -1 && + ionvideo_canvas_id[1] != -1 && + ionvideo_canvas_id[2] != -1 && + ionvideo_canvas_id[3] != -1 && + ionvideo_canvas_id[4] != -1) + return; + + for (i = 0; i < IONVIDEO_CANVAS_COUNT; i++) { + if (ionvideo_canvas_id[i] == -1) + ionvideo_canvas_id[i] + = canvas_pool_map_alloc_canvas(owner); + } + + for (i = 0; i < IONVIDEO_CANVAS_COUNT; i++) { + if (ionvideo_canvas_id[i] == -1) { + pr_err("ionvideo_alloc_canvas %x, %x, %x, %x, %x\n", + ionvideo_canvas_id[0], + ionvideo_canvas_id[1], + ionvideo_canvas_id[2], + ionvideo_canvas_id[3], + ionvideo_canvas_id[4]); + break; + } + } +} + +void ionvideo_free_canvas(void) +{ + int i; + + for (i = 0; i < IONVIDEO_CANVAS_COUNT; i++) { + if (ionvideo_canvas_id[i] != -1) { + canvas_pool_map_free_canvas(ionvideo_canvas_id[i]); + ionvideo_canvas_id[i] = -1; + } + } +} + static inline void paint_mode_convert(int paint_mode, int *src_position, int *dst_paint_position, int *dst_plane_position) @@ -121,21 +167,21 @@ static inline void ge2d_src_config(struct vframe_s *vf, struct canvas_s src_cs0, src_cs1, src_cs2; if (vf->canvas0Addr == (u32)-1) { - canvas_config_config(PPMGR2_CANVAS_INDEX_SRC, - &src_vf.canvas0_config[0]); + canvas_config_config(ionvideo_canvas_id[2], + &src_vf.canvas0_config[0]); if (src_vf.plane_num > 1) - canvas_config_config(PPMGR2_CANVAS_INDEX_SRC + 1, - &src_vf.canvas0_config[1]); + canvas_config_config(ionvideo_canvas_id[3], + &src_vf.canvas0_config[1]); if (src_vf.plane_num > 2) - canvas_config_config(PPMGR2_CANVAS_INDEX_SRC + 2, - &src_vf.canvas0_config[2]); + canvas_config_config(ionvideo_canvas_id[4], + &src_vf.canvas0_config[2]); src_vf.canvas0Addr = - (PPMGR2_CANVAS_INDEX_SRC) - | ((PPMGR2_CANVAS_INDEX_SRC + 1) << 8) - | ((PPMGR2_CANVAS_INDEX_SRC + 2) << 16); + ionvideo_canvas_id[2] + | (ionvideo_canvas_id[3] << 8) + | (ionvideo_canvas_id[4] << 16); ge2d_config->src_planes[0].addr = src_vf.canvas0_config[0].phy_addr; @@ -409,34 +455,16 @@ int ppmgr2_canvas_config(struct ppmgr2_device *ppd, int index) if (ppd->ge2d_fmt == GE2D_FORMAT_M24_NV21 || ppd->ge2d_fmt == GE2D_FORMAT_M24_NV12) { - canvas_config(PPMGR2_CANVAS_INDEX, (ulong)phy_addr, - canvas_width, canvas_height, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); + canvas_config(ionvideo_canvas_id[0], (ulong)phy_addr, + canvas_width, canvas_height, CANVAS_ADDR_NOWRAP, + CANVAS_BLKMODE_LINEAR); canvas_config( - PPMGR2_CANVAS_INDEX + 1, + ionvideo_canvas_id[1], (ulong)(phy_addr + (canvas_width * canvas_height)), canvas_width, canvas_height >> 1, CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - ppd->canvas_id[index] = (PPMGR2_CANVAS_INDEX) - | ((PPMGR2_CANVAS_INDEX + 1) << 8); - } else if (ppd->ge2d_fmt == GE2D_FORMAT_S8_Y) { - canvas_config(PPMGR2_CANVAS_INDEX, (ulong)phy_addr, - canvas_width, canvas_height, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config( - PPMGR2_CANVAS_INDEX + 1, - (ulong)(phy_addr + canvas_width * canvas_height), - canvas_width >> 1, canvas_height >> 1, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - canvas_config( - PPMGR2_CANVAS_INDEX + 2, - (ulong)(phy_addr + (canvas_width * canvas_height * 5 - >> 2)), - canvas_width >> 1, canvas_height >> 1, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - ppd->canvas_id[index] = (PPMGR2_CANVAS_INDEX) - | ((PPMGR2_CANVAS_INDEX + 1) << 8) - | ((PPMGR2_CANVAS_INDEX + 2) << 16); + ppd->canvas_id[index] = ionvideo_canvas_id[0] + | (ionvideo_canvas_id[1] << 8); } else { int bpp = 0; @@ -451,10 +479,10 @@ int ppmgr2_canvas_config(struct ppmgr2_device *ppd, int index) ppmgr2_printk(1, "Not support format!\n"); return -1; } - canvas_config(PPMGR2_CANVAS_INDEX, (ulong)phy_addr, - canvas_width * bpp, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - ppd->canvas_id[index] = PPMGR2_CANVAS_INDEX; + canvas_config(ionvideo_canvas_id[0], (ulong)phy_addr, + canvas_width * bpp, canvas_height, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + ppd->canvas_id[index] = ionvideo_canvas_id[0]; } ppmgr2_printk(2, "canvas[%d] phy_addr:%p width:%d height:%d\n", index, @@ -504,6 +532,7 @@ int ppmgr2_process(struct vframe_s *vf, struct ppmgr2_device *ppd, int index) } mutex_lock(ppd->ge2d_canvas_mutex); + ionvideo_alloc_canvas(); ppmgr2_canvas_config(ppd, index); dst_canvas_id = ppd->canvas_id[index]; src_position[0] = 0;