diff --git a/drivers/staging/omapdrm/Makefile b/drivers/staging/omapdrm/Makefile index 592cf69020cd7b6b133e18da3f92b1aef6d0315a..d9cdc120d122e904ea24bec55224ad8635ba6e8a 100644 --- a/drivers/staging/omapdrm/Makefile +++ b/drivers/staging/omapdrm/Makefile @@ -7,6 +7,7 @@ ccflags-y := -Iinclude/drm -Werror omapdrm-y := omap_drv.o \ omap_debugfs.o \ omap_crtc.o \ + omap_plane.o \ omap_encoder.o \ omap_connector.o \ omap_fb.o \ diff --git a/drivers/staging/omapdrm/omap_crtc.c b/drivers/staging/omapdrm/omap_crtc.c index cffdf5e1239424331edb51f45528139255263626..a91c788980197dea0ad405dfc935f00a9cc8d9de 100644 --- a/drivers/staging/omapdrm/omap_crtc.c +++ b/drivers/staging/omapdrm/omap_crtc.c @@ -27,196 +27,95 @@ struct omap_crtc { struct drm_crtc base; - struct omap_overlay *ovl; - struct omap_overlay_info info; + struct drm_plane *plane; + const char *name; int id; - /* if there is a pending flip, this will be non-null: */ + /* if there is a pending flip, these will be non-null: */ struct drm_pending_vblank_event *event; + struct drm_framebuffer *old_fb; }; -/* push changes down to dss2 */ -static int commit(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - struct omap_overlay *ovl = omap_crtc->ovl; - struct omap_overlay_info *info = &omap_crtc->info; - int ret; - - DBG("%s", omap_crtc->ovl->name); - DBG("%dx%d -> %dx%d (%d)", info->width, info->height, info->out_width, - info->out_height, info->screen_width); - DBG("%d,%d %08x", info->pos_x, info->pos_y, info->paddr); - - /* NOTE: do we want to do this at all here, or just wait - * for dpms(ON) since other CRTC's may not have their mode - * set yet, so fb dimensions may still change.. - */ - ret = ovl->set_overlay_info(ovl, info); - if (ret) { - dev_err(dev->dev, "could not set overlay info\n"); - return ret; - } - - /* our encoder doesn't necessarily get a commit() after this, in - * particular in the dpms() and mode_set_base() cases, so force the - * manager to update: - * - * could this be in the encoder somehow? - */ - if (ovl->manager) { - ret = ovl->manager->apply(ovl->manager); - if (ret) { - dev_err(dev->dev, "could not apply settings\n"); - return ret; - } - } - - if (info->enabled) { - omap_framebuffer_flush(crtc->fb, crtc->x, crtc->y, - crtc->fb->width, crtc->fb->height); - } - - return 0; -} - -/* update parameters that are dependent on the framebuffer dimensions and - * position within the fb that this crtc scans out from. This is called - * when framebuffer dimensions or x,y base may have changed, either due - * to our mode, or a change in another crtc that is scanning out of the - * same fb. - */ -static void update_scanout(struct drm_crtc *crtc) -{ - struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - dma_addr_t paddr; - unsigned int screen_width; - - omap_framebuffer_get_buffer(crtc->fb, crtc->x, crtc->y, - NULL, &paddr, &screen_width); - - DBG("%s: %d,%d: %08x (%d)", omap_crtc->ovl->name, - crtc->x, crtc->y, (u32)paddr, screen_width); - - omap_crtc->info.paddr = paddr; - omap_crtc->info.screen_width = screen_width; -} - static void omap_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, uint32_t start, uint32_t size) { - struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - DBG("%s", omap_crtc->ovl->name); + /* not supported.. at least not yet */ } static void omap_crtc_destroy(struct drm_crtc *crtc) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - DBG("%s", omap_crtc->ovl->name); + omap_crtc->plane->funcs->destroy(omap_crtc->plane); drm_crtc_cleanup(crtc); kfree(omap_crtc); } static void omap_crtc_dpms(struct drm_crtc *crtc, int mode) { + struct omap_drm_private *priv = crtc->dev->dev_private; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + int i; - DBG("%s: %d", omap_crtc->ovl->name, mode); + WARN_ON(omap_plane_dpms(omap_crtc->plane, mode)); - if (mode == DRM_MODE_DPMS_ON) { - update_scanout(crtc); - omap_crtc->info.enabled = true; - } else { - omap_crtc->info.enabled = false; + for (i = 0; i < priv->num_planes; i++) { + struct drm_plane *plane = priv->planes[i]; + if (plane->crtc == crtc) + WARN_ON(omap_plane_dpms(plane, mode)); } - - WARN_ON(commit(crtc)); } static bool omap_crtc_mode_fixup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) { - struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - DBG("%s", omap_crtc->ovl->name); return true; } 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 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); + struct drm_plane *plane = omap_crtc->plane; - 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; + return plane->funcs->update_plane(plane, crtc, crtc->fb, + 0, 0, mode->hdisplay, mode->vdisplay, + x << 16, y << 16, + mode->hdisplay << 16, mode->vdisplay << 16); } static void omap_crtc_prepare(struct drm_crtc *crtc) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - struct omap_overlay *ovl = omap_crtc->ovl; - - DBG("%s", omap_crtc->ovl->name); - - ovl->get_overlay_info(ovl, &omap_crtc->info); - + DBG("%s", omap_crtc->name); omap_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); } static void omap_crtc_commit(struct drm_crtc *crtc) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - DBG("%s", omap_crtc->ovl->name); + DBG("%s", omap_crtc->name); omap_crtc_dpms(crtc, DRM_MODE_DPMS_ON); } static int omap_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) + struct drm_framebuffer *old_fb) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct drm_plane *plane = omap_crtc->plane; + struct drm_display_mode *mode = &crtc->mode; - DBG("%s %d,%d: fb=%p", omap_crtc->ovl->name, x, y, old_fb); - - update_scanout(crtc); - - return commit(crtc); + return plane->funcs->update_plane(plane, crtc, crtc->fb, + 0, 0, mode->hdisplay, mode->vdisplay, + x << 16, y << 16, + mode->hdisplay << 16, mode->vdisplay << 16); } static void omap_crtc_load_lut(struct drm_crtc *crtc) { - struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - DBG("%s", omap_crtc->ovl->name); } static void page_flip_cb(void *arg) @@ -225,15 +124,16 @@ static void page_flip_cb(void *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 drm_framebuffer *old_fb = omap_crtc->old_fb; struct timeval now; unsigned long flags; WARN_ON(!event); omap_crtc->event = NULL; + omap_crtc->old_fb = NULL; - update_scanout(crtc); - WARN_ON(commit(crtc)); + omap_crtc_mode_set_base(crtc, crtc->x, crtc->y, old_fb); /* wakeup userspace */ /* TODO: this should happen *after* flip in vsync IRQ handler */ @@ -264,8 +164,9 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, return -EINVAL; } - crtc->fb = fb; + omap_crtc->old_fb = crtc->fb; omap_crtc->event = event; + crtc->fb = fb; omap_gem_op_async(omap_framebuffer_bo(fb), OMAP_GEM_READ, page_flip_cb, crtc); @@ -290,12 +191,6 @@ static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = { .load_lut = omap_crtc_load_lut, }; -struct omap_overlay *omap_crtc_get_overlay(struct drm_crtc *crtc) -{ - struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - return omap_crtc->ovl; -} - /* initialize crtc */ struct drm_crtc *omap_crtc_init(struct drm_device *dev, struct omap_overlay *ovl, int id) @@ -310,9 +205,13 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, goto fail; } - omap_crtc->ovl = ovl; - omap_crtc->id = id; crtc = &omap_crtc->base; + + omap_crtc->plane = omap_plane_init(dev, ovl, (1 << id), true); + omap_crtc->plane->crtc = crtc; + omap_crtc->name = ovl->name; + omap_crtc->id = id; + drm_crtc_init(dev, crtc, &omap_crtc_funcs); drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs); diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c index 4db40f717b94410b98e942ec23f2925340666ea8..2de99ffecc510ebf3718a63d231dc1477c8198de 100644 --- a/drivers/staging/omapdrm/omap_drv.c +++ b/drivers/staging/omapdrm/omap_drv.c @@ -204,12 +204,6 @@ static int create_crtc(struct drm_device *dev, struct omap_overlay *ovl, struct omap_overlay_manager *mgr = NULL; struct drm_crtc *crtc; - if (ovl->manager) { - DBG("disconnecting %s from %s", ovl->name, - ovl->manager->name); - ovl->unset_manager(ovl); - } - /* find next best connector, ones with detected connection first */ while (*j < priv->num_connectors && !mgr) { @@ -245,11 +239,6 @@ static int create_crtc(struct drm_device *dev, struct omap_overlay *ovl, (*j)++; } - if (mgr) { - DBG("connecting %s to %s", ovl->name, mgr->name); - ovl->set_manager(ovl, mgr); - } - crtc = omap_crtc_init(dev, ovl, priv->num_crtcs); if (!crtc) { @@ -265,6 +254,26 @@ static int create_crtc(struct drm_device *dev, struct omap_overlay *ovl, return 0; } +static int create_plane(struct drm_device *dev, struct omap_overlay *ovl, + unsigned int possible_crtcs) +{ + struct omap_drm_private *priv = dev->dev_private; + struct drm_plane *plane = + omap_plane_init(dev, ovl, possible_crtcs, false); + + if (!plane) { + dev_err(dev->dev, "could not create plane: %s\n", + ovl->name); + return -ENOMEM; + } + + BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)); + + priv->planes[priv->num_planes++] = plane; + + return 0; +} + static int match_dev_name(struct omap_dss_device *dssdev, void *data) { return !strcmp(dssdev->name, data); @@ -332,6 +341,12 @@ static int omap_modeset_init(struct drm_device *dev) omap_dss_get_overlay(kms_pdata->ovl_ids[i]); create_crtc(dev, ovl, &j, connected_connectors); } + + for (i = 0; i < kms_pdata->pln_cnt; i++) { + struct omap_overlay *ovl = + omap_dss_get_overlay(kms_pdata->pln_ids[i]); + create_plane(dev, ovl, (1 << priv->num_crtcs) - 1); + } } else { /* otherwise just grab up to CONFIG_DRM_OMAP_NUM_CRTCS and try * to make educated guesses about everything else @@ -353,6 +368,12 @@ static int omap_modeset_init(struct drm_device *dev) create_crtc(dev, omap_dss_get_overlay(i), &j, connected_connectors); } + + /* use any remaining overlays as drm planes */ + for (; i < omap_dss_get_num_overlays(); i++) { + struct omap_overlay *ovl = omap_dss_get_overlay(i); + create_plane(dev, ovl, (1 << priv->num_crtcs) - 1); + } } /* for now keep the mapping of CRTCs and encoders static.. */ @@ -361,15 +382,7 @@ static int omap_modeset_init(struct drm_device *dev) struct omap_overlay_manager *mgr = omap_encoder_get_manager(encoder); - encoder->possible_crtcs = 0; - - for (j = 0; j < priv->num_crtcs; j++) { - struct omap_overlay *ovl = - omap_crtc_get_overlay(priv->crtcs[j]); - if (ovl->manager == mgr) { - encoder->possible_crtcs |= (1 << j); - } - } + encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; DBG("%s: possible_crtcs=%08x", mgr->name, encoder->possible_crtcs); diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h index 4ad2ae55ec43d8fbd12efe3d639138b11e5ecb6a..e2b1b553e8b625a4a902113cda2f50134c7d6072 100644 --- a/drivers/staging/omapdrm/omap_drv.h +++ b/drivers/staging/omapdrm/omap_drv.h @@ -42,6 +42,8 @@ struct omap_drm_private { unsigned int num_crtcs; struct drm_crtc *crtcs[8]; + unsigned int num_planes; + struct drm_plane *planes[8]; unsigned int num_encoders; struct drm_encoder *encoders[8]; unsigned int num_connectors; @@ -62,7 +64,11 @@ void omap_fbdev_free(struct drm_device *dev); struct drm_crtc *omap_crtc_init(struct drm_device *dev, struct omap_overlay *ovl, int id); -struct omap_overlay *omap_crtc_get_overlay(struct drm_crtc *crtc); + +struct drm_plane *omap_plane_init(struct drm_device *dev, + struct omap_overlay *ovl, unsigned int possible_crtcs, + bool priv); +int omap_plane_dpms(struct drm_plane *plane, int mode); struct drm_encoder *omap_encoder_init(struct drm_device *dev, struct omap_overlay_manager *mgr); diff --git a/drivers/staging/omapdrm/omap_plane.c b/drivers/staging/omapdrm/omap_plane.c new file mode 100644 index 0000000000000000000000000000000000000000..a1d948c45ab6c5f91b420656893d73702ee1f625 --- /dev/null +++ b/drivers/staging/omapdrm/omap_plane.c @@ -0,0 +1,308 @@ +/* + * drivers/staging/omapdrm/omap_plane.c + * + * Copyright (C) 2011 Texas Instruments + * Author: Rob Clark + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "omap_drv.h" + +/* some hackery because omapdss has an 'enum omap_plane' (which would be + * better named omap_plane_id).. and compiler seems unhappy about having + * both a 'struct omap_plane' and 'enum omap_plane' + */ +#define omap_plane _omap_plane + +/* + * plane funcs + */ + +#define to_omap_plane(x) container_of(x, struct omap_plane, base) + +struct omap_plane { + struct drm_plane base; + struct omap_overlay *ovl; + struct omap_overlay_info info; + + /* Source values, converted to integers because we don't support + * fractional positions: + */ + unsigned int src_x, src_y; +}; + + +/* push changes down to dss2 */ +static int commit(struct drm_plane *plane) +{ + struct drm_device *dev = plane->dev; + struct omap_plane *omap_plane = to_omap_plane(plane); + struct omap_overlay *ovl = omap_plane->ovl; + struct omap_overlay_info *info = &omap_plane->info; + int ret; + + DBG("%s", ovl->name); + DBG("%dx%d -> %dx%d (%d)", info->width, info->height, info->out_width, + info->out_height, info->screen_width); + DBG("%d,%d %08x", info->pos_x, info->pos_y, info->paddr); + + /* NOTE: do we want to do this at all here, or just wait + * for dpms(ON) since other CRTC's may not have their mode + * set yet, so fb dimensions may still change.. + */ + ret = ovl->set_overlay_info(ovl, info); + if (ret) { + dev_err(dev->dev, "could not set overlay info\n"); + return ret; + } + + /* our encoder doesn't necessarily get a commit() after this, in + * particular in the dpms() and mode_set_base() cases, so force the + * manager to update: + * + * could this be in the encoder somehow? + */ + if (ovl->manager) { + ret = ovl->manager->apply(ovl->manager); + if (ret) { + dev_err(dev->dev, "could not apply settings\n"); + return ret; + } + } + + if (info->enabled) { + omap_framebuffer_flush(plane->fb, info->pos_x, info->pos_y, + info->out_width, info->out_height); + } + + return 0; +} + +/* when CRTC that we are attached to has potentially changed, this checks + * if we are attached to proper manager, and if necessary updates. + */ +static void update_manager(struct drm_plane *plane) +{ + struct omap_drm_private *priv = plane->dev->dev_private; + struct omap_plane *omap_plane = to_omap_plane(plane); + struct omap_overlay *ovl = omap_plane->ovl; + struct omap_overlay_manager *mgr = NULL; + int i; + + if (plane->crtc) { + for (i = 0; i < priv->num_encoders; i++) { + struct drm_encoder *encoder = priv->encoders[i]; + if (encoder->crtc == plane->crtc) { + mgr = omap_encoder_get_manager(encoder); + break; + } + } + } + + if (ovl->manager != mgr) { + bool enabled = omap_plane->info.enabled; + + /* don't switch things around with enabled overlays: */ + if (enabled) + omap_plane_dpms(plane, DRM_MODE_DPMS_OFF); + + if (ovl->manager) { + DBG("disconnecting %s from %s", ovl->name, + ovl->manager->name); + ovl->unset_manager(ovl); + } + + if (mgr) { + DBG("connecting %s to %s", ovl->name, mgr->name); + ovl->set_manager(ovl, mgr); + } + + if (enabled && mgr) + omap_plane_dpms(plane, DRM_MODE_DPMS_ON); + } +} + +/* 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); + unsigned int screen_width; /* really means "pitch" */ + dma_addr_t paddr; + + omap_framebuffer_get_buffer(plane->fb, + omap_plane->src_x, omap_plane->src_y, + NULL, &paddr, &screen_width); + + DBG("%s: %d,%d: %08x (%d)", omap_plane->ovl->name, + omap_plane->src_x, omap_plane->src_y, + (u32)paddr, screen_width); + + omap_plane->info.paddr = paddr; + omap_plane->info.screen_width = screen_width; +} + +static int omap_plane_update(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.enabled = true; + 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); + commit(plane); + + return 0; +} + +static int omap_plane_disable(struct drm_plane *plane) +{ + return omap_plane_dpms(plane, DRM_MODE_DPMS_OFF); +} + +static void omap_plane_destroy(struct drm_plane *plane) +{ + struct omap_plane *omap_plane = to_omap_plane(plane); + DBG("%s", omap_plane->ovl->name); + omap_plane_disable(plane); + drm_plane_cleanup(plane); + kfree(omap_plane); +} + +int omap_plane_dpms(struct drm_plane *plane, int mode) +{ + struct omap_plane *omap_plane = to_omap_plane(plane); + + DBG("%s: %d", omap_plane->ovl->name, mode); + + if (mode == DRM_MODE_DPMS_ON) { + update_scanout(plane); + omap_plane->info.enabled = true; + } else { + omap_plane->info.enabled = false; + } + + return commit(plane); +} + +static const struct drm_plane_funcs omap_plane_funcs = { + .update_plane = omap_plane_update, + .disable_plane = omap_plane_disable, + .destroy = omap_plane_destroy, +}; + +static const uint32_t formats[] = { + DRM_FORMAT_RGB565, + DRM_FORMAT_RGBX4444, + DRM_FORMAT_XRGB4444, + DRM_FORMAT_RGBA4444, + DRM_FORMAT_ABGR4444, + DRM_FORMAT_XRGB1555, + DRM_FORMAT_ARGB1555, + DRM_FORMAT_RGB888, + DRM_FORMAT_RGBX8888, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_RGBA8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_NV12, + DRM_FORMAT_YUYV, + DRM_FORMAT_UYVY, +}; + +/* initialize plane */ +struct drm_plane *omap_plane_init(struct drm_device *dev, + struct omap_overlay *ovl, unsigned int possible_crtcs, + bool priv) +{ + struct drm_plane *plane = NULL; + struct omap_plane *omap_plane; + + DBG("%s: possible_crtcs=%08x, priv=%d", ovl->name, + possible_crtcs, priv); + + omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL); + if (!omap_plane) { + dev_err(dev->dev, "could not allocate plane\n"); + goto fail; + } + + omap_plane->ovl = ovl; + plane = &omap_plane->base; + + drm_plane_init(dev, plane, possible_crtcs, &omap_plane_funcs, + formats, ARRAY_SIZE(formats), priv); + + /* get our starting configuration, set defaults for parameters + * we don't currently use, etc: + */ + ovl->get_overlay_info(ovl, &omap_plane->info); + omap_plane->info.rotation_type = OMAP_DSS_ROT_DMA; + omap_plane->info.rotation = OMAP_DSS_ROT_0; + omap_plane->info.global_alpha = 0xff; + omap_plane->info.mirror = 0; + omap_plane->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 (priv) + omap_plane->info.zorder = 0; + else + omap_plane->info.zorder = 1; + + /* TODO color mode should come from fb.. this will come in a + * subsequent patch + */ + omap_plane->info.color_mode = OMAP_DSS_COLOR_RGB24U; + + update_manager(plane); + + return plane; + +fail: + if (plane) { + omap_plane_destroy(plane); + } + return NULL; +} diff --git a/drivers/staging/omapdrm/omap_priv.h b/drivers/staging/omapdrm/omap_priv.h index c324709aa9a1d9e346e9f80884ea0af86f7c82f4..ef6441447147399650399b39523dd31a0ab75b50 100644 --- a/drivers/staging/omapdrm/omap_priv.h +++ b/drivers/staging/omapdrm/omap_priv.h @@ -27,14 +27,22 @@ * pipes/overlays/CRTCs are used.. if this is not provided, then instead the * first CONFIG_DRM_OMAP_NUM_CRTCS are used, and they are each connected to * one manager, with priority given to managers that are connected to - * detected devices. This should be a good default behavior for most cases, - * but yet there still might be times when you wish to do something different. + * detected devices. Remaining overlays are used as video planes. This + * should be a good default behavior for most cases, but yet there still + * might be times when you wish to do something different. */ struct omap_kms_platform_data { + /* overlays to use as CRTCs: */ int ovl_cnt; const int *ovl_ids; + + /* overlays to use as video planes: */ + int pln_cnt; + const int *pln_ids; + int mgr_cnt; const int *mgr_ids; + int dev_cnt; const char **dev_names; };