Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk> --- drivers/gpu/drm/i915/intel_display.c | 9 +++++++++ drivers/gpu/drm/i915/intel_dp.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 8 ++++++++ drivers/gpu/drm/i915/intel_fb.c | 9 +++++++++ drivers/gpu/drm/i915/intel_lvds.c | 1 + drivers/gpu/drm/i915/intel_panel.c | 10 ++++++++++ 6 files changed, 38 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 43e226d..c1d8200 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9233,6 +9233,15 @@ void intel_connector_attach_encoder(struct intel_connector *connector, &encoder->base); } +bool intel_connector_get_preferred_mode(struct intel_connector *connector, + struct drm_display_mode *mode) +{ + if (!connector->get_preferred_mode) + return false; + + return connector->get_preferred_mode(connector, mode); +} + /* * set vga decode state - true == enable VGA decode */ diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c82aed3..c8597d9 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2922,6 +2922,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, } if (is_edp(intel_dp)) { + intel_connector->get_preferred_mode = intel_connector_get_panel_fixed_mode; intel_panel_init(&intel_connector->panel, fixed_mode); intel_panel_setup_backlight(connector); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a6c0b25..8bd9bf0 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -204,6 +204,9 @@ struct intel_connector { * and active (i.e. dpms ON state). */ bool (*get_hw_state)(struct intel_connector *); + bool (*get_preferred_mode)(struct intel_connector *, + struct drm_display_mode *); + /* Panel info for eDP and LVDS */ struct intel_panel panel; @@ -505,6 +508,9 @@ extern int intel_panel_init(struct intel_panel *panel, struct drm_display_mode *fixed_mode); extern void intel_panel_fini(struct intel_panel *panel); +extern bool intel_connector_get_panel_fixed_mode(struct intel_connector *connector, + struct drm_display_mode *mode); + extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode); extern void intel_pch_panel_fitting(struct drm_device *dev, @@ -576,6 +582,8 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi) bool ibx_digital_port_connected(struct drm_i915_private *dev_priv, struct intel_digital_port *port); +extern bool intel_connector_get_preferred_mode(struct intel_connector *connector, + struct drm_display_mode *mode); extern void intel_connector_attach_encoder(struct intel_connector *connector, struct intel_encoder *encoder); extern struct drm_encoder *intel_best_encoder(struct drm_connector *connector); diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index ca6c8e6..32bc904 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -237,6 +237,7 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, for (i = 0; i < fb_helper->connector_count; i++) { struct drm_connector *connector; struct drm_encoder *encoder; + struct drm_display_mode mode; connector = fb_helper->connector_info[i]->connector; if (!enabled[i]) { @@ -266,6 +267,14 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, return false; } + if (intel_connector_get_preferred_mode(to_intel_connector(connector), &mode) && + !drm_mode_equal(&mode, &encoder->crtc->mode)) { + DRM_DEBUG_KMS("connector %s on crtc %d has an non-native mode, aborting\n", + drm_get_connector_name(connector), + encoder->crtc->base.id); + return false; + } + modes[i] = &encoder->crtc->mode; crtcs[i] = intel_fb_helper_crtc(fb_helper, encoder->crtc); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 3da1b2a..9f4381e 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -1134,6 +1134,7 @@ bool intel_lvds_init(struct drm_device *dev) intel_encoder->get_hw_state = intel_lvds_get_hw_state; intel_encoder->get_mode_flags = intel_lvds_get_mode_flags; intel_connector->get_hw_state = intel_connector_get_hw_state; + intel_connector->get_preferred_mode = intel_connector_get_panel_fixed_mode; intel_connector_attach_encoder(intel_connector, intel_encoder); intel_encoder->type = INTEL_OUTPUT_LVDS; diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index bee8cb6..212e088 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -35,6 +35,16 @@ #define PCI_LBPC 0xf4 /* legacy/combination backlight modes */ +bool intel_connector_get_panel_fixed_mode(struct intel_connector *connector, + struct drm_display_mode *mode) +{ + if (!connector->panel.fixed_mode) + return false; + + *mode = *connector->panel.fixed_mode; + return true; +} + void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode) -- 1.7.10.4