msm: kgsl: Move timestamps inside the context structure
Store the timestamps inside the context rather than in a
list stored in the ringbuffer. This allows for easier
maintanability as well as keeping all context data
centralized.
Change-Id: I0467d07be6c8bb9f062a81a40629c0288be7e868
Signed-off-by: Carter Cooper <ccooper@codeaurora.org>
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index f0ce8f9..c227faa 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -434,7 +434,7 @@
KGSL_CMD_FLAGS_PMODE,
&link[0], sizedwords);
kgsl_mmu_disable_clk_on_ts(&device->mmu,
- adreno_dev->ringbuffer.timestamp[KGSL_MEMSTORE_GLOBAL], true);
+ adreno_dev->ringbuffer.global_ts, true);
}
if (sizedwords > (sizeof(link)/sizeof(unsigned int))) {
@@ -1390,8 +1390,6 @@
static void adreno_set_max_ts_for_bad_ctxs(struct kgsl_device *device)
{
- struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
- struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
struct kgsl_context *context;
struct adreno_context *temp_adreno_context;
int next = 0;
@@ -1403,11 +1401,11 @@
kgsl_sharedmem_writel(&device->memstore,
KGSL_MEMSTORE_OFFSET(context->id,
soptimestamp),
- rb->timestamp[context->id]);
+ temp_adreno_context->timestamp);
kgsl_sharedmem_writel(&device->memstore,
KGSL_MEMSTORE_OFFSET(context->id,
eoptimestamp),
- rb->timestamp[context->id]);
+ temp_adreno_context->timestamp);
}
next = next + 1;
}
@@ -2032,15 +2030,14 @@
int ret = 0;
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
- unsigned int timestamp;
KGSL_FT_INFO(device,
"Start Parameters: IB1: 0x%X, "
"Bad context_id: %u, global_eop: 0x%x\n",
ft_data->ib1, ft_data->context_id, ft_data->global_eop);
- timestamp = rb->timestamp[KGSL_MEMSTORE_GLOBAL];
- KGSL_FT_INFO(device, "Last issued global timestamp: %x\n", timestamp);
+ KGSL_FT_INFO(device, "Last issued global timestamp: %x\n",
+ rb->global_ts);
/* We may need to replay commands multiple times based on whether
* multiple contexts hang the GPU */
@@ -2072,11 +2069,9 @@
adreno_dev->drawctxt_active->pagetable;
else
device->mmu.hwpagetable = device->mmu.defaultpagetable;
- rb->timestamp[KGSL_MEMSTORE_GLOBAL] = timestamp;
kgsl_sharedmem_writel(&device->memstore,
KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
- eoptimestamp),
- rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
+ eoptimestamp), rb->global_ts);
/* switch to NULL ctxt */
if (adreno_dev->drawctxt_active != NULL)
@@ -2895,7 +2890,7 @@
if (kgsl_check_timestamp(device, context, timestamp))
return 0;
- ts_issued = adreno_dev->ringbuffer.timestamp[context_id];
+ ts_issued = adreno_context_timestamp(context, &adreno_dev->ringbuffer);
adreno_regread(device, REG_CP_RB_RPTR, &rptr);
mb();
@@ -2926,7 +2921,7 @@
if (context_id == KGSL_CONTEXT_INVALID)
return -EINVAL;
- ts_issued = adreno_dev->ringbuffer.timestamp[context_id];
+ ts_issued = adreno_context_timestamp(context, &adreno_dev->ringbuffer);
if (timestamp_cmp(timestamp, ts_issued) <= 0)
return 0;
@@ -2970,8 +2965,6 @@
int ts_compare = 1;
int io, ret = -ETIMEDOUT;
- /* Get out early if the context has already been destroyed */
-
if (context_id == KGSL_CONTEXT_INVALID) {
KGSL_DRV_WARN(device, "context was detached");
return -EINVAL;
@@ -3062,6 +3055,7 @@
}
time_elapsed += wait;
+
/* If user specified timestamps are being used, wait at least
* KGSL_SYNCOBJ_SERVER_TIMEOUT msecs for the user driver to
* issue a IB for a timestamp before checking to see if the
@@ -3083,6 +3077,7 @@
* Reset the invalid timestamp flag on a valid
* wait
*/
+
context->wait_on_invalid_ts = false;
}
}
@@ -3119,9 +3114,9 @@
switch (type) {
case KGSL_TIMESTAMP_QUEUED: {
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
- struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
- timestamp = rb->timestamp[context_id];
+ timestamp = adreno_context_timestamp(context,
+ &adreno_dev->ringbuffer);
break;
}
case KGSL_TIMESTAMP_CONSUMED:
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index b4a5292..d4b0390 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -318,6 +318,20 @@
cmd[1] == KGSL_CONTEXT_TO_MEM_IDENTIFIER);
}
+static inline int adreno_context_timestamp(struct kgsl_context *k_ctxt,
+ struct adreno_ringbuffer *rb)
+{
+ struct adreno_context *a_ctxt = NULL;
+
+ if (k_ctxt)
+ a_ctxt = k_ctxt->devctxt;
+
+ if (a_ctxt && a_ctxt->flags & CTXT_FLAGS_PER_CONTEXT_TS)
+ return a_ctxt->timestamp;
+
+ return rb->global_ts;
+}
+
/**
* adreno_encode_istore_size - encode istore size in CP format
* @adreno_dev - The 3D device.
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index d0b2bd0..8f0bca2 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -148,7 +148,6 @@
{
struct adreno_context *drawctxt;
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
- struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
int ret;
drawctxt = kzalloc(sizeof(struct adreno_context), GFP_KERNEL);
@@ -161,7 +160,7 @@
drawctxt->pagetable = pagetable;
drawctxt->bin_base_offset = 0;
drawctxt->id = context->id;
- rb->timestamp[context->id] = 0;
+ drawctxt->timestamp = 0;
*flags &= (KGSL_CONTEXT_PREAMBLE |
KGSL_CONTEXT_NO_GMEM_ALLOC |
diff --git a/drivers/gpu/msm/adreno_drawctxt.h b/drivers/gpu/msm/adreno_drawctxt.h
index f0f3b6b..dfa4277 100644
--- a/drivers/gpu/msm/adreno_drawctxt.h
+++ b/drivers/gpu/msm/adreno_drawctxt.h
@@ -100,6 +100,7 @@
char pid_name[TASK_COMM_LEN];
unsigned int id;
unsigned int ib_gpu_time_used;
+ unsigned int timestamp;
uint32_t flags;
uint32_t pagefault;
unsigned long pagefault_ts;
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 9d50e6b..91609ef 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -333,7 +333,7 @@
return 0;
if (init_ram)
- rb->timestamp[KGSL_MEMSTORE_GLOBAL] = 0;
+ rb->global_ts = 0;
kgsl_sharedmem_set(&rb->memptrs_desc, 0, 0,
sizeof(struct kgsl_rbmemptrs));
@@ -524,11 +524,11 @@
memset(rb, 0, sizeof(struct adreno_ringbuffer));
}
-static uint32_t
+static int
adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb,
struct adreno_context *context,
unsigned int flags, unsigned int *cmds,
- int sizedwords, uint32_t timestamp)
+ int sizedwords)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(rb->device);
unsigned int *ringcmds;
@@ -537,28 +537,17 @@
unsigned int rcmd_gpu;
unsigned int context_id = KGSL_MEMSTORE_GLOBAL;
unsigned int gpuaddr = rb->device->memstore.gpuaddr;
+ unsigned int timestamp;
/*
* 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 && context->flags & CTXT_FLAGS_PER_CONTEXT_TS)
+ if (context && context->flags & CTXT_FLAGS_PER_CONTEXT_TS &&
+ !(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE))
context_id = context->id;
- if ((context && context->flags & CTXT_FLAGS_USER_GENERATED_TS) &&
- (!(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE))) {
- if (timestamp_cmp(rb->timestamp[context_id],
- timestamp) >= 0) {
- KGSL_DRV_ERR(rb->device,
- "Invalid user generated ts <%d:0x%x>, "
- "less than last issued ts <%d:0x%x>\n",
- context_id, timestamp, context_id,
- rb->timestamp[context_id]);
- return -ERANGE;
- }
- }
-
/* reserve space to temporarily turn off protected mode
* error checking if needed
*/
@@ -594,13 +583,8 @@
total_sizedwords += 2;
ringcmds = adreno_ringbuffer_allocspace(rb, context, total_sizedwords);
- if (!ringcmds) {
- /*
- * We could not allocate space in ringbuffer, just return the
- * last timestamp
- */
- return rb->timestamp[context_id];
- }
+ if (!ringcmds)
+ return -ENOSPC;
rcmd_gpu = rb->buffer_desc.gpuaddr
+ sizeof(uint)*(rb->wptr-total_sizedwords);
@@ -613,6 +597,14 @@
GSL_RB_WRITE(ringcmds, rcmd_gpu, KGSL_CMD_INTERNAL_IDENTIFIER);
}
+ /* always increment the global timestamp. once. */
+ rb->global_ts++;
+
+ if (KGSL_MEMSTORE_GLOBAL != context_id)
+ timestamp = context->timestamp;
+ else
+ timestamp = rb->global_ts;
+
if (flags & KGSL_CMD_FLAGS_PMODE) {
/* disable protected mode error checking */
GSL_RB_WRITE(ringcmds, rcmd_gpu,
@@ -632,21 +624,6 @@
GSL_RB_WRITE(ringcmds, rcmd_gpu, 1);
}
- /* always increment the global timestamp. once. */
- rb->timestamp[KGSL_MEMSTORE_GLOBAL]++;
-
- /* Do not update context's timestamp for internal submissions */
- if (context && !(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE)) {
- if (context_id == KGSL_MEMSTORE_GLOBAL)
- rb->timestamp[context->id] =
- rb->timestamp[KGSL_MEMSTORE_GLOBAL];
- else if (context->flags & CTXT_FLAGS_USER_GENERATED_TS)
- rb->timestamp[context_id] = timestamp;
- else
- rb->timestamp[context_id]++;
- }
- timestamp = rb->timestamp[context_id];
-
/* HW Workaround for MMU Page fault
* due to memory getting free early before
* GPU completes it.
@@ -659,7 +636,7 @@
/* scratchpad ts for fault tolerance */
GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_type0_packet(REG_CP_TIMESTAMP, 1));
- GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
+ GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->global_ts);
if (adreno_is_a3xx(adreno_dev)) {
/*
@@ -697,8 +674,7 @@
GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
eoptimestamp)));
- GSL_RB_WRITE(ringcmds, rcmd_gpu,
- rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
+ GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->global_ts);
} else {
GSL_RB_WRITE(ringcmds, rcmd_gpu,
cp_type3_packet(CP_EVENT_WRITE, 3));
@@ -706,8 +682,7 @@
GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
eoptimestamp)));
- GSL_RB_WRITE(ringcmds, rcmd_gpu,
- rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
+ GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->global_ts);
}
if (context) {
/* Conditional execution based on memory values */
@@ -761,7 +736,7 @@
adreno_ringbuffer_submit(rb);
- return timestamp;
+ return 0;
}
unsigned int
@@ -781,7 +756,7 @@
flags |= KGSL_CMD_FLAGS_INTERNAL_ISSUE;
return adreno_ringbuffer_addcmds(rb, drawctxt, flags, cmds,
- sizedwords, 0);
+ sizedwords);
}
static bool _parse_ibs(struct kgsl_device_private *dev_priv, uint gpuaddr,
@@ -1075,10 +1050,30 @@
adreno_drawctxt_switch(adreno_dev, drawctxt, flags);
- *timestamp = adreno_ringbuffer_addcmds(&adreno_dev->ringbuffer,
+ if (drawctxt->flags & CTXT_FLAGS_USER_GENERATED_TS) {
+ if (timestamp_cmp(drawctxt->timestamp, *timestamp) >= 0) {
+ KGSL_DRV_ERR(device,
+ "Invalid user generated ts <%d:0x%x>, "
+ "less than last issued ts <%d:0x%x>\n",
+ drawctxt->id, *timestamp, drawctxt->id,
+ drawctxt->timestamp);
+ return -ERANGE;
+ }
+ drawctxt->timestamp = *timestamp;
+ } else
+ drawctxt->timestamp++;
+
+ ret = adreno_ringbuffer_addcmds(&adreno_dev->ringbuffer,
drawctxt,
(flags & KGSL_CMD_FLAGS_EOF),
- &link[0], (cmds - link), *timestamp);
+ &link[0], (cmds - link));
+ if (ret)
+ goto done;
+
+ if (drawctxt->flags & CTXT_FLAGS_PER_CONTEXT_TS)
+ *timestamp = drawctxt->timestamp;
+ else
+ *timestamp = adreno_dev->ringbuffer.global_ts;
#ifdef CONFIG_MSM_KGSL_CFF_DUMP
/*
diff --git a/drivers/gpu/msm/adreno_ringbuffer.h b/drivers/gpu/msm/adreno_ringbuffer.h
index fa03c05..3157f41 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.h
+++ b/drivers/gpu/msm/adreno_ringbuffer.h
@@ -56,7 +56,7 @@
unsigned int wptr; /* write pointer offset in dwords from baseaddr */
unsigned int rptr; /* read pointer offset in dwords from baseaddr */
- unsigned int timestamp[KGSL_MEMSTORE_MAX];
+ unsigned int global_ts;
};