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); } }
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; }
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); }
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); }
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)); }
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; }
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; }
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; }
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; }