aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nouveau_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_display.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index e0a56b277884..a60a9f51e890 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -33,10 +33,10 @@
#include "nouveau_crtc.h"
#include "nouveau_dma.h"
#include "nouveau_connector.h"
-#include "nouveau_software.h"
-#include "nouveau_fence.h"
#include "nv50_display.h"
+#include "nouveau_fence.h"
+
#include <subdev/bios/gpio.h>
static void
@@ -260,6 +260,24 @@ nouveau_display_fini(struct drm_device *dev)
disp->fini(dev);
}
+static void
+nouveau_display_vblank_notify(void *data, int crtc)
+{
+ drm_handle_vblank(data, crtc);
+}
+
+static void
+nouveau_display_vblank_get(void *data, int crtc)
+{
+ drm_vblank_get(data, crtc);
+}
+
+static void
+nouveau_display_vblank_put(void *data, int crtc)
+{
+ drm_vblank_put(data, crtc);
+}
+
int
nouveau_display_create(struct drm_device *dev)
{
@@ -365,6 +383,10 @@ nouveau_vblank_enable(struct drm_device *dev, int crtc)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
+ if (dev_priv->card_type >= NV_D0)
+ nv_mask(dev, 0x6100c0 + (crtc * 0x800), 1, 1);
+ else
+
if (dev_priv->card_type >= NV_50)
nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, 0,
NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(crtc));
@@ -380,6 +402,9 @@ nouveau_vblank_disable(struct drm_device *dev, int crtc)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
+ if (dev_priv->card_type >= NV_D0)
+ nv_mask(dev, 0x6100c0 + (crtc * 0x800), 1, 0);
+ else
if (dev_priv->card_type >= NV_50)
nv_mask(dev, NV50_PDISPLAY_INTR_EN_1,
NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(crtc), 0);
@@ -436,8 +461,8 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
struct nouveau_fence **pfence)
{
struct nouveau_fence_chan *fctx = chan->fence;
- struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
- struct drm_device *dev = chan->dev;
+ struct drm_device *dev = nouveau_drv(chan->drm);
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
unsigned long flags;
int ret;
@@ -492,7 +517,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct nouveau_fence *fence;
int ret;
- if (!dev_priv->channel)
+ if (!nvdrm_channel(dev))
return -ENODEV;
s = kzalloc(sizeof(*s), GFP_KERNEL);
@@ -513,10 +538,10 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
/* Choose the channel the flip will be handled in */
fence = new_bo->bo.sync_obj;
if (fence)
- chan = nouveau_channel_get_unlocked(fence->channel);
+ chan = fence->channel;
if (!chan)
- chan = nouveau_channel_get_unlocked(dev_priv->channel);
- mutex_lock(&chan->mutex);
+ chan = nvdrm_channel(dev);
+ mutex_lock(nvchan_mutex(chan));
/* Emit a page flip */
if (dev_priv->card_type >= NV_50) {
@@ -525,13 +550,13 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
else
ret = nv50_display_flip_next(crtc, fb, chan);
if (ret) {
- nouveau_channel_put(&chan);
+ mutex_unlock(nvchan_mutex(chan));
goto fail_unreserve;
}
}
ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence);
- nouveau_channel_put(&chan);
+ mutex_unlock(nvchan_mutex(chan));
if (ret)
goto fail_unreserve;
@@ -554,14 +579,14 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
struct nouveau_page_flip_state *ps)
{
struct nouveau_fence_chan *fctx = chan->fence;
- struct drm_device *dev = chan->dev;
+ struct drm_device *dev = nouveau_drv(chan->drm);
struct nouveau_page_flip_state *s;
unsigned long flags;
spin_lock_irqsave(&dev->event_lock, flags);
if (list_empty(&fctx->flip)) {
- NV_ERROR(dev, "Unexpected pageflip in channel %d.\n", chan->id);
+ NV_ERROR(dev, "unexpected pageflip\n");
spin_unlock_irqrestore(&dev->event_lock, flags);
return -EINVAL;
}
@@ -592,7 +617,7 @@ int
nouveau_flip_complete(void *data)
{
struct nouveau_channel *chan = data;
- struct drm_device *dev = chan->dev;
+ struct drm_device *dev = nouveau_drv(chan->drm);
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_page_flip_state state;