@@ -547,6 +547,15 @@ bridge_to_cdns_dsi_input(struct drm_bridge *bridge)
547
547
return container_of (bridge , struct cdns_dsi_input , bridge );
548
548
}
549
549
550
+ static unsigned int mode_to_dpi_hfp (const struct drm_display_mode * mode ,
551
+ bool mode_valid_check )
552
+ {
553
+ if (mode_valid_check )
554
+ return mode -> hsync_start - mode -> hdisplay ;
555
+
556
+ return mode -> crtc_hsync_start - mode -> crtc_hdisplay ;
557
+ }
558
+
550
559
static int cdns_dsi_get_dphy_pll_cfg (struct cdns_dphy * dphy ,
551
560
struct cdns_dphy_cfg * cfg ,
552
561
unsigned int dpi_htotal ,
@@ -733,14 +742,12 @@ static unsigned int dpi_to_dsi_timing(unsigned int dpi_timing,
733
742
static int cdns_dsi_mode2cfg (struct cdns_dsi * dsi ,
734
743
const struct drm_display_mode * mode ,
735
744
struct cdns_dsi_cfg * dsi_cfg ,
736
- struct cdns_dphy_cfg * dphy_cfg ,
737
745
bool mode_valid_check )
738
746
{
739
- unsigned long dsi_htotal = 0 , dsi_hss_hsa_hse_hbp = 0 ;
740
747
struct cdns_dsi_output * output = & dsi -> output ;
741
- unsigned int dsi_hfp_ext = 0 , dpi_hfp , tmp ;
748
+ unsigned int tmp ;
742
749
bool sync_pulse = false;
743
- int bpp , nlanes , ret ;
750
+ int bpp , nlanes ;
744
751
745
752
memset (dsi_cfg , 0 , sizeof (* dsi_cfg ));
746
753
@@ -759,8 +766,6 @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi,
759
766
mode -> crtc_hsync_end : mode -> crtc_hsync_start );
760
767
761
768
dsi_cfg -> hbp = dpi_to_dsi_timing (tmp , bpp , DSI_HBP_FRAME_OVERHEAD );
762
- dsi_htotal += dsi_cfg -> hbp + DSI_HBP_FRAME_OVERHEAD ;
763
- dsi_hss_hsa_hse_hbp += dsi_cfg -> hbp + DSI_HBP_FRAME_OVERHEAD ;
764
769
765
770
if (sync_pulse ) {
766
771
if (mode_valid_check )
@@ -770,49 +775,91 @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi,
770
775
771
776
dsi_cfg -> hsa = dpi_to_dsi_timing (tmp , bpp ,
772
777
DSI_HSA_FRAME_OVERHEAD );
773
- dsi_htotal += dsi_cfg -> hsa + DSI_HSA_FRAME_OVERHEAD ;
774
- dsi_hss_hsa_hse_hbp += dsi_cfg -> hsa + DSI_HSA_FRAME_OVERHEAD ;
775
778
}
776
779
777
780
dsi_cfg -> hact = dpi_to_dsi_timing (mode_valid_check ?
778
781
mode -> hdisplay : mode -> crtc_hdisplay ,
779
782
bpp , 0 );
780
- dsi_htotal += dsi_cfg -> hact ;
783
+ dsi_cfg -> hfp = dpi_to_dsi_timing (mode_to_dpi_hfp (mode , mode_valid_check ),
784
+ bpp , DSI_HFP_FRAME_OVERHEAD );
781
785
782
- if (mode_valid_check )
783
- dpi_hfp = mode -> hsync_start - mode -> hdisplay ;
784
- else
785
- dpi_hfp = mode -> crtc_hsync_start - mode -> crtc_hdisplay ;
786
+ return 0 ;
787
+ }
788
+
789
+ static int cdns_dphy_validate (struct cdns_dsi * dsi ,
790
+ struct cdns_dsi_cfg * dsi_cfg ,
791
+ struct cdns_dphy_cfg * dphy_cfg ,
792
+ const struct drm_display_mode * mode ,
793
+ bool mode_valid_check )
794
+ {
795
+ struct cdns_dsi_output * output = & dsi -> output ;
796
+ unsigned long dsi_htotal ;
797
+ unsigned int dsi_hfp_ext = 0 ;
798
+
799
+ int ret ;
800
+
801
+ dsi_htotal = dsi_cfg -> hbp + DSI_HBP_FRAME_OVERHEAD ;
802
+ if (output -> dev -> mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE )
803
+ dsi_htotal += dsi_cfg -> hsa + DSI_HSA_FRAME_OVERHEAD ;
786
804
787
- dsi_cfg -> hfp = dpi_to_dsi_timing ( dpi_hfp , bpp , DSI_HFP_FRAME_OVERHEAD ) ;
805
+ dsi_htotal += dsi_cfg -> hact ;
788
806
dsi_htotal += dsi_cfg -> hfp + DSI_HFP_FRAME_OVERHEAD ;
789
807
790
808
if (mode_valid_check )
791
809
ret = cdns_dsi_get_dphy_pll_cfg (dsi -> dphy , dphy_cfg ,
792
- mode -> htotal , bpp ,
810
+ mode -> htotal ,
811
+ mipi_dsi_pixel_format_to_bpp (output -> dev -> format ),
793
812
mode -> clock * 1000 ,
794
- dsi_htotal , nlanes ,
813
+ dsi_htotal ,
814
+ output -> dev -> lanes ,
795
815
& dsi_hfp_ext );
796
816
else
797
817
ret = cdns_dsi_get_dphy_pll_cfg (dsi -> dphy , dphy_cfg ,
798
- mode -> crtc_htotal , bpp ,
818
+ mode -> crtc_htotal ,
819
+ mipi_dsi_pixel_format_to_bpp (output -> dev -> format ),
799
820
mode -> crtc_clock * 1000 ,
800
- dsi_htotal , nlanes ,
821
+ dsi_htotal ,
822
+ output -> dev -> lanes ,
801
823
& dsi_hfp_ext );
802
-
803
824
if (ret )
804
825
return ret ;
805
826
806
827
dsi_cfg -> hfp += dsi_hfp_ext ;
807
- dsi_htotal += dsi_hfp_ext ;
808
- dsi_cfg -> htotal = dsi_htotal ;
828
+ dsi_cfg -> htotal = dsi_htotal + dsi_hfp_ext ;
829
+
830
+ return 0 ;
831
+ }
832
+
833
+ static int cdns_dsi_check_conf (struct cdns_dsi * dsi ,
834
+ const struct drm_display_mode * mode ,
835
+ struct cdns_dsi_cfg * dsi_cfg ,
836
+ struct cdns_dphy_cfg * dphy_cfg ,
837
+ bool mode_valid_check )
838
+ {
839
+ struct cdns_dsi_output * output = & dsi -> output ;
840
+ unsigned long dsi_hss_hsa_hse_hbp ;
841
+ unsigned int nlanes = output -> dev -> lanes ;
842
+ int ret ;
843
+
844
+ ret = cdns_dsi_mode2cfg (dsi , mode , dsi_cfg , mode_valid_check );
845
+ if (ret )
846
+ return ret ;
847
+
848
+ ret = cdns_dphy_validate (dsi , dsi_cfg , dphy_cfg , mode , mode_valid_check );
849
+ if (ret )
850
+ return ret ;
851
+
852
+ dsi_hss_hsa_hse_hbp = dsi_cfg -> hbp + DSI_HBP_FRAME_OVERHEAD ;
853
+ if (output -> dev -> mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE )
854
+ dsi_hss_hsa_hse_hbp += dsi_cfg -> hsa + DSI_HSA_FRAME_OVERHEAD ;
809
855
810
856
/*
811
857
* Make sure DPI(HFP) > DSI(HSS+HSA+HSE+HBP) to guarantee that the FIFO
812
858
* is empty before we start a receiving a new line on the DPI
813
859
* interface.
814
860
*/
815
- if ((u64 )dphy_cfg -> lane_bps * dpi_hfp * nlanes <
861
+ if ((u64 )dphy_cfg -> lane_bps *
862
+ mode_to_dpi_hfp (mode , mode_valid_check ) * nlanes <
816
863
(u64 )dsi_hss_hsa_hse_hbp *
817
864
(mode_valid_check ? mode -> clock : mode -> crtc_clock ) * 1000 )
818
865
return - EINVAL ;
@@ -844,7 +891,7 @@ cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge,
844
891
struct cdns_dsi_output * output = & dsi -> output ;
845
892
struct cdns_dphy_cfg dphy_cfg ;
846
893
struct cdns_dsi_cfg dsi_cfg ;
847
- int bpp , nlanes , ret ;
894
+ int bpp , ret ;
848
895
849
896
/*
850
897
* VFP_DSI should be less than VFP_DPI and VFP_DSI should be at
@@ -862,11 +909,9 @@ cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge,
862
909
if ((mode -> hdisplay * bpp ) % 32 )
863
910
return MODE_H_ILLEGAL ;
864
911
865
- nlanes = output -> dev -> lanes ;
866
-
867
- ret = cdns_dsi_mode2cfg (dsi , mode , & dsi_cfg , & dphy_cfg , true);
912
+ ret = cdns_dsi_check_conf (dsi , mode , & dsi_cfg , & dphy_cfg , true);
868
913
if (ret )
869
- return MODE_CLOCK_RANGE ;
914
+ return MODE_BAD ;
870
915
871
916
return MODE_OK ;
872
917
}
@@ -992,7 +1037,7 @@ static void cdns_dsi_bridge_enable(struct drm_bridge *bridge)
992
1037
bpp = mipi_dsi_pixel_format_to_bpp (output -> dev -> format );
993
1038
nlanes = output -> dev -> lanes ;
994
1039
995
- WARN_ON_ONCE (cdns_dsi_mode2cfg (dsi , mode , & dsi_cfg , & dphy_cfg , false));
1040
+ WARN_ON_ONCE (cdns_dsi_check_conf (dsi , mode , & dsi_cfg , & dphy_cfg , false));
996
1041
997
1042
cdns_dsi_hs_init (dsi , & dphy_cfg );
998
1043
cdns_dsi_init_link (dsi );
0 commit comments