aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv50_dac.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-07-01 01:33:45 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-07-12 20:13:15 -0400
commitec7fc4a1a7b322380d053fb04bfc4537be3cdfe5 (patch)
treec091a7c4a55072cf4fd455470691ef473c48e603 /drivers/gpu/drm/nouveau/nv50_dac.c
parentdf4cf1b72d726d788388858673fa61e42fdb9ad8 (diff)
drm/nv50: supply encoder disable() hook for SOR outputs
Allows us to remove a driver hack that used to be necessary to disable encoders in certain situations before setting up a mode. The DRM has better knowledge of when this is needed than the driver does. This fixes a number of display switching issues. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_dac.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv50_dac.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c
index e114f818751..f5fd35a657c 100644
--- a/drivers/gpu/drm/nouveau/nv50_dac.c
+++ b/drivers/gpu/drm/nouveau/nv50_dac.c
@@ -37,13 +37,17 @@
37#include "nv50_display.h" 37#include "nv50_display.h"
38 38
39static void 39static void
40nv50_dac_disconnect(struct nouveau_encoder *nv_encoder) 40nv50_dac_disconnect(struct drm_encoder *encoder)
41{ 41{
42 struct drm_device *dev = to_drm_encoder(nv_encoder)->dev; 42 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
43 struct drm_device *dev = encoder->dev;
43 struct drm_nouveau_private *dev_priv = dev->dev_private; 44 struct drm_nouveau_private *dev_priv = dev->dev_private;
44 struct nouveau_channel *evo = dev_priv->evo; 45 struct nouveau_channel *evo = dev_priv->evo;
45 int ret; 46 int ret;
46 47
48 if (!nv_encoder->crtc)
49 return;
50
47 NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or); 51 NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or);
48 52
49 ret = RING_SPACE(evo, 2); 53 ret = RING_SPACE(evo, 2);
@@ -53,6 +57,8 @@ nv50_dac_disconnect(struct nouveau_encoder *nv_encoder)
53 } 57 }
54 BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1); 58 BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1);
55 OUT_RING(evo, 0); 59 OUT_RING(evo, 0);
60
61 nv_encoder->crtc = NULL;
56} 62}
57 63
58static enum drm_connector_status 64static enum drm_connector_status
@@ -243,6 +249,8 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
243 BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 2); 249 BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 2);
244 OUT_RING(evo, mode_ctl); 250 OUT_RING(evo, mode_ctl);
245 OUT_RING(evo, mode_ctl2); 251 OUT_RING(evo, mode_ctl2);
252
253 nv_encoder->crtc = encoder->crtc;
246} 254}
247 255
248static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = { 256static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = {
@@ -253,7 +261,8 @@ static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = {
253 .prepare = nv50_dac_prepare, 261 .prepare = nv50_dac_prepare,
254 .commit = nv50_dac_commit, 262 .commit = nv50_dac_commit,
255 .mode_set = nv50_dac_mode_set, 263 .mode_set = nv50_dac_mode_set,
256 .detect = nv50_dac_detect 264 .detect = nv50_dac_detect,
265 .disable = nv50_dac_disconnect
257}; 266};
258 267
259static void 268static void
@@ -288,8 +297,6 @@ nv50_dac_create(struct drm_connector *connector, struct dcb_entry *entry)
288 nv_encoder->dcb = entry; 297 nv_encoder->dcb = entry;
289 nv_encoder->or = ffs(entry->or) - 1; 298 nv_encoder->or = ffs(entry->or) - 1;
290 299
291 nv_encoder->disconnect = nv50_dac_disconnect;
292
293 drm_encoder_init(connector->dev, encoder, &nv50_dac_encoder_funcs, 300 drm_encoder_init(connector->dev, encoder, &nv50_dac_encoder_funcs,
294 DRM_MODE_ENCODER_DAC); 301 DRM_MODE_ENCODER_DAC);
295 drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs); 302 drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs);