Пример #1
0
/*
 * Allocate the buffers for the VRFB space.  Data is copied from V4L2
 * buffers to the VRFB buffers using the DMA engine.
 */
int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
			  unsigned int *count, unsigned int startindex)
{
	int i;
	bool yuv_mode;

	if (!is_rotation_enabled(vout))
		return 0;

	/* If rotation is enabled, allocate memory for VRFB space also */
	*count = *count > VRFB_NUM_BUFS ? VRFB_NUM_BUFS : *count;

	/* Allocate the VRFB buffers only if the buffers are not
	 * allocated during init time.
	 */
	if (!vout->vrfb_static_allocation)
		if (omap_vout_allocate_vrfb_buffers(vout, count, startindex))
			return -ENOMEM;

	if (vout->dss_mode == OMAP_DSS_COLOR_YUV2 ||
			vout->dss_mode == OMAP_DSS_COLOR_UYVY)
		yuv_mode = true;
	else
		yuv_mode = false;

	for (i = 0; i < *count; i++)
		omap_vrfb_setup(&vout->vrfb_context[i],
				vout->smsshado_phy_addr[i], vout->pix.width,
				vout->pix.height, vout->bpp, yuv_mode);

	return 0;
}
Пример #2
0
int omap_setup_vrfb_buffer(struct dss2_ovl_info *ovl_info)
{
	int i = 0;
	int mode = ovl_info->cfg.color_mode;
	int got_vrfb_mapped_buf = 0;

	if (!have_vrfb_ctx) {
		pr_err("%s: No VRFB context available for setup\n", __func__);
		return 1;
	}

	for (i = 0; i < VRFB_NUM_SLOTS; i++) {
		if (ion_vrfb_t[i].ba == ovl_info->ba) {
			if (ion_vrfb_t[i].ismapped) {
				if (check_vrfb_params(
					&ion_vrfb_t[i].vrfb_context,
					ovl_info)) {
					got_vrfb_mapped_buf = 0;
					ion_vrfb_t[i].ismapped = 0;
				} else {
					ovl_info->ba = ion_vrfb_t[i].
						vrfb_context.
						paddr[ovl_info->cfg.rotation]
						+ omap_get_vrfb_offset(
						&ion_vrfb_t[i].vrfb_context,
						ovl_info->cfg.rotation);
				got_vrfb_mapped_buf = 1;
				}
			}
			break;
		}
	}

	if (!got_vrfb_mapped_buf) {
		omap_vrfb_setup(&ion_vrfb_t[i].vrfb_context,
				ovl_info->ba, ovl_info->cfg.crop.w,
				ovl_info->cfg.crop.h, get_bpp(mode),
				is_yuv_mode(mode));

		ovl_info->ba = ion_vrfb_t[i].
				vrfb_context.paddr[ovl_info->cfg.rotation]
				+ omap_get_vrfb_offset(
				&ion_vrfb_t[i].vrfb_context,
				ovl_info->cfg.rotation);
		ion_vrfb_t[i].ismapped = 1;
	}

	if (ovl_info->cfg.rotation & 1)	{
#if 0		//[email protected]  ti patch for HDMI
		ovl_info->cfg.win.w =
			(ovl_info->cfg.win.h * ovl_info->cfg.win.h) /
			ovl_info->cfg.win.w;
#else
		ovl_info->cfg.win.w = (ovl_info->cfg.win.w * ovl_info->cfg.win.h) / ovl_info->cfg.win.h;
#endif
	}

	ovl_info->cfg.stride =  VRFB_LINE_LENGTH * 2;

	return 0;
}
Пример #3
0
static int omapvout_dss_perform_vrfb_dma(struct omapvout_device *vout,
					int buf_idx, bool vrfb_cfg)
{
	int rc = 0;
	int rot = 0;
	struct omapvout_dss_vrfb *vrfb;
	u32 src_paddr;
	u32 dst_paddr;

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

	if (vout->dss->vrfb.req_status != DMA_CHAN_ALLOTED)
		return -EINVAL;

	vrfb = &vout->dss->vrfb;

	if (vrfb_cfg) {
		enum omap_color_mode dss_fmt;
		int bytespp;
		int w, h;
		u32 fmt = vout->pix.pixelformat;

		w = vout->crop.width;
		h = vout->crop.height;

		dss_fmt = omapvout_dss_color_mode(vout->pix.pixelformat);
		omap_vrfb_setup(&vrfb->ctx[0], vrfb->phy_addr[0],
				w, h, dss_fmt, vout->rotation);
		omap_vrfb_setup(&vrfb->ctx[1], vrfb->phy_addr[1],
				w, h, dss_fmt, vout->rotation);

		bytespp = omapvout_dss_format_bytespp(vout->pix.pixelformat);
		vrfb->en = (w * bytespp) / 4; /* 32 bit ES */
		vrfb->fn = h;
		vrfb->dst_ei = 1;
		if (fmt == V4L2_PIX_FMT_YUYV || fmt == V4L2_PIX_FMT_UYVY) {
			vrfb->dst_fi = (OMAP_VRFB_LINE_LEN * bytespp * 2)
							- (vrfb->en * 4) + 1;
		} else {
			vrfb->dst_fi = (OMAP_VRFB_LINE_LEN * bytespp)
							- (vrfb->en * 4) + 1;
		}
	}

	switch (vout->rotation) {
	case 1:
		rot = 3;
		break;
	case 3:
		rot = 1;
		break;
	default:
		rot = vout->rotation;
		break;
	}

	src_paddr = vout->queue.bufs[buf_idx]->baddr;
	dst_paddr = vrfb->ctx[vrfb->next].paddr[rot];

	omap_set_dma_transfer_params(vrfb->dma_ch, OMAP_DMA_DATA_TYPE_S32,
				vrfb->en, vrfb->fn, OMAP_DMA_SYNC_ELEMENT,
				vrfb->dma_id, 0x0);
	omap_set_dma_src_params(vrfb->dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
				src_paddr, 0, 0);
	omap_set_dma_src_burst_mode(vrfb->dma_ch, OMAP_DMA_DATA_BURST_16);
	omap_set_dma_dest_params(vrfb->dma_ch, 0, OMAP_DMA_AMODE_DOUBLE_IDX,
				dst_paddr, vrfb->dst_ei, vrfb->dst_fi);
	omap_set_dma_dest_burst_mode(vrfb->dma_ch, OMAP_DMA_DATA_BURST_16);
	omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE, 0x20, 0);

	vrfb->dma_complete = false;
	omap_start_dma(vrfb->dma_ch);
	wait_event_interruptible_timeout(vrfb->wait, vrfb->dma_complete,
							VRFB_TX_TIMEOUT);

	if (!vrfb->dma_complete) {
		DBG("VRFB DMA timeout\n");
		omap_stop_dma(vrfb->dma_ch);
		return -EINVAL;
	}

	return rc;
}