1 /*
2  * Copyright (C) 2005 The Unichrome Project, All Rights Reserved.
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, sub license,
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 (including the
12  * next paragraph) shall be included in all copies or substantial portions
13  * of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #ifndef _VIA_DRMCLIENT_H
25 #define _VIA_DRMCLIENT_H
26 
27 #include "stdint.h"
28 #include "drm.h"
29 #include "xf86drm.h"
30 
31 #ifdef X_NEED_DRMLOCK
32 #define drm_hw_lock_t drmLock
33 #endif
34 
35 #define UNICHROME_LOCK(fd, lockNo, saPriv, context, lastcontext, ret)	\
36     do {								\
37 	volatile drm_hw_lock_t *lockPtr = XVMCLOCKPTR((saPriv), (lockNo));	\
38 	unsigned lockVal;						\
39         DRM_CAS_RESULT(__ret);						\
40 									\
41 	ret = 0;							\
42 	lockVal = lockPtr->lock & ~(DRM_LOCK_HELD | DRM_LOCK_CONT);	\
43 	DRM_CAS(lockPtr, lockVal, (context) | DRM_LOCK_HELD, __ret);	\
44 	if (__ret) {							\
45 	    drm_via_futex_t fx;						\
46 									\
47             lockVal = lockPtr->lock;					\
48 	    if (! (lockVal & DRM_LOCK_HELD)) continue;			\
49 	    if ((lockVal & ~(DRM_LOCK_HELD | DRM_LOCK_CONT) )		\
50 		== (context)) {						\
51 	      lastcontext = lockVal & ~(DRM_LOCK_HELD | DRM_LOCK_CONT);	\
52 		break;							\
53 	    }								\
54 	    fx.val = lockVal | DRM_LOCK_CONT;				\
55 	    DRM_CAS( lockPtr, lockVal, fx.val, __ret);			\
56 	    lockVal = lockPtr->lock;					\
57 	    if (__ret) continue;					\
58 	    fx.func = VIA_FUTEX_WAIT;					\
59 	    fx.lock = (lockNo);						\
60 	    fx.ms = 10;							\
61 	    ret = drmCommandWrite((fd), DRM_VIA_DEC_FUTEX,		\
62 				  &fx,sizeof(fx));			\
63 	    lastcontext = lockVal;					\
64 	    if (ret) break;						\
65 	    continue;							\
66 	} else {							\
67 	    lastcontext = lockVal;					\
68 	    break;							\
69 	}								\
70     } while (1)								\
71 
72 #define UNICHROME_UNLOCK(fd, lockNo, saPriv, context)			\
73     do {								\
74       volatile drm_hw_lock_t *lockPtr = XVMCLOCKPTR((saPriv), (lockNo)); 	\
75 									\
76 	if ((lockPtr->lock & ~DRM_LOCK_CONT) ==				\
77 	       ((context) | DRM_LOCK_HELD)) {				\
78 	  DRM_CAS_RESULT(__ret);					\
79 	    DRM_CAS(lockPtr,(context) | DRM_LOCK_HELD, context, __ret); \
80 	    if (__ret) {						\
81 		drm_via_futex_t fx;					\
82 		fx.func = VIA_FUTEX_WAKE;				\
83 		fx.lock = lockNo;					\
84 		DRM_CAS(lockPtr, (context) | DRM_LOCK_HELD |		\
85 			DRM_LOCK_CONT,					\
86 			context, __ret);				\
87 		drmCommandWrite((fd), DRM_VIA_DEC_FUTEX, &fx,		\
88 				sizeof(fx));				\
89 	    }								\
90 	}								\
91     } while (0)								\
92 
93 #define UNICHROME_LOCK_DECODER1 0
94 #define UNICHROME_LOCK_DECODER2 1
95 #define UNICHROME_LOCK_HQV      4
96 #define __user
97 
98 #endif
99