Exemplo n.º 1
0
void omap_get_vrfb_buffer(__u32 paddr)
{
	int i = 0;
	int j = 0;

	if (have_vrfb_ctx >= VRFB_NUM_SLOTS)
		return;

	for (i = 0; i < VRFB_NUM_SLOTS; i++) {
		if (ion_vrfb_t[i].ba == 0) {
			if (omap_vrfb_request_ctx
				(&ion_vrfb_t[i].vrfb_context)) {
				pr_err("%s:VRFB allocation failed\n", __func__);
				for (j = 0; j < VRFB_NUM_SLOTS; j++)
					if (ion_vrfb_t[j].ba) {
						omap_vrfb_release_ctx(
						&ion_vrfb_t[j].vrfb_context);
						ion_vrfb_t[j].ba = 0;
						ion_vrfb_t[j].ismapped = 0;
						have_vrfb_ctx--;
				}
			return ;
			}
			ion_vrfb_t[i].ba = paddr;
			ion_vrfb_t[i].ismapped = 0;
			have_vrfb_ctx++;
			break;
		}
	}

	return;
}
Exemplo n.º 2
0
int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num,
			      bool static_vrfb_allocation)
{
	int ret = 0, i, j;
	struct omap_vout_device *vout;
	struct video_device *vfd;
	int image_width, image_height;
	int vrfb_num_bufs = VRFB_NUM_BUFS;
	struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
	struct omap2video_device *vid_dev =
		container_of(v4l2_dev, struct omap2video_device, v4l2_dev);

	vout = vid_dev->vouts[vid_num];
	vfd = vout->vfd;

	for (i = 0; i < VRFB_NUM_BUFS; i++) {
		if (omap_vrfb_request_ctx(&vout->vrfb_context[i])) {
			dev_info(&pdev->dev, ": VRFB allocation failed\n");
			for (j = 0; j < i; j++)
				omap_vrfb_release_ctx(&vout->vrfb_context[j]);
			ret = -ENOMEM;
			goto free_buffers;
		}
	}

	/* Calculate VRFB memory size */
	/* allocate for worst case size */
	image_width = VID_MAX_WIDTH / TILE_SIZE;
	if (VID_MAX_WIDTH % TILE_SIZE)
		image_width++;

	image_width = image_width * TILE_SIZE;
	image_height = VID_MAX_HEIGHT / TILE_SIZE;

	if (VID_MAX_HEIGHT % TILE_SIZE)
		image_height++;

	image_height = image_height * TILE_SIZE;
	vout->smsshado_size = PAGE_ALIGN(image_width * image_height * 2 * 2);

	/*
	 * Request and Initialize DMA, for DMA based VRFB transfer
	 */
	vout->vrfb_dma_tx.dev_id = OMAP_DMA_NO_DEVICE;
	vout->vrfb_dma_tx.dma_ch = -1;
	vout->vrfb_dma_tx.req_status = DMA_CHAN_ALLOTED;
	ret = omap_request_dma(vout->vrfb_dma_tx.dev_id, "VRFB DMA TX",
			omap_vout_vrfb_dma_tx_callback,
			(void *) &vout->vrfb_dma_tx, &vout->vrfb_dma_tx.dma_ch);
	if (ret < 0) {
		vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED;
		dev_info(&pdev->dev, ": failed to allocate DMA Channel for"
				" video%d\n", vfd->minor);
	}
	init_waitqueue_head(&vout->vrfb_dma_tx.wait);

	/* statically allocated the VRFB buffer is done through
	   commands line aruments */
	if (static_vrfb_allocation) {
		if (omap_vout_allocate_vrfb_buffers(vout, &vrfb_num_bufs, -1)) {
			ret =  -ENOMEM;
			goto release_vrfb_ctx;
		}
		vout->vrfb_static_allocation = 1;
	}
	return 0;

release_vrfb_ctx:
	for (j = 0; j < VRFB_NUM_BUFS; j++)
		omap_vrfb_release_ctx(&vout->vrfb_context[j]);
free_buffers:
	omap_vout_free_buffers(vout);

	return ret;
}
Exemplo n.º 3
0
static int omapvout_dss_acquire_vrfb(struct omapvout_device *vout)
{
	int rc = 0;
	int size;
	int w, h;
	int max_pixels;
	struct omapvout_dss_vrfb *vrfb;

	/* It is assumed that the caller has locked the vout mutex */

	vrfb = &vout->dss->vrfb;
	vrfb->dma_id = OMAP_DMA_NO_DEVICE;
	vrfb->dma_ch = -1;
	vrfb->req_status = DMA_CHAN_NOT_ALLOTED;
	vrfb->next = 0;

	rc = omap_vrfb_request_ctx(&vrfb->ctx[0]);
	if (rc != 0) {
		DBG("VRFB context allocation 0 failed %d\n", rc);
		goto failed_ctx0;
	}

	rc = omap_vrfb_request_ctx(&vrfb->ctx[1]);
	if (rc != 0) {
		DBG("VRFB context allocation 1 failed %d\n", rc);
		goto failed_ctx1;
	}

	/* Determine the VFRB buffer size by oversizing for the VRFB */
	w = vout->max_video_width;
	h = vout->max_video_height;
	max_pixels = w * h;
	w += 32; /* Oversize as typical for VRFB */
	h += 32;
	size = PAGE_ALIGN(w * h * (vout->max_video_buffer_size / max_pixels));
	vrfb->size = size;

	rc = omapvout_mem_alloc(size, &vrfb->phy_addr[0], &vrfb->virt_addr[0]);
	if (rc != 0) {
		DBG("VRFB buffer alloc 0 failed %d\n", rc);
		goto failed_mem0;
	}

	rc = omapvout_mem_alloc(size, &vrfb->phy_addr[1], &vrfb->virt_addr[1]);
	if (rc != 0) {
		DBG("VRFB buffer alloc 1 failed %d\n", rc);
		goto failed_mem1;
	}

	rc = omap_request_dma(vrfb->dma_id, "VRFB DMA",
				omapvout_dss_vrfb_dma_cb,
				(void *)vrfb,
				&vrfb->dma_ch);
	if (rc != 0) {
		printk(KERN_INFO "No VRFB DMA channel for %d\n", vout->id);
		goto failed_dma;
	}

	vrfb->req_status = DMA_CHAN_ALLOTED;
	init_waitqueue_head(&vrfb->wait);

	return rc;

failed_dma:
	omapvout_mem_free(vrfb->phy_addr[1], vrfb->virt_addr[1], size);
failed_mem1:
	omapvout_mem_free(vrfb->phy_addr[0], vrfb->virt_addr[0], size);
failed_mem0:
	omap_vrfb_release_ctx(&vrfb->ctx[1]);
failed_ctx1:
	omap_vrfb_release_ctx(&vrfb->ctx[0]);
failed_ctx0:
	return rc;
}