From 17dbbb866ddb8fd187e87e1e1c57dd0a635abb2b Mon Sep 17 00:00:00 2001 From: zhangzhaopeng Date: Tue, 7 Jan 2025 16:13:50 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E6=B8=85=E7=A9=BAlogo=20buffer=E7=9A=84?= =?UTF-8?q?=E5=90=8C=E6=97=B6=E5=88=A0=E9=99=A4=E5=AE=9A=E6=97=B6=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../video/fbdev/sunxi/disp2/disp/dev_fb.c | 82 +++++++++++++------ 1 file changed, 57 insertions(+), 25 deletions(-) diff --git a/lichee/linux-4.9/drivers/video/fbdev/sunxi/disp2/disp/dev_fb.c b/lichee/linux-4.9/drivers/video/fbdev/sunxi/disp2/disp/dev_fb.c index 23dbe68fe..dbdb05644 100644 --- a/lichee/linux-4.9/drivers/video/fbdev/sunxi/disp2/disp/dev_fb.c +++ b/lichee/linux-4.9/drivers/video/fbdev/sunxi/disp2/disp/dev_fb.c @@ -104,18 +104,28 @@ struct fb_info_t { #define SHOW_DELAY_TIME 150 #endif #define END_DELAT_TIME 10 + +#define TIMER_STOP 0 +#define TIMER_START 1 + typedef struct { void *vaddr; size_t size; int screen_width; -} disp_ion_mem_kernel; +} disp_ion_mem_kernel_t; + +typedef struct { + unsigned char init_flag; + struct timer_list timer; + spinlock_t logo_lock; +} disp_logo_timer_info; #if defined(CONFIG_LOGO_FRONT) static uint8_t fade_out_count = 0; #endif -static disp_ion_mem_kernel pic_info; +static disp_ion_mem_kernel_t pic_info; static char __iomem *fb_dst = NULL; -static struct timer_list logo_timer; +static disp_logo_timer_info logo_timer_info = {.init_flag = TIMER_STOP}; static int sunxi_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg); /* H */ @@ -1704,35 +1714,43 @@ struct fb_dmabuf_export { #if defined(CONFIG_DISP2_SUNXI_KERNEL_LOAD_HAS_LOGO) static void logo_flash_callback(unsigned long data) { + unsigned long flags; + spin_lock_irqsave(&(logo_timer_info.logo_lock), flags); + if (logo_timer_info.init_flag == TIMER_STOP) + { + spin_unlock_irqrestore(&(logo_timer_info.logo_lock), flags); + return; + } + switch(data) { case 0: { flush_pic(H_LOGO_START_POS_X, H_LOGO_START_POS_Y, H_LOGO_WIDTH_PIX, H_LOGO_HEIGH_PIX, (int *)fb_dst, H_logo, 0xFFFFFFFF); // 0xFF7FD8F5 - logo_timer.expires = jiffies + msecs_to_jiffies(FLASH_DELAY_TIME); + logo_timer_info.timer.expires = jiffies + msecs_to_jiffies(FLASH_DELAY_TIME); break; } case 1: { flush_pic(A_LOGO_START_POS_X, A_LOGO_START_POS_Y, A_LOGO_WIDTH_PIX, A_LOGO_HEIGH_PIX, (int *)fb_dst, A_logo, 0xFFFFFFFF); - logo_timer.expires = jiffies + msecs_to_jiffies(FLASH_DELAY_TIME); + logo_timer_info.timer.expires = jiffies + msecs_to_jiffies(FLASH_DELAY_TIME); break; } case 2: { flush_pic(S_LOGO_START_POS_X, S_LOGO_START_POS_Y, S_LOGO_WIDTH_PIX, S_LOGO_HEIGH_PIX, (int *)fb_dst, S_logo, 0xFFFFFFFF); - logo_timer.expires = jiffies + msecs_to_jiffies(SHOW_DELAY_TIME); + logo_timer_info.timer.expires = jiffies + msecs_to_jiffies(SHOW_DELAY_TIME); break; } #if defined(CONFIG_LOGO_FRONT) case 3: { flush_pic_end(H_LOGO_START_POS_X, (H_LOGO_START_POS_Y + (fade_out_count * PICTURE_GONE_PIXEL)), (S_LOGO_START_POS_X + S_LOGO_WIDTH_PIX - H_LOGO_START_POS_X), PICTURE_GONE_PIXEL, (int *)fb_dst); - logo_timer.expires = jiffies + msecs_to_jiffies(END_DELAT_TIME); + logo_timer_info.timer.expires = jiffies + msecs_to_jiffies(END_DELAT_TIME); fade_out_count ++; if (fade_out_count < FADE_OUT_TIMES) { - logo_timer.data --; + logo_timer_info.timer.data --; } break; } @@ -1741,41 +1759,43 @@ static void logo_flash_callback(unsigned long data) case 3: { flush_pic(H_LOGO_START_POS_X, H_LOGO_START_POS_Y, H_LOGO_WIDTH_PIX, H_LOGO_HEIGH_PIX, (int *)fb_dst, H_logo, 0xFFFFEF00); // 0xFF7FD8F5 - logo_timer.expires = jiffies + msecs_to_jiffies(FLASH_DELAY_TIME); + logo_timer_info.timer.expires = jiffies + msecs_to_jiffies(FLASH_DELAY_TIME); break; } case 4: { flush_pic(H_LOGO_START_POS_X, H_LOGO_START_POS_Y, H_LOGO_WIDTH_PIX, H_LOGO_HEIGH_PIX, (int *)fb_dst, H_logo, 0xFFFFFFFF); flush_pic(A_LOGO_START_POS_X, A_LOGO_START_POS_Y, A_LOGO_WIDTH_PIX, A_LOGO_HEIGH_PIX, (int *)fb_dst, A_logo, 0xFFFFEF00); - logo_timer.expires = jiffies + msecs_to_jiffies(FLASH_DELAY_TIME); + logo_timer_info.timer.expires = jiffies + msecs_to_jiffies(FLASH_DELAY_TIME); break; } case 5: { flush_pic(A_LOGO_START_POS_X, A_LOGO_START_POS_Y, A_LOGO_WIDTH_PIX, A_LOGO_HEIGH_PIX, (int *)fb_dst, A_logo, 0xFFFFFFFF); flush_pic(S_LOGO_START_POS_X, S_LOGO_START_POS_Y, S_LOGO_WIDTH_PIX, S_LOGO_HEIGH_PIX, (int *)fb_dst, S_logo, 0xFFFFEF00); - logo_timer.expires = jiffies + msecs_to_jiffies(FLASH_DELAY_TIME); + logo_timer_info.timer.expires = jiffies + msecs_to_jiffies(FLASH_DELAY_TIME); break; } case 6: { flush_pic(S_LOGO_START_POS_X, S_LOGO_START_POS_Y, S_LOGO_WIDTH_PIX, S_LOGO_HEIGH_PIX, (int *)fb_dst, S_logo, 0xFFFFFFFF); - logo_timer.expires = jiffies + msecs_to_jiffies(FLASH_DELAY_TIME); + logo_timer_info.timer.expires = jiffies + msecs_to_jiffies(FLASH_DELAY_TIME); break; } #endif default: { - del_timer(&logo_timer); + del_timer(&(logo_timer_info.timer)); + spin_unlock_irqrestore(&(logo_timer_info.logo_lock), flags); return; } } /* flush to screen */ sunxi_fb_ioctl(g_fbi.fbinfo[0], FBIO_FLUSH_LOGO, 0); /* update timer */ - logo_timer.data ++; - add_timer(&logo_timer); + logo_timer_info.timer.data ++; + mod_timer(&(logo_timer_info.timer), logo_timer_info.timer.expires); + spin_unlock_irqrestore(&(logo_timer_info.logo_lock), flags); } #endif @@ -2057,12 +2077,19 @@ static int sunxi_fb_ioctl(struct fb_info *info, unsigned int cmd, } case FBIO_CLEAN_LOGO: { - // TODO: delete timer with mutex #if defined(CONFIG_ION_SUNXI) - flush_pic(H_LOGO_START_POS_X, H_LOGO_START_POS_Y, H_LOGO_WIDTH_PIX, H_LOGO_HEIGH_PIX, (int *)fb_dst, H_logo, 0); - flush_pic(A_LOGO_START_POS_X, A_LOGO_START_POS_Y, A_LOGO_WIDTH_PIX, A_LOGO_HEIGH_PIX, (int *)fb_dst, A_logo, 0); - flush_pic(S_LOGO_START_POS_X, S_LOGO_START_POS_Y, S_LOGO_WIDTH_PIX, S_LOGO_HEIGH_PIX, (int *)fb_dst, S_logo, 0); - disp_ion_flush_cache((void *)pic_info.vaddr, pic_info.size); + unsigned long flags; + if(logo_timer_info.init_flag == TIMER_START) + { + spin_lock_irqsave(&(logo_timer_info.logo_lock), flags); + del_timer(&(logo_timer_info.timer)); + flush_pic(H_LOGO_START_POS_X, H_LOGO_START_POS_Y, H_LOGO_WIDTH_PIX, H_LOGO_HEIGH_PIX, (int *)fb_dst, H_logo, 0); + flush_pic(A_LOGO_START_POS_X, A_LOGO_START_POS_Y, A_LOGO_WIDTH_PIX, A_LOGO_HEIGH_PIX, (int *)fb_dst, A_logo, 0); + flush_pic(S_LOGO_START_POS_X, S_LOGO_START_POS_Y, S_LOGO_WIDTH_PIX, S_LOGO_HEIGH_PIX, (int *)fb_dst, S_logo, 0); + disp_ion_flush_cache((void *)pic_info.vaddr, pic_info.size); + logo_timer_info.init_flag = TIMER_STOP; + spin_unlock_irqrestore(&(logo_timer_info.logo_lock), flags); + } #endif break; } @@ -3199,6 +3226,9 @@ s32 fb_init(struct platform_device *pdev) s32 value = 0; char primary_key[20]; sprintf(primary_key, "eink"); +#endif +#if defined(CONFIG_DISP2_SUNXI_KERNEL_LOAD_HAS_LOGO) + unsigned long flags; #endif /* struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 }; */ @@ -3350,9 +3380,9 @@ s32 fb_init(struct platform_device *pdev) /* TODO:judge pic width must less than screen width */ fb_dst = g_fbi.fbinfo[i]->screen_base; /* TODO: fb_dst shuold be static char __iomem *fb_dst[SUNXI_FB_MAX]; fb_dst = g_fbi.fbinfo[i]->screen_base; */ - init_timer(&logo_timer); - logo_timer.function = logo_flash_callback; - logo_timer.data = 0; // count + init_timer(&(logo_timer_info.timer)); + logo_timer_info.timer.function = logo_flash_callback; + logo_timer_info.timer.data = 0; // count if ((fb_para.width < (S_LOGO_START_POS_X + S_LOGO_WIDTH_PIX - H_LOGO_START_POS_X)) || fb_para.height < (S_LOGO_START_POS_Y + S_LOGO_HEIGH_PIX)) { @@ -3360,8 +3390,10 @@ s32 fb_init(struct platform_device *pdev) printk(KERN_EMERG "logo is larger than sreen size, x:%d Y:%d\n", fb_para.width, fb_para.height); } - logo_timer.expires = jiffies + msecs_to_jiffies(START_DELAY_TIME); - add_timer(&logo_timer); + logo_timer_info.timer.expires = jiffies + msecs_to_jiffies(START_DELAY_TIME); + spin_lock_init(&(logo_timer_info.logo_lock)); + logo_timer_info.init_flag = TIMER_START; + add_timer(&(logo_timer_info.timer)); pic_info.vaddr = &(fb_dst[(fb_para.width * H_LOGO_START_POS_Y + H_LOGO_START_POS_X) * sizeof(int)]); /* size:two buffer ARGB with the whole logo size*/