Skip to content

Commit

Permalink
drm/i915: IBX+ doesn't have separate vsync/hsync controls on the VGA DAC
Browse files Browse the repository at this point in the history
When the PCH split occurred, hw dropped support for separate hsync and
vsync disable in the VGA DAC.  So add a PCH specific DPMS function that
just uses the port enable bit for controlling DPMS states.

Before this fix, when anything other than a full DPMS off occurred,
the VGA port would be left enabled and scanning out while all the other
heads would turn off as expected.

v2: duplicate encoder helper vtable into pch and gmch versions (Daniel)

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=48491
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
[danvet: s/intel_crt_dpms/gmch_crt_dpms as suggested by Chris.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Jesse Barnes authored and Daniel Vetter committed Apr 18, 2012
1 parent 446f254 commit df0323c
Showing 1 changed file with 43 additions and 11 deletions.
54 changes: 43 additions & 11 deletions drivers/gpu/drm/i915/intel_crt.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,36 @@ static struct intel_crt *intel_attached_crt(struct drm_connector *connector)
struct intel_crt, base);
}

static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
static void pch_crt_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 temp, reg;
u32 temp;

if (HAS_PCH_SPLIT(dev))
reg = PCH_ADPA;
else
reg = ADPA;
temp = I915_READ(PCH_ADPA);
temp &= ~ADPA_DAC_ENABLE;

switch (mode) {
case DRM_MODE_DPMS_ON:
temp |= ADPA_DAC_ENABLE;
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
/* Just leave port enable cleared */
break;
}

I915_WRITE(PCH_ADPA, temp);
}

temp = I915_READ(reg);
static void gmch_crt_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 temp;

temp = I915_READ(ADPA);
temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
temp &= ~ADPA_DAC_ENABLE;

Expand All @@ -85,7 +103,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
break;
}

I915_WRITE(reg, temp);
I915_WRITE(ADPA, temp);
}

static int intel_crt_mode_valid(struct drm_connector *connector,
Expand Down Expand Up @@ -516,12 +534,20 @@ static void intel_crt_reset(struct drm_connector *connector)
* Routines for controlling stuff on the analog port
*/

static const struct drm_encoder_helper_funcs intel_crt_helper_funcs = {
.dpms = intel_crt_dpms,
static const struct drm_encoder_helper_funcs pch_encoder_funcs = {
.mode_fixup = intel_crt_mode_fixup,
.prepare = intel_encoder_prepare,
.commit = intel_encoder_commit,
.mode_set = intel_crt_mode_set,
.dpms = pch_crt_dpms,
};

static const struct drm_encoder_helper_funcs gmch_encoder_funcs = {
.mode_fixup = intel_crt_mode_fixup,
.prepare = intel_encoder_prepare,
.commit = intel_encoder_commit,
.mode_set = intel_crt_mode_set,
.dpms = gmch_crt_dpms,
};

static const struct drm_connector_funcs intel_crt_connector_funcs = {
Expand Down Expand Up @@ -567,6 +593,7 @@ void intel_crt_init(struct drm_device *dev)
struct intel_crt *crt;
struct intel_connector *intel_connector;
struct drm_i915_private *dev_priv = dev->dev_private;
const struct drm_encoder_helper_funcs *encoder_helper_funcs;

/* Skip machines without VGA that falsely report hotplug events */
if (dmi_check_system(intel_no_crt))
Expand Down Expand Up @@ -602,7 +629,12 @@ void intel_crt_init(struct drm_device *dev)
connector->interlace_allowed = 1;
connector->doublescan_allowed = 0;

drm_encoder_helper_add(&crt->base.base, &intel_crt_helper_funcs);
if (HAS_PCH_SPLIT(dev))
encoder_helper_funcs = &pch_encoder_funcs;
else
encoder_helper_funcs = &gmch_encoder_funcs;

drm_encoder_helper_add(&crt->base.base, encoder_helper_funcs);
drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);

drm_sysfs_connector_add(connector);
Expand Down

0 comments on commit df0323c

Please sign in to comment.