Merged via-1-2-0
[platform/upstream/libdrm.git] / shared-core / via_map.c
1 /*
2  * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3  * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sub license,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19  * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24 #define __NO_VERSION__
25 #include "via.h"
26 #include "drmP.h"
27 #include "via_drv.h"
28
29 int via_do_init_map(drm_device_t *dev, drm_via_init_t *init)
30 {
31         drm_via_private_t *dev_priv;
32         unsigned int i;
33         
34         DRM_DEBUG("%s\n", __FUNCTION__);
35
36         dev_priv = DRM(alloc)(sizeof(drm_via_private_t), DRM_MEM_DRIVER);
37         if (dev_priv == NULL)
38                 return -ENOMEM;
39
40         memset(dev_priv, 0, sizeof(drm_via_private_t));
41         
42         DRM_GETSAREA();
43         if (!dev_priv->sarea) {
44                 DRM_ERROR("could not find sarea!\n");
45                 dev->dev_private = (void *)dev_priv;
46                 via_do_cleanup_map(dev);
47                 return -EINVAL;
48         }
49
50         DRM_FIND_MAP(dev_priv->fb, init->fb_offset);
51         if (!dev_priv->fb) {
52                 DRM_ERROR("could not find framebuffer!\n");
53                 dev->dev_private = (void *)dev_priv;
54                 via_do_cleanup_map(dev);
55                 return -EINVAL;
56         }
57         DRM_FIND_MAP(dev_priv->mmio, init->mmio_offset);
58         if (!dev_priv->mmio) {
59                 DRM_ERROR("could not find mmio region!\n");
60                 dev->dev_private = (void *)dev_priv;
61                 via_do_cleanup_map(dev);
62                 return -EINVAL;
63         }
64         
65         dev_priv->sarea_priv =
66                 (drm_via_sarea_t *)((u8 *)dev_priv->sarea->handle +
67                                     init->sarea_priv_offset);
68
69         dev_priv->agpAddr = init->agpAddr;
70
71         
72         for (i=0; i<VIA_NR_XVMC_LOCKS; ++i) 
73                 DRM_INIT_WAITQUEUE( &(dev_priv->decoder_queue[i]) );
74
75         dev->dev_private = (void *)dev_priv;
76
77         return 0;
78 }
79
80 int via_do_cleanup_map(drm_device_t *dev)
81 {
82         if (dev->dev_private) {
83
84                 drm_via_private_t *dev_priv = dev->dev_private;
85
86                 DRM(free)(dev_priv, sizeof(drm_via_private_t),
87                           DRM_MEM_DRIVER);
88                 dev->dev_private = NULL;
89         }
90
91         return 0;
92 }
93
94 int via_map_init( DRM_IOCTL_ARGS )
95 {
96         DRM_DEVICE;
97         drm_via_init_t init;
98
99         DRM_DEBUG("%s\n", __FUNCTION__);
100
101         DRM_COPY_FROM_USER_IOCTL(init, (drm_via_init_t *)data, sizeof(init));
102
103         switch (init.func) {
104         case VIA_INIT_MAP:
105                 return via_do_init_map(dev, &init);
106         case VIA_CLEANUP_MAP:
107                 return via_do_cleanup_map(dev);
108         }
109
110         return -EINVAL;
111 }
112
113 int via_decoder_futex( DRM_IOCTL_ARGS ) 
114 {
115         DRM_DEVICE;
116         drm_via_futex_t fx;
117         volatile int *lock;
118         drm_via_private_t *dev_priv = (drm_via_private_t*) dev->dev_private;
119         drm_via_sarea_t *sAPriv = dev_priv->sarea_priv;
120         int ret = 0;
121
122         DRM_COPY_FROM_USER_IOCTL(fx, (drm_via_futex_t *) data, sizeof(fx));
123     
124         if (fx.lock > VIA_NR_XVMC_LOCKS)
125                 return -EFAULT;
126
127         lock = XVMCLOCKPTR(sAPriv,fx.lock);
128
129         switch(fx.op) {
130         case VIA_FUTEX_WAIT:
131                 DRM_WAIT_ON(ret, dev_priv->decoder_queue[fx.lock], 
132                             (fx.ms / 10)*(DRM_HZ/100), 
133                             *lock != fx.val);
134                 return ret;
135         case VIA_FUTEX_WAKE:
136                 DRM_WAKEUP( &(dev_priv->decoder_queue[fx.lock]) );
137                 return 0;
138         }
139         return 0;
140 }
141             
142         
143