struct kgsl_context * adreno_drawctxt_create(struct kgsl_device_private *dev_priv, uint32_t *flags) { struct adreno_context *drawctxt; struct kgsl_device *device = dev_priv->device; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); int ret; drawctxt = kzalloc(sizeof(struct adreno_context), GFP_KERNEL); if (drawctxt == NULL) return ERR_PTR(-ENOMEM); ret = kgsl_context_init(dev_priv, &drawctxt->base); if (ret != 0) { kfree(drawctxt); return ERR_PTR(ret); } drawctxt->bin_base_offset = 0; drawctxt->timestamp = 0; drawctxt->base.flags = *flags & (KGSL_CONTEXT_PREAMBLE | KGSL_CONTEXT_NO_GMEM_ALLOC | KGSL_CONTEXT_PER_CONTEXT_TS | KGSL_CONTEXT_USER_GENERATED_TS | KGSL_CONTEXT_NO_FAULT_TOLERANCE | KGSL_CONTEXT_TYPE_MASK); drawctxt->base.flags |= KGSL_CONTEXT_PER_CONTEXT_TS; drawctxt->type = (drawctxt->base.flags & KGSL_CONTEXT_TYPE_MASK) >> KGSL_CONTEXT_TYPE_SHIFT; mutex_init(&drawctxt->mutex); init_waitqueue_head(&drawctxt->wq); init_waitqueue_head(&drawctxt->waiting); plist_node_init(&drawctxt->pending, ADRENO_CONTEXT_DEFAULT_PRIORITY); if (adreno_dev->gpudev->ctxt_create) { ret = adreno_dev->gpudev->ctxt_create(adreno_dev, drawctxt); if (ret) goto err; } else if ((drawctxt->base.flags & KGSL_CONTEXT_PREAMBLE) == 0 || (drawctxt->base.flags & KGSL_CONTEXT_NO_GMEM_ALLOC) == 0) { KGSL_DEV_ERR_ONCE(device, "legacy context switch not supported\n"); ret = -EINVAL; goto err; } else { drawctxt->ops = &adreno_preamble_ctx_ops; } kgsl_sharedmem_writel(device, &device->memstore, KGSL_MEMSTORE_OFFSET(drawctxt->base.id, soptimestamp), 0); kgsl_sharedmem_writel(device, &device->memstore, KGSL_MEMSTORE_OFFSET(drawctxt->base.id, eoptimestamp), 0); *flags = drawctxt->base.flags; return &drawctxt->base; err: kgsl_context_detach(&drawctxt->base); return ERR_PTR(ret); }
/** * adreno_drawctxt_create - create a new adreno draw context * @dev_priv: the owner of the context * @flags: flags for the context (passed from user space) * * Create and return a new draw context for the 3D core. */ struct kgsl_context * adreno_drawctxt_create(struct kgsl_device_private *dev_priv, uint32_t *flags) { struct adreno_context *drawctxt; struct kgsl_device *device = dev_priv->device; int ret; drawctxt = kzalloc(sizeof(struct adreno_context), GFP_KERNEL); if (drawctxt == NULL) return ERR_PTR(-ENOMEM); ret = kgsl_context_init(dev_priv, &drawctxt->base); if (ret != 0) { kfree(drawctxt); return ERR_PTR(ret); } drawctxt->timestamp = 0; drawctxt->base.flags = *flags & (KGSL_CONTEXT_PREAMBLE | KGSL_CONTEXT_NO_GMEM_ALLOC | KGSL_CONTEXT_PER_CONTEXT_TS | KGSL_CONTEXT_USER_GENERATED_TS | KGSL_CONTEXT_NO_FAULT_TOLERANCE | KGSL_CONTEXT_CTX_SWITCH | KGSL_CONTEXT_PRIORITY_MASK | KGSL_CONTEXT_TYPE_MASK | KGSL_CONTEXT_PWR_CONSTRAINT); /* Always enable per-context timestamps */ drawctxt->base.flags |= KGSL_CONTEXT_PER_CONTEXT_TS; drawctxt->type = (drawctxt->base.flags & KGSL_CONTEXT_TYPE_MASK) >> KGSL_CONTEXT_TYPE_SHIFT; mutex_init(&drawctxt->mutex); init_waitqueue_head(&drawctxt->wq); init_waitqueue_head(&drawctxt->waiting); /* Set the context priority */ _set_context_priority(drawctxt); /* * Set up the plist node for the dispatcher. Insert the node into the * drawctxt pending list based on priority. */ plist_node_init(&drawctxt->pending, drawctxt->base.priority); if ((drawctxt->base.flags & KGSL_CONTEXT_PREAMBLE) == 0 || (drawctxt->base.flags & KGSL_CONTEXT_NO_GMEM_ALLOC) == 0) { KGSL_DEV_ERR_ONCE(device, "legacy context switch not supported\n"); ret = -EINVAL; goto err; } kgsl_sharedmem_writel(device, &device->memstore, KGSL_MEMSTORE_OFFSET(drawctxt->base.id, soptimestamp), 0); kgsl_sharedmem_writel(device, &device->memstore, KGSL_MEMSTORE_OFFSET(drawctxt->base.id, eoptimestamp), 0); /* copy back whatever flags we dediced were valid */ *flags = drawctxt->base.flags; return &drawctxt->base; err: kgsl_context_detach(&drawctxt->base); return ERR_PTR(ret); }
/** * adreno_drawctxt_create - create a new adreno draw context * @dev_priv: the owner of the context * @flags: flags for the context (passed from user space) * * Create and return a new draw context for the 3D core. */ struct kgsl_context * adreno_drawctxt_create(struct kgsl_device_private *dev_priv, uint32_t *flags) { struct adreno_context *drawctxt; struct kgsl_device *device = dev_priv->device; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); int ret; drawctxt = kzalloc(sizeof(struct adreno_context), GFP_KERNEL); if (drawctxt == NULL) return ERR_PTR(-ENOMEM); ret = kgsl_context_init(dev_priv, &drawctxt->base); if (ret != 0) { kfree(drawctxt); return ERR_PTR(ret); } drawctxt->bin_base_offset = 0; drawctxt->timestamp = 0; drawctxt->base.flags = *flags & (KGSL_CONTEXT_PREAMBLE | KGSL_CONTEXT_NO_GMEM_ALLOC | KGSL_CONTEXT_PER_CONTEXT_TS | KGSL_CONTEXT_USER_GENERATED_TS | KGSL_CONTEXT_NO_FAULT_TOLERANCE | KGSL_CONTEXT_TYPE_MASK); /* Always enable per-context timestamps */ drawctxt->base.flags |= KGSL_CONTEXT_PER_CONTEXT_TS; mutex_init(&drawctxt->mutex); init_waitqueue_head(&drawctxt->wq); init_waitqueue_head(&drawctxt->waiting); /* * Set up the plist node for the dispatcher. For now all contexts have * the same priority, but later the priority will be set at create time * by the user */ plist_node_init(&drawctxt->pending, ADRENO_CONTEXT_DEFAULT_PRIORITY); if (adreno_dev->gpudev->ctxt_create) { ret = adreno_dev->gpudev->ctxt_create(adreno_dev, drawctxt); if (ret) goto err; } else if ((drawctxt->base.flags & KGSL_CONTEXT_PREAMBLE) == 0 || (drawctxt->base.flags & KGSL_CONTEXT_NO_GMEM_ALLOC) == 0) { KGSL_DEV_ERR_ONCE(device, "legacy context switch not supported\n"); ret = -EINVAL; goto err; } else { drawctxt->ops = &adreno_preamble_ctx_ops; } kgsl_sharedmem_writel(device, &device->memstore, KGSL_MEMSTORE_OFFSET(drawctxt->base.id, soptimestamp), 0); kgsl_sharedmem_writel(device, &device->memstore, KGSL_MEMSTORE_OFFSET(drawctxt->base.id, eoptimestamp), 0); /* copy back whatever flags we dediced were valid */ *flags = drawctxt->base.flags; return &drawctxt->base; err: kgsl_context_detach(&drawctxt->base); return ERR_PTR(ret); }