Subversion Repositories Kolibri OS

Rev

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

Rev 1404 Rev 1428
Line 42... Line 42...
42
 
42
 
43
int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib)
43
int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib)
44
{
44
{
45
	struct radeon_fence *fence;
45
	struct radeon_fence *fence;
46
	struct radeon_ib *nib;
-
 
47
	unsigned long i;
46
	struct radeon_ib *nib;
Line 48... Line 47...
48
	int r = 0;
47
	int r = 0, i, c;
49
 
48
 
50
	*ib = NULL;
49
	*ib = NULL;
51
	r = radeon_fence_create(rdev, &fence);
50
	r = radeon_fence_create(rdev, &fence);
52
	if (r) {
51
	if (r) {
53
		DRM_ERROR("failed to create fence for new IB\n");
52
		dev_err(rdev->dev, "failed to create fence for new IB\n");
54
		return r;
53
		return r;
55
	}
54
	}
56
    mutex_lock(&rdev->ib_pool.mutex);
55
    mutex_lock(&rdev->ib_pool.mutex);
57
	i = find_first_zero_bit(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
-
 
58
	if (i < RADEON_IB_POOL_SIZE) {
56
	for (i = rdev->ib_pool.head_id, c = 0, nib = NULL; c < RADEON_IB_POOL_SIZE; c++, i++) {
59
		set_bit(i, rdev->ib_pool.alloc_bm);
57
		i &= (RADEON_IB_POOL_SIZE - 1);
60
		rdev->ib_pool.ibs[i].length_dw = 0;
-
 
61
		*ib = &rdev->ib_pool.ibs[i];
58
		if (rdev->ib_pool.ibs[i].free) {
62
		mutex_unlock(&rdev->ib_pool.mutex);
59
			nib = &rdev->ib_pool.ibs[i];
-
 
60
			break;
63
		goto out;
61
	}
64
	}
62
	}
65
	if (list_empty(&rdev->ib_pool.scheduled_ibs)) {
63
	if (nib == NULL) {
66
		/* we go do nothings here */
64
		/* This should never happen, it means we allocated all
67
		mutex_unlock(&rdev->ib_pool.mutex);
-
 
68
		DRM_ERROR("all IB allocated none scheduled.\n");
65
		 * IB and haven't scheduled one yet, return EBUSY to
69
		r = -EINVAL;
66
		 * userspace hoping that on ioctl recall we get better
70
		goto out;
-
 
71
	}
67
		 * luck
72
	/* get the first ib on the scheduled list */
-
 
73
	nib = list_entry(rdev->ib_pool.scheduled_ibs.next,
-
 
74
			 struct radeon_ib, list);
-
 
75
	if (nib->fence == NULL) {
68
		 */
76
		/* we go do nothings here */
69
		dev_err(rdev->dev, "no free indirect buffer !\n");
77
		mutex_unlock(&rdev->ib_pool.mutex);
70
		mutex_unlock(&rdev->ib_pool.mutex);
78
		DRM_ERROR("IB %lu scheduled without a fence.\n", nib->idx);
-
 
79
		r = -EINVAL;
71
		radeon_fence_unref(&fence);
-
 
72
		return -EBUSY;
-
 
73
	}
-
 
74
	rdev->ib_pool.head_id = (nib->idx + 1) & (RADEON_IB_POOL_SIZE - 1);
80
		goto out;
75
	nib->free = false;
81
	}
-
 
82
	mutex_unlock(&rdev->ib_pool.mutex);
76
	if (nib->fence) {
83
 
77
		mutex_unlock(&rdev->ib_pool.mutex);
84
	r = radeon_fence_wait(nib->fence, false);
78
	r = radeon_fence_wait(nib->fence, false);
85
	if (r) {
79
	if (r) {
-
 
80
			dev_err(rdev->dev, "error waiting fence of IB(%u:0x%016lX:%u)\n",
-
 
81
				nib->idx, (unsigned long)nib->gpu_addr, nib->length_dw);
86
		DRM_ERROR("radeon: IB(%lu:0x%016lX:%u)\n", nib->idx,
82
			mutex_lock(&rdev->ib_pool.mutex);
-
 
83
			nib->free = true;
87
			  (unsigned long)nib->gpu_addr, nib->length_dw);
84
			mutex_unlock(&rdev->ib_pool.mutex);
-
 
85
			radeon_fence_unref(&fence);
-
 
86
			return r;
88
		DRM_ERROR("radeon: GPU lockup detected, fail to get a IB\n");
87
	}
89
		goto out;
88
		mutex_lock(&rdev->ib_pool.mutex);
90
	}
-
 
-
 
89
	}
91
	radeon_fence_unref(&nib->fence);
90
	radeon_fence_unref(&nib->fence);
92
 
-
 
93
	nib->length_dw = 0;
-
 
94
 
-
 
95
	/* scheduled list is accessed here */
-
 
96
	mutex_lock(&rdev->ib_pool.mutex);
-
 
97
	list_del(&nib->list);
91
	nib->fence = fence;
98
	INIT_LIST_HEAD(&nib->list);
-
 
99
	mutex_unlock(&rdev->ib_pool.mutex);
92
	nib->length_dw = 0;
100
 
-
 
101
	*ib = nib;
-
 
102
out:
-
 
103
	if (r) {
-
 
104
		radeon_fence_unref(&fence);
-
 
105
	} else {
-
 
106
		(*ib)->fence = fence;
93
	mutex_unlock(&rdev->ib_pool.mutex);
107
	}
94
	*ib = nib;
Line 108... Line 95...
108
	return r;
95
	return 0;
109
}
96
}
110
 
97
 
Line 111... Line 98...
111
void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
98
void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
112
{
99
{
113
	struct radeon_ib *tmp = *ib;
100
	struct radeon_ib *tmp = *ib;
114
 
101
 
115
	*ib = NULL;
-
 
116
	if (tmp == NULL) {
-
 
117
		return;
-
 
118
	}
-
 
119
	mutex_lock(&rdev->ib_pool.mutex);
-
 
120
	if (!list_empty(&tmp->list) && !radeon_fence_signaled(tmp->fence)) {
-
 
121
		/* IB is scheduled & not signaled don't do anythings */
-
 
122
		mutex_unlock(&rdev->ib_pool.mutex);
-
 
123
		return;
102
	*ib = NULL;
124
	}
103
	if (tmp == NULL) {
125
	list_del(&tmp->list);
-
 
126
	INIT_LIST_HEAD(&tmp->list);
104
		return;
127
	if (tmp->fence)
105
	}
128
		radeon_fence_unref(&tmp->fence);
106
	if (!tmp->fence->emited)
129
 
107
		radeon_fence_unref(&tmp->fence);
Line 130... Line 108...
130
	tmp->length_dw = 0;
108
	mutex_lock(&rdev->ib_pool.mutex);
131
	clear_bit(tmp->idx, rdev->ib_pool.alloc_bm);
109
	tmp->free = true;
132
	mutex_unlock(&rdev->ib_pool.mutex);
110
	mutex_unlock(&rdev->ib_pool.mutex);
Line 133... Line 111...
133
}
111
}
134
 
112
 
135
int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
113
int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
136
{
114
{
137
	int r = 0;
115
	int r = 0;
Line 138... Line 116...
138
 
116
 
139
	if (!ib->length_dw || !rdev->cp.ready) {
117
	if (!ib->length_dw || !rdev->cp.ready) {
Line 149... Line 127...
149
		return r;
127
		return r;
150
	}
128
	}
151
	radeon_ring_ib_execute(rdev, ib);
129
	radeon_ring_ib_execute(rdev, ib);
152
	radeon_fence_emit(rdev, ib->fence);
130
	radeon_fence_emit(rdev, ib->fence);
153
	mutex_lock(&rdev->ib_pool.mutex);
131
	mutex_lock(&rdev->ib_pool.mutex);
154
	list_add_tail(&ib->list, &rdev->ib_pool.scheduled_ibs);
132
	/* once scheduled IB is considered free and protected by the fence */
-
 
133
	ib->free = true;
155
	mutex_unlock(&rdev->ib_pool.mutex);
134
	mutex_unlock(&rdev->ib_pool.mutex);
156
	radeon_ring_unlock_commit(rdev);
135
	radeon_ring_unlock_commit(rdev);
157
	return 0;
136
	return 0;
158
}
137
}
159
#endif
138
#endif
Line 166... Line 145...
166
	int r = 0;
145
	int r = 0;
Line 167... Line 146...
167
 
146
 
168
	if (rdev->ib_pool.robj)
147
	if (rdev->ib_pool.robj)
169
		return 0;
148
		return 0;
170
	/* Allocate 1M object buffer */
-
 
171
	INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs);
149
	/* Allocate 1M object buffer */
172
	r = radeon_bo_create(rdev, NULL,  RADEON_IB_POOL_SIZE*64*1024,
150
	r = radeon_bo_create(rdev, NULL,  RADEON_IB_POOL_SIZE*64*1024,
173
				 true, RADEON_GEM_DOMAIN_GTT,
151
				 true, RADEON_GEM_DOMAIN_GTT,
174
				&rdev->ib_pool.robj);
152
				&rdev->ib_pool.robj);
175
	if (r) {
153
	if (r) {
Line 197... Line 175...
197
		offset = i * 64 * 1024;
175
		offset = i * 64 * 1024;
198
		rdev->ib_pool.ibs[i].gpu_addr = gpu_addr + offset;
176
		rdev->ib_pool.ibs[i].gpu_addr = gpu_addr + offset;
199
		rdev->ib_pool.ibs[i].ptr = ptr + offset;
177
		rdev->ib_pool.ibs[i].ptr = ptr + offset;
200
		rdev->ib_pool.ibs[i].idx = i;
178
		rdev->ib_pool.ibs[i].idx = i;
201
		rdev->ib_pool.ibs[i].length_dw = 0;
179
		rdev->ib_pool.ibs[i].length_dw = 0;
202
		INIT_LIST_HEAD(&rdev->ib_pool.ibs[i].list);
180
		rdev->ib_pool.ibs[i].free = true;
203
	}
181
	}
204
	bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
182
	rdev->ib_pool.head_id = 0;
205
	rdev->ib_pool.ready = true;
183
	rdev->ib_pool.ready = true;
206
	DRM_INFO("radeon: ib pool ready.\n");
184
	DRM_INFO("radeon: ib pool ready.\n");
207
	if (radeon_debugfs_ib_init(rdev)) {
185
	if (radeon_debugfs_ib_init(rdev)) {
208
		DRM_ERROR("Failed to register debugfs file for IB !\n");
186
		DRM_ERROR("Failed to register debugfs file for IB !\n");
209
	}
187
	}
Line 216... Line 194...
216
 
194
 
217
	if (!rdev->ib_pool.ready) {
195
	if (!rdev->ib_pool.ready) {
218
		return;
196
		return;
219
	}
197
	}
220
	mutex_lock(&rdev->ib_pool.mutex);
-
 
221
	bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
198
	mutex_lock(&rdev->ib_pool.mutex);
222
	if (rdev->ib_pool.robj) {
199
	if (rdev->ib_pool.robj) {
223
		r = radeon_bo_reserve(rdev->ib_pool.robj, false);
200
		r = radeon_bo_reserve(rdev->ib_pool.robj, false);
224
		if (likely(r == 0)) {
201
		if (likely(r == 0)) {
225
			radeon_bo_kunmap(rdev->ib_pool.robj);
202
			radeon_bo_kunmap(rdev->ib_pool.robj);
Line 370... Line 347...
370
	unsigned i;
347
	unsigned i;
Line 371... Line 348...
371
 
348
 
372
	if (ib == NULL) {
349
	if (ib == NULL) {
373
		return 0;
350
		return 0;
374
	}
351
	}
375
	seq_printf(m, "IB %04lu\n", ib->idx);
352
	seq_printf(m, "IB %04u\n", ib->idx);
376
	seq_printf(m, "IB fence %p\n", ib->fence);
353
	seq_printf(m, "IB fence %p\n", ib->fence);
377
	seq_printf(m, "IB size %05u dwords\n", ib->length_dw);
354
	seq_printf(m, "IB size %05u dwords\n", ib->length_dw);
378
	for (i = 0; i < ib->length_dw; i++) {
355
	for (i = 0; i < ib->length_dw; i++) {
379
		seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]);
356
		seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]);