@@ -894,6 +894,14 @@ bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
}
EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo);
+bool drm_mode_same_size(const struct drm_display_mode *mode1,
+ const struct drm_display_mode *mode2)
+{
+ return mode1->vdisplay == mode2->vdisplay &&
+ mode1->hdisplay == mode2->hdisplay;
+}
+EXPORT_SYMBOL(drm_mode_same_size);
+
/**
* drm_mode_validate_size - make sure modes adhere to size constraints
* @dev: DRM device
@@ -369,31 +369,30 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
/* go for command line mode first */
modes[i] = drm_pick_cmdline_mode(fb_conn, width, height);
- /* try for preferred next */
+ /* try for preferred next or match current */
if (!modes[i]) {
+ struct drm_display_mode *preferred;
+
DRM_DEBUG_KMS("looking for preferred mode on connector %d\n",
fb_conn->connector->base.id);
- modes[i] = drm_has_preferred_mode(fb_conn, width,
- height);
- }
-
- /* last resort: use current mode */
- if (!modes[i]) {
- /*
- * IMPORTANT: We want to use the adjusted mode (i.e.
- * after the panel fitter upscaling) as the initial
- * config, not the input mode, which is what crtc->mode
- * usually contains. But since our current fastboot
- * code puts a mode derived from the post-pfit timings
- * into crtc->mode this works out correctly. We don't
- * use hwmode anywhere right now, so use it for this
- * since the fb helper layer wants a pointer to
- * something we own.
- */
+ preferred = drm_has_preferred_mode(fb_conn, width,
+ height);
intel_mode_from_pipe_config(&encoder->crtc->hwmode,
&to_intel_crtc(encoder->crtc)->config);
- modes[i] = &encoder->crtc->hwmode;
+ modes[i] = &encoder->crtc->hwmode;
+
+ if (preferred &&
+ !drm_mode_same_size(preferred, modes[i])) {
+ DRM_DEBUG_KMS("using preferred mode %s "
+ "instead of current mode %s "
+ "on connector %d\n",
+ preferred->name,
+ modes[i]->name,
+ fb_conn->connector->base.id);
+ modes[i] = preferred;
+ }
}
+
crtcs[i] = new_crtc;
DRM_DEBUG_KMS("connector %s on crtc %d: %s\n",
@@ -1020,6 +1020,8 @@ extern bool drm_mode_equal(const struct drm_display_mode *mode1, const struct dr
extern bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2);
extern int drm_mode_width(const struct drm_display_mode *mode);
extern int drm_mode_height(const struct drm_display_mode *mode);
+extern bool drm_mode_same_size(const struct drm_display_mode *mode1,
+ const struct drm_display_mode *mode2);
/* for us by fb module */
extern struct drm_display_mode *drm_mode_create(struct drm_device *dev);