2 * Copyright 2007 Nouveau Project
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 #include "nouveau_drmif.h"
27 #include "nouveau_local.h"
29 #define NOTIFIER(__v) \
30 struct nouveau_notifier_priv *notifier = nouveau_notifier(user); \
31 volatile uint32_t *n = (void*)notifier->map + (id * 32)
34 nouveau_notifier_alloc(struct nouveau_channel *userchan, uint32_t handle,
35 int count, struct nouveau_notifier **usernotifier)
37 struct nouveau_notifier_priv *notifier;
40 if (!userchan || !usernotifier || *usernotifier)
43 notifier = calloc(1, sizeof(*notifier));
46 notifier->base.channel = userchan;
47 notifier->base.handle = handle;
49 notifier->drm.channel = userchan->id;
50 notifier->drm.handle = handle;
51 notifier->drm.count = count;
52 if ((ret = drmCommandWriteRead(nouveau_device(userchan->device)->fd,
53 DRM_NOUVEAU_NOTIFIEROBJ_ALLOC,
55 sizeof(notifier->drm)))) {
56 nouveau_notifier_free((void *)¬ifier);
60 notifier->map = (void *)nouveau_channel(userchan)->notifier_block +
62 *usernotifier = ¬ifier->base;
67 nouveau_notifier_free(struct nouveau_notifier **usernotifier)
70 struct nouveau_notifier_priv *notifier;
74 notifier = nouveau_notifier(*usernotifier);
78 struct nouveau_channel_priv *chan;
79 struct nouveau_device_priv *nv;
80 struct drm_nouveau_gpuobj_free f;
82 chan = nouveau_channel(notifier->base.channel);
83 nv = nouveau_device(chan->base.device);
85 f.channel = chan->drm.channel;
86 f.handle = notifier->base.handle;
87 drmCommandWrite(nv->fd, DRM_NOUVEAU_GPUOBJ_FREE, &f, sizeof(f));
93 nouveau_notifier_reset(struct nouveau_notifier *user, int id)
97 n[NV_NOTIFY_TIME_0 /4] = 0x00000000;
98 n[NV_NOTIFY_TIME_1 /4] = 0x00000000;
99 n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000;
100 n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS <<
101 NV_NOTIFY_STATE_STATUS_SHIFT);
105 nouveau_notifier_status(struct nouveau_notifier *user, int id)
109 return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT;
113 nouveau_notifier_return_val(struct nouveau_notifier *user, int id)
117 return n[NV_NOTIFY_RETURN_VALUE/4];
121 nouveau_notifier_wait_status(struct nouveau_notifier *user, int id,
122 int status, int timeout)
125 uint32_t time = 0, t_start = NOUVEAU_TIME_MSEC();
127 while (time <= timeout) {
130 v = n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT;
135 time = NOUVEAU_TIME_MSEC() - t_start;