int kgsl_g12_cmdstream_start(struct kgsl_device *device)
{
	struct kgsl_g12_device *g12_device = (struct kgsl_g12_device *) device;
	int result;
	unsigned int cmd = VGV3_NEXTCMD_JUMP << VGV3_NEXTCMD_NEXTCMD_FSHIFT;

	g12_device->timestamp = 0;
	g12_device->current_timestamp = 0;

	addmarker(&g12_device->ringbuffer, 0);

	result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D,
			ADDR_VGV3_MODE, 4);
	if (result != 0)
		return result;

	result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D,
			ADDR_VGV3_NEXTADDR,
			g12_device->ringbuffer.cmdbufdesc.gpuaddr);
	if (result != 0)
		return result;

	result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D,
			ADDR_VGV3_NEXTCMD, cmd | 5);
	if (result != 0)
		return result;

	result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D,
			ADDR_VGV3_WRITEADDR, device->memstore.gpuaddr);

	if (result != 0)
		return result;

	cmd = (int)(((1) & VGV3_CONTROL_MARKADD_FMASK)
			<< VGV3_CONTROL_MARKADD_FSHIFT);

	result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D,
			ADDR_VGV3_CONTROL, cmd);

	if (result != 0)
		return result;

	result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D,
			ADDR_VGV3_CONTROL, 0);
	if (result != 0)
		return result;

	return result;
}
int
kgsl_g12_cmdstream_issueibcmds(struct kgsl_device_private *dev_priv,
			struct kgsl_context *context,
			struct kgsl_ibdesc *ibdesc,
			unsigned int numibs,
			uint32_t *timestamp,
			unsigned int ctrl)
{
	int result = 0;
	unsigned int ofs        = PACKETSIZE_STATESTREAM * sizeof(unsigned int);
	unsigned int cnt        = 5;
	unsigned int nextaddr   = 0;
	unsigned int index	= 0;
	unsigned int nextindex;
	unsigned int nextcnt    = KGSL_G12_STREAM_END_CMD | 5;
	struct kgsl_memdesc tmp = {0};
	unsigned int cmd;
	struct kgsl_device *device = dev_priv->device;
	struct kgsl_pagetable *pagetable = dev_priv->process_priv->pagetable;
	struct kgsl_g12_device *g12_device = KGSL_G12_DEVICE(device);
	unsigned int sizedwords;

	if (device->state & KGSL_STATE_HUNG) {
		return -EINVAL;
		goto error;
	}
	if (numibs != 1) {
		KGSL_DRV_ERR(device, "Invalid number of ibs: %d\n", numibs);
		result = -EINVAL;
		goto error;
	}
	cmd = ibdesc[0].gpuaddr;
	sizedwords = ibdesc[0].sizedwords;

	tmp.hostptr = (void *)*timestamp;

	KGSL_CMD_INFO(device, "ctxt %d ibaddr 0x%08x sizedwords %d\n",
		context->id, cmd, sizedwords);
	/* context switch */
	if ((context->id != (int)g12_device->ringbuffer.prevctx) ||
	    (ctrl & KGSL_CONTEXT_CTX_SWITCH)) {
		KGSL_CMD_INFO(device, "context switch %d -> %d\n",
			context->id, g12_device->ringbuffer.prevctx);
		kgsl_mmu_setstate(device, pagetable);
		cnt = PACKETSIZE_STATESTREAM;
		ofs = 0;
	}
	kgsl_g12_setstate(device, kgsl_pt_get_flags(device->mmu.hwpagetable,
						    device->id));

	result = wait_event_interruptible_timeout(device->wait_queue,
				  room_in_rb(g12_device),
				  msecs_to_jiffies(KGSL_TIMEOUT_DEFAULT));
	if (result <= 0) {
		KGSL_CMD_ERR(device, "wait_event_interruptible_timeout "
			"failed: %d\n", result);
		goto error;
	}
	result = 0;

	index = g12_device->current_timestamp % KGSL_G12_PACKET_COUNT;
	g12_device->current_timestamp++;
	nextindex = g12_device->current_timestamp % KGSL_G12_PACKET_COUNT;
	*timestamp = g12_device->current_timestamp;

	g12_device->ringbuffer.prevctx = context->id;

	addcmd(&g12_device->ringbuffer, index, cmd + ofs, cnt);

	/* Make sure the next ringbuffer entry has a marker */
	addmarker(&g12_device->ringbuffer, nextindex);

	nextaddr = g12_device->ringbuffer.cmdbufdesc.gpuaddr
		+ rb_offset(nextindex);

	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 memory before activating the hardware for the new command*/
	mb();

	cmd = (int)(((2) & VGV3_CONTROL_MARKADD_FMASK)
		<< VGV3_CONTROL_MARKADD_FSHIFT);

	kgsl_g12_cmdwindow_write(device,
				KGSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, cmd);
	kgsl_g12_cmdwindow_write(device,
				KGSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, 0);
error:
	return result;
}
int
kgsl_g12_cmdstream_issueibcmds(struct kgsl_device_private *dev_priv,
			int drawctxt_index,
			uint32_t ibaddr,
			int sizedwords,
			uint32_t *timestamp,
			unsigned int ctrl)
{
	unsigned int result = 0;
	unsigned int ofs        = PACKETSIZE_STATESTREAM * sizeof(unsigned int);
	unsigned int cnt        = 5;
	unsigned int nextaddr   = 0;
	unsigned int index	= 0;
	unsigned int nextindex;
	unsigned int nextcnt    = KGSL_G12_STREAM_END_CMD | 5;
	struct kgsl_memdesc tmp = {0};
	unsigned int cmd;
	struct kgsl_device *device = dev_priv->device;
	struct kgsl_pagetable *pagetable = dev_priv->process_priv->pagetable;
	struct kgsl_g12_device *g12_device = (struct kgsl_g12_device *) device;

	cmd = ibaddr;

	tmp.hostptr = (void *)*timestamp;

	KGSL_CMD_INFO("ctxt %d ibaddr 0x%08x sizedwords %d",
		      drawctxt_index, ibaddr, sizedwords);
	/* context switch */
	if (drawctxt_index != (int)g12_device->ringbuffer.prevctx) {
		KGSL_CMD_INFO("context switch %d -> %d",
				drawctxt_index, g12_device->ringbuffer.prevctx);
		kgsl_mmu_setstate(device, pagetable);
		cnt = PACKETSIZE_STATESTREAM;
		ofs = 0;
	}
	kgsl_g12_setstate(device, kgsl_pt_get_flags(device->mmu.hwpagetable,
						    device->id));

	result = wait_event_interruptible_timeout(g12_device->wait_timestamp_wq,
				  room_in_rb(g12_device),
				  msecs_to_jiffies(KGSL_TIMEOUT_DEFAULT));
	if (result < 0) {
		KGSL_CMD_ERR("failed waiting for ringbuffer. result %d",
			     result);
		goto error;
	}
	result = 0;

	index = g12_device->current_timestamp % KGSL_G12_PACKET_COUNT;
	g12_device->current_timestamp++;
	nextindex = g12_device->current_timestamp % KGSL_G12_PACKET_COUNT;
	*timestamp = g12_device->current_timestamp;

	g12_device->ringbuffer.prevctx = drawctxt_index;

	addcmd(&g12_device->ringbuffer, index, cmd + ofs, cnt);

	/* Make sure the next ringbuffer entry has a marker */
	addmarker(&g12_device->ringbuffer, nextindex);

	nextaddr = g12_device->ringbuffer.cmdbufdesc.gpuaddr
		+ rb_offset(nextindex);

	tmp.hostptr = (void *)(tmp.hostptr +
			(sizedwords * sizeof(unsigned int)));
	tmp.size = 12;

	kgsl_sharedmem_writel(&tmp, 4, nextaddr);
	kgsl_sharedmem_writel(&tmp, 8, nextcnt);

	cmd = (int)(((2) & VGV3_CONTROL_MARKADD_FMASK)
		<< VGV3_CONTROL_MARKADD_FSHIFT);

	kgsl_g12_cmdwindow_write(device,
				KGSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, cmd);
	kgsl_g12_cmdwindow_write(device,
				KGSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, 0);
error:
	return result;
}
示例#4
0
int
kgsl_g12_drawctxt_create(struct kgsl_device *device,
			uint32_t ctxt_id_mask,
			unsigned int *drawctxt_id)
{
	int i;
	int cmd;
	int result;
	unsigned int ctx_id;

	if (g_z1xx.numcontext == 0) {
		for (i = 0; i < GSL_HAL_NUMCMDBUFFERS; i++) {
			int flags = 0;
			if (kgsl_sharedmem_alloc(flags, GSL_HAL_CMDBUFFERSIZE,
					&g_z1xx.cmdbufdesc[i]) !=  0)
				return -ENOMEM;


			g_z1xx.cmdbuf[i] = kzalloc(GSL_HAL_CMDBUFFERSIZE,
						   GFP_KERNEL);


			g_z1xx.curr = i;
			g_z1xx.offs = 0;
			addmarker(&g_z1xx);
			kgsl_sharedmem_write(&g_z1xx.cmdbufdesc[i], 0,
					 g_z1xx.cmdbuf[i],
					 (512 + 13) *
					 sizeof(unsigned int));
		}
		g_z1xx.curr = 0;
		cmd = (int)(((VGV3_NEXTCMD_JUMP) &
			VGV3_NEXTCMD_NEXTCMD_FMASK)
			<< VGV3_NEXTCMD_NEXTCMD_FSHIFT);

		/* set cmd stream buffer to hw */
		result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D,
					 ADDR_VGV3_MODE, 4);
		if (result != 0)
			return result;
		result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D,
					 ADDR_VGV3_NEXTADDR,
					 g_z1xx.cmdbufdesc[0].physaddr);
		if (result != 0)
			return result;
		result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D,
					 ADDR_VGV3_NEXTCMD, cmd | 5);
		if (result != 0)
			return result;

		cmd = (int)(((1) & VGV3_CONTROL_MARKADD_FMASK)
			<< VGV3_CONTROL_MARKADD_FSHIFT);
		result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D,
					 ADDR_VGV3_CONTROL, cmd);
		if (result != 0)
			return result;
		result = kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D,
					 ADDR_VGV3_CONTROL, 0);
		if (result != 0)
			return result;
	}
	ctx_id = ffz(ctxt_id_mask);

	g_z1xx.numcontext++;
	if (g_z1xx.numcontext > KGSL_G12_CONTEXT_MAX) {
		*drawctxt_id = 0;
		return KGSL_FAILURE;

	}
	*drawctxt_id = ctx_id;

	return KGSL_SUCCESS;
}