2 * Copyright 2012 Red Hat Inc.
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 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.
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"
33 nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS
)
35 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
36 struct drm_nouveau_getparam
*getparam
= data
;
38 switch (getparam
->param
) {
39 case NOUVEAU_GETPARAM_CHIPSET_ID
:
40 getparam
->value
= dev_priv
->chipset
;
42 case NOUVEAU_GETPARAM_PCI_VENDOR
:
43 getparam
->value
= dev
->pci_vendor
;
45 case NOUVEAU_GETPARAM_PCI_DEVICE
:
46 getparam
->value
= dev
->pci_device
;
48 case NOUVEAU_GETPARAM_BUS_TYPE
:
49 if (drm_pci_device_is_agp(dev
))
52 if (!pci_is_pcie(dev
->pdev
))
57 case NOUVEAU_GETPARAM_FB_SIZE
:
58 getparam
->value
= dev_priv
->fb_available_size
;
60 case NOUVEAU_GETPARAM_AGP_SIZE
:
61 getparam
->value
= dev_priv
->gart_info
.aper_size
;
63 case NOUVEAU_GETPARAM_VM_VRAM_BASE
:
64 getparam
->value
= 0; /* deprecated */
66 case NOUVEAU_GETPARAM_PTIMER_TIME
:
67 getparam
->value
= dev_priv
->engine
.timer
.read(dev
);
69 case NOUVEAU_GETPARAM_HAS_BO_USAGE
:
72 case NOUVEAU_GETPARAM_HAS_PAGEFLIP
:
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
79 if (dev_priv
->chipset
>= 0x40) {
80 getparam
->value
= nv_rd32(dev
, NV40_PMC_GRAPH_UNITS
);
85 NV_DEBUG(dev
, "unknown parameter %lld\n", getparam
->param
);
93 nouveau_abi16_ioctl_setparam(ABI16_IOCTL_ARGS
)
99 nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS
)
101 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
102 struct drm_nouveau_channel_alloc
*init
= data
;
103 struct nouveau_channel
*chan
;
106 if (!dev_priv
->eng
[NVOBJ_ENGINE_GR
])
109 if (init
->fb_ctxdma_handle
== ~0 || init
->tt_ctxdma_handle
== ~0)
112 ret
= nouveau_channel_alloc(dev
, &chan
, file_priv
,
113 init
->fb_ctxdma_handle
,
114 init
->tt_ctxdma_handle
);
117 init
->channel
= chan
->id
;
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
;
126 init
->pushbuf_domains
= NOUVEAU_GEM_DOMAIN_GART
;
128 init
->pushbuf_domains
= NOUVEAU_GEM_DOMAIN_VRAM
;
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;
139 /* Named memory object area */
140 ret
= drm_gem_handle_create(file_priv
, chan
->notifier_bo
->gem
,
141 &init
->notifier_handle
);
144 atomic_inc(&chan
->users
); /* userspace reference */
145 nouveau_channel_put(&chan
);
150 nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS
)
152 struct drm_nouveau_channel_free
*req
= data
;
153 struct nouveau_channel
*chan
;
155 chan
= nouveau_channel_get(file_priv
, req
->channel
);
157 return PTR_ERR(chan
);
159 list_del(&chan
->list
);
160 atomic_dec(&chan
->users
);
161 nouveau_channel_put(&chan
);
166 nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS
)
168 struct drm_nouveau_grobj_alloc
*init
= data
;
169 struct nouveau_channel
*chan
;
172 if (init
->handle
== ~0)
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)
181 if (init
->class == 0x906e) {
182 NV_DEBUG(dev
, "906e not supported yet\n");
186 chan
= nouveau_channel_get(file_priv
, init
->channel
);
188 return PTR_ERR(chan
);
190 if (nouveau_ramht_find(chan
, init
->handle
)) {
195 ret
= nouveau_gpuobj_gr_new(chan
, init
->handle
, init
->class);
197 NV_ERROR(dev
, "Error creating object: %d (%d/0x%08x)\n",
198 ret
, init
->channel
, init
->handle
);
202 nouveau_channel_put(&chan
);
207 nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS
)
209 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
210 struct drm_nouveau_notifierobj_alloc
*na
= data
;
211 struct nouveau_channel
*chan
;
214 /* completely unnecessary for these chipsets... */
215 if (unlikely(dev_priv
->card_type
>= NV_C0
))
218 chan
= nouveau_channel_get(file_priv
, na
->channel
);
220 return PTR_ERR(chan
);
222 ret
= nouveau_notifier_alloc(chan
, na
->handle
, na
->size
, 0, 0x1000,
224 nouveau_channel_put(&chan
);
229 nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS
)
231 struct drm_nouveau_gpuobj_free
*objfree
= data
;
232 struct nouveau_channel
*chan
;
235 chan
= nouveau_channel_get(file_priv
, objfree
->channel
);
237 return PTR_ERR(chan
);
239 /* Synchronize with the user channel */
240 nouveau_channel_idle(chan
);
242 ret
= nouveau_ramht_remove(chan
, objfree
->handle
);
243 nouveau_channel_put(&chan
);