@@ -429,6 +429,9 @@ static void fbtft_update_display(struct fbtft_par *par, unsigned int start_line,
429429 if (par -> pdata -> rotate == 90 )
430430 par -> fbtftops .set_addr_win (par , 80 , start_line ,
431431 320 - 1 , end_line );
432+ else if (par -> pdata -> rotate == 180 )
433+ par -> fbtftops .set_addr_win (par , 0 , 80 ,
434+ par -> info -> var .xres - 1 , 320 - 1 );
432435 else
433436 par -> fbtftops .set_addr_win (par , 0 , start_line ,
434437 par -> info -> var .xres - 1 , end_line );
@@ -575,13 +578,19 @@ void fbtft_post_process_screen(struct fbtft_par *par)
575578 screen_post_process = true;
576579 }
577580
581+ /* Get last memory buffer not written */
582+ if (par -> must_render ){
583+ par -> vmem_ptr = par -> vmem_back_buffers [par -> vmem_prev_buf_idx ];
584+ }
585+ else {
586+ par -> vmem_ptr = par -> info -> screen_buffer ;
587+ }
588+ //par->vmem_ptr = par->vmem_back_buffers[par->vmem_prev_buf_idx];
589+ //par->vmem_ptr = par->info->screen_buffer;
590+
578591 /* Post process */
579592 if (screen_post_process ) {
580- /* Change vmem ptr to send by SPI */
581- par -> vmem_ptr = par -> vmem_post_process ;
582-
583593 /* Copy buffer */
584-
585594 /*
586595 This should be handled using a double buffer (or
587596 triple depending on game fps vs screen fps) pointed
@@ -598,17 +607,22 @@ void fbtft_post_process_screen(struct fbtft_par *par)
598607 be noticed much and it takes up so little CPU that
599608 really, it's worth the compromise for now
600609 */
610+ #if 1
601611 //printk("m\n");
602612 memcpy (par -> vmem_post_process + par -> write_line_start * par -> info -> fix .line_length ,
603- par -> info -> screen_buffer + par -> write_line_start * par -> info -> fix .line_length ,
613+ par -> vmem_ptr + par -> write_line_start * par -> info -> fix .line_length ,
604614 (par -> write_line_end - par -> write_line_start + 1 ) * par -> info -> fix .line_length );
605615 //printk("n\n");
606616
617+ /* Change vmem ptr to send by SPI */
618+ par -> vmem_ptr = par -> vmem_post_process ;
619+ #endif
620+
607621 /* Notifications */
608622 if (par -> notification [0 ]) {
609623 x_notif = 0 ;
610624 y_notif = 0 ;
611- basic_text_out16_bg ((u16 * )par -> vmem_post_process , par -> info -> var .xres , par -> info -> var .yres ,
625+ basic_text_out16_bg ((u16 * )par -> vmem_ptr , par -> info -> var .xres , par -> info -> var .yres ,
612626 x_notif , y_notif , RGB565 (255 , 255 , 255 ), RGB565 (0 , 0 , 0 ), par -> notification );
613627
614628 if (y_notif < par -> write_line_start )
@@ -619,19 +633,44 @@ void fbtft_post_process_screen(struct fbtft_par *par)
619633
620634 /* Low battery icon */
621635 if (par -> low_battery ) {
622- draw_low_battery ((u16 * )par -> vmem_post_process , par -> info -> var .xres , par -> info -> var .yres );
636+ draw_low_battery ((u16 * )par -> vmem_ptr , par -> info -> var .xres , par -> info -> var .yres );
623637 }
624638
625639 /* Soft rotation */
626640 if (par -> pdata -> rotate_soft )
627- fbtft_rotate_soft ((u16 * )par -> vmem_post_process , par -> info -> var .yres , par -> pdata -> rotate_soft );
628- } else
629- par -> vmem_ptr = par -> info -> screen_buffer ;
641+ fbtft_rotate_soft ((u16 * )par -> vmem_ptr , par -> info -> var .yres , par -> pdata -> rotate_soft );
642+ }
643+ }
644+
645+ /* Copy framebuffer memory in current back buffer, then
646+ change current back buffer */
647+ void fbtft_flip_backbuffer (struct fbtft_par * par )
648+ {
649+ //spin_lock(&par->dirty_lock);
650+ memcpy (par -> vmem_back_buffers [par -> vmem_cur_buf_idx ],
651+ par -> info -> screen_buffer ,
652+ par -> vmem_size );
653+ par -> vmem_prev_buf_idx = par -> vmem_cur_buf_idx ;
654+ par -> vmem_cur_buf_idx = (par -> vmem_cur_buf_idx + 1 )%FBTFT_VMEM_BUFS ;
655+ par -> must_render ++ ;
656+ //spin_unlock(&par->dirty_lock);
657+ }
658+
659+ static void fbtft_first_io (struct fb_info * info ){
660+ /*struct fbtft_par *par = info->par;
661+ printk("f\n");*/
630662}
631663
632664static void fbtft_deferred_io (struct fb_info * info , struct list_head * pagelist )
633665{
666+
634667 struct fbtft_par * par = info -> par ;
668+
669+ /* This disables fbtft's defered io, useful in spi_async mode or
670+ if any other driver handles screens updates instead of fbtft */
671+ if (par -> spi_async_mode )
672+ return VM_FAULT_LOCKED ;
673+
635674 unsigned int dirty_lines_start , dirty_lines_end ;
636675 struct page * page ;
637676 unsigned long index ;
@@ -772,20 +811,24 @@ static struct page *fb_deferred_io_page(struct fb_info *info, unsigned long offs
772811 return page ;
773812}
774813
775- /* this is to find and return the vmalloc-ed fb pages */
814+ /* This is to find and return the vmalloc-ed fb pages */
776815static int fb_deferred_io_fault (struct vm_fault * vmf )
777816{
778817 unsigned long offset ;
779818 struct page * page ;
780819 struct fb_info * info = vmf -> vma -> vm_private_data ;
781820
782821 offset = vmf -> pgoff << PAGE_SHIFT ;
783- if (offset >= info -> fix .smem_len )
822+ if (offset >= info -> fix .smem_len ){
823+ printk ("fault\n" );
784824 return VM_FAULT_SIGBUS ;
825+ }
785826
786827 page = fb_deferred_io_page (info , offset );
787- if (!page )
828+ if (!page ){
829+ printk ("no page\n" );
788830 return VM_FAULT_SIGBUS ;
831+ }
789832
790833 get_page (page );
791834
@@ -827,8 +870,9 @@ static int fb_deferred_io_mkwrite(struct vm_fault *vmf)
827870 mutex_lock (& fbdefio -> lock );
828871
829872 /* first write in this cycle, notify the driver */
830- if (fbdefio -> first_io && list_empty (& fbdefio -> pagelist ))
873+ if (fbdefio -> first_io && list_empty (& fbdefio -> pagelist )){
831874 fbdefio -> first_io (info );
875+ }
832876
833877 /*
834878 * We want the page to remain locked from ->page_mkwrite until
@@ -1008,6 +1052,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
10081052 struct fb_ops * fbops = NULL ;
10091053 struct fb_deferred_io * fbdefio = NULL ;
10101054 u8 * vmem = NULL ;
1055+ u8 * vmem_back_buffers [FBTFT_VMEM_BUFS ] = {NULL };
10111056 u8 * vmem_post_process = NULL ;
10121057 void * txbuf = NULL ;
10131058 void * buf = NULL ;
@@ -1078,10 +1123,16 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
10781123
10791124 vmem_size = display -> width * display -> height * bpp / 8 ;
10801125 vmem = vzalloc (vmem_size );
1081- if (!vmem )
1082- goto alloc_fail ;
1126+ for (i = 0 ; i < FBTFT_VMEM_BUFS ; ++ i )
1127+ {
1128+ vmem_back_buffers [i ] = devm_kzalloc (dev , vmem_size , GFP_KERNEL );
1129+ if (!vmem_back_buffers [i ])
1130+ goto alloc_fail ;
1131+ }
10831132
1084- vmem_post_process = kzalloc (vmem_size , GFP_DMA | GFP_KERNEL );
1133+ vmem_post_process = devm_kzalloc (dev , vmem_size , GFP_KERNEL );
1134+ //vmem_post_process = kzalloc(vmem_size, GFP_DMA | GFP_KERNEL);
1135+ //vmem_post_process = vzalloc(vmem_size);
10851136 if (!vmem_post_process )
10861137 goto alloc_fail ;
10871138
@@ -1126,10 +1177,11 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
11261177
11271178 fbdefio -> delay = HZ /fps ;
11281179 fbdefio -> deferred_io = fbtft_deferred_io ;
1180+ fbdefio -> first_io = fbtft_first_io ;
11291181 fb_deferred_io_init (info );
11301182
1131- // Overload
1132- info -> fbops -> fb_mmap = fbtft_fb_deferred_io_mmap ;
1183+ // Surcharge fb_mmap (after fb_deferred_io_init)
1184+ fbops -> fb_mmap = fbtft_fb_deferred_io_mmap ;
11331185
11341186 strncpy (info -> fix .id , dev -> driver -> name , 16 );
11351187 info -> fix .type = FB_TYPE_PACKED_PIXELS ;
@@ -1139,13 +1191,13 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
11391191 info -> fix .ywrapstep = 0 ;
11401192 info -> fix .line_length = width * bpp / 8 ;
11411193 info -> fix .accel = FB_ACCEL_NONE ;
1142- info -> fix .smem_len = vmem_size ;
1194+ info -> fix .smem_len = vmem_size * FBTFT_VMEM_BUFS ;
11431195
11441196 info -> var .rotate = pdata -> rotate ;
11451197 info -> var .xres = width ;
11461198 info -> var .yres = height ;
11471199 info -> var .xres_virtual = info -> var .xres ;
1148- info -> var .yres_virtual = info -> var .yres ;
1200+ info -> var .yres_virtual = info -> var .yres * 2 ; // So that SDL allows SDL_DOUBLEBUF
11491201 info -> var .bits_per_pixel = bpp ;
11501202 info -> var .nonstd = 1 ;
11511203
@@ -1163,8 +1215,16 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
11631215
11641216 par = info -> par ;
11651217 par -> info = info ;
1218+ par -> vmem_size = vmem_size ;
1219+ for (i = 0 ; i < FBTFT_VMEM_BUFS ; ++ i )
1220+ {
1221+ par -> vmem_back_buffers [i ] = vmem_back_buffers [i ];
1222+ }
11661223 par -> vmem_post_process = vmem_post_process ;
1167- par -> vmem_ptr = par -> info -> screen_buffer ;
1224+ par -> vmem_prev_buf_idx = 0 ;
1225+ par -> vmem_cur_buf_idx = 0 ;
1226+ par -> vmem_ptr = par -> info -> screen_buffer + (par -> vmem_cur_buf_idx * par -> vmem_size );
1227+ par -> must_render = 0 ;
11681228 par -> pdata = pdata ;
11691229 pdata -> par = par ;
11701230 par -> debug = display -> debug ;
@@ -1653,9 +1713,24 @@ static irqreturn_t irq_TE_handler(int irq_no, void *dev_id)
16531713 }
16541714#endif //DEBUG_TE_IRQ_COUNT
16551715
1656- if (pdata -> par -> ready_for_spi_async ){
1657- fbtft_start_new_screen_transfer_async (pdata -> par );
1716+ if (!pdata -> par -> ready_for_spi_async )
1717+ return IRQ_HANDLED ;
1718+
1719+ #if 0
1720+ if (pdata -> par -> must_render <= 0 )
1721+ return IRQ_HANDLED ;
1722+ /*static int prev_must_render = 0;
1723+ if (prev_must_render == pdata->par->must_render);
1724+ return IRQ_HANDLED;*/
1725+
1726+ pdata -> par -> must_render -- ;
1727+ if (pdata -> par -> must_render > 1024 ){
1728+ pdata -> par -> must_render = 1 ;
16581729 }
1730+ prev_must_render = pdata -> par -> must_render ;
1731+ #endif
1732+
1733+ fbtft_start_new_screen_transfer_async (pdata -> par );
16591734
16601735 return IRQ_HANDLED ;
16611736}
0 commit comments