diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 421b7e2ece3b88befea155ea845de63e18b90786..8d9e7c0e9e4bd3464662b0c1cf9ef090c48cb6a6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8091,6 +8091,9 @@ intel_pipe_config_compare(struct drm_device *dev, return false; \ } +#define PIPE_CONF_QUIRK(quirk) \ + ((current_config->quirks | pipe_config->quirks) & (quirk)) + PIPE_CONF_CHECK_I(cpu_transcoder); PIPE_CONF_CHECK_I(has_pch_encoder); @@ -8121,14 +8124,16 @@ intel_pipe_config_compare(struct drm_device *dev, PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, DRM_MODE_FLAG_INTERLACE); - PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, - DRM_MODE_FLAG_PHSYNC); - PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, - DRM_MODE_FLAG_NHSYNC); - PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, - DRM_MODE_FLAG_PVSYNC); - PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, - DRM_MODE_FLAG_NVSYNC); + if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) { + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, + DRM_MODE_FLAG_PHSYNC); + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, + DRM_MODE_FLAG_NHSYNC); + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, + DRM_MODE_FLAG_PVSYNC); + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, + DRM_MODE_FLAG_NVSYNC); + } PIPE_CONF_CHECK_I(requested_mode.hdisplay); PIPE_CONF_CHECK_I(requested_mode.vdisplay); @@ -8145,6 +8150,7 @@ intel_pipe_config_compare(struct drm_device *dev, #undef PIPE_CONF_CHECK_I #undef PIPE_CONF_CHECK_FLAGS +#undef PIPE_CONF_QUIRK return true; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1735cdc86770dd44a0985283f884fd2859602068..b76a956cfb9acf4e5e505aa1df0674ed2b199500 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -193,6 +193,17 @@ typedef struct dpll { } intel_clock_t; struct intel_crtc_config { + /** + * quirks - bitfield with hw state readout quirks + * + * For various reasons the hw state readout code might not be able to + * completely faithfully read out the current state. These cases are + * tracked with quirk flags so that fastboot and state checker can act + * accordingly. + */ +#define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */ + unsigned long quirks; + struct drm_display_mode requested_mode; struct drm_display_mode adjusted_mode; /* This flag must be set by the encoder's compute_config callback if it diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 5c816dd75becb0fde8e77fc0b7e91043bb908e88..960358d8e3369764b7a1e74be83ed5b2d19c81d3 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1324,19 +1324,21 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); if (!ret) { + /* Some sdvo encoders are not spec compliant and don't + * implement the mandatory get_timings function. */ DRM_DEBUG_DRIVER("failed to retrieve SDVO DTD\n"); - return; - } - - if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) - flags |= DRM_MODE_FLAG_PHSYNC; - else - flags |= DRM_MODE_FLAG_NHSYNC; + pipe_config->quirks |= PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS; + } else { + if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) + flags |= DRM_MODE_FLAG_PHSYNC; + else + flags |= DRM_MODE_FLAG_NHSYNC; - if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) - flags |= DRM_MODE_FLAG_PVSYNC; - else - flags |= DRM_MODE_FLAG_NVSYNC; + if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) + flags |= DRM_MODE_FLAG_PVSYNC; + else + flags |= DRM_MODE_FLAG_NVSYNC; + } pipe_config->adjusted_mode.flags |= flags;