Subversion Repositories Kolibri OS

Rev

Rev 1963 | Rev 2997 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1126 serge 1
/*
2
 * Copyright 2008 Advanced Micro Devices, Inc.
3
 * Copyright 2008 Red Hat Inc.
4
 * Copyright 2009 Jerome Glisse.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions 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 NONINFRINGEMENT.  IN NO EVENT SHALL
19
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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
22
 * OTHER DEALINGS IN THE SOFTWARE.
23
 *
24
 * Authors: Dave Airlie
25
 *          Alex Deucher
26
 *          Jerome Glisse
27
 */
28
#include "drmP.h"
29
#include "drm.h"
30
#include "radeon_drm.h"
31
#include "radeon.h"
32
 
33
int radeon_gem_object_init(struct drm_gem_object *obj)
34
{
35
	/* we do nothings here */
36
	return 0;
37
}
38
 
39
void radeon_gem_object_free(struct drm_gem_object *gobj)
40
{
1986 serge 41
	struct radeon_bo *robj = gem_to_radeon_bo(gobj);
1126 serge 42
 
43
	if (robj) {
1404 serge 44
		radeon_bo_unref(&robj);
1126 serge 45
	}
46
}
47
 
48
int radeon_gem_object_create(struct radeon_device *rdev, int size,
1404 serge 49
                 int alignment, int initial_domain,
50
                 bool discardable, bool kernel,
51
				struct drm_gem_object **obj)
1126 serge 52
{
1404 serge 53
    struct radeon_bo *robj;
1126 serge 54
	int r;
55
 
56
	*obj = NULL;
57
	/* At least align on page size */
58
	if (alignment < PAGE_SIZE) {
59
		alignment = PAGE_SIZE;
60
	}
1986 serge 61
	r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, &robj);
1126 serge 62
	if (r) {
1986 serge 63
		if (r != -ERESTARTSYS)
64
			DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n",
65
				  size, initial_domain, alignment, r);
1404 serge 66
        return r;
1126 serge 67
	}
1986 serge 68
	*obj = &robj->gem_base;
69
 
70
	mutex_lock(&rdev->gem.mutex);
71
	list_add_tail(&robj->list, &rdev->gem.objects);
72
	mutex_unlock(&rdev->gem.mutex);
73
 
1126 serge 74
	return 0;
75
}
76
 
77
int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain,
78
			  uint64_t *gpu_addr)
79
{
1986 serge 80
	struct radeon_bo *robj = gem_to_radeon_bo(obj);
1404 serge 81
	int r;
1126 serge 82
 
1404 serge 83
	r = radeon_bo_reserve(robj, false);
84
	if (unlikely(r != 0))
85
		return r;
86
	r = radeon_bo_pin(robj, pin_domain, gpu_addr);
87
	radeon_bo_unreserve(robj);
88
	return r;
1126 serge 89
}
90
 
91
void radeon_gem_object_unpin(struct drm_gem_object *obj)
92
{
1986 serge 93
	struct radeon_bo *robj = gem_to_radeon_bo(obj);
1404 serge 94
	int r;
95
 
96
	r = radeon_bo_reserve(robj, false);
97
	if (likely(r == 0)) {
98
		radeon_bo_unpin(robj);
99
		radeon_bo_unreserve(robj);
100
	}
1126 serge 101
}
102
 
103
int radeon_gem_set_domain(struct drm_gem_object *gobj,
104
			  uint32_t rdomain, uint32_t wdomain)
105
{
1404 serge 106
	struct radeon_bo *robj;
1126 serge 107
	uint32_t domain;
108
	int r;
109
 
110
	/* FIXME: reeimplement */
1986 serge 111
	robj = gem_to_radeon_bo(gobj);
1126 serge 112
	/* work out where to validate the buffer to */
113
	domain = wdomain;
114
	if (!domain) {
115
		domain = rdomain;
116
	}
117
	if (!domain) {
118
		/* Do nothings */
119
		printk(KERN_WARNING "Set domain withou domain !\n");
120
		return 0;
121
	}
122
	if (domain == RADEON_GEM_DOMAIN_CPU) {
123
		/* Asking for cpu access wait for object idle */
1404 serge 124
//		r = radeon_bo_wait(robj, NULL, false);
125
//		if (r) {
126
//			printk(KERN_ERR "Failed to wait for object !\n");
127
//			return r;
128
//		}
1126 serge 129
	}
130
	return 0;
131
}
132
 
133
int radeon_gem_init(struct radeon_device *rdev)
134
{
135
	INIT_LIST_HEAD(&rdev->gem.objects);
136
	return 0;
137
}
138
 
139
void radeon_gem_fini(struct radeon_device *rdev)
140
{
141
 //  radeon_object_force_delete(rdev);
142
}
143
 
144
#if 0
145
/*
146
 * GEM ioctls.
147
 */
148
int radeon_gem_info_ioctl(struct drm_device *dev, void *data,
149
			  struct drm_file *filp)
150
{
151
	struct radeon_device *rdev = dev->dev_private;
152
	struct drm_radeon_gem_info *args = data;
1986 serge 153
	struct ttm_mem_type_manager *man;
1126 serge 154
 
1986 serge 155
	man = &rdev->mman.bdev.man[TTM_PL_VRAM];
156
 
1179 serge 157
	args->vram_size = rdev->mc.real_vram_size;
1986 serge 158
	args->vram_visible = (u64)man->size << PAGE_SHIFT;
1963 serge 159
	if (rdev->stollen_vga_memory)
160
		args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory);
161
	args->vram_visible -= radeon_fbdev_total_size(rdev);
162
	args->gart_size = rdev->mc.gtt_size - rdev->cp.ring_size - 4096 -
163
		RADEON_IB_POOL_SIZE*64*1024;
1126 serge 164
	return 0;
165
}
166
 
167
int radeon_gem_pread_ioctl(struct drm_device *dev, void *data,
168
			   struct drm_file *filp)
169
{
170
	/* TODO: implement */
171
	DRM_ERROR("unimplemented %s\n", __func__);
172
	return -ENOSYS;
173
}
174
 
175
int radeon_gem_pwrite_ioctl(struct drm_device *dev, void *data,
176
			    struct drm_file *filp)
177
{
178
	/* TODO: implement */
179
	DRM_ERROR("unimplemented %s\n", __func__);
180
	return -ENOSYS;
181
}
182
 
183
int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
184
			    struct drm_file *filp)
185
{
186
	struct radeon_device *rdev = dev->dev_private;
187
	struct drm_radeon_gem_create *args = data;
188
	struct drm_gem_object *gobj;
189
	uint32_t handle;
190
	int r;
191
 
192
	/* create a gem object to contain this object in */
193
	args->size = roundup(args->size, PAGE_SIZE);
194
	r = radeon_gem_object_create(rdev, args->size, args->alignment,
195
				     args->initial_domain, false,
1404 serge 196
					false, &gobj);
1126 serge 197
	if (r) {
198
		return r;
199
	}
200
	r = drm_gem_handle_create(filp, gobj, &handle);
1963 serge 201
	/* drop reference from allocate - handle holds it now */
202
	drm_gem_object_unreference_unlocked(gobj);
1126 serge 203
	if (r) {
204
		return r;
205
	}
206
	args->handle = handle;
207
	return 0;
208
}
209
 
210
int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
211
				struct drm_file *filp)
212
{
213
	/* transition the BO to a domain -
214
	 * just validate the BO into a certain domain */
215
	struct drm_radeon_gem_set_domain *args = data;
216
	struct drm_gem_object *gobj;
1404 serge 217
	struct radeon_bo *robj;
1126 serge 218
	int r;
219
 
220
	/* for now if someone requests domain CPU -
221
	 * just make sure the buffer is finished with */
222
 
223
	/* just do a BO wait for now */
224
	gobj = drm_gem_object_lookup(dev, filp, args->handle);
225
	if (gobj == NULL) {
1963 serge 226
		return -ENOENT;
1126 serge 227
	}
1986 serge 228
	robj = gem_to_radeon_bo(gobj);
1126 serge 229
 
230
	r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain);
231
 
1963 serge 232
	drm_gem_object_unreference_unlocked(gobj);
1126 serge 233
	return r;
234
}
235
 
1986 serge 236
int radeon_mode_dumb_mmap(struct drm_file *filp,
237
			  struct drm_device *dev,
238
			  uint32_t handle, uint64_t *offset_p)
1126 serge 239
{
240
	struct drm_gem_object *gobj;
1404 serge 241
	struct radeon_bo *robj;
1126 serge 242
 
1986 serge 243
	gobj = drm_gem_object_lookup(dev, filp, handle);
1126 serge 244
	if (gobj == NULL) {
1963 serge 245
		return -ENOENT;
1126 serge 246
	}
1986 serge 247
	robj = gem_to_radeon_bo(gobj);
248
	*offset_p = radeon_bo_mmap_offset(robj);
1963 serge 249
	drm_gem_object_unreference_unlocked(gobj);
1404 serge 250
	return 0;
1126 serge 251
}
252
 
1986 serge 253
int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data,
254
			  struct drm_file *filp)
255
{
256
	struct drm_radeon_gem_mmap *args = data;
257
 
258
	return radeon_mode_dumb_mmap(filp, dev, args->handle, &args->addr_ptr);
259
}
260
 
1126 serge 261
int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
262
			  struct drm_file *filp)
263
{
1404 serge 264
	struct drm_radeon_gem_busy *args = data;
265
	struct drm_gem_object *gobj;
266
	struct radeon_bo *robj;
267
	int r;
268
	uint32_t cur_placement = 0;
269
 
270
	gobj = drm_gem_object_lookup(dev, filp, args->handle);
271
	if (gobj == NULL) {
1963 serge 272
		return -ENOENT;
1404 serge 273
	}
1986 serge 274
	robj = gem_to_radeon_bo(gobj);
1404 serge 275
	r = radeon_bo_wait(robj, &cur_placement, true);
276
	switch (cur_placement) {
277
	case TTM_PL_VRAM:
278
		args->domain = RADEON_GEM_DOMAIN_VRAM;
279
		break;
280
	case TTM_PL_TT:
281
		args->domain = RADEON_GEM_DOMAIN_GTT;
282
		break;
283
	case TTM_PL_SYSTEM:
284
		args->domain = RADEON_GEM_DOMAIN_CPU;
285
	default:
286
		break;
287
	}
1963 serge 288
	drm_gem_object_unreference_unlocked(gobj);
1404 serge 289
	return r;
1126 serge 290
}
291
 
292
int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
293
			      struct drm_file *filp)
294
{
295
	struct drm_radeon_gem_wait_idle *args = data;
296
	struct drm_gem_object *gobj;
1404 serge 297
	struct radeon_bo *robj;
1126 serge 298
	int r;
299
 
300
	gobj = drm_gem_object_lookup(dev, filp, args->handle);
301
	if (gobj == NULL) {
1963 serge 302
		return -ENOENT;
1126 serge 303
	}
1986 serge 304
	robj = gem_to_radeon_bo(gobj);
1404 serge 305
	r = radeon_bo_wait(robj, NULL, false);
306
	/* callback hw specific functions if any */
307
	if (robj->rdev->asic->ioctl_wait_idle)
308
		robj->rdev->asic->ioctl_wait_idle(robj->rdev, robj);
1963 serge 309
	drm_gem_object_unreference_unlocked(gobj);
1126 serge 310
	return r;
311
}
312
 
1404 serge 313
int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data,
314
				struct drm_file *filp)
315
{
316
	struct drm_radeon_gem_set_tiling *args = data;
317
	struct drm_gem_object *gobj;
318
	struct radeon_bo *robj;
319
	int r = 0;
320
 
321
	DRM_DEBUG("%d \n", args->handle);
322
	gobj = drm_gem_object_lookup(dev, filp, args->handle);
323
	if (gobj == NULL)
1963 serge 324
		return -ENOENT;
1986 serge 325
	robj = gem_to_radeon_bo(gobj);
1404 serge 326
	r = radeon_bo_set_tiling_flags(robj, args->tiling_flags, args->pitch);
1963 serge 327
	drm_gem_object_unreference_unlocked(gobj);
1404 serge 328
	return r;
329
}
330
 
1126 serge 331
#endif