int adreno_drawctxt_switch(struct adreno_device *adreno_dev, struct adreno_context *drawctxt, unsigned int flags) { struct kgsl_device *device = &adreno_dev->dev; int ret = 0; /* already current? */ if (adreno_dev->drawctxt_active == drawctxt) return ret; trace_adreno_drawctxt_switch(adreno_dev->drawctxt_active, drawctxt, flags); /* Get a refcount to the new instance */ if (drawctxt) { if (!_kgsl_context_get(&drawctxt->base)) return -EINVAL; ret = kgsl_mmu_setstate(&device->mmu, drawctxt->base.proc_priv->pagetable, adreno_dev->drawctxt_active ? adreno_dev->drawctxt_active->base.id : KGSL_CONTEXT_INVALID); /* Set the new context */ ret = adreno_context_restore(adreno_dev, drawctxt); if (ret) { KGSL_DRV_ERR(device, "Error in GPU context %d restore: %d\n", drawctxt->base.id, ret); return ret; } } else { /* * No context - set the default pagetable and thats it. * If there isn't a current context, the kgsl_mmu_setstate * will use the CPU path so we don't need to give * it a valid context id. */ ret = kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable, adreno_dev->drawctxt_active->base.id); } /* Put the old instance of the active drawctxt */ if (adreno_dev->drawctxt_active) kgsl_context_put(&adreno_dev->drawctxt_active->base); adreno_dev->drawctxt_active = drawctxt; return 0; }
int adreno_drawctxt_switch(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb, struct adreno_context *drawctxt, unsigned int flags) { struct kgsl_device *device = &adreno_dev->dev; struct kgsl_pagetable *new_pt; int ret = 0; /* We always expect a valid rb */ BUG_ON(!rb); /* already current? */ if (rb->drawctxt_active == drawctxt) return ret; trace_adreno_drawctxt_switch(rb, drawctxt, flags); /* Get a refcount to the new instance */ if (drawctxt) { if (!_kgsl_context_get(&drawctxt->base)) return -EINVAL; new_pt = drawctxt->base.proc_priv->pagetable; } else { /* No context - set the default pagetable and thats it. */ new_pt = device->mmu.defaultpagetable; } ret = adreno_iommu_set_pt(rb, new_pt); if (ret) { KGSL_DRV_ERR(device, "Failed to set pagetable on rb %d\n", rb->id); return ret; } /* Put the old instance of the active drawctxt */ if (rb->drawctxt_active) kgsl_context_put(&rb->drawctxt_active->base); rb->drawctxt_active = drawctxt; /* Set the new context */ adreno_context_restore(rb); return 0; }
int adreno_drawctxt_switch(struct adreno_device *adreno_dev, struct adreno_context *drawctxt, unsigned int flags) { struct kgsl_device *device = &adreno_dev->dev; int ret = 0; if (drawctxt) { if (flags & KGSL_CONTEXT_SAVE_GMEM) set_bit(ADRENO_CONTEXT_GMEM_SAVE, &drawctxt->priv); else clear_bit(ADRENO_CONTEXT_GMEM_SAVE, &drawctxt->priv); } if (adreno_dev->drawctxt_active == drawctxt) { if (drawctxt && drawctxt->ops->draw_workaround) ret = drawctxt->ops->draw_workaround(adreno_dev, drawctxt); return ret; } trace_adreno_drawctxt_switch(adreno_dev->drawctxt_active, drawctxt, flags); if (adreno_dev->drawctxt_active) { ret = context_save(adreno_dev, adreno_dev->drawctxt_active); if (ret) { KGSL_DRV_ERR(device, "Error in GPU context %d save: %d\n", adreno_dev->drawctxt_active->base.id, ret); return ret; } } if (drawctxt) { if (!_kgsl_context_get(&drawctxt->base)) return -EINVAL; ret = kgsl_mmu_setstate(&device->mmu, drawctxt->base.proc_priv->pagetable, adreno_dev->drawctxt_active ? adreno_dev->drawctxt_active->base.id : KGSL_CONTEXT_INVALID); ret = drawctxt->ops->restore(adreno_dev, drawctxt); if (ret) { KGSL_DRV_ERR(device, "Error in GPU context %d restore: %d\n", drawctxt->base.id, ret); return ret; } } else { ret = kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable, adreno_dev->drawctxt_active->base.id); } if (adreno_dev->drawctxt_active) kgsl_context_put(&adreno_dev->drawctxt_active->base); adreno_dev->drawctxt_active = drawctxt; return 0; }
int adreno_drawctxt_switch(struct adreno_device *adreno_dev, struct adreno_context *drawctxt, unsigned int flags) { struct kgsl_device *device = &adreno_dev->dev; int ret = 0; if (drawctxt) { /* * Handle legacy gmem / save restore flag on each IB. * Userspace sets to guard IB sequences that require * gmem to be saved and clears it at the end of the * sequence. */ if (flags & KGSL_CONTEXT_SAVE_GMEM) /* Set the flag in context so that the save is done * when this context is switched out. */ set_bit(ADRENO_CONTEXT_GMEM_SAVE, &drawctxt->priv); else /* Remove GMEM saving flag from the context */ clear_bit(ADRENO_CONTEXT_GMEM_SAVE, &drawctxt->priv); } /* already current? */ if (adreno_dev->drawctxt_active == drawctxt) { if (drawctxt && drawctxt->ops->draw_workaround) ret = drawctxt->ops->draw_workaround(adreno_dev, drawctxt); return ret; } trace_adreno_drawctxt_switch(adreno_dev->drawctxt_active, drawctxt, flags); /* Get a refcount to the new instance */ if (drawctxt) { if (!_kgsl_context_get(&drawctxt->base)) return -EINVAL; ret = kgsl_mmu_setstate(&device->mmu, drawctxt->base.proc_priv->pagetable, adreno_dev->drawctxt_active ? adreno_dev->drawctxt_active->base.id : KGSL_CONTEXT_INVALID); /* Set the new context */ ret = drawctxt->ops->restore(adreno_dev, drawctxt); if (ret) { KGSL_DRV_ERR(device, "Error in GPU context %d restore: %d\n", drawctxt->base.id, ret); return ret; } } else { /* * No context - set the default pagetable and thats it. * If there isn't a current context, the kgsl_mmu_setstate * will use the CPU path so we don't need to give * it a valid context id. */ ret = kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable, adreno_dev->drawctxt_active->base.id); } /* Put the old instance of the active drawctxt */ if (adreno_dev->drawctxt_active) kgsl_context_put(&adreno_dev->drawctxt_active->base); adreno_dev->drawctxt_active = drawctxt; return 0; }