110
110
#define HDMI_PLL_LOCK BIT(31)
111
111
#define HDMI_PLL_LOCK_G12A (3 << 30)
112
112
113
- #define PIXEL_FREQ_1000_1001 (_freq ) \
114
- DIV_ROUND_CLOSEST_ULL((_freq) * 1000ULL, 1001ULL)
115
- #define PHY_FREQ_1000_1001 (_freq ) \
116
- (PIXEL_FREQ_1000_1001(DIV_ROUND_DOWN_ULL(_freq, 10ULL)) * 10)
113
+ #define FREQ_1000_1001 (_freq ) DIV_ROUND_CLOSEST_ULL((_freq) * 1000ULL, 1001ULL)
117
114
118
115
/* VID PLL Dividers */
119
116
enum {
@@ -772,6 +769,36 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
772
769
pll_freq );
773
770
}
774
771
772
+ static bool meson_vclk_freqs_are_matching_param (unsigned int idx ,
773
+ unsigned long long phy_freq ,
774
+ unsigned long long vclk_freq )
775
+ {
776
+ DRM_DEBUG_DRIVER ("i = %d vclk_freq = %lluHz alt = %lluHz\n" ,
777
+ idx , params [idx ].vclk_freq ,
778
+ FREQ_1000_1001 (params [idx ].vclk_freq ));
779
+ DRM_DEBUG_DRIVER ("i = %d phy_freq = %lluHz alt = %lluHz\n" ,
780
+ idx , params [idx ].phy_freq ,
781
+ FREQ_1000_1001 (params [idx ].phy_freq ));
782
+
783
+ /* Match strict frequency */
784
+ if (phy_freq == params [idx ].phy_freq &&
785
+ vclk_freq == params [idx ].vclk_freq )
786
+ return true;
787
+
788
+ /* Match 1000/1001 variant: vclk deviation has to be less than 1kHz
789
+ * (drm EDID is defined in 1kHz steps, so everything smaller must be
790
+ * rounding error) and the PHY freq deviation has to be less than
791
+ * 10kHz (as the TMDS clock is 10 times the pixel clock, so anything
792
+ * smaller must be rounding error as well).
793
+ */
794
+ if (abs (vclk_freq - FREQ_1000_1001 (params [idx ].vclk_freq )) < 1000 &&
795
+ abs (phy_freq - FREQ_1000_1001 (params [idx ].phy_freq )) < 10000 )
796
+ return true;
797
+
798
+ /* no match */
799
+ return false;
800
+ }
801
+
775
802
enum drm_mode_status
776
803
meson_vclk_vic_supported_freq (struct meson_drm * priv ,
777
804
unsigned long long phy_freq ,
@@ -790,19 +817,7 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv,
790
817
}
791
818
792
819
for (i = 0 ; params [i ].pixel_freq ; ++ i ) {
793
- DRM_DEBUG_DRIVER ("i = %d pixel_freq = %lluHz alt = %lluHz\n" ,
794
- i , params [i ].pixel_freq ,
795
- PIXEL_FREQ_1000_1001 (params [i ].pixel_freq ));
796
- DRM_DEBUG_DRIVER ("i = %d phy_freq = %lluHz alt = %lluHz\n" ,
797
- i , params [i ].phy_freq ,
798
- PHY_FREQ_1000_1001 (params [i ].phy_freq ));
799
- /* Match strict frequency */
800
- if (phy_freq == params [i ].phy_freq &&
801
- vclk_freq == params [i ].vclk_freq )
802
- return MODE_OK ;
803
- /* Match 1000/1001 variant */
804
- if (phy_freq == PHY_FREQ_1000_1001 (params [i ].phy_freq ) &&
805
- vclk_freq == PIXEL_FREQ_1000_1001 (params [i ].vclk_freq ))
820
+ if (meson_vclk_freqs_are_matching_param (i , phy_freq , vclk_freq ))
806
821
return MODE_OK ;
807
822
}
808
823
@@ -1075,10 +1090,8 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
1075
1090
}
1076
1091
1077
1092
for (freq = 0 ; params [freq ].pixel_freq ; ++ freq ) {
1078
- if ((phy_freq == params [freq ].phy_freq ||
1079
- phy_freq == PHY_FREQ_1000_1001 (params [freq ].phy_freq )) &&
1080
- (vclk_freq == params [freq ].vclk_freq ||
1081
- vclk_freq == PIXEL_FREQ_1000_1001 (params [freq ].vclk_freq ))) {
1093
+ if (meson_vclk_freqs_are_matching_param (freq , phy_freq ,
1094
+ vclk_freq )) {
1082
1095
if (vclk_freq != params [freq ].vclk_freq )
1083
1096
vic_alternate_clock = true;
1084
1097
else
0 commit comments