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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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);
		}
	}
}