diff options
Diffstat (limited to 'drivers/staging/omapdrm/omap_drv.c')
-rw-r--r-- | drivers/staging/omapdrm/omap_drv.c | 97 |
1 files changed, 64 insertions, 33 deletions
diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c index 602aa2dd49c8..3df5b4c58ecd 100644 --- a/drivers/staging/omapdrm/omap_drv.c +++ b/drivers/staging/omapdrm/omap_drv.c @@ -21,6 +21,7 @@ #include "drm_crtc_helper.h" #include "drm_fb_helper.h" +#include "omap_dmm_tiler.h" #define DRIVER_NAME MODULE_NAME #define DRIVER_DESC "OMAP DRM" @@ -204,12 +205,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 +240,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 +255,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 +342,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 +369,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 +383,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); @@ -377,8 +391,8 @@ static int omap_modeset_init(struct drm_device *dev) dump_video_chains(); - dev->mode_config.min_width = 256; - dev->mode_config.min_height = 256; + dev->mode_config.min_width = 32; + dev->mode_config.min_height = 32; /* note: eventually will need some cpu_is_omapXYZ() type stuff here * to fill in these limits properly on different OMAP generations.. @@ -557,6 +571,11 @@ static int dev_load(struct drm_device *dev, unsigned long flags) dev->dev_private = priv; + priv->wq = alloc_workqueue("omapdrm", + WQ_UNBOUND | WQ_NON_REENTRANT, 1); + + INIT_LIST_HEAD(&priv->obj_list); + omap_gem_init(dev); ret = omap_modeset_init(dev); @@ -585,6 +604,8 @@ static int dev_load(struct drm_device *dev, unsigned long flags) static int dev_unload(struct drm_device *dev) { + struct omap_drm_private *priv = dev->dev_private; + DBG("unload: dev=%p", dev); drm_vblank_cleanup(dev); @@ -594,6 +615,9 @@ static int dev_unload(struct drm_device *dev) omap_modeset_free(dev); omap_gem_deinit(dev); + flush_workqueue(priv->wq); + destroy_workqueue(priv->wq); + kfree(dev->dev_private); dev->dev_private = NULL; @@ -708,6 +732,18 @@ static struct vm_operations_struct omap_gem_vm_ops = { .close = drm_gem_vm_close, }; +static const struct file_operations omapdriver_fops = { + .owner = THIS_MODULE, + .open = drm_open, + .unlocked_ioctl = drm_ioctl, + .release = drm_release, + .mmap = omap_gem_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + .read = drm_read, + .llseek = noop_llseek, +}; + static struct drm_driver omap_drm_driver = { .driver_features = DRIVER_HAVE_IRQ | DRIVER_MODESET | DRIVER_GEM, @@ -738,17 +774,7 @@ static struct drm_driver omap_drm_driver = { .dumb_destroy = omap_gem_dumb_destroy, .ioctls = ioctls, .num_ioctls = DRM_OMAP_NUM_IOCTLS, - .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .unlocked_ioctl = drm_ioctl, - .release = drm_release, - .mmap = omap_gem_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - .read = drm_read, - .llseek = noop_llseek, - }, + .fops = &omapdriver_fops, .name = DRIVER_NAME, .desc = DRIVER_DESC, .date = DRIVER_DATE, @@ -777,6 +803,9 @@ static void pdev_shutdown(struct platform_device *device) static int pdev_probe(struct platform_device *device) { DBG("%s", device->name); + if (platform_driver_register(&omap_dmm_driver)) + dev_err(&device->dev, "DMM registration failed\n"); + return drm_platform_init(&omap_drm_driver, device); } @@ -784,6 +813,8 @@ static int pdev_remove(struct platform_device *device) { DBG(""); drm_platform_exit(&omap_drm_driver, device); + + platform_driver_unregister(&omap_dmm_driver); return 0; } |