/* initialize plane */ struct drm_plane *omap_plane_init(struct drm_device *dev, int idx, enum drm_plane_type type, u32 possible_crtcs) { struct omap_drm_private *priv = dev->dev_private; unsigned int num_planes = priv->dispc_ops->get_num_ovls(priv->dispc); struct drm_plane *plane; struct omap_plane *omap_plane; enum omap_plane_id id; int ret; u32 nformats; const u32 *formats; if (WARN_ON(idx >= ARRAY_SIZE(plane_idx_to_id))) return ERR_PTR(-EINVAL); id = plane_idx_to_id[idx]; DBG("%s: type=%d", plane_id_to_name[id], type); omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL); if (!omap_plane) return ERR_PTR(-ENOMEM); formats = priv->dispc_ops->ovl_get_color_modes(priv->dispc, id); for (nformats = 0; formats[nformats]; ++nformats) ; omap_plane->id = id; omap_plane->name = plane_id_to_name[id]; plane = &omap_plane->base; ret = drm_universal_plane_init(dev, plane, possible_crtcs, &omap_plane_funcs, formats, nformats, NULL, type, NULL); if (ret < 0) goto error; drm_plane_helper_add(plane, &omap_plane_helper_funcs); omap_plane_install_properties(plane, &plane->base); drm_plane_create_zpos_property(plane, 0, 0, num_planes - 1); return plane; error: dev_err(dev->dev, "%s(): could not create plane: %s\n", __func__, plane_id_to_name[id]); kfree(omap_plane); return NULL; }
/* initialize crtc */ struct drm_crtc *omap_crtc_init(struct drm_device *dev, struct drm_plane *plane, enum omap_channel channel, int id) { struct drm_crtc *crtc = NULL; struct omap_crtc *omap_crtc; int ret; DBG("%s", channel_names[channel]); omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL); if (!omap_crtc) return NULL; crtc = &omap_crtc->base; init_waitqueue_head(&omap_crtc->pending_wait); omap_crtc->channel = channel; omap_crtc->name = channel_names[channel]; omap_crtc->vblank_irq.irqmask = pipe2vbl(crtc); omap_crtc->vblank_irq.irq = omap_crtc_vblank_irq; omap_crtc->error_irq.irqmask = dispc_mgr_get_sync_lost_irq(channel); omap_crtc->error_irq.irq = omap_crtc_error_irq; omap_irq_register(dev, &omap_crtc->error_irq); /* temporary: */ omap_crtc->mgr = omap_dss_get_overlay_manager(channel); ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL, &omap_crtc_funcs); if (ret < 0) { kfree(omap_crtc); return NULL; } drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs); omap_plane_install_properties(crtc->primary, &crtc->base); omap_crtcs[channel] = omap_crtc; return crtc; }
/* initialize plane */ struct drm_plane *omap_plane_init(struct drm_device *dev, int id, bool private_plane) { struct omap_drm_private *priv = dev->dev_private; struct drm_plane *plane = NULL; struct omap_plane *omap_plane; struct omap_overlay_info *info; int ret; DBG("%s: priv=%d", plane_names[id], private_plane); omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL); if (!omap_plane) goto fail; ret = kfifo_alloc(&omap_plane->unpin_fifo, 16, GFP_KERNEL); if (ret) { dev_err(dev->dev, "could not allocate unpin FIFO\n"); goto fail; } omap_plane->nformats = omap_framebuffer_get_formats( omap_plane->formats, ARRAY_SIZE(omap_plane->formats), dss_feat_get_supported_color_modes(id)); omap_plane->id = id; omap_plane->name = plane_names[id]; plane = &omap_plane->base; omap_plane->apply.pre_apply = omap_plane_pre_apply; omap_plane->apply.post_apply = omap_plane_post_apply; omap_plane->error_irq.irqmask = error_irqs[id]; omap_plane->error_irq.irq = omap_plane_error_irq; omap_irq_register(dev, &omap_plane->error_irq); drm_plane_init(dev, plane, (1 << priv->num_crtcs) - 1, &omap_plane_funcs, omap_plane->formats, omap_plane->nformats, private_plane); omap_plane_install_properties(plane, &plane->base); /* get our starting configuration, set defaults for parameters * we don't currently use, etc: */ info = &omap_plane->info; info->rotation_type = OMAP_DSS_ROT_DMA; info->rotation = OMAP_DSS_ROT_0; info->global_alpha = 0xff; info->mirror = 0; /* Set defaults depending on whether we are a CRTC or overlay * layer. * TODO add ioctl to give userspace an API to change this.. this * will come in a subsequent patch. */ if (private_plane) omap_plane->info.zorder = 0; else omap_plane->info.zorder = id; return plane; fail: if (plane) omap_plane_destroy(plane); return NULL; }