@@ -9424,6 +9424,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
*/
@@ -2926,6 +2926,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);
}
@@ -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;
@@ -514,6 +517,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,
@@ -585,6 +591,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);
@@ -216,6 +216,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]) {
@@ -245,6 +246,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);
@@ -1129,6 +1129,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;
@@ -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)