Subversion Repositories Kolibri OS

Rev

Rev 5078 | Rev 5346 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5078 Rev 5271
Line 82... Line 82...
82
static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
82
static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
83
{
83
{
84
	struct drm_device *ddev = p->rdev->ddev;
84
	struct drm_device *ddev = p->rdev->ddev;
85
	struct radeon_cs_chunk *chunk;
85
	struct radeon_cs_chunk *chunk;
86
	struct radeon_cs_buckets buckets;
86
	struct radeon_cs_buckets buckets;
87
	unsigned i, j;
87
	unsigned i;
88
	bool duplicate;
88
	bool need_mmap_lock = false;
-
 
89
	int r;
Line 89... Line 90...
89
 
90
 
90
	if (p->chunk_relocs_idx == -1) {
91
	if (p->chunk_relocs == NULL) {
91
		return 0;
92
		return 0;
92
	}
93
	}
93
	chunk = &p->chunks[p->chunk_relocs_idx];
94
	chunk = p->chunk_relocs;
94
	p->dma_reloc_idx = 0;
95
	p->dma_reloc_idx = 0;
95
	/* FIXME: we assume that each relocs use 4 dwords */
96
	/* FIXME: we assume that each relocs use 4 dwords */
96
	p->nrelocs = chunk->length_dw / 4;
-
 
97
	p->relocs_ptr = kcalloc(p->nrelocs, sizeof(void *), GFP_KERNEL);
-
 
98
	if (p->relocs_ptr == NULL) {
-
 
99
		return -ENOMEM;
-
 
100
	}
97
	p->nrelocs = chunk->length_dw / 4;
101
	p->relocs = kcalloc(p->nrelocs, sizeof(struct radeon_cs_reloc), GFP_KERNEL);
98
	p->relocs = kcalloc(p->nrelocs, sizeof(struct radeon_bo_list), GFP_KERNEL);
102
	if (p->relocs == NULL) {
99
	if (p->relocs == NULL) {
103
		return -ENOMEM;
100
		return -ENOMEM;
Line 104... Line 101...
104
	}
101
	}
Line 105... Line 102...
105
 
102
 
106
	radeon_cs_buckets_init(&buckets);
103
	radeon_cs_buckets_init(&buckets);
-
 
104
 
107
 
105
	for (i = 0; i < p->nrelocs; i++) {
Line 108... Line -...
108
	for (i = 0; i < p->nrelocs; i++) {
-
 
109
		struct drm_radeon_cs_reloc *r;
106
		struct drm_radeon_cs_reloc *r;
110
		unsigned priority;
-
 
111
 
-
 
112
		duplicate = false;
-
 
113
		r = (struct drm_radeon_cs_reloc *)&chunk->kdata[i*4];
-
 
114
		for (j = 0; j < i; j++) {
-
 
115
			if (r->handle == p->relocs[j].handle) {
-
 
116
				p->relocs_ptr[i] = &p->relocs[j];
-
 
117
				duplicate = true;
-
 
118
				break;
-
 
119
			}
-
 
120
		}
-
 
121
		if (duplicate) {
-
 
122
			p->relocs[i].handle = 0;
107
		struct drm_gem_object *gobj;
123
			continue;
-
 
124
		}
108
		unsigned priority;
125
 
109
 
126
		p->relocs[i].gobj = drm_gem_object_lookup(ddev, p->filp,
110
		r = (struct drm_radeon_cs_reloc *)&chunk->kdata[i*4];
127
							  r->handle);
111
		gobj = drm_gem_object_lookup(ddev, p->filp, r->handle);
128
		if (p->relocs[i].gobj == NULL) {
112
		if (gobj == NULL) {
129
			DRM_ERROR("gem object lookup failed 0x%x\n",
-
 
130
				  r->handle);
113
			DRM_ERROR("gem object lookup failed 0x%x\n",
Line 131... Line 114...
131
			return -ENOENT;
114
				  r->handle);
132
		}
115
			return -ENOENT;
133
		p->relocs_ptr[i] = &p->relocs[i];
116
		}
134
		p->relocs[i].robj = gem_to_radeon_bo(p->relocs[i].gobj);
117
		p->relocs[i].robj = gem_to_radeon_bo(gobj);
Line 141... Line 124...
141
		 */
124
		 */
142
		priority = (r->flags & RADEON_RELOC_PRIO_MASK) * 2
125
		priority = (r->flags & RADEON_RELOC_PRIO_MASK) * 2
143
			   + !!r->write_domain;
126
			   + !!r->write_domain;
Line 144... Line 127...
144
 
127
 
145
		/* the first reloc of an UVD job is the msg and that must be in
128
		/* the first reloc of an UVD job is the msg and that must be in
146
		   VRAM, also but everything into VRAM on AGP cards to avoid
129
		   VRAM, also but everything into VRAM on AGP cards and older
147
		   image corruptions */
130
		   IGP chips to avoid image corruptions */
148
		if (p->ring == R600_RING_TYPE_UVD_INDEX &&
131
		if (p->ring == R600_RING_TYPE_UVD_INDEX &&
-
 
132
		    (i == 0 || drm_pci_device_is_agp(p->rdev->ddev) ||
-
 
133
		     p->rdev->family == CHIP_RS780 ||
-
 
134
		     p->rdev->family == CHIP_RS880)) {
149
		    (i == 0 || drm_pci_device_is_agp(p->rdev->ddev))) {
135
 
150
			/* TODO: is this still needed for NI+ ? */
136
			/* TODO: is this still needed for NI+ ? */
151
			p->relocs[i].prefered_domains =
137
			p->relocs[i].prefered_domains =
Line 152... Line 138...
152
				RADEON_GEM_DOMAIN_VRAM;
138
				RADEON_GEM_DOMAIN_VRAM;
Line 169... Line 155...
169
			p->relocs[i].prefered_domains = domain;
155
			p->relocs[i].prefered_domains = domain;
170
			if (domain == RADEON_GEM_DOMAIN_VRAM)
156
			if (domain == RADEON_GEM_DOMAIN_VRAM)
171
				domain |= RADEON_GEM_DOMAIN_GTT;
157
				domain |= RADEON_GEM_DOMAIN_GTT;
172
			p->relocs[i].allowed_domains = domain;
158
			p->relocs[i].allowed_domains = domain;
173
		}
159
		}
174
 
160
/*
-
 
161
		if (radeon_ttm_tt_has_userptr(p->relocs[i].robj->tbo.ttm)) {
-
 
162
			uint32_t domain = p->relocs[i].prefered_domains;
-
 
163
			if (!(domain & RADEON_GEM_DOMAIN_GTT)) {
-
 
164
				DRM_ERROR("Only RADEON_GEM_DOMAIN_GTT is "
-
 
165
					  "allowed for userptr BOs\n");
-
 
166
				return -EINVAL;
-
 
167
			}
-
 
168
			need_mmap_lock = true;
-
 
169
			domain = RADEON_GEM_DOMAIN_GTT;
-
 
170
			p->relocs[i].prefered_domains = domain;
-
 
171
			p->relocs[i].allowed_domains = domain;
-
 
172
		}
-
 
173
*/
175
		p->relocs[i].tv.bo = &p->relocs[i].robj->tbo;
174
		p->relocs[i].tv.bo = &p->relocs[i].robj->tbo;
176
		p->relocs[i].handle = r->handle;
175
		p->relocs[i].tv.shared = !r->write_domain;
Line 177... Line 176...
177
 
176
 
178
		radeon_cs_buckets_add(&buckets, &p->relocs[i].tv.head,
177
		radeon_cs_buckets_add(&buckets, &p->relocs[i].tv.head,
179
				      priority);
178
				      priority);
Line 180... Line 179...
180
	}
179
	}
Line 181... Line 180...
181
 
180
 
182
	radeon_cs_buckets_get_list(&buckets, &p->validated);
181
	radeon_cs_buckets_get_list(&buckets, &p->validated);
183
 
182
 
-
 
183
	if (p->cs_flags & RADEON_CS_USE_VM)
-
 
184
		p->vm_bos = radeon_vm_get_bos(p->rdev, p->ib.vm,
-
 
185
					      &p->validated);
-
 
186
//	if (need_mmap_lock)
-
 
187
//		down_read(¤t->mm->mmap_sem);
-
 
188
 
-
 
189
	r = radeon_bo_list_validate(p->rdev, &p->ticket, &p->validated, p->ring);
Line 184... Line 190...
184
	if (p->cs_flags & RADEON_CS_USE_VM)
190
 
185
		p->vm_bos = radeon_vm_get_bos(p->rdev, p->ib.vm,
191
//	if (need_mmap_lock)
Line 186... Line 192...
186
					      &p->validated);
192
//		up_read(¤t->mm->mmap_sem);
187
 
193
 
188
	return radeon_bo_list_validate(p->rdev, &p->ticket, &p->validated, p->ring);
194
	return r;
Line 229... Line 235...
229
		break;
235
		break;
230
	}
236
	}
231
	return 0;
237
	return 0;
232
}
238
}
Line 233... Line 239...
233
 
239
 
234
static void radeon_cs_sync_rings(struct radeon_cs_parser *p)
240
static int radeon_cs_sync_rings(struct radeon_cs_parser *p)
-
 
241
{
235
{
242
	struct radeon_bo_list *reloc;
Line 236... Line 243...
236
	int i;
243
	int r;
237
 
244
 
238
	for (i = 0; i < p->nrelocs; i++) {
-
 
Line -... Line 245...
-
 
245
	list_for_each_entry(reloc, &p->validated, tv.head) {
239
		if (!p->relocs[i].robj)
246
		struct reservation_object *resv;
240
			continue;
247
 
-
 
248
		resv = reloc->robj->tbo.resv;
-
 
249
		r = radeon_sync_resv(p->rdev, &p->ib.sync, resv,
241
 
250
				     reloc->tv.shared);
-
 
251
		if (r)
242
		radeon_semaphore_sync_to(p->ib.semaphore,
252
			return r;
Line 243... Line 253...
243
					 p->relocs[i].robj->tbo.sync_obj);
253
	}
244
	}
254
	return 0;
245
}
255
}
Line 258... Line 268...
258
	}
268
	}
259
	/* get chunks */
269
	/* get chunks */
260
	INIT_LIST_HEAD(&p->validated);
270
	INIT_LIST_HEAD(&p->validated);
261
	p->idx = 0;
271
	p->idx = 0;
262
	p->ib.sa_bo = NULL;
272
	p->ib.sa_bo = NULL;
263
	p->ib.semaphore = NULL;
-
 
264
	p->const_ib.sa_bo = NULL;
273
	p->const_ib.sa_bo = NULL;
265
	p->const_ib.semaphore = NULL;
-
 
266
	p->chunk_ib_idx = -1;
274
	p->chunk_ib = NULL;
267
	p->chunk_relocs_idx = -1;
275
	p->chunk_relocs = NULL;
268
	p->chunk_flags_idx = -1;
276
	p->chunk_flags = NULL;
269
	p->chunk_const_ib_idx = -1;
277
	p->chunk_const_ib = NULL;
270
	p->chunks_array = kcalloc(cs->num_chunks, sizeof(uint64_t), GFP_KERNEL);
278
	p->chunks_array = kcalloc(cs->num_chunks, sizeof(uint64_t), GFP_KERNEL);
271
	if (p->chunks_array == NULL) {
279
	if (p->chunks_array == NULL) {
272
		return -ENOMEM;
280
		return -ENOMEM;
273
	}
281
	}
274
	chunk_array_ptr = (uint64_t *)(unsigned long)(cs->chunks);
282
	chunk_array_ptr = (uint64_t *)(unsigned long)(cs->chunks);
Line 291... Line 299...
291
		if (copy_from_user(&user_chunk, chunk_ptr,
299
		if (copy_from_user(&user_chunk, chunk_ptr,
292
				       sizeof(struct drm_radeon_cs_chunk))) {
300
				       sizeof(struct drm_radeon_cs_chunk))) {
293
			return -EFAULT;
301
			return -EFAULT;
294
		}
302
		}
295
		p->chunks[i].length_dw = user_chunk.length_dw;
303
		p->chunks[i].length_dw = user_chunk.length_dw;
296
		p->chunks[i].chunk_id = user_chunk.chunk_id;
-
 
297
		if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) {
304
		if (user_chunk.chunk_id == RADEON_CHUNK_ID_RELOCS) {
298
			p->chunk_relocs_idx = i;
305
			p->chunk_relocs = &p->chunks[i];
299
		}
306
		}
300
		if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_IB) {
307
		if (user_chunk.chunk_id == RADEON_CHUNK_ID_IB) {
301
			p->chunk_ib_idx = i;
308
			p->chunk_ib = &p->chunks[i];
302
			/* zero length IB isn't useful */
309
			/* zero length IB isn't useful */
303
			if (p->chunks[i].length_dw == 0)
310
			if (p->chunks[i].length_dw == 0)
304
				return -EINVAL;
311
				return -EINVAL;
305
		}
312
		}
306
		if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_CONST_IB) {
313
		if (user_chunk.chunk_id == RADEON_CHUNK_ID_CONST_IB) {
307
			p->chunk_const_ib_idx = i;
314
			p->chunk_const_ib = &p->chunks[i];
308
			/* zero length CONST IB isn't useful */
315
			/* zero length CONST IB isn't useful */
309
			if (p->chunks[i].length_dw == 0)
316
			if (p->chunks[i].length_dw == 0)
310
				return -EINVAL;
317
				return -EINVAL;
311
		}
318
		}
312
		if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) {
319
		if (user_chunk.chunk_id == RADEON_CHUNK_ID_FLAGS) {
313
			p->chunk_flags_idx = i;
320
			p->chunk_flags = &p->chunks[i];
314
			/* zero length flags aren't useful */
321
			/* zero length flags aren't useful */
315
			if (p->chunks[i].length_dw == 0)
322
			if (p->chunks[i].length_dw == 0)
316
				return -EINVAL;
323
				return -EINVAL;
317
		}
324
		}
Line 318... Line 325...
318
 
325
 
319
		size = p->chunks[i].length_dw;
326
		size = p->chunks[i].length_dw;
320
		cdata = (void __user *)(unsigned long)user_chunk.chunk_data;
327
		cdata = (void __user *)(unsigned long)user_chunk.chunk_data;
321
		p->chunks[i].user_ptr = cdata;
328
		p->chunks[i].user_ptr = cdata;
322
		if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_CONST_IB)
329
		if (user_chunk.chunk_id == RADEON_CHUNK_ID_CONST_IB)
Line 323... Line 330...
323
			continue;
330
			continue;
324
 
331
 
325
		if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_IB) {
332
		if (user_chunk.chunk_id == RADEON_CHUNK_ID_IB) {
326
			if (!p->rdev || !(p->rdev->flags & RADEON_IS_AGP))
333
			if (!p->rdev || !(p->rdev->flags & RADEON_IS_AGP))
Line 327... Line 334...
327
				continue;
334
				continue;
Line 333... Line 340...
333
			return -ENOMEM;
340
			return -ENOMEM;
334
		}
341
		}
335
		if (copy_from_user(p->chunks[i].kdata, cdata, size)) {
342
		if (copy_from_user(p->chunks[i].kdata, cdata, size)) {
336
			return -EFAULT;
343
			return -EFAULT;
337
		}
344
		}
338
		if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) {
345
		if (user_chunk.chunk_id == RADEON_CHUNK_ID_FLAGS) {
339
			p->cs_flags = p->chunks[i].kdata[0];
346
			p->cs_flags = p->chunks[i].kdata[0];
340
			if (p->chunks[i].length_dw > 1)
347
			if (p->chunks[i].length_dw > 1)
341
				ring = p->chunks[i].kdata[1];
348
				ring = p->chunks[i].kdata[1];
342
			if (p->chunks[i].length_dw > 2)
349
			if (p->chunks[i].length_dw > 2)
343
				priority = (s32)p->chunks[i].kdata[2];
350
				priority = (s32)p->chunks[i].kdata[2];
Line 374... Line 381...
374
}
381
}
Line 375... Line 382...
375
 
382
 
376
static int cmp_size_smaller_first(void *priv, struct list_head *a,
383
static int cmp_size_smaller_first(void *priv, struct list_head *a,
377
				  struct list_head *b)
384
				  struct list_head *b)
378
{
385
{
379
	struct radeon_cs_reloc *la = list_entry(a, struct radeon_cs_reloc, tv.head);
386
	struct radeon_bo_list *la = list_entry(a, struct radeon_bo_list, tv.head);
Line 380... Line 387...
380
	struct radeon_cs_reloc *lb = list_entry(b, struct radeon_cs_reloc, tv.head);
387
	struct radeon_bo_list *lb = list_entry(b, struct radeon_bo_list, tv.head);
381
 
388
 
382
	/* Sort A before B if A is smaller. */
389
	/* Sort A before B if A is smaller. */
Line 408... Line 415...
408
		 */
415
		 */
409
		list_sort(NULL, &parser->validated, cmp_size_smaller_first);
416
		list_sort(NULL, &parser->validated, cmp_size_smaller_first);
Line 410... Line 417...
410
 
417
 
411
		ttm_eu_fence_buffer_objects(&parser->ticket,
418
		ttm_eu_fence_buffer_objects(&parser->ticket,
412
					    &parser->validated,
419
					    &parser->validated,
413
					    parser->ib.fence);
420
					    &parser->ib.fence->base);
414
	} else if (backoff) {
421
	} else if (backoff) {
415
		ttm_eu_backoff_reservation(&parser->ticket,
422
		ttm_eu_backoff_reservation(&parser->ticket,
416
					   &parser->validated);
423
					   &parser->validated);
Line 417... Line 424...
417
	}
424
	}
418
 
425
 
419
	if (parser->relocs != NULL) {
426
	if (parser->relocs != NULL) {
-
 
427
		for (i = 0; i < parser->nrelocs; i++) {
-
 
428
			struct radeon_bo *bo = parser->relocs[i].robj;
-
 
429
			if (bo == NULL)
420
		for (i = 0; i < parser->nrelocs; i++) {
430
				continue;
421
			if (parser->relocs[i].gobj)
431
 
422
				drm_gem_object_unreference_unlocked(parser->relocs[i].gobj);
432
			drm_gem_object_unreference_unlocked(&bo->gem_base);
423
		}
433
		}
424
	}
434
	}
425
	kfree(parser->track);
-
 
426
	kfree(parser->relocs);
435
	kfree(parser->track);
427
	kfree(parser->relocs_ptr);
436
	kfree(parser->relocs);
428
	kfree(parser->vm_bos);
437
	drm_free_large(parser->vm_bos);
429
	for (i = 0; i < parser->nchunks; i++)
438
	for (i = 0; i < parser->nchunks; i++)
430
		drm_free_large(parser->chunks[i].kdata);
439
		drm_free_large(parser->chunks[i].kdata);
431
	kfree(parser->chunks);
440
	kfree(parser->chunks);
Line 437... Line 446...
437
static int radeon_cs_ib_chunk(struct radeon_device *rdev,
446
static int radeon_cs_ib_chunk(struct radeon_device *rdev,
438
			      struct radeon_cs_parser *parser)
447
			      struct radeon_cs_parser *parser)
439
{
448
{
440
	int r;
449
	int r;
Line 441... Line 450...
441
 
450
 
442
	if (parser->chunk_ib_idx == -1)
451
	if (parser->chunk_ib == NULL)
Line 443... Line 452...
443
		return 0;
452
		return 0;
444
 
453
 
Line 449... Line 458...
449
	if (r || parser->parser_error) {
458
	if (r || parser->parser_error) {
450
		DRM_ERROR("Invalid command stream !\n");
459
		DRM_ERROR("Invalid command stream !\n");
451
		return r;
460
		return r;
452
	}
461
	}
Line -... Line 462...
-
 
462
 
-
 
463
	r = radeon_cs_sync_rings(parser);
-
 
464
	if (r) {
-
 
465
		if (r != -ERESTARTSYS)
-
 
466
			DRM_ERROR("Failed to sync rings: %i\n", r);
-
 
467
		return r;
-
 
468
	}
453
 
469
 
454
	if (parser->ring == R600_RING_TYPE_UVD_INDEX)
470
	if (parser->ring == R600_RING_TYPE_UVD_INDEX)
455
		radeon_uvd_note_usage(rdev);
471
		radeon_uvd_note_usage(rdev);
456
	else if ((parser->ring == TN_RING_TYPE_VCE1_INDEX) ||
472
	else if ((parser->ring == TN_RING_TYPE_VCE1_INDEX) ||
457
		 (parser->ring == TN_RING_TYPE_VCE2_INDEX))
473
		 (parser->ring == TN_RING_TYPE_VCE2_INDEX))
Line 458... Line -...
458
		radeon_vce_note_usage(rdev);
-
 
459
 
474
		radeon_vce_note_usage(rdev);
460
	radeon_cs_sync_rings(parser);
475
 
461
	r = radeon_ib_schedule(rdev, &parser->ib, NULL, true);
476
	r = radeon_ib_schedule(rdev, &parser->ib, NULL, true);
462
	if (r) {
477
	if (r) {
463
		DRM_ERROR("Failed to schedule IB !\n");
478
		DRM_ERROR("Failed to schedule IB !\n");
Line 491... Line 506...
491
		return r;
506
		return r;
Line 492... Line 507...
492
 
507
 
493
	for (i = 0; i < p->nrelocs; i++) {
508
	for (i = 0; i < p->nrelocs; i++) {
Line 494... Line -...
494
		struct radeon_bo *bo;
-
 
495
 
-
 
496
		/* ignore duplicates */
-
 
497
		if (p->relocs_ptr[i] != &p->relocs[i])
-
 
498
			continue;
509
		struct radeon_bo *bo;
499
 
510
 
500
		bo = p->relocs[i].robj;
511
		bo = p->relocs[i].robj;
501
		bo_va = radeon_vm_bo_find(vm, bo);
512
		bo_va = radeon_vm_bo_find(vm, bo);
502
		if (bo_va == NULL) {
513
		if (bo_va == NULL) {
503
			dev_err(rdev->dev, "bo %p not in vm %p\n", bo, vm);
514
			dev_err(rdev->dev, "bo %p not in vm %p\n", bo, vm);
Line 504... Line 515...
504
			return -EINVAL;
515
			return -EINVAL;
505
		}
516
		}
506
 
517
 
-
 
518
		r = radeon_vm_bo_update(rdev, bo_va, &bo->tbo.mem);
-
 
519
		if (r)
507
		r = radeon_vm_bo_update(rdev, bo_va, &bo->tbo.mem);
520
			return r;
Line 508... Line 521...
508
		if (r)
521
 
509
			return r;
522
		radeon_sync_fence(&p->ib.sync, bo_va->last_pt_update);
Line 517... Line 530...
517
{
530
{
518
	struct radeon_fpriv *fpriv = parser->filp->driver_priv;
531
	struct radeon_fpriv *fpriv = parser->filp->driver_priv;
519
	struct radeon_vm *vm = &fpriv->vm;
532
	struct radeon_vm *vm = &fpriv->vm;
520
	int r;
533
	int r;
Line 521... Line 534...
521
 
534
 
522
	if (parser->chunk_ib_idx == -1)
535
	if (parser->chunk_ib == NULL)
523
		return 0;
536
		return 0;
524
	if ((parser->cs_flags & RADEON_CS_USE_VM) == 0)
537
	if ((parser->cs_flags & RADEON_CS_USE_VM) == 0)
Line 525... Line 538...
525
		return 0;
538
		return 0;
Line 542... Line 555...
542
	mutex_lock(&vm->mutex);
555
	mutex_lock(&vm->mutex);
543
	r = radeon_bo_vm_update_pte(parser, vm);
556
	r = radeon_bo_vm_update_pte(parser, vm);
544
	if (r) {
557
	if (r) {
545
		goto out;
558
		goto out;
546
	}
559
	}
-
 
560
 
547
	radeon_cs_sync_rings(parser);
561
	r = radeon_cs_sync_rings(parser);
-
 
562
	if (r) {
-
 
563
		if (r != -ERESTARTSYS)
548
	radeon_semaphore_sync_to(parser->ib.semaphore, vm->fence);
564
			DRM_ERROR("Failed to sync rings: %i\n", r);
-
 
565
		goto out;
-
 
566
	}
Line 549... Line 567...
549
 
567
 
550
	if ((rdev->family >= CHIP_TAHITI) &&
568
	if ((rdev->family >= CHIP_TAHITI) &&
551
	    (parser->chunk_const_ib_idx != -1)) {
569
	    (parser->chunk_const_ib != NULL)) {
552
		r = radeon_ib_schedule(rdev, &parser->ib, &parser->const_ib, true);
570
		r = radeon_ib_schedule(rdev, &parser->ib, &parser->const_ib, true);
553
	} else {
571
	} else {
554
		r = radeon_ib_schedule(rdev, &parser->ib, NULL, true);
572
		r = radeon_ib_schedule(rdev, &parser->ib, NULL, true);
Line 573... Line 591...
573
{
591
{
574
	struct radeon_cs_chunk *ib_chunk;
592
	struct radeon_cs_chunk *ib_chunk;
575
	struct radeon_vm *vm = NULL;
593
	struct radeon_vm *vm = NULL;
576
	int r;
594
	int r;
Line 577... Line 595...
577
 
595
 
578
	if (parser->chunk_ib_idx == -1)
596
	if (parser->chunk_ib == NULL)
Line 579... Line 597...
579
		return 0;
597
		return 0;
580
 
598
 
581
	if (parser->cs_flags & RADEON_CS_USE_VM) {
599
	if (parser->cs_flags & RADEON_CS_USE_VM) {
Line 582... Line 600...
582
		struct radeon_fpriv *fpriv = parser->filp->driver_priv;
600
		struct radeon_fpriv *fpriv = parser->filp->driver_priv;
583
		vm = &fpriv->vm;
601
		vm = &fpriv->vm;
584
 
602
 
585
		if ((rdev->family >= CHIP_TAHITI) &&
603
		if ((rdev->family >= CHIP_TAHITI) &&
586
		    (parser->chunk_const_ib_idx != -1)) {
604
		    (parser->chunk_const_ib != NULL)) {
587
			ib_chunk = &parser->chunks[parser->chunk_const_ib_idx];
605
			ib_chunk = parser->chunk_const_ib;
588
			if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) {
606
			if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) {
589
				DRM_ERROR("cs IB CONST too big: %d\n", ib_chunk->length_dw);
607
				DRM_ERROR("cs IB CONST too big: %d\n", ib_chunk->length_dw);
Line 601... Line 619...
601
					       ib_chunk->user_ptr,
619
					       ib_chunk->user_ptr,
602
					       ib_chunk->length_dw * 4))
620
					       ib_chunk->length_dw * 4))
603
				return -EFAULT;
621
				return -EFAULT;
604
		}
622
		}
Line 605... Line 623...
605
 
623
 
606
		ib_chunk = &parser->chunks[parser->chunk_ib_idx];
624
		ib_chunk = parser->chunk_ib;
607
		if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) {
625
		if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) {
608
			DRM_ERROR("cs IB too big: %d\n", ib_chunk->length_dw);
626
			DRM_ERROR("cs IB too big: %d\n", ib_chunk->length_dw);
609
			return -EINVAL;
627
			return -EINVAL;
610
		}
628
		}
611
	}
629
	}
Line 612... Line 630...
612
	ib_chunk = &parser->chunks[parser->chunk_ib_idx];
630
	ib_chunk = parser->chunk_ib;
613
 
631
 
614
	r =  radeon_ib_get(rdev, parser->ring, &parser->ib,
632
	r =  radeon_ib_get(rdev, parser->ring, &parser->ib,
615
			   vm, ib_chunk->length_dw * 4);
633
			   vm, ib_chunk->length_dw * 4);
Line 692... Line 710...
692
 **/
710
 **/
693
int radeon_cs_packet_parse(struct radeon_cs_parser *p,
711
int radeon_cs_packet_parse(struct radeon_cs_parser *p,
694
			   struct radeon_cs_packet *pkt,
712
			   struct radeon_cs_packet *pkt,
695
			   unsigned idx)
713
			   unsigned idx)
696
{
714
{
697
	struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx];
715
	struct radeon_cs_chunk *ib_chunk = p->chunk_ib;
698
	struct radeon_device *rdev = p->rdev;
716
	struct radeon_device *rdev = p->rdev;
699
	uint32_t header;
717
	uint32_t header;
Line 700... Line 718...
700
 
718
 
701
	if (idx >= ib_chunk->length_dw) {
719
	if (idx >= ib_chunk->length_dw) {
Line 786... Line 804...
786
 *
804
 *
787
 * Check if next packet is relocation packet3, do bo validation and compute
805
 * Check if next packet is relocation packet3, do bo validation and compute
788
 * GPU offset using the provided start.
806
 * GPU offset using the provided start.
789
 **/
807
 **/
790
int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p,
808
int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p,
791
				struct radeon_cs_reloc **cs_reloc,
809
				struct radeon_bo_list **cs_reloc,
792
				int nomm)
810
				int nomm)
793
{
811
{
794
	struct radeon_cs_chunk *relocs_chunk;
812
	struct radeon_cs_chunk *relocs_chunk;
795
	struct radeon_cs_packet p3reloc;
813
	struct radeon_cs_packet p3reloc;
796
	unsigned idx;
814
	unsigned idx;
797
	int r;
815
	int r;
Line 798... Line 816...
798
 
816
 
799
	if (p->chunk_relocs_idx == -1) {
817
	if (p->chunk_relocs == NULL) {
800
		DRM_ERROR("No relocation chunk !\n");
818
		DRM_ERROR("No relocation chunk !\n");
801
		return -EINVAL;
819
		return -EINVAL;
802
	}
820
	}
803
	*cs_reloc = NULL;
821
	*cs_reloc = NULL;
804
	relocs_chunk = &p->chunks[p->chunk_relocs_idx];
822
	relocs_chunk = p->chunk_relocs;
805
	r = radeon_cs_packet_parse(p, &p3reloc, p->idx);
823
	r = radeon_cs_packet_parse(p, &p3reloc, p->idx);
806
	if (r)
824
	if (r)
807
		return r;
825
		return r;
808
	p->idx += p3reloc.count + 2;
826
	p->idx += p3reloc.count + 2;
Line 825... Line 843...
825
		*cs_reloc = p->relocs;
843
		*cs_reloc = p->relocs;
826
		(*cs_reloc)->gpu_offset =
844
		(*cs_reloc)->gpu_offset =
827
			(u64)relocs_chunk->kdata[idx + 3] << 32;
845
			(u64)relocs_chunk->kdata[idx + 3] << 32;
828
		(*cs_reloc)->gpu_offset |= relocs_chunk->kdata[idx + 0];
846
		(*cs_reloc)->gpu_offset |= relocs_chunk->kdata[idx + 0];
829
	} else
847
	} else
830
		*cs_reloc = p->relocs_ptr[(idx / 4)];
848
		*cs_reloc = &p->relocs[(idx / 4)];
831
	return 0;
849
	return 0;
832
}
850
}