@@ -632,7 +632,34 @@ static int ast_primary_plane_init(struct ast_device *ast)
632
632
* Cursor plane
633
633
*/
634
634
635
- static void ast_update_cursor_image (u8 __iomem * dst , const u8 * src , int width , int height )
635
+ static u32 ast_cursor_calculate_checksum (const void * src , unsigned int width , unsigned int height )
636
+ {
637
+ u32 csum = 0 ;
638
+ unsigned int one_pixel_copy = width & BIT (0 );
639
+ unsigned int two_pixel_copy = width - one_pixel_copy ;
640
+ unsigned int trailing_bytes = (AST_MAX_HWC_WIDTH - width ) * sizeof (u16 );
641
+ unsigned int x , y ;
642
+
643
+ for (y = 0 ; y < height ; y ++ ) {
644
+ for (x = 0 ; x < two_pixel_copy ; x += 2 ) {
645
+ const u32 * src32 = (const u32 * )src ;
646
+
647
+ csum += * src32 ;
648
+ src += SZ_4 ;
649
+ }
650
+ if (one_pixel_copy ) {
651
+ const u16 * src16 = (const u16 * )src ;
652
+
653
+ csum += * src16 ;
654
+ src += SZ_2 ;
655
+ }
656
+ src += trailing_bytes ;
657
+ }
658
+
659
+ return csum ;
660
+ }
661
+
662
+ static void ast_update_cursor_image (u8 __iomem * dst , const u8 * src , u8 * tmp , int width , int height )
636
663
{
637
664
union {
638
665
u32 ul ;
@@ -642,9 +669,9 @@ static void ast_update_cursor_image(u8 __iomem *dst, const u8 *src, int width, i
642
669
u16 us ;
643
670
u8 b [2 ];
644
671
} data16 ;
645
- u32 csum = 0 ;
672
+ u32 csum ;
646
673
s32 alpha_dst_delta , last_alpha_dst_delta ;
647
- u8 __iomem * dstxor ;
674
+ u8 * dstxor ;
648
675
const u8 * srcxor ;
649
676
int i , j ;
650
677
u32 per_pixel_copy , two_pixel_copy ;
@@ -653,7 +680,7 @@ static void ast_update_cursor_image(u8 __iomem *dst, const u8 *src, int width, i
653
680
last_alpha_dst_delta = alpha_dst_delta - (width << 1 );
654
681
655
682
srcxor = src ;
656
- dstxor = ( u8 * ) dst + last_alpha_dst_delta + (AST_MAX_HWC_HEIGHT - height ) * alpha_dst_delta ;
683
+ dstxor = tmp + last_alpha_dst_delta + (AST_MAX_HWC_HEIGHT - height ) * alpha_dst_delta ;
657
684
per_pixel_copy = width & 1 ;
658
685
two_pixel_copy = width >> 1 ;
659
686
@@ -665,28 +692,29 @@ static void ast_update_cursor_image(u8 __iomem *dst, const u8 *src, int width, i
665
692
data32 .b [1 ] = srcdata32 [0 ].b [3 ] | (srcdata32 [0 ].b [2 ] >> 4 );
666
693
data32 .b [2 ] = srcdata32 [1 ].b [1 ] | (srcdata32 [1 ].b [0 ] >> 4 );
667
694
data32 .b [3 ] = srcdata32 [1 ].b [3 ] | (srcdata32 [1 ].b [2 ] >> 4 );
668
-
669
- writel (data32 .ul , dstxor );
670
- csum += data32 .ul ;
695
+ memcpy (dstxor , & data32 , 4 );
671
696
672
697
dstxor += 4 ;
673
698
srcxor += 8 ;
674
-
675
699
}
676
700
677
701
for (i = 0 ; i < per_pixel_copy ; i ++ ) {
678
702
srcdata32 [0 ].ul = * ((u32 * )srcxor ) & 0xf0f0f0f0 ;
679
703
data16 .b [0 ] = srcdata32 [0 ].b [1 ] | (srcdata32 [0 ].b [0 ] >> 4 );
680
704
data16 .b [1 ] = srcdata32 [0 ].b [3 ] | (srcdata32 [0 ].b [2 ] >> 4 );
681
- writew (data16 .us , dstxor );
682
- csum += (u32 )data16 .us ;
705
+ memcpy (dstxor , & data16 , 2 );
683
706
684
707
dstxor += 2 ;
685
708
srcxor += 4 ;
686
709
}
687
710
dstxor += last_alpha_dst_delta ;
688
711
}
689
712
713
+ csum = ast_cursor_calculate_checksum (tmp , width , height );
714
+
715
+ /* write pixel data */
716
+ memcpy_toio (dst , tmp , AST_HWC_SIZE );
717
+
690
718
/* write checksum + signature */
691
719
dst += AST_HWC_SIZE ;
692
720
writel (csum , dst );
@@ -767,6 +795,7 @@ static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane,
767
795
static void ast_cursor_plane_helper_atomic_update (struct drm_plane * plane ,
768
796
struct drm_atomic_state * state )
769
797
{
798
+ struct ast_cursor_plane * ast_cursor_plane = to_ast_cursor_plane (plane );
770
799
struct ast_plane * ast_plane = to_ast_plane (plane );
771
800
struct drm_plane_state * plane_state = drm_atomic_get_new_plane_state (state , plane );
772
801
struct drm_shadow_plane_state * shadow_plane_state = to_drm_shadow_plane_state (plane_state );
@@ -789,7 +818,8 @@ static void ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
789
818
*/
790
819
791
820
if (drm_atomic_helper_damage_merged (old_plane_state , plane_state , & damage )) {
792
- ast_update_cursor_image (dst , src , fb -> width , fb -> height );
821
+ ast_update_cursor_image (dst , src , ast_cursor_plane -> argb4444 ,
822
+ fb -> width , fb -> height );
793
823
ast_set_cursor_base (ast , dst_off );
794
824
}
795
825
@@ -849,8 +879,9 @@ static const struct drm_plane_funcs ast_cursor_plane_funcs = {
849
879
static int ast_cursor_plane_init (struct ast_device * ast )
850
880
{
851
881
struct drm_device * dev = & ast -> base ;
852
- struct ast_plane * ast_cursor_plane = & ast -> cursor_plane ;
853
- struct drm_plane * cursor_plane = & ast_cursor_plane -> base ;
882
+ struct ast_cursor_plane * ast_cursor_plane = & ast -> cursor_plane ;
883
+ struct ast_plane * ast_plane = & ast_cursor_plane -> base ;
884
+ struct drm_plane * cursor_plane = & ast_plane -> base ;
854
885
size_t size ;
855
886
void __iomem * vaddr ;
856
887
u64 offset ;
@@ -869,7 +900,7 @@ static int ast_cursor_plane_init(struct ast_device *ast)
869
900
vaddr = ast -> vram + ast -> vram_fb_available - size ;
870
901
offset = ast -> vram_fb_available - size ;
871
902
872
- ret = ast_plane_init (dev , ast_cursor_plane , vaddr , offset , size ,
903
+ ret = ast_plane_init (dev , ast_plane , vaddr , offset , size ,
873
904
0x01 , & ast_cursor_plane_funcs ,
874
905
ast_cursor_plane_formats , ARRAY_SIZE (ast_cursor_plane_formats ),
875
906
NULL , DRM_PLANE_TYPE_CURSOR );
@@ -1156,7 +1187,7 @@ static int ast_crtc_init(struct ast_device *ast)
1156
1187
int ret ;
1157
1188
1158
1189
ret = drm_crtc_init_with_planes (dev , crtc , & ast -> primary_plane .base ,
1159
- & ast -> cursor_plane .base , & ast_crtc_funcs ,
1190
+ & ast -> cursor_plane .base . base , & ast_crtc_funcs ,
1160
1191
NULL );
1161
1192
if (ret )
1162
1193
return ret ;
0 commit comments