Skip to content

Commit

Permalink
drm/i915/dp: manage sink power state if possible
Browse files Browse the repository at this point in the history
On sinks with a DPCD rev of 1.1 or greater, we can send sink power
management commands to address 0x600 per section 5.1.5 of the
DisplayPort 1.1a spec.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
  • Loading branch information
Jesse Barnes authored and Keith Packard committed Jul 7, 2011
1 parent df0c237 commit c7ad381
Showing 1 changed file with 35 additions and 0 deletions.
35 changes: 35 additions & 0 deletions drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -942,11 +942,44 @@ static void ironlake_edp_pll_off(struct drm_encoder *encoder)
udelay(200);
}

/* If the sink supports it, try to set the power state appropriately */
static void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
{
int ret, i;

/* Should have a valid DPCD by this point */
if (intel_dp->dpcd[DP_DPCD_REV] < 0x11)
return;

if (mode != DRM_MODE_DPMS_ON) {
ret = intel_dp_aux_native_write_1(intel_dp, DP_SET_POWER,
DP_SET_POWER_D3);
if (ret != 1)
DRM_DEBUG_DRIVER("failed to write sink power state\n");
} else {
/*
* When turning on, we need to retry for 1ms to give the sink
* time to wake up.
*/
for (i = 0; i < 3; i++) {
ret = intel_dp_aux_native_write_1(intel_dp,
DP_SET_POWER,
DP_SET_POWER_D0);
if (ret == 1)
break;
msleep(1);
}
}
}

static void intel_dp_prepare(struct drm_encoder *encoder)
{
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct drm_device *dev = encoder->dev;

/* Wake up the sink first */
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);

if (is_edp(intel_dp)) {
ironlake_edp_backlight_off(dev);
ironlake_edp_panel_off(dev);
Expand Down Expand Up @@ -990,6 +1023,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
if (mode != DRM_MODE_DPMS_ON) {
if (is_edp(intel_dp))
ironlake_edp_backlight_off(dev);
intel_dp_sink_dpms(intel_dp, mode);
intel_dp_link_down(intel_dp);
if (is_edp(intel_dp))
ironlake_edp_panel_off(dev);
Expand All @@ -998,6 +1032,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
} else {
if (is_edp(intel_dp))
ironlake_edp_panel_vdd_on(intel_dp);
intel_dp_sink_dpms(intel_dp, mode);
if (!(dp_reg & DP_PORT_EN)) {
intel_dp_start_link_train(intel_dp);
if (is_edp(intel_dp)) {
Expand Down

0 comments on commit c7ad381

Please sign in to comment.