radeon_ring.c revision c1341e52802ab401be7addb55408e23307f9074b
1771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/*
2771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Copyright 2008 Advanced Micro Devices, Inc.
3771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Copyright 2008 Red Hat Inc.
4771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Copyright 2009 Jerome Glisse.
5771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *
6771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Permission is hereby granted, free of charge, to any person obtaining a
7771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * copy of this software and associated documentation files (the "Software"),
8771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * to deal in the Software without restriction, including without limitation
9771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * and/or sell copies of the Software, and to permit persons to whom the
11771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Software is furnished to do so, subject to the following conditions:
12771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *
13771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * The above copyright notice and this permission notice shall be included in
14771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * all copies or substantial portions of the Software.
15771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *
16771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * OTHER DEALINGS IN THE SOFTWARE.
23771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *
24771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Authors: Dave Airlie
25771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *          Alex Deucher
26771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *          Jerome Glisse
27771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */
28771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include <linux/seq_file.h>
295a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
30771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "drmP.h"
31771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "radeon_drm.h"
32771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "radeon_reg.h"
33771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "radeon.h"
34771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "atom.h"
35771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
36771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_debugfs_ib_init(struct radeon_device *rdev);
37af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königint radeon_debugfs_ring_init(struct radeon_device *rdev);
38771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
39ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleenu32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx)
40ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen{
41ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen	struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx];
42ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen	u32 pg_idx, pg_offset;
43ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen	u32 idx_value = 0;
44ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen	int new_page;
45ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen
46ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen	pg_idx = (idx * 4) / PAGE_SIZE;
47ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen	pg_offset = (idx * 4) % PAGE_SIZE;
48ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen
49ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen	if (ibc->kpage_idx[0] == pg_idx)
50ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen		return ibc->kpage[0][pg_offset/4];
51ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen	if (ibc->kpage_idx[1] == pg_idx)
52ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen		return ibc->kpage[1][pg_offset/4];
53ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen
54ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen	new_page = radeon_cs_update_pages(p, pg_idx);
55ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen	if (new_page < 0) {
56ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen		p->parser_error = new_page;
57ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen		return 0;
58ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen	}
59ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen
60ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen	idx_value = ibc->kpage[new_page][pg_offset/4];
61ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen	return idx_value;
62ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen}
63ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen
64e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_write(struct radeon_ring *ring, uint32_t v)
65ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen{
66ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen#if DRM_DEBUG_CODE
67e32eb50dbe43862606a51caa94368ec6bd019434Christian König	if (ring->count_dw <= 0) {
68ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen		DRM_ERROR("radeon: writting more dword to ring than expected !\n");
69ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen	}
70ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen#endif
71e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ring[ring->wptr++] = v;
72e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->wptr &= ring->ptr_mask;
73e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->count_dw--;
74e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ring_free_dw--;
75ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen}
76ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen
77b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse/*
78b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse * IB.
79b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse */
80c1341e52802ab401be7addb55408e23307f9074bJerome Glissebool radeon_ib_try_free(struct radeon_device *rdev, struct radeon_ib *ib)
819f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse{
82b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	bool done = false;
83b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse
84b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	/* only free ib which have been emited */
85b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	if (ib->fence && ib->fence->emitted) {
86b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		if (radeon_fence_signaled(ib->fence)) {
87b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			radeon_fence_unref(&ib->fence);
88b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			radeon_sa_bo_free(rdev, &ib->sa_bo);
89b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			done = true;
90b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		}
919f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse	}
92b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	return done;
939f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse}
949f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse
9569e130a6a42270f94e6ee0bce34c3480a6b9da61Jerome Glisseint radeon_ib_get(struct radeon_device *rdev, int ring,
9669e130a6a42270f94e6ee0bce34c3480a6b9da61Jerome Glisse		  struct radeon_ib **ib, unsigned size)
97771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
98771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	struct radeon_fence *fence;
99b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	unsigned cretry = 0;
100b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	int r = 0, i, idx;
101771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
102771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	*ib = NULL;
10369e130a6a42270f94e6ee0bce34c3480a6b9da61Jerome Glisse	/* align size on 256 bytes */
10469e130a6a42270f94e6ee0bce34c3480a6b9da61Jerome Glisse	size = ALIGN(size, 256);
105b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse
1067b1f2485db253aaa0081e1c5213533e166130732Christian König	r = radeon_fence_create(rdev, &fence, ring);
107771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	if (r) {
10891cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse		dev_err(rdev->dev, "failed to create fence for new IB\n");
109771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		return r;
110771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
111b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse
112771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	mutex_lock(&rdev->ib_pool.mutex);
113b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	idx = rdev->ib_pool.head_id;
114b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisseretry:
115b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	if (cretry > 5) {
116b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		dev_err(rdev->dev, "failed to get an ib after 5 retry\n");
117ecb114a128d150422d22eda238cb812f6b20bf39Dave Airlie		mutex_unlock(&rdev->ib_pool.mutex);
11891cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse		radeon_fence_unref(&fence);
119b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		return -ENOMEM;
120771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
121b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	cretry++;
122b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
123b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		radeon_ib_try_free(rdev, &rdev->ib_pool.ibs[idx]);
124b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		if (rdev->ib_pool.ibs[idx].fence == NULL) {
125b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			r = radeon_sa_bo_new(rdev, &rdev->ib_pool.sa_manager,
126b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse					     &rdev->ib_pool.ibs[idx].sa_bo,
12769e130a6a42270f94e6ee0bce34c3480a6b9da61Jerome Glisse					     size, 256);
128b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			if (!r) {
129b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				*ib = &rdev->ib_pool.ibs[idx];
130b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				(*ib)->ptr = rdev->ib_pool.sa_manager.cpu_ptr;
131b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				(*ib)->ptr += ((*ib)->sa_bo.offset >> 2);
132b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				(*ib)->gpu_addr = rdev->ib_pool.sa_manager.gpu_addr;
133b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				(*ib)->gpu_addr += (*ib)->sa_bo.offset;
134b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				(*ib)->fence = fence;
135b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				/* ib are most likely to be allocated in a ring fashion
136b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				 * thus rdev->ib_pool.head_id should be the id of the
137b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				 * oldest ib
138b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				 */
139b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				rdev->ib_pool.head_id = (1 + idx);
140b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				rdev->ib_pool.head_id &= (RADEON_IB_POOL_SIZE - 1);
141b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				mutex_unlock(&rdev->ib_pool.mutex);
142b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				return 0;
143b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			}
14491cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse		}
145b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1);
146b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	}
147b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	/* this should be rare event, ie all ib scheduled none signaled yet.
148b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	 */
149b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
150c1341e52802ab401be7addb55408e23307f9074bJerome Glisse		if (rdev->ib_pool.ibs[idx].fence && rdev->ib_pool.ibs[idx].fence->emitted) {
151b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			r = radeon_fence_wait(rdev->ib_pool.ibs[idx].fence, false);
152b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			if (!r) {
153b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				goto retry;
154b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			}
155b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			/* an error happened */
156b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			break;
157b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		}
158b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1);
159771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
160ecb114a128d150422d22eda238cb812f6b20bf39Dave Airlie	mutex_unlock(&rdev->ib_pool.mutex);
161b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	radeon_fence_unref(&fence);
162b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	return r;
163771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
164771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
165771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissevoid radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
166771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
167771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	struct radeon_ib *tmp = *ib;
168771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
169771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	*ib = NULL;
170771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	if (tmp == NULL) {
171771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		return;
172771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
173771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	mutex_lock(&rdev->ib_pool.mutex);
174b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	if (tmp->fence && !tmp->fence->emitted) {
175b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		radeon_sa_bo_free(rdev, &tmp->sa_bo);
176b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		radeon_fence_unref(&tmp->fence);
177b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	}
178771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	mutex_unlock(&rdev->ib_pool.mutex);
179771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
180771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
181771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
182771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
183e32eb50dbe43862606a51caa94368ec6bd019434Christian König	struct radeon_ring *ring = &rdev->ring[ib->fence->ring];
184771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	int r = 0;
185771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
186e32eb50dbe43862606a51caa94368ec6bd019434Christian König	if (!ib->length_dw || !ring->ready) {
187771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		/* TODO: Nothings in the ib we should report. */
18891cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse		DRM_ERROR("radeon: couldn't schedule IB(%u).\n", ib->idx);
189771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		return -EINVAL;
190771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
191ecb114a128d150422d22eda238cb812f6b20bf39Dave Airlie
1926cdf65855cf884712532fc72770baaef7bdf1b9aDave Airlie	/* 64 dwords should be enough for fence too */
193e32eb50dbe43862606a51caa94368ec6bd019434Christian König	r = radeon_ring_lock(rdev, ring, 64);
194771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	if (r) {
195ec4f2ac471e25d3e0cea05abb8da34c05a0868f9Paul Bolle		DRM_ERROR("radeon: scheduling IB failed (%d).\n", r);
196771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		return r;
197771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
1984c87bc268d764cf8846d20ea54b355d1e87507c9Christian König	radeon_ring_ib_execute(rdev, ib->fence->ring, ib);
199771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	radeon_fence_emit(rdev, ib->fence);
200e32eb50dbe43862606a51caa94368ec6bd019434Christian König	radeon_ring_unlock_commit(rdev, ring);
201771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return 0;
202771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
203771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
204771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_ib_pool_init(struct radeon_device *rdev)
205771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
206b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	int i, r;
207771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
208b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	mutex_lock(&rdev->ib_pool.mutex);
209b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	if (rdev->ib_pool.ready) {
210b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		mutex_unlock(&rdev->ib_pool.mutex);
2119f022ddfb23793b475ff7e57ac08a766dd5d31bdJerome Glisse		return 0;
212771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
213b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse
214b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	r = radeon_sa_bo_manager_init(rdev, &rdev->ib_pool.sa_manager,
215b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				      RADEON_IB_POOL_SIZE*64*1024,
216b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				      RADEON_GEM_DOMAIN_GTT);
217771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	if (r) {
218b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		mutex_unlock(&rdev->ib_pool.mutex);
219771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		return r;
220771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
221771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
222b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
223b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		rdev->ib_pool.ibs[i].fence = NULL;
224771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		rdev->ib_pool.ibs[i].idx = i;
225771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		rdev->ib_pool.ibs[i].length_dw = 0;
226b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		INIT_LIST_HEAD(&rdev->ib_pool.ibs[i].sa_bo.list);
227771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
22891cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse	rdev->ib_pool.head_id = 0;
229771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	rdev->ib_pool.ready = true;
230771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	DRM_INFO("radeon: ib pool ready.\n");
231b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse
232771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	if (radeon_debugfs_ib_init(rdev)) {
233771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		DRM_ERROR("Failed to register debugfs file for IB !\n");
234771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
235af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	if (radeon_debugfs_ring_init(rdev)) {
236af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König		DRM_ERROR("Failed to register debugfs file for rings !\n");
237af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	}
238b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	mutex_unlock(&rdev->ib_pool.mutex);
239b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	return 0;
240771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
241771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
242771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissevoid radeon_ib_pool_fini(struct radeon_device *rdev)
243771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
244b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	unsigned i;
2454c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse
246771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	mutex_lock(&rdev->ib_pool.mutex);
247b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	if (rdev->ib_pool.ready) {
248b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
249b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			radeon_sa_bo_free(rdev, &rdev->ib_pool.ibs[i].sa_bo);
250b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			radeon_fence_unref(&rdev->ib_pool.ibs[i].fence);
2514c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse		}
252b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		radeon_sa_bo_manager_fini(rdev, &rdev->ib_pool.sa_manager);
253b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		rdev->ib_pool.ready = false;
254771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
255b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	mutex_unlock(&rdev->ib_pool.mutex);
256771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
257771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
258b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisseint radeon_ib_pool_start(struct radeon_device *rdev)
259b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse{
260b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	return radeon_sa_bo_manager_start(rdev, &rdev->ib_pool.sa_manager);
261b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse}
262b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse
263b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisseint radeon_ib_pool_suspend(struct radeon_device *rdev)
264b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse{
265b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	return radeon_sa_bo_manager_suspend(rdev, &rdev->ib_pool.sa_manager);
266b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse}
267771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
268771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/*
269771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Ring.
270771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */
271e32eb50dbe43862606a51caa94368ec6bd019434Christian Königint radeon_ring_index(struct radeon_device *rdev, struct radeon_ring *ring)
272bf85279958da96cb4b11aac89b34f0424c3c120eChristian König{
273bf85279958da96cb4b11aac89b34f0424c3c120eChristian König	/* r1xx-r5xx only has CP ring */
274bf85279958da96cb4b11aac89b34f0424c3c120eChristian König	if (rdev->family < CHIP_R600)
275bf85279958da96cb4b11aac89b34f0424c3c120eChristian König		return RADEON_RING_TYPE_GFX_INDEX;
276bf85279958da96cb4b11aac89b34f0424c3c120eChristian König
277bf85279958da96cb4b11aac89b34f0424c3c120eChristian König	if (rdev->family >= CHIP_CAYMAN) {
278e32eb50dbe43862606a51caa94368ec6bd019434Christian König		if (ring == &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX])
279bf85279958da96cb4b11aac89b34f0424c3c120eChristian König			return CAYMAN_RING_TYPE_CP1_INDEX;
280e32eb50dbe43862606a51caa94368ec6bd019434Christian König		else if (ring == &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX])
281bf85279958da96cb4b11aac89b34f0424c3c120eChristian König			return CAYMAN_RING_TYPE_CP2_INDEX;
282bf85279958da96cb4b11aac89b34f0424c3c120eChristian König	}
283bf85279958da96cb4b11aac89b34f0424c3c120eChristian König	return RADEON_RING_TYPE_GFX_INDEX;
284bf85279958da96cb4b11aac89b34f0424c3c120eChristian König}
285bf85279958da96cb4b11aac89b34f0424c3c120eChristian König
286e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring)
287771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
28878c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher	u32 rptr;
28978c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher
290724c80e1d630296d1324859e964d80d35007d83cAlex Deucher	if (rdev->wb.enabled)
29178c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher		rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
2925596a9db156107b01ceb7db4d50cc091117da627Christian König	else
29378c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher		rptr = RREG32(ring->rptr_reg);
29478c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher	ring->rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
295771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	/* This works because ring_size is a power of 2 */
296e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ring_free_dw = (ring->rptr + (ring->ring_size / 4));
297e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ring_free_dw -= ring->wptr;
298e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ring_free_dw &= ring->ptr_mask;
299e32eb50dbe43862606a51caa94368ec6bd019434Christian König	if (!ring->ring_free_dw) {
300e32eb50dbe43862606a51caa94368ec6bd019434Christian König		ring->ring_free_dw = ring->ring_size / 4;
301771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
302771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
303771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
3047b1f2485db253aaa0081e1c5213533e166130732Christian König
305e32eb50dbe43862606a51caa94368ec6bd019434Christian Königint radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw)
306771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
307771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	int r;
308771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
309771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	/* Align requested size with padding so unlock_commit can
310771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	 * pad safely */
311e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ndw = (ndw + ring->align_mask) & ~ring->align_mask;
312e32eb50dbe43862606a51caa94368ec6bd019434Christian König	while (ndw > (ring->ring_free_dw - 1)) {
313e32eb50dbe43862606a51caa94368ec6bd019434Christian König		radeon_ring_free_size(rdev, ring);
314e32eb50dbe43862606a51caa94368ec6bd019434Christian König		if (ndw < ring->ring_free_dw) {
315771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse			break;
316771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		}
317e32eb50dbe43862606a51caa94368ec6bd019434Christian König		r = radeon_fence_wait_next(rdev, radeon_ring_index(rdev, ring));
31891700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett		if (r)
319771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse			return r;
320771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
321e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->count_dw = ndw;
322e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->wptr_old = ring->wptr;
323771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return 0;
324771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
325771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
326e32eb50dbe43862606a51caa94368ec6bd019434Christian Königint radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw)
32791700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett{
32891700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett	int r;
32991700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett
330e32eb50dbe43862606a51caa94368ec6bd019434Christian König	mutex_lock(&ring->mutex);
331e32eb50dbe43862606a51caa94368ec6bd019434Christian König	r = radeon_ring_alloc(rdev, ring, ndw);
33291700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett	if (r) {
333e32eb50dbe43862606a51caa94368ec6bd019434Christian König		mutex_unlock(&ring->mutex);
33491700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett		return r;
33591700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett	}
33691700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett	return 0;
33791700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett}
33891700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett
339e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring)
340771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
341771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	unsigned count_dw_pad;
342771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	unsigned i;
343771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
344771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	/* We pad to match fetch size */
345e32eb50dbe43862606a51caa94368ec6bd019434Christian König	count_dw_pad = (ring->align_mask + 1) -
346e32eb50dbe43862606a51caa94368ec6bd019434Christian König		       (ring->wptr & ring->align_mask);
347771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	for (i = 0; i < count_dw_pad; i++) {
34878c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher		radeon_ring_write(ring, ring->nop);
349771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
350771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	DRM_MEMORYBARRIER();
35178c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher	WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & ring->ptr_reg_mask);
352e32eb50dbe43862606a51caa94368ec6bd019434Christian König	(void)RREG32(ring->wptr_reg);
35391700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett}
35491700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett
355e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring)
35691700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett{
357e32eb50dbe43862606a51caa94368ec6bd019434Christian König	radeon_ring_commit(rdev, ring);
358e32eb50dbe43862606a51caa94368ec6bd019434Christian König	mutex_unlock(&ring->mutex);
359771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
360771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
361e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *ring)
362771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
363e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->wptr = ring->wptr_old;
364e32eb50dbe43862606a51caa94368ec6bd019434Christian König	mutex_unlock(&ring->mutex);
365771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
366771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
367e32eb50dbe43862606a51caa94368ec6bd019434Christian Königint radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size,
36878c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher		     unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg,
36978c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher		     u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop)
370771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
371771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	int r;
372771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
373e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ring_size = ring_size;
374e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->rptr_offs = rptr_offs;
375e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->rptr_reg = rptr_reg;
376e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->wptr_reg = wptr_reg;
37778c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher	ring->ptr_reg_shift = ptr_reg_shift;
37878c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher	ring->ptr_reg_mask = ptr_reg_mask;
37978c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher	ring->nop = nop;
380771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	/* Allocate ring buffer */
381e32eb50dbe43862606a51caa94368ec6bd019434Christian König	if (ring->ring_obj == NULL) {
382e32eb50dbe43862606a51caa94368ec6bd019434Christian König		r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true,
3834c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse					RADEON_GEM_DOMAIN_GTT,
384e32eb50dbe43862606a51caa94368ec6bd019434Christian König					&ring->ring_obj);
385771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		if (r) {
3864c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse			dev_err(rdev->dev, "(%d) ring create failed\n", r);
387771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse			return r;
388771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		}
389e32eb50dbe43862606a51caa94368ec6bd019434Christian König		r = radeon_bo_reserve(ring->ring_obj, false);
3904c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse		if (unlikely(r != 0))
3914c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse			return r;
392e32eb50dbe43862606a51caa94368ec6bd019434Christian König		r = radeon_bo_pin(ring->ring_obj, RADEON_GEM_DOMAIN_GTT,
393e32eb50dbe43862606a51caa94368ec6bd019434Christian König					&ring->gpu_addr);
394771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		if (r) {
395e32eb50dbe43862606a51caa94368ec6bd019434Christian König			radeon_bo_unreserve(ring->ring_obj);
3964c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse			dev_err(rdev->dev, "(%d) ring pin failed\n", r);
397771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse			return r;
398771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		}
399e32eb50dbe43862606a51caa94368ec6bd019434Christian König		r = radeon_bo_kmap(ring->ring_obj,
400e32eb50dbe43862606a51caa94368ec6bd019434Christian König				       (void **)&ring->ring);
401e32eb50dbe43862606a51caa94368ec6bd019434Christian König		radeon_bo_unreserve(ring->ring_obj);
402771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		if (r) {
4034c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse			dev_err(rdev->dev, "(%d) ring map failed\n", r);
404771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse			return r;
405771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		}
406771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
407e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ptr_mask = (ring->ring_size / 4) - 1;
408e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ring_free_dw = ring->ring_size / 4;
409771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return 0;
410771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
411771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
412e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *ring)
413771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
4144c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse	int r;
415ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher	struct radeon_bo *ring_obj;
4164c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse
417e32eb50dbe43862606a51caa94368ec6bd019434Christian König	mutex_lock(&ring->mutex);
418e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring_obj = ring->ring_obj;
419e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ring = NULL;
420e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ring_obj = NULL;
421e32eb50dbe43862606a51caa94368ec6bd019434Christian König	mutex_unlock(&ring->mutex);
422ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher
423ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher	if (ring_obj) {
424ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher		r = radeon_bo_reserve(ring_obj, false);
4254c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse		if (likely(r == 0)) {
426ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher			radeon_bo_kunmap(ring_obj);
427ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher			radeon_bo_unpin(ring_obj);
428ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher			radeon_bo_unreserve(ring_obj);
4294c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse		}
430ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher		radeon_bo_unref(&ring_obj);
431771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
432771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
433771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
434771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/*
435771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Debugfs info
436771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */
437771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#if defined(CONFIG_DEBUG_FS)
438af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König
439af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic int radeon_debugfs_ring_info(struct seq_file *m, void *data)
440af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König{
441af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	struct drm_info_node *node = (struct drm_info_node *) m->private;
442af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	struct drm_device *dev = node->minor->dev;
443af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	struct radeon_device *rdev = dev->dev_private;
444af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	int ridx = *(int*)node->info_ent->data;
445af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	struct radeon_ring *ring = &rdev->ring[ridx];
446af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	unsigned count, i, j;
447af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König
448af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	radeon_ring_free_size(rdev, ring);
449af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	count = (ring->ring_size / 4) - ring->ring_free_dw;
450af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	seq_printf(m, "wptr(0x%04x): 0x%08x\n", ring->wptr_reg, RREG32(ring->wptr_reg));
451af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	seq_printf(m, "rptr(0x%04x): 0x%08x\n", ring->rptr_reg, RREG32(ring->rptr_reg));
452af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	seq_printf(m, "driver's copy of the wptr: 0x%08x\n", ring->wptr);
453af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr);
454af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw);
455af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	seq_printf(m, "%u dwords in ring\n", count);
456af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	i = ring->rptr;
457af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	for (j = 0; j <= count; j++) {
458af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König		seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]);
459af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König		i = (i + 1) & ring->ptr_mask;
460af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	}
461af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	return 0;
462af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König}
463af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König
464af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic int radeon_ring_type_gfx_index = RADEON_RING_TYPE_GFX_INDEX;
465af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic int cayman_ring_type_cp1_index = CAYMAN_RING_TYPE_CP1_INDEX;
466af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic int cayman_ring_type_cp2_index = CAYMAN_RING_TYPE_CP2_INDEX;
467af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König
468af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic struct drm_info_list radeon_debugfs_ring_info_list[] = {
469af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	{"radeon_ring_gfx", radeon_debugfs_ring_info, 0, &radeon_ring_type_gfx_index},
470af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	{"radeon_ring_cp1", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp1_index},
471af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	{"radeon_ring_cp2", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp2_index},
472af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König};
473af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König
474771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic int radeon_debugfs_ib_info(struct seq_file *m, void *data)
475771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
476771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	struct drm_info_node *node = (struct drm_info_node *) m->private;
477771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	struct radeon_ib *ib = node->info_ent->data;
478771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	unsigned i;
479771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
480771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	if (ib == NULL) {
481771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		return 0;
482771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
48391cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse	seq_printf(m, "IB %04u\n", ib->idx);
484771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	seq_printf(m, "IB fence %p\n", ib->fence);
485771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	seq_printf(m, "IB size %05u dwords\n", ib->length_dw);
486771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	for (i = 0; i < ib->length_dw; i++) {
487771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]);
488771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
489771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return 0;
490771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
491771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
492771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE];
493771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32];
494771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#endif
495771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
496af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königint radeon_debugfs_ring_init(struct radeon_device *rdev)
497af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König{
498af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König#if defined(CONFIG_DEBUG_FS)
499af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list,
500af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König					ARRAY_SIZE(radeon_debugfs_ring_info_list));
501af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König#else
502af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	return 0;
503af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König#endif
504af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König}
505af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König
506771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_debugfs_ib_init(struct radeon_device *rdev)
507771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
508771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#if defined(CONFIG_DEBUG_FS)
509771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	unsigned i;
510771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
511771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
512771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i);
513771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		radeon_debugfs_ib_list[i].name = radeon_debugfs_ib_names[i];
514771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		radeon_debugfs_ib_list[i].show = &radeon_debugfs_ib_info;
515771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		radeon_debugfs_ib_list[i].driver_features = 0;
516771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		radeon_debugfs_ib_list[i].data = &rdev->ib_pool.ibs[i];
517771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
518771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return radeon_debugfs_add_files(rdev, radeon_debugfs_ib_list,
519771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse					RADEON_IB_POOL_SIZE);
520771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#else
521771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return 0;
522771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#endif
523771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
524