nouveau: reindent nouveau_span.c
[mesa.git] / src / mesa / drivers / dri / nouveau / nouveau_sync.c
1 /*
2 * Copyright (C) 2007 Ben Skeggs.
3 *
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 */
27
28 #include "vblank.h" /* for DO_USLEEP */
29
30 #include "nouveau_context.h"
31 #include "nouveau_fifo.h"
32 #include "nouveau_mem.h"
33 #include "nouveau_msg.h"
34 #include "nouveau_object.h"
35 #include "nouveau_reg.h"
36 #include "nouveau_sync.h"
37
38 #define NOTIFIER(__v) \
39 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \
40 volatile uint32_t *__v = (void*)nmesa->notifier_block + notifier->offset
41
42 struct drm_nouveau_notifierobj_alloc *
43 nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count)
44 {
45 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
46 struct drm_nouveau_notifierobj_alloc *notifier;
47 int ret;
48
49 #ifdef NOUVEAU_RING_DEBUG
50 return NULL;
51 #endif
52 notifier = CALLOC_STRUCT(drm_nouveau_notifierobj_alloc);
53 if (!notifier)
54 return NULL;
55
56 notifier->channel = nmesa->fifo.channel;
57 notifier->handle = handle;
58 notifier->count = count;
59 ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC,
60 notifier, sizeof(*notifier));
61 if (ret) {
62 MESSAGE("Failed to create notifier 0x%08x: %d\n", handle, ret);
63 FREE(notifier);
64 return NULL;
65 }
66
67 return notifier;
68 }
69
70 void
71 nouveau_notifier_destroy(GLcontext *ctx,
72 struct drm_nouveau_notifierobj_alloc *notifier)
73 {
74 /*XXX: free notifier object.. */
75 FREE(notifier);
76 }
77
78 void
79 nouveau_notifier_reset(GLcontext *ctx,
80 struct drm_nouveau_notifierobj_alloc *notifier,
81 GLuint id)
82 {
83 NOTIFIER(n);
84
85 #ifdef NOUVEAU_RING_DEBUG
86 return;
87 #endif
88
89 n[NV_NOTIFY_TIME_0 /4] = 0x00000000;
90 n[NV_NOTIFY_TIME_1 /4] = 0x00000000;
91 n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000;
92 n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS <<
93 NV_NOTIFY_STATE_STATUS_SHIFT);
94 }
95
96 GLuint
97 nouveau_notifier_status(GLcontext *ctx,
98 struct drm_nouveau_notifierobj_alloc *notifier,
99 GLuint id)
100 {
101 NOTIFIER(n);
102
103 return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT;
104 }
105
106 GLuint
107 nouveau_notifier_return_val(GLcontext *ctx,
108 struct drm_nouveau_notifierobj_alloc *notifier,
109 GLuint id)
110 {
111 NOTIFIER(n);
112
113 return n[NV_NOTIFY_RETURN_VALUE/4];
114 }
115
116 GLboolean
117 nouveau_notifier_wait_status(GLcontext *ctx,
118 struct drm_nouveau_notifierobj_alloc *notifier,
119 GLuint id, GLuint status, GLuint timeout)
120 {
121 NOTIFIER(n);
122 unsigned int time = 0;
123
124 #ifdef NOUVEAU_RING_DEBUG
125 return GL_TRUE;
126 #endif
127
128 while (time <= timeout) {
129 if (n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_ERROR_CODE_MASK) {
130 MESSAGE("Notifier returned error: 0x%04x\n",
131 n[NV_NOTIFY_STATE/4] &
132 NV_NOTIFY_STATE_ERROR_CODE_MASK);
133 return GL_FALSE;
134 }
135
136 if (((n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_STATUS_MASK) >>
137 NV_NOTIFY_STATE_STATUS_SHIFT) == status)
138 return GL_TRUE;
139
140 if (timeout) {
141 DO_USLEEP(1);
142 time++;
143 }
144 }
145
146 MESSAGE("Notifier timed out\n");
147 return GL_FALSE;
148 }
149
150 void
151 nouveau_notifier_wait_nop(GLcontext *ctx,
152 struct drm_nouveau_notifierobj_alloc *notifier,
153 GLuint subc)
154 {
155 NOTIFIER(n);
156 GLboolean ret;
157
158 nouveau_notifier_reset(ctx, notifier, 0);
159
160 BEGIN_RING_SIZE(subc, NV_NOTIFY, 1);
161 OUT_RING (NV_NOTIFY_STYLE_WRITE_ONLY);
162 BEGIN_RING_SIZE(subc, NV_NOP, 1);
163 OUT_RING (0);
164 FIRE_RING();
165
166 ret = nouveau_notifier_wait_status(ctx, notifier, 0,
167 NV_NOTIFY_STATE_STATUS_COMPLETED,
168 0 /* no timeout */);
169 if (ret == GL_FALSE) MESSAGE("wait on notifier failed\n");
170 }
171
172 GLboolean nouveauSyncInitFuncs(GLcontext *ctx)
173 {
174 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
175
176 #ifdef NOUVEAU_RING_DEBUG
177 return GL_TRUE;
178 #endif
179
180 nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify, 1);
181 if (!nmesa->syncNotifier) {
182 MESSAGE("Failed to create channel sync notifier\n");
183 return GL_FALSE;
184 }
185
186 /* 0x180 is SET_DMA_NOTIFY, should be correct for all supported 3D
187 * object classes
188 */
189 BEGIN_RING_CACHE(NvSub3D, 0x180, 1);
190 OUT_RING_CACHE (NvSyncNotify);
191 BEGIN_RING_SIZE(NvSubMemFormat,
192 NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
193 OUT_RING (NvSyncNotify);
194
195 return GL_TRUE;
196 }
197