Exemplo n.º 1
0
static int xvip_dma_stop_streaming(struct vb2_queue *vq)
{
	struct xvip_dma *dma = vb2_get_drv_priv(vq);
	struct xvip_pipeline *pipe = to_xvip_pipeline(&dma->video.entity);
	struct xilinx_vdma_config config;

	/* Stop the pipeline. */
	xvip_pipeline_set_stream(pipe, false);

	/* Stop and reset the DMA engine. */
	dmaengine_device_control(dma->dma, DMA_TERMINATE_ALL, 0);

	config.reset = 1;

	dmaengine_device_control(dma->dma, DMA_SLAVE_CONFIG,
				 (unsigned long)&config);

	/* Cleanup the pipeline and mark it as being stopped. */
	xvip_pipeline_cleanup(pipe);
	media_entity_pipeline_stop(&dma->video.entity);

	return 0;
}
Exemplo n.º 2
0
static int
xvip_dma_set_format(struct file *file, void *fh, struct v4l2_format *format)
{
	struct v4l2_fh *vfh = file->private_data;
	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
	const struct xvip_video_format *info;
	struct xilinx_vdma_config config;
	int ret;

	__xvip_dma_try_format(dma, &format->fmt.pix, &info);

	mutex_lock(&dma->lock);

	if (vb2_is_streaming(&dma->queue)) {
		ret = -EBUSY;
		goto done;
	}

	dma->format = format->fmt.pix;
	dma->fmtinfo = info;

	/* Configure the DMA engine. */
	memset(&config, 0, sizeof(config));

	config.park = 1;
	config.park_frm = 0;
	config.vsize = dma->format.height;
	config.hsize = dma->format.width * info->bpp;
	config.stride = dma->format.bytesperline;
	config.ext_fsync = 2;

	dmaengine_device_control(dma->dma, DMA_SLAVE_CONFIG,
				 (unsigned long)&config);

	ret = 0;

done:
	mutex_unlock(&dma->lock);
	return ret;
}
Exemplo n.º 3
0
/* mode set a plane */
int xilinx_drm_plane_mode_set(struct drm_plane *base_plane,
			      struct drm_framebuffer *fb,
			      int crtc_x, int crtc_y,
			      unsigned int crtc_w, unsigned int crtc_h,
			      uint32_t src_x, uint32_t src_y,
			      uint32_t src_w, uint32_t src_h)
{
	struct xilinx_drm_plane *plane = to_xilinx_plane(base_plane);
	struct drm_gem_cma_object *obj;

	DRM_DEBUG_KMS("plane->id: %d\n", plane->id);

	if (fb->pixel_format != plane->format) {
		DRM_ERROR("unsupported pixel format %08x\n", fb->pixel_format);
		return -EINVAL;
	}

	/* configure cresample */
	if (plane->cresample)
		xilinx_cresample_configure(plane->cresample, crtc_w, crtc_h);

	/* configure rgb2yuv */
	if (plane->rgb2yuv)
		xilinx_rgb2yuv_configure(plane->rgb2yuv, crtc_w, crtc_h);

	obj = drm_fb_cma_get_gem_obj(fb, 0);
	if (!obj) {
		DRM_ERROR("failed to get a gem obj for fb\n");
		return -EINVAL;
	}

	plane->x = src_x;
	plane->y = src_y;
	plane->bpp = fb->bits_per_pixel / 8;
	plane->paddr = obj->paddr;

	DRM_DEBUG_KMS("h: %d(%d), v: %d(%d), paddr: %p\n",
		      src_w, crtc_x, src_h, crtc_y, (void *)obj->paddr);
	DRM_DEBUG_KMS("bpp: %d\n", plane->bpp);

	/* configure vdma desc */
	plane->vdma.dma_config.hsize = src_w * plane->bpp;
	plane->vdma.dma_config.vsize = src_h;
	plane->vdma.dma_config.stride = fb->pitches[0];
	plane->vdma.dma_config.park = 1;
	plane->vdma.dma_config.park_frm = 0;

	dmaengine_device_control(plane->vdma.chan, DMA_SLAVE_CONFIG,
				 (unsigned long)&plane->vdma.dma_config);

	/* set OSD dimensions */
	if (plane->manager->osd) {
		xilinx_osd_disable_rue(plane->manager->osd);

		/* if a plane is private, it's for crtc */
		if (plane->priv)
			xilinx_osd_set_dimension(plane->manager->osd,
						 crtc_w, crtc_h);

		xilinx_osd_layer_set_dimension(plane->osd_layer, crtc_x, crtc_y,
					       src_w, src_h);

		xilinx_osd_enable_rue(plane->manager->osd);
	}

	return 0;
}
Exemplo n.º 4
0
/* set plane dpms */
void xilinx_drm_plane_dpms(struct drm_plane *base_plane, int dpms)
{
	struct xilinx_drm_plane *plane = to_xilinx_plane(base_plane);
	struct xilinx_drm_plane_manager *manager = plane->manager;
	struct xilinx_vdma_config dma_config;

	DRM_DEBUG_KMS("plane->id: %d\n", plane->id);
	DRM_DEBUG_KMS("dpms: %d -> %d\n", plane->dpms, dpms);

	if (plane->dpms == dpms)
		return;

	plane->dpms = dpms;
	switch (dpms) {
	case DRM_MODE_DPMS_ON:
		/* start vdma engine */
		dma_async_issue_pending(plane->vdma.chan);

		if (plane->rgb2yuv)
			xilinx_rgb2yuv_enable(plane->rgb2yuv);

		if (plane->cresample)
			xilinx_cresample_enable(plane->cresample);

		/* enable osd */
		if (manager->osd) {
			xilinx_osd_disable_rue(manager->osd);

			xilinx_osd_layer_set_priority(plane->osd_layer,
						      plane->prio);
			xilinx_osd_layer_set_alpha(plane->osd_layer, 1,
						   plane->alpha);
			xilinx_osd_layer_enable(plane->osd_layer);
			if (plane->priv) {
				/* set background color as black */
				xilinx_osd_set_color(manager->osd, 0x0, 0x0,
						     0x0);
				xilinx_osd_enable(manager->osd);
			}

			xilinx_osd_enable_rue(manager->osd);
		}

		break;
	default:
		/* disable/reset osd */
		if (manager->osd) {
			xilinx_osd_disable_rue(manager->osd);

			xilinx_osd_layer_set_dimension(plane->osd_layer,
						       0, 0, 0, 0);
			xilinx_osd_layer_disable(plane->osd_layer);
			if (plane->priv)
				xilinx_osd_reset(manager->osd);

			xilinx_osd_enable_rue(manager->osd);
		}

		if (plane->cresample) {
			xilinx_cresample_disable(plane->cresample);
			xilinx_cresample_reset(plane->cresample);
		}

		if (plane->rgb2yuv) {
			xilinx_rgb2yuv_disable(plane->rgb2yuv);
			xilinx_rgb2yuv_reset(plane->rgb2yuv);
		}

		/* reset vdma */
		dma_config.reset = 1;
		dmaengine_device_control(plane->vdma.chan, DMA_SLAVE_CONFIG,
					 (unsigned long)&dma_config);

		/* stop vdma engine and release descriptors */
		dmaengine_terminate_all(plane->vdma.chan);
		break;
	}
}