drm/nouveau/pageflip: kick flip handling out of engsw and into fence

This is all very much a policy thing, and hence will not belong in SW
after the rework.

engsw now only handles receiving the event to say "can flip now" and makes
a callback to perform the actual work.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Ben Skeggs
2012-07-22 11:55:54 +10:00
parent bc9e7b9a61
commit f589be88ca
17 ha cambiato i file con 265 aggiunte e 114 eliminazioni

Vedi File

@@ -28,6 +28,7 @@
#include <engine/fifo.h>
#include <core/ramht.h>
#include "nouveau_fence.h"
#include "nv50_display.h"
struct nvc0_fence_priv {
struct nouveau_fence_priv base;
@@ -38,8 +39,16 @@ struct nvc0_fence_priv {
struct nvc0_fence_chan {
struct nouveau_fence_chan base;
struct nouveau_vma vma;
struct nouveau_vma dispc_vma[4];
};
u64
nvc0_fence_crtc(struct nouveau_channel *chan, int crtc)
{
struct nvc0_fence_chan *fctx = chan->fence;
return fctx->dispc_vma[crtc].offset;
}
static int
nvc0_fence_emit(struct nouveau_fence *fence)
{
@@ -94,9 +103,25 @@ nvc0_fence_read(struct nouveau_channel *chan)
static void
nvc0_fence_context_del(struct nouveau_channel *chan)
{
struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nvc0_fence_priv *priv = dev_priv->fence.func;
struct nvc0_fence_chan *fctx = chan->fence;
int i;
if (dev_priv->card_type >= NV_D0) {
for (i = 0; i < dev->mode_config.num_crtc; i++) {
struct nouveau_bo *bo = nvd0_display_crtc_sema(dev, i);
nouveau_bo_vma_del(bo, &fctx->dispc_vma[i]);
}
} else
if (dev_priv->card_type >= NV_50) {
struct nv50_display *disp = nv50_display(dev);
for (i = 0; i < dev->mode_config.num_crtc; i++) {
struct nv50_display_crtc *dispc = &disp->crtc[i];
nouveau_bo_vma_del(dispc->sem.bo, &fctx->dispc_vma[i]);
}
}
nouveau_bo_vma_del(priv->bo, &fctx->vma);
nouveau_fence_context_del(&fctx->base);
@@ -107,10 +132,11 @@ nvc0_fence_context_del(struct nouveau_channel *chan)
static int
nvc0_fence_context_new(struct nouveau_channel *chan)
{
struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nvc0_fence_priv *priv = dev_priv->fence.func;
struct nvc0_fence_chan *fctx;
int ret;
int ret, i;
fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL);
if (!fctx)
@@ -122,6 +148,17 @@ nvc0_fence_context_new(struct nouveau_channel *chan)
if (ret)
nvc0_fence_context_del(chan);
/* map display semaphore buffers into channel's vm */
for (i = 0; !ret && i < dev->mode_config.num_crtc; i++) {
struct nouveau_bo *bo;
if (dev_priv->card_type >= NV_D0)
bo = nvd0_display_crtc_sema(dev, i);
else
bo = nv50_display(dev)->crtc[i].sem.bo;
ret = nouveau_bo_vma_add(bo, chan->vm, &fctx->dispc_vma[i]);
}
nouveau_bo_wr32(priv->bo, chan->id * 16/4, 0x00000000);
return ret;
}