This patch adds three new ioctl's to the VIA Unichrome/Pro DRM driver:
[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         dev_priv->fb = drm_core_findmap(dev, 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         dev_priv->mmio = drm_core_findmap(dev, 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                 via_dma_cleanup(dev);
87
88                 DRM(free)(dev_priv, sizeof(drm_via_private_t),
89                           DRM_MEM_DRIVER);
90                 dev->dev_private = NULL;
91         }
92
93         return 0;
94 }
95
96 int via_map_init( DRM_IOCTL_ARGS )
97 {
98         DRM_DEVICE;
99         drm_via_init_t init;
100
101         DRM_DEBUG("%s\n", __FUNCTION__);
102
103         DRM_COPY_FROM_USER_IOCTL(init, (drm_via_init_t *)data, sizeof(init));
104
105         switch (init.func) {
106         case VIA_INIT_MAP:
107                 return via_do_init_map(dev, &init);
108         case VIA_CLEANUP_MAP:
109                 return via_do_cleanup_map(dev);
110         }
111
112         return -EINVAL;
113 }
114
115 int via_decoder_futex( DRM_IOCTL_ARGS ) 
116 {
117         DRM_DEVICE;
118         drm_via_futex_t fx;
119         volatile int *lock;
120         drm_via_private_t *dev_priv = (drm_via_private_t*) dev->dev_private;
121         drm_via_sarea_t *sAPriv = dev_priv->sarea_priv;
122         int ret = 0;
123
124         DRM_COPY_FROM_USER_IOCTL(fx, (drm_via_futex_t *) data, sizeof(fx));
125     
126         if (fx.lock > VIA_NR_XVMC_LOCKS)
127                 return -EFAULT;
128
129         lock = XVMCLOCKPTR(sAPriv,fx.lock);
130
131         switch(fx.op) {
132         case VIA_FUTEX_WAIT:
133                 DRM_WAIT_ON(ret, dev_priv->decoder_queue[fx.lock], 
134                             (fx.ms / 10)*(DRM_HZ/100), 
135                             *lock != fx.val);
136                 return ret;
137         case VIA_FUTEX_WAKE:
138                 DRM_WAKEUP( &(dev_priv->decoder_queue[fx.lock]) );
139                 return 0;
140         }
141         return 0;
142 }
143             
144         
145