Read the current hardware state to retrieve the active mode and populate
our CRTC config if that mode matches our presumptions.
v2: check that get_hw_state gave us a valid pipe (Imre)
add clock_get for ILK+ (Jesse)
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
drivers/gpu/drm/i915/i915_drv.h |2 +
drivers/gpu/drm/i915/intel_crt.c | 27 ++-
drivers/gpu/drm/i915/intel_display.c | 139 +++---
drivers/gpu/drm/i915/intel_dp.c | 22 ++
drivers/gpu/drm/i915/intel_drv.h |7 +-
drivers/gpu/drm/i915/intel_dvo.c | 36 ++---
drivers/gpu/drm/i915/intel_hdmi.c| 22 ++
drivers/gpu/drm/i915/intel_lvds.c| 27 ++-
drivers/gpu/drm/i915/intel_sdvo.c| 23 ++
9 files changed, 262 insertions(+), 43 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d32ed27..905ce86 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -283,6 +283,8 @@ struct drm_i915_display_funcs {
void (*update_linetime_wm)(struct drm_device *dev, int pipe,
struct drm_display_mode *mode);
void (*modeset_global_resources)(struct drm_device *dev);
+ bool (*crtc_get_mode)(struct drm_crtc *crtc,
+struct drm_display_mode *mode);
int (*crtc_mode_set)(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 32a3693..da0ae7e 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -81,6 +81,27 @@ static bool intel_crt_get_hw_state(struct intel_encoder
*encoder,
return true;
}
+static unsigned intel_crt_get_mode_flags(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *dev_priv = encoder-base.dev-dev_private;
+ struct intel_crt *crt = intel_encoder_to_crt(encoder);
+ u32 tmp, flags = 0;
+
+ tmp = I915_READ(crt-adpa_reg);
+
+ if (tmp ADPA_HSYNC_ACTIVE_HIGH)
+ flags |= DRM_MODE_FLAG_PHSYNC;
+ else
+ flags |= DRM_MODE_FLAG_NHSYNC;
+
+ if (tmp ADPA_VSYNC_ACTIVE_HIGH)
+ flags |= DRM_MODE_FLAG_PVSYNC;
+ else
+ flags |= DRM_MODE_FLAG_NVSYNC;
+
+ return flags;
+}
+
static void intel_disable_crt(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = encoder-base.dev-dev_private;
@@ -776,10 +797,12 @@ void intel_crt_init(struct drm_device *dev)
crt-base.disable = intel_disable_crt;
crt-base.enable = intel_enable_crt;
- if (HAS_DDI(dev))
+ if (HAS_DDI(dev)) {
crt-base.get_hw_state = intel_ddi_get_hw_state;
- else
+ } else {
crt-base.get_hw_state = intel_crt_get_hw_state;
+ crt-base.get_mode_flags = intel_crt_get_mode_flags;
+ }
intel_connector-get_hw_state = intel_connector_get_hw_state;
drm_encoder_helper_add(crt-base.base, crt_encoder_funcs);
diff --git a/drivers/gpu/drm/i915/intel_display.c
b/drivers/gpu/drm/i915/intel_display.c
index a55ef8f..35a1984 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6748,11 +6748,12 @@ void intel_release_load_detect_pipe(struct
drm_connector *connector,
}
/* Returns the clock of the currently programmed mode of the given pipe. */
-static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
+static int i9xx_crtc_clock_get(struct drm_crtc *crtc)
{
+ struct drm_device *dev = crtc-dev;
struct drm_i915_private *dev_priv = dev-dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- int pipe = intel_crtc-pipe;
+ enum pipe pipe = intel_crtc-pipe;
u32 dpll = I915_READ(DPLL(pipe));
u32 fp;
intel_clock_t clock;
@@ -6835,35 +6836,104 @@ static int intel_crtc_clock_get(struct drm_device
*dev, struct drm_crtc *crtc)
}
/** Returns the currently programmed mode of the given pipe. */
-struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
-struct drm_crtc *crtc)
+static bool i9xx_crtc_get_mode(struct drm_crtc *crtc,
+ struct drm_display_mode *mode)
{
- struct drm_i915_private *dev_priv = dev-dev_private;
+ struct drm_i915_private *dev_priv = crtc-dev-dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
enum transcoder cpu_transcoder = intel_crtc-cpu_transcoder;
- struct drm_display_mode *mode;
- int htot = I915_READ(HTOTAL(cpu_transcoder));
- int hsync = I915_READ(HSYNC(cpu_transcoder));
- int vtot = I915_READ(VTOTAL(cpu_transcoder));
- int vsync = I915_READ(VSYNC(cpu_transcoder));
+ u32