Пример #1
0
static void page_flip_cb(void *arg)
{
	struct drm_crtc *crtc = arg;
	struct drm_device *dev = crtc->dev;
	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
	struct drm_pending_vblank_event *event = omap_crtc->event;
	struct timeval now;
	unsigned long flags;

	WARN_ON(!event);

	omap_crtc->event = NULL;

	update_scanout(crtc);
	WARN_ON(commit(crtc));

	/* wakeup userspace */
	/* TODO: this should happen *after* flip in vsync IRQ handler */
	if (event) {
		spin_lock_irqsave(&dev->event_lock, flags);
		event->event.sequence = drm_vblank_count_and_time(
				dev, omap_crtc->id, &now);
		event->event.tv_sec = now.tv_sec;
		event->event.tv_usec = now.tv_usec;
		list_add_tail(&event->base.link,
				&event->base.file_priv->event_list);
		wake_up_interruptible(&event->base.file_priv->event_wait);
		spin_unlock_irqrestore(&dev->event_lock, flags);
	}
}
Пример #2
0
static int mdp4_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
		struct drm_framebuffer *old_fb)
{
	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
	struct drm_plane *plane = mdp4_crtc->plane;
	struct drm_display_mode *mode = &crtc->mode;
	int ret;

	/* grab extra ref for update_scanout() */
	drm_framebuffer_reference(crtc->primary->fb);

	ret = mdp4_plane_mode_set(plane, crtc, crtc->primary->fb,
			0, 0, mode->hdisplay, mode->vdisplay,
			x << 16, y << 16,
			mode->hdisplay << 16, mode->vdisplay << 16);
	if (ret) {
		drm_framebuffer_unreference(crtc->primary->fb);
		return ret;
	}

	update_fb(crtc, crtc->primary->fb);
	update_scanout(crtc, crtc->primary->fb);

	return 0;
}
Пример #3
0
static int omap_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
		    struct drm_framebuffer *old_fb)
{
	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);

	DBG("%s %d,%d: fb=%p", omap_crtc->ovl->name, x, y, old_fb);

	update_scanout(crtc);

	return commit(crtc);
}
Пример #4
0
static void pageflip_cb(struct msm_fence_cb *cb)
{
	struct mdp4_crtc *mdp4_crtc =
		container_of(cb, struct mdp4_crtc, pageflip_cb);
	struct drm_crtc *crtc = &mdp4_crtc->base;
	struct drm_framebuffer *fb = crtc->primary->fb;

	if (!fb)
		return;

	drm_framebuffer_reference(fb);
	mdp4_plane_set_scanout(mdp4_crtc->plane, fb);
	update_scanout(crtc, fb);
}
Пример #5
0
static void omap_crtc_dpms(struct drm_crtc *crtc, int mode)
{
	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);

	DBG("%s: %d", omap_crtc->ovl->name, mode);

	if (mode == DRM_MODE_DPMS_ON) {
		update_scanout(crtc);
		omap_crtc->info.enabled = true;
	} else {
		omap_crtc->info.enabled = false;
	}

	WARN_ON(commit(crtc));
}
Пример #6
0
int omap_plane_dpms(struct drm_plane *plane, int mode)
{
	struct omap_plane *omap_plane = to_omap_plane(plane);
	struct omap_overlay *ovl = omap_plane->ovl;
	int r;

	DBG("%s: %d", omap_plane->ovl->name, mode);

	if (mode == DRM_MODE_DPMS_ON) {
		update_scanout(plane);
		r = commit(plane);
		if (!r)
			r = ovl->enable(ovl);
	} else {
		r = ovl->disable(ovl);
		update_pin(plane, NULL);
	}

	return r;
}
Пример #7
0
static int omap_crtc_mode_set(struct drm_crtc *crtc,
			       struct drm_display_mode *mode,
			       struct drm_display_mode *adjusted_mode,
			       int x, int y,
			       struct drm_framebuffer *old_fb)
{
	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);

	DBG("%s: %d,%d: %dx%d", omap_crtc->ovl->name, x, y,
			mode->hdisplay, mode->vdisplay);

	/* just use adjusted mode */
	mode = adjusted_mode;

	omap_crtc->info.width = mode->hdisplay;
	omap_crtc->info.height = mode->vdisplay;
	omap_crtc->info.out_width = mode->hdisplay;
	omap_crtc->info.out_height = mode->vdisplay;
	omap_crtc->info.color_mode = OMAP_DSS_COLOR_RGB24U;
	omap_crtc->info.rotation_type = OMAP_DSS_ROT_DMA;
	omap_crtc->info.rotation = OMAP_DSS_ROT_0;
	omap_crtc->info.global_alpha = 0xff;
	omap_crtc->info.mirror = 0;
	omap_crtc->info.mirror = 0;
	omap_crtc->info.pos_x = 0;
	omap_crtc->info.pos_y = 0;
#if 0 /* re-enable when these are available in DSS2 driver */
	omap_crtc->info.zorder = 3;        /* GUI in the front, video behind */
	omap_crtc->info.min_x_decim = 1;
	omap_crtc->info.max_x_decim = 1;
	omap_crtc->info.min_y_decim = 1;
	omap_crtc->info.max_y_decim = 1;
#endif

	update_scanout(crtc);

	return 0;
}
Пример #8
0
int omap_plane_mode_set(struct drm_plane *plane,
		struct drm_crtc *crtc, 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 omap_plane *omap_plane = to_omap_plane(plane);

	/* src values are in Q16 fixed point, convert to integer: */
	src_x = src_x >> 16;
	src_y = src_y >> 16;
	src_w = src_w >> 16;
	src_h = src_h >> 16;

	omap_plane->info.pos_x = crtc_x;
	omap_plane->info.pos_y = crtc_y;
	omap_plane->info.out_width = crtc_w;
	omap_plane->info.out_height = crtc_h;
	omap_plane->info.width = src_w;
	omap_plane->info.height = src_h;
	omap_plane->src_x = src_x;
	omap_plane->src_y = src_y;

	/* note: this is done after this fxn returns.. but if we need
	 * to do a commit/update_scanout, etc before this returns we
	 * need the current value.
	 */
	plane->fb = fb;
	plane->crtc = crtc;

	update_scanout(plane);
	update_manager(plane);

	return 0;
}
Пример #9
0
static int mdp4_crtc_mode_set(struct drm_crtc *crtc,
		struct drm_display_mode *mode,
		struct drm_display_mode *adjusted_mode,
		int x, int y,
		struct drm_framebuffer *old_fb)
{
	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
	struct mdp4_kms *mdp4_kms = get_kms(crtc);
	enum mdp4_dma dma = mdp4_crtc->dma;
	int ret, ovlp = mdp4_crtc->ovlp;

	mode = adjusted_mode;

	DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
			mdp4_crtc->name, mode->base.id, mode->name,
			mode->vrefresh, mode->clock,
			mode->hdisplay, mode->hsync_start,
			mode->hsync_end, mode->htotal,
			mode->vdisplay, mode->vsync_start,
			mode->vsync_end, mode->vtotal,
			mode->type, mode->flags);

	/* grab extra ref for update_scanout() */
	drm_framebuffer_reference(crtc->primary->fb);

	ret = mdp4_plane_mode_set(mdp4_crtc->plane, crtc, crtc->primary->fb,
			0, 0, mode->hdisplay, mode->vdisplay,
			x << 16, y << 16,
			mode->hdisplay << 16, mode->vdisplay << 16);
	if (ret) {
		drm_framebuffer_unreference(crtc->primary->fb);
		dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n",
				mdp4_crtc->name, ret);
		return ret;
	}

	mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_SIZE(dma),
			MDP4_DMA_SRC_SIZE_WIDTH(mode->hdisplay) |
			MDP4_DMA_SRC_SIZE_HEIGHT(mode->vdisplay));

	/* take data from pipe: */
	mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_BASE(dma), 0);
	mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_STRIDE(dma),
			crtc->primary->fb->pitches[0]);
	mdp4_write(mdp4_kms, REG_MDP4_DMA_DST_SIZE(dma),
			MDP4_DMA_DST_SIZE_WIDTH(0) |
			MDP4_DMA_DST_SIZE_HEIGHT(0));

	mdp4_write(mdp4_kms, REG_MDP4_OVLP_BASE(ovlp), 0);
	mdp4_write(mdp4_kms, REG_MDP4_OVLP_SIZE(ovlp),
			MDP4_OVLP_SIZE_WIDTH(mode->hdisplay) |
			MDP4_OVLP_SIZE_HEIGHT(mode->vdisplay));
	mdp4_write(mdp4_kms, REG_MDP4_OVLP_STRIDE(ovlp),
			crtc->primary->fb->pitches[0]);

	mdp4_write(mdp4_kms, REG_MDP4_OVLP_CFG(ovlp), 1);

	if (dma == DMA_E) {
		mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(0), 0x00ff0000);
		mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(1), 0x00ff0000);
		mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(2), 0x00ff0000);
	}

	update_fb(crtc, crtc->primary->fb);
	update_scanout(crtc, crtc->primary->fb);

	return 0;
}