void adreno_drawctxt_destroy(struct kgsl_device *device, struct kgsl_context *context) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct adreno_context *drawctxt; if (context == NULL || context->devctxt == NULL) return; drawctxt = context->devctxt; /* deactivate context */ if (adreno_dev->drawctxt_active == drawctxt) { /* no need to save GMEM or shader, the context is * being destroyed. */ drawctxt->flags &= ~(CTXT_FLAGS_GMEM_SAVE | CTXT_FLAGS_SHADER_SAVE | CTXT_FLAGS_GMEM_SHADOW | CTXT_FLAGS_STATE_SHADOW); adreno_drawctxt_switch(adreno_dev, NULL, 0); } adreno_idle(device); if (adreno_is_a20x(adreno_dev) && adreno_dev->drawctxt_active) kgsl_setstate(&device->mmu, adreno_dev->drawctxt_active->id, KGSL_MMUFLAGS_PTUPDATE); kgsl_sharedmem_free(&drawctxt->gpustate); kgsl_sharedmem_free(&drawctxt->context_gmem_shadow.gmemshadow); kfree(drawctxt); context->devctxt = NULL; }
int kgsl_g12_cmdstream_issueibcmds(struct kgsl_device *device, struct kgsl_pagetable *pagetable, int drawctxt_index, uint32_t ibaddr, int sizedwords, int *timestamp, unsigned int ctrl) { unsigned int ofs = PACKETSIZE_STATESTREAM * sizeof(unsigned int); unsigned int cnt = 5; unsigned int nextbuf = (g_z1xx.curr + 1) % GSL_HAL_NUMCMDBUFFERS; unsigned int nextaddr = g_z1xx.cmdbufdesc[nextbuf].physaddr; unsigned int nextcnt = 0x9000 | 5; struct kgsl_memdesc tmp = {0}; unsigned int cmd; cmd = ibaddr; tmp.hostptr = (void *)*timestamp; /* context switch */ if (drawctxt_index != (int)g_z1xx.prevctx) { kgsl_mmu_setstate(device, pagetable); cnt = PACKETSIZE_STATESTREAM; ofs = 0; } else { kgsl_setstate(device, device->mmu.tlb_flags); } device->current_timestamp++; *timestamp = device->current_timestamp; g_z1xx.prevctx = drawctxt_index; g_z1xx.offs = 10; beginpacket(&g_z1xx, cmd + ofs, cnt); tmp.hostptr = (void *)(tmp.hostptr + (sizedwords * sizeof(unsigned int))); tmp.size = 12; kgsl_sharedmem_writel(&tmp, 4, nextaddr); kgsl_sharedmem_writel(&tmp, 8, nextcnt); /* sync mem */ kgsl_sharedmem_write((const struct kgsl_memdesc *) &g_z1xx.cmdbufdesc[g_z1xx.curr], 0, g_z1xx.cmdbuf[g_z1xx.curr], (512 + 13) * sizeof(unsigned int)); g_z1xx.offs = 0; g_z1xx.curr = nextbuf; kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, ctrl); kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, 0); return KGSL_SUCCESS; }
void adreno_drawctxt_destroy(struct kgsl_device *device, struct kgsl_context *context) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct adreno_context *drawctxt; if (context == NULL || context->devctxt == NULL) return; drawctxt = context->devctxt; if (adreno_dev->drawctxt_active == drawctxt) { drawctxt->flags &= ~(CTXT_FLAGS_GMEM_SAVE | CTXT_FLAGS_SHADER_SAVE | CTXT_FLAGS_GMEM_SHADOW | CTXT_FLAGS_STATE_SHADOW); #ifdef CONFIG_MSM_KGSL_GPU_USAGE device->current_process_priv = NULL; #endif adreno_drawctxt_switch(adreno_dev, NULL, 0); } if (device->state != KGSL_STATE_HUNG) adreno_idle(device); if (adreno_is_a20x(adreno_dev) && adreno_dev->drawctxt_active) kgsl_setstate(&device->mmu, adreno_dev->drawctxt_active->id, KGSL_MMUFLAGS_PTUPDATE); kgsl_sharedmem_free(&drawctxt->gpustate); kgsl_sharedmem_free(&drawctxt->context_gmem_shadow.gmemshadow); kfree(drawctxt); context->devctxt = NULL; }
static void kgsl_iommu_setstate(struct kgsl_mmu *mmu, struct kgsl_pagetable *pagetable, unsigned int context_id) { if (mmu->flags & KGSL_FLAGS_STARTED) { if (mmu->hwpagetable != pagetable) { unsigned int flags = 0; mmu->hwpagetable = pagetable; flags |= kgsl_mmu_pt_get_flags(mmu->hwpagetable, mmu->device->id) | KGSL_MMUFLAGS_TLBFLUSH; kgsl_setstate(mmu, context_id, KGSL_MMUFLAGS_PTUPDATE | flags); } } }
int kgsl_g12_drawctxt_destroy(struct kgsl_device *device, struct kgsl_context *context) { struct kgsl_g12_device *g12_device = KGSL_G12_DEVICE(device); kgsl_g12_idle(device, KGSL_TIMEOUT_DEFAULT); if (g12_device->ringbuffer.prevctx == context->id) { g12_device->ringbuffer.prevctx = KGSL_G12_INVALID_CONTEXT; device->mmu.hwpagetable = device->mmu.defaultpagetable; kgsl_setstate(device, KGSL_MMUFLAGS_PTUPDATE); } return 0; }
static void kgsl_iommu_setstate(struct kgsl_mmu *mmu, struct kgsl_pagetable *pagetable, unsigned int context_id) { if (mmu->flags & KGSL_FLAGS_STARTED) { struct kgsl_iommu *iommu = mmu->priv; struct kgsl_iommu_pt *iommu_pt = pagetable->priv; /* page table not current, then setup mmu to use new * specified page table */ if (mmu->hwpagetable != pagetable) { unsigned int flags = 0; mmu->hwpagetable = pagetable; /* force tlb flush if asid is reused */ if (iommu->asid_reuse && (KGSL_IOMMU_ASID_REUSE == iommu_pt->asid)) flags |= KGSL_MMUFLAGS_TLBFLUSH; flags |= kgsl_mmu_pt_get_flags(mmu->hwpagetable, mmu->device->id); kgsl_setstate(mmu, context_id, KGSL_MMUFLAGS_PTUPDATE | flags); } } }