blob: 59bc43605cf65ba7a5336645a3de65a52999ccb0 [file] [log] [blame]
Ben Skeggs292da612011-12-09 16:11:06 +10001/*
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 * Authors: Ben Skeggs
23 */
24
Rob Clarkc09dcbc2014-09-28 14:19:14 -040025#ifdef HAVE_CONFIG_H
26# include <config.h>
27#endif
28
Ben Skeggs292da612011-12-09 16:11:06 +100029#include <stdlib.h>
30#include <stdint.h>
Ben Skeggsc41b4942012-11-23 12:40:30 +100031#include <stddef.h>
Ben Skeggs292da612011-12-09 16:11:06 +100032
33#include "private.h"
34
Ben Skeggsc41b4942012-11-23 12:40:30 +100035
Emil Velikov76e97992015-03-23 21:52:00 +000036drm_private int
Ben Skeggs292da612011-12-09 16:11:06 +100037abi16_chan_nv04(struct nouveau_object *obj)
38{
39 struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
Ben Skeggs292da612011-12-09 16:11:06 +100040 struct nv04_fifo *nv04 = obj->data;
Emil Velikova9e58802015-08-15 18:01:53 +010041 struct drm_nouveau_channel_alloc req = {
42 .fb_ctxdma_handle = nv04->vram,
43 .tt_ctxdma_handle = nv04->gart
44 };
Ben Skeggs292da612011-12-09 16:11:06 +100045 int ret;
46
Ben Skeggs292da612011-12-09 16:11:06 +100047 ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
48 &req, sizeof(req));
49 if (ret)
50 return ret;
51
52 nv04->base.channel = req.channel;
53 nv04->base.pushbuf = req.pushbuf_domains;
54 nv04->notify = req.notifier_handle;
55 nv04->base.object->handle = req.channel;
56 nv04->base.object->length = sizeof(*nv04);
57 return 0;
58}
59
Emil Velikov76e97992015-03-23 21:52:00 +000060drm_private int
Ben Skeggs292da612011-12-09 16:11:06 +100061abi16_chan_nvc0(struct nouveau_object *obj)
62{
63 struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
Ben Skeggs73b9a282012-04-17 08:35:43 +100064 struct drm_nouveau_channel_alloc req = {};
Ben Skeggs292da612011-12-09 16:11:06 +100065 struct nvc0_fifo *nvc0 = obj->data;
66 int ret;
67
68 ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
69 &req, sizeof(req));
70 if (ret)
71 return ret;
72
73 nvc0->base.channel = req.channel;
74 nvc0->base.pushbuf = req.pushbuf_domains;
Christoph Bumiller754655c2012-04-19 20:03:39 +020075 nvc0->notify = req.notifier_handle;
Ben Skeggs292da612011-12-09 16:11:06 +100076 nvc0->base.object->handle = req.channel;
77 nvc0->base.object->length = sizeof(*nvc0);
78 return 0;
79}
80
Emil Velikov76e97992015-03-23 21:52:00 +000081drm_private int
Ben Skeggsc41b4942012-11-23 12:40:30 +100082abi16_chan_nve0(struct nouveau_object *obj)
83{
84 struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
85 struct drm_nouveau_channel_alloc req = {};
86 struct nve0_fifo *nve0 = obj->data;
87 int ret;
88
89 if (obj->length > offsetof(struct nve0_fifo, engine)) {
90 req.fb_ctxdma_handle = 0xffffffff;
91 req.tt_ctxdma_handle = nve0->engine;
92 }
93
94 ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
95 &req, sizeof(req));
96 if (ret)
97 return ret;
98
99 nve0->base.channel = req.channel;
100 nve0->base.pushbuf = req.pushbuf_domains;
101 nve0->notify = req.notifier_handle;
102 nve0->base.object->handle = req.channel;
103 nve0->base.object->length = sizeof(*nve0);
104 return 0;
105}
106
Emil Velikov76e97992015-03-23 21:52:00 +0000107drm_private int
Ben Skeggs292da612011-12-09 16:11:06 +1000108abi16_engobj(struct nouveau_object *obj)
109{
110 struct drm_nouveau_grobj_alloc req = {
Emil Velikova9e58802015-08-15 18:01:53 +0100111 .channel = obj->parent->handle,
112 .handle = obj->handle,
113 .class = obj->oclass,
Ben Skeggs292da612011-12-09 16:11:06 +1000114 };
115 struct nouveau_device *dev;
116 int ret;
117
118 dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
119 ret = drmCommandWrite(dev->fd, DRM_NOUVEAU_GROBJ_ALLOC,
120 &req, sizeof(req));
121 if (ret)
122 return ret;
123
124 obj->length = sizeof(struct nouveau_object *);
125 return 0;
126}
127
Emil Velikov76e97992015-03-23 21:52:00 +0000128drm_private int
Ben Skeggs292da612011-12-09 16:11:06 +1000129abi16_ntfy(struct nouveau_object *obj)
130{
131 struct nv04_notify *ntfy = obj->data;
132 struct drm_nouveau_notifierobj_alloc req = {
Emil Velikova9e58802015-08-15 18:01:53 +0100133 .channel = obj->parent->handle,
134 .handle = ntfy->object->handle,
135 .size = ntfy->length,
Ben Skeggs292da612011-12-09 16:11:06 +1000136 };
137 struct nouveau_device *dev;
138 int ret;
139
140 dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
141 ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC,
142 &req, sizeof(req));
143 if (ret)
144 return ret;
145
146 ntfy->offset = req.offset;
147 ntfy->object->length = sizeof(*ntfy);
148 return 0;
149}
150
Emil Velikov76e97992015-03-23 21:52:00 +0000151drm_private void
Ben Skeggs292da612011-12-09 16:11:06 +1000152abi16_bo_info(struct nouveau_bo *bo, struct drm_nouveau_gem_info *info)
153{
154 struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
155
156 nvbo->map_handle = info->map_handle;
157 bo->handle = info->handle;
158 bo->size = info->size;
159 bo->offset = info->offset;
160
161 bo->flags = 0;
162 if (info->domain & NOUVEAU_GEM_DOMAIN_VRAM)
163 bo->flags |= NOUVEAU_BO_VRAM;
164 if (info->domain & NOUVEAU_GEM_DOMAIN_GART)
165 bo->flags |= NOUVEAU_BO_GART;
166 if (!(info->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG))
167 bo->flags |= NOUVEAU_BO_CONTIG;
168 if (nvbo->map_handle)
169 bo->flags |= NOUVEAU_BO_MAP;
170
171 if (bo->device->chipset >= 0xc0) {
172 bo->config.nvc0.memtype = (info->tile_flags & 0xff00) >> 8;
173 bo->config.nvc0.tile_mode = info->tile_mode;
174 } else
175 if (bo->device->chipset >= 0x80 || bo->device->chipset == 0x50) {
176 bo->config.nv50.memtype = (info->tile_flags & 0x07f00) >> 8 |
177 (info->tile_flags & 0x30000) >> 9;
178 bo->config.nv50.tile_mode = info->tile_mode << 4;
179 } else {
180 bo->config.nv04.surf_flags = info->tile_flags & 7;
181 bo->config.nv04.surf_pitch = info->tile_mode;
182 }
183}
184
Emil Velikov76e97992015-03-23 21:52:00 +0000185drm_private int
Ben Skeggs292da612011-12-09 16:11:06 +1000186abi16_bo_init(struct nouveau_bo *bo, uint32_t alignment,
187 union nouveau_bo_config *config)
188{
189 struct nouveau_device *dev = bo->device;
190 struct drm_nouveau_gem_new req = {};
191 struct drm_nouveau_gem_info *info = &req.info;
192 int ret;
193
194 if (bo->flags & NOUVEAU_BO_VRAM)
195 info->domain |= NOUVEAU_GEM_DOMAIN_VRAM;
196 if (bo->flags & NOUVEAU_BO_GART)
197 info->domain |= NOUVEAU_GEM_DOMAIN_GART;
198 if (!info->domain)
199 info->domain |= NOUVEAU_GEM_DOMAIN_VRAM |
200 NOUVEAU_GEM_DOMAIN_GART;
201
202 if (bo->flags & NOUVEAU_BO_MAP)
203 info->domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE;
204
Alexandre Courbota1acffd2015-05-21 15:08:28 +0900205 if (bo->flags & NOUVEAU_BO_COHERENT)
206 info->domain |= NOUVEAU_GEM_DOMAIN_COHERENT;
207
Ben Skeggs292da612011-12-09 16:11:06 +1000208 if (!(bo->flags & NOUVEAU_BO_CONTIG))
209 info->tile_flags = NOUVEAU_GEM_TILE_NONCONTIG;
210
211 info->size = bo->size;
212 req.align = alignment;
213
214 if (config) {
215 if (dev->chipset >= 0xc0) {
216 info->tile_flags = (config->nvc0.memtype & 0xff) << 8;
217 info->tile_mode = config->nvc0.tile_mode;
218 } else
219 if (dev->chipset >= 0x80 || dev->chipset == 0x50) {
220 info->tile_flags = (config->nv50.memtype & 0x07f) << 8 |
221 (config->nv50.memtype & 0x180) << 9;
222 info->tile_mode = config->nv50.tile_mode >> 4;
223 } else {
224 info->tile_flags = config->nv04.surf_flags & 7;
225 info->tile_mode = config->nv04.surf_pitch;
226 }
227 }
228
229 if (!nouveau_device(dev)->have_bo_usage)
230 info->tile_flags &= 0x0000ff00;
231
232 ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_NEW,
233 &req, sizeof(req));
234 if (ret == 0)
235 abi16_bo_info(bo, &req.info);
236 return ret;
237}