@@ -3107,6 +3107,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
31073107 void * data = hdmi -> plat_data -> phy_data ;
31083108 int i , ret = 0 ;
31093109 struct drm_display_mode * preferred_mode = NULL ;
3110+ struct drm_display_mode * default_mode = NULL ;
31103111
31113112 memset (metedata , 0 , sizeof (* metedata ));
31123113 edid = dw_hdmi_get_edid (hdmi , connector );
@@ -3160,24 +3161,58 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
31603161 dw_hdmi_check_output_type_changed (hdmi );
31613162
31623163 if ((hdmi -> preset_max_hdisplay ) && (hdmi -> preset_max_vdisplay )) {
3164+ #ifdef DEBUG
3165+ #define MODE_DBG (x ) (dev_err(hdmi->dev, "hdisplay: %d vdisplay: %d flags: %x refresh: %d\n", x->hdisplay, x->vdisplay, x->flags, drm_mode_vrefresh(x)))
3166+ #define MODE_MSG (x ) (dev_err(hdmi->dev, x))
3167+ #else
3168+ #define MODE_DBG (x ) {}
3169+ #define MODE_MSG (x ) {}
3170+ #endif
3171+ #define IS_PREFERRED (x ) (x->flags & DRM_MODE_TYPE_PREFERRED)
3172+ #define PIXEL_COUNT (x ) (x->hdisplay * x->vdisplay)
3173+ #define IS_BETTER (x , y ) ((PIXEL_COUNT(x) <= hdmi->preset_max_hdisplay * hdmi->preset_max_vdisplay && !(x->flags & DRM_MODE_FLAG_INTERLACE) && drm_mode_vrefresh(x) <= 60) && \
3174+ (PIXEL_COUNT(x) > PIXEL_COUNT(y) || (PIXEL_COUNT(x) == PIXEL_COUNT(y) && drm_mode_vrefresh(x) >= drm_mode_vrefresh(y)) || PIXEL_COUNT(y) > hdmi->preset_max_hdisplay * hdmi->preset_max_vdisplay || drm_mode_vrefresh(y) > 60))
3175+
3176+ // Find default mode
31633177 list_for_each_entry (mode , & connector -> probed_modes , head ) {
3164- mode -> type &= ~DRM_MODE_TYPE_PREFERRED ;
3165- if (mode -> hdisplay == hdmi -> preset_max_hdisplay &&
3166- mode -> vdisplay == hdmi -> preset_max_vdisplay ) {
3167- preferred_mode ?:(preferred_mode = mode );
3168- if (!(mode -> flags & DRM_MODE_FLAG_INTERLACE )) {
3169- if ((preferred_mode -> flags & DRM_MODE_FLAG_INTERLACE ) || (
3170- drm_mode_vrefresh (mode ) >
3171- drm_mode_vrefresh (preferred_mode ) &&
3172- drm_mode_vrefresh (mode ) <= 60 )) {
3173- preferred_mode = mode ;
3174- }
3175- }
3178+ if (IS_PREFERRED (mode )) {
3179+ default_mode = mode ;
3180+ MODE_MSG ("found default_mode\n" );
3181+ MODE_DBG (default_mode );
3182+ break ;
31763183 }
31773184 }
31783185
3179- if (preferred_mode )
3186+ // Provide a sane initial mode for later comparision
3187+ if (default_mode ) {
3188+ preferred_mode = default_mode ;
3189+ MODE_MSG ("preferred_mode = default_mode\n" );
3190+ }
3191+ else {
3192+ preferred_mode = list_entry (& connector -> probed_modes , struct drm_display_mode , head );
3193+ MODE_MSG ("preferred_mode = connector->probed_modes[0]\n" );
3194+ MODE_DBG (preferred_mode );
3195+ }
3196+
3197+ // Searching for better mode within our criteria
3198+ list_for_each_entry (mode , & connector -> probed_modes , head ) {
3199+ if (IS_BETTER (mode , preferred_mode )) {
3200+ preferred_mode = mode ;
3201+ MODE_MSG ("preferred_mode updated\n" );
3202+ MODE_DBG (preferred_mode );
3203+ }
3204+ }
3205+
3206+ // Update preferred mode
3207+ if (!default_mode ) {
31803208 preferred_mode -> type |= DRM_MODE_TYPE_PREFERRED ;
3209+ MODE_MSG ("missing default_mode, preferred_mode used as default_mode\n" );
3210+ }
3211+ else if (PIXEL_COUNT (default_mode ) > hdmi -> preset_max_hdisplay * hdmi -> preset_max_vdisplay ) {
3212+ default_mode -> type &= ~DRM_MODE_TYPE_PREFERRED ;
3213+ preferred_mode -> type |= DRM_MODE_TYPE_PREFERRED ;
3214+ MODE_MSG ("default_mode resolution is above limit\n" );
3215+ }
31813216 }
31823217
31833218 return ret ;
0 commit comments