110110#define HDMI_PLL_LOCK BIT(31)
111111#define HDMI_PLL_LOCK_G12A (3 << 30)
112112
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)
117114
118115/* VID PLL Dividers */
119116enum {
@@ -772,6 +769,36 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
772769 pll_freq );
773770}
774771
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+
775802enum drm_mode_status
776803meson_vclk_vic_supported_freq (struct meson_drm * priv ,
777804 unsigned long long phy_freq ,
@@ -790,19 +817,7 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv,
790817 }
791818
792819 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 ))
806821 return MODE_OK ;
807822 }
808823
@@ -1075,10 +1090,8 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
10751090 }
10761091
10771092 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 )) {
10821095 if (vclk_freq != params [freq ].vclk_freq )
10831096 vic_alternate_clock = true;
10841097 else
0 commit comments