aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-10-05 21:51:45 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-12-21 04:01:15 -0500
commit549cd872b0777bd72a66daa56558af28ec20d8a5 (patch)
tree24e3855e21d373634da7e679cb83c821bf1a4749 /drivers/gpu
parentb2337f2333c0bdefc9b230da17ed7188e4eb7f6c (diff)
drm/nv50/crtc: disable flip overlay around scaling mode changes
Prevents EVO getting all angry at us. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/nv50_crtc.c79
1 files changed, 40 insertions, 39 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c
index 882080e0b4f5..8eb108b28eb1 100644
--- a/drivers/gpu/drm/nouveau/nv50_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
@@ -38,6 +38,39 @@
38#include "nouveau_connector.h" 38#include "nouveau_connector.h"
39#include "nv50_display.h" 39#include "nv50_display.h"
40 40
41static int
42nv50_crtc_wait_complete(struct drm_crtc *crtc)
43{
44 struct drm_device *dev = crtc->dev;
45 struct drm_nouveau_private *dev_priv = dev->dev_private;
46 struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
47 struct nv50_display *disp = nv50_display(dev);
48 struct nouveau_channel *evo = disp->master;
49 u64 start;
50 int ret;
51
52 ret = RING_SPACE(evo, 6);
53 if (ret)
54 return ret;
55 BEGIN_RING(evo, 0, 0x0084, 1);
56 OUT_RING (evo, 0x80000000);
57 BEGIN_RING(evo, 0, 0x0080, 1);
58 OUT_RING (evo, 0);
59 BEGIN_RING(evo, 0, 0x0084, 1);
60 OUT_RING (evo, 0x00000000);
61
62 nv_wo32(disp->ntfy, 0x000, 0x00000000);
63 FIRE_RING (evo);
64
65 start = ptimer->read(dev);
66 do {
67 if (nv_ro32(disp->ntfy, 0x000))
68 return 0;
69 } while (ptimer->read(dev) - start < 2000000000ULL);
70
71 return -EBUSY;
72}
73
41static void 74static void
42nv50_crtc_lut_load(struct drm_crtc *crtc) 75nv50_crtc_lut_load(struct drm_crtc *crtc)
43{ 76{
@@ -184,10 +217,11 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, int scaling_mode, bool update)
184{ 217{
185 struct nouveau_connector *nv_connector = 218 struct nouveau_connector *nv_connector =
186 nouveau_crtc_connector_get(nv_crtc); 219 nouveau_crtc_connector_get(nv_crtc);
187 struct drm_device *dev = nv_crtc->base.dev; 220 struct drm_crtc *crtc = &nv_crtc->base;
221 struct drm_device *dev = crtc->dev;
188 struct nouveau_channel *evo = nv50_display(dev)->master; 222 struct nouveau_channel *evo = nv50_display(dev)->master;
189 struct drm_display_mode *native_mode = NULL; 223 struct drm_display_mode *native_mode = NULL;
190 struct drm_display_mode *mode = &nv_crtc->base.mode; 224 struct drm_display_mode *mode = &crtc->mode;
191 uint32_t outX, outY, horiz, vert; 225 uint32_t outX, outY, horiz, vert;
192 int ret; 226 int ret;
193 227
@@ -231,7 +265,7 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, int scaling_mode, bool update)
231 break; 265 break;
232 } 266 }
233 267
234 ret = RING_SPACE(evo, update ? 7 : 5); 268 ret = RING_SPACE(evo, 5);
235 if (ret) 269 if (ret)
236 return ret; 270 return ret;
237 271
@@ -251,9 +285,9 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, int scaling_mode, bool update)
251 OUT_RING(evo, outY << 16 | outX); 285 OUT_RING(evo, outY << 16 | outX);
252 286
253 if (update) { 287 if (update) {
254 BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); 288 nv50_display_flip_stop(crtc);
255 OUT_RING(evo, 0); 289 nv50_crtc_wait_complete(crtc);
256 FIRE_RING(evo); 290 nv50_display_flip_next(crtc, crtc->fb, NULL);
257 } 291 }
258 292
259 return 0; 293 return 0;
@@ -441,39 +475,6 @@ nv50_crtc_dpms(struct drm_crtc *crtc, int mode)
441{ 475{
442} 476}
443 477
444static int
445nv50_crtc_wait_complete(struct drm_crtc *crtc)
446{
447 struct drm_device *dev = crtc->dev;
448 struct drm_nouveau_private *dev_priv = dev->dev_private;
449 struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
450 struct nv50_display *disp = nv50_display(dev);
451 struct nouveau_channel *evo = disp->master;
452 u64 start;
453 int ret;
454
455 ret = RING_SPACE(evo, 6);
456 if (ret)
457 return ret;
458 BEGIN_RING(evo, 0, 0x0084, 1);
459 OUT_RING (evo, 0x80000000);
460 BEGIN_RING(evo, 0, 0x0080, 1);
461 OUT_RING (evo, 0);
462 BEGIN_RING(evo, 0, 0x0084, 1);
463 OUT_RING (evo, 0x00000000);
464
465 nv_wo32(disp->ntfy, 0x000, 0x00000000);
466 FIRE_RING (evo);
467
468 start = ptimer->read(dev);
469 do {
470 if (nv_ro32(disp->ntfy, 0x000))
471 return 0;
472 } while (ptimer->read(dev) - start < 2000000000ULL);
473
474 return -EBUSY;
475}
476
477static void 478static void
478nv50_crtc_prepare(struct drm_crtc *crtc) 479nv50_crtc_prepare(struct drm_crtc *crtc)
479{ 480{