Files
linux-legacy/drivers/mxc/amd-gpu/common/gsl_ringbuffer.c
2012-11-21 14:02:55 -06:00

1164 lines
39 KiB
C

/* Copyright (c) 2002,2007-2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
*/
#include "gsl.h"
#include "gsl_hal.h"
#include "gsl_cmdstream.h"
#ifdef GSL_BLD_YAMATO
//////////////////////////////////////////////////////////////////////////////
// ucode
//////////////////////////////////////////////////////////////////////////////
#define uint32 unsigned int
#include "pm4_microcode.inl"
#include "pfp_microcode_nrt.inl"
#undef uint32
//////////////////////////////////////////////////////////////////////////////
// defines
//////////////////////////////////////////////////////////////////////////////
#define GSL_RB_NOP_SIZEDWORDS 2 // default is 2
#define GSL_RB_PROTECTED_MODE_CONTROL 0x00000000 // protected mode error checking below register address 0x800
// note: if CP_INTERRUPT packet is used then checking needs
// to change to below register address 0x7C8
//////////////////////////////////////////////////////////////////////////////
// ringbuffer size log2 quadwords equivalent
//////////////////////////////////////////////////////////////////////////////
OSINLINE unsigned int
gsl_ringbuffer_sizelog2quadwords(unsigned int sizedwords)
{
unsigned int sizelog2quadwords = 0;
int i = sizedwords >> 1;
while (i >>= 1)
{
sizelog2quadwords++;
}
return (sizelog2quadwords);
}
//////////////////////////////////////////////////////////////////////////////
// private prototypes
//////////////////////////////////////////////////////////////////////////////
#ifdef _DEBUG
static void kgsl_ringbuffer_debug(gsl_ringbuffer_t *rb, gsl_rb_debug_t *rb_debug);
#endif
//////////////////////////////////////////////////////////////////////////////
// functions
//////////////////////////////////////////////////////////////////////////////
void
kgsl_cp_intrcallback(gsl_intrid_t id, void *cookie)
{
gsl_ringbuffer_t *rb = (gsl_ringbuffer_t *) cookie;
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE,
"--> void kgsl_cp_intrcallback(gsl_intrid_t id=%I, void *cookie=0x%08x)\n", id, cookie );
switch(id)
{
// error condition interrupt
case GSL_INTR_YDX_CP_T0_PACKET_IN_IB:
case GSL_INTR_YDX_CP_OPCODE_ERROR:
case GSL_INTR_YDX_CP_PROTECTED_MODE_ERROR:
case GSL_INTR_YDX_CP_RESERVED_BIT_ERROR:
case GSL_INTR_YDX_CP_IB_ERROR:
printk(KERN_ERR "GPU: CP Error\n");
schedule_work(&rb->device->irq_err_work);
break;
// non-error condition interrupt
case GSL_INTR_YDX_CP_SW_INT:
case GSL_INTR_YDX_CP_IB2_INT:
case GSL_INTR_YDX_CP_IB1_INT:
case GSL_INTR_YDX_CP_RING_BUFFER:
// signal intr completion event
kos_event_signal(rb->device->intr.evnt[id]);
break;
default:
break;
}
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_cp_intrcallback.\n" );
}
//----------------------------------------------------------------------------
void
kgsl_ringbuffer_watchdog()
{
gsl_ringbuffer_t *rb = &(gsl_driver.device[GSL_DEVICE_YAMATO-1]).ringbuffer; // device_id is 1 based
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE,
"--> void kgsl_ringbuffer_watchdog()\n" );
if (rb->flags & GSL_FLAGS_STARTED)
{
GSL_RB_MUTEX_LOCK();
GSL_RB_GET_READPTR(rb, &rb->rptr);
// ringbuffer is currently not empty
if (rb->rptr != rb->wptr)
{
// and a rptr sample was taken during interval n-1
if (rb->watchdog.flags & GSL_FLAGS_ACTIVE)
{
// and the rptr did not advance between interval n-1 and n
if (rb->rptr == rb->watchdog.rptr_sample)
{
// then the core has hung
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_FATAL,
"ERROR: Watchdog detected core hung.\n" );
rb->device->ftbl.device_destroy(rb->device);
return;
}
}
// save rptr sample for interval n
rb->watchdog.flags |= GSL_FLAGS_ACTIVE;
rb->watchdog.rptr_sample = rb->rptr;
}
else
{
// clear rptr sample for interval n
rb->watchdog.flags &= ~GSL_FLAGS_ACTIVE;
}
GSL_RB_MUTEX_UNLOCK();
}
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_watchdog.\n" );
}
//----------------------------------------------------------------------------
#ifdef _DEBUG
OSINLINE void
kgsl_ringbuffer_checkregister(unsigned int reg, int pmodecheck)
{
if (pmodecheck)
{
// check for register protection mode violation
if (reg <= (GSL_RB_PROTECTED_MODE_CONTROL & 0x3FFF))
{
kgsl_log_write( KGSL_LOG_GROUP_MEMORY | KGSL_LOG_LEVEL_ERROR, "ERROR: Register protection mode violation.\n" );
KOS_ASSERT(0);
}
}
// range check register offset
if (reg > (gsl_driver.device[GSL_DEVICE_YAMATO-1].regspace.sizebytes >> 2))
{
kgsl_log_write( KGSL_LOG_GROUP_MEMORY | KGSL_LOG_LEVEL_ERROR, "ERROR: Register out of range.\n" );
KOS_ASSERT(0);
}
}
//----------------------------------------------------------------------------
void
kgsl_ringbuffer_checkpm4type0(unsigned int header, unsigned int** cmds, int pmodeoff)
{
pm4_type0 pm4header = *((pm4_type0*) &header);
unsigned int reg;
if (pm4header.one_reg_wr)
{
reg = pm4header.base_index;
}
else
{
reg = pm4header.base_index + pm4header.count;
}
kgsl_ringbuffer_checkregister(reg, !pmodeoff);
*cmds += pm4header.count + 1;
}
//----------------------------------------------------------------------------
void
kgsl_ringbuffer_checkpm4type3(unsigned int header, unsigned int** cmds, int indirection, int pmodeoff)
{
pm4_type3 pm4header = *((pm4_type3*) &header);
unsigned int *ordinal2 = *cmds;
unsigned int *ibcmds, *end;
unsigned int reg, length;
// check indirect buffer level
if (indirection > 2)
{
kgsl_log_write( KGSL_LOG_GROUP_MEMORY | KGSL_LOG_LEVEL_ERROR, "ERROR: Only two levels of indirection supported.\n" );
KOS_ASSERT(0);
}
switch(pm4header.it_opcode)
{
case PM4_INDIRECT_BUFFER:
case PM4_INDIRECT_BUFFER_PFD:
// determine ib host base and end address
ibcmds = (unsigned int*) kgsl_sharedmem_convertaddr(*ordinal2, 0);
end = ibcmds + *(ordinal2 + 1);
// walk through the ib
while(ibcmds < end)
{
unsigned int tmpheader = *(ibcmds++);
switch(tmpheader & PM4_PKT_MASK)
{
case PM4_TYPE0_PKT:
kgsl_ringbuffer_checkpm4type0(tmpheader, &ibcmds, pmodeoff);
break;
case PM4_TYPE1_PKT:
case PM4_TYPE2_PKT:
break;
case PM4_TYPE3_PKT:
kgsl_ringbuffer_checkpm4type3(tmpheader, &ibcmds, (indirection + 1), pmodeoff);
break;
}
}
break;
case PM4_ME_INIT:
if(indirection != 0)
{
kgsl_log_write( KGSL_LOG_GROUP_MEMORY | KGSL_LOG_LEVEL_ERROR, "ERROR: ME INIT packet cannot reside in an ib.\n" );
KOS_ASSERT(0);
}
break;
case PM4_REG_RMW:
reg = (*ordinal2) & 0x1FFF;
kgsl_ringbuffer_checkregister(reg, !pmodeoff);
break;
case PM4_SET_CONSTANT:
if((((*ordinal2) >> 16) & 0xFF) == 0x4) // incremental register update
{
reg = 0x2000 + ((*ordinal2) & 0x3FF); // gfx decode space address starts at 0x2000
length = pm4header.count - 1;
kgsl_ringbuffer_checkregister(reg + length, 0);
}
break;
case PM4_LOAD_CONSTANT_CONTEXT:
if(((*(ordinal2 + 1) >> 16) & 0xFF) == 0x4) // incremental register update
{
reg = 0x2000 + (*(ordinal2 + 1) & 0x3FF); // gfx decode space address starts at 0x2000
length = *(ordinal2 + 2);
kgsl_ringbuffer_checkregister(reg + length, 0);
}
break;
case PM4_COND_WRITE:
if(((*ordinal2) & 0x00000100) == 0x0) // write to register
{
reg = *(ordinal2 + 4) & 0x3FFF;
kgsl_ringbuffer_checkregister(reg, !pmodeoff);
}
break;
}
*cmds += pm4header.count + 1;
}
//----------------------------------------------------------------------------
void
kgsl_ringbuffer_checkpm4(unsigned int* cmds, unsigned int sizedwords, int pmodeoff)
{
unsigned int *ringcmds = cmds;
unsigned int *end = cmds + sizedwords;
while(ringcmds < end)
{
unsigned int header = *(ringcmds++);
switch(header & PM4_PKT_MASK)
{
case PM4_TYPE0_PKT:
kgsl_ringbuffer_checkpm4type0(header, &ringcmds, pmodeoff);
break;
case PM4_TYPE1_PKT:
case PM4_TYPE2_PKT:
break;
case PM4_TYPE3_PKT:
kgsl_ringbuffer_checkpm4type3(header, &ringcmds, 0, pmodeoff);
break;
}
}
}
#endif // _DEBUG
//----------------------------------------------------------------------------
static void
kgsl_ringbuffer_submit(gsl_ringbuffer_t *rb)
{
unsigned int value;
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE,
"--> static void kgsl_ringbuffer_submit(gsl_ringbuffer_t *rb=0x%08x)\n", rb );
KOS_ASSERT(rb->wptr != 0);
kgsl_device_active(rb->device);
GSL_RB_UPDATE_WPTR_POLLING(rb);
// send the wptr to the hw
rb->device->ftbl.device_regwrite(rb->device, mmCP_RB_WPTR, rb->wptr);
rb->flags |= GSL_FLAGS_ACTIVE;
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_submit.\n" );
}
//----------------------------------------------------------------------------
static int
kgsl_ringbuffer_waitspace(gsl_ringbuffer_t *rb, unsigned int numcmds, int wptr_ahead)
{
int nopcount;
unsigned int freecmds;
unsigned int *cmds;
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE,
"--> static int kgsl_ringbuffer_waitspace(gsl_ringbuffer_t *rb=0x%08x, unsigned int numcmds=%d, int wptr_ahead=%d)\n",
rb, numcmds, wptr_ahead );
// if wptr ahead, fill the remaining with NOPs
if (wptr_ahead)
{
nopcount = rb->sizedwords - rb->wptr - 1; // -1 for header
cmds = (unsigned int *)rb->buffer_desc.hostptr + rb->wptr;
GSL_RB_WRITE(cmds, pm4_nop_packet(nopcount));
rb->wptr++;
kgsl_ringbuffer_submit(rb);
rb->wptr = 0;
GSL_RB_STATS(rb->stats.wraps++);
}
KGSL_DEBUG(GSL_DBGFLAGS_DUMPX, KGSL_DEBUG_DUMPX(BB_DUMP_RBWAIT, GSL_DEVICE_YAMATO, rb->wptr, numcmds, "kgsl_ringbuffer_waitspace"));
// wait for space in ringbuffer
for( ; ; )
{
GSL_RB_GET_READPTR(rb, &rb->rptr);
freecmds = rb->rptr - rb->wptr;
if ((freecmds == 0) || (freecmds > numcmds))
{
break;
}
}
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_waitspace. Return value %B\n", GSL_SUCCESS );
return (GSL_SUCCESS);
}
//----------------------------------------------------------------------------
static unsigned int *
kgsl_ringbuffer_addcmds(gsl_ringbuffer_t *rb, unsigned int numcmds)
{
unsigned int *ptr;
int status = GSL_SUCCESS;
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE,
"--> static unsigned int* kgsl_ringbuffer_addcmds(gsl_ringbuffer_t *rb=0x%08x, unsigned int numcmds=%d)\n",
rb, numcmds );
KOS_ASSERT(numcmds < rb->sizedwords);
// update host copy of read pointer when running in safe mode
if (rb->device->flags & GSL_FLAGS_SAFEMODE)
{
GSL_RB_GET_READPTR(rb, &rb->rptr);
}
// check for available space
if (rb->wptr >= rb->rptr)
{
// wptr ahead or equal to rptr
if ((rb->wptr + numcmds) > (rb->sizedwords - GSL_RB_NOP_SIZEDWORDS)) // reserve dwords for nop packet
{
status = kgsl_ringbuffer_waitspace(rb, numcmds, 1);
}
}
else
{
// wptr behind rptr
if ((rb->wptr + numcmds) >= rb->rptr)
{
status = kgsl_ringbuffer_waitspace(rb, numcmds, 0);
}
// check for remaining space
if ((rb->wptr + numcmds) > (rb->sizedwords - GSL_RB_NOP_SIZEDWORDS)) // reserve dwords for nop packet
{
status = kgsl_ringbuffer_waitspace(rb, numcmds, 1);
}
}
ptr = (unsigned int *)rb->buffer_desc.hostptr + rb->wptr;
rb->wptr += numcmds;
if (status == GSL_SUCCESS)
{
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_waitspace. Return value 0x%08x\n", ptr );
return (ptr);
}
else
{
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_waitspace. Return value 0x%08x\n", NULL );
return (NULL);
}
}
//----------------------------------------------------------------------------
int
kgsl_ringbuffer_start(gsl_ringbuffer_t *rb)
{
int status;
cp_rb_cntl_u cp_rb_cntl;
int i;
unsigned int *cmds;
gsl_device_t *device = rb->device;
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE,
"--> static int kgsl_ringbuffer_start(gsl_ringbuffer_t *rb=0x%08x)\n", rb );
if (rb->flags & GSL_FLAGS_STARTED)
{
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_start. Return value %B\n", GSL_SUCCESS );
return (GSL_SUCCESS);
}
// clear memptrs values
kgsl_sharedmem_set0(&rb->memptrs_desc, 0, 0, sizeof(gsl_rbmemptrs_t));
// clear ringbuffer
kgsl_sharedmem_set0(&rb->buffer_desc, 0, 0x12341234, (rb->sizedwords << 2));
// setup WPTR polling address
device->ftbl.device_regwrite(device, mmCP_RB_WPTR_BASE, (rb->memptrs_desc.gpuaddr + GSL_RB_MEMPTRS_WPTRPOLL_OFFSET));
// setup WPTR delay
device->ftbl.device_regwrite(device, mmCP_RB_WPTR_DELAY, 0/*0x70000010*/);
// setup RB_CNTL
device->ftbl.device_regread(device, mmCP_RB_CNTL, (unsigned int *)&cp_rb_cntl);
cp_rb_cntl.f.rb_bufsz = gsl_ringbuffer_sizelog2quadwords(rb->sizedwords); // size of ringbuffer
cp_rb_cntl.f.rb_blksz = rb->blksizequadwords; // quadwords to read before updating mem RPTR
cp_rb_cntl.f.rb_poll_en = GSL_RB_CNTL_POLL_EN; // WPTR polling
cp_rb_cntl.f.rb_no_update = GSL_RB_CNTL_NO_UPDATE; // mem RPTR writebacks
device->ftbl.device_regwrite(device, mmCP_RB_CNTL, cp_rb_cntl.val);
// setup RB_BASE
device->ftbl.device_regwrite(device, mmCP_RB_BASE, rb->buffer_desc.gpuaddr);
// setup RPTR_ADDR
device->ftbl.device_regwrite(device, mmCP_RB_RPTR_ADDR, rb->memptrs_desc.gpuaddr + GSL_RB_MEMPTRS_RPTR_OFFSET);
// explicitly clear all cp interrupts when running in safe mode
if (rb->device->flags & GSL_FLAGS_SAFEMODE)
{
device->ftbl.device_regwrite(device, mmCP_INT_ACK, 0xFFFFFFFF);
}
// setup scratch/timestamp addr
device->ftbl.device_regwrite(device, mmSCRATCH_ADDR, device->memstore.gpuaddr + GSL_DEVICE_MEMSTORE_OFFSET(soptimestamp));
// setup scratch/timestamp mask
device->ftbl.device_regwrite(device, mmSCRATCH_UMSK, GSL_RB_MEMPTRS_SCRATCH_MASK);
// load the CP ucode
device->ftbl.device_regwrite(device, mmCP_DEBUG, 0x02000000);
device->ftbl.device_regwrite(device, mmCP_ME_RAM_WADDR, 0);
for (i = 0; i < PM4_MICROCODE_SIZE; i++ )
{
device->ftbl.device_regwrite(device, mmCP_ME_RAM_DATA, aPM4_Microcode[i][0]);
device->ftbl.device_regwrite(device, mmCP_ME_RAM_DATA, aPM4_Microcode[i][1]);
device->ftbl.device_regwrite(device, mmCP_ME_RAM_DATA, aPM4_Microcode[i][2]);
}
// load the prefetch parser ucode
device->ftbl.device_regwrite(device, mmCP_PFP_UCODE_ADDR, 0);
for ( i = 0; i < PFP_MICROCODE_SIZE_NRT; i++ )
{
device->ftbl.device_regwrite(device, mmCP_PFP_UCODE_DATA, aPFP_Microcode_nrt[i]);
}
// queue thresholds ???
device->ftbl.device_regwrite(device, mmCP_QUEUE_THRESHOLDS, 0x000C0804);
// reset pointers
rb->rptr = 0;
rb->wptr = 0;
// init timestamp
rb->timestamp = 0;
GSL_RB_INIT_TIMESTAMP(rb);
// clear ME_HALT to start micro engine
device->ftbl.device_regwrite(device, mmCP_ME_CNTL, 0);
// ME_INIT
cmds = kgsl_ringbuffer_addcmds(rb, 19);
GSL_RB_WRITE(cmds, PM4_HDR_ME_INIT);
GSL_RB_WRITE(cmds, 0x000003ff); // All fields present (bits 9:0)
GSL_RB_WRITE(cmds, 0x00000000); // Disable/Enable Real-Time Stream processing (present but ignored)
GSL_RB_WRITE(cmds, 0x00000000); // Enable (2D to 3D) and (3D to 2D) implicit synchronization (present but ignored)
GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(mmRB_SURFACE_INFO));
GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(mmPA_SC_WINDOW_OFFSET));
GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(mmVGT_MAX_VTX_INDX));
GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(mmSQ_PROGRAM_CNTL));
GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(mmRB_DEPTHCONTROL));
GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(mmPA_SU_POINT_SIZE));
GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(mmPA_SC_LINE_CNTL));
GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(mmPA_SU_POLY_OFFSET_FRONT_SCALE));
GSL_RB_WRITE(cmds, 0x80000180); // Vertex and Pixel Shader Start Addresses in instructions (3 DWORDS per instruction)
GSL_RB_WRITE(cmds, 0x00000001); // Maximum Contexts
GSL_RB_WRITE(cmds, 0x00000000); // Write Confirm Interval and The CP will wait the wait_interval * 16 clocks between polling
GSL_RB_WRITE(cmds, 0x00000000); // NQ and External Memory Swap
GSL_RB_WRITE(cmds, GSL_RB_PROTECTED_MODE_CONTROL); // Protected mode error checking
GSL_RB_WRITE(cmds, 0x00000000); // Disable header dumping and Header dump address
GSL_RB_WRITE(cmds, 0x00000000); // Header dump size
KGSL_DEBUG(GSL_DBGFLAGS_PM4CHECK, kgsl_ringbuffer_checkpm4((unsigned int *)rb->buffer_desc.hostptr, 19, 1));
KGSL_DEBUG(GSL_DBGFLAGS_PM4, KGSL_DEBUG_DUMPPM4((unsigned int *)rb->buffer_desc.hostptr, 19));
kgsl_ringbuffer_submit(rb);
// idle device to validate ME INIT
status = device->ftbl.device_idle(device, GSL_TIMEOUT_DEFAULT);
if (status == GSL_SUCCESS)
{
rb->flags |= GSL_FLAGS_STARTED;
}
// enable cp interrupts
kgsl_intr_attach(&device->intr, GSL_INTR_YDX_CP_SW_INT, kgsl_cp_intrcallback, (void *) rb);
kgsl_intr_attach(&device->intr, GSL_INTR_YDX_CP_T0_PACKET_IN_IB, kgsl_cp_intrcallback, (void *) rb);
kgsl_intr_attach(&device->intr, GSL_INTR_YDX_CP_OPCODE_ERROR, kgsl_cp_intrcallback, (void *) rb);
kgsl_intr_attach(&device->intr, GSL_INTR_YDX_CP_PROTECTED_MODE_ERROR, kgsl_cp_intrcallback, (void *) rb);
kgsl_intr_attach(&device->intr, GSL_INTR_YDX_CP_RESERVED_BIT_ERROR, kgsl_cp_intrcallback, (void *) rb);
kgsl_intr_attach(&device->intr, GSL_INTR_YDX_CP_IB_ERROR, kgsl_cp_intrcallback, (void *) rb);
kgsl_intr_attach(&device->intr, GSL_INTR_YDX_CP_IB2_INT, kgsl_cp_intrcallback, (void *) rb);
kgsl_intr_attach(&device->intr, GSL_INTR_YDX_CP_IB1_INT, kgsl_cp_intrcallback, (void *) rb);
kgsl_intr_attach(&device->intr, GSL_INTR_YDX_CP_RING_BUFFER, kgsl_cp_intrcallback, (void *) rb);
kgsl_intr_enable(&device->intr, GSL_INTR_YDX_CP_SW_INT);
kgsl_intr_enable(&device->intr, GSL_INTR_YDX_CP_T0_PACKET_IN_IB);
kgsl_intr_enable(&device->intr, GSL_INTR_YDX_CP_OPCODE_ERROR);
kgsl_intr_enable(&device->intr, GSL_INTR_YDX_CP_PROTECTED_MODE_ERROR);
kgsl_intr_enable(&device->intr, GSL_INTR_YDX_CP_RESERVED_BIT_ERROR);
kgsl_intr_enable(&device->intr, GSL_INTR_YDX_CP_IB_ERROR);
kgsl_intr_enable(&device->intr, GSL_INTR_YDX_CP_IB2_INT);
kgsl_intr_enable(&device->intr, GSL_INTR_YDX_CP_IB1_INT);
kgsl_intr_enable(&device->intr, GSL_INTR_YDX_CP_RING_BUFFER);
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_start. Return value %B\n", status );
return (status);
}
//----------------------------------------------------------------------------
int
kgsl_ringbuffer_stop(gsl_ringbuffer_t *rb)
{
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE,
"--> static int kgsl_ringbuffer_stop(gsl_ringbuffer_t *rb=0x%08x)\n", rb );
if (rb->flags & GSL_FLAGS_STARTED)
{
// disable cp interrupts
kgsl_intr_detach(&rb->device->intr, GSL_INTR_YDX_CP_SW_INT);
kgsl_intr_detach(&rb->device->intr, GSL_INTR_YDX_CP_T0_PACKET_IN_IB);
kgsl_intr_detach(&rb->device->intr, GSL_INTR_YDX_CP_OPCODE_ERROR);
kgsl_intr_detach(&rb->device->intr, GSL_INTR_YDX_CP_PROTECTED_MODE_ERROR);
kgsl_intr_detach(&rb->device->intr, GSL_INTR_YDX_CP_RESERVED_BIT_ERROR);
kgsl_intr_detach(&rb->device->intr, GSL_INTR_YDX_CP_IB_ERROR);
kgsl_intr_detach(&rb->device->intr, GSL_INTR_YDX_CP_IB2_INT);
kgsl_intr_detach(&rb->device->intr, GSL_INTR_YDX_CP_IB1_INT);
kgsl_intr_detach(&rb->device->intr, GSL_INTR_YDX_CP_RING_BUFFER);
// ME_HALT
rb->device->ftbl.device_regwrite(rb->device, mmCP_ME_CNTL, 0x10000000);
rb->flags &= ~GSL_FLAGS_STARTED;
}
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_stop. Return value %B\n", GSL_SUCCESS );
return (GSL_SUCCESS);
}
//----------------------------------------------------------------------------
int
kgsl_ringbuffer_init(gsl_device_t *device)
{
int status;
gsl_flags_t flags;
gsl_ringbuffer_t *rb = &device->ringbuffer;
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE,
"--> int kgsl_ringbuffer_init(gsl_device_t *device=0x%08x)\n", device );
rb->device = device;
rb->sizedwords = (2 << gsl_cfg_rb_sizelog2quadwords);
rb->blksizequadwords = gsl_cfg_rb_blksizequadwords;
GSL_RB_MUTEX_CREATE();
// allocate memory for ringbuffer, needs to be double octword aligned
// align on page from contiguous physical memory
flags = (GSL_MEMFLAGS_ALIGNPAGE | GSL_MEMFLAGS_CONPHYS | GSL_MEMFLAGS_STRICTREQUEST);
KGSL_DEBUG(GSL_DBGFLAGS_DUMPX, flags = (GSL_MEMFLAGS_ALIGNPAGE | GSL_MEMFLAGS_STRICTREQUEST)); /* set MMU table for ringbuffer */
status = kgsl_sharedmem_alloc0(device->id, flags, (rb->sizedwords << 2), &rb->buffer_desc);
KGSL_DEBUG(GSL_DBGFLAGS_DUMPX, KGSL_DEBUG_DUMPX(BB_DUMP_RINGBUF_SET, (unsigned int)rb->buffer_desc.gpuaddr, (unsigned int)rb->buffer_desc.hostptr, 0, "kgsl_ringbuffer_init"));
if (status != GSL_SUCCESS)
{
kgsl_ringbuffer_close(rb);
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_init. Return value %B\n", status );
return (status);
}
// allocate memory for polling and timestamps
flags = (GSL_MEMFLAGS_ALIGN32 | GSL_MEMFLAGS_CONPHYS);
KGSL_DEBUG(GSL_DBGFLAGS_DUMPX, flags = GSL_MEMFLAGS_ALIGN32);
status = kgsl_sharedmem_alloc0(device->id, flags, sizeof(gsl_rbmemptrs_t), &rb->memptrs_desc);
if (status != GSL_SUCCESS)
{
kgsl_ringbuffer_close(rb);
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_init. Return value %B\n", status );
return (status);
}
// overlay structure on memptrs memory
rb->memptrs = (gsl_rbmemptrs_t *)rb->memptrs_desc.hostptr;
rb->flags |= GSL_FLAGS_INITIALIZED;
// validate command stream data when running in safe mode
if (device->flags & GSL_FLAGS_SAFEMODE)
{
gsl_driver.flags_debug |= GSL_DBGFLAGS_PM4CHECK;
}
// start ringbuffer
status = kgsl_ringbuffer_start(rb);
if (status != GSL_SUCCESS)
{
kgsl_ringbuffer_close(rb);
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_init. Return value %B\n", status );
return (status);
}
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_init. Return value %B\n", GSL_SUCCESS );
return (GSL_SUCCESS);
}
//----------------------------------------------------------------------------
int
kgsl_ringbuffer_close(gsl_ringbuffer_t *rb)
{
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE,
"--> int kgsl_ringbuffer_close(gsl_ringbuffer_t *rb=0x%08x)\n", rb );
GSL_RB_MUTEX_LOCK();
// stop ringbuffer
kgsl_ringbuffer_stop(rb);
// free buffer
if (rb->buffer_desc.hostptr)
{
kgsl_sharedmem_free0(&rb->buffer_desc, GSL_CALLER_PROCESSID_GET());
}
// free memory pointers
if (rb->memptrs_desc.hostptr)
{
kgsl_sharedmem_free0(&rb->memptrs_desc, GSL_CALLER_PROCESSID_GET());
}
rb->flags &= ~GSL_FLAGS_INITIALIZED;
GSL_RB_MUTEX_UNLOCK();
GSL_RB_MUTEX_FREE();
kos_memset(rb, 0, sizeof(gsl_ringbuffer_t));
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_close. Return value %B\n", GSL_SUCCESS );
return (GSL_SUCCESS);
}
//----------------------------------------------------------------------------
gsl_timestamp_t
kgsl_ringbuffer_issuecmds(gsl_device_t *device, int pmodeoff, unsigned int *cmds, int sizedwords, unsigned int pid)
{
gsl_ringbuffer_t *rb = &device->ringbuffer;
unsigned int pmodesizedwords;
unsigned int *ringcmds;
unsigned int timestamp;
pmodeoff = 0;
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE,
"--> gsl_timestamp_t kgsl_ringbuffer_issuecmds(gsl_device_t *device=0x%08x, int pmodeoff=%d, unsigned int *cmds=0x%08x, int sizedwords=%d, unsigned int pid=0x%08x)\n",
device, pmodeoff, cmds, sizedwords, pid );
if (!(device->ringbuffer.flags & GSL_FLAGS_STARTED))
{
return (0);
}
// set mmu pagetable
kgsl_mmu_setpagetable(device, pid);
KGSL_DEBUG(GSL_DBGFLAGS_PM4CHECK, kgsl_ringbuffer_checkpm4(cmds, sizedwords, pmodeoff));
KGSL_DEBUG(GSL_DBGFLAGS_PM4, KGSL_DEBUG_DUMPPM4(cmds, sizedwords));
// reserve space to temporarily turn off protected mode error checking if needed
pmodesizedwords = pmodeoff ? 8 : 0;
#if defined GSL_RB_TIMESTAMP_INTERUPT
pmodesizedwords += 2;
#endif
// allocate space in ringbuffer
ringcmds = kgsl_ringbuffer_addcmds(rb, pmodesizedwords + sizedwords + 6);
if (pmodeoff)
{
// disable protected mode error checking
*ringcmds++ = pm4_type3_packet(PM4_ME_INIT, 2);
*ringcmds++ = 0x00000080;
*ringcmds++ = 0x00000000;
}
// copy the cmds to the ringbuffer
kos_memcpy(ringcmds, cmds, (sizedwords << 2));
ringcmds += sizedwords;
if (pmodeoff)
{
*ringcmds++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1);
*ringcmds++ = 0;
// re-enable protected mode error checking
*ringcmds++ = pm4_type3_packet(PM4_ME_INIT, 2);
*ringcmds++ = 0x00000080;
*ringcmds++ = GSL_RB_PROTECTED_MODE_CONTROL;
}
// increment timestamp
rb->timestamp++;
timestamp = rb->timestamp;
// start-of-pipeline and end-of-pipeline timestamps
*ringcmds++ = pm4_type0_packet(mmCP_TIMESTAMP, 1);
*ringcmds++ = rb->timestamp;
*ringcmds++ = pm4_type3_packet(PM4_EVENT_WRITE, 3);
*ringcmds++ = CACHE_FLUSH_TS;
*ringcmds++ = device->memstore.gpuaddr + GSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp);
*ringcmds++ = rb->timestamp;
#if defined GSL_RB_TIMESTAMP_INTERUPT
*ringcmds++ = pm4_type3_packet(PM4_INTERRUPT, 1);
*ringcmds++ = 0x80000000;
#endif
KGSL_DEBUG(GSL_DBGFLAGS_DUMPX, KGSL_DEBUG_DUMPX(BB_DUMP_MEMWRITE, (unsigned int)((char*)ringcmds - ((pmodesizedwords + sizedwords + 6) << 2)), (unsigned int)((char*)ringcmds - ((pmodesizedwords + sizedwords + 6) << 2)), (pmodesizedwords + sizedwords + 6) << 2, "kgsl_ringbuffer_issuecmds"));
// issue the commands
kgsl_ringbuffer_submit(rb);
// stats
GSL_RB_STATS(rb->stats.wordstotal += sizedwords);
GSL_RB_STATS(rb->stats.issues++);
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_issuecmds. Return value %d\n", timestamp );
// return timestamp of issued commands
return (timestamp);
}
//----------------------------------------------------------------------------
int
kgsl_ringbuffer_issueibcmds(gsl_device_t *device, int drawctxt_index, gpuaddr_t ibaddr, int sizedwords, gsl_timestamp_t *timestamp, gsl_flags_t flags)
{
unsigned int link[3];
int dumpx_swap;
(void)dumpx_swap; // used only when BB_DUMPX is defined
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE,
"--> gsl_timestamp_t kgsl_ringbuffer_issueibcmds(gsl_device_t device=%0x%08x, int drawctxt_index=%d, gpuaddr_t ibaddr=0x%08x, int sizedwords=%d, gsl_timestamp_t *timestamp=0x%08x)\n",
device, drawctxt_index, ibaddr, sizedwords, timestamp );
if (!(device->ringbuffer.flags & GSL_FLAGS_STARTED))
{
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_issueibcmds. Return value %B\n", GSL_FAILURE );
return (GSL_FAILURE);
}
KOS_ASSERT(ibaddr);
KOS_ASSERT(sizedwords);
KGSL_DEBUG(GSL_DBGFLAGS_DUMPX, dumpx_swap = kgsl_dumpx_parse_ibs(ibaddr, sizedwords));
GSL_RB_MUTEX_LOCK();
// context switch if needed
kgsl_drawctxt_switch(device, &device->drawctxt[drawctxt_index], flags);
link[0] = PM4_HDR_INDIRECT_BUFFER_PFD;
link[1] = ibaddr;
link[2] = sizedwords;
*timestamp = kgsl_ringbuffer_issuecmds(device, 0, &link[0], 3, GSL_CALLER_PROCESSID_GET());
GSL_RB_MUTEX_UNLOCK();
// idle device when running in safe mode
if (device->flags & GSL_FLAGS_SAFEMODE)
{
device->ftbl.device_idle(device, GSL_TIMEOUT_DEFAULT);
}
else
{
KGSL_DEBUG(GSL_DBGFLAGS_DUMPX,
{
// insert wait for idle after every IB1
// this is conservative but works reliably and is ok even for performance simulations
device->ftbl.device_idle(device, GSL_TIMEOUT_DEFAULT);
});
}
KGSL_DEBUG(GSL_DBGFLAGS_DUMPX,
{
if(dumpx_swap)
{
KGSL_DEBUG_DUMPX( BB_DUMP_EXPORT_CBUF, 0, 0, 0, "resolve");
KGSL_DEBUG_DUMPX( BB_DUMP_FLUSH,0,0,0," ");
}
});
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_issueibcmds. Return value %B\n", GSL_SUCCESS );
return (GSL_SUCCESS);
}
//----------------------------------------------------------------------------
#ifdef _DEBUG
static void
kgsl_ringbuffer_debug(gsl_ringbuffer_t *rb, gsl_rb_debug_t *rb_debug)
{
kos_memset(rb_debug, 0, sizeof(gsl_rb_debug_t));
rb_debug->pm4_ucode_rel = PM4_MICROCODE_VERSION;
rb_debug->pfp_ucode_rel = PFP_MICROCODE_VERSION;
rb->device->ftbl.device_regread(rb->device, mmCP_RB_BASE, (unsigned int *)&rb_debug->cp_rb_base);
rb->device->ftbl.device_regread(rb->device, mmCP_RB_CNTL, (unsigned int *)&rb_debug->cp_rb_cntl);
rb->device->ftbl.device_regread(rb->device, mmCP_RB_RPTR_ADDR, (unsigned int *)&rb_debug->cp_rb_rptr_addr);
rb->device->ftbl.device_regread(rb->device, mmCP_RB_RPTR, (unsigned int *)&rb_debug->cp_rb_rptr);
rb->device->ftbl.device_regread(rb->device, mmCP_RB_WPTR, (unsigned int *)&rb_debug->cp_rb_wptr);
rb->device->ftbl.device_regread(rb->device, mmCP_RB_WPTR_BASE, (unsigned int *)&rb_debug->cp_rb_wptr_base);
rb->device->ftbl.device_regread(rb->device, mmSCRATCH_UMSK, (unsigned int *)&rb_debug->scratch_umsk);
rb->device->ftbl.device_regread(rb->device, mmSCRATCH_ADDR, (unsigned int *)&rb_debug->scratch_addr);
rb->device->ftbl.device_regread(rb->device, mmCP_ME_CNTL, (unsigned int *)&rb_debug->cp_me_cntl);
rb->device->ftbl.device_regread(rb->device, mmCP_ME_STATUS, (unsigned int *)&rb_debug->cp_me_status);
rb->device->ftbl.device_regread(rb->device, mmCP_DEBUG, (unsigned int *)&rb_debug->cp_debug);
rb->device->ftbl.device_regread(rb->device, mmCP_STAT, (unsigned int *)&rb_debug->cp_stat);
rb->device->ftbl.device_regread(rb->device, mmRBBM_STATUS, (unsigned int *)&rb_debug->rbbm_status);
rb_debug->sop_timestamp = kgsl_cmdstream_readtimestamp(rb->device->id, GSL_TIMESTAMP_CONSUMED);
rb_debug->eop_timestamp = kgsl_cmdstream_readtimestamp(rb->device->id, GSL_TIMESTAMP_RETIRED);
}
#endif
//----------------------------------------------------------------------------
int
kgsl_ringbuffer_querystats(gsl_ringbuffer_t *rb, gsl_rbstats_t *stats)
{
#ifdef GSL_STATS_RINGBUFFER
KOS_ASSERT(stats);
if (!(rb->flags & GSL_FLAGS_STARTED))
{
return (GSL_FAILURE);
}
kos_memcpy(stats, &rb->stats, sizeof(gsl_rbstats_t));
return (GSL_SUCCESS);
#else
// unreferenced formal parameters
(void) rb;
(void) stats;
return (GSL_FAILURE_NOTSUPPORTED);
#endif // GSL_STATS_RINGBUFFER
}
//----------------------------------------------------------------------------
int
kgsl_ringbuffer_bist(gsl_ringbuffer_t *rb)
{
unsigned int *cmds;
unsigned int temp, k, j;
int status;
int i;
#ifdef _DEBUG
gsl_rb_debug_t rb_debug;
#endif
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE,
"--> int kgsl_ringbuffer_bist(gsl_ringbuffer_t *rb=0x%08x)\n", rb );
if (!(rb->flags & GSL_FLAGS_STARTED))
{
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_bist. Return value %d\n", GSL_FAILURE );
return (GSL_FAILURE);
}
// simple nop submit
cmds = kgsl_ringbuffer_addcmds(rb, 2);
if (!cmds)
{
#ifdef _DEBUG
kgsl_ringbuffer_debug(rb, &rb_debug);
#endif
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_bist. Return value %d\n", GSL_FAILURE );
return (GSL_FAILURE);
}
GSL_RB_WRITE(cmds, pm4_nop_packet(1));
GSL_RB_WRITE(cmds, 0xDEADBEEF);
kgsl_ringbuffer_submit(rb);
status = rb->device->ftbl.device_idle(rb->device, GSL_TIMEOUT_DEFAULT);
if (status != GSL_SUCCESS)
{
#ifdef _DEBUG
kgsl_ringbuffer_debug(rb, &rb_debug);
#endif
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_bist. Return value %d\n", status );
return (status);
}
// simple scratch submit
cmds = kgsl_ringbuffer_addcmds(rb, 2);
if (!cmds)
{
#ifdef _DEBUG
kgsl_ringbuffer_debug(rb, &rb_debug);
#endif
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_bist. Return value %d\n", GSL_FAILURE );
return (GSL_FAILURE);
}
GSL_RB_WRITE(cmds, pm4_type0_packet(mmSCRATCH_REG7, 1));
GSL_RB_WRITE(cmds, 0xFEEDF00D);
kgsl_ringbuffer_submit(rb);
status = rb->device->ftbl.device_idle(rb->device, GSL_TIMEOUT_DEFAULT);
if (status != GSL_SUCCESS)
{
#ifdef _DEBUG
kgsl_ringbuffer_debug(rb, &rb_debug);
#endif
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_bist. Return value %d\n", status );
return (status);
}
rb->device->ftbl.device_regread(rb->device, mmSCRATCH_REG7, &temp);
if (temp != 0xFEEDF00D)
{
#ifdef _DEBUG
kgsl_ringbuffer_debug(rb, &rb_debug);
#endif
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_bist. Return value %d\n", GSL_FAILURE );
return (GSL_FAILURE);
}
// simple wraps
for (i = 0; i < 256; i+=2)
{
j = ((rb->sizedwords >> 2) - 256) + i;
cmds = kgsl_ringbuffer_addcmds(rb, j);
if (!cmds)
{
#ifdef _DEBUG
kgsl_ringbuffer_debug(rb, &rb_debug);
#endif
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_bist. Return value %d\n", GSL_FAILURE );
return (GSL_FAILURE);
}
k = 0;
while (k < j)
{
k+=2;
GSL_RB_WRITE(cmds, pm4_type0_packet(mmSCRATCH_REG7, 1));
GSL_RB_WRITE(cmds, k);
}
kgsl_ringbuffer_submit(rb);
status = rb->device->ftbl.device_idle(rb->device, GSL_TIMEOUT_DEFAULT);
if (status != GSL_SUCCESS)
{
#ifdef _DEBUG
kgsl_ringbuffer_debug(rb, &rb_debug);
#endif
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_bist. Return value %d\n", status );
return (status);
}
rb->device->ftbl.device_regread(rb->device, mmSCRATCH_REG7, &temp);
if (temp != k)
{
#ifdef _DEBUG
kgsl_ringbuffer_debug(rb, &rb_debug);
#endif
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_bist. Return value %d\n", GSL_FAILURE );
return (GSL_FAILURE);
}
}
// max size submits, TODO do this at least with regreads
for (i = 0; i < 256; i++)
{
cmds = kgsl_ringbuffer_addcmds(rb, (rb->sizedwords >> 2));
if (!cmds)
{
#ifdef _DEBUG
kgsl_ringbuffer_debug(rb, &rb_debug);
#endif
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_bist. Return value %d\n", GSL_FAILURE );
return (GSL_FAILURE);
}
GSL_RB_WRITE(cmds, pm4_nop_packet((rb->sizedwords >> 2) - 1));
kgsl_ringbuffer_submit(rb);
status = rb->device->ftbl.device_idle(rb->device, GSL_TIMEOUT_DEFAULT);
if (status != GSL_SUCCESS)
{
#ifdef _DEBUG
kgsl_ringbuffer_debug(rb, &rb_debug);
#endif
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_bist. Return value %d\n", status );
return (status);
}
}
// submit load with randomness
#ifdef GSL_RB_USE_MEM_TIMESTAMP
// scratch memptr validate
#endif // GSL_RB_USE_MEM_TIMESTAMP
#ifdef GSL_RB_USE_MEM_RPTR
// rptr memptr validate
#endif // GSL_RB_USE_MEM_RPTR
#ifdef GSL_RB_USE_WPTR_POLLING
// wptr memptr validate
#endif // GSL_RB_USE_WPTR_POLLING
kgsl_log_write( KGSL_LOG_GROUP_COMMAND | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_ringbuffer_bist. Return value %d\n", GSL_SUCCESS );
return (GSL_SUCCESS);
}
#endif