]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/nouveau/nouveau_abi16.c
UAPI: (Scripted) Convert #include "..." to #include <path/...> in drivers/gpu/
[karo-tx-linux.git] / drivers / gpu / drm / nouveau / nouveau_abi16.c
1 /*
2  * Copyright 2012 Red Hat Inc.
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, 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:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  */
23
24 #include <drm/drmP.h>
25
26 #include "nouveau_drv.h"
27 #include "nouveau_dma.h"
28 #include "nouveau_abi16.h"
29 #include "nouveau_ramht.h"
30 #include "nouveau_software.h"
31
32 int
33 nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
34 {
35         struct drm_nouveau_private *dev_priv = dev->dev_private;
36         struct drm_nouveau_getparam *getparam = data;
37
38         switch (getparam->param) {
39         case NOUVEAU_GETPARAM_CHIPSET_ID:
40                 getparam->value = dev_priv->chipset;
41                 break;
42         case NOUVEAU_GETPARAM_PCI_VENDOR:
43                 getparam->value = dev->pci_vendor;
44                 break;
45         case NOUVEAU_GETPARAM_PCI_DEVICE:
46                 getparam->value = dev->pci_device;
47                 break;
48         case NOUVEAU_GETPARAM_BUS_TYPE:
49                 if (drm_pci_device_is_agp(dev))
50                         getparam->value = 0;
51                 else
52                 if (!pci_is_pcie(dev->pdev))
53                         getparam->value = 1;
54                 else
55                         getparam->value = 2;
56                 break;
57         case NOUVEAU_GETPARAM_FB_SIZE:
58                 getparam->value = dev_priv->fb_available_size;
59                 break;
60         case NOUVEAU_GETPARAM_AGP_SIZE:
61                 getparam->value = dev_priv->gart_info.aper_size;
62                 break;
63         case NOUVEAU_GETPARAM_VM_VRAM_BASE:
64                 getparam->value = 0; /* deprecated */
65                 break;
66         case NOUVEAU_GETPARAM_PTIMER_TIME:
67                 getparam->value = dev_priv->engine.timer.read(dev);
68                 break;
69         case NOUVEAU_GETPARAM_HAS_BO_USAGE:
70                 getparam->value = 1;
71                 break;
72         case NOUVEAU_GETPARAM_HAS_PAGEFLIP:
73                 getparam->value = 1;
74                 break;
75         case NOUVEAU_GETPARAM_GRAPH_UNITS:
76                 /* NV40 and NV50 versions are quite different, but register
77                  * address is the same. User is supposed to know the card
78                  * family anyway... */
79                 if (dev_priv->chipset >= 0x40) {
80                         getparam->value = nv_rd32(dev, NV40_PMC_GRAPH_UNITS);
81                         break;
82                 }
83                 /* FALLTHRU */
84         default:
85                 NV_DEBUG(dev, "unknown parameter %lld\n", getparam->param);
86                 return -EINVAL;
87         }
88
89         return 0;
90 }
91
92 int
93 nouveau_abi16_ioctl_setparam(ABI16_IOCTL_ARGS)
94 {
95         return -EINVAL;
96 }
97
98 int
99 nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
100 {
101         struct drm_nouveau_private *dev_priv = dev->dev_private;
102         struct drm_nouveau_channel_alloc *init = data;
103         struct nouveau_channel *chan;
104         int ret;
105
106         if (!dev_priv->eng[NVOBJ_ENGINE_GR])
107                 return -ENODEV;
108
109         if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
110                 return -EINVAL;
111
112         ret = nouveau_channel_alloc(dev, &chan, file_priv,
113                                     init->fb_ctxdma_handle,
114                                     init->tt_ctxdma_handle);
115         if (ret)
116                 return ret;
117         init->channel  = chan->id;
118
119         if (nouveau_vram_pushbuf == 0) {
120                 if (chan->dma.ib_max)
121                         init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM |
122                                                 NOUVEAU_GEM_DOMAIN_GART;
123                 else if (chan->pushbuf_bo->bo.mem.mem_type == TTM_PL_VRAM)
124                         init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM;
125                 else
126                         init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART;
127         } else {
128                 init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM;
129         }
130
131         if (dev_priv->card_type < NV_C0) {
132                 init->subchan[0].handle = 0x00000000;
133                 init->subchan[0].grclass = 0x0000;
134                 init->subchan[1].handle = NvSw;
135                 init->subchan[1].grclass = NV_SW;
136                 init->nr_subchan = 2;
137         }
138
139         /* Named memory object area */
140         ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem,
141                                     &init->notifier_handle);
142
143         if (ret == 0)
144                 atomic_inc(&chan->users); /* userspace reference */
145         nouveau_channel_put(&chan);
146         return ret;
147 }
148
149 int
150 nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS)
151 {
152         struct drm_nouveau_channel_free *req = data;
153         struct nouveau_channel *chan;
154
155         chan = nouveau_channel_get(file_priv, req->channel);
156         if (IS_ERR(chan))
157                 return PTR_ERR(chan);
158
159         list_del(&chan->list);
160         atomic_dec(&chan->users);
161         nouveau_channel_put(&chan);
162         return 0;
163 }
164
165 int
166 nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
167 {
168         struct drm_nouveau_grobj_alloc *init = data;
169         struct nouveau_channel *chan;
170         int ret;
171
172         if (init->handle == ~0)
173                 return -EINVAL;
174
175         /* compatibility with userspace that assumes 506e for all chipsets */
176         if (init->class == 0x506e) {
177                 init->class = nouveau_software_class(dev);
178                 if (init->class == 0x906e)
179                         return 0;
180         } else
181         if (init->class == 0x906e) {
182                 NV_DEBUG(dev, "906e not supported yet\n");
183                 return -EINVAL;
184         }
185
186         chan = nouveau_channel_get(file_priv, init->channel);
187         if (IS_ERR(chan))
188                 return PTR_ERR(chan);
189
190         if (nouveau_ramht_find(chan, init->handle)) {
191                 ret = -EEXIST;
192                 goto out;
193         }
194
195         ret = nouveau_gpuobj_gr_new(chan, init->handle, init->class);
196         if (ret) {
197                 NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n",
198                          ret, init->channel, init->handle);
199         }
200
201 out:
202         nouveau_channel_put(&chan);
203         return ret;
204 }
205
206 int
207 nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
208 {
209         struct drm_nouveau_private *dev_priv = dev->dev_private;
210         struct drm_nouveau_notifierobj_alloc *na = data;
211         struct nouveau_channel *chan;
212         int ret;
213
214         /* completely unnecessary for these chipsets... */
215         if (unlikely(dev_priv->card_type >= NV_C0))
216                 return -EINVAL;
217
218         chan = nouveau_channel_get(file_priv, na->channel);
219         if (IS_ERR(chan))
220                 return PTR_ERR(chan);
221
222         ret = nouveau_notifier_alloc(chan, na->handle, na->size, 0, 0x1000,
223                                      &na->offset);
224         nouveau_channel_put(&chan);
225         return ret;
226 }
227
228 int
229 nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS)
230 {
231         struct drm_nouveau_gpuobj_free *objfree = data;
232         struct nouveau_channel *chan;
233         int ret;
234
235         chan = nouveau_channel_get(file_priv, objfree->channel);
236         if (IS_ERR(chan))
237                 return PTR_ERR(chan);
238
239         /* Synchronize with the user channel */
240         nouveau_channel_idle(chan);
241
242         ret = nouveau_ramht_remove(chan, objfree->handle);
243         nouveau_channel_put(&chan);
244         return ret;
245 }