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
27 #include "nouveau_private.h"
29 #define NOTIFIER(__v) \
30 struct nouveau_notifier_priv *nvnotify = nouveau_notifier(notifier); \
31 volatile uint32_t *__v = (uint32_t *)((char *)nvnotify->map + (id * 32))
34 nouveau_notifier_alloc(struct nouveau_channel
*chan
, uint32_t handle
,
35 int count
, struct nouveau_notifier
**notifier
)
37 struct nouveau_notifier_priv
*nvnotify
;
40 if (!chan
|| !notifier
|| *notifier
)
43 nvnotify
= calloc(1, sizeof(struct nouveau_notifier_priv
));
46 nvnotify
->base
.channel
= chan
;
47 nvnotify
->base
.handle
= handle
;
49 nvnotify
->drm
.channel
= chan
->id
;
50 nvnotify
->drm
.handle
= handle
;
51 nvnotify
->drm
.count
= count
;
52 if ((ret
= drmCommandWriteRead(nouveau_device(chan
->device
)->fd
,
53 DRM_NOUVEAU_NOTIFIEROBJ_ALLOC
,
55 sizeof(nvnotify
->drm
)))) {
56 nouveau_notifier_free((void *)&nvnotify
);
60 nvnotify
->map
= (char *)nouveau_channel(chan
)->notifier_block
+
62 *notifier
= &nvnotify
->base
;
67 nouveau_notifier_free(struct nouveau_notifier
**notifier
)
70 struct nouveau_notifier_priv
*nvnotify
;
71 struct nouveau_channel_priv
*nvchan
;
72 struct nouveau_device_priv
*nvdev
;
73 struct drm_nouveau_gpuobj_free f
;
75 if (!notifier
|| !*notifier
)
77 nvnotify
= nouveau_notifier(*notifier
);
80 nvchan
= nouveau_channel(nvnotify
->base
.channel
);
81 nvdev
= nouveau_device(nvchan
->base
.device
);
83 f
.channel
= nvchan
->drm
.channel
;
84 f
.handle
= nvnotify
->base
.handle
;
85 drmCommandWrite(nvdev
->fd
, DRM_NOUVEAU_GPUOBJ_FREE
, &f
, sizeof(f
));
90 nouveau_notifier_reset(struct nouveau_notifier
*notifier
, int id
)
94 n
[NV_NOTIFY_TIME_0
/4] = 0x00000000;
95 n
[NV_NOTIFY_TIME_1
/4] = 0x00000000;
96 n
[NV_NOTIFY_RETURN_VALUE
/4] = 0x00000000;
97 n
[NV_NOTIFY_STATE
/4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS
<<
98 NV_NOTIFY_STATE_STATUS_SHIFT
);
102 nouveau_notifier_status(struct nouveau_notifier
*notifier
, int id
)
106 return n
[NV_NOTIFY_STATE
/4] >> NV_NOTIFY_STATE_STATUS_SHIFT
;
110 nouveau_notifier_return_val(struct nouveau_notifier
*notifier
, int id
)
114 return n
[NV_NOTIFY_RETURN_VALUE
/4];
122 gettimeofday(&tv
, NULL
);
123 return (double)tv
.tv_sec
+ tv
.tv_usec
/ 1000000.0;
127 nouveau_notifier_wait_status(struct nouveau_notifier
*notifier
, int id
,
128 uint32_t status
, double timeout
)
131 double time
= 0, t_start
= gettime();
133 while (time
<= timeout
) {
136 v
= n
[NV_NOTIFY_STATE
/4] >> NV_NOTIFY_STATE_STATUS_SHIFT
;
141 time
= gettime() - t_start
;