summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-06-06 14:55:52 +0200
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-06-06 22:35:44 +0200
commitbb760063790fbbc3c956f23aff4dbdfdd3c03818 (patch)
tree98eb28033453c59d178793c3fb4d37189fd010cd
parenta38911a3fede294e2adfd2deea8104dfbbd760c5 (diff)
downloadop-kernel-dev-bb760063790fbbc3c956f23aff4dbdfdd3c03818.zip
op-kernel-dev-bb760063790fbbc3c956f23aff4dbdfdd3c03818.tar.gz
drm/i915: pipe config quirk infrastructure plus sdvo mode.flags fix
For various reasons the hw state readout might not be able to faithfully match the hw state: - broken hw (like the case which motivated this patch here where the sdvo encoder does not implemented mandatory functionality correctly). - platforms which are not supported fully with the pipe config infrastructure - if our code doesn't support a given hw configuration natively, e.g. special restrictions on the per-pipe panel fitters when they're used in high-quality scaling modes. In all these cases both fastboot and the hw state cross checker need to be aware of these cases and act accordingly. To be able to do this add a new quirk flag to the pipe config structure. The specific case at hand is an sdvo encoder which doesn't implement the get_timings function, so adjusted_mode flags will be wrong. The strange thing though is that the encoder _does_ work, even though it doesn't implement any of the timings functions (so neither get nor set, neither for input nor output timings). Not that non-compliant sdvo encoder are any surprise at all ... v2: - Don't read random garbage from the dtd if the get_timings call failed (suggested by Chris). - Still check the interlaced flag, that's read out from someplace else. We want maximal paranoia, after all. Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/intel_display.c22
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h11
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c24
3 files changed, 38 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 421b7e2..8d9e7c0 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 1735cdc..b76a956 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 5c816dd..960358d 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;
OpenPOWER on IntegriCloud