summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nouveau_drm.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2013-01-30 23:23:34 (GMT)
committerBen Skeggs <bskeggs@redhat.com>2013-02-20 06:00:46 (GMT)
commit1d7c71a3e2f77336df536855b0efd2dc5bdeb41b (patch)
tree8343ee580c5de2abcab27bc1bf51a7f44563e4d2 /drivers/gpu/drm/nouveau/nouveau_drm.c
parent21a5ace0bfb737d65e6d345ccf3d63fdee141f98 (diff)
downloadlinux-fsl-qoriq-1d7c71a3e2f77336df536855b0efd2dc5bdeb41b.tar.xz
drm/nouveau/disp: port vblank handling to event interface
This removes the nastiness with the interactions between display and software engines when handling vblank semaphore release interrupts. Now, all the semantics are handled in one place (sw) \o/. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_drm.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index ef1ad21..ce91c8d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -34,6 +34,8 @@
#include <subdev/device.h>
#include <subdev/vm.h>
+#include <engine/disp.h>
+
#include "nouveau_drm.h"
#include "nouveau_irq.h"
#include "nouveau_dma.h"
@@ -68,6 +70,32 @@ module_param_named(modeset, nouveau_modeset, int, 0400);
static struct drm_driver driver;
+static int
+nouveau_drm_vblank_enable(struct drm_device *dev, int head)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_disp *pdisp = nouveau_disp(drm->device);
+ nouveau_event_get(pdisp->vblank, head, &drm->vblank);
+ return 0;
+}
+
+static void
+nouveau_drm_vblank_disable(struct drm_device *dev, int head)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_disp *pdisp = nouveau_disp(drm->device);
+ nouveau_event_put(pdisp->vblank, head, &drm->vblank);
+}
+
+static int
+nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head)
+{
+ struct nouveau_drm *drm =
+ container_of(event, struct nouveau_drm, vblank);
+ drm_handle_vblank(drm->dev, head);
+ return NVKM_EVENT_KEEP;
+}
+
static u64
nouveau_name(struct pci_dev *pdev)
{
@@ -259,6 +287,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
dev->dev_private = drm;
drm->dev = dev;
+ drm->vblank.func = nouveau_drm_vblank_handler;
INIT_LIST_HEAD(&drm->clients);
spin_lock_init(&drm->tile.lock);
@@ -643,8 +672,8 @@ driver = {
.irq_handler = nouveau_irq_handler,
.get_vblank_counter = drm_vblank_count,
- .enable_vblank = nouveau_vblank_enable,
- .disable_vblank = nouveau_vblank_disable,
+ .enable_vblank = nouveau_drm_vblank_enable,
+ .disable_vblank = nouveau_drm_vblank_disable,
.ioctls = nouveau_ioctls,
.fops = &nouveau_driver_fops,