@@ -146,6 +146,31 @@ static inline struct ssd130x_device *drm_to_ssd130x(struct drm_device *drm)
146
146
return container_of (drm , struct ssd130x_device , drm );
147
147
}
148
148
149
+ static int ssd130x_buf_alloc (struct ssd130x_device * ssd130x )
150
+ {
151
+ unsigned int page_height = ssd130x -> device_info -> page_height ;
152
+ unsigned int pages = DIV_ROUND_UP (ssd130x -> height , page_height );
153
+
154
+ ssd130x -> buffer = kcalloc (DIV_ROUND_UP (ssd130x -> width , 8 ),
155
+ ssd130x -> height , GFP_KERNEL );
156
+ if (!ssd130x -> buffer )
157
+ return - ENOMEM ;
158
+
159
+ ssd130x -> data_array = kcalloc (ssd130x -> width , pages , GFP_KERNEL );
160
+ if (!ssd130x -> data_array ) {
161
+ kfree (ssd130x -> buffer );
162
+ return - ENOMEM ;
163
+ }
164
+
165
+ return 0 ;
166
+ }
167
+
168
+ static void ssd130x_buf_free (struct ssd130x_device * ssd130x )
169
+ {
170
+ kfree (ssd130x -> data_array );
171
+ kfree (ssd130x -> buffer );
172
+ }
173
+
149
174
/*
150
175
* Helper to write data (SSD130X_DATA) to the device.
151
176
*/
@@ -434,11 +459,12 @@ static int ssd130x_init(struct ssd130x_device *ssd130x)
434
459
SSD130X_SET_ADDRESS_MODE_HORIZONTAL );
435
460
}
436
461
437
- static int ssd130x_update_rect (struct ssd130x_device * ssd130x , u8 * buf ,
438
- struct drm_rect * rect )
462
+ static int ssd130x_update_rect (struct ssd130x_device * ssd130x , struct drm_rect * rect )
439
463
{
440
464
unsigned int x = rect -> x1 ;
441
465
unsigned int y = rect -> y1 ;
466
+ u8 * buf = ssd130x -> buffer ;
467
+ u8 * data_array = ssd130x -> data_array ;
442
468
unsigned int width = drm_rect_width (rect );
443
469
unsigned int height = drm_rect_height (rect );
444
470
unsigned int line_length = DIV_ROUND_UP (width , 8 );
@@ -447,14 +473,9 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, u8 *buf,
447
473
struct drm_device * drm = & ssd130x -> drm ;
448
474
u32 array_idx = 0 ;
449
475
int ret , i , j , k ;
450
- u8 * data_array = NULL ;
451
476
452
477
drm_WARN_ONCE (drm , y % 8 != 0 , "y must be aligned to screen page\n" );
453
478
454
- data_array = kcalloc (width , pages , GFP_KERNEL );
455
- if (!data_array )
456
- return - ENOMEM ;
457
-
458
479
/*
459
480
* The screen is divided in pages, each having a height of 8
460
481
* pixels, and the width of the screen. When sending a byte of
@@ -488,11 +509,11 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, u8 *buf,
488
509
/* Set address range for horizontal addressing mode */
489
510
ret = ssd130x_set_col_range (ssd130x , ssd130x -> col_offset + x , width );
490
511
if (ret < 0 )
491
- goto out_free ;
512
+ return ret ;
492
513
493
514
ret = ssd130x_set_page_range (ssd130x , ssd130x -> page_offset + y / 8 , pages );
494
515
if (ret < 0 )
495
- goto out_free ;
516
+ return ret ;
496
517
}
497
518
498
519
for (i = 0 ; i < pages ; i ++ ) {
@@ -522,11 +543,11 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, u8 *buf,
522
543
ssd130x -> page_offset + i ,
523
544
ssd130x -> col_offset + x );
524
545
if (ret < 0 )
525
- goto out_free ;
546
+ return ret ;
526
547
527
548
ret = ssd130x_write_data (ssd130x , data_array , width );
528
549
if (ret < 0 )
529
- goto out_free ;
550
+ return ret ;
530
551
531
552
array_idx = 0 ;
532
553
}
@@ -536,29 +557,19 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, u8 *buf,
536
557
if (!ssd130x -> page_address_mode )
537
558
ret = ssd130x_write_data (ssd130x , data_array , width * pages );
538
559
539
- out_free :
540
- kfree (data_array );
541
560
return ret ;
542
561
}
543
562
544
563
static void ssd130x_clear_screen (struct ssd130x_device * ssd130x )
545
564
{
546
- u8 * buf = NULL ;
547
565
struct drm_rect fullscreen = {
548
566
.x1 = 0 ,
549
567
.x2 = ssd130x -> width ,
550
568
.y1 = 0 ,
551
569
.y2 = ssd130x -> height ,
552
570
};
553
571
554
- buf = kcalloc (DIV_ROUND_UP (ssd130x -> width , 8 ), ssd130x -> height ,
555
- GFP_KERNEL );
556
- if (!buf )
557
- return ;
558
-
559
- ssd130x_update_rect (ssd130x , buf , & fullscreen );
560
-
561
- kfree (buf );
572
+ ssd130x_update_rect (ssd130x , & fullscreen );
562
573
}
563
574
564
575
static int ssd130x_fb_blit_rect (struct drm_framebuffer * fb , const struct iosys_map * vmap ,
@@ -569,30 +580,27 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_m
569
580
struct iosys_map dst ;
570
581
unsigned int dst_pitch ;
571
582
int ret = 0 ;
572
- u8 * buf = NULL ;
583
+ u8 * buf = ssd130x -> buffer ;
584
+
585
+ if (!buf )
586
+ return 0 ;
573
587
574
588
/* Align y to display page boundaries */
575
589
rect -> y1 = round_down (rect -> y1 , page_height );
576
590
rect -> y2 = min_t (unsigned int , round_up (rect -> y2 , page_height ), ssd130x -> height );
577
591
578
592
dst_pitch = DIV_ROUND_UP (drm_rect_width (rect ), page_height );
579
- buf = kcalloc (dst_pitch , drm_rect_height (rect ), GFP_KERNEL );
580
- if (!buf )
581
- return - ENOMEM ;
582
593
583
594
ret = drm_gem_fb_begin_cpu_access (fb , DMA_FROM_DEVICE );
584
595
if (ret )
585
- goto out_free ;
596
+ return ret ;
586
597
587
598
iosys_map_set_vaddr (& dst , buf );
588
599
drm_fb_xrgb8888_to_mono (& dst , & dst_pitch , vmap , fb , rect );
589
600
590
601
drm_gem_fb_end_cpu_access (fb , DMA_FROM_DEVICE );
591
602
592
- ssd130x_update_rect (ssd130x , buf , rect );
593
-
594
- out_free :
595
- kfree (buf );
603
+ ssd130x_update_rect (ssd130x , rect );
596
604
597
605
return ret ;
598
606
}
@@ -701,14 +709,22 @@ static void ssd130x_encoder_helper_atomic_enable(struct drm_encoder *encoder,
701
709
return ;
702
710
703
711
ret = ssd130x_init (ssd130x );
704
- if (ret ) {
705
- ssd130x_power_off (ssd130x );
706
- return ;
707
- }
712
+ if (ret )
713
+ goto power_off ;
714
+
715
+ ret = ssd130x_buf_alloc (ssd130x );
716
+ if (ret )
717
+ goto power_off ;
708
718
709
719
ssd130x_write_cmd (ssd130x , 1 , SSD130X_DISPLAY_ON );
710
720
711
721
backlight_enable (ssd130x -> bl_dev );
722
+
723
+ return ;
724
+
725
+ power_off :
726
+ ssd130x_power_off (ssd130x );
727
+ return ;
712
728
}
713
729
714
730
static void ssd130x_encoder_helper_atomic_disable (struct drm_encoder * encoder ,
@@ -721,6 +737,8 @@ static void ssd130x_encoder_helper_atomic_disable(struct drm_encoder *encoder,
721
737
722
738
ssd130x_write_cmd (ssd130x , 1 , SSD130X_DISPLAY_OFF );
723
739
740
+ ssd130x_buf_free (ssd130x );
741
+
724
742
ssd130x_power_off (ssd130x );
725
743
}
726
744
0 commit comments