aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nvc0_fence.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-24 15:42:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-24 15:42:54 -0400
commitf2fde3a65e88330017b816faf2ef75f141d21375 (patch)
tree57152ab5756e7ed1c58742e7e16f13a45ff11f21 /drivers/gpu/drm/nouveau/nvc0_fence.c
parent28f3d717618156c0dcd2f497d791b578a7931d87 (diff)
parent8c914028f5ddaa417b7d0f4b7fdc24caceaa8043 (diff)
Merge branch 'drm-core-next' of git://people.freedesktop.org/~airlied/linux
Pull main drm updates from Dave Airlie: "This is the main merge window request for the drm. It's big, but jam packed will lots of features and of course 0 regressions. (okay maybe there'll be one). Highlights: - new KMS drivers for server GPU chipsets: ast, mgag200 and cirrus (qemu only). These drivers use the generic modesetting drivers. - initial prime/dma-buf support for i915, nouveau, radeon, udl and exynos - switcheroo audio support: so GPUs with HDMI can turn off the sound driver without crashing stuff. - There are some patches drifting outside drivers/gpu into x86 and EFI for better handling of multiple video adapters in Apple Macs, they've got correct acks except one trivial fixup. - Core: edid parser has better DMT and reduced blanking support, crtc properties, plane properties, - Drivers: exynos: add 2D core accel support, prime support, hdmi features intel: more Haswell support, initial Valleyview support, more hdmi infoframe fixes, update MAINTAINERS for Daniel, lots of cleanups and fixes radeon: more HDMI audio support, improved GPU lockup recovery support, remove nested mutexes, less memory copying on PCIE, fix bus master enable race (kexec), improved fence handling gma500: cleanups, 1080p support, acpi fixes nouveau: better nva3 memory reclocking, kepler accel (needs external firmware rip), async buffer moves on nv84+ hw. I've some more dma-buf patches that rely on the dma-buf merge for vmap stuff, and I've a few fixes building up, but I'd decided I'd better get rid of the main pull sooner rather than later, so the audio guys are also unblocked." Fix up trivial conflict due to some duplicated changes in drivers/gpu/drm/i915/intel_ringbuffer.c * 'drm-core-next' of git://people.freedesktop.org/~airlied/linux: (605 commits) drm/nouveau/nvd9: Fix GPIO initialisation sequence. drm/nouveau: Unregister switcheroo client on exit drm/nouveau: Check dsm on switcheroo unregister drm/nouveau: fix a minor annoyance in an output string drm/nouveau: turn a BUG into a WARN drm/nv50: decode PGRAPH DATA_ERROR = 0x24 drm/nouveau/disp: fix dithering not being enabled on some eDP macbooks drm/nvd9/copy: initialise copy engine, seems to work like nvc0 drm/nvc0/ttm: use copy engines for async buffer moves drm/nva3/ttm: use copy engine for async buffer moves drm/nv98/ttm: add in a (disabled) crypto engine buffer copy method drm/nv84/ttm: use crypto engine for async buffer copies drm/nouveau/ttm: untangle code to support accelerated buffer moves drm/nouveau/fbcon: use fence for sync, rather than notifier drm/nv98/crypt: non-stub implementation of the engine hooks drm/nouveau/fifo: turn all fifo modules into engine modules drm/nv50/graph: remove ability to do interrupt-driven context switching drm/nv50: remove manual context unload on context destruction drm/nv50: remove execution engine context saves on suspend drm/nv50/fifo: use hardware channel kickoff functionality ...
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvc0_fence.c')
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_fence.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nvc0_fence.c b/drivers/gpu/drm/nouveau/nvc0_fence.c
new file mode 100644
index 000000000000..47ab388a606e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvc0_fence.c
@@ -0,0 +1,184 @@
1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24
25#include "drmP.h"
26#include "nouveau_drv.h"
27#include "nouveau_dma.h"
28#include "nouveau_fifo.h"
29#include "nouveau_ramht.h"
30#include "nouveau_fence.h"
31
32struct nvc0_fence_priv {
33 struct nouveau_fence_priv base;
34 struct nouveau_bo *bo;
35};
36
37struct nvc0_fence_chan {
38 struct nouveau_fence_chan base;
39 struct nouveau_vma vma;
40};
41
42static int
43nvc0_fence_emit(struct nouveau_fence *fence)
44{
45 struct nouveau_channel *chan = fence->channel;
46 struct nvc0_fence_chan *fctx = chan->engctx[NVOBJ_ENGINE_FENCE];
47 u64 addr = fctx->vma.offset + chan->id * 16;
48 int ret;
49
50 ret = RING_SPACE(chan, 5);
51 if (ret == 0) {
52 BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
53 OUT_RING (chan, upper_32_bits(addr));
54 OUT_RING (chan, lower_32_bits(addr));
55 OUT_RING (chan, fence->sequence);
56 OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG);
57 FIRE_RING (chan);
58 }
59
60 return ret;
61}
62
63static int
64nvc0_fence_sync(struct nouveau_fence *fence,
65 struct nouveau_channel *prev, struct nouveau_channel *chan)
66{
67 struct nvc0_fence_chan *fctx = chan->engctx[NVOBJ_ENGINE_FENCE];
68 u64 addr = fctx->vma.offset + prev->id * 16;
69 int ret;
70
71 ret = RING_SPACE(chan, 5);
72 if (ret == 0) {
73 BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
74 OUT_RING (chan, upper_32_bits(addr));
75 OUT_RING (chan, lower_32_bits(addr));
76 OUT_RING (chan, fence->sequence);
77 OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_GEQUAL |
78 NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD);
79 FIRE_RING (chan);
80 }
81
82 return ret;
83}
84
85static u32
86nvc0_fence_read(struct nouveau_channel *chan)
87{
88 struct nvc0_fence_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_FENCE);
89 return nouveau_bo_rd32(priv->bo, chan->id * 16/4);
90}
91
92static void
93nvc0_fence_context_del(struct nouveau_channel *chan, int engine)
94{
95 struct nvc0_fence_priv *priv = nv_engine(chan->dev, engine);
96 struct nvc0_fence_chan *fctx = chan->engctx[engine];
97
98 nouveau_bo_vma_del(priv->bo, &fctx->vma);
99 nouveau_fence_context_del(&fctx->base);
100 chan->engctx[engine] = NULL;
101 kfree(fctx);
102}
103
104static int
105nvc0_fence_context_new(struct nouveau_channel *chan, int engine)
106{
107 struct nvc0_fence_priv *priv = nv_engine(chan->dev, engine);
108 struct nvc0_fence_chan *fctx;
109 int ret;
110
111 fctx = chan->engctx[engine] = kzalloc(sizeof(*fctx), GFP_KERNEL);
112 if (!fctx)
113 return -ENOMEM;
114
115 nouveau_fence_context_new(&fctx->base);
116
117 ret = nouveau_bo_vma_add(priv->bo, chan->vm, &fctx->vma);
118 if (ret)
119 nvc0_fence_context_del(chan, engine);
120
121 nouveau_bo_wr32(priv->bo, chan->id * 16/4, 0x00000000);
122 return ret;
123}
124
125static int
126nvc0_fence_fini(struct drm_device *dev, int engine, bool suspend)
127{
128 return 0;
129}
130
131static int
132nvc0_fence_init(struct drm_device *dev, int engine)
133{
134 return 0;
135}
136
137static void
138nvc0_fence_destroy(struct drm_device *dev, int engine)
139{
140 struct drm_nouveau_private *dev_priv = dev->dev_private;
141 struct nvc0_fence_priv *priv = nv_engine(dev, engine);
142
143 nouveau_bo_unmap(priv->bo);
144 nouveau_bo_ref(NULL, &priv->bo);
145 dev_priv->eng[engine] = NULL;
146 kfree(priv);
147}
148
149int
150nvc0_fence_create(struct drm_device *dev)
151{
152 struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
153 struct drm_nouveau_private *dev_priv = dev->dev_private;
154 struct nvc0_fence_priv *priv;
155 int ret;
156
157 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
158 if (!priv)
159 return -ENOMEM;
160
161 priv->base.engine.destroy = nvc0_fence_destroy;
162 priv->base.engine.init = nvc0_fence_init;
163 priv->base.engine.fini = nvc0_fence_fini;
164 priv->base.engine.context_new = nvc0_fence_context_new;
165 priv->base.engine.context_del = nvc0_fence_context_del;
166 priv->base.emit = nvc0_fence_emit;
167 priv->base.sync = nvc0_fence_sync;
168 priv->base.read = nvc0_fence_read;
169 dev_priv->eng[NVOBJ_ENGINE_FENCE] = &priv->base.engine;
170
171 ret = nouveau_bo_new(dev, 16 * pfifo->channels, 0, TTM_PL_FLAG_VRAM,
172 0, 0, NULL, &priv->bo);
173 if (ret == 0) {
174 ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM);
175 if (ret == 0)
176 ret = nouveau_bo_map(priv->bo);
177 if (ret)
178 nouveau_bo_ref(NULL, &priv->bo);
179 }
180
181 if (ret)
182 nvc0_fence_destroy(dev, NVOBJ_ENGINE_FENCE);
183 return ret;
184}