@@ -832,10 +832,14 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm,
832832 return & plane -> base ;
833833}
834834
835- static const u32 tegra_cursor_plane_formats [] = {
835+ static const u32 tegra_legacy_cursor_plane_formats [] = {
836836 DRM_FORMAT_RGBA8888 ,
837837};
838838
839+ static const u32 tegra_cursor_plane_formats [] = {
840+ DRM_FORMAT_ARGB8888 ,
841+ };
842+
839843static int tegra_cursor_atomic_check (struct drm_plane * plane ,
840844 struct drm_atomic_state * state )
841845{
@@ -875,12 +879,24 @@ static void tegra_cursor_atomic_update(struct drm_plane *plane,
875879 plane );
876880 struct tegra_plane_state * tegra_plane_state = to_tegra_plane_state (new_state );
877881 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 ;
879888
880889 /* rien ne va plus */
881890 if (!new_state -> crtc || !new_state -> fb )
882891 return ;
883892
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+
884900 switch (new_state -> crtc_w ) {
885901 case 32 :
886902 value |= CURSOR_SIZE_32x32 ;
@@ -908,7 +924,7 @@ static void tegra_cursor_atomic_update(struct drm_plane *plane,
908924 tegra_dc_writel (dc , value , DC_DISP_CURSOR_START_ADDR );
909925
910926#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 ) ;
912928 tegra_dc_writel (dc , value , DC_DISP_CURSOR_START_ADDR_HI );
913929#endif
914930
@@ -920,15 +936,39 @@ static void tegra_cursor_atomic_update(struct drm_plane *plane,
920936 value = tegra_dc_readl (dc , DC_DISP_BLEND_CURSOR_CONTROL );
921937 value &= ~CURSOR_DST_BLEND_MASK ;
922938 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+
924945 value |= CURSOR_DST_BLEND_NEG_K1_TIMES_SRC ;
925946 value |= CURSOR_SRC_BLEND_K1_TIMES_SRC ;
926947 value |= CURSOR_ALPHA ;
927948 tegra_dc_writel (dc , value , DC_DISP_BLEND_CURSOR_CONTROL );
928949
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+
929970 /* 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 );
932972 tegra_dc_writel (dc , value , DC_DISP_CURSOR_POSITION );
933973}
934974
@@ -982,8 +1022,13 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
9821022 plane -> index = 6 ;
9831023 plane -> dc = dc ;
9841024
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+ }
9871032
9881033 err = drm_universal_plane_init (drm , & plane -> base , possible_crtcs ,
9891034 & tegra_plane_funcs , formats ,
0 commit comments