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
1129fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse	radeon_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");
1179fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse		radeon_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;
135721604a15b934f0a8d1909acb8017f029128be2fJerome Glisse				(*ib)->vm_id = 0;
136dfcf5f36529d69eb35f4fdedfa6f244c5249698cAlex Deucher				(*ib)->is_const_ib = false;
137b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				/* ib are most likely to be allocated in a ring fashion
138b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				 * thus rdev->ib_pool.head_id should be the id of the
139b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				 * oldest ib
140b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				 */
141b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				rdev->ib_pool.head_id = (1 + idx);
142b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				rdev->ib_pool.head_id &= (RADEON_IB_POOL_SIZE - 1);
1439fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse				radeon_mutex_unlock(&rdev->ib_pool.mutex);
144b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				return 0;
145b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			}
14691cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse		}
147b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1);
148b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	}
149b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	/* this should be rare event, ie all ib scheduled none signaled yet.
150b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	 */
151b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
152c1341e52802ab401be7addb55408e23307f9074bJerome Glisse		if (rdev->ib_pool.ibs[idx].fence && rdev->ib_pool.ibs[idx].fence->emitted) {
153b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			r = radeon_fence_wait(rdev->ib_pool.ibs[idx].fence, false);
154b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			if (!r) {
155b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				goto retry;
156b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			}
157b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			/* an error happened */
158b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			break;
159b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		}
160b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1);
161771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
1629fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse	radeon_mutex_unlock(&rdev->ib_pool.mutex);
163b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	radeon_fence_unref(&fence);
164b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	return r;
165771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
166771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
167771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissevoid radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
168771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
169771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	struct radeon_ib *tmp = *ib;
170771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
171771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	*ib = NULL;
172771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	if (tmp == NULL) {
173771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		return;
174771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
1759fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse	radeon_mutex_lock(&rdev->ib_pool.mutex);
176b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	if (tmp->fence && !tmp->fence->emitted) {
177b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		radeon_sa_bo_free(rdev, &tmp->sa_bo);
178b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		radeon_fence_unref(&tmp->fence);
179b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	}
1809fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse	radeon_mutex_unlock(&rdev->ib_pool.mutex);
181771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
182771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
183771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
184771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
185e32eb50dbe43862606a51caa94368ec6bd019434Christian König	struct radeon_ring *ring = &rdev->ring[ib->fence->ring];
186771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	int r = 0;
187771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
188e32eb50dbe43862606a51caa94368ec6bd019434Christian König	if (!ib->length_dw || !ring->ready) {
189771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		/* TODO: Nothings in the ib we should report. */
19091cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse		DRM_ERROR("radeon: couldn't schedule IB(%u).\n", ib->idx);
191771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		return -EINVAL;
192771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
193ecb114a128d150422d22eda238cb812f6b20bf39Dave Airlie
1946cdf65855cf884712532fc72770baaef7bdf1b9aDave Airlie	/* 64 dwords should be enough for fence too */
195e32eb50dbe43862606a51caa94368ec6bd019434Christian König	r = radeon_ring_lock(rdev, ring, 64);
196771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	if (r) {
197ec4f2ac471e25d3e0cea05abb8da34c05a0868f9Paul Bolle		DRM_ERROR("radeon: scheduling IB failed (%d).\n", r);
198771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		return r;
199771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
2004c87bc268d764cf8846d20ea54b355d1e87507c9Christian König	radeon_ring_ib_execute(rdev, ib->fence->ring, ib);
201771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	radeon_fence_emit(rdev, ib->fence);
202e32eb50dbe43862606a51caa94368ec6bd019434Christian König	radeon_ring_unlock_commit(rdev, ring);
203771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return 0;
204771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
205771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
206771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_ib_pool_init(struct radeon_device *rdev)
207771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
208d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse	struct radeon_sa_manager tmp;
209b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	int i, r;
210771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
211d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse	r = radeon_sa_bo_manager_init(rdev, &tmp,
212b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				      RADEON_IB_POOL_SIZE*64*1024,
213b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse				      RADEON_GEM_DOMAIN_GTT);
214771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	if (r) {
215771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		return r;
216771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
217771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
2189fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse	radeon_mutex_lock(&rdev->ib_pool.mutex);
219d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse	if (rdev->ib_pool.ready) {
2209fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse		radeon_mutex_unlock(&rdev->ib_pool.mutex);
221d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse		radeon_sa_bo_manager_fini(rdev, &tmp);
222d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse		return 0;
223d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse	}
224d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse
225d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse	rdev->ib_pool.sa_manager = tmp;
226d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse	INIT_LIST_HEAD(&rdev->ib_pool.sa_manager.sa_bo);
227b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
228b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		rdev->ib_pool.ibs[i].fence = NULL;
229771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		rdev->ib_pool.ibs[i].idx = i;
230771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		rdev->ib_pool.ibs[i].length_dw = 0;
231b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		INIT_LIST_HEAD(&rdev->ib_pool.ibs[i].sa_bo.list);
232771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
23391cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse	rdev->ib_pool.head_id = 0;
234771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	rdev->ib_pool.ready = true;
235771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	DRM_INFO("radeon: ib pool ready.\n");
236b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse
237771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	if (radeon_debugfs_ib_init(rdev)) {
238771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		DRM_ERROR("Failed to register debugfs file for IB !\n");
239771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
240af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	if (radeon_debugfs_ring_init(rdev)) {
241af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König		DRM_ERROR("Failed to register debugfs file for rings !\n");
242af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	}
2439fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse	radeon_mutex_unlock(&rdev->ib_pool.mutex);
244b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	return 0;
245771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
246771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
247771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissevoid radeon_ib_pool_fini(struct radeon_device *rdev)
248771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
249b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	unsigned i;
2504c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse
2519fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse	radeon_mutex_lock(&rdev->ib_pool.mutex);
252b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	if (rdev->ib_pool.ready) {
253b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
254b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			radeon_sa_bo_free(rdev, &rdev->ib_pool.ibs[i].sa_bo);
255b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse			radeon_fence_unref(&rdev->ib_pool.ibs[i].fence);
2564c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse		}
257b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		radeon_sa_bo_manager_fini(rdev, &rdev->ib_pool.sa_manager);
258b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse		rdev->ib_pool.ready = false;
259771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
2609fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse	radeon_mutex_unlock(&rdev->ib_pool.mutex);
261771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
262771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
263b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisseint radeon_ib_pool_start(struct radeon_device *rdev)
264b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse{
265b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	return radeon_sa_bo_manager_start(rdev, &rdev->ib_pool.sa_manager);
266b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse}
267b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse
268b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisseint radeon_ib_pool_suspend(struct radeon_device *rdev)
269b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse{
270b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse	return radeon_sa_bo_manager_suspend(rdev, &rdev->ib_pool.sa_manager);
271b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse}
272771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
273771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/*
274771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Ring.
275771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */
276e32eb50dbe43862606a51caa94368ec6bd019434Christian Königint radeon_ring_index(struct radeon_device *rdev, struct radeon_ring *ring)
277bf85279958da96cb4b11aac89b34f0424c3c120eChristian König{
278bf85279958da96cb4b11aac89b34f0424c3c120eChristian König	/* r1xx-r5xx only has CP ring */
279bf85279958da96cb4b11aac89b34f0424c3c120eChristian König	if (rdev->family < CHIP_R600)
280bf85279958da96cb4b11aac89b34f0424c3c120eChristian König		return RADEON_RING_TYPE_GFX_INDEX;
281bf85279958da96cb4b11aac89b34f0424c3c120eChristian König
282bf85279958da96cb4b11aac89b34f0424c3c120eChristian König	if (rdev->family >= CHIP_CAYMAN) {
283e32eb50dbe43862606a51caa94368ec6bd019434Christian König		if (ring == &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX])
284bf85279958da96cb4b11aac89b34f0424c3c120eChristian König			return CAYMAN_RING_TYPE_CP1_INDEX;
285e32eb50dbe43862606a51caa94368ec6bd019434Christian König		else if (ring == &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX])
286bf85279958da96cb4b11aac89b34f0424c3c120eChristian König			return CAYMAN_RING_TYPE_CP2_INDEX;
287bf85279958da96cb4b11aac89b34f0424c3c120eChristian König	}
288bf85279958da96cb4b11aac89b34f0424c3c120eChristian König	return RADEON_RING_TYPE_GFX_INDEX;
289bf85279958da96cb4b11aac89b34f0424c3c120eChristian König}
290bf85279958da96cb4b11aac89b34f0424c3c120eChristian König
291e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring)
292771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
29378c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher	u32 rptr;
29478c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher
295724c80e1d630296d1324859e964d80d35007d83cAlex Deucher	if (rdev->wb.enabled)
29678c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher		rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
2975596a9db156107b01ceb7db4d50cc091117da627Christian König	else
29878c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher		rptr = RREG32(ring->rptr_reg);
29978c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher	ring->rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
300771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	/* This works because ring_size is a power of 2 */
301e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ring_free_dw = (ring->rptr + (ring->ring_size / 4));
302e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ring_free_dw -= ring->wptr;
303e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ring_free_dw &= ring->ptr_mask;
304e32eb50dbe43862606a51caa94368ec6bd019434Christian König	if (!ring->ring_free_dw) {
305e32eb50dbe43862606a51caa94368ec6bd019434Christian König		ring->ring_free_dw = ring->ring_size / 4;
306771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
307771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
308771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
3097b1f2485db253aaa0081e1c5213533e166130732Christian König
310e32eb50dbe43862606a51caa94368ec6bd019434Christian Königint radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw)
311771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
312771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	int r;
313771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
314771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	/* Align requested size with padding so unlock_commit can
315771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	 * pad safely */
316e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ndw = (ndw + ring->align_mask) & ~ring->align_mask;
317e32eb50dbe43862606a51caa94368ec6bd019434Christian König	while (ndw > (ring->ring_free_dw - 1)) {
318e32eb50dbe43862606a51caa94368ec6bd019434Christian König		radeon_ring_free_size(rdev, ring);
319e32eb50dbe43862606a51caa94368ec6bd019434Christian König		if (ndw < ring->ring_free_dw) {
320771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse			break;
321771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		}
322e32eb50dbe43862606a51caa94368ec6bd019434Christian König		r = radeon_fence_wait_next(rdev, radeon_ring_index(rdev, ring));
32391700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett		if (r)
324771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse			return r;
325771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
326e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->count_dw = ndw;
327e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->wptr_old = ring->wptr;
328771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return 0;
329771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
330771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
331e32eb50dbe43862606a51caa94368ec6bd019434Christian Königint radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw)
33291700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett{
33391700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett	int r;
33491700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett
335e32eb50dbe43862606a51caa94368ec6bd019434Christian König	mutex_lock(&ring->mutex);
336e32eb50dbe43862606a51caa94368ec6bd019434Christian König	r = radeon_ring_alloc(rdev, ring, ndw);
33791700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett	if (r) {
338e32eb50dbe43862606a51caa94368ec6bd019434Christian König		mutex_unlock(&ring->mutex);
33991700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett		return r;
34091700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett	}
34191700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett	return 0;
34291700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett}
34391700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett
344e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring)
345771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
346771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	unsigned count_dw_pad;
347771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	unsigned i;
348771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
349771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	/* We pad to match fetch size */
350e32eb50dbe43862606a51caa94368ec6bd019434Christian König	count_dw_pad = (ring->align_mask + 1) -
351e32eb50dbe43862606a51caa94368ec6bd019434Christian König		       (ring->wptr & ring->align_mask);
352771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	for (i = 0; i < count_dw_pad; i++) {
35378c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher		radeon_ring_write(ring, ring->nop);
354771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
355771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	DRM_MEMORYBARRIER();
35678c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher	WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & ring->ptr_reg_mask);
357e32eb50dbe43862606a51caa94368ec6bd019434Christian König	(void)RREG32(ring->wptr_reg);
35891700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett}
35991700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett
360e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring)
36191700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett{
362e32eb50dbe43862606a51caa94368ec6bd019434Christian König	radeon_ring_commit(rdev, ring);
363e32eb50dbe43862606a51caa94368ec6bd019434Christian König	mutex_unlock(&ring->mutex);
364771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
365771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
366e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *ring)
367771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
368e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->wptr = ring->wptr_old;
369e32eb50dbe43862606a51caa94368ec6bd019434Christian König	mutex_unlock(&ring->mutex);
370771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
371771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
372e32eb50dbe43862606a51caa94368ec6bd019434Christian Königint radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size,
37378c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher		     unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg,
37478c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher		     u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop)
375771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
376771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	int r;
377771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
378e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ring_size = ring_size;
379e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->rptr_offs = rptr_offs;
380e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->rptr_reg = rptr_reg;
381e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->wptr_reg = wptr_reg;
38278c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher	ring->ptr_reg_shift = ptr_reg_shift;
38378c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher	ring->ptr_reg_mask = ptr_reg_mask;
38478c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher	ring->nop = nop;
385771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	/* Allocate ring buffer */
386e32eb50dbe43862606a51caa94368ec6bd019434Christian König	if (ring->ring_obj == NULL) {
387e32eb50dbe43862606a51caa94368ec6bd019434Christian König		r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true,
3884c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse					RADEON_GEM_DOMAIN_GTT,
389e32eb50dbe43862606a51caa94368ec6bd019434Christian König					&ring->ring_obj);
390771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		if (r) {
3914c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse			dev_err(rdev->dev, "(%d) ring create failed\n", r);
392771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse			return r;
393771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		}
394e32eb50dbe43862606a51caa94368ec6bd019434Christian König		r = radeon_bo_reserve(ring->ring_obj, false);
3954c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse		if (unlikely(r != 0))
3964c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse			return r;
397e32eb50dbe43862606a51caa94368ec6bd019434Christian König		r = radeon_bo_pin(ring->ring_obj, RADEON_GEM_DOMAIN_GTT,
398e32eb50dbe43862606a51caa94368ec6bd019434Christian König					&ring->gpu_addr);
399771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		if (r) {
400e32eb50dbe43862606a51caa94368ec6bd019434Christian König			radeon_bo_unreserve(ring->ring_obj);
4014c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse			dev_err(rdev->dev, "(%d) ring pin failed\n", r);
402771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse			return r;
403771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		}
404e32eb50dbe43862606a51caa94368ec6bd019434Christian König		r = radeon_bo_kmap(ring->ring_obj,
405e32eb50dbe43862606a51caa94368ec6bd019434Christian König				       (void **)&ring->ring);
406e32eb50dbe43862606a51caa94368ec6bd019434Christian König		radeon_bo_unreserve(ring->ring_obj);
407771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		if (r) {
4084c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse			dev_err(rdev->dev, "(%d) ring map failed\n", r);
409771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse			return r;
410771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		}
411771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
412e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ptr_mask = (ring->ring_size / 4) - 1;
413e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ring_free_dw = ring->ring_size / 4;
414771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return 0;
415771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
416771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
417e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *ring)
418771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
4194c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse	int r;
420ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher	struct radeon_bo *ring_obj;
4214c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse
422e32eb50dbe43862606a51caa94368ec6bd019434Christian König	mutex_lock(&ring->mutex);
423e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring_obj = ring->ring_obj;
424e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ring = NULL;
425e32eb50dbe43862606a51caa94368ec6bd019434Christian König	ring->ring_obj = NULL;
426e32eb50dbe43862606a51caa94368ec6bd019434Christian König	mutex_unlock(&ring->mutex);
427ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher
428ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher	if (ring_obj) {
429ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher		r = radeon_bo_reserve(ring_obj, false);
4304c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse		if (likely(r == 0)) {
431ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher			radeon_bo_kunmap(ring_obj);
432ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher			radeon_bo_unpin(ring_obj);
433ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher			radeon_bo_unreserve(ring_obj);
4344c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse		}
435ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher		radeon_bo_unref(&ring_obj);
436771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
437771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
438771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
439771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/*
440771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Debugfs info
441771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */
442771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#if defined(CONFIG_DEBUG_FS)
443af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König
444af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic int radeon_debugfs_ring_info(struct seq_file *m, void *data)
445af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König{
446af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	struct drm_info_node *node = (struct drm_info_node *) m->private;
447af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	struct drm_device *dev = node->minor->dev;
448af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	struct radeon_device *rdev = dev->dev_private;
449af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	int ridx = *(int*)node->info_ent->data;
450af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	struct radeon_ring *ring = &rdev->ring[ridx];
451af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	unsigned count, i, j;
452af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König
453af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	radeon_ring_free_size(rdev, ring);
454af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	count = (ring->ring_size / 4) - ring->ring_free_dw;
455af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	seq_printf(m, "wptr(0x%04x): 0x%08x\n", ring->wptr_reg, RREG32(ring->wptr_reg));
456af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	seq_printf(m, "rptr(0x%04x): 0x%08x\n", ring->rptr_reg, RREG32(ring->rptr_reg));
457af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	seq_printf(m, "driver's copy of the wptr: 0x%08x\n", ring->wptr);
458af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr);
459af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw);
460af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	seq_printf(m, "%u dwords in ring\n", count);
461af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	i = ring->rptr;
462af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	for (j = 0; j <= count; j++) {
463af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König		seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]);
464af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König		i = (i + 1) & ring->ptr_mask;
465af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	}
466af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	return 0;
467af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König}
468af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König
469af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic int radeon_ring_type_gfx_index = RADEON_RING_TYPE_GFX_INDEX;
470af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic int cayman_ring_type_cp1_index = CAYMAN_RING_TYPE_CP1_INDEX;
471af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic int cayman_ring_type_cp2_index = CAYMAN_RING_TYPE_CP2_INDEX;
472af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König
473af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic struct drm_info_list radeon_debugfs_ring_info_list[] = {
474af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	{"radeon_ring_gfx", radeon_debugfs_ring_info, 0, &radeon_ring_type_gfx_index},
475af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	{"radeon_ring_cp1", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp1_index},
476af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	{"radeon_ring_cp2", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp2_index},
477af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König};
478af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König
479771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic int radeon_debugfs_ib_info(struct seq_file *m, void *data)
480771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
481771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	struct drm_info_node *node = (struct drm_info_node *) m->private;
482293f9fd53aa1529500ba16d89850100a058b11c1Christian König	struct drm_device *dev = node->minor->dev;
483293f9fd53aa1529500ba16d89850100a058b11c1Christian König	struct radeon_device *rdev = dev->dev_private;
484293f9fd53aa1529500ba16d89850100a058b11c1Christian König	struct radeon_ib *ib = &rdev->ib_pool.ibs[*((unsigned*)node->info_ent->data)];
485771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	unsigned i;
486771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
487771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	if (ib == NULL) {
488771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		return 0;
489771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
49091cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse	seq_printf(m, "IB %04u\n", ib->idx);
491771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	seq_printf(m, "IB fence %p\n", ib->fence);
492771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	seq_printf(m, "IB size %05u dwords\n", ib->length_dw);
493771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	for (i = 0; i < ib->length_dw; i++) {
494771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]);
495771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
496771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return 0;
497771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
498771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
499771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE];
500771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32];
501293f9fd53aa1529500ba16d89850100a058b11c1Christian Königstatic unsigned radeon_debugfs_ib_idx[RADEON_IB_POOL_SIZE];
502771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#endif
503771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
504af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königint radeon_debugfs_ring_init(struct radeon_device *rdev)
505af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König{
506af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König#if defined(CONFIG_DEBUG_FS)
507f0d14daa6906070ca044b86f483fdde7d81f5294Michel Dänzer	if (rdev->family >= CHIP_CAYMAN)
508f0d14daa6906070ca044b86f483fdde7d81f5294Michel Dänzer		return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list,
509f0d14daa6906070ca044b86f483fdde7d81f5294Michel Dänzer						ARRAY_SIZE(radeon_debugfs_ring_info_list));
510f0d14daa6906070ca044b86f483fdde7d81f5294Michel Dänzer	else
511f0d14daa6906070ca044b86f483fdde7d81f5294Michel Dänzer		return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, 1);
512af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König#else
513af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König	return 0;
514af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König#endif
515af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König}
516af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König
517771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_debugfs_ib_init(struct radeon_device *rdev)
518771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{
519771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#if defined(CONFIG_DEBUG_FS)
520771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	unsigned i;
521771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse
522771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
523771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i);
524293f9fd53aa1529500ba16d89850100a058b11c1Christian König		radeon_debugfs_ib_idx[i] = i;
525771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		radeon_debugfs_ib_list[i].name = radeon_debugfs_ib_names[i];
526771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		radeon_debugfs_ib_list[i].show = &radeon_debugfs_ib_info;
527771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse		radeon_debugfs_ib_list[i].driver_features = 0;
528293f9fd53aa1529500ba16d89850100a058b11c1Christian König		radeon_debugfs_ib_list[i].data = &radeon_debugfs_ib_idx[i];
529771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	}
530771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return radeon_debugfs_add_files(rdev, radeon_debugfs_ib_list,
531771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse					RADEON_IB_POOL_SIZE);
532771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#else
533771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse	return 0;
534771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#endif
535771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}
536