Loading drivers/gpu/msm/adreno.c +67 −1 Original line number Diff line number Diff line Loading @@ -2460,12 +2460,56 @@ static int adreno_getproperty(struct kgsl_device *device, return status; } static int adreno_setproperty(struct kgsl_device *device, static int adreno_set_constraint(struct kgsl_device *device, struct kgsl_context *context, struct kgsl_device_constraint *constraint) { int status = 0; switch (constraint->type) { case KGSL_CONSTRAINT_PWRLEVEL: { struct kgsl_device_constraint_pwrlevel pwr; if (constraint->size != sizeof(pwr)) { status = -EINVAL; break; } if (copy_from_user(&pwr, (void __user *)constraint->data, sizeof(pwr))) { status = -EFAULT; break; } if (pwr.level >= KGSL_CONSTRAINT_PWR_MAXLEVELS) { status = -EINVAL; break; } context->pwr_constraint.type = KGSL_CONSTRAINT_PWRLEVEL; context->pwr_constraint.sub_type = pwr.level; } break; case KGSL_CONSTRAINT_NONE: context->pwr_constraint.type = KGSL_CONSTRAINT_NONE; break; default: status = -EINVAL; break; } return status; } static int adreno_setproperty(struct kgsl_device_private *dev_priv, enum kgsl_property_type type, void __user *value, unsigned int sizebytes) { int status = -EINVAL; struct kgsl_device *device = dev_priv->device; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); switch (type) { Loading Loading @@ -2502,6 +2546,28 @@ static int adreno_setproperty(struct kgsl_device *device, status = 0; } break; case KGSL_PROP_PWR_CONSTRAINT: { struct kgsl_device_constraint constraint; struct kgsl_context *context; if (sizebytes != sizeof(constraint)) break; if (copy_from_user(&constraint, value, sizeof(constraint))) { status = -EFAULT; break; } context = kgsl_context_get_owner(dev_priv, constraint.context_id); if (context == NULL) break; status = adreno_set_constraint(device, context, &constraint); kgsl_context_put(context); } break; default: break; } Loading drivers/gpu/msm/adreno_drawctxt.c +3 −2 Original line number Diff line number Diff line /* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2002,2007-2014, The Linux Foundation. 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 Loading Loading @@ -334,7 +334,8 @@ adreno_drawctxt_create(struct kgsl_device_private *dev_priv, KGSL_CONTEXT_NO_FAULT_TOLERANCE | KGSL_CONTEXT_CTX_SWITCH | KGSL_CONTEXT_PRIORITY_MASK | KGSL_CONTEXT_TYPE_MASK); KGSL_CONTEXT_TYPE_MASK | KGSL_CONTEXT_PWR_CONSTRAINT); /* Always enable per-context timestamps */ drawctxt->base.flags |= KGSL_CONTEXT_PER_CONTEXT_TS; Loading drivers/gpu/msm/adreno_ringbuffer.c +63 −1 Original line number Diff line number Diff line /* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2002,2007-2014, The Linux Foundation. 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 Loading Loading @@ -1102,6 +1102,65 @@ adreno_ringbuffer_issueibcmds(struct kgsl_device_private *dev_priv, return ret; } unsigned int adreno_ringbuffer_get_constraint(struct kgsl_device *device, struct kgsl_context *context) { unsigned int pwrlevel = device->pwrctrl.active_pwrlevel; switch (context->pwr_constraint.type) { case KGSL_CONSTRAINT_PWRLEVEL: { switch (context->pwr_constraint.sub_type) { case KGSL_CONSTRAINT_PWR_MAX: pwrlevel = device->pwrctrl.max_pwrlevel; break; case KGSL_CONSTRAINT_PWR_MIN: pwrlevel = device->pwrctrl.min_pwrlevel; break; default: break; } } break; } return pwrlevel; } void adreno_ringbuffer_set_constraint(struct kgsl_device *device, struct kgsl_cmdbatch *cmdbatch) { unsigned int constraint; struct kgsl_context *context = cmdbatch->context; /* * Check if the context has a constraint and constraint flags are * set. */ if (context->pwr_constraint.type && ((context->flags & KGSL_CONTEXT_PWR_CONSTRAINT) || (cmdbatch->flags & KGSL_CONTEXT_PWR_CONSTRAINT))) { constraint = adreno_ringbuffer_get_constraint(device, context); /* * If a constraint is already set, set a new * constraint only if it is faster */ if ((device->pwrctrl.constraint.type == KGSL_CONSTRAINT_NONE) || (constraint < device->pwrctrl.constraint.hint.pwrlevel.level)) { kgsl_pwrctrl_pwrlevel_change(device, constraint); device->pwrctrl.constraint.type = context->pwr_constraint.type; device->pwrctrl.constraint.hint. pwrlevel.level = constraint; } } } /* adreno_rindbuffer_submitcmd - submit userspace IBs to the GPU */ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev, struct kgsl_cmdbatch *cmdbatch) Loading Loading @@ -1212,6 +1271,9 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev, test_bit(ADRENO_DEVICE_PWRON_FIXUP, &adreno_dev->priv)) flags |= KGSL_CMD_FLAGS_PWRON_FIXUP; /* Set the constraints before adding to ringbuffer */ adreno_ringbuffer_set_constraint(device, cmdbatch); ret = adreno_ringbuffer_addcmds(&adreno_dev->ringbuffer, drawctxt, flags, Loading drivers/gpu/msm/kgsl.c +2 −2 Original line number Diff line number Diff line Loading @@ -1335,8 +1335,8 @@ long kgsl_ioctl_device_setproperty(struct kgsl_device_private *dev_priv, if (dev_priv->device->ftbl->setproperty) result = dev_priv->device->ftbl->setproperty( dev_priv->device, param->type, param->value, param->sizebytes); dev_priv, param->type, param->value, param->sizebytes); return result; } Loading drivers/gpu/msm/kgsl_device.h +4 −2 Original line number Diff line number Diff line /* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2002,2007-2014, The Linux Foundation. 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 Loading Loading @@ -136,7 +136,7 @@ struct kgsl_functable { void (*drawctxt_destroy) (struct kgsl_context *context); long (*ioctl) (struct kgsl_device_private *dev_priv, unsigned int cmd, void *data); int (*setproperty) (struct kgsl_device *device, int (*setproperty) (struct kgsl_device_private *dev_priv, enum kgsl_property_type type, void __user *value, unsigned int sizebytes); void (*drawctxt_sched)(struct kgsl_device *device, Loading Loading @@ -362,6 +362,7 @@ struct kgsl_process_private; * @pagefault_ts: global timestamp of the pagefault, if KGSL_CONTEXT_PAGEFAULT * is set. * @flags: flags from userspace controlling the behavior of this context * @pwr_constraint: power constraint from userspace for this context */ struct kgsl_context { struct kref refcount; Loading @@ -380,6 +381,7 @@ struct kgsl_context { struct list_head events_list; unsigned int pagefault_ts; unsigned int flags; struct kgsl_pwr_constraint pwr_constraint; }; /** Loading Loading
drivers/gpu/msm/adreno.c +67 −1 Original line number Diff line number Diff line Loading @@ -2460,12 +2460,56 @@ static int adreno_getproperty(struct kgsl_device *device, return status; } static int adreno_setproperty(struct kgsl_device *device, static int adreno_set_constraint(struct kgsl_device *device, struct kgsl_context *context, struct kgsl_device_constraint *constraint) { int status = 0; switch (constraint->type) { case KGSL_CONSTRAINT_PWRLEVEL: { struct kgsl_device_constraint_pwrlevel pwr; if (constraint->size != sizeof(pwr)) { status = -EINVAL; break; } if (copy_from_user(&pwr, (void __user *)constraint->data, sizeof(pwr))) { status = -EFAULT; break; } if (pwr.level >= KGSL_CONSTRAINT_PWR_MAXLEVELS) { status = -EINVAL; break; } context->pwr_constraint.type = KGSL_CONSTRAINT_PWRLEVEL; context->pwr_constraint.sub_type = pwr.level; } break; case KGSL_CONSTRAINT_NONE: context->pwr_constraint.type = KGSL_CONSTRAINT_NONE; break; default: status = -EINVAL; break; } return status; } static int adreno_setproperty(struct kgsl_device_private *dev_priv, enum kgsl_property_type type, void __user *value, unsigned int sizebytes) { int status = -EINVAL; struct kgsl_device *device = dev_priv->device; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); switch (type) { Loading Loading @@ -2502,6 +2546,28 @@ static int adreno_setproperty(struct kgsl_device *device, status = 0; } break; case KGSL_PROP_PWR_CONSTRAINT: { struct kgsl_device_constraint constraint; struct kgsl_context *context; if (sizebytes != sizeof(constraint)) break; if (copy_from_user(&constraint, value, sizeof(constraint))) { status = -EFAULT; break; } context = kgsl_context_get_owner(dev_priv, constraint.context_id); if (context == NULL) break; status = adreno_set_constraint(device, context, &constraint); kgsl_context_put(context); } break; default: break; } Loading
drivers/gpu/msm/adreno_drawctxt.c +3 −2 Original line number Diff line number Diff line /* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2002,2007-2014, The Linux Foundation. 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 Loading Loading @@ -334,7 +334,8 @@ adreno_drawctxt_create(struct kgsl_device_private *dev_priv, KGSL_CONTEXT_NO_FAULT_TOLERANCE | KGSL_CONTEXT_CTX_SWITCH | KGSL_CONTEXT_PRIORITY_MASK | KGSL_CONTEXT_TYPE_MASK); KGSL_CONTEXT_TYPE_MASK | KGSL_CONTEXT_PWR_CONSTRAINT); /* Always enable per-context timestamps */ drawctxt->base.flags |= KGSL_CONTEXT_PER_CONTEXT_TS; Loading
drivers/gpu/msm/adreno_ringbuffer.c +63 −1 Original line number Diff line number Diff line /* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2002,2007-2014, The Linux Foundation. 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 Loading Loading @@ -1102,6 +1102,65 @@ adreno_ringbuffer_issueibcmds(struct kgsl_device_private *dev_priv, return ret; } unsigned int adreno_ringbuffer_get_constraint(struct kgsl_device *device, struct kgsl_context *context) { unsigned int pwrlevel = device->pwrctrl.active_pwrlevel; switch (context->pwr_constraint.type) { case KGSL_CONSTRAINT_PWRLEVEL: { switch (context->pwr_constraint.sub_type) { case KGSL_CONSTRAINT_PWR_MAX: pwrlevel = device->pwrctrl.max_pwrlevel; break; case KGSL_CONSTRAINT_PWR_MIN: pwrlevel = device->pwrctrl.min_pwrlevel; break; default: break; } } break; } return pwrlevel; } void adreno_ringbuffer_set_constraint(struct kgsl_device *device, struct kgsl_cmdbatch *cmdbatch) { unsigned int constraint; struct kgsl_context *context = cmdbatch->context; /* * Check if the context has a constraint and constraint flags are * set. */ if (context->pwr_constraint.type && ((context->flags & KGSL_CONTEXT_PWR_CONSTRAINT) || (cmdbatch->flags & KGSL_CONTEXT_PWR_CONSTRAINT))) { constraint = adreno_ringbuffer_get_constraint(device, context); /* * If a constraint is already set, set a new * constraint only if it is faster */ if ((device->pwrctrl.constraint.type == KGSL_CONSTRAINT_NONE) || (constraint < device->pwrctrl.constraint.hint.pwrlevel.level)) { kgsl_pwrctrl_pwrlevel_change(device, constraint); device->pwrctrl.constraint.type = context->pwr_constraint.type; device->pwrctrl.constraint.hint. pwrlevel.level = constraint; } } } /* adreno_rindbuffer_submitcmd - submit userspace IBs to the GPU */ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev, struct kgsl_cmdbatch *cmdbatch) Loading Loading @@ -1212,6 +1271,9 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev, test_bit(ADRENO_DEVICE_PWRON_FIXUP, &adreno_dev->priv)) flags |= KGSL_CMD_FLAGS_PWRON_FIXUP; /* Set the constraints before adding to ringbuffer */ adreno_ringbuffer_set_constraint(device, cmdbatch); ret = adreno_ringbuffer_addcmds(&adreno_dev->ringbuffer, drawctxt, flags, Loading
drivers/gpu/msm/kgsl.c +2 −2 Original line number Diff line number Diff line Loading @@ -1335,8 +1335,8 @@ long kgsl_ioctl_device_setproperty(struct kgsl_device_private *dev_priv, if (dev_priv->device->ftbl->setproperty) result = dev_priv->device->ftbl->setproperty( dev_priv->device, param->type, param->value, param->sizebytes); dev_priv, param->type, param->value, param->sizebytes); return result; } Loading
drivers/gpu/msm/kgsl_device.h +4 −2 Original line number Diff line number Diff line /* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2002,2007-2014, The Linux Foundation. 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 Loading Loading @@ -136,7 +136,7 @@ struct kgsl_functable { void (*drawctxt_destroy) (struct kgsl_context *context); long (*ioctl) (struct kgsl_device_private *dev_priv, unsigned int cmd, void *data); int (*setproperty) (struct kgsl_device *device, int (*setproperty) (struct kgsl_device_private *dev_priv, enum kgsl_property_type type, void __user *value, unsigned int sizebytes); void (*drawctxt_sched)(struct kgsl_device *device, Loading Loading @@ -362,6 +362,7 @@ struct kgsl_process_private; * @pagefault_ts: global timestamp of the pagefault, if KGSL_CONTEXT_PAGEFAULT * is set. * @flags: flags from userspace controlling the behavior of this context * @pwr_constraint: power constraint from userspace for this context */ struct kgsl_context { struct kref refcount; Loading @@ -380,6 +381,7 @@ struct kgsl_context { struct list_head events_list; unsigned int pagefault_ts; unsigned int flags; struct kgsl_pwr_constraint pwr_constraint; }; /** Loading