@@ -30,12 +30,17 @@ to_ipu_plane_state(struct drm_plane_state *p)
30
30
return container_of (p , struct ipu_plane_state , base );
31
31
}
32
32
33
+ static unsigned int ipu_src_rect_width (const struct drm_plane_state * state )
34
+ {
35
+ return ALIGN (drm_rect_width (& state -> src ) >> 16 , 8 );
36
+ }
37
+
33
38
static inline struct ipu_plane * to_ipu_plane (struct drm_plane * p )
34
39
{
35
40
return container_of (p , struct ipu_plane , base );
36
41
}
37
42
38
- static const uint32_t ipu_plane_formats [] = {
43
+ static const uint32_t ipu_plane_all_formats [] = {
39
44
DRM_FORMAT_ARGB1555 ,
40
45
DRM_FORMAT_XRGB1555 ,
41
46
DRM_FORMAT_ABGR1555 ,
@@ -72,6 +77,31 @@ static const uint32_t ipu_plane_formats[] = {
72
77
DRM_FORMAT_BGRX8888_A8 ,
73
78
};
74
79
80
+ static const uint32_t ipu_plane_rgb_formats [] = {
81
+ DRM_FORMAT_ARGB1555 ,
82
+ DRM_FORMAT_XRGB1555 ,
83
+ DRM_FORMAT_ABGR1555 ,
84
+ DRM_FORMAT_XBGR1555 ,
85
+ DRM_FORMAT_RGBA5551 ,
86
+ DRM_FORMAT_BGRA5551 ,
87
+ DRM_FORMAT_ARGB4444 ,
88
+ DRM_FORMAT_ARGB8888 ,
89
+ DRM_FORMAT_XRGB8888 ,
90
+ DRM_FORMAT_ABGR8888 ,
91
+ DRM_FORMAT_XBGR8888 ,
92
+ DRM_FORMAT_RGBA8888 ,
93
+ DRM_FORMAT_RGBX8888 ,
94
+ DRM_FORMAT_BGRA8888 ,
95
+ DRM_FORMAT_BGRX8888 ,
96
+ DRM_FORMAT_RGB565 ,
97
+ DRM_FORMAT_RGB565_A8 ,
98
+ DRM_FORMAT_BGR565_A8 ,
99
+ DRM_FORMAT_RGB888_A8 ,
100
+ DRM_FORMAT_BGR888_A8 ,
101
+ DRM_FORMAT_RGBX8888_A8 ,
102
+ DRM_FORMAT_BGRX8888_A8 ,
103
+ };
104
+
75
105
static const uint64_t ipu_format_modifiers [] = {
76
106
DRM_FORMAT_MOD_LINEAR ,
77
107
DRM_FORMAT_MOD_INVALID
@@ -264,7 +294,6 @@ void ipu_plane_disable_deferred(struct drm_plane *plane)
264
294
ipu_plane_disable (ipu_plane , false);
265
295
}
266
296
}
267
- EXPORT_SYMBOL_GPL (ipu_plane_disable_deferred );
268
297
269
298
static void ipu_plane_state_reset (struct drm_plane * plane )
270
299
{
@@ -284,6 +313,8 @@ static void ipu_plane_state_reset(struct drm_plane *plane)
284
313
__drm_atomic_helper_plane_reset (plane , & ipu_state -> base );
285
314
ipu_state -> base .zpos = zpos ;
286
315
ipu_state -> base .normalized_zpos = zpos ;
316
+ ipu_state -> base .color_encoding = DRM_COLOR_YCBCR_BT601 ;
317
+ ipu_state -> base .color_range = DRM_COLOR_YCBCR_LIMITED_RANGE ;
287
318
}
288
319
}
289
320
@@ -320,10 +351,11 @@ static bool ipu_plane_format_mod_supported(struct drm_plane *plane,
320
351
if (modifier == DRM_FORMAT_MOD_LINEAR )
321
352
return true;
322
353
323
- /* without a PRG there are no supported modifiers */
324
- if (!ipu_prg_present (ipu ))
325
- return false;
326
-
354
+ /*
355
+ * Without a PRG the possible modifiers list only includes the linear
356
+ * modifier, so we always take the early return from this function and
357
+ * only end up here if the PRG is present.
358
+ */
327
359
return ipu_prg_format_supported (ipu , format , modifier );
328
360
}
329
361
@@ -415,6 +447,12 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
415
447
if (old_fb && fb -> pitches [0 ] != old_fb -> pitches [0 ])
416
448
crtc_state -> mode_changed = true;
417
449
450
+ if (ALIGN (fb -> width , 8 ) * fb -> format -> cpp [0 ] >
451
+ fb -> pitches [0 ] + fb -> offsets [0 ]) {
452
+ dev_warn (dev , "pitch is not big enough for 8 pixels alignment" );
453
+ return - EINVAL ;
454
+ }
455
+
418
456
switch (fb -> format -> format ) {
419
457
case DRM_FORMAT_YUV420 :
420
458
case DRM_FORMAT_YVU420 :
@@ -590,12 +628,31 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
590
628
if (ipu_state -> use_pre ) {
591
629
axi_id = ipu_chan_assign_axi_id (ipu_plane -> dma );
592
630
ipu_prg_channel_configure (ipu_plane -> ipu_ch , axi_id ,
593
- drm_rect_width ( & new_state -> src ) >> 16 ,
631
+ ipu_src_rect_width ( new_state ) ,
594
632
drm_rect_height (& new_state -> src ) >> 16 ,
595
633
fb -> pitches [0 ], fb -> format -> format ,
596
634
fb -> modifier , & eba );
597
635
}
598
636
637
+ if (!old_state -> fb ||
638
+ old_state -> fb -> format -> format != fb -> format -> format ||
639
+ old_state -> color_encoding != new_state -> color_encoding ||
640
+ old_state -> color_range != new_state -> color_range ) {
641
+ ics = ipu_drm_fourcc_to_colorspace (fb -> format -> format );
642
+ switch (ipu_plane -> dp_flow ) {
643
+ case IPU_DP_FLOW_SYNC_BG :
644
+ ipu_dp_setup_channel (ipu_plane -> dp , new_state -> color_encoding ,
645
+ new_state -> color_range , ics ,
646
+ IPUV3_COLORSPACE_RGB );
647
+ break ;
648
+ case IPU_DP_FLOW_SYNC_FG :
649
+ ipu_dp_setup_channel (ipu_plane -> dp , new_state -> color_encoding ,
650
+ new_state -> color_range , ics ,
651
+ IPUV3_COLORSPACE_UNKNOWN );
652
+ break ;
653
+ }
654
+ }
655
+
599
656
if (old_state -> fb && !drm_atomic_crtc_needs_modeset (crtc_state )) {
600
657
/* nothing to do if PRE is used */
601
658
if (ipu_state -> use_pre )
@@ -615,17 +672,20 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
615
672
ics = ipu_drm_fourcc_to_colorspace (fb -> format -> format );
616
673
switch (ipu_plane -> dp_flow ) {
617
674
case IPU_DP_FLOW_SYNC_BG :
618
- ipu_dp_setup_channel (ipu_plane -> dp , ics , IPUV3_COLORSPACE_RGB );
675
+ ipu_dp_setup_channel (ipu_plane -> dp , DRM_COLOR_YCBCR_BT601 ,
676
+ DRM_COLOR_YCBCR_LIMITED_RANGE , ics ,
677
+ IPUV3_COLORSPACE_RGB );
619
678
break ;
620
679
case IPU_DP_FLOW_SYNC_FG :
621
- ipu_dp_setup_channel (ipu_plane -> dp , ics ,
622
- IPUV3_COLORSPACE_UNKNOWN );
680
+ ipu_dp_setup_channel (ipu_plane -> dp , DRM_COLOR_YCBCR_BT601 ,
681
+ DRM_COLOR_YCBCR_LIMITED_RANGE , ics ,
682
+ IPUV3_COLORSPACE_UNKNOWN );
623
683
break ;
624
684
}
625
685
626
686
ipu_dmfc_config_wait4eot (ipu_plane -> dmfc , drm_rect_width (dst ));
627
687
628
- width = drm_rect_width ( & new_state -> src ) >> 16 ;
688
+ width = ipu_src_rect_width ( new_state ) ;
629
689
height = drm_rect_height (& new_state -> src ) >> 16 ;
630
690
info = drm_format_info (fb -> format -> format );
631
691
ipu_calculate_bursts (width , info -> cpp [0 ], fb -> pitches [0 ],
@@ -690,7 +750,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
690
750
691
751
ipu_cpmem_zero (ipu_plane -> alpha_ch );
692
752
ipu_cpmem_set_resolution (ipu_plane -> alpha_ch ,
693
- drm_rect_width ( & new_state -> src ) >> 16 ,
753
+ ipu_src_rect_width ( new_state ) ,
694
754
drm_rect_height (& new_state -> src ) >> 16 );
695
755
ipu_cpmem_set_format_passthrough (ipu_plane -> alpha_ch , 8 );
696
756
ipu_cpmem_set_high_priority (ipu_plane -> alpha_ch );
@@ -821,7 +881,6 @@ int ipu_planes_assign_pre(struct drm_device *dev,
821
881
822
882
return 0 ;
823
883
}
824
- EXPORT_SYMBOL_GPL (ipu_planes_assign_pre );
825
884
826
885
struct ipu_plane * ipu_plane_init (struct drm_device * dev , struct ipu_soc * ipu ,
827
886
int dma , int dp , unsigned int possible_crtcs ,
@@ -830,16 +889,28 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
830
889
struct ipu_plane * ipu_plane ;
831
890
const uint64_t * modifiers = ipu_format_modifiers ;
832
891
unsigned int zpos = (type == DRM_PLANE_TYPE_PRIMARY ) ? 0 : 1 ;
892
+ unsigned int format_count ;
893
+ const uint32_t * formats ;
833
894
int ret ;
834
895
835
896
DRM_DEBUG_KMS ("channel %d, dp flow %d, possible_crtcs=0x%x\n" ,
836
897
dma , dp , possible_crtcs );
837
898
899
+ if (dp == IPU_DP_FLOW_SYNC_BG || dp == IPU_DP_FLOW_SYNC_FG ) {
900
+ formats = ipu_plane_all_formats ;
901
+ format_count = ARRAY_SIZE (ipu_plane_all_formats );
902
+ } else {
903
+ formats = ipu_plane_rgb_formats ;
904
+ format_count = ARRAY_SIZE (ipu_plane_rgb_formats );
905
+ }
906
+
907
+ if (ipu_prg_present (ipu ))
908
+ modifiers = pre_format_modifiers ;
909
+
838
910
ipu_plane = drmm_universal_plane_alloc (dev , struct ipu_plane , base ,
839
911
possible_crtcs , & ipu_plane_funcs ,
840
- ipu_plane_formats ,
841
- ARRAY_SIZE (ipu_plane_formats ),
842
- modifiers , type , NULL );
912
+ formats , format_count , modifiers ,
913
+ type , NULL );
843
914
if (IS_ERR (ipu_plane )) {
844
915
DRM_ERROR ("failed to allocate and initialize %s plane\n" ,
845
916
zpos ? "overlay" : "primary" );
@@ -850,9 +921,6 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
850
921
ipu_plane -> dma = dma ;
851
922
ipu_plane -> dp_flow = dp ;
852
923
853
- if (ipu_prg_present (ipu ))
854
- modifiers = pre_format_modifiers ;
855
-
856
924
drm_plane_helper_add (& ipu_plane -> base , & ipu_plane_helper_funcs );
857
925
858
926
if (dp == IPU_DP_FLOW_SYNC_BG || dp == IPU_DP_FLOW_SYNC_FG )
@@ -864,6 +932,15 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
864
932
if (ret )
865
933
return ERR_PTR (ret );
866
934
935
+ ret = drm_plane_create_color_properties (& ipu_plane -> base ,
936
+ BIT (DRM_COLOR_YCBCR_BT601 ) |
937
+ BIT (DRM_COLOR_YCBCR_BT709 ),
938
+ BIT (DRM_COLOR_YCBCR_LIMITED_RANGE ),
939
+ DRM_COLOR_YCBCR_BT601 ,
940
+ DRM_COLOR_YCBCR_LIMITED_RANGE );
941
+ if (ret )
942
+ return ERR_PTR (ret );
943
+
867
944
ret = ipu_plane_get_resources (dev , ipu_plane );
868
945
if (ret ) {
869
946
DRM_ERROR ("failed to get %s plane resources: %pe\n" ,
0 commit comments