diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2013-02-13 21:59:36 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2013-02-20 01:00:52 -0500 |
commit | 60e5cb79cbd27a36836fc04177d7c323ee873563 (patch) | |
tree | 31ee56acd841375f6fddbe3572d57916b00142b2 /drivers/gpu/drm/nouveau | |
parent | bba9852feedf3d38f963278e07bdd3db622090b9 (diff) |
drm/nv17/fence: split from nv10 code
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r-- | drivers/gpu/drm/nouveau/Makefile | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drm.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fence.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv10_fence.c | 99 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv17_fence.c | 149 |
5 files changed, 158 insertions, 98 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index e0bd21a99de8..4208db9b1388 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile | |||
@@ -207,7 +207,8 @@ nouveau-y += nouveau_drm.o nouveau_chan.o nouveau_dma.o nouveau_fence.o | |||
207 | nouveau-y += nouveau_irq.o nouveau_vga.o nouveau_agp.o | 207 | nouveau-y += nouveau_irq.o nouveau_vga.o nouveau_agp.o |
208 | nouveau-y += nouveau_ttm.o nouveau_sgdma.o nouveau_bo.o nouveau_gem.o | 208 | nouveau-y += nouveau_ttm.o nouveau_sgdma.o nouveau_bo.o nouveau_gem.o |
209 | nouveau-y += nouveau_prime.o nouveau_abi16.o | 209 | nouveau-y += nouveau_prime.o nouveau_abi16.o |
210 | nouveau-y += nv04_fence.o nv10_fence.o nv50_fence.o nv84_fence.o nvc0_fence.o | 210 | nouveau-y += nv04_fence.o nv10_fence.o nv17_fence.o |
211 | nouveau-y += nv50_fence.o nv84_fence.o nvc0_fence.o | ||
211 | 212 | ||
212 | # drm/kms | 213 | # drm/kms |
213 | nouveau-y += nouveau_bios.o nouveau_fbcon.o nouveau_display.o | 214 | nouveau-y += nouveau_bios.o nouveau_fbcon.o nouveau_display.o |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index ce91c8d43bb7..f9144910b78e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
@@ -160,7 +160,8 @@ nouveau_accel_init(struct nouveau_drm *drm) | |||
160 | 160 | ||
161 | /* initialise synchronisation routines */ | 161 | /* initialise synchronisation routines */ |
162 | if (device->card_type < NV_10) ret = nv04_fence_create(drm); | 162 | if (device->card_type < NV_10) ret = nv04_fence_create(drm); |
163 | else if (device->card_type < NV_50) ret = nv10_fence_create(drm); | 163 | else if (device->chipset < 0x17) ret = nv10_fence_create(drm); |
164 | else if (device->card_type < NV_50) ret = nv17_fence_create(drm); | ||
164 | else if (device->chipset < 0x84) ret = nv50_fence_create(drm); | 165 | else if (device->chipset < 0x84) ret = nv50_fence_create(drm); |
165 | else if (device->card_type < NV_C0) ret = nv84_fence_create(drm); | 166 | else if (device->card_type < NV_C0) ret = nv84_fence_create(drm); |
166 | else ret = nvc0_fence_create(drm); | 167 | else ret = nvc0_fence_create(drm); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h index f1f0c6dfc3e8..fb0993c3dc39 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.h +++ b/drivers/gpu/drm/nouveau/nouveau_fence.h | |||
@@ -65,6 +65,8 @@ u32 nv10_fence_read(struct nouveau_channel *); | |||
65 | void nv10_fence_context_del(struct nouveau_channel *); | 65 | void nv10_fence_context_del(struct nouveau_channel *); |
66 | void nv10_fence_destroy(struct nouveau_drm *); | 66 | void nv10_fence_destroy(struct nouveau_drm *); |
67 | int nv10_fence_create(struct nouveau_drm *); | 67 | int nv10_fence_create(struct nouveau_drm *); |
68 | |||
69 | int nv17_fence_create(struct nouveau_drm *); | ||
68 | void nv17_fence_resume(struct nouveau_drm *drm); | 70 | void nv17_fence_resume(struct nouveau_drm *drm); |
69 | 71 | ||
70 | int nv50_fence_create(struct nouveau_drm *); | 72 | int nv50_fence_create(struct nouveau_drm *); |
diff --git a/drivers/gpu/drm/nouveau/nv10_fence.c b/drivers/gpu/drm/nouveau/nv10_fence.c index a8ea4af3ca76..e4f124a48d4e 100644 --- a/drivers/gpu/drm/nouveau/nv10_fence.c +++ b/drivers/gpu/drm/nouveau/nv10_fence.c | |||
@@ -50,45 +50,6 @@ nv10_fence_sync(struct nouveau_fence *fence, | |||
50 | return -ENODEV; | 50 | return -ENODEV; |
51 | } | 51 | } |
52 | 52 | ||
53 | int | ||
54 | nv17_fence_sync(struct nouveau_fence *fence, | ||
55 | struct nouveau_channel *prev, struct nouveau_channel *chan) | ||
56 | { | ||
57 | struct nv10_fence_priv *priv = chan->drm->fence; | ||
58 | u32 value; | ||
59 | int ret; | ||
60 | |||
61 | if (!mutex_trylock(&prev->cli->mutex)) | ||
62 | return -EBUSY; | ||
63 | |||
64 | spin_lock(&priv->lock); | ||
65 | value = priv->sequence; | ||
66 | priv->sequence += 2; | ||
67 | spin_unlock(&priv->lock); | ||
68 | |||
69 | ret = RING_SPACE(prev, 5); | ||
70 | if (!ret) { | ||
71 | BEGIN_NV04(prev, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 4); | ||
72 | OUT_RING (prev, NvSema); | ||
73 | OUT_RING (prev, 0); | ||
74 | OUT_RING (prev, value + 0); | ||
75 | OUT_RING (prev, value + 1); | ||
76 | FIRE_RING (prev); | ||
77 | } | ||
78 | |||
79 | if (!ret && !(ret = RING_SPACE(chan, 5))) { | ||
80 | BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 4); | ||
81 | OUT_RING (chan, NvSema); | ||
82 | OUT_RING (chan, 0); | ||
83 | OUT_RING (chan, value + 1); | ||
84 | OUT_RING (chan, value + 2); | ||
85 | FIRE_RING (chan); | ||
86 | } | ||
87 | |||
88 | mutex_unlock(&prev->cli->mutex); | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | u32 | 53 | u32 |
93 | nv10_fence_read(struct nouveau_channel *chan) | 54 | nv10_fence_read(struct nouveau_channel *chan) |
94 | { | 55 | { |
@@ -104,39 +65,17 @@ nv10_fence_context_del(struct nouveau_channel *chan) | |||
104 | kfree(fctx); | 65 | kfree(fctx); |
105 | } | 66 | } |
106 | 67 | ||
107 | static int | 68 | int |
108 | nv10_fence_context_new(struct nouveau_channel *chan) | 69 | nv10_fence_context_new(struct nouveau_channel *chan) |
109 | { | 70 | { |
110 | struct nv10_fence_priv *priv = chan->drm->fence; | ||
111 | struct nv10_fence_chan *fctx; | 71 | struct nv10_fence_chan *fctx; |
112 | int ret = 0; | ||
113 | 72 | ||
114 | fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); | 73 | fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); |
115 | if (!fctx) | 74 | if (!fctx) |
116 | return -ENOMEM; | 75 | return -ENOMEM; |
117 | 76 | ||
118 | nouveau_fence_context_new(&fctx->base); | 77 | nouveau_fence_context_new(&fctx->base); |
119 | 78 | return 0; | |
120 | if (priv->bo) { | ||
121 | struct ttm_mem_reg *mem = &priv->bo->bo.mem; | ||
122 | struct nouveau_object *object; | ||
123 | u32 start = mem->start * PAGE_SIZE; | ||
124 | u32 limit = mem->start + mem->size - 1; | ||
125 | |||
126 | ret = nouveau_object_new(nv_object(chan->cli), chan->handle, | ||
127 | NvSema, 0x0002, | ||
128 | &(struct nv_dma_class) { | ||
129 | .flags = NV_DMA_TARGET_VRAM | | ||
130 | NV_DMA_ACCESS_RDWR, | ||
131 | .start = start, | ||
132 | .limit = limit, | ||
133 | }, sizeof(struct nv_dma_class), | ||
134 | &object); | ||
135 | } | ||
136 | |||
137 | if (ret) | ||
138 | nv10_fence_context_del(chan); | ||
139 | return ret; | ||
140 | } | 79 | } |
141 | 80 | ||
142 | void | 81 | void |
@@ -151,18 +90,10 @@ nv10_fence_destroy(struct nouveau_drm *drm) | |||
151 | kfree(priv); | 90 | kfree(priv); |
152 | } | 91 | } |
153 | 92 | ||
154 | void nv17_fence_resume(struct nouveau_drm *drm) | ||
155 | { | ||
156 | struct nv10_fence_priv *priv = drm->fence; | ||
157 | |||
158 | nouveau_bo_wr32(priv->bo, 0, priv->sequence); | ||
159 | } | ||
160 | |||
161 | int | 93 | int |
162 | nv10_fence_create(struct nouveau_drm *drm) | 94 | nv10_fence_create(struct nouveau_drm *drm) |
163 | { | 95 | { |
164 | struct nv10_fence_priv *priv; | 96 | struct nv10_fence_priv *priv; |
165 | int ret = 0; | ||
166 | 97 | ||
167 | priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL); | 98 | priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL); |
168 | if (!priv) | 99 | if (!priv) |
@@ -175,29 +106,5 @@ nv10_fence_create(struct nouveau_drm *drm) | |||
175 | priv->base.read = nv10_fence_read; | 106 | priv->base.read = nv10_fence_read; |
176 | priv->base.sync = nv10_fence_sync; | 107 | priv->base.sync = nv10_fence_sync; |
177 | spin_lock_init(&priv->lock); | 108 | spin_lock_init(&priv->lock); |
178 | 109 | return 0; | |
179 | if (nv_device(drm->device)->chipset >= 0x17) { | ||
180 | ret = nouveau_bo_new(drm->dev, 4096, 0x1000, TTM_PL_FLAG_VRAM, | ||
181 | 0, 0x0000, NULL, &priv->bo); | ||
182 | if (!ret) { | ||
183 | ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM); | ||
184 | if (!ret) { | ||
185 | ret = nouveau_bo_map(priv->bo); | ||
186 | if (ret) | ||
187 | nouveau_bo_unpin(priv->bo); | ||
188 | } | ||
189 | if (ret) | ||
190 | nouveau_bo_ref(NULL, &priv->bo); | ||
191 | } | ||
192 | |||
193 | if (ret == 0) { | ||
194 | nouveau_bo_wr32(priv->bo, 0x000, 0x00000000); | ||
195 | priv->base.sync = nv17_fence_sync; | ||
196 | priv->base.resume = nv17_fence_resume; | ||
197 | } | ||
198 | } | ||
199 | |||
200 | if (ret) | ||
201 | nv10_fence_destroy(drm); | ||
202 | return ret; | ||
203 | } | 110 | } |
diff --git a/drivers/gpu/drm/nouveau/nv17_fence.c b/drivers/gpu/drm/nouveau/nv17_fence.c new file mode 100644 index 000000000000..fe194451e0ad --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv17_fence.c | |||
@@ -0,0 +1,149 @@ | |||
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 <bskeggs@redhat.com> | ||
23 | */ | ||
24 | |||
25 | #include <core/object.h> | ||
26 | #include <core/class.h> | ||
27 | |||
28 | #include "nouveau_drm.h" | ||
29 | #include "nouveau_dma.h" | ||
30 | #include "nv10_fence.h" | ||
31 | |||
32 | int | ||
33 | nv17_fence_sync(struct nouveau_fence *fence, | ||
34 | struct nouveau_channel *prev, struct nouveau_channel *chan) | ||
35 | { | ||
36 | struct nv10_fence_priv *priv = chan->drm->fence; | ||
37 | u32 value; | ||
38 | int ret; | ||
39 | |||
40 | if (!mutex_trylock(&prev->cli->mutex)) | ||
41 | return -EBUSY; | ||
42 | |||
43 | spin_lock(&priv->lock); | ||
44 | value = priv->sequence; | ||
45 | priv->sequence += 2; | ||
46 | spin_unlock(&priv->lock); | ||
47 | |||
48 | ret = RING_SPACE(prev, 5); | ||
49 | if (!ret) { | ||
50 | BEGIN_NV04(prev, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 4); | ||
51 | OUT_RING (prev, NvSema); | ||
52 | OUT_RING (prev, 0); | ||
53 | OUT_RING (prev, value + 0); | ||
54 | OUT_RING (prev, value + 1); | ||
55 | FIRE_RING (prev); | ||
56 | } | ||
57 | |||
58 | if (!ret && !(ret = RING_SPACE(chan, 5))) { | ||
59 | BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 4); | ||
60 | OUT_RING (chan, NvSema); | ||
61 | OUT_RING (chan, 0); | ||
62 | OUT_RING (chan, value + 1); | ||
63 | OUT_RING (chan, value + 2); | ||
64 | FIRE_RING (chan); | ||
65 | } | ||
66 | |||
67 | mutex_unlock(&prev->cli->mutex); | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static int | ||
72 | nv17_fence_context_new(struct nouveau_channel *chan) | ||
73 | { | ||
74 | struct nv10_fence_priv *priv = chan->drm->fence; | ||
75 | struct nv10_fence_chan *fctx; | ||
76 | struct ttm_mem_reg *mem = &priv->bo->bo.mem; | ||
77 | struct nouveau_object *object; | ||
78 | u32 start = mem->start * PAGE_SIZE; | ||
79 | u32 limit = mem->start + mem->size - 1; | ||
80 | int ret = 0; | ||
81 | |||
82 | fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); | ||
83 | if (!fctx) | ||
84 | return -ENOMEM; | ||
85 | |||
86 | nouveau_fence_context_new(&fctx->base); | ||
87 | |||
88 | ret = nouveau_object_new(nv_object(chan->cli), chan->handle, | ||
89 | NvSema, 0x0002, | ||
90 | &(struct nv_dma_class) { | ||
91 | .flags = NV_DMA_TARGET_VRAM | | ||
92 | NV_DMA_ACCESS_RDWR, | ||
93 | .start = start, | ||
94 | .limit = limit, | ||
95 | }, sizeof(struct nv_dma_class), | ||
96 | &object); | ||
97 | if (ret) | ||
98 | nv10_fence_context_del(chan); | ||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | void | ||
103 | nv17_fence_resume(struct nouveau_drm *drm) | ||
104 | { | ||
105 | struct nv10_fence_priv *priv = drm->fence; | ||
106 | |||
107 | nouveau_bo_wr32(priv->bo, 0, priv->sequence); | ||
108 | } | ||
109 | |||
110 | int | ||
111 | nv17_fence_create(struct nouveau_drm *drm) | ||
112 | { | ||
113 | struct nv10_fence_priv *priv; | ||
114 | int ret = 0; | ||
115 | |||
116 | priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
117 | if (!priv) | ||
118 | return -ENOMEM; | ||
119 | |||
120 | priv->base.dtor = nv10_fence_destroy; | ||
121 | priv->base.resume = nv17_fence_resume; | ||
122 | priv->base.context_new = nv17_fence_context_new; | ||
123 | priv->base.context_del = nv10_fence_context_del; | ||
124 | priv->base.emit = nv10_fence_emit; | ||
125 | priv->base.read = nv10_fence_read; | ||
126 | priv->base.sync = nv17_fence_sync; | ||
127 | spin_lock_init(&priv->lock); | ||
128 | |||
129 | ret = nouveau_bo_new(drm->dev, 4096, 0x1000, TTM_PL_FLAG_VRAM, | ||
130 | 0, 0x0000, NULL, &priv->bo); | ||
131 | if (!ret) { | ||
132 | ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM); | ||
133 | if (!ret) { | ||
134 | ret = nouveau_bo_map(priv->bo); | ||
135 | if (ret) | ||
136 | nouveau_bo_unpin(priv->bo); | ||
137 | } | ||
138 | if (ret) | ||
139 | nouveau_bo_ref(NULL, &priv->bo); | ||
140 | } | ||
141 | |||
142 | if (ret) { | ||
143 | nv10_fence_destroy(drm); | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | nouveau_bo_wr32(priv->bo, 0x000, 0x00000000); | ||
148 | return ret; | ||
149 | } | ||