Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 218290
b: refs/heads/master
c: 01cb9ea
h: refs/heads/master
v: v3
  • Loading branch information
Jesse Barnes authored and Chris Wilson committed Oct 8, 2010
1 parent 50eca6f commit 9212aec
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 46 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5c5313c8db9bfb549e080fc4cb0a4c3c2aa7a73d
refs/heads/master: 01cb9ea633ddf3e8770dfe7851e88610087098bc
3 changes: 3 additions & 0 deletions trunk/drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -1373,6 +1373,9 @@
#define PP_SEQUENCE_ON (1 << 28)
#define PP_SEQUENCE_OFF (2 << 28)
#define PP_SEQUENCE_MASK 0x30000000
#define PP_CYCLE_DELAY_ACTIVE (1 << 27)
#define PP_SEQUENCE_STATE_ON_IDLE (1 << 3)
#define PP_SEQUENCE_STATE_MASK 0x0000000f
#define PP_CONTROL 0x61204
#define POWER_TARGET_ON (1 << 0)
#define PP_ON_DELAYS 0x61208
Expand Down
77 changes: 32 additions & 45 deletions trunk/drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -788,10 +788,11 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
}

/* Returns true if the panel was already on when called */
static bool ironlake_edp_panel_on (struct drm_device *dev)
static bool ironlake_edp_panel_on (struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp;
u32 pp, idle_on_mask = PP_ON | PP_SEQUENCE_STATE_ON_IDLE;

if (I915_READ(PCH_PP_STATUS) & PP_ON)
return true;
Expand All @@ -803,19 +804,20 @@ static bool ironlake_edp_panel_on (struct drm_device *dev)
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);

pp |= POWER_TARGET_ON;
pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON;
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);

/* Ouch. We need to wait here for some panels, like Dell e6510
* https://bugs.freedesktop.org/show_bug.cgi?id=29278i
*/
msleep(300);

if (wait_for(I915_READ(PCH_PP_STATUS) & PP_ON, 5000))
if (wait_for((I915_READ(PCH_PP_STATUS) & idle_on_mask) == idle_on_mask,
5000))
DRM_ERROR("panel on wait timed out: 0x%08x\n",
I915_READ(PCH_PP_STATUS));

pp &= ~(PANEL_UNLOCK_REGS);
pp |= PANEL_POWER_RESET; /* restore panel reset bit */
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);
Expand All @@ -826,7 +828,8 @@ static bool ironlake_edp_panel_on (struct drm_device *dev)
static void ironlake_edp_panel_off (struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp;
u32 pp, idle_off_mask = PP_ON | PP_SEQUENCE_MASK |
PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK;

pp = I915_READ(PCH_PP_CONTROL);

Expand All @@ -837,12 +840,12 @@ static void ironlake_edp_panel_off (struct drm_device *dev)

pp &= ~POWER_TARGET_ON;
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);

if (wait_for((I915_READ(PCH_PP_STATUS) & PP_ON) == 0, 5000))
if (wait_for((I915_READ(PCH_PP_STATUS) & idle_off_mask) == 0, 5000))
DRM_ERROR("panel off wait timed out: 0x%08x\n",
I915_READ(PCH_PP_STATUS));

/* Make sure VDD is enabled so DP AUX will work */
pp |= PANEL_POWER_RESET; /* restore panel reset bit */
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);
Expand All @@ -853,36 +856,19 @@ static void ironlake_edp_panel_off (struct drm_device *dev)
msleep(300);
}

static void ironlake_edp_panel_vdd_on(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp;

pp = I915_READ(PCH_PP_CONTROL);
pp |= EDP_FORCE_VDD;
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);
msleep(300);
}

static void ironlake_edp_panel_vdd_off(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp;

pp = I915_READ(PCH_PP_CONTROL);
pp &= ~EDP_FORCE_VDD;
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);
msleep(300);
}

static void ironlake_edp_backlight_on (struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp;

DRM_DEBUG_KMS("\n");
/*
* If we enable the backlight right away following a panel power
* on, we may see slight flicker as the panel syncs with the eDP
* link. So delay a bit to make sure the image is solid before
* allowing it to appear.
*/
msleep(300);
pp = I915_READ(PCH_PP_CONTROL);
pp |= EDP_BLC_ENABLE;
I915_WRITE(PCH_PP_CONTROL, pp);
Expand Down Expand Up @@ -932,10 +918,12 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
uint32_t dp_reg = I915_READ(intel_dp->output_reg);

if (is_edp(intel_dp)) {
ironlake_edp_panel_off(dev);
ironlake_edp_backlight_off(dev);
ironlake_edp_panel_vdd_on(dev);
ironlake_edp_pll_on(encoder);
ironlake_edp_panel_on(intel_dp);
if (!is_pch_edp(intel_dp))
ironlake_edp_pll_on(encoder);
else
ironlake_edp_pll_off(encoder);
}
if (dp_reg & DP_PORT_EN)
intel_dp_link_down(intel_dp);
Expand All @@ -949,7 +937,7 @@ static void intel_dp_commit(struct drm_encoder *encoder)
intel_dp_start_link_train(intel_dp);

if (is_edp(intel_dp))
ironlake_edp_panel_on(dev);
ironlake_edp_panel_on(intel_dp);

intel_dp_complete_link_train(intel_dp);

Expand All @@ -966,19 +954,19 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
uint32_t dp_reg = I915_READ(intel_dp->output_reg);

if (mode != DRM_MODE_DPMS_ON) {
if (is_edp(intel_dp)) {
if (is_edp(intel_dp))
ironlake_edp_backlight_off(dev);
ironlake_edp_panel_off(dev);
}
if (dp_reg & DP_PORT_EN)
intel_dp_link_down(intel_dp);
if (is_edp(intel_dp))
ironlake_edp_panel_off(dev);
if (is_edp(intel_dp) && !is_pch_edp(intel_dp))
ironlake_edp_pll_off(encoder);
} else {
if (!(dp_reg & DP_PORT_EN)) {
intel_dp_start_link_train(intel_dp);
if (is_edp(intel_dp))
ironlake_edp_panel_on(dev);
ironlake_edp_panel_on(intel_dp);
intel_dp_start_link_train(intel_dp);
intel_dp_complete_link_train(intel_dp);
if (is_edp(intel_dp))
ironlake_edp_backlight_on(dev);
Expand Down Expand Up @@ -1445,9 +1433,10 @@ ironlake_dp_detect(struct drm_connector *connector)
struct intel_dp *intel_dp = intel_attached_dp(connector);
enum drm_connector_status status;

/* Panel needs power for AUX to work */
/* Can't disconnect eDP */
if (is_edp(intel_dp))
ironlake_edp_panel_vdd_on(connector->dev);
return connector_status_connected;

status = connector_status_disconnected;
if (intel_dp_aux_native_read(intel_dp,
0x000, intel_dp->dpcd,
Expand All @@ -1458,8 +1447,6 @@ ironlake_dp_detect(struct drm_connector *connector)
}
DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0],
intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]);
if (is_edp(intel_dp))
ironlake_edp_panel_vdd_off(connector->dev);
return status;
}

Expand Down

0 comments on commit 9212aec

Please sign in to comment.