static void omap_plane_pre_apply(struct omap_drm_apply *apply) { struct omap_plane *omap_plane = container_of(apply, struct omap_plane, apply); struct omap_drm_window *win = &omap_plane->win; struct drm_plane *plane = &omap_plane->base; struct drm_device *dev = plane->dev; struct omap_overlay_info *info = &omap_plane->info; struct drm_crtc *crtc = plane->crtc; enum omap_channel channel; bool enabled = omap_plane->enabled && crtc; bool ilace, replication; u32 low, high; int ret; DBG("%s, enabled=%d", omap_plane->name, enabled); /* if fb has changed, pin new fb: */ update_pin(plane, enabled ? plane->fb : NULL); if (!enabled) { dispc_ovl_enable(omap_plane->id, false); return; } channel = omap_crtc_channel(crtc); /* update scanout: */ omap_framebuffer_update_scanout(plane->fb, win, info); DBG("%dx%d -> %dx%d (%d)", info->width, info->height, info->out_width, info->out_height, info->screen_width); DBG("%d,%d %pad %pad", info->pos_x, info->pos_y, &info->paddr, &info->p_uv_addr); /* TODO: */ ilace = false; replication = false; dispc_ovl_compute_fifo_thresholds(omap_plane->id, &low, &high, false, false); dispc_ovl_set_fifo_threshold(omap_plane->id, low, high); /* and finally, update omapdss: */ ret = dispc_ovl_setup(omap_plane->id, info, replication, omap_crtc_timings(crtc), false); if (ret) { dev_err(dev->dev, "dispc_ovl_setup failed: %d\n", ret); return; } dispc_ovl_enable(omap_plane->id, true); dispc_ovl_set_channel_out(omap_plane->id, channel); }
static void omap_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { struct omap_drm_private *priv = plane->dev->dev_private; struct omap_plane *omap_plane = to_omap_plane(plane); struct drm_plane_state *state = plane->state; struct omap_overlay_info info; int ret; DBG("%s, crtc=%p fb=%p", omap_plane->name, state->crtc, state->fb); memset(&info, 0, sizeof(info)); info.rotation_type = OMAP_DSS_ROT_NONE; info.rotation = DRM_MODE_ROTATE_0; info.global_alpha = 0xff; info.zorder = state->normalized_zpos; /* update scanout: */ omap_framebuffer_update_scanout(state->fb, state, &info); DBG("%dx%d -> %dx%d (%d)", info.width, info.height, info.out_width, info.out_height, info.screen_width); DBG("%d,%d %pad %pad", info.pos_x, info.pos_y, &info.paddr, &info.p_uv_addr); /* and finally, update omapdss: */ ret = priv->dispc_ops->ovl_setup(priv->dispc, omap_plane->id, &info, omap_crtc_timings(state->crtc), false, omap_crtc_channel(state->crtc)); if (ret) { dev_err(plane->dev->dev, "Failed to setup plane %s\n", omap_plane->name); priv->dispc_ops->ovl_enable(priv->dispc, omap_plane->id, false); return; } priv->dispc_ops->ovl_enable(priv->dispc, omap_plane->id, true); }
/* update parameters that are dependent on the framebuffer dimensions and * position within the fb that this plane scans out from. This is called * when framebuffer or x,y base may have changed. */ static void update_scanout(struct drm_plane *plane) { struct omap_plane *omap_plane = to_omap_plane(plane); struct omap_overlay_info *info = &omap_plane->info; int ret; ret = update_pin(plane, plane->fb); if (ret) { dev_err(plane->dev->dev, "could not pin fb: %d\n", ret); omap_plane_dpms(plane, DRM_MODE_DPMS_OFF); return; } omap_framebuffer_update_scanout(plane->fb, omap_plane->src_x, omap_plane->src_y, info); DBG("%s: %d,%d: %08x %08x (%d)", omap_plane->ovl->name, omap_plane->src_x, omap_plane->src_y, (u32)info->paddr, (u32)info->p_uv_addr, info->screen_width); }