amd-gpu: Z160 context rework

* gsl_drawctxt_t -> kgsl_drawctxt (this touches some Z430 stuff too)
* gsl_z1xx_t et al -> kgsl_z1xx
* move some defines to includes
* use symbolic values in addmarker/beginpacket
* remove kgsl_context and opencode it's usage in ioctls etc.
* rename context_* ftbl functions to device_context_* like Qualcomm .35
* add kgsl_g12_cmdstream.c and kgsl_g12_drawctxt.c like Qualcomms .32
  but retain functionality from our versions of these functions

behavior change:

* under fbdev, tiger and es11ex work fine most of the time
  - es11ex will soft-lockup occasionally
* under imxng, tiger locks occasionally when moving the mouse pointer
  - I thought this bug was fixed
* under imxng, es11ex locks after good 30 seconds
  - but does NOT hang the system anymore (strange)

Since some gsl_driver.lock usage was moved I wonder if this is the
source of our race condition?
This commit is contained in:
Matt Sealey
2012-11-30 13:16:24 -06:00
parent 340b0e2ad3
commit 90fc28dc4f
12 changed files with 554 additions and 465 deletions

View File

@@ -1,11 +1,12 @@
obj-$(CONFIG_MXC_KGSL) += mxc_kgsl.o
mxc_kgsl-objs += kgsl_cmdstream.o \
kgsl_cmdwindow.o \
kgsl_context.o \
kgsl_device.o \
kgsl_drawctxt.o \
kgsl_driver.o \
kgsl_g12.o \
kgsl_g12_cmdstream.o \
kgsl_g12_drawctxt.o \
kgsl_intrmgr.o \
kgsl_memmgr.o \
kgsl_mmu.o \

View File

@@ -1,87 +0,0 @@
/* Copyright (c) 2008-2010, Advanced Micro Devices. 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 "kgsl_types.h"
#include "kgsl_mmu.h"
#include "kgsl_buildconfig.h"
#include "kgsl_hal.h"
#include "kgsl_halconfig.h"
#include "kgsl_memmgr.h"
#include "kgsl_sharedmem.h"
#include "kgsl_properties.h"
#include "kgsl_intrmgr.h"
#include "kgsl_ringbuffer.h"
#include "kgsl_drawctxt.h"
#include "kgsl_cmdwindow.h"
#include "kgsl_device.h"
#include "kgsl_driver.h"
#include "kgsl_linux_map.h"
#include "kgsl_hwaccess.h"
//////////////////////////////////////////////////////////////////////////////
// functions
//////////////////////////////////////////////////////////////////////////////
int
kgsl_context_create(unsigned int device_id, unsigned int type, unsigned int *drawctxt_id, unsigned int flags)
{
struct kgsl_device* device = &gsl_driver.device[device_id-1];
int status;
mutex_lock(&gsl_driver.lock);
if (device->ftbl.context_create)
{
status = device->ftbl.context_create(device, type, drawctxt_id, flags);
}
else
{
status = GSL_FAILURE;
}
mutex_unlock(&gsl_driver.lock);
return status;
}
//----------------------------------------------------------------------------
int
kgsl_context_destroy(unsigned int device_id, unsigned int drawctxt_id)
{
struct kgsl_device* device = &gsl_driver.device[device_id-1];
int status;
mutex_lock(&gsl_driver.lock);
if (device->ftbl.context_destroy)
{
status = device->ftbl.context_destroy(device, drawctxt_id);
}
else
{
status = GSL_FAILURE;
}
mutex_unlock(&gsl_driver.lock);
return status;
}
//----------------------------------------------------------------------------

View File

@@ -70,8 +70,8 @@ struct kgsl_functable {
int (*mmu_tlbinvalidate) (struct kgsl_device *device, unsigned int reg_invalidate, unsigned int pid);
int (*mmu_setpagetable) (struct kgsl_device *device, unsigned int reg_ptbase, uint32_t ptbase, unsigned int pid);
int (*cmdstream_issueibcmds) (struct kgsl_device *device, int drawctxt_index, uint32_t ibaddr, int sizedwords, unsigned int *timestamp, unsigned int flags);
int (*context_create) (struct kgsl_device *device, unsigned int type, unsigned int *drawctxt_id, unsigned int flags);
int (*context_destroy) (struct kgsl_device *device_id, unsigned int drawctxt_id);
int (*device_drawctxt_create) (struct kgsl_device *device, unsigned int type, unsigned int *drawctxt_id, unsigned int flags);
int (*device_drawctxt_destroy) (struct kgsl_device *device_id, unsigned int drawctxt_id);
};
#define GSL_CALLER_PROCESS_MAX 64

View File

@@ -119,8 +119,4 @@ int kgsl_drawctxt_destroy(struct kgsl_device* device, unsigned int drawctxt_
int kgsl_drawctxt_bind_gmem_shadow(unsigned int device_id, unsigned int drawctxt_id, const struct kgsl_gmem_desc* gmem_rect, unsigned int shadow_x, unsigned int shadow_y, const struct kgsl_buffer_desc* shadow_buffer, unsigned int buffer_id);
/* these are in the wrong place..! */
int kgsl_context_create(unsigned int device_id, unsigned int type, unsigned int *drawctxt_id, unsigned int flags);
int kgsl_context_destroy(unsigned int device_id, unsigned int drawctxt_id);
#endif // __GSL_DRAWCTXT_H

View File

@@ -26,6 +26,8 @@
#include "kgsl_sharedmem.h"
#include "kgsl_driver.h"
#include "kgsl_ioctl.h"
#include "kgsl_g12_drawctxt.h"
#include "kgsl_g12_cmdstream.h"
#include "g12_reg.h"
#include "kgsl_g12_vgv3types.h"
@@ -36,15 +38,9 @@
#define GSL_IRQ_TIMEOUT 200
int kgsl_g12_regread(struct kgsl_device *device, unsigned int offsetwords, unsigned int *value);
int kgsl_g12_regwrite(struct kgsl_device *device, unsigned int offsetwords, unsigned int value);
//----------------------------------------------------------------------------
#define GSL_HAL_NUMCMDBUFFERS 5
#define GSL_HAL_CMDBUFFERSIZE (1024 + 13) * sizeof(unsigned int)
/* G12 MH arbiter config*/
#define KGSL_G12_CFG_G12_MHARB \
(0x10 \
@@ -63,82 +59,9 @@ int kgsl_g12_regwrite(struct kgsl_device *device, unsigned int offsetwords, unsi
| (1 << MH_ARBITER_CONFIG__RB_CLNT_ENABLE__SHIFT) \
| (1 << MH_ARBITER_CONFIG__PA_CLNT_ENABLE__SHIFT))
#define ALIGN_IN_BYTES( dim, alignment ) ( ( (dim) + (alignment-1) ) & ~(alignment-1) )
#ifdef _Z180
#define NUMTEXUNITS 4
#define TEXUNITREGCOUNT 25
#define VG_REGCOUNT 0x39
#define GSL_HAL_EDGE0BUFSIZE 0x3E8+64
#define GSL_HAL_EDGE1BUFSIZE 0x8000+64
#define GSL_HAL_EDGE2BUFSIZE 0x80020+64
#define GSL_HAL_EDGE0REG ADDR_VGV1_CBUF
#define GSL_HAL_EDGE1REG ADDR_VGV1_BBUF
#define GSL_HAL_EDGE2REG ADDR_VGV1_EBUF
#else
#define NUMTEXUNITS 2
#define TEXUNITREGCOUNT 24
#define VG_REGCOUNT 0x3A
#define L1TILESIZE 64
#define GSL_HAL_EDGE0BUFSIZE L1TILESIZE*L1TILESIZE*4+64
#define GSL_HAL_EDGE1BUFSIZE L1TILESIZE*L1TILESIZE*16+64
#define GSL_HAL_EDGE0REG ADDR_VGV1_CBASE1
#define GSL_HAL_EDGE1REG ADDR_VGV1_UBASE2
#endif
#define PACKETSIZE_BEGIN 3
#define PACKETSIZE_G2DCOLOR 2
#define PACKETSIZE_TEXUNIT (TEXUNITREGCOUNT*2)
#define PACKETSIZE_REG (VG_REGCOUNT*2)
#define PACKETSIZE_STATE (PACKETSIZE_TEXUNIT*NUMTEXUNITS + PACKETSIZE_REG + PACKETSIZE_BEGIN + PACKETSIZE_G2DCOLOR)
#define PACKETSIZE_STATESTREAM ALIGN_IN_BYTES((PACKETSIZE_STATE*sizeof(unsigned int)), 32) / sizeof(unsigned int)
//----------------------------------------------------------------------------
typedef struct
{
unsigned int id;
// unsigned int regs[];
}gsl_hal_z1xxdrawctx_t;
typedef struct
{
unsigned int offs;
unsigned int curr;
unsigned int prevctx;
struct kgsl_memdesc e0;
struct kgsl_memdesc e1;
struct kgsl_memdesc e2;
unsigned int* cmdbuf[GSL_HAL_NUMCMDBUFFERS];
struct kgsl_memdesc cmdbufdesc[GSL_HAL_NUMCMDBUFFERS];
unsigned int timestamp[GSL_HAL_NUMCMDBUFFERS];
unsigned int numcontext;
unsigned int nextUniqueContextID;
}gsl_z1xx_t;
static gsl_z1xx_t g_z1xx = {0};
extern int z160_version;
//----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////
// functions
//////////////////////////////////////////////////////////////////////////////
static int kgsl_g12_addtimestamp(struct kgsl_device* device, unsigned int *timestamp);
static int kgsl_g12_issueibcmds(struct kgsl_device* device, int drawctxt_index, uint32_t ibaddr, int sizedwords, unsigned int *timestamp, unsigned int flags);
static int kgsl_g12_context_create(struct kgsl_device* device, unsigned int type, unsigned int *drawctxt_id, unsigned int flags);
static int kgsl_g12_context_destroy(struct kgsl_device* device, unsigned int drawctxt_id);
static unsigned int drawctx_id = 0;
static int kgsl_g12_idle(struct kgsl_device *device, unsigned int timeout);
//----------------------------------------------------------------------------
void
kgsl_g12_intrcallback(gsl_intrid_t id, void *cookie)
{
@@ -172,8 +95,6 @@ kgsl_g12_intrcallback(gsl_intrid_t id, void *cookie)
}
}
//----------------------------------------------------------------------------
int
kgsl_g12_isr(struct kgsl_device *device)
{
@@ -206,8 +127,6 @@ kgsl_g12_isr(struct kgsl_device *device)
return (GSL_SUCCESS);
}
//----------------------------------------------------------------------------
int
kgsl_g12_tlbinvalidate(struct kgsl_device *device, unsigned int reg_invalidate, unsigned int pid)
{
@@ -225,8 +144,6 @@ kgsl_g12_tlbinvalidate(struct kgsl_device *device, unsigned int reg_invalidate,
return (GSL_SUCCESS);
}
//----------------------------------------------------------------------------
int
kgsl_g12_setpagetable(struct kgsl_device *device, unsigned int reg_ptbase, uint32_t ptbase, unsigned int pid)
{
@@ -243,8 +160,6 @@ kgsl_g12_setpagetable(struct kgsl_device *device, unsigned int reg_ptbase, uint3
return (GSL_SUCCESS);
}
//----------------------------------------------------------------------------
static void kgsl_g12_updatetimestamp(struct kgsl_device *device)
{
unsigned int count = 0;
@@ -262,8 +177,6 @@ static void kgsl_g12_updatetimestamp(struct kgsl_device *device)
kgsl_sharedmem_write0(&device->memstore, KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp), &device->timestamp, 4, 0);
}
//----------------------------------------------------------------------------
static void kgsl_g12_irqtask(struct work_struct *work)
{
struct kgsl_device *device = &gsl_driver.device[KGSL_DEVICE_G12-1];
@@ -278,8 +191,6 @@ static void kgsl_g12_irqerr(struct work_struct *work)
}
//----------------------------------------------------------------------------
int
kgsl_g12_init(struct kgsl_device *device)
{
@@ -336,8 +247,6 @@ kgsl_g12_init(struct kgsl_device *device)
return (status);
}
//----------------------------------------------------------------------------
int
kgsl_g12_close(struct kgsl_device *device)
{
@@ -379,14 +288,12 @@ kgsl_g12_close(struct kgsl_device *device)
DEBUG_ASSERT(g_z1xx.numcontext == 0);
memset(&g_z1xx, 0, sizeof(gsl_z1xx_t));
memset(&g_z1xx, 0, sizeof(struct kgsl_g12_z1xx));
}
return (GSL_SUCCESS);
}
//----------------------------------------------------------------------------
int
kgsl_g12_destroy(struct kgsl_device *device)
{
@@ -415,8 +322,6 @@ kgsl_g12_destroy(struct kgsl_device *device)
return (GSL_SUCCESS);
}
//----------------------------------------------------------------------------
int
kgsl_g12_start(struct kgsl_device *device, unsigned int flags)
{
@@ -441,8 +346,6 @@ kgsl_g12_start(struct kgsl_device *device, unsigned int flags)
return (status);
}
//----------------------------------------------------------------------------
int
kgsl_g12_stop(struct kgsl_device *device)
{
@@ -460,8 +363,6 @@ kgsl_g12_stop(struct kgsl_device *device)
return (status);
}
//----------------------------------------------------------------------------
int
kgsl_g12_getproperty(struct kgsl_device *device, gsl_property_type_t type, void *value, unsigned int sizebytes)
{
@@ -491,8 +392,6 @@ kgsl_g12_getproperty(struct kgsl_device *device, gsl_property_type_t type, void
return (status);
}
//----------------------------------------------------------------------------
int
kgsl_g12_setproperty(struct kgsl_device *device, gsl_property_type_t type, void *value, unsigned int sizebytes)
{
@@ -517,8 +416,6 @@ kgsl_g12_setproperty(struct kgsl_device *device, gsl_property_type_t type, void
return (status);
}
//----------------------------------------------------------------------------
int
kgsl_g12_idle(struct kgsl_device *device, unsigned int timeout)
{
@@ -537,8 +434,6 @@ kgsl_g12_idle(struct kgsl_device *device, unsigned int timeout)
return (GSL_SUCCESS);
}
//----------------------------------------------------------------------------
int kgsl_g12_regread(struct kgsl_device *device, unsigned int offsetwords, unsigned int *value)
{
unsigned int *reg;
@@ -600,9 +495,6 @@ int kgsl_g12_regwrite(struct kgsl_device *device, unsigned int offsetwords, unsi
return GSL_SUCCESS;
}
//----------------------------------------------------------------------------
int
kgsl_g12_waitirq(struct kgsl_device *device, gsl_intrid_t intr_id, unsigned int *count, unsigned int timeout)
{
@@ -670,8 +562,6 @@ kgsl_g12_waitirq(struct kgsl_device *device, gsl_intrid_t intr_id, unsigned int
return (status);
}
//----------------------------------------------------------------------------
int
kgsl_g12_waittimestamp(struct kgsl_device *device, unsigned int timestamp, unsigned int timeout)
{
@@ -687,255 +577,26 @@ kgsl_g12_waittimestamp(struct kgsl_device *device, unsigned int timestamp, unsig
int
kgsl_g12_getfunctable(struct kgsl_functable *ftbl)
{
ftbl->init = kgsl_g12_init;
ftbl->close = kgsl_g12_close;
ftbl->destroy = kgsl_g12_destroy;
ftbl->start = kgsl_g12_start;
ftbl->stop = kgsl_g12_stop;
ftbl->getproperty = kgsl_g12_getproperty;
ftbl->setproperty = kgsl_g12_setproperty;
ftbl->idle = kgsl_g12_idle;
ftbl->regread = kgsl_g12_regread;
ftbl->regwrite = kgsl_g12_regwrite;
ftbl->waitirq = kgsl_g12_waitirq;
ftbl->waittimestamp = kgsl_g12_waittimestamp;
ftbl->runpending = NULL;
ftbl->addtimestamp = kgsl_g12_addtimestamp;
ftbl->intr_isr = kgsl_g12_isr;
ftbl->mmu_tlbinvalidate = kgsl_g12_tlbinvalidate;
ftbl->mmu_setpagetable = kgsl_g12_setpagetable;
ftbl->cmdstream_issueibcmds = kgsl_g12_issueibcmds;
ftbl->context_create = kgsl_g12_context_create;
ftbl->context_destroy = kgsl_g12_context_destroy;
ftbl->init = kgsl_g12_init;
ftbl->close = kgsl_g12_close;
ftbl->destroy = kgsl_g12_destroy;
ftbl->start = kgsl_g12_start;
ftbl->stop = kgsl_g12_stop;
ftbl->getproperty = kgsl_g12_getproperty;
ftbl->setproperty = kgsl_g12_setproperty;
ftbl->idle = kgsl_g12_idle;
ftbl->regread = kgsl_g12_regread;
ftbl->regwrite = kgsl_g12_regwrite;
ftbl->waitirq = kgsl_g12_waitirq;
ftbl->waittimestamp = kgsl_g12_waittimestamp;
ftbl->runpending = NULL;
ftbl->addtimestamp = kgsl_g12_addtimestamp;
ftbl->intr_isr = kgsl_g12_isr;
ftbl->mmu_tlbinvalidate = kgsl_g12_tlbinvalidate;
ftbl->mmu_setpagetable = kgsl_g12_setpagetable;
ftbl->cmdstream_issueibcmds = kgsl_g12_issueibcmds;
ftbl->device_drawctxt_create = kgsl_g12_drawctxt_create;
ftbl->device_drawctxt_destroy = kgsl_g12_drawctxt_destroy;
return (GSL_SUCCESS);
}
//----------------------------------------------------------------------------
static void addmarker(gsl_z1xx_t* z1xx)
{
DEBUG_ASSERT(z1xx);
{
unsigned int *p = z1xx->cmdbuf[z1xx->curr];
/* todo: use symbolic values */
p[z1xx->offs++] = 0x7C000176;
p[z1xx->offs++] = (0x8000|5);
p[z1xx->offs++] = ADDR_VGV3_LAST<<24;
p[z1xx->offs++] = ADDR_VGV3_LAST<<24;
p[z1xx->offs++] = ADDR_VGV3_LAST<<24;
p[z1xx->offs++] = 0x7C000176;
p[z1xx->offs++] = 5;
p[z1xx->offs++] = ADDR_VGV3_LAST<<24;
p[z1xx->offs++] = ADDR_VGV3_LAST<<24;
p[z1xx->offs++] = ADDR_VGV3_LAST<<24;
}
}
//----------------------------------------------------------------------------
static void beginpacket(gsl_z1xx_t* z1xx, uint32_t cmd, unsigned int nextcnt)
{
unsigned int *p = z1xx->cmdbuf[z1xx->curr];
p[z1xx->offs++] = 0x7C000176;
p[z1xx->offs++] = 5;
p[z1xx->offs++] = ADDR_VGV3_LAST<<24;
p[z1xx->offs++] = ADDR_VGV3_LAST<<24;
p[z1xx->offs++] = ADDR_VGV3_LAST<<24;
p[z1xx->offs++] = 0x7C000275;
p[z1xx->offs++] = cmd;
p[z1xx->offs++] = 0x1000|nextcnt; // nextcount
p[z1xx->offs++] = ADDR_VGV3_LAST<<24;
p[z1xx->offs++] = ADDR_VGV3_LAST<<24;
}
//----------------------------------------------------------------------------
static int
kgsl_g12_issueibcmds(struct kgsl_device* device, int drawctxt_index, uint32_t ibaddr, int sizedwords, unsigned int *timestamp, unsigned int flags)
{
unsigned int ofs = PACKETSIZE_STATESTREAM*sizeof(unsigned int);
unsigned int cnt = 5;
unsigned int cmd = ibaddr;
unsigned int nextbuf = (g_z1xx.curr+1)%GSL_HAL_NUMCMDBUFFERS;
unsigned int nextaddr = g_z1xx.cmdbufdesc[nextbuf].gpuaddr;
unsigned int nextcnt = 0x9000|5;
struct kgsl_memdesc tmp = {0};
unsigned int processed_timestamp;
(void) flags;
// read what is the latest timestamp device have processed
KGSL_CMDSTREAM_GET_EOP_TIMESTAMP(device, (int *)&processed_timestamp);
/* wait for the next buffer's timestamp to occur */
while(processed_timestamp < g_z1xx.timestamp[nextbuf])
{
kgsl_cmdstream_waittimestamp(device->id, g_z1xx.timestamp[nextbuf], 1000);
KGSL_CMDSTREAM_GET_EOP_TIMESTAMP(device, (int *)&processed_timestamp);
}
*timestamp = g_z1xx.timestamp[nextbuf] = device->current_timestamp + 1;
/* context switch */
if (drawctxt_index != (int)g_z1xx.prevctx)
{
cnt = PACKETSIZE_STATESTREAM;
ofs = 0;
}
g_z1xx.prevctx = drawctxt_index;
g_z1xx.offs = 10;
beginpacket(&g_z1xx, cmd+ofs, cnt);
tmp.gpuaddr=ibaddr+(sizedwords*sizeof(unsigned int));
kgsl_sharedmem_write0(&tmp, 4, &nextaddr, 4, false);
kgsl_sharedmem_write0(&tmp, 8, &nextcnt, 4, false);
/* sync mem */
kgsl_sharedmem_write0((const struct kgsl_memdesc *)&g_z1xx.cmdbufdesc[g_z1xx.curr], 0, g_z1xx.cmdbuf[g_z1xx.curr], (512 + 13) * sizeof(unsigned int), false);
g_z1xx.offs = 0;
g_z1xx.curr = nextbuf;
/* increment mark counter */
#ifdef V3_SYNC
if (device->timestamp == device->current_timestamp)
{
kgsl_cmdwindow_write0(2, GSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, flags);
kgsl_cmdwindow_write0(2, GSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, 0);
}
#else
kgsl_cmdwindow_write0(2, GSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, flags);
kgsl_cmdwindow_write0(2, GSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, 0);
#endif
/* increment consumed timestamp */
device->current_timestamp++;
kgsl_sharedmem_write0(&device->memstore, KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp), &device->current_timestamp, 4, 0);
return (GSL_SUCCESS);
}
//----------------------------------------------------------------------------
static int
kgsl_g12_context_create(struct kgsl_device* device, unsigned int type, unsigned int *drawctxt_id, unsigned int flags)
{
int status = 0;
int i;
int cmd;
unsigned int gslflags = (GSL_MEMFLAGS_CONPHYS | GSL_MEMFLAGS_ALIGNPAGE);
// unreferenced formal parameters
(void) device;
(void) type;
//(void) drawctxt_id;
(void) flags;
kgsl_device_active(device);
if (g_z1xx.numcontext==0)
{
g_z1xx.nextUniqueContextID = 0;
/* todo: move this to device create or start. Error checking!! */
for (i=0;i<GSL_HAL_NUMCMDBUFFERS;i++)
{
status = kgsl_sharedmem_alloc0(KGSL_DEVICE_ANY, gslflags, GSL_HAL_CMDBUFFERSIZE, &g_z1xx.cmdbufdesc[i]);
DEBUG_ASSERT(status == GSL_SUCCESS);
g_z1xx.cmdbuf[i]=kmalloc(GSL_HAL_CMDBUFFERSIZE, GFP_KERNEL);
DEBUG_ASSERT(g_z1xx.cmdbuf[i]);
memset((void*)g_z1xx.cmdbuf[i], 0, GSL_HAL_CMDBUFFERSIZE);
g_z1xx.curr = i;
g_z1xx.offs = 0;
addmarker(&g_z1xx);
status = kgsl_sharedmem_write0(&g_z1xx.cmdbufdesc[i],0, g_z1xx.cmdbuf[i], (512 + 13) * sizeof(unsigned int), false);
DEBUG_ASSERT(status == GSL_SUCCESS);
}
g_z1xx.curr = 0;
cmd = VGV3_NEXTCMD_JUMP << VGV3_NEXTCMD_NEXTCMD_FSHIFT;
/* set cmd stream buffer to hw */
status |= kgsl_cmdwindow_write0(KGSL_DEVICE_G12, GSL_CMDWINDOW_2D, ADDR_VGV3_MODE, 4);
status |= kgsl_cmdwindow_write0(KGSL_DEVICE_G12, GSL_CMDWINDOW_2D, ADDR_VGV3_NEXTADDR, g_z1xx.cmdbufdesc[0].gpuaddr );
status |= kgsl_cmdwindow_write0(KGSL_DEVICE_G12, GSL_CMDWINDOW_2D, ADDR_VGV3_NEXTCMD, cmd | 5);
DEBUG_ASSERT(status == GSL_SUCCESS);
/* Edge buffer setup todo: move register setup to own function.
This function can be then called, if power managemnet is used and clocks are turned off and then on.
*/
status |= kgsl_sharedmem_alloc0(KGSL_DEVICE_ANY, gslflags, GSL_HAL_EDGE0BUFSIZE, &g_z1xx.e0);
status |= kgsl_sharedmem_alloc0(KGSL_DEVICE_ANY, gslflags, GSL_HAL_EDGE1BUFSIZE, &g_z1xx.e1);
status |= kgsl_sharedmem_set0(&g_z1xx.e0, 0, 0, GSL_HAL_EDGE0BUFSIZE);
status |= kgsl_sharedmem_set0(&g_z1xx.e1, 0, 0, GSL_HAL_EDGE1BUFSIZE);
status |= kgsl_cmdwindow_write0(KGSL_DEVICE_G12, GSL_CMDWINDOW_2D, GSL_HAL_EDGE0REG, g_z1xx.e0.gpuaddr);
status |= kgsl_cmdwindow_write0(KGSL_DEVICE_G12, GSL_CMDWINDOW_2D, GSL_HAL_EDGE1REG, g_z1xx.e1.gpuaddr);
#ifdef _Z180
kgsl_sharedmem_alloc0(KGSL_DEVICE_ANY, gslflags, GSL_HAL_EDGE2BUFSIZE, &g_z1xx.e2);
kgsl_sharedmem_set0(&g_z1xx.e2, 0, 0, GSL_HAL_EDGE2BUFSIZE);
kgsl_cmdwindow_write0(KGSL_DEVICE_G12, GSL_CMDWINDOW_2D, GSL_HAL_EDGE2REG, g_z1xx.e2.gpuaddr);
#endif
DEBUG_ASSERT(status == GSL_SUCCESS);
}
if(g_z1xx.numcontext < GSL_CONTEXT_MAX)
{
g_z1xx.numcontext++;
g_z1xx.nextUniqueContextID++;
*drawctxt_id=g_z1xx.nextUniqueContextID;
status = GSL_SUCCESS;
}
else
{
status = GSL_FAILURE;
}
return status;
}
//----------------------------------------------------------------------------
static int
kgsl_g12_context_destroy(struct kgsl_device* device, unsigned int drawctxt_id)
{
// unreferenced formal parameters
(void) device;
(void) drawctxt_id;
g_z1xx.numcontext--;
if (g_z1xx.numcontext<0)
{
g_z1xx.numcontext=0;
return (GSL_FAILURE);
}
if (g_z1xx.numcontext==0)
{
int i;
for (i=0;i<GSL_HAL_NUMCMDBUFFERS;i++)
{
kgsl_sharedmem_free0(&g_z1xx.cmdbufdesc[i], current->tgid);
kfree(g_z1xx.cmdbuf[i]);
}
kgsl_sharedmem_free0(&g_z1xx.e0, current->tgid);
kgsl_sharedmem_free0(&g_z1xx.e1, current->tgid);
#ifdef _Z180
kgsl_sharedmem_free0(&g_z1xx.e2, current->tgid);
#endif
}
return (GSL_SUCCESS);
}
//----------------------------------------------------------------------------
static int
kgsl_g12_addtimestamp(struct kgsl_device* device, unsigned int *timestamp)
{
device->current_timestamp++;
*timestamp = device->current_timestamp;
return (GSL_SUCCESS);
return GSL_SUCCESS;
}

View File

@@ -0,0 +1,139 @@
/* Copyright (c) 2002,2007-2010, 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 <linux/delay.h>
#include <linux/sched.h>
#include <linux/io.h>
#include "kgsl_types.h"
#include "kgsl_hal.h"
#include "kgsl_cmdstream.h"
#include "kgsl_sharedmem.h"
#include "kgsl_driver.h"
#include "kgsl_ioctl.h"
#include "kgsl_g12_drawctxt.h"
#include "g12_reg.h"
#include "kgsl_g12_vgv3types.h"
#ifdef CONFIG_ARCH_MX35
#define V3_SYNC
#endif
static void beginpacket(struct kgsl_g12_z1xx* z1xx, uint32_t cmd, unsigned int nextcount)
{
unsigned int *p = z1xx->cmdbuf[z1xx->curr];
p[z1xx->offs++] = KGSL_G12_STREAM_PACKET;
p[z1xx->offs++] = 5;
p[z1xx->offs++] = ADDR_VGV3_LAST << 24;
p[z1xx->offs++] = ADDR_VGV3_LAST << 24;
p[z1xx->offs++] = ADDR_VGV3_LAST << 24;
p[z1xx->offs++] = KGSL_G12_STREAM_PACKET_CALL;
p[z1xx->offs++] = cmd;
p[z1xx->offs++] = KGSL_G12_CALL_CMD | nextcount;
p[z1xx->offs++] = ADDR_VGV3_LAST << 24;
p[z1xx->offs++] = ADDR_VGV3_LAST << 24;
}
int kgsl_g12_issueibcmds(struct kgsl_device* device, int drawctxt_index, uint32_t ibaddr,
int sizedwords, unsigned int *timestamp, unsigned int flags)
{
unsigned int ofs = PACKETSIZE_STATESTREAM * sizeof(unsigned int);
unsigned int cnt = 5;
unsigned int cmd = ibaddr;
unsigned int nextbuf = (g_z1xx.curr+1) % GSL_HAL_NUMCMDBUFFERS;
unsigned int nextaddr = g_z1xx.cmdbufdesc[nextbuf].gpuaddr;
unsigned int nextcnt = KGSL_G12_STREAM_END_CMD | 5;
struct kgsl_memdesc tmp = {0};
unsigned int processed_timestamp;
(void) flags;
/* read what is the latest timestamp device have processed */
/* note: diverge from qcom */
KGSL_CMDSTREAM_GET_EOP_TIMESTAMP(device, (int *)&processed_timestamp);
/* wait for the next buffer's timestamp to occur - note: diverge */
while(processed_timestamp < g_z1xx.timestamp[nextbuf]) {
kgsl_cmdstream_waittimestamp(device->id, g_z1xx.timestamp[nextbuf], 1000);
KGSL_CMDSTREAM_GET_EOP_TIMESTAMP(device, (int *)&processed_timestamp);
}
// QCOM
// tmp.hostptr = (void *) *timestamp;
// device->current_timestamp++;
// *timestamp = device->current_timestamp;
*timestamp = g_z1xx.timestamp[nextbuf] = device->current_timestamp + 1;
/* context switch */
if (drawctxt_index != (int) g_z1xx.prevctx) {
cnt = PACKETSIZE_STATESTREAM;
ofs = 0;
}
g_z1xx.prevctx = drawctxt_index;
g_z1xx.offs = 10;
beginpacket(&g_z1xx, cmd + ofs, cnt);
// tmp.hostptr = (void*)(tmp.hostptr + (sizedwords * sizeof(unsigned int)));
// tmp.size = 12;
tmp.gpuaddr = ibaddr + (sizedwords * sizeof(unsigned int));
kgsl_sharedmem_write0(&tmp, 4, &nextaddr, 4, false);
kgsl_sharedmem_write0(&tmp, 8, &nextcnt, 4, false);
/* sync mem */
kgsl_sharedmem_write0((const struct kgsl_memdesc *)
&g_z1xx.cmdbufdesc[g_z1xx.curr], 0,
g_z1xx.cmdbuf[g_z1xx.curr],
(512 + 13) * sizeof(unsigned int), false);
g_z1xx.offs = 0;
g_z1xx.curr = nextbuf;
/* this is Freescale code but it matches a .35 msm kernel too */
/* increment mark counter */
#ifdef V3_SYNC
if (device->timestamp == device->current_timestamp) {
kgsl_cmdwindow_write0(2, GSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, flags);
kgsl_cmdwindow_write0(2, GSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, 0);
}
#else
kgsl_cmdwindow_write0(2, GSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, flags);
kgsl_cmdwindow_write0(2, GSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, 0);
#endif
/* increment consumed timestamp */
device->current_timestamp++;
kgsl_sharedmem_write0(&device->memstore, KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp), &device->current_timestamp, 4, 0);
/* end FSL code */
return GSL_SUCCESS;
}
int kgsl_g12_addtimestamp(struct kgsl_device* device, unsigned int *timestamp)
{
device->current_timestamp++;
*timestamp = device->current_timestamp;
return GSL_SUCCESS;
}

View File

@@ -0,0 +1,50 @@
/* Copyright (c) 2002,2007-2010, Code Aurora Forum. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Code Aurora Forum, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _GSL_CMDSTREAM_H
#define _GSL_CMDSTREAM_H
#include <linux/types.h>
#include <linux/mutex.h>
#include "kgsl_device.h"
#include "kgsl_sharedmem.h"
struct kgsl_device;
int kgsl_g12_cmdstream_check_timestamp(struct kgsl_device *device,
unsigned int timestamp);
int kgsl_g12_cmdstream_issueibcmds(struct kgsl_device *device,
int drawctxt_index,
uint32_t ibaddr,
int sizedwords,
int *timestamp,
unsigned int flags);
int kgsl_g12_cmdstream_addtimestamp(struct kgsl_device *device,
int *timestamp);
#endif /* _GSL_CMDSTREAM_H */

View File

@@ -0,0 +1,178 @@
/* Copyright (c) 2002,2007-2010, 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 <linux/delay.h>
#include <linux/sched.h>
#include <linux/io.h>
#include "kgsl_g12_drawctxt.h"
#include "kgsl_types.h"
#include "kgsl_hal.h"
#include "kgsl_cmdstream.h"
#include "kgsl_sharedmem.h"
#include "kgsl_driver.h"
#include "kgsl_ioctl.h"
#include "kgsl_g12_vgv3types.h"
#include "g12_reg.h"
struct kgsl_g12_z1xx g_z1xx = {0};
static void addmarker(struct kgsl_g12_z1xx *z1xx)
{
if (z1xx) {
unsigned int *p = z1xx->cmdbuf[z1xx->curr];
p[z1xx->offs++] = KGSL_G12_STREAM_PACKET;
p[z1xx->offs++] = (KGSL_G12_MARKER_CMD | 5);
p[z1xx->offs++] = ADDR_VGV3_LAST << 24;
p[z1xx->offs++] = ADDR_VGV3_LAST << 24;
p[z1xx->offs++] = ADDR_VGV3_LAST << 24;
p[z1xx->offs++] = KGSL_G12_STREAM_PACKET;
p[z1xx->offs++] = 5;
p[z1xx->offs++] = ADDR_VGV3_LAST << 24;
p[z1xx->offs++] = ADDR_VGV3_LAST << 24;
p[z1xx->offs++] = ADDR_VGV3_LAST << 24;
}
}
int kgsl_g12_drawctxt_create(struct kgsl_device* device, unsigned int type, unsigned int *drawctxt_id, unsigned int flags)
{
int i;
int cmd;
int result;
unsigned int gslflags = (GSL_MEMFLAGS_CONPHYS | GSL_MEMFLAGS_ALIGNPAGE);
// unreferenced formal parameters
(void) device;
(void) type;
(void) flags;
kgsl_device_active(device);
if (g_z1xx.numcontext == 0) {
g_z1xx.nextUniqueContextID = 0;
/* todo: move this to device create or start. Error checking!! */
for (i = 0; i < GSL_HAL_NUMCMDBUFFERS; i++) {
if (kgsl_sharedmem_alloc0(KGSL_DEVICE_ANY, gslflags,
GSL_HAL_CMDBUFFERSIZE, &g_z1xx.cmdbufdesc[i]) != GSL_SUCCESS)
return GSL_FAILURE;
g_z1xx.cmdbuf[i] = kzalloc(GSL_HAL_CMDBUFFERSIZE, GFP_KERNEL);
g_z1xx.curr = i;
g_z1xx.offs = 0;
addmarker(&g_z1xx);
kgsl_sharedmem_write0(&g_z1xx.cmdbufdesc[i], 0, g_z1xx.cmdbuf[i],
(512 + 13) * sizeof(unsigned int), false);
}
g_z1xx.curr = 0;
cmd = VGV3_NEXTCMD_JUMP << VGV3_NEXTCMD_NEXTCMD_FSHIFT;
/* set cmd stream buffer to hw */
result = kgsl_cmdwindow_write0(KGSL_DEVICE_G12, GSL_CMDWINDOW_2D,
ADDR_VGV3_MODE, 4);
if (result != GSL_SUCCESS)
return result;
result = kgsl_cmdwindow_write0(KGSL_DEVICE_G12, GSL_CMDWINDOW_2D,
ADDR_VGV3_NEXTADDR,
g_z1xx.cmdbufdesc[0].gpuaddr );
if (result != GSL_SUCCESS)
return result;
result = kgsl_cmdwindow_write0(KGSL_DEVICE_G12, GSL_CMDWINDOW_2D,
ADDR_VGV3_NEXTCMD, cmd | 5);
if (result != GSL_SUCCESS)
return result;
/*
* NOTE: diverges from upstream Qualcomm code...!!!
* there are some cmdwindow writes to VGV3_CONTROL to add markers?
*/
/* NOTE: this may be done in Qualcomm's userspace...
*
* Edge buffer setup todo: move register setup to own function.
* This function can be then called, if power managemnet is used and clocks are turned off and then on.
*/
result = kgsl_sharedmem_alloc0(KGSL_DEVICE_ANY, gslflags, GSL_HAL_EDGE0BUFSIZE, &g_z1xx.e0);
if (result != GSL_SUCCESS)
return result;
result = kgsl_sharedmem_alloc0(KGSL_DEVICE_ANY, gslflags, GSL_HAL_EDGE1BUFSIZE, &g_z1xx.e1);
if (result != GSL_SUCCESS)
return result;
result = kgsl_sharedmem_set0(&g_z1xx.e0, 0, 0, GSL_HAL_EDGE0BUFSIZE);
if (result != GSL_SUCCESS)
return result;
result = kgsl_sharedmem_set0(&g_z1xx.e1, 0, 0, GSL_HAL_EDGE1BUFSIZE);
result = kgsl_cmdwindow_write0(KGSL_DEVICE_G12, GSL_CMDWINDOW_2D, GSL_HAL_EDGE0REG, g_z1xx.e0.gpuaddr);
if (result != GSL_SUCCESS)
return result;
result = kgsl_cmdwindow_write0(KGSL_DEVICE_G12, GSL_CMDWINDOW_2D, GSL_HAL_EDGE1REG, g_z1xx.e1.gpuaddr);
if (result != GSL_SUCCESS)
return result;
#ifdef _Z180
kgsl_sharedmem_alloc0(KGSL_DEVICE_ANY, gslflags, GSL_HAL_EDGE2BUFSIZE, &g_z1xx.e2);
kgsl_sharedmem_set0(&g_z1xx.e2, 0, 0, GSL_HAL_EDGE2BUFSIZE);
kgsl_cmdwindow_write0(KGSL_DEVICE_G12, GSL_CMDWINDOW_2D, GSL_HAL_EDGE2REG, g_z1xx.e2.gpuaddr);
#endif
}
/* diverge from qualcomm - it returns numcontext */
g_z1xx.numcontext++;
g_z1xx.nextUniqueContextID++;
*drawctxt_id = g_z1xx.nextUniqueContextID;
return GSL_SUCCESS;
}
int kgsl_g12_drawctxt_destroy(struct kgsl_device* device, unsigned int drawctxt_id)
{
(void) device;
(void) drawctxt_id;
g_z1xx.numcontext--;
if (g_z1xx.numcontext < 0) {
g_z1xx.numcontext=0;
return GSL_FAILURE;
}
if (g_z1xx.numcontext == 0) {
int i;
for (i = 0; i < GSL_HAL_NUMCMDBUFFERS; i++) {
kgsl_sharedmem_free0(&g_z1xx.cmdbufdesc[i], current->tgid);
kfree(g_z1xx.cmdbuf[i]);
}
/* remember, qualcomm's code doesn't have these edge buffers? */
kgsl_sharedmem_free0(&g_z1xx.e0, current->tgid);
kgsl_sharedmem_free0(&g_z1xx.e1, current->tgid);
#ifdef _Z180
kgsl_sharedmem_free0(&g_z1xx.e2, current->tgid);
#endif
}
return GSL_SUCCESS;
}

View File

@@ -0,0 +1,129 @@
/* Copyright (c) 2002,2007-2010, Code Aurora Forum. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Code Aurora Forum, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __GSL_DRAWCTXT_G12_H
#define __GSL_DRAWCTXT_G12_H
#include "kgsl_sharedmem.h"
struct kgsl_device;
#define GSL_HAL_NUMCMDBUFFERS 5
#define GSL_HAL_CMDBUFFERSIZE ((1024 + 13) * sizeof(unsigned int))
#define ALIGN_IN_BYTES(dim, alignment) (((dim) + (alignment - 1)) & \
~(alignment - 1))
#define PACKETSIZE_BEGIN 3
#define PACKETSIZE_G2DCOLOR 2
#define PACKETSIZE_TEXUNIT (TEXUNITREGCOUNT * 2)
#define PACKETSIZE_REG (VG_REGCOUNT * 2)
#define PACKETSIZE_STATE (PACKETSIZE_TEXUNIT * NUMTEXUNITS + \
PACKETSIZE_REG + PACKETSIZE_BEGIN + \
PACKETSIZE_G2DCOLOR)
#define PACKETSIZE_STATESTREAM (ALIGN_IN_BYTES((PACKETSIZE_STATE * \
sizeof(unsigned int)), 32) / \
sizeof(unsigned int))
#define KGSL_G12_PACKET_SIZE 15
#define KGSL_G12_MARKER_SIZE 10
#define KGSL_G12_CALL_CMD 0x1000
#define KGSL_G12_MARKER_CMD 0x8000
#define KGSL_G12_STREAM_END_CMD 0x9000
#define KGSL_G12_STREAM_PACKET 0x7C000176
#define KGSL_G12_STREAM_PACKET_CALL 0x7C000275
struct kgsl_g12_hal_z1xxdrawctx_t {
unsigned int id;
};
struct kgsl_g12_z1xx {
unsigned int offs;
unsigned int curr;
unsigned int prevctx;
struct kgsl_memdesc e0;
struct kgsl_memdesc e1;
#ifdef _Z180
struct kgsl_memdesc e2;
#endif
unsigned int *cmdbuf[GSL_HAL_NUMCMDBUFFERS];
struct kgsl_memdesc cmdbufdesc[GSL_HAL_NUMCMDBUFFERS];
unsigned int timestamp[GSL_HAL_NUMCMDBUFFERS];
unsigned int numcontext;
unsigned int nextUniqueContextID;
};
extern struct kgsl_g12_z1xx g_z1xx;
extern int z160_version;
int
kgsl_g12_drawctxt_create(struct kgsl_device *device,
unsigned int type,
unsigned int *drawctxt_id,
unsigned int flags);
int
kgsl_g12_drawctxt_destroy(struct kgsl_device *device,
unsigned int drawctxt_id);
#ifdef _Z180
#define NUMTEXUNITS 4
#define TEXUNITREGCOUNT 25
#define VG_REGCOUNT 0x39
#define GSL_HAL_EDGE0BUFSIZE 0x3E8 + 64
#define GSL_HAL_EDGE1BUFSIZE 0x8000 + 64
#define GSL_HAL_EDGE2BUFSIZE 0x80020 + 64
#define GSL_HAL_EDGE0REG ADDR_VGV1_CBUF
#define GSL_HAL_EDGE1REG ADDR_VGV1_BBUF
#define GSL_HAL_EDGE2REG ADDR_VGV1_EBUF
#else
#define NUMTEXUNITS 2
#define TEXUNITREGCOUNT 24
#define VG_REGCOUNT 0x3A
#define L1TILESIZE 64
#define GSL_HAL_EDGE0BUFSIZE L1TILESIZE * L1TILESIZE * 4 + 64
#define GSL_HAL_EDGE1BUFSIZE L1TILESIZE * L1TILESIZE * 16 + 64
#define GSL_HAL_EDGE0REG ADDR_VGV1_CBASE1
#define GSL_HAL_EDGE1REG ADDR_VGV1_UBASE2
#endif
/* should be in kgsl_g12_drawctxt.h? */
int kgsl_g12_addtimestamp(struct kgsl_device* device, unsigned int *timestamp);
int kgsl_g12_issueibcmds(struct kgsl_device* device, int drawctxt_index, uint32_t ibaddr, int sizedwords, unsigned int *timestamp, unsigned int flags);
int kgsl_g12_drawctxt_create(struct kgsl_device* device, unsigned int type, unsigned int *drawctxt_id, unsigned int flags);
int kgsl_g12_drawctxt_destroy(struct kgsl_device* device, unsigned int drawctxt_id);
#endif /* __GSL_DRAWCTXT_H */

View File

@@ -409,6 +409,7 @@ static int gsl_kmod_ioctl(struct inode *inode, struct file *fd, unsigned int cmd
kgsl_context_create_t param;
unsigned int tmp;
int tmpStatus;
struct kgsl_device *device;
#if defined(GSL_IOCTL_DEBUG)
printk(KERN_INFO "--> %s: IOCTL_KGSL_CONTEXT_CREATE\n", __func__);
@@ -420,14 +421,20 @@ static int gsl_kmod_ioctl(struct inode *inode, struct file *fd, unsigned int cmd
kgslStatus = GSL_FAILURE;
break;
}
kgslStatus = kgsl_context_create(param.device_id, param.type, &tmp, param.flags);
device = &gsl_driver.device[param.device_id-1];
mutex_lock(&gsl_driver.lock);
kgslStatus = device->ftbl.device_drawctxt_create(device, param.type, &tmp, param.flags);
mutex_unlock(&gsl_driver.lock);
if (kgslStatus == GSL_SUCCESS)
{
if (copy_to_user(param.drawctxt_id, &tmp, sizeof(unsigned int)))
{
tmpStatus = kgsl_context_destroy(param.device_id, tmp);
mutex_lock(&gsl_driver.lock);
tmpStatus = device->ftbl.device_drawctxt_destroy(device, *param.drawctxt_id);
mutex_unlock(&gsl_driver.lock);
/* is asserting ok? Basicly we should return the error from copy_to_user
* but will the user space interpret it correctly? Will the user space
* but will the user space interpret it correctly? Will the user space
* always check against GSL_SUCCESS or GSL_FAILURE as they are not the only
* return values.
*/
@@ -446,6 +453,7 @@ static int gsl_kmod_ioctl(struct inode *inode, struct file *fd, unsigned int cmd
case IOCTL_KGSL_CONTEXT_DESTROY:
{
kgsl_context_destroy_t param;
struct kgsl_device *device;
#if defined(GSL_IOCTL_DEBUG)
printk(KERN_INFO "--> %s: IOCTL_KGSL_CONTEXT_DESTROY\n", __func__);
#endif
@@ -455,7 +463,12 @@ static int gsl_kmod_ioctl(struct inode *inode, struct file *fd, unsigned int cmd
kgslStatus = GSL_FAILURE;
break;
}
kgslStatus = kgsl_context_destroy(param.device_id, param.drawctxt_id);
device = &gsl_driver.device[param.device_id-1];
mutex_lock(&gsl_driver.lock);
kgslStatus = device->ftbl.device_drawctxt_destroy(device, param.drawctxt_id);
mutex_unlock(&gsl_driver.lock);
del_device_context_from_array(fd, param.device_id, param.drawctxt_id);
break;
}

View File

@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/fs.h>
#include "kgsl_driver.h"
#include "kgsl_kmod_cleanup.h"
#include "kgsl_device.h"
#include "kgsl_drawctxt.h"
@@ -243,7 +244,7 @@ void del_all_devices_contexts(struct file *fd)
u32 ctx_array_index;
s8 ctx;
int err;
datp = get_fd_private_data(fd);
/* device_id is 1 based */
@@ -255,7 +256,15 @@ void del_all_devices_contexts(struct file *fd)
ctx = datp->created_contexts_array[device_index][ctx_array_index];
if(ctx != EMPTY_ENTRY)
{
err = kgsl_context_destroy(id, ctx);
struct kgsl_device *device = &gsl_driver.device[id];
if (device && device->ftbl.device_drawctxt_destroy) {
mutex_lock(&gsl_driver.lock);
err = device->ftbl.device_drawctxt_destroy(device, ctx);
mutex_unlock(&gsl_driver.lock);
} else
err = GSL_FAILURE;
if(err != GSL_SUCCESS)
{
printk(KERN_ERR "%s: could not destroy context %d on device id = %u\n", __func__, ctx, id);

View File

@@ -929,8 +929,8 @@ kgsl_yamato_getfunctable(struct kgsl_functable *ftbl)
ftbl->mmu_tlbinvalidate = kgsl_yamato_tlbinvalidate;
ftbl->mmu_setpagetable = kgsl_yamato_setpagetable;
ftbl->cmdstream_issueibcmds = kgsl_ringbuffer_issueibcmds;
ftbl->context_create = kgsl_drawctxt_create;
ftbl->context_destroy = kgsl_drawctxt_destroy;
ftbl->device_drawctxt_create = kgsl_drawctxt_create;
ftbl->device_drawctxt_destroy = kgsl_drawctxt_destroy;
return (GSL_SUCCESS);
}