@@ -599,6 +599,7 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
599
599
600
600
if (old_state -> colorspace != new_state -> colorspace ||
601
601
old_vc4_state -> broadcast_rgb != new_vc4_state -> broadcast_rgb ||
602
+ old_vc4_state -> requested_output_format != new_vc4_state -> requested_output_format ||
602
603
!drm_connector_atomic_hdr_metadata_equal (old_state , new_state )) {
603
604
struct drm_crtc_state * crtc_state ;
604
605
@@ -625,6 +626,8 @@ static int vc4_hdmi_connector_get_property(struct drm_connector *connector,
625
626
626
627
if (property == vc4_hdmi -> broadcast_rgb_property ) {
627
628
* val = vc4_conn_state -> broadcast_rgb ;
629
+ } else if (property == vc4_hdmi -> output_format_property ) {
630
+ * val = vc4_conn_state -> requested_output_format ;
628
631
} else {
629
632
drm_dbg (drm , "Unknown property [PROP:%d:%s]\n" ,
630
633
property -> base .id , property -> name );
@@ -648,6 +651,9 @@ static int vc4_hdmi_connector_set_property(struct drm_connector *connector,
648
651
if (property == vc4_hdmi -> broadcast_rgb_property ) {
649
652
vc4_conn_state -> broadcast_rgb = val ;
650
653
return 0 ;
654
+ } else if (property == vc4_hdmi -> output_format_property ) {
655
+ vc4_conn_state -> requested_output_format = val ;
656
+ return 0 ;
651
657
}
652
658
653
659
drm_dbg (drm , "Unknown property [PROP:%d:%s]\n" ,
@@ -692,6 +698,7 @@ vc4_hdmi_connector_duplicate_state(struct drm_connector *connector)
692
698
new_state -> tmds_char_rate = vc4_state -> tmds_char_rate ;
693
699
new_state -> output_bpc = vc4_state -> output_bpc ;
694
700
new_state -> output_format = vc4_state -> output_format ;
701
+ new_state -> requested_output_format = vc4_state -> requested_output_format ;
695
702
new_state -> broadcast_rgb = vc4_state -> broadcast_rgb ;
696
703
__drm_atomic_helper_connector_duplicate_state (connector , & new_state -> base );
697
704
@@ -740,6 +747,33 @@ vc4_hdmi_attach_broadcast_rgb_property(struct drm_device *dev,
740
747
VC4_HDMI_BROADCAST_RGB_AUTO );
741
748
}
742
749
750
+ static const struct drm_prop_enum_list output_format_names [] = {
751
+ { VC4_HDMI_OUTPUT_AUTO , "Automatic" },
752
+ { VC4_HDMI_OUTPUT_RGB , "RGB" },
753
+ { VC4_HDMI_OUTPUT_YUV422 , "YCbCr 4:2:2" },
754
+ { VC4_HDMI_OUTPUT_YUV444 , "YCbCr 4:4:4" },
755
+ };
756
+
757
+ static void
758
+ vc4_hdmi_attach_output_format_property (struct drm_device * dev ,
759
+ struct vc4_hdmi * vc4_hdmi )
760
+ {
761
+ struct drm_property * prop = vc4_hdmi -> output_format_property ;
762
+
763
+ if (!prop ) {
764
+ prop = drm_property_create_enum (dev , DRM_MODE_PROP_ENUM ,
765
+ "Output format" ,
766
+ output_format_names ,
767
+ ARRAY_SIZE (output_format_names ));
768
+ if (!prop )
769
+ return ;
770
+
771
+ vc4_hdmi -> output_format_property = prop ;
772
+ }
773
+
774
+ drm_object_attach_property (& vc4_hdmi -> connector .base , prop , 0 );
775
+ }
776
+
743
777
static int vc4_hdmi_connector_init (struct drm_device * dev ,
744
778
struct vc4_hdmi * vc4_hdmi )
745
779
{
@@ -790,6 +824,7 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
790
824
}
791
825
792
826
vc4_hdmi_attach_broadcast_rgb_property (dev , vc4_hdmi );
827
+ vc4_hdmi_attach_output_format_property (dev , vc4_hdmi );
793
828
794
829
drm_connector_attach_encoder (connector , encoder );
795
830
@@ -1960,6 +1995,10 @@ static void vc4_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder,
1960
1995
& crtc_state -> adjusted_mode );
1961
1996
vc4_hdmi -> output_bpc = vc4_state -> output_bpc ;
1962
1997
vc4_hdmi -> output_format = vc4_state -> output_format ;
1998
+ vc4_hdmi -> requested_output_format = vc4_state -> requested_output_format ;
1999
+ memcpy (& vc4_hdmi -> saved_adjusted_mode ,
2000
+ & crtc_state -> adjusted_mode ,
2001
+ sizeof (vc4_hdmi -> saved_adjusted_mode ));
1963
2002
mutex_unlock (& vc4_hdmi -> mutex );
1964
2003
}
1965
2004
@@ -2118,6 +2157,26 @@ vc4_hdmi_encoder_compute_format(const struct vc4_hdmi *vc4_hdmi,
2118
2157
const struct drm_display_info * info = & connector -> display_info ;
2119
2158
unsigned int format ;
2120
2159
2160
+ if (vc4_state -> requested_output_format != VC4_HDMI_OUTPUT_AUTO ) {
2161
+ drm_dbg (dev , "Trying with user requested output %u\n" ,
2162
+ vc4_state -> requested_output_format );
2163
+
2164
+ format = vc4_state -> requested_output_format ;
2165
+ if (vc4_hdmi_sink_supports_format_bpc (vc4_hdmi , info , mode ,
2166
+ format , bpc )) {
2167
+ int ret ;
2168
+
2169
+ ret = vc4_hdmi_encoder_compute_clock (vc4_hdmi , vc4_state ,
2170
+ mode , bpc , format );
2171
+ if (!ret ) {
2172
+ vc4_state -> output_format = format ;
2173
+ return 0 ;
2174
+ }
2175
+ }
2176
+
2177
+ return - EINVAL ;
2178
+ }
2179
+
2121
2180
drm_dbg (dev , "Trying with an RGB output\n" );
2122
2181
2123
2182
format = VC4_HDMI_OUTPUT_RGB ;
0 commit comments