summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nvc0_software.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-04-30 11:34:10 -0500
committerBen Skeggs <bskeggs@redhat.com>2012-05-24 16:55:43 +1000
commit35bcf5d55540e47091a67e5962f12b88d51d7131 (patch)
tree162d17e735b85817c8c6c881093995a2e6eef336 /drivers/gpu/drm/nouveau/nvc0_software.c
parent20abd1634a6e2eedb84ca977adea56b8aa06cc3e (diff)
downloadtalos-obmc-linux-35bcf5d55540e47091a67e5962f12b88d51d7131.tar.gz
talos-obmc-linux-35bcf5d55540e47091a67e5962f12b88d51d7131.zip
drm/nouveau: move flip-related channel setup to software engine
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvc0_software.c')
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_software.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/nvc0_software.c b/drivers/gpu/drm/nouveau/nvc0_software.c
index a1b43f580995..93e8c164fec6 100644
--- a/drivers/gpu/drm/nouveau/nvc0_software.c
+++ b/drivers/gpu/drm/nouveau/nvc0_software.c
@@ -23,22 +23,37 @@
*/
#include "drmP.h"
+
#include "nouveau_drv.h"
#include "nouveau_ramht.h"
#include "nouveau_software.h"
+#include "nv50_display.h"
+
struct nvc0_software_priv {
struct nouveau_software_priv base;
};
struct nvc0_software_chan {
struct nouveau_software_chan base;
+ struct nouveau_vma dispc_vma[4];
};
+u64
+nvc0_software_crtc(struct nouveau_channel *chan, int crtc)
+{
+ struct nvc0_software_chan *pch = chan->engctx[NVOBJ_ENGINE_SW];
+ return pch->dispc_vma[crtc].offset;
+}
+
static int
nvc0_software_context_new(struct nouveau_channel *chan, int engine)
{
+ struct drm_device *dev = chan->dev;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nvc0_software_priv *psw = nv_engine(dev, NVOBJ_ENGINE_SW);
struct nvc0_software_chan *pch;
+ int ret = 0, i;
pch = kzalloc(sizeof(*pch), GFP_KERNEL);
if (!pch)
@@ -46,13 +61,45 @@ nvc0_software_context_new(struct nouveau_channel *chan, int engine)
nouveau_software_context_new(&pch->base);
chan->engctx[engine] = pch;
- return 0;
+
+ /* 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, &pch->dispc_vma[i]);
+ }
+
+ if (ret)
+ psw->base.base.context_del(chan, engine);
+ return ret;
}
static void
nvc0_software_context_del(struct nouveau_channel *chan, int engine)
{
+ struct drm_device *dev = chan->dev;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nvc0_software_chan *pch = chan->engctx[engine];
+ 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, &pch->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, &pch->dispc_vma[i]);
+ }
+ }
+
chan->engctx[engine] = NULL;
kfree(pch);
}
OpenPOWER on IntegriCloud