aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-12-07 18:00:20 -0500
committerChris Wilson <chris@chris-wilson.co.uk>2010-12-07 18:02:08 -0500
commit1a1c69762a14f50dd574a9cbabbfa1b1542f580e (patch)
tree117fc29dc9f936f0125e08206c9a60a4e5ffbad7 /drivers/gpu/drm/i915
parent0be732841fb925b6f1242211ea211c022b6ac26c (diff)
parent1b39d6f37622f1da70aa2cfd38bfff9a52c13e05 (diff)
Merge branch 'drm-intel-fixes' into drm-intel-next
Conflicts: drivers/gpu/drm/i915/i915_gem.c drivers/gpu/drm/i915/intel_dp.c
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c17
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c7
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c98
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c30
4 files changed, 91 insertions, 61 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b57ce033e42a..27fa2a1b26a5 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3356,9 +3356,24 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
3356 * use this buffer rather sooner than later, so issuing the required 3356 * use this buffer rather sooner than later, so issuing the required
3357 * flush earlier is beneficial. 3357 * flush earlier is beneficial.
3358 */ 3358 */
3359 if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) 3359 if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) {
3360 i915_gem_flush_ring(dev, obj->ring, 3360 i915_gem_flush_ring(dev, obj->ring,
3361 0, obj->base.write_domain); 3361 0, obj->base.write_domain);
3362 } else if (obj->ring->outstanding_lazy_request ==
3363 obj->last_rendering_seqno) {
3364 struct drm_i915_gem_request *request;
3365
3366 /* This ring is not being cleared by active usage,
3367 * so emit a request to do so.
3368 */
3369 request = kzalloc(sizeof(*request), GFP_KERNEL);
3370 if (request)
3371 ret = i915_add_request(dev,
3372 NULL, request,
3373 obj->ring);
3374 else
3375 ret = -ENOMEM;
3376 }
3362 3377
3363 /* Update the active list for the hardware's current position. 3378 /* Update the active list for the hardware's current position.
3364 * Otherwise this only updates on a delayed timer or when irqs 3379 * Otherwise this only updates on a delayed timer or when irqs
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 2c9601f2f208..63101230b78d 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1376,6 +1376,9 @@ intel_dp_link_down(struct intel_dp *intel_dp)
1376 struct drm_i915_private *dev_priv = dev->dev_private; 1376 struct drm_i915_private *dev_priv = dev->dev_private;
1377 uint32_t DP = intel_dp->DP; 1377 uint32_t DP = intel_dp->DP;
1378 1378
1379 if ((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0)
1380 return;
1381
1379 DRM_DEBUG_KMS("\n"); 1382 DRM_DEBUG_KMS("\n");
1380 1383
1381 if (is_edp(intel_dp)) { 1384 if (is_edp(intel_dp)) {
@@ -1399,9 +1402,9 @@ intel_dp_link_down(struct intel_dp *intel_dp)
1399 if (is_edp(intel_dp)) 1402 if (is_edp(intel_dp))
1400 DP |= DP_LINK_TRAIN_OFF; 1403 DP |= DP_LINK_TRAIN_OFF;
1401 1404
1402 if (!HAS_PCH_CPT(dev) && (DP & DP_PIPEB_SELECT)) { 1405 if (!HAS_PCH_CPT(dev) &&
1406 I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
1403 struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); 1407 struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc);
1404
1405 /* Hardware workaround: leaving our transcoder select 1408 /* Hardware workaround: leaving our transcoder select
1406 * set to transcoder B while it's off will prevent the 1409 * set to transcoder B while it's off will prevent the
1407 * corresponding HDMI output on transcoder A. 1410 * corresponding HDMI output on transcoder A.
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 6d1106eafcfd..aa2307080be2 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -68,7 +68,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector)
68/** 68/**
69 * Sets the power state for the panel. 69 * Sets the power state for the panel.
70 */ 70 */
71static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on) 71static void intel_lvds_enable(struct intel_lvds *intel_lvds)
72{ 72{
73 struct drm_device *dev = intel_lvds->base.base.dev; 73 struct drm_device *dev = intel_lvds->base.base.dev;
74 struct drm_i915_private *dev_priv = dev->dev_private; 74 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -82,26 +82,61 @@ static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on)
82 lvds_reg = LVDS; 82 lvds_reg = LVDS;
83 } 83 }
84 84
85 if (on) { 85 I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN);
86 I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN);
87 I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
88 intel_panel_set_backlight(dev, dev_priv->backlight_level);
89 } else {
90 dev_priv->backlight_level = intel_panel_get_backlight(dev);
91
92 intel_panel_set_backlight(dev, 0);
93 I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
94 86
95 if (intel_lvds->pfit_control) { 87 if (intel_lvds->pfit_dirty) {
96 if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) 88 /*
97 DRM_ERROR("timed out waiting for panel to power off\n"); 89 * Enable automatic panel scaling so that non-native modes
98 I915_WRITE(PFIT_CONTROL, 0); 90 * fill the screen. The panel fitter should only be
99 intel_lvds->pfit_control = 0; 91 * adjusted whilst the pipe is disabled, according to
92 * register description and PRM.
93 */
94 DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
95 intel_lvds->pfit_control,
96 intel_lvds->pfit_pgm_ratios);
97 if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) {
98 DRM_ERROR("timed out waiting for panel to power off\n");
99 } else {
100 I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios);
101 I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control);
100 intel_lvds->pfit_dirty = false; 102 intel_lvds->pfit_dirty = false;
101 } 103 }
104 }
105
106 I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
107 POSTING_READ(lvds_reg);
108
109 intel_panel_set_backlight(dev, dev_priv->backlight_level);
110}
102 111
103 I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); 112static void intel_lvds_disable(struct intel_lvds *intel_lvds)
113{
114 struct drm_device *dev = intel_lvds->base.base.dev;
115 struct drm_i915_private *dev_priv = dev->dev_private;
116 u32 ctl_reg, lvds_reg;
117
118 if (HAS_PCH_SPLIT(dev)) {
119 ctl_reg = PCH_PP_CONTROL;
120 lvds_reg = PCH_LVDS;
121 } else {
122 ctl_reg = PP_CONTROL;
123 lvds_reg = LVDS;
124 }
125
126 dev_priv->backlight_level = intel_panel_get_backlight(dev);
127 intel_panel_set_backlight(dev, 0);
128
129 I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
130
131 if (intel_lvds->pfit_control) {
132 if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000))
133 DRM_ERROR("timed out waiting for panel to power off\n");
134
135 I915_WRITE(PFIT_CONTROL, 0);
136 intel_lvds->pfit_dirty = true;
104 } 137 }
138
139 I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN);
105 POSTING_READ(lvds_reg); 140 POSTING_READ(lvds_reg);
106} 141}
107 142
@@ -110,9 +145,9 @@ static void intel_lvds_dpms(struct drm_encoder *encoder, int mode)
110 struct intel_lvds *intel_lvds = to_intel_lvds(encoder); 145 struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
111 146
112 if (mode == DRM_MODE_DPMS_ON) 147 if (mode == DRM_MODE_DPMS_ON)
113 intel_lvds_set_power(intel_lvds, true); 148 intel_lvds_enable(intel_lvds);
114 else 149 else
115 intel_lvds_set_power(intel_lvds, false); 150 intel_lvds_disable(intel_lvds);
116 151
117 /* XXX: We never power down the LVDS pairs. */ 152 /* XXX: We never power down the LVDS pairs. */
118} 153}
@@ -414,43 +449,18 @@ static void intel_lvds_commit(struct drm_encoder *encoder)
414 /* Always do a full power on as we do not know what state 449 /* Always do a full power on as we do not know what state
415 * we were left in. 450 * we were left in.
416 */ 451 */
417 intel_lvds_set_power(intel_lvds, true); 452 intel_lvds_enable(intel_lvds);
418} 453}
419 454
420static void intel_lvds_mode_set(struct drm_encoder *encoder, 455static void intel_lvds_mode_set(struct drm_encoder *encoder,
421 struct drm_display_mode *mode, 456 struct drm_display_mode *mode,
422 struct drm_display_mode *adjusted_mode) 457 struct drm_display_mode *adjusted_mode)
423{ 458{
424 struct drm_device *dev = encoder->dev;
425 struct drm_i915_private *dev_priv = dev->dev_private;
426 struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
427
428 /* 459 /*
429 * The LVDS pin pair will already have been turned on in the 460 * The LVDS pin pair will already have been turned on in the
430 * intel_crtc_mode_set since it has a large impact on the DPLL 461 * intel_crtc_mode_set since it has a large impact on the DPLL
431 * settings. 462 * settings.
432 */ 463 */
433
434 if (HAS_PCH_SPLIT(dev))
435 return;
436
437 if (!intel_lvds->pfit_dirty)
438 return;
439
440 /*
441 * Enable automatic panel scaling so that non-native modes fill the
442 * screen. Should be enabled before the pipe is enabled, according to
443 * register description and PRM.
444 */
445 DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
446 intel_lvds->pfit_control,
447 intel_lvds->pfit_pgm_ratios);
448 if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000))
449 DRM_ERROR("timed out waiting for panel to power off\n");
450
451 I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios);
452 I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control);
453 intel_lvds->pfit_dirty = false;
454} 464}
455 465
456/** 466/**
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 0ee78525959a..67c545204f19 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -157,23 +157,25 @@ static int init_ring_common(struct intel_ring_buffer *ring)
157 157
158 /* G45 ring initialization fails to reset head to zero */ 158 /* G45 ring initialization fails to reset head to zero */
159 if (head != 0) { 159 if (head != 0) {
160 DRM_ERROR("%s head not reset to zero " 160 DRM_DEBUG_KMS("%s head not reset to zero "
161 "ctl %08x head %08x tail %08x start %08x\n", 161 "ctl %08x head %08x tail %08x start %08x\n",
162 ring->name, 162 ring->name,
163 I915_READ_CTL(ring), 163 I915_READ_CTL(ring),
164 I915_READ_HEAD(ring), 164 I915_READ_HEAD(ring),
165 I915_READ_TAIL(ring), 165 I915_READ_TAIL(ring),
166 I915_READ_START(ring)); 166 I915_READ_START(ring));
167 167
168 I915_WRITE_HEAD(ring, 0); 168 I915_WRITE_HEAD(ring, 0);
169 169
170 DRM_ERROR("%s head forced to zero " 170 if (I915_READ_HEAD(ring) & HEAD_ADDR) {
171 "ctl %08x head %08x tail %08x start %08x\n", 171 DRM_ERROR("failed to set %s head to zero "
172 ring->name, 172 "ctl %08x head %08x tail %08x start %08x\n",
173 I915_READ_CTL(ring), 173 ring->name,
174 I915_READ_HEAD(ring), 174 I915_READ_CTL(ring),
175 I915_READ_TAIL(ring), 175 I915_READ_HEAD(ring),
176 I915_READ_START(ring)); 176 I915_READ_TAIL(ring),
177 I915_READ_START(ring));
178 }
177 } 179 }
178 180
179 I915_WRITE_CTL(ring, 181 I915_WRITE_CTL(ring,