msm: kgsl: Add a new property to IOCTL_KGSL_DEVICE_GETPROPERTY

Return the reset status of the GPU unit when
IOCTL_KGSL_DEVICE_GETPROPERTY is called with
type KGSL_PROP_GPU_RESET_STAT
This commit is contained in:
securecrt 2012-06-21 12:54:12 +08:00
parent 69555a62d1
commit dcf924f072
4 changed files with 81 additions and 1 deletions

View File

@ -623,6 +623,8 @@ adreno_recover_hang(struct kgsl_device *device)
unsigned int soptimestamp;
unsigned int eoptimestamp;
struct adreno_context *drawctxt;
struct kgsl_context *context;
int next = 0;
KGSL_DRV_ERR(device, "Starting recovery from 3D GPU hang....\n");
rb_buffer = vmalloc(rb->buffer_desc.size);
@ -691,6 +693,24 @@ adreno_recover_hang(struct kgsl_device *device)
drawctxt->flags |= CTXT_FLAGS_GPU_HANG;
/*
* Set the reset status of all contexts to
* INNOCENT_CONTEXT_RESET_EXT except for the bad context
* since thats the guilty party
*/
while ((context = idr_get_next(&device->context_idr, &next))) {
if (KGSL_CTX_STAT_GUILTY_CONTEXT_RESET_EXT !=
context->reset_status) {
if (context->devctxt != drawctxt)
context->reset_status =
KGSL_CTX_STAT_INNOCENT_CONTEXT_RESET_EXT;
else
context->reset_status =
KGSL_CTX_STAT_GUILTY_CONTEXT_RESET_EXT;
}
next = next + 1;
}
/* Restore valid commands in ringbuffer */
adreno_ringbuffer_restore(rb, rb_buffer, num_rb_contents);
rb->timestamp = timestamp;

View File

@ -794,6 +794,40 @@ static long kgsl_ioctl_device_getproperty(struct kgsl_device_private *dev_priv,
break;
}
case KGSL_PROP_GPU_RESET_STAT:
{
/* Return reset status of given context and clear it */
uint32_t id;
struct kgsl_context *context;
if (param->sizebytes != sizeof(unsigned int)) {
result = -EINVAL;
break;
}
/* We expect the value passed in to contain the context id */
if (copy_from_user(&id, param->value,
sizeof(unsigned int))) {
result = -EFAULT;
break;
}
context = kgsl_find_context(dev_priv, id);
if (!context) {
result = -EINVAL;
break;
}
/*
* Copy the reset status to value which also serves as
* the out parameter
*/
if (copy_to_user(param->value, &(context->reset_status),
sizeof(unsigned int))) {
result = -EFAULT;
break;
}
/* Clear reset status once its been queried */
context->reset_status = KGSL_CTX_STAT_NO_ERROR;
break;
}
default:
result = dev_priv->device->ftbl->getproperty(
dev_priv->device, param->type,

5
drivers/gpu/msm/kgsl_device.h Normal file → Executable file
View File

@ -185,6 +185,11 @@ struct kgsl_context {
/* Pointer to the device specific context information */
void *devctxt;
/*
* Status indicating whether a gpu reset occurred and whether this
* context was responsible for causing it
*/
unsigned int reset_status;
};
struct kgsl_process_private {

View File

@ -59,6 +59,24 @@
#define KGSL_FLAGS_RESERVED2 0x00000080
#define KGSL_FLAGS_SOFT_RESET 0x00000100
/* Clock flags to show which clocks should be controled by a given platform */
#define KGSL_CLK_SRC 0x00000001
#define KGSL_CLK_CORE 0x00000002
#define KGSL_CLK_IFACE 0x00000004
#define KGSL_CLK_MEM 0x00000008
#define KGSL_CLK_MEM_IFACE 0x00000010
#define KGSL_CLK_AXI 0x00000020
/*
* Reset status values for context
*/
enum kgsl_ctx_reset_stat {
KGSL_CTX_STAT_NO_ERROR = 0x00000000,
KGSL_CTX_STAT_GUILTY_CONTEXT_RESET_EXT = 0x00000001,
KGSL_CTX_STAT_INNOCENT_CONTEXT_RESET_EXT = 0x00000002,
KGSL_CTX_STAT_UNKNOWN_CONTEXT_RESET_EXT = 0x00000003
};
#define KGSL_MAX_PWRLEVELS 5
#define KGSL_CONVERT_TO_MBPS(val) \
@ -75,7 +93,9 @@ enum kgsl_deviceid {
enum kgsl_user_mem_type {
KGSL_USER_MEM_TYPE_PMEM = 0x00000000,
KGSL_USER_MEM_TYPE_ASHMEM = 0x00000001,
KGSL_USER_MEM_TYPE_ADDR = 0x00000002
KGSL_USER_MEM_TYPE_ADDR = 0x00000002,
KGSL_USER_MEM_TYPE_ION = 0x00000003,
KGSL_USER_MEM_TYPE_MAX = 0x00000004,
};
struct kgsl_devinfo {
@ -133,6 +153,7 @@ enum kgsl_property_type {
KGSL_PROP_MMU_ENABLE = 0x00000006,
KGSL_PROP_INTERRUPT_WAITS = 0x00000007,
KGSL_PROP_VERSION = 0x00000008,
KGSL_PROP_GPU_RESET_STAT = 0x00000009
};
struct kgsl_shadowprop {