@@ -632,7 +632,34 @@ static int ast_primary_plane_init(struct ast_device *ast)
632632 * Cursor plane
633633 */
634634
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 )
636663{
637664 union {
638665 u32 ul ;
@@ -642,9 +669,9 @@ static void ast_update_cursor_image(u8 __iomem *dst, const u8 *src, int width, i
642669 u16 us ;
643670 u8 b [2 ];
644671 } data16 ;
645- u32 csum = 0 ;
672+ u32 csum ;
646673 s32 alpha_dst_delta , last_alpha_dst_delta ;
647- u8 __iomem * dstxor ;
674+ u8 * dstxor ;
648675 const u8 * srcxor ;
649676 int i , j ;
650677 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
653680 last_alpha_dst_delta = alpha_dst_delta - (width << 1 );
654681
655682 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 ;
657684 per_pixel_copy = width & 1 ;
658685 two_pixel_copy = width >> 1 ;
659686
@@ -665,28 +692,29 @@ static void ast_update_cursor_image(u8 __iomem *dst, const u8 *src, int width, i
665692 data32 .b [1 ] = srcdata32 [0 ].b [3 ] | (srcdata32 [0 ].b [2 ] >> 4 );
666693 data32 .b [2 ] = srcdata32 [1 ].b [1 ] | (srcdata32 [1 ].b [0 ] >> 4 );
667694 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 );
671696
672697 dstxor += 4 ;
673698 srcxor += 8 ;
674-
675699 }
676700
677701 for (i = 0 ; i < per_pixel_copy ; i ++ ) {
678702 srcdata32 [0 ].ul = * ((u32 * )srcxor ) & 0xf0f0f0f0 ;
679703 data16 .b [0 ] = srcdata32 [0 ].b [1 ] | (srcdata32 [0 ].b [0 ] >> 4 );
680704 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 );
683706
684707 dstxor += 2 ;
685708 srcxor += 4 ;
686709 }
687710 dstxor += last_alpha_dst_delta ;
688711 }
689712
713+ csum = ast_cursor_calculate_checksum (tmp , width , height );
714+
715+ /* write pixel data */
716+ memcpy_toio (dst , tmp , AST_HWC_SIZE );
717+
690718 /* write checksum + signature */
691719 dst += AST_HWC_SIZE ;
692720 writel (csum , dst );
@@ -767,6 +795,7 @@ static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane,
767795static void ast_cursor_plane_helper_atomic_update (struct drm_plane * plane ,
768796 struct drm_atomic_state * state )
769797{
798+ struct ast_cursor_plane * ast_cursor_plane = to_ast_cursor_plane (plane );
770799 struct ast_plane * ast_plane = to_ast_plane (plane );
771800 struct drm_plane_state * plane_state = drm_atomic_get_new_plane_state (state , plane );
772801 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,
789818 */
790819
791820 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 );
793823 ast_set_cursor_base (ast , dst_off );
794824 }
795825
@@ -849,8 +879,9 @@ static const struct drm_plane_funcs ast_cursor_plane_funcs = {
849879static int ast_cursor_plane_init (struct ast_device * ast )
850880{
851881 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 ;
854885 size_t size ;
855886 void __iomem * vaddr ;
856887 u64 offset ;
@@ -869,7 +900,7 @@ static int ast_cursor_plane_init(struct ast_device *ast)
869900 vaddr = ast -> vram + ast -> vram_fb_available - size ;
870901 offset = ast -> vram_fb_available - size ;
871902
872- ret = ast_plane_init (dev , ast_cursor_plane , vaddr , offset , size ,
903+ ret = ast_plane_init (dev , ast_plane , vaddr , offset , size ,
873904 0x01 , & ast_cursor_plane_funcs ,
874905 ast_cursor_plane_formats , ARRAY_SIZE (ast_cursor_plane_formats ),
875906 NULL , DRM_PLANE_TYPE_CURSOR );
@@ -1156,7 +1187,7 @@ static int ast_crtc_init(struct ast_device *ast)
11561187 int ret ;
11571188
11581189 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 ,
11601191 NULL );
11611192 if (ret )
11621193 return ret ;
0 commit comments