diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-12-07 18:00:20 -0500 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-12-07 18:02:08 -0500 |
commit | 1a1c69762a14f50dd574a9cbabbfa1b1542f580e (patch) | |
tree | 117fc29dc9f936f0125e08206c9a60a4e5ffbad7 | |
parent | 0be732841fb925b6f1242211ea211c022b6ac26c (diff) | |
parent | 1b39d6f37622f1da70aa2cfd38bfff9a52c13e05 (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
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 98 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 30 |
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 | */ |
71 | static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on) | 71 | static 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); | 112 | static 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 | ||
420 | static void intel_lvds_mode_set(struct drm_encoder *encoder, | 455 | static 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, |