msm: kgsl: Check if GPU is hung when reserving space in rb
A busy loop is executed when we allocate space from the ringbuffer.
If the GPU is hung then we can wait indefinitely in the busy loop.
Add a wait time to this busy loop, and if the wait time elapses then
report a GPU hang instead of waiting indefinitely.
Change-Id: I035c39063cbfa25380702720f929df5319e73e61
Signed-off-by: Shubhraprakash Das <sadas@codeaurora.org>
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index ad0ec48..ab47d40 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -246,6 +246,7 @@
}
static void adreno_iommu_setstate(struct kgsl_device *device,
+ unsigned int context_id,
uint32_t flags)
{
unsigned int pt_val, reg_pt_val;
@@ -256,11 +257,17 @@
struct kgsl_memdesc **reg_map_desc;
void *reg_map_array = NULL;
int num_iommu_units, i;
+ struct kgsl_context *context;
+ struct adreno_context *adreno_ctx = NULL;
if (!adreno_dev->drawctxt_active)
return kgsl_mmu_device_setstate(&device->mmu, flags);
num_iommu_units = kgsl_mmu_get_reg_map_desc(&device->mmu,
®_map_array);
+
+ context = idr_find(&device->context_idr, context_id);
+ adreno_ctx = context->devctxt;
+
reg_map_desc = reg_map_array;
if (kgsl_mmu_enable_clk(&device->mmu,
@@ -375,7 +382,6 @@
sizedwords += (cmds - &link[0]);
if (sizedwords) {
- unsigned int ts;
/*
* add an interrupt at the end of commands so that the smmu
* disable clock off function will get called
@@ -383,9 +389,13 @@
*cmds++ = cp_type3_packet(CP_INTERRUPT, 1);
*cmds++ = CP_INT_CNTL__RB_INT_MASK;
sizedwords += 2;
- ts = adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
+ /* This returns the per context timestamp but we need to
+ * use the global timestamp for iommu clock disablement */
+ adreno_ringbuffer_issuecmds(device, adreno_ctx,
+ KGSL_CMD_FLAGS_PMODE,
&link[0], sizedwords);
- kgsl_mmu_disable_clk_on_ts(&device->mmu, ts, true);
+ kgsl_mmu_disable_clk_on_ts(&device->mmu,
+ adreno_dev->ringbuffer.timestamp[KGSL_MEMSTORE_GLOBAL], true);
}
done:
if (num_iommu_units)
@@ -393,6 +403,7 @@
}
static void adreno_gpummu_setstate(struct kgsl_device *device,
+ unsigned int context_id,
uint32_t flags)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
@@ -400,6 +411,8 @@
unsigned int *cmds = &link[0];
int sizedwords = 0;
unsigned int mh_mmu_invalidate = 0x00000003; /*invalidate all and tc */
+ struct kgsl_context *context;
+ struct adreno_context *adreno_ctx = NULL;
/*
* Fix target freeze issue by adding TLB flush for each submit
@@ -414,6 +427,9 @@
* easier to filter out the mmu accesses from the dump
*/
if (!kgsl_cff_dump_enable && adreno_dev->drawctxt_active) {
+ context = idr_find(&device->context_idr, context_id);
+ adreno_ctx = context->devctxt;
+
if (flags & KGSL_MMUFLAGS_PTUPDATE) {
/* wait for graphics pipe to be idle */
*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
@@ -486,7 +502,8 @@
sizedwords += 2;
}
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
+ adreno_ringbuffer_issuecmds(device, adreno_ctx,
+ KGSL_CMD_FLAGS_PMODE,
&link[0], sizedwords);
} else {
kgsl_mmu_device_setstate(&device->mmu, flags);
@@ -494,13 +511,14 @@
}
static void adreno_setstate(struct kgsl_device *device,
+ unsigned int context_id,
uint32_t flags)
{
/* call the mmu specific handler */
if (KGSL_MMU_TYPE_GPU == kgsl_mmu_get_mmutype())
- return adreno_gpummu_setstate(device, flags);
+ return adreno_gpummu_setstate(device, context_id, flags);
else if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_get_mmutype())
- return adreno_iommu_setstate(device, flags);
+ return adreno_iommu_setstate(device, context_id, flags);
}
static unsigned int
@@ -896,8 +914,7 @@
return ret;
}
-static int
-adreno_dump_and_recover(struct kgsl_device *device)
+int adreno_dump_and_recover(struct kgsl_device *device)
{
int result = -ETIMEDOUT;
@@ -937,6 +954,7 @@
done:
return result;
}
+EXPORT_SYMBOL(adreno_dump_and_recover);
static int adreno_getproperty(struct kgsl_device *device,
enum kgsl_property_type type,
@@ -1325,6 +1343,7 @@
int status;
unsigned int ref_ts, enableflag;
unsigned int context_id;
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
mutex_lock(&device->mutex);
context_id = _get_context_id(context);
@@ -1370,8 +1389,15 @@
* get an interrupt */
cmds[0] = cp_type3_packet(CP_NOP, 1);
cmds[1] = 0;
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
- &cmds[0], 2);
+
+ if (adreno_dev->drawctxt_active)
+ adreno_ringbuffer_issuecmds(device,
+ adreno_dev->drawctxt_active,
+ KGSL_CMD_FLAGS_NONE, &cmds[0], 2);
+ else
+ /* We would never call this function if there
+ * was no active contexts running */
+ BUG();
}
}
unlock:
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index feaa36f..88ed895 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -99,7 +99,8 @@
int (*ctxt_create)(struct adreno_device *, struct adreno_context *);
void (*ctxt_save)(struct adreno_device *, struct adreno_context *);
void (*ctxt_restore)(struct adreno_device *, struct adreno_context *);
- void (*ctxt_draw_workaround)(struct adreno_device *);
+ void (*ctxt_draw_workaround)(struct adreno_device *,
+ struct adreno_context *);
irqreturn_t (*irq_handler)(struct adreno_device *);
void (*irq_control)(struct adreno_device *, int);
void * (*snapshot)(struct adreno_device *, void *, int *, int);
@@ -143,6 +144,8 @@
void *adreno_snapshot(struct kgsl_device *device, void *snapshot, int *remain,
int hang);
+int adreno_dump_and_recover(struct kgsl_device *device);
+
static inline int adreno_is_a200(struct adreno_device *adreno_dev)
{
return (adreno_dev->gpurev == ADRENO_REV_A200);
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index d846d3d..3aa3be5 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1450,7 +1450,8 @@
return ret;
}
-static void a2xx_drawctxt_workaround(struct adreno_device *adreno_dev)
+static void a2xx_drawctxt_draw_workaround(struct adreno_device *adreno_dev,
+ struct adreno_context *context)
{
struct kgsl_device *device = &adreno_dev->dev;
unsigned int cmd[11];
@@ -1497,7 +1498,7 @@
| adreno_dev->pix_shader_start;
}
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
+ adreno_ringbuffer_issuecmds(device, context, KGSL_CMD_FLAGS_PMODE,
&cmd[0], cmds - cmd);
}
@@ -1516,12 +1517,13 @@
if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
/* save registers and constants. */
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_NONE,
context->reg_save, 3);
if (context->flags & CTXT_FLAGS_SHADER_SAVE) {
/* save shader partitioning and instructions. */
- adreno_ringbuffer_issuecmds(device,
+ adreno_ringbuffer_issuecmds(device, context,
KGSL_CMD_FLAGS_PMODE,
context->shader_save, 3);
@@ -1529,7 +1531,8 @@
* fixup shader partitioning parameter for
* SET_SHADER_BASES.
*/
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_NONE,
context->shader_fixup, 3);
context->flags |= CTXT_FLAGS_SHADER_RESTORE;
@@ -1541,19 +1544,21 @@
/* save gmem.
* (note: changes shader. shader must already be saved.)
*/
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_PMODE,
context->context_gmem_shadow.gmem_save, 3);
/* Restore TP0_CHICKEN */
if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_NONE,
context->chicken_restore, 3);
}
adreno_dev->gpudev->ctx_switches_since_last_draw = 0;
context->flags |= CTXT_FLAGS_GMEM_RESTORE;
} else if (adreno_is_a2xx(adreno_dev))
- a2xx_drawctxt_workaround(adreno_dev);
+ a2xx_drawctxt_draw_workaround(adreno_dev, context);
}
static void a2xx_drawctxt_restore(struct adreno_device *adreno_dev,
@@ -1564,7 +1569,8 @@
if (context == NULL) {
/* No context - set the default apgetable and thats it */
- kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable);
+ kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable,
+ adreno_dev->drawctxt_active->id);
return;
}
@@ -1576,8 +1582,9 @@
cmds[3] = device->memstore.gpuaddr +
KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context);
cmds[4] = context->id;
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE, cmds, 5);
- kgsl_mmu_setstate(&device->mmu, context->pagetable);
+ adreno_ringbuffer_issuecmds(device, context, KGSL_CMD_FLAGS_NONE,
+ cmds, 5);
+ kgsl_mmu_setstate(&device->mmu, context->pagetable, context->id);
#ifndef CONFIG_MSM_KGSL_CFF_DUMP_NO_CONTEXT_MEM_DUMP
kgsl_cffdump_syncmem(NULL, &context->gpustate,
@@ -1589,12 +1596,14 @@
* (note: changes shader. shader must not already be restored.)
*/
if (context->flags & CTXT_FLAGS_GMEM_RESTORE) {
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_PMODE,
context->context_gmem_shadow.gmem_restore, 3);
if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
/* Restore TP0_CHICKEN */
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_NONE,
context->chicken_restore, 3);
}
@@ -1604,12 +1613,12 @@
if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
/* restore registers and constants. */
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
- context->reg_restore, 3);
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_NONE, context->reg_restore, 3);
/* restore shader instructions & partitioning. */
if (context->flags & CTXT_FLAGS_SHADER_RESTORE) {
- adreno_ringbuffer_issuecmds(device,
+ adreno_ringbuffer_issuecmds(device, context,
KGSL_CMD_FLAGS_NONE,
context->shader_restore, 3);
}
@@ -1618,8 +1627,8 @@
if (adreno_is_a20x(adreno_dev)) {
cmds[0] = cp_type3_packet(CP_SET_BIN_BASE_OFFSET, 1);
cmds[1] = context->bin_base_offset;
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
- cmds, 2);
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_NONE, cmds, 2);
}
}
@@ -2011,7 +2020,7 @@
.ctxt_create = a2xx_drawctxt_create,
.ctxt_save = a2xx_drawctxt_save,
.ctxt_restore = a2xx_drawctxt_restore,
- .ctxt_draw_workaround = a2xx_drawctxt_workaround,
+ .ctxt_draw_workaround = a2xx_drawctxt_draw_workaround,
.irq_handler = a2xx_irq_handler,
.irq_control = a2xx_irq_control,
.snapshot = a2xx_snapshot,
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index a6b4210..6eebeb8 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -2226,16 +2226,17 @@
if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
/* Fixup self modifying IBs for save operations */
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
- context->save_fixup, 3);
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_NONE, context->save_fixup, 3);
/* save registers and constants. */
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_NONE,
context->regconstant_save, 3);
if (context->flags & CTXT_FLAGS_SHADER_SAVE) {
/* Save shader instructions */
- adreno_ringbuffer_issuecmds(device,
+ adreno_ringbuffer_issuecmds(device, context,
KGSL_CMD_FLAGS_PMODE, context->shader_save, 3);
context->flags |= CTXT_FLAGS_SHADER_RESTORE;
@@ -2249,7 +2250,8 @@
* already be saved.)
*/
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_PMODE,
context->context_gmem_shadow.
gmem_save, 3);
context->flags |= CTXT_FLAGS_GMEM_RESTORE;
@@ -2264,7 +2266,8 @@
if (context == NULL) {
/* No context - set the default pagetable and thats it */
- kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable);
+ kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable,
+ adreno_dev->drawctxt_active->id);
return;
}
@@ -2276,8 +2279,9 @@
cmds[3] = device->memstore.gpuaddr +
KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context);
cmds[4] = context->id;
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE, cmds, 5);
- kgsl_mmu_setstate(&device->mmu, context->pagetable);
+ adreno_ringbuffer_issuecmds(device, context, KGSL_CMD_FLAGS_NONE,
+ cmds, 5);
+ kgsl_mmu_setstate(&device->mmu, context->pagetable, context->id);
/*
* Restore GMEM. (note: changes shader.
@@ -2285,29 +2289,34 @@
*/
if (context->flags & CTXT_FLAGS_GMEM_RESTORE) {
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_PMODE,
context->context_gmem_shadow.
gmem_restore, 3);
context->flags &= ~CTXT_FLAGS_GMEM_RESTORE;
}
if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
- context->reg_restore, 3);
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_NONE, context->reg_restore, 3);
/* Fixup self modifying IBs for restore operations */
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_NONE,
context->restore_fixup, 3);
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_NONE,
context->constant_restore, 3);
if (context->flags & CTXT_FLAGS_SHADER_RESTORE)
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_NONE,
context->shader_restore, 3);
/* Restore HLSQ_CONTROL_0 register */
- adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
+ adreno_ringbuffer_issuecmds(device, context,
+ KGSL_CMD_FLAGS_NONE,
context->hlsqcontrol_restore, 3);
}
}
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index 267fd45..098c4f5 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -274,7 +274,7 @@
if (adreno_dev->gpudev->ctxt_draw_workaround &&
adreno_is_a225(adreno_dev))
adreno_dev->gpudev->ctxt_draw_workaround(
- adreno_dev);
+ adreno_dev, drawctxt);
return;
}
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 347a57d..73b4513 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -53,6 +53,9 @@
unsigned int freecmds;
unsigned int *cmds;
uint cmds_gpu;
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(rb->device);
+ unsigned long wait_timeout = msecs_to_jiffies(adreno_dev->wait_timeout);
+ unsigned long wait_time;
/* if wptr ahead, fill the remaining with NOPs */
if (wptr_ahead) {
@@ -79,13 +82,27 @@
rb->wptr = 0;
}
+ wait_time = jiffies + wait_timeout;
/* wait for space in ringbuffer */
- do {
+ while (1) {
GSL_RB_GET_READPTR(rb, &rb->rptr);
freecmds = rb->rptr - rb->wptr;
- } while ((freecmds != 0) && (freecmds <= numcmds));
+ if (freecmds == 0 || freecmds > numcmds)
+ break;
+
+ if (time_after(jiffies, wait_time)) {
+ KGSL_DRV_ERR(rb->device,
+ "Timed out while waiting for freespace in ringbuffer "
+ "rptr: 0x%x, wptr: 0x%x\n", rb->rptr, rb->wptr);
+ if (!adreno_dump_and_recover(rb->device))
+ wait_time = jiffies + wait_timeout;
+ else
+ /* GPU is hung and we cannot recover */
+ BUG();
+ }
+ }
}
unsigned int *adreno_ringbuffer_allocspace(struct adreno_ringbuffer *rb,
@@ -439,15 +456,13 @@
unsigned int context_id = KGSL_MEMSTORE_GLOBAL;
unsigned int gpuaddr = rb->device->memstore.gpuaddr;
- if (context != NULL) {
- /*
- * if the context was not created with per context timestamp
- * support, we must use the global timestamp since issueibcmds
- * will be returning that one.
- */
- if (context->flags & CTXT_FLAGS_PER_CONTEXT_TS)
- context_id = context->id;
- }
+ /*
+ * if the context was not created with per context timestamp
+ * support, we must use the global timestamp since issueibcmds
+ * will be returning that one.
+ */
+ if (context->flags & CTXT_FLAGS_PER_CONTEXT_TS)
+ context_id = context->id;
/* reserve space to temporarily turn off protected mode
* error checking if needed
@@ -460,7 +475,7 @@
total_sizedwords += 7;
total_sizedwords += 2; /* scratchpad ts for recovery */
- if (context) {
+ if (context->flags & CTXT_FLAGS_PER_CONTEXT_TS) {
total_sizedwords += 3; /* sop timestamp */
total_sizedwords += 4; /* eop timestamp */
total_sizedwords += 3; /* global timestamp without cache
@@ -470,6 +485,15 @@
}
ringcmds = adreno_ringbuffer_allocspace(rb, total_sizedwords);
+ /* GPU may hang during space allocation, if thats the case the current
+ * context may have hung the GPU */
+ if (context->flags & CTXT_FLAGS_GPU_HANG) {
+ KGSL_CTXT_WARN(rb->device,
+ "Context %p caused a gpu hang. Will not accept commands for context %d\n",
+ context, context->id);
+ return rb->timestamp[context_id];
+ }
+
rcmd_gpu = rb->buffer_desc.gpuaddr
+ sizeof(uint)*(rb->wptr-total_sizedwords);
@@ -525,7 +549,7 @@
GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x00);
}
- if (context) {
+ if (context->flags & CTXT_FLAGS_PER_CONTEXT_TS) {
/* start-of-pipeline timestamp */
GSL_RB_WRITE(ringcmds, rcmd_gpu,
cp_type3_packet(CP_MEM_WRITE, 2));
@@ -593,6 +617,7 @@
unsigned int
adreno_ringbuffer_issuecmds(struct kgsl_device *device,
+ struct adreno_context *drawctxt,
unsigned int flags,
unsigned int *cmds,
int sizedwords)
@@ -603,7 +628,7 @@
if (device->state & KGSL_STATE_HUNG)
return kgsl_readtimestamp(device, KGSL_MEMSTORE_GLOBAL,
KGSL_TIMESTAMP_RETIRED);
- return adreno_ringbuffer_addcmds(rb, NULL, flags, cmds, sizedwords);
+ return adreno_ringbuffer_addcmds(rb, drawctxt, flags, cmds, sizedwords);
}
static bool _parse_ibs(struct kgsl_device_private *dev_priv, uint gpuaddr,
@@ -870,7 +895,7 @@
*cmds++ = cp_nop_packet(1);
*cmds++ = KGSL_END_OF_IB_IDENTIFIER;
- kgsl_setstate(&device->mmu,
+ kgsl_setstate(&device->mmu, context->id,
kgsl_mmu_pt_get_flags(device->mmu.hwpagetable,
device->id));
diff --git a/drivers/gpu/msm/adreno_ringbuffer.h b/drivers/gpu/msm/adreno_ringbuffer.h
index ebea4ed..6429f46 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.h
+++ b/drivers/gpu/msm/adreno_ringbuffer.h
@@ -104,6 +104,7 @@
void adreno_ringbuffer_close(struct adreno_ringbuffer *rb);
unsigned int adreno_ringbuffer_issuecmds(struct kgsl_device *device,
+ struct adreno_context *drawctxt,
unsigned int flags,
unsigned int *cmdaddr,
int sizedwords);
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 4524668..d464cf1 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -97,7 +97,8 @@
/* Optional functions - these functions are not mandatory. The
driver will check that the function pointer is not NULL before
calling the hook */
- void (*setstate) (struct kgsl_device *device, uint32_t flags);
+ void (*setstate) (struct kgsl_device *device, unsigned int context_id,
+ uint32_t flags);
int (*drawctxt_create) (struct kgsl_device *device,
struct kgsl_pagetable *pagetable, struct kgsl_context *context,
uint32_t flags);
diff --git a/drivers/gpu/msm/kgsl_gpummu.c b/drivers/gpu/msm/kgsl_gpummu.c
index d9fe3c6..c121110 100644
--- a/drivers/gpu/msm/kgsl_gpummu.c
+++ b/drivers/gpu/msm/kgsl_gpummu.c
@@ -485,7 +485,8 @@
}
static void kgsl_gpummu_setstate(struct kgsl_mmu *mmu,
- struct kgsl_pagetable *pagetable)
+ struct kgsl_pagetable *pagetable,
+ unsigned int context_id)
{
if (mmu->flags & KGSL_FLAGS_STARTED) {
/* page table not current, then setup mmu to use new
@@ -499,7 +500,7 @@
kgsl_mmu_pt_get_flags(pagetable, mmu->device->id);
/* call device specific set page table */
- kgsl_setstate(mmu, KGSL_MMUFLAGS_TLBFLUSH |
+ kgsl_setstate(mmu, context_id, KGSL_MMUFLAGS_TLBFLUSH |
KGSL_MMUFLAGS_PTUPDATE);
}
}
@@ -583,7 +584,7 @@
kgsl_regwrite(mmu->device, MH_MMU_VA_RANGE,
(KGSL_PAGETABLE_BASE |
(CONFIG_MSM_KGSL_PAGE_TABLE_SIZE >> 16)));
- kgsl_setstate(mmu, KGSL_MMUFLAGS_TLBFLUSH);
+ kgsl_setstate(mmu, KGSL_MEMSTORE_GLOBAL, KGSL_MMUFLAGS_TLBFLUSH);
mmu->flags |= KGSL_FLAGS_STARTED;
return 0;
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 8d66eaa..28f6f48 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -617,7 +617,8 @@
}
static void kgsl_iommu_setstate(struct kgsl_mmu *mmu,
- struct kgsl_pagetable *pagetable)
+ struct kgsl_pagetable *pagetable,
+ unsigned int context_id)
{
if (mmu->flags & KGSL_FLAGS_STARTED) {
struct kgsl_iommu *iommu = mmu->priv;
@@ -634,7 +635,8 @@
flags |= KGSL_MMUFLAGS_TLBFLUSH;
flags |= kgsl_mmu_pt_get_flags(mmu->hwpagetable,
mmu->device->id);
- kgsl_setstate(mmu, KGSL_MMUFLAGS_PTUPDATE | flags);
+ kgsl_setstate(mmu, context_id,
+ KGSL_MMUFLAGS_PTUPDATE | flags);
}
}
}
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index dfaadba..3e72919 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -543,13 +543,14 @@
}
EXPORT_SYMBOL(kgsl_mmu_putpagetable);
-void kgsl_setstate(struct kgsl_mmu *mmu, uint32_t flags)
+void kgsl_setstate(struct kgsl_mmu *mmu, unsigned int context_id,
+ uint32_t flags)
{
struct kgsl_device *device = mmu->device;
if (KGSL_MMU_TYPE_NONE == kgsl_mmu_type)
return;
else if (device->ftbl->setstate)
- device->ftbl->setstate(device, flags);
+ device->ftbl->setstate(device, context_id, flags);
else if (mmu->mmu_ops->mmu_device_setstate)
mmu->mmu_ops->mmu_device_setstate(mmu, flags);
}
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index de53946..d4dac22 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -125,7 +125,8 @@
int (*mmu_start) (struct kgsl_mmu *mmu);
void (*mmu_stop) (struct kgsl_mmu *mmu);
void (*mmu_setstate) (struct kgsl_mmu *mmu,
- struct kgsl_pagetable *pagetable);
+ struct kgsl_pagetable *pagetable,
+ unsigned int context_id);
void (*mmu_device_setstate) (struct kgsl_mmu *mmu,
uint32_t flags);
void (*mmu_pagefault) (struct kgsl_mmu *mmu);
@@ -193,7 +194,8 @@
int kgsl_mmu_unmap(struct kgsl_pagetable *pagetable,
struct kgsl_memdesc *memdesc);
unsigned int kgsl_virtaddr_to_physaddr(void *virtaddr);
-void kgsl_setstate(struct kgsl_mmu *mmu, uint32_t flags);
+void kgsl_setstate(struct kgsl_mmu *mmu, unsigned int context_id,
+ uint32_t flags);
int kgsl_mmu_get_ptname_from_ptbase(unsigned int pt_base);
int kgsl_mmu_pt_get_flags(struct kgsl_pagetable *pt,
enum kgsl_deviceid id);
@@ -219,10 +221,11 @@
}
static inline void kgsl_mmu_setstate(struct kgsl_mmu *mmu,
- struct kgsl_pagetable *pagetable)
+ struct kgsl_pagetable *pagetable,
+ unsigned int context_id)
{
if (mmu->mmu_ops && mmu->mmu_ops->mmu_setstate)
- mmu->mmu_ops->mmu_setstate(mmu, pagetable);
+ mmu->mmu_ops->mmu_setstate(mmu, pagetable, context_id);
}
static inline void kgsl_mmu_device_setstate(struct kgsl_mmu *mmu,
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index bc2685c..6efba45 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -444,11 +444,13 @@
(ctrl & KGSL_CONTEXT_CTX_SWITCH)) {
KGSL_CMD_INFO(device, "context switch %d -> %d\n",
context->id, z180_dev->ringbuffer.prevctx);
- kgsl_mmu_setstate(&device->mmu, pagetable);
+ kgsl_mmu_setstate(&device->mmu, pagetable,
+ KGSL_MEMSTORE_GLOBAL);
cnt = PACKETSIZE_STATESTREAM;
ofs = 0;
}
kgsl_setstate(&device->mmu,
+ KGSL_MEMSTORE_GLOBAL,
kgsl_mmu_pt_get_flags(device->mmu.hwpagetable,
device->id));
@@ -861,7 +863,8 @@
if (z180_dev->ringbuffer.prevctx == context->id) {
z180_dev->ringbuffer.prevctx = Z180_INVALID_CONTEXT;
device->mmu.hwpagetable = device->mmu.defaultpagetable;
- kgsl_setstate(&device->mmu, KGSL_MMUFLAGS_PTUPDATE);
+ kgsl_setstate(&device->mmu, KGSL_MEMSTORE_GLOBAL,
+ KGSL_MMUFLAGS_PTUPDATE);
}
}