drm/radeon: document radeon_ring.c (v4)
Adds documentation to most of the functions in radeon_ring.c v2: adjust per Christian's suggestions v3: adjust per Christian's latest patches v4: adjust per my latest changes Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Christian König <christian.koenig@amd.com>
This commit is contained in:
parent
d66b7ec24a
commit
75923280e5
|
@ -35,10 +35,28 @@
|
|||
#include "atom.h"
|
||||
|
||||
/*
|
||||
* IB.
|
||||
* IB
|
||||
* IBs (Indirect Buffers) and areas of GPU accessible memory where
|
||||
* commands are stored. You can put a pointer to the IB in the
|
||||
* command ring and the hw will fetch the commands from the IB
|
||||
* and execute them. Generally userspace acceleration drivers
|
||||
* produce command buffers which are send to the kernel and
|
||||
* put in IBs for execution by the requested ring.
|
||||
*/
|
||||
int radeon_debugfs_sa_init(struct radeon_device *rdev);
|
||||
|
||||
/**
|
||||
* radeon_ib_get - request an IB (Indirect Buffer)
|
||||
*
|
||||
* @rdev: radeon_device pointer
|
||||
* @ring: ring index the IB is associated with
|
||||
* @ib: IB object returned
|
||||
* @size: requested IB size
|
||||
*
|
||||
* Request an IB (all asics). IBs are allocated using the
|
||||
* suballocator.
|
||||
* Returns 0 on success, error on failure.
|
||||
*/
|
||||
int radeon_ib_get(struct radeon_device *rdev, int ring,
|
||||
struct radeon_ib *ib, unsigned size)
|
||||
{
|
||||
|
@ -67,6 +85,14 @@ int radeon_ib_get(struct radeon_device *rdev, int ring,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_ib_free - free an IB (Indirect Buffer)
|
||||
*
|
||||
* @rdev: radeon_device pointer
|
||||
* @ib: IB object to free
|
||||
*
|
||||
* Free an IB (all asics).
|
||||
*/
|
||||
void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib)
|
||||
{
|
||||
radeon_semaphore_free(rdev, &ib->semaphore, ib->fence);
|
||||
|
@ -74,6 +100,26 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib)
|
|||
radeon_fence_unref(&ib->fence);
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_ib_schedule - schedule an IB (Indirect Buffer) on the ring
|
||||
*
|
||||
* @rdev: radeon_device pointer
|
||||
* @ib: IB object to schedule
|
||||
* @const_ib: Const IB to schedule (SI only)
|
||||
*
|
||||
* Schedule an IB on the associated ring (all asics).
|
||||
* Returns 0 on success, error on failure.
|
||||
*
|
||||
* On SI, there are two parallel engines fed from the primary ring,
|
||||
* the CE (Constant Engine) and the DE (Drawing Engine). Since
|
||||
* resource descriptors have moved to memory, the CE allows you to
|
||||
* prime the caches while the DE is updating register state so that
|
||||
* the resource descriptors will be already in cache when the draw is
|
||||
* processed. To accomplish this, the userspace driver submits two
|
||||
* IBs, one for the CE and one for the DE. If there is a CE IB (called
|
||||
* a CONST_IB), it will be put on the ring prior to the DE IB. Prior
|
||||
* to SI there was just a DE IB.
|
||||
*/
|
||||
int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
|
||||
struct radeon_ib *const_ib)
|
||||
{
|
||||
|
@ -124,6 +170,15 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_ib_pool_init - Init the IB (Indirect Buffer) pool
|
||||
*
|
||||
* @rdev: radeon_device pointer
|
||||
*
|
||||
* Initialize the suballocator to manage a pool of memory
|
||||
* for use as IBs (all asics).
|
||||
* Returns 0 on success, error on failure.
|
||||
*/
|
||||
int radeon_ib_pool_init(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
@ -150,6 +205,14 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_ib_pool_fini - Free the IB (Indirect Buffer) pool
|
||||
*
|
||||
* @rdev: radeon_device pointer
|
||||
*
|
||||
* Tear down the suballocator managing the pool of memory
|
||||
* for use as IBs (all asics).
|
||||
*/
|
||||
void radeon_ib_pool_fini(struct radeon_device *rdev)
|
||||
{
|
||||
if (rdev->ib_pool_ready) {
|
||||
|
@ -159,6 +222,16 @@ void radeon_ib_pool_fini(struct radeon_device *rdev)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_ib_ring_tests - test IBs on the rings
|
||||
*
|
||||
* @rdev: radeon_device pointer
|
||||
*
|
||||
* Test an IB (Indirect Buffer) on each ring.
|
||||
* If the test fails, disable the ring.
|
||||
* Returns 0 on success, error if the primary GFX ring
|
||||
* IB test fails.
|
||||
*/
|
||||
int radeon_ib_ring_tests(struct radeon_device *rdev)
|
||||
{
|
||||
unsigned i;
|
||||
|
@ -190,10 +263,28 @@ int radeon_ib_ring_tests(struct radeon_device *rdev)
|
|||
}
|
||||
|
||||
/*
|
||||
* Ring.
|
||||
* Rings
|
||||
* Most engines on the GPU are fed via ring buffers. Ring
|
||||
* buffers are areas of GPU accessible memory that the host
|
||||
* writes commands into and the GPU reads commands out of.
|
||||
* There is a rptr (read pointer) that determines where the
|
||||
* GPU is currently reading, and a wptr (write pointer)
|
||||
* which determines where the host has written. When the
|
||||
* pointers are equal, the ring is idle. When the host
|
||||
* writes commands to the ring buffer, it increments the
|
||||
* wptr. The GPU then starts fetching commands and executes
|
||||
* them until the pointers are equal again.
|
||||
*/
|
||||
int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *ring);
|
||||
|
||||
/**
|
||||
* radeon_ring_write - write a value to the ring
|
||||
*
|
||||
* @ring: radeon_ring structure holding ring information
|
||||
* @v: dword (dw) value to write
|
||||
*
|
||||
* Write a value to the requested ring buffer (all asics).
|
||||
*/
|
||||
void radeon_ring_write(struct radeon_ring *ring, uint32_t v)
|
||||
{
|
||||
#if DRM_DEBUG_CODE
|
||||
|
@ -207,6 +298,16 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v)
|
|||
ring->ring_free_dw--;
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_ring_supports_scratch_reg - check if the ring supports
|
||||
* writing to scratch registers
|
||||
*
|
||||
* @rdev: radeon_device pointer
|
||||
* @ring: radeon_ring structure holding ring information
|
||||
*
|
||||
* Check if a specific ring supports writing to scratch registers (all asics).
|
||||
* Returns true if the ring supports writing to scratch regs, false if not.
|
||||
*/
|
||||
bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev,
|
||||
struct radeon_ring *ring)
|
||||
{
|
||||
|
@ -220,6 +321,14 @@ bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_ring_free_size - update the free size
|
||||
*
|
||||
* @rdev: radeon_device pointer
|
||||
* @ring: radeon_ring structure holding ring information
|
||||
*
|
||||
* Update the free dw slots in the ring buffer (all asics).
|
||||
*/
|
||||
void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring)
|
||||
{
|
||||
u32 rptr;
|
||||
|
@ -238,7 +347,16 @@ void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* radeon_ring_alloc - allocate space on the ring buffer
|
||||
*
|
||||
* @rdev: radeon_device pointer
|
||||
* @ring: radeon_ring structure holding ring information
|
||||
* @ndw: number of dwords to allocate in the ring buffer
|
||||
*
|
||||
* Allocate @ndw dwords in the ring buffer (all asics).
|
||||
* Returns 0 on success, error on failure.
|
||||
*/
|
||||
int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw)
|
||||
{
|
||||
int r;
|
||||
|
@ -260,6 +378,17 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsi
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_ring_lock - lock the ring and allocate space on it
|
||||
*
|
||||
* @rdev: radeon_device pointer
|
||||
* @ring: radeon_ring structure holding ring information
|
||||
* @ndw: number of dwords to allocate in the ring buffer
|
||||
*
|
||||
* Lock the ring and allocate @ndw dwords in the ring buffer
|
||||
* (all asics).
|
||||
* Returns 0 on success, error on failure.
|
||||
*/
|
||||
int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw)
|
||||
{
|
||||
int r;
|
||||
|
@ -273,6 +402,16 @@ int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsig
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_ring_commit - tell the GPU to execute the new
|
||||
* commands on the ring buffer
|
||||
*
|
||||
* @rdev: radeon_device pointer
|
||||
* @ring: radeon_ring structure holding ring information
|
||||
*
|
||||
* Update the wptr (write pointer) to tell the GPU to
|
||||
* execute new commands on the ring buffer (all asics).
|
||||
*/
|
||||
void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring)
|
||||
{
|
||||
/* We pad to match fetch size */
|
||||
|
@ -284,23 +423,55 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring)
|
|||
(void)RREG32(ring->wptr_reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_ring_unlock_commit - tell the GPU to execute the new
|
||||
* commands on the ring buffer and unlock it
|
||||
*
|
||||
* @rdev: radeon_device pointer
|
||||
* @ring: radeon_ring structure holding ring information
|
||||
*
|
||||
* Call radeon_ring_commit() then unlock the ring (all asics).
|
||||
*/
|
||||
void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring)
|
||||
{
|
||||
radeon_ring_commit(rdev, ring);
|
||||
mutex_unlock(&rdev->ring_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_ring_undo - reset the wptr
|
||||
*
|
||||
* @ring: radeon_ring structure holding ring information
|
||||
*
|
||||
* Reset the driver's copy of the wtpr (all asics).
|
||||
*/
|
||||
void radeon_ring_undo(struct radeon_ring *ring)
|
||||
{
|
||||
ring->wptr = ring->wptr_old;
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_ring_unlock_undo - reset the wptr and unlock the ring
|
||||
*
|
||||
* @ring: radeon_ring structure holding ring information
|
||||
*
|
||||
* Call radeon_ring_undo() then unlock the ring (all asics).
|
||||
*/
|
||||
void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *ring)
|
||||
{
|
||||
radeon_ring_undo(ring);
|
||||
mutex_unlock(&rdev->ring_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_ring_force_activity - add some nop packets to the ring
|
||||
*
|
||||
* @rdev: radeon_device pointer
|
||||
* @ring: radeon_ring structure holding ring information
|
||||
*
|
||||
* Add some nop packets to the ring to force activity (all asics).
|
||||
* Used for lockup detection to see if the rptr is advancing.
|
||||
*/
|
||||
void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring)
|
||||
{
|
||||
int r;
|
||||
|
@ -315,6 +486,13 @@ void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_ring_force_activity - update lockup variables
|
||||
*
|
||||
* @ring: radeon_ring structure holding ring information
|
||||
*
|
||||
* Update the last rptr value and timestamp (all asics).
|
||||
*/
|
||||
void radeon_ring_lockup_update(struct radeon_ring *ring)
|
||||
{
|
||||
ring->last_rptr = ring->rptr;
|
||||
|
@ -458,6 +636,22 @@ int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_ring_init - init driver ring struct.
|
||||
*
|
||||
* @rdev: radeon_device pointer
|
||||
* @ring: radeon_ring structure holding ring information
|
||||
* @ring_size: size of the ring
|
||||
* @rptr_offs: offset of the rptr writeback location in the WB buffer
|
||||
* @rptr_reg: MMIO offset of the rptr register
|
||||
* @wptr_reg: MMIO offset of the wptr register
|
||||
* @ptr_reg_shift: bit offset of the rptr/wptr values
|
||||
* @ptr_reg_mask: bit mask of the rptr/wptr values
|
||||
* @nop: nop packet for this ring
|
||||
*
|
||||
* Initialize the driver information for the selected ring (all asics).
|
||||
* Returns 0 on success, error on failure.
|
||||
*/
|
||||
int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size,
|
||||
unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg,
|
||||
u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop)
|
||||
|
@ -511,6 +705,14 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_ring_fini - tear down the driver ring struct.
|
||||
*
|
||||
* @rdev: radeon_device pointer
|
||||
* @ring: radeon_ring structure holding ring information
|
||||
*
|
||||
* Tear down the driver information for the selected ring (all asics).
|
||||
*/
|
||||
void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *ring)
|
||||
{
|
||||
int r;
|
||||
|
|
Loading…
Reference in a new issue