@@ -832,10 +832,14 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm,
832
832
return & plane -> base ;
833
833
}
834
834
835
- static const u32 tegra_cursor_plane_formats [] = {
835
+ static const u32 tegra_legacy_cursor_plane_formats [] = {
836
836
DRM_FORMAT_RGBA8888 ,
837
837
};
838
838
839
+ static const u32 tegra_cursor_plane_formats [] = {
840
+ DRM_FORMAT_ARGB8888 ,
841
+ };
842
+
839
843
static int tegra_cursor_atomic_check (struct drm_plane * plane ,
840
844
struct drm_atomic_state * state )
841
845
{
@@ -875,12 +879,24 @@ static void tegra_cursor_atomic_update(struct drm_plane *plane,
875
879
plane );
876
880
struct tegra_plane_state * tegra_plane_state = to_tegra_plane_state (new_state );
877
881
struct tegra_dc * dc = to_tegra_dc (new_state -> crtc );
878
- u32 value = CURSOR_CLIP_DISPLAY ;
882
+ struct tegra_drm * tegra = plane -> dev -> dev_private ;
883
+ #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
884
+ u64 dma_mask = * dc -> dev -> dma_mask ;
885
+ #endif
886
+ unsigned int x , y ;
887
+ u32 value = 0 ;
879
888
880
889
/* rien ne va plus */
881
890
if (!new_state -> crtc || !new_state -> fb )
882
891
return ;
883
892
893
+ /*
894
+ * Legacy display supports hardware clipping of the cursor, but
895
+ * nvdisplay relies on software to clip the cursor to the screen.
896
+ */
897
+ if (!dc -> soc -> has_nvdisplay )
898
+ value |= CURSOR_CLIP_DISPLAY ;
899
+
884
900
switch (new_state -> crtc_w ) {
885
901
case 32 :
886
902
value |= CURSOR_SIZE_32x32 ;
@@ -908,7 +924,7 @@ static void tegra_cursor_atomic_update(struct drm_plane *plane,
908
924
tegra_dc_writel (dc , value , DC_DISP_CURSOR_START_ADDR );
909
925
910
926
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
911
- value = (tegra_plane_state -> iova [0 ] >> 32 ) & 0x3 ;
927
+ value = (tegra_plane_state -> iova [0 ] >> 32 ) & ( dma_mask >> 32 ) ;
912
928
tegra_dc_writel (dc , value , DC_DISP_CURSOR_START_ADDR_HI );
913
929
#endif
914
930
@@ -920,15 +936,39 @@ static void tegra_cursor_atomic_update(struct drm_plane *plane,
920
936
value = tegra_dc_readl (dc , DC_DISP_BLEND_CURSOR_CONTROL );
921
937
value &= ~CURSOR_DST_BLEND_MASK ;
922
938
value &= ~CURSOR_SRC_BLEND_MASK ;
923
- value |= CURSOR_MODE_NORMAL ;
939
+
940
+ if (dc -> soc -> has_nvdisplay )
941
+ value &= ~CURSOR_COMPOSITION_MODE_XOR ;
942
+ else
943
+ value |= CURSOR_MODE_NORMAL ;
944
+
924
945
value |= CURSOR_DST_BLEND_NEG_K1_TIMES_SRC ;
925
946
value |= CURSOR_SRC_BLEND_K1_TIMES_SRC ;
926
947
value |= CURSOR_ALPHA ;
927
948
tegra_dc_writel (dc , value , DC_DISP_BLEND_CURSOR_CONTROL );
928
949
950
+ /* nvdisplay relies on software for clipping */
951
+ if (dc -> soc -> has_nvdisplay ) {
952
+ struct drm_rect src ;
953
+
954
+ x = new_state -> dst .x1 ;
955
+ y = new_state -> dst .y1 ;
956
+
957
+ drm_rect_fp_to_int (& src , & new_state -> src );
958
+
959
+ value = (src .y1 & tegra -> vmask ) << 16 | (src .x1 & tegra -> hmask );
960
+ tegra_dc_writel (dc , value , DC_DISP_PCALC_HEAD_SET_CROPPED_POINT_IN_CURSOR );
961
+
962
+ value = (drm_rect_height (& src ) & tegra -> vmask ) << 16 |
963
+ (drm_rect_width (& src ) & tegra -> hmask );
964
+ tegra_dc_writel (dc , value , DC_DISP_PCALC_HEAD_SET_CROPPED_SIZE_IN_CURSOR );
965
+ } else {
966
+ x = new_state -> crtc_x ;
967
+ y = new_state -> crtc_y ;
968
+ }
969
+
929
970
/* position the cursor */
930
- value = (new_state -> crtc_y & 0x3fff ) << 16 |
931
- (new_state -> crtc_x & 0x3fff );
971
+ value = ((y & tegra -> vmask ) << 16 ) | (x & tegra -> hmask );
932
972
tegra_dc_writel (dc , value , DC_DISP_CURSOR_POSITION );
933
973
}
934
974
@@ -982,8 +1022,13 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
982
1022
plane -> index = 6 ;
983
1023
plane -> dc = dc ;
984
1024
985
- num_formats = ARRAY_SIZE (tegra_cursor_plane_formats );
986
- formats = tegra_cursor_plane_formats ;
1025
+ if (!dc -> soc -> has_nvdisplay ) {
1026
+ num_formats = ARRAY_SIZE (tegra_legacy_cursor_plane_formats );
1027
+ formats = tegra_legacy_cursor_plane_formats ;
1028
+ } else {
1029
+ num_formats = ARRAY_SIZE (tegra_cursor_plane_formats );
1030
+ formats = tegra_cursor_plane_formats ;
1031
+ }
987
1032
988
1033
err = drm_universal_plane_init (drm , & plane -> base , possible_crtcs ,
989
1034
& tegra_plane_funcs , formats ,
0 commit comments